1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.util.Arrays;
  29 import java.util.Objects;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 import static jdk.incubator.vector.VectorIntrinsics.*;
  32 
  33 @SuppressWarnings("cast")
  34 final class $vectortype$ extends $abstractvectortype$<Shapes.$shape$> {
  35     static final $Type$$bits$Species SPECIES = new $Type$$bits$Species();
  36 
  37     static final $vectortype$ ZERO = new $vectortype$();
  38 
  39     static final int LENGTH = SPECIES.length();
  40 
  41     private final $type$[] vec; // Don't access directly, use getElements() instead.
  42 
  43     private $type$[] getElements() {
  44         return VectorIntrinsics.maybeRebox(this).vec;
  45     }
  46 
  47     $vectortype$() {
  48         vec = new $type$[SPECIES.length()];
  49     }
  50 
  51     $vectortype$($type$[] v) {
  52         vec = v;
  53     }
  54 
  55     @Override
  56     public int length() { return LENGTH; }
  57 
  58     // Unary operator
  59 
  60     @Override
  61     $vectortype$ uOp(FUnOp f) {
  62         $type$[] vec = getElements();
  63         $type$[] res = new $type$[length()];
  64         for (int i = 0; i < length(); i++) {
  65             res[i] = f.apply(i, vec[i]);
  66         }
  67         return new $vectortype$(res);
  68     }
  69 
  70     @Override
  71     $vectortype$ uOp(Mask<$Boxtype$, Shapes.$shape$> o, FUnOp f) {
  72         $type$[] vec = getElements();
  73         $type$[] res = new $type$[length()];
  74         boolean[] mbits = (($masktype$)o).getBits();
  75         for (int i = 0; i < length(); i++) {
  76             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  77         }
  78         return new $vectortype$(res);
  79     }
  80 
  81     // Binary operator
  82 
  83     @Override
  84     $vectortype$ bOp(Vector<$Boxtype$, Shapes.$shape$> o, FBinOp f) {
  85         $type$[] res = new $type$[length()];
  86         $type$[] vec1 = this.getElements();
  87         $type$[] vec2 = (($vectortype$)o).getElements();
  88         for (int i = 0; i < length(); i++) {
  89             res[i] = f.apply(i, vec1[i], vec2[i]);
  90         }
  91         return new $vectortype$(res);
  92     }
  93 
  94     @Override
  95     $vectortype$ bOp(Vector<$Boxtype$, Shapes.$shape$> o1, Mask<$Boxtype$, Shapes.$shape$> o2, FBinOp f) {
  96         $type$[] res = new $type$[length()];
  97         $type$[] vec1 = this.getElements();
  98         $type$[] vec2 = (($vectortype$)o1).getElements();
  99         boolean[] mbits = (($masktype$)o2).getBits();
 100         for (int i = 0; i < length(); i++) {
 101             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 102         }
 103         return new $vectortype$(res);
 104     }
 105 
 106     // Trinary operator
 107 
 108     @Override
 109     $vectortype$ tOp(Vector<$Boxtype$, Shapes.$shape$> o1, Vector<$Boxtype$, Shapes.$shape$> o2, FTriOp f) {
 110         $type$[] res = new $type$[length()];
 111         $type$[] vec1 = this.getElements();
 112         $type$[] vec2 = (($vectortype$)o1).getElements();
 113         $type$[] vec3 = (($vectortype$)o2).getElements();
 114         for (int i = 0; i < length(); i++) {
 115             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 116         }
 117         return new $vectortype$(res);
 118     }
 119 
 120     @Override
 121     $vectortype$ tOp(Vector<$Boxtype$, Shapes.$shape$> o1, Vector<$Boxtype$, Shapes.$shape$> o2, Mask<$Boxtype$, Shapes.$shape$> o3, FTriOp f) {
 122         $type$[] res = new $type$[length()];
 123         $type$[] vec1 = getElements();
 124         $type$[] vec2 = (($vectortype$)o1).getElements();
 125         $type$[] vec3 = (($vectortype$)o2).getElements();
 126         boolean[] mbits = (($masktype$)o3).getBits();
 127         for (int i = 0; i < length(); i++) {
 128             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 129         }
 130         return new $vectortype$(res);
 131     }
 132 
 133     @Override
 134     $type$ rOp($type$ v, FBinOp f) {
 135         $type$[] vec = getElements();
 136         for (int i = 0; i < length(); i++) {
 137             v = f.apply(i, v, vec[i]);
 138         }
 139         return v;
 140     }
 141 
 142     // Binary operations with scalars
 143 
 144     @Override
 145     @ForceInline
 146     public $abstractvectortype$<Shapes.$shape$> add($type$ o) {
 147         return add(SPECIES.broadcast(o));
 148     }
 149 
 150     @Override
 151     @ForceInline
 152     public $abstractvectortype$<Shapes.$shape$> add($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 153         return add(SPECIES.broadcast(o), m);
 154     }
 155 
 156     @Override
 157     @ForceInline
 158     public $abstractvectortype$<Shapes.$shape$> addSaturate($type$ o) {
 159         return addSaturate(SPECIES.broadcast(o));
 160     }
 161 
 162     @Override
 163     @ForceInline
 164     public $abstractvectortype$<Shapes.$shape$> addSaturate($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 165         return addSaturate(SPECIES.broadcast(o), m);
 166     }
 167 
 168     @Override
 169     @ForceInline
 170     public $abstractvectortype$<Shapes.$shape$> sub($type$ o) {
 171         return sub(SPECIES.broadcast(o));
 172     }
 173 
 174     @Override
 175     @ForceInline
 176     public $abstractvectortype$<Shapes.$shape$> sub($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 177         return sub(SPECIES.broadcast(o), m);
 178     }
 179 
 180     @Override
 181     @ForceInline
 182     public $abstractvectortype$<Shapes.$shape$> subSaturate($type$ o) {
 183         return subSaturate(SPECIES.broadcast(o));
 184     }
 185 
 186     @Override
 187     @ForceInline
 188     public $abstractvectortype$<Shapes.$shape$> subSaturate($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 189         return subSaturate(SPECIES.broadcast(o), m);
 190     }
 191 
 192     @Override
 193     @ForceInline
 194     public $abstractvectortype$<Shapes.$shape$> mul($type$ o) {
 195         return mul(SPECIES.broadcast(o));
 196     }
 197 
 198     @Override
 199     @ForceInline
 200     public $abstractvectortype$<Shapes.$shape$> mul($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 201         return mul(SPECIES.broadcast(o), m);
 202     }
 203 
 204     @Override
 205     @ForceInline
 206     public $abstractvectortype$<Shapes.$shape$> min($type$ o) {
 207         return min(SPECIES.broadcast(o));
 208     }
 209 
 210     @Override
 211     @ForceInline
 212     public $abstractvectortype$<Shapes.$shape$> max($type$ o) {
 213         return max(SPECIES.broadcast(o));
 214     }
 215 
 216     @Override
 217     @ForceInline
 218     public Mask<$Boxtype$, Shapes.$shape$> equal($type$ o) {
 219         return equal(SPECIES.broadcast(o));
 220     }
 221 
 222     @Override
 223     @ForceInline
 224     public Mask<$Boxtype$, Shapes.$shape$> notEqual($type$ o) {
 225         return notEqual(SPECIES.broadcast(o));
 226     }
 227 
 228     @Override
 229     @ForceInline
 230     public Mask<$Boxtype$, Shapes.$shape$> lessThan($type$ o) {
 231         return lessThan(SPECIES.broadcast(o));
 232     }
 233 
 234     @Override
 235     @ForceInline
 236     public Mask<$Boxtype$, Shapes.$shape$> lessThanEq($type$ o) {
 237         return lessThanEq(SPECIES.broadcast(o));
 238     }
 239 
 240     @Override
 241     @ForceInline
 242     public Mask<$Boxtype$, Shapes.$shape$> greaterThan($type$ o) {
 243         return greaterThan(SPECIES.broadcast(o));
 244     }
 245 
 246     @Override
 247     @ForceInline
 248     public Mask<$Boxtype$, Shapes.$shape$> greaterThanEq($type$ o) {
 249         return greaterThanEq(SPECIES.broadcast(o));
 250     }
 251 
 252     @Override
 253     @ForceInline
 254     public $abstractvectortype$<Shapes.$shape$> blend($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 255         return blend(SPECIES.broadcast(o), m);
 256     }
 257 
 258 #if[FP]
 259     @Override
 260     @ForceInline
 261     public $abstractvectortype$<Shapes.$shape$> div($type$ o) {
 262         return div(SPECIES.broadcast(o));
 263     }
 264 
 265     @Override
 266     @ForceInline
 267     public $abstractvectortype$<Shapes.$shape$> div($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 268         return div(SPECIES.broadcast(o), m);
 269     }
 270 
 271     @Override
 272     @ForceInline
 273     public $abstractvectortype$<Shapes.$shape$> atan2($type$ o) {
 274         return atan2(SPECIES.broadcast(o));
 275     }
 276 
 277     @Override
 278     @ForceInline
 279     public $abstractvectortype$<Shapes.$shape$> atan2($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 280         return atan2(SPECIES.broadcast(o), m);
 281     }
 282 
 283     @Override
 284     @ForceInline
 285     public $abstractvectortype$<Shapes.$shape$> pow($type$ o) {
 286         return pow(SPECIES.broadcast(o));
 287     }
 288 
 289     @Override
 290     @ForceInline
 291     public $abstractvectortype$<Shapes.$shape$> pow($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 292         return pow(SPECIES.broadcast(o), m);
 293     }
 294 
 295     @Override
 296     @ForceInline
 297     public $abstractvectortype$<Shapes.$shape$> fma($type$ o1, $type$ o2) {
 298         return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2));
 299     }
 300 
 301     @Override
 302     @ForceInline
 303     public $abstractvectortype$<Shapes.$shape$> fma($type$ o1, $type$ o2, Mask<$Boxtype$,Shapes.$shape$> m) {
 304         return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2), m);
 305     }
 306 
 307     @Override
 308     @ForceInline
 309     public $abstractvectortype$<Shapes.$shape$> hypot($type$ o) {
 310         return hypot(SPECIES.broadcast(o));
 311     }
 312 
 313     @Override
 314     @ForceInline
 315     public $abstractvectortype$<Shapes.$shape$> hypot($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 316         return hypot(SPECIES.broadcast(o), m);
 317     }
 318 #end[FP]
 319 
 320 #if[BITWISE]
 321     @Override
 322     @ForceInline
 323     public $abstractvectortype$<Shapes.$shape$> and($type$ o) {
 324         return and(SPECIES.broadcast(o));
 325     }
 326 
 327     @Override
 328     @ForceInline
 329     public $abstractvectortype$<Shapes.$shape$> and($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 330         return and(SPECIES.broadcast(o), m);
 331     }
 332 
 333     @Override
 334     @ForceInline
 335     public $abstractvectortype$<Shapes.$shape$> or($type$ o) {
 336         return or(SPECIES.broadcast(o));
 337     }
 338 
 339     @Override
 340     @ForceInline
 341     public $abstractvectortype$<Shapes.$shape$> or($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 342         return or(SPECIES.broadcast(o), m);
 343     }
 344 
 345     @Override
 346     @ForceInline
 347     public $abstractvectortype$<Shapes.$shape$> xor($type$ o) {
 348         return xor(SPECIES.broadcast(o));
 349     }
 350 
 351     @Override
 352     @ForceInline
 353     public $abstractvectortype$<Shapes.$shape$> xor($type$ o, Mask<$Boxtype$,Shapes.$shape$> m) {
 354         return xor(SPECIES.broadcast(o), m);
 355     }
 356 #end[BITWISE]
 357 
 358 
 359     // Unary operations
 360 
 361     @Override
 362     @ForceInline
 363     public $vectortype$ abs() {
 364         return ($vectortype$) VectorIntrinsics.unaryOp(
 365             VECTOR_OP_ABS, $vectortype$.class, $type$.class, LENGTH,
 366             this,
 367             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.abs(a)));
 368     }
 369 
 370 #if[intOrFP]
 371     @Override
 372     @ForceInline
 373     public $vectortype$ neg() {
 374         return ($vectortype$) VectorIntrinsics.unaryOp(
 375             VECTOR_OP_NEG, $vectortype$.class, $type$.class, LENGTH,
 376             this,
 377             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) -a));
 378     }
 379 #end[intOrFP]
 380 
 381 #if[FP]
 382     @Override
 383     @ForceInline
 384     public $vectortype$ div(Vector<$Boxtype$,Shapes.$shape$> o) {
 385         Objects.requireNonNull(o);
 386         $vectortype$ v = ($vectortype$)o;
 387         return ($vectortype$) VectorIntrinsics.binaryOp(
 388             VECTOR_OP_DIV, $vectortype$.class, $type$.class, LENGTH,
 389             this, v,
 390             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a / b)));
 391     }
 392 
 393     @Override
 394     @ForceInline
 395     public $vectortype$ sqrt() {
 396         return ($vectortype$) VectorIntrinsics.unaryOp(
 397             VECTOR_OP_SQRT, $vectortype$.class, $type$.class, LENGTH,
 398             this,
 399             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.sqrt((double) a)));
 400     }
 401 #end[FP]
 402 
 403 #if[BITWISE]
 404     @Override
 405     @ForceInline
 406     public $vectortype$ not() {
 407         return ($vectortype$) VectorIntrinsics.unaryOp(
 408             VECTOR_OP_NOT, $vectortype$.class, $type$.class, LENGTH,
 409             this,
 410             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) ~a));
 411     }
 412 #end[BITWISE]
 413     // Binary operations
 414 
 415     @Override
 416     @ForceInline
 417     public $vectortype$ add(Vector<$Boxtype$,Shapes.$shape$> o) {
 418         Objects.requireNonNull(o);
 419         $vectortype$ v = ($vectortype$)o;
 420         return ($vectortype$) VectorIntrinsics.binaryOp(
 421             VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
 422             this, v,
 423             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a + b)));
 424     }
 425 
 426     @Override
 427     @ForceInline
 428     public $vectortype$ sub(Vector<$Boxtype$,Shapes.$shape$> o) {
 429         Objects.requireNonNull(o);
 430         $vectortype$ v = ($vectortype$)o;
 431         return ($vectortype$) VectorIntrinsics.binaryOp(
 432             VECTOR_OP_SUB, $vectortype$.class, $type$.class, LENGTH,
 433             this, v,
 434             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a - b)));
 435     }
 436 
 437     @Override
 438     @ForceInline
 439     public $vectortype$ mul(Vector<$Boxtype$,Shapes.$shape$> o) {
 440         Objects.requireNonNull(o);
 441         $vectortype$ v = ($vectortype$)o;
 442         return ($vectortype$) VectorIntrinsics.binaryOp(
 443             VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
 444             this, v,
 445             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a * b)));
 446     }
 447 
 448     @Override
 449     @ForceInline
 450     public $vectortype$ min(Vector<$Boxtype$,Shapes.$shape$> o) {
 451         Objects.requireNonNull(o);
 452         $vectortype$ v = ($vectortype$)o;
 453         return ($vectortype$) VectorIntrinsics.binaryOp(
 454             VECTOR_OP_MIN, $vectortype$.class, $type$.class, LENGTH,
 455             this, v,
 456             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$) ((a < b) ? a : b)));
 457     }
 458 
 459     @Override
 460     @ForceInline
 461     public $vectortype$ max(Vector<$Boxtype$,Shapes.$shape$> o) {
 462         Objects.requireNonNull(o);
 463         $vectortype$ v = ($vectortype$)o;
 464         return ($vectortype$) VectorIntrinsics.binaryOp(
 465             VECTOR_OP_MAX, $vectortype$.class, $type$.class, LENGTH,
 466             this, v,
 467             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$) ((a > b) ? a : b)));
 468         }
 469 
 470 #if[intOrFP]
 471     @Override
 472     @ForceInline
 473     public $vectortype$ add(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 474         // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a + b));
 475         return blend(add(v), m);
 476     }
 477 
 478     @Override
 479     @ForceInline
 480     public $vectortype$ sub(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 481         // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a - b));
 482         return blend(sub(v), m);
 483     }
 484 
 485     @Override
 486     @ForceInline
 487     public $vectortype$ mul(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 488         // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a * b));
 489         return blend(mul(v), m);
 490     }
 491 #end[intOrFP]
 492 
 493 #if[FP]
 494     @Override
 495     @ForceInline
 496     public $vectortype$ div(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 497         // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a / b));
 498         return blend(div(v), m);
 499     }
 500 #end[FP]
 501 
 502 #if[BITWISE]
 503     @Override
 504     @ForceInline
 505     public $vectortype$ and(Vector<$Boxtype$,Shapes.$shape$> o) {
 506         Objects.requireNonNull(o);
 507         $vectortype$ v = ($vectortype$)o;
 508         return ($vectortype$) VectorIntrinsics.binaryOp(
 509             VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH,
 510             this, v,
 511             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a & b)));
 512     }
 513 
 514     @Override
 515     @ForceInline
 516     public $vectortype$ or(Vector<$Boxtype$,Shapes.$shape$> o) {
 517         Objects.requireNonNull(o);
 518         $vectortype$ v = ($vectortype$)o;
 519         return ($vectortype$) VectorIntrinsics.binaryOp(
 520             VECTOR_OP_OR, $vectortype$.class, $type$.class, LENGTH,
 521             this, v,
 522             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a | b)));
 523     }
 524 
 525     @Override
 526     @ForceInline
 527     public $vectortype$ xor(Vector<$Boxtype$,Shapes.$shape$> o) {
 528         Objects.requireNonNull(o);
 529         $vectortype$ v = ($vectortype$)o;
 530         return ($vectortype$) VectorIntrinsics.binaryOp(
 531             VECTOR_OP_XOR, $vectortype$.class, $type$.class, LENGTH,
 532             this, v,
 533             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a ^ b)));
 534     }
 535 
 536     @Override
 537     @ForceInline
 538     public $vectortype$ and(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 539         return blend(and(v), m);
 540     }
 541 
 542     @Override
 543     @ForceInline
 544     public $vectortype$ or(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 545         return blend(or(v), m);
 546     }
 547 
 548     @Override
 549     @ForceInline
 550     public $vectortype$ xor(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) {
 551         return blend(xor(v), m);
 552     }
 553 
 554     @Override
 555     @ForceInline
 556     public $vectortype$ shiftL(int s) {
 557         return ($vectortype$) VectorIntrinsics.broadcastInt(
 558             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
 559             this, s,
 560             (v, i) -> v.uOp((__, a) -> ($type$) (a << i)));
 561     }
 562 
 563     @Override
 564     @ForceInline
 565     public $vectortype$ shiftR(int s) {
 566         return ($vectortype$) VectorIntrinsics.broadcastInt(
 567             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
 568             this, s,
 569             (v, i) -> v.uOp((__, a) -> ($type$) (a >>> i)));
 570     }
 571 
 572     @Override
 573     @ForceInline
 574     public $vectortype$ aShiftR(int s) {
 575         return ($vectortype$) VectorIntrinsics.broadcastInt(
 576             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
 577             this, s,
 578             (v, i) -> v.uOp((__, a) -> ($type$) (a >> i)));
 579     }
 580 #end[BITWISE]
 581 
 582 #if[intOrLong]
 583     @Override
 584     @ForceInline
 585     public $vectortype$ shiftL(Vector<$Boxtype$,Shapes.$shape$> s) {
 586         $vectortype$ v = ($vectortype$)s;
 587         return ($vectortype$) VectorIntrinsics.binaryOp(
 588             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
 589             this, v,
 590             (v1, v2) -> (($vectortype$)v1).bOp(v2,(i,a, b) -> ($type$) (a << b)));
 591     }
 592 
 593     @Override
 594     @ForceInline
 595     public $vectortype$ shiftR(Vector<$Boxtype$,Shapes.$shape$> s) {
 596         $vectortype$ v = ($vectortype$)s;
 597         return ($vectortype$) VectorIntrinsics.binaryOp(
 598             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
 599             this, v,
 600             (v1, v2) -> (($vectortype$)v1).bOp(v2,(i,a, b) -> ($type$) (a >>> b)));
 601     }
 602 
 603     @Override
 604     @ForceInline
 605     public $vectortype$ ashiftR(Vector<$Boxtype$,Shapes.$shape$> s) {
 606         $vectortype$ v = ($vectortype$)s;
 607         return ($vectortype$) VectorIntrinsics.binaryOp(
 608             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
 609             this, v,
 610             (v1, v2) -> (($vectortype$)v1).bOp(v2,(i,a, b) -> ($type$) (a >> b)));
 611     }
 612 #end[intOrLong]
 613     // Ternary operations
 614 
 615 #if[FP]
 616     @Override
 617     @ForceInline
 618     public $vectortype$ fma(Vector<$Boxtype$,Shapes.$shape$> o1, Vector<$Boxtype$,Shapes.$shape$> o2) {
 619         Objects.requireNonNull(o1);
 620         Objects.requireNonNull(o2);
 621         $vectortype$ v1 = ($vectortype$)o1;
 622         $vectortype$ v2 = ($vectortype$)o2;
 623         return ($vectortype$) VectorIntrinsics.ternaryOp(
 624             VECTOR_OP_FMA, $vectortype$.class, $type$.class, LENGTH,
 625             this, v1, v2,
 626             (w1, w2, w3) -> w1.tOp(w2, w3, (i, a, b, c) -> Math.fma(a, b, c)));
 627     }
 628 #end[FP]
 629 
 630     // Type specific horizontal reductions
 631 
 632 #if[BITWISE]
 633     @Override
 634     @ForceInline
 635     public $type$ addAll() {
 636         return ($type$) VectorIntrinsics.reductionCoerced(
 637             VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
 638             this,
 639             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b)));
 640     }
 641 
 642     @Override
 643     @ForceInline
 644     public $type$ andAll() {
 645         return ($type$) VectorIntrinsics.reductionCoerced(
 646             VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH,
 647             this,
 648             v -> (long) v.rOp(($type$) -1, (i, a, b) -> ($type$) (a & b)));
 649     }
 650 #end[BITWISE]
 651 #if[intOrLong]
 652 
 653     @Override
 654     @ForceInline
 655     public $type$ mulAll() {
 656         return ($type$) VectorIntrinsics.reductionCoerced(
 657             VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
 658             this,
 659             v -> (long) v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b)));
 660     }
 661 
 662     @Override
 663     @ForceInline
 664     public $type$ orAll() {
 665         return ($type$) VectorIntrinsics.reductionCoerced(
 666             VECTOR_OP_OR, $vectortype$.class, $type$.class, LENGTH,
 667             this,
 668             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a | b)));
 669     }
 670 
 671     @Override
 672     @ForceInline
 673     public $type$ xorAll() {
 674         return ($type$) VectorIntrinsics.reductionCoerced(
 675             VECTOR_OP_XOR, $vectortype$.class, $type$.class, LENGTH,
 676             this,
 677             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a ^ b)));
 678     }
 679 
 680     @Override
 681     @ForceInline
 682     public $type$ subAll() {
 683         return ($type$) VectorIntrinsics.reductionCoerced(
 684             VECTOR_OP_SUB, $vectortype$.class, $type$.class, LENGTH,
 685             this,
 686             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a - b)));
 687     }
 688 #end[intOrLong]
 689 #if[FP]
 690     @Override
 691     @ForceInline
 692     public $type$ addAll() {
 693         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
 694                                 VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
 695                                 this,
 696                                 v -> {
 697                                     $type$ r = v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b));
 698                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
 699                                 });
 700         return $Type$.$bitstype$BitsTo$Fptype$(bits);
 701     }
 702 
 703     @Override
 704     @ForceInline
 705     public $type$ mulAll() {
 706         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
 707                                 VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
 708                                 this,
 709                                 v -> {
 710                                     $type$ r = v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b));
 711                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
 712                                 });
 713         return $Type$.$bitstype$BitsTo$Fptype$(bits);
 714     }
 715 #end[FP]
 716 
 717     // Memory operations
 718 
 719     @Override
 720     @ForceInline
 721     public void intoArray($type$[] a, int ix) {
 722         Objects.requireNonNull(a);
 723         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 724         VectorIntrinsics.store($vectortype$.class, $type$.class, LENGTH,
 725                                a, ix, this,
 726                                (arr, idx, v) -> v.forEach((i, a_) -> (($type$[])arr)[idx + i] = a_));
 727     }
 728 
 729     @Override
 730     @ForceInline
 731     public void intoArray($type$[] a, int ax, Mask<$Boxtype$, Shapes.$shape$> m) {
 732         // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_);
 733         $vectortype$ oldVal = SPECIES.fromArray(a, ax);
 734         $vectortype$ newVal = oldVal.blend(this, m);
 735         newVal.intoArray(a, ax);
 736     }
 737 
 738     //
 739 
 740     @Override
 741     public String toString() {
 742         return Arrays.toString(getElements());
 743     }
 744 
 745     @Override
 746     public boolean equals(Object o) {
 747         if (this == o) return true;
 748         if (o == null || this.getClass() != o.getClass()) return false;
 749 
 750         $vectortype$ that = ($vectortype$) o;
 751         return Arrays.equals(this.getElements(), that.getElements());
 752     }
 753 
 754     @Override
 755     public int hashCode() {
 756         return Arrays.hashCode(vec);
 757     }
 758 
 759     // Binary test
 760 
 761     @Override
 762     $masktype$ bTest(Vector<$Boxtype$, Shapes.$shape$> o, FBinTest f) {
 763         $type$[] vec1 = getElements();
 764         $type$[] vec2 = (($vectortype$)o).getElements();
 765         boolean[] bits = new boolean[length()];
 766         for (int i = 0; i < length(); i++){
 767             bits[i] = f.apply(i, vec1[i], vec2[i]);
 768         }
 769         return new $masktype$(bits);
 770     }
 771 
 772     // Comparisons
 773 
 774     @Override
 775     @ForceInline
 776     public $masktype$ equal(Vector<$Boxtype$, Shapes.$shape$> o) {
 777         Objects.requireNonNull(o);
 778         $vectortype$ v = ($vectortype$)o;
 779 
 780         return ($masktype$) VectorIntrinsics.compare(
 781             BT_eq, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 782             this, v,
 783             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 784     }
 785 
 786     @Override
 787     @ForceInline
 788     public $masktype$ notEqual(Vector<$Boxtype$, Shapes.$shape$> o) {
 789         Objects.requireNonNull(o);
 790         $vectortype$ v = ($vectortype$)o;
 791 
 792         return ($masktype$) VectorIntrinsics.compare(
 793             BT_ne, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 794             this, v,
 795             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 796     }
 797 
 798     @Override
 799     @ForceInline
 800     public $masktype$ lessThan(Vector<$Boxtype$, Shapes.$shape$> o) {
 801         Objects.requireNonNull(o);
 802         $vectortype$ v = ($vectortype$)o;
 803 
 804         return ($masktype$) VectorIntrinsics.compare(
 805             BT_lt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 806             this, v,
 807             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
 808     }
 809 
 810     @Override
 811     @ForceInline
 812     public $masktype$ lessThanEq(Vector<$Boxtype$, Shapes.$shape$> o) {
 813         Objects.requireNonNull(o);
 814         $vectortype$ v = ($vectortype$)o;
 815 
 816         return ($masktype$) VectorIntrinsics.compare(
 817             BT_le, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 818             this, v,
 819             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
 820     }
 821 
 822     @Override
 823     @ForceInline
 824     public $masktype$ greaterThan(Vector<$Boxtype$, Shapes.$shape$> o) {
 825         Objects.requireNonNull(o);
 826         $vectortype$ v = ($vectortype$)o;
 827 
 828         return ($masktype$) VectorIntrinsics.compare(
 829             BT_gt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 830             this, v,
 831             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
 832     }
 833 
 834     @Override
 835     @ForceInline
 836     public $masktype$ greaterThanEq(Vector<$Boxtype$, Shapes.$shape$> o) {
 837         Objects.requireNonNull(o);
 838         $vectortype$ v = ($vectortype$)o;
 839 
 840         return ($masktype$) VectorIntrinsics.compare(
 841             BT_ge, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 842             this, v,
 843             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
 844     }
 845 
 846     // Foreach
 847 
 848     @Override
 849     void forEach(FUnCon f) {
 850         $type$[] vec = getElements();
 851         for (int i = 0; i < length(); i++) {
 852             f.apply(i, vec[i]);
 853         }
 854     }
 855 
 856     @Override
 857     void forEach(Mask<$Boxtype$, Shapes.$shape$> o, FUnCon f) {
 858         boolean[] mbits = (($masktype$)o).getBits();
 859         forEach((i, a) -> {
 860             if (mbits[i]) { f.apply(i, a); }
 861         });
 862     }
 863 
 864 #if[FP]
 865     $bitsvectortype$ toBits() {
 866         $type$[] vec = getElements();
 867         $bitstype$[] res = new $bitstype$[this.species().length()];
 868         for(int i = 0; i < this.species().length(); i++){
 869             res[i] = $Type$.$type$To$Bitstype$Bits(vec[i]);
 870         }
 871         return new $bitsvectortype$(res);
 872     }
 873 #end[FP]
 874 
 875 #if[intOrLong]
 876     $fpvectortype$ toFP() {
 877         $type$[] vec = getElements();
 878         $fptype$[] res = new $fptype$[this.species().length()];
 879         for(int i = 0; i < this.species().length(); i++){
 880             res[i] = $Boxfptype$.$bitstype$BitsTo$Fptype$(vec[i]);
 881         }
 882         return new $fpvectortype$(res);
 883     }
 884 #end[intOrLong]
 885 
 886     @Override
 887     public $vectortype$ rotateEL(int j) {
 888         $type$[] vec = getElements();
 889         $type$[] res = new $type$[length()];
 890         for (int i = 0; i < length(); i++){
 891             res[(j + i) % length()] = vec[i];
 892         }
 893         return new $vectortype$(res);
 894     }
 895 
 896     @Override
 897     public $vectortype$ rotateER(int j) {
 898         $type$[] vec = getElements();
 899         $type$[] res = new $type$[length()];
 900         for (int i = 0; i < length(); i++){
 901             int z = i - j;
 902             if(j < 0) {
 903                 res[length() + z] = vec[i];
 904             } else {
 905                 res[z] = vec[i];
 906             }
 907         }
 908         return new $vectortype$(res);
 909     }
 910 
 911     @Override
 912     public $vectortype$ shiftEL(int j) {
 913         $type$[] vec = getElements();
 914         $type$[] res = new $type$[length()];
 915         for (int i = 0; i < length() - j; i++) {
 916             res[i] = vec[i + j];
 917         }
 918         return new $vectortype$(res);
 919     }
 920 
 921     @Override
 922     public $vectortype$ shiftER(int j) {
 923         $type$[] vec = getElements();
 924         $type$[] res = new $type$[length()];
 925         for (int i = 0; i < length() - j; i++){
 926             res[i + j] = vec[i];
 927         }
 928         return new $vectortype$(res);
 929     }
 930 
 931     @Override
 932     public $vectortype$ shuffle(Vector<$Boxtype$, Shapes.$shape$> o, Shuffle<$Boxtype$, Shapes.$shape$> s) {
 933         $vectortype$ v = ($vectortype$) o;
 934         return uOp((i, a) -> {
 935             $type$[] vec = this.getElements();
 936             int e = s.getElement(i);
 937             if(e >= 0 && e < length()) {
 938                 //from this
 939                 return vec[e];
 940             } else if(e < length() * 2) {
 941                 //from o
 942                 return v.getElements()[e - length()];
 943             } else {
 944                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 945             }
 946         });
 947     }
 948 
 949     @Override
 950     public $vectortype$ swizzle(Shuffle<$Boxtype$, Shapes.$shape$> s) {
 951         return uOp((i, a) -> {
 952             $type$[] vec = this.getElements();
 953             int e = s.getElement(i);
 954             if(e >= 0 && e < length()) {
 955                 return vec[e];
 956             } else {
 957                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 958             }
 959         });
 960     }
 961 
 962     @Override
 963     @ForceInline
 964     public $vectortype$ blend(Vector<$Boxtype$, Shapes.$shape$> o1, Mask<$Boxtype$, Shapes.$shape$> o2) {
 965         Objects.requireNonNull(o1);
 966         Objects.requireNonNull(o2);
 967         $vectortype$ v = ($vectortype$)o1;
 968         $masktype$   m = ($masktype$)o2;
 969 
 970         return ($vectortype$) VectorIntrinsics.blend(
 971             $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
 972             this, v, m,
 973             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
 974     }
 975 
 976     // Accessors
 977 
 978     @Override
 979     public $type$ get(int i) {
 980         $type$[] vec = getElements();
 981         return vec[i];
 982     }
 983 
 984     @Override
 985     public $vectortype$ with(int i, $type$ e) {
 986         $type$[] res = vec.clone();
 987         res[i] = e;
 988         return new $vectortype$(res);
 989     }
 990 
 991     // Mask
 992 
 993     static final class $masktype$ extends AbstractMask<$Boxtype$, Shapes.$shape$> {
 994         static final $masktype$ TRUE_MASK = new $masktype$(true);
 995         static final $masktype$ FALSE_MASK = new $masktype$(false);
 996 
 997         // FIXME: was temporarily put here to simplify rematerialization support in the JVM
 998         private final boolean[] bits; // Don't access directly, use getBits() instead.
 999 
1000         public $masktype$(boolean[] bits) {
1001             this(bits, 0);
1002         }
1003 
1004         public $masktype$(boolean[] bits, int i) {
1005             this.bits = Arrays.copyOfRange(bits, i, i + species().length());
1006         }
1007 
1008         public $masktype$(boolean val) {
1009             boolean[] bits = new boolean[species().length()];
1010             Arrays.fill(bits, val);
1011             this.bits = bits;
1012         }
1013 
1014         boolean[] getBits() {
1015             return VectorIntrinsics.maybeRebox(this).bits;
1016         }
1017 
1018         @Override
1019         $masktype$ uOp(MUnOp f) {
1020             boolean[] res = new boolean[species().length()];
1021             boolean[] bits = getBits();
1022             for (int i = 0; i < species().length(); i++) {
1023                 res[i] = f.apply(i, bits[i]);
1024             }
1025             return new $masktype$(res);
1026         }
1027 
1028         @Override
1029         $masktype$ bOp(Mask<$Boxtype$, Shapes.$shape$> o, MBinOp f) {
1030             boolean[] res = new boolean[species().length()];
1031             boolean[] bits = getBits();
1032             boolean[] mbits = (($masktype$)o).getBits();
1033             for (int i = 0; i < species().length(); i++) {
1034                 res[i] = f.apply(i, bits[i], mbits[i]);
1035             }
1036             return new $masktype$(res);
1037         }
1038 
1039         @Override
1040         public $Type$$bits$Species species() {
1041             return SPECIES;
1042         }
1043 
1044         @Override
1045         public $vectortype$ toVector() {
1046             $type$[] res = new $type$[species().length()];
1047             boolean[] bits = getBits();
1048             for (int i = 0; i < species().length(); i++) {
1049                 res[i] = ($type$) (bits[i] ? -1 : 0);
1050             }
1051             return new $vectortype$(res);
1052         }
1053 
1054         @Override
1055         @ForceInline
1056         @SuppressWarnings("unchecked")
1057         public <Z> Mask<Z, Shapes.$shape$> rebracket(Species<Z, Shapes.$shape$> species) {
1058             Objects.requireNonNull(species);
1059             // TODO: check proper element type
1060             return VectorIntrinsics.reinterpret(
1061                 $masktype$.class, $type$.class, LENGTH,
1062                 species.elementType(), species.length(), this,
1063                 (m, t) -> m.reshape(species)
1064             );
1065         }
1066 
1067         // Unary operations
1068 
1069         //Mask<E, S> not();
1070 
1071         // Binary operations
1072 
1073         @Override
1074         @ForceInline
1075         public $masktype$ and(Mask<$Boxtype$,Shapes.$shape$> o) {
1076             Objects.requireNonNull(o);
1077             $masktype$ m = ($masktype$)o;
1078             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, $masktype$.class, $bitstype$.class, LENGTH,
1079                                              this, m,
1080                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1081         }
1082 
1083         @Override
1084         @ForceInline
1085         public $masktype$ or(Mask<$Boxtype$,Shapes.$shape$> o) {
1086             Objects.requireNonNull(o);
1087             $masktype$ m = ($masktype$)o;
1088             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, $masktype$.class, $bitstype$.class, LENGTH,
1089                                              this, m,
1090                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1091         }
1092 
1093         // Reductions
1094 
1095         @Override
1096         @ForceInline
1097         public boolean anyTrue() {
1098             return VectorIntrinsics.test(COND_notZero, $masktype$.class, $bitstype$.class, LENGTH,
1099                                          this, this,
1100                                          (m1, m2) -> super.anyTrue());
1101         }
1102 
1103         @Override
1104         @ForceInline
1105         public boolean allTrue() {
1106             return VectorIntrinsics.test(COND_carrySet, $masktype$.class, $bitstype$.class, LENGTH,
1107                                          this, species().maskAllTrue(),
1108                                          (m1, m2) -> super.allTrue());
1109         }
1110     }
1111 
1112     // Shuffle
1113 
1114     static final class $shuffletype$ extends AbstractShuffle<$Boxtype$, Shapes.$shape$> {
1115         static final IntVector.IntSpecies<Shapes.$shape$> INT_SPECIES = IntVector.speciesInstance(Shapes.$Shape$);
1116 
1117         public $shuffletype$(int[] reorder) {
1118             super(reorder);
1119         }
1120 
1121         public $shuffletype$(int[] reorder, int i) {
1122             super(reorder, i);
1123         }
1124 
1125         @Override
1126         public $Type$$bits$Species species() {
1127             return SPECIES;
1128         }
1129 
1130         @Override
1131         public IntVector.IntSpecies<Shapes.$shape$> intSpecies() {
1132             return INT_SPECIES;
1133         }
1134     }
1135 
1136     // Species
1137 
1138     @Override
1139     public $Type$$bits$Species species() {
1140         return SPECIES;
1141     }
1142 
1143     static final class $Type$$bits$Species extends $Type$Species<Shapes.$shape$> {
1144         static final int BIT_SIZE = Shapes.$Shape$.bitSize();
1145 
1146         static final int LENGTH = BIT_SIZE / $Boxtype$.SIZE;
1147 
1148         @Override
1149         public String toString() {
1150            StringBuilder sb = new StringBuilder("Shape[");
1151            sb.append(bitSize()).append(" bits, ");
1152            sb.append(length()).append(" ").append($type$.class.getSimpleName()).append("s x ");
1153            sb.append(elementSize()).append(" bits");
1154            sb.append("]");
1155            return sb.toString();
1156         }
1157 
1158         @Override
1159         @ForceInline
1160         public int bitSize() {
1161             return BIT_SIZE;
1162         }
1163 
1164         @Override
1165         @ForceInline
1166         public int length() {
1167             return LENGTH;
1168         }
1169 
1170         @Override
1171         @ForceInline
1172         public Class<$Boxtype$> elementType() {
1173             return $type$.class;
1174         }
1175 
1176         @Override
1177         @ForceInline
1178         public int elementSize() {
1179             return $Boxtype$.SIZE;
1180         }
1181 
1182         @Override
1183         @ForceInline
1184         public Shapes.$shape$ shape() {
1185             return Shapes.$Shape$;
1186         }
1187 
1188         @Override
1189         $vectortype$ op(FOp f) {
1190             $type$[] res = new $type$[length()];
1191             for (int i = 0; i < length(); i++) {
1192                 res[i] = f.apply(i);
1193             }
1194             return new $vectortype$(res);
1195         }
1196 
1197         @Override
1198         $vectortype$ op(Mask<$Boxtype$, Shapes.$shape$> o, FOp f) {
1199             $type$[] res = new $type$[length()];
1200             boolean[] mbits = (($masktype$)o).getBits();
1201             for (int i = 0; i < length(); i++) {
1202                 if (mbits[i]) {
1203                     res[i] = f.apply(i);
1204                 }
1205             }
1206             return new $vectortype$(res);
1207         }
1208 
1209         // Factories
1210 
1211         @Override
1212         public $masktype$ maskFromValues(boolean... bits) {
1213             return new $masktype$(bits);
1214         }
1215 
1216         @Override
1217         public $masktype$ maskFromArray(boolean[] bits, int i) {
1218             return new $masktype$(bits, i);
1219         }
1220 
1221         @Override
1222         public $shuffletype$ shuffleFromValues(int... ixs) {
1223             return new $shuffletype$(ixs);
1224         }
1225 
1226         @Override
1227         public $shuffletype$ shuffleFromArray(int[] ixs, int i) {
1228             return new $shuffletype$(ixs, i);
1229         }
1230 
1231         @Override
1232         public $shuffletype$ shuffleFromVector(Vector<Integer, Shapes.$shape$> v) {
1233             int[] a = ((IntVector<Shapes.$shape$>) v).toArray();
1234             return new $shuffletype$(a, 0);
1235         }
1236 
1237 #if[FP]
1238         @Override
1239         @ForceInline
1240         public $vectortype$ zero() {
1241             return VectorIntrinsics.broadcastCoerced($vectortype$.class, $type$.class, LENGTH,
1242                                                      $Type$.$type$To$Bitstype$Bits(0.0f),
1243                                                      (z -> ZERO));
1244         }
1245 
1246         @Override
1247         @ForceInline
1248         public $vectortype$ broadcast($type$ e) {
1249             return VectorIntrinsics.broadcastCoerced(
1250                 $vectortype$.class, $type$.class, LENGTH,
1251                 $Type$.$type$To$Bitstype$Bits(e),
1252                 ((long bits) -> SPECIES.op(i -> $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits))));
1253         }
1254 #end[FP]
1255 #if[BITWISE]
1256         @Override
1257         @ForceInline
1258         public $vectortype$ zero() {
1259             return VectorIntrinsics.broadcastCoerced($vectortype$.class, $type$.class, LENGTH,
1260                                                      0,
1261                                                      (z -> ZERO));
1262         }
1263 
1264         @Override
1265         @ForceInline
1266         public $vectortype$ broadcast($type$ e) {
1267             return VectorIntrinsics.broadcastCoerced(
1268                 $vectortype$.class, $type$.class, LENGTH,
1269                 e,
1270                 ((long bits) -> SPECIES.op(i -> ($type$)bits)));
1271         }
1272 #end[BITWISE]
1273 
1274         @Override
1275         @ForceInline
1276         public $masktype$ maskAllTrue() {
1277             return VectorIntrinsics.broadcastCoerced($masktype$.class, $bitstype$.class, LENGTH,
1278                                                      ($bitstype$)-1,
1279                                                      (z -> $masktype$.TRUE_MASK));
1280         }
1281 
1282         @Override
1283         @ForceInline
1284         public $masktype$ maskAllFalse() {
1285             return VectorIntrinsics.broadcastCoerced($masktype$.class, $bitstype$.class, LENGTH,
1286                                                      0,
1287                                                      (z -> $masktype$.FALSE_MASK));
1288         }
1289 
1290         @Override
1291         @ForceInline
1292         public $vectortype$ fromArray($type$[] a, int ix) {
1293             Objects.requireNonNull(a);
1294             ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
1295             return ($vectortype$) VectorIntrinsics.load($vectortype$.class, $type$.class, LENGTH,
1296                                                         a, ix,
1297                                                         (arr, idx) -> super.fromArray(($type$[]) arr, idx));
1298         }
1299 
1300         @Override
1301         @ForceInline
1302         public $vectortype$ fromArray($type$[] a, int ax, Mask<$Boxtype$, Shapes.$shape$> m) {
1303             return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]);
1304         }
1305 
1306         @ForceInline
1307         @SuppressWarnings("unchecked")
1308         private <S extends Shape> $vectortype$ castFromByte(ByteVector<S> o) {
1309             if (o.bitSize() == 64) {
1310                 Byte64Vector so = (Byte64Vector)o;
1311                 return VectorIntrinsics.cast(
1312                     Byte64Vector.class, byte.class, so.length(),
1313                     $type$.class, LENGTH, so,
1314                     (v, t) -> ($vectortype$)super.cast(v)
1315                 );
1316             } else if (o.bitSize() == 128) {
1317                 Byte128Vector so = (Byte128Vector)o;
1318                 return VectorIntrinsics.cast(
1319                     Byte128Vector.class, byte.class, so.length(),
1320                     $type$.class, LENGTH, so,
1321                     (v, t) -> ($vectortype$)super.cast(v)
1322                 );
1323             } else if (o.bitSize() == 256) {
1324                 Byte256Vector so = (Byte256Vector)o;
1325                 return VectorIntrinsics.cast(
1326                     Byte256Vector.class, byte.class, so.length(),
1327                     $type$.class, LENGTH, so,
1328                     (v, t) -> ($vectortype$)super.cast(v)
1329                 );
1330             } else if (o.bitSize() == 512) {
1331                 Byte512Vector so = (Byte512Vector)o;
1332                 return VectorIntrinsics.cast(
1333                     Byte512Vector.class, byte.class, so.length(),
1334                     $type$.class, LENGTH, so,
1335                     (v, t) -> ($vectortype$)super.cast(v)
1336                 );
1337             } else {
1338                 throw new InternalError("Unimplemented size");
1339             }
1340         }
1341 
1342         @ForceInline
1343         @SuppressWarnings("unchecked")
1344         private <S extends Shape> $vectortype$ castFromShort(ShortVector<S> o) {
1345             if (o.bitSize() == 64) {
1346                 Short64Vector so = (Short64Vector)o;
1347                 return VectorIntrinsics.cast(
1348                     Short64Vector.class, short.class, so.length(),
1349                     $type$.class, LENGTH, so,
1350                     (v, t) -> ($vectortype$)super.cast(v)
1351                 );
1352             } else if (o.bitSize() == 128) {
1353                 Short128Vector so = (Short128Vector)o;
1354                 return VectorIntrinsics.cast(
1355                     Short128Vector.class, short.class, so.length(),
1356                     $type$.class, LENGTH, so,
1357                     (v, t) -> ($vectortype$)super.cast(v)
1358                 );
1359             } else if (o.bitSize() == 256) {
1360                 Short256Vector so = (Short256Vector)o;
1361                 return VectorIntrinsics.cast(
1362                     Short256Vector.class, short.class, so.length(),
1363                     $type$.class, LENGTH, so,
1364                     (v, t) -> ($vectortype$)super.cast(v)
1365                 );
1366             } else if (o.bitSize() == 512) {
1367                 Short512Vector so = (Short512Vector)o;
1368                 return VectorIntrinsics.cast(
1369                     Short512Vector.class, short.class, so.length(),
1370                     $type$.class, LENGTH, so,
1371                     (v, t) -> ($vectortype$)super.cast(v)
1372                 );
1373             } else {
1374                 throw new InternalError("Unimplemented size");
1375             }
1376         }
1377 
1378         @ForceInline
1379         @SuppressWarnings("unchecked")
1380         private <S extends Shape> $vectortype$ castFromInt(IntVector<S> o) {
1381             if (o.bitSize() == 64) {
1382                 Int64Vector so = (Int64Vector)o;
1383                 return VectorIntrinsics.cast(
1384                     Int64Vector.class, int.class, so.length(),
1385                     $type$.class, LENGTH, so,
1386                     (v, t) -> ($vectortype$)super.cast(v)
1387                 );
1388             } else if (o.bitSize() == 128) {
1389                 Int128Vector so = (Int128Vector)o;
1390                 return VectorIntrinsics.cast(
1391                     Int128Vector.class, int.class, so.length(),
1392                     $type$.class, LENGTH, so,
1393                     (v, t) -> ($vectortype$)super.cast(v)
1394                 );
1395             } else if (o.bitSize() == 256) {
1396                 Int256Vector so = (Int256Vector)o;
1397                 return VectorIntrinsics.cast(
1398                     Int256Vector.class, int.class, so.length(),
1399                     $type$.class, LENGTH, so,
1400                     (v, t) -> ($vectortype$)super.cast(v)
1401                 );
1402             } else if (o.bitSize() == 512) {
1403                 Int512Vector so = (Int512Vector)o;
1404                 return VectorIntrinsics.cast(
1405                     Int512Vector.class, int.class, so.length(),
1406                     $type$.class, LENGTH, so,
1407                     (v, t) -> ($vectortype$)super.cast(v)
1408                 );
1409             } else {
1410                 throw new InternalError("Unimplemented size");
1411             }
1412         }
1413 
1414         @ForceInline
1415         @SuppressWarnings("unchecked")
1416         private <S extends Shape> $vectortype$ castFromLong(LongVector<S> o) {
1417             if (o.bitSize() == 64) {
1418                 Long64Vector so = (Long64Vector)o;
1419                 return VectorIntrinsics.cast(
1420                     Long64Vector.class, long.class, so.length(),
1421                     $type$.class, LENGTH, so,
1422                     (v, t) -> ($vectortype$)super.cast(v)
1423                 );
1424             } else if (o.bitSize() == 128) {
1425                 Long128Vector so = (Long128Vector)o;
1426                 return VectorIntrinsics.cast(
1427                     Long128Vector.class, long.class, so.length(),
1428                     $type$.class, LENGTH, so,
1429                     (v, t) -> ($vectortype$)super.cast(v)
1430                 );
1431             } else if (o.bitSize() == 256) {
1432                 Long256Vector so = (Long256Vector)o;
1433                 return VectorIntrinsics.cast(
1434                     Long256Vector.class, long.class, so.length(),
1435                     $type$.class, LENGTH, so,
1436                     (v, t) -> ($vectortype$)super.cast(v)
1437                 );
1438             } else if (o.bitSize() == 512) {
1439                 Long512Vector so = (Long512Vector)o;
1440                 return VectorIntrinsics.cast(
1441                     Long512Vector.class, long.class, so.length(),
1442                     $type$.class, LENGTH, so,
1443                     (v, t) -> ($vectortype$)super.cast(v)
1444                 );
1445             } else {
1446                 throw new InternalError("Unimplemented size");
1447             }
1448         }
1449 
1450         @ForceInline
1451         @SuppressWarnings("unchecked")
1452         private <S extends Shape> $vectortype$ castFromFloat(FloatVector<S> o) {
1453             if (o.bitSize() == 64) {
1454                 Float64Vector so = (Float64Vector)o;
1455                 return VectorIntrinsics.cast(
1456                     Float64Vector.class, float.class, so.length(),
1457                     $type$.class, LENGTH, so,
1458                     (v, t) -> ($vectortype$)super.cast(v)
1459                 );
1460             } else if (o.bitSize() == 128) {
1461                 Float128Vector so = (Float128Vector)o;
1462                 return VectorIntrinsics.cast(
1463                     Float128Vector.class, float.class, so.length(),
1464                     $type$.class, LENGTH, so,
1465                     (v, t) -> ($vectortype$)super.cast(v)
1466                 );
1467             } else if (o.bitSize() == 256) {
1468                 Float256Vector so = (Float256Vector)o;
1469                 return VectorIntrinsics.cast(
1470                     Float256Vector.class, float.class, so.length(),
1471                     $type$.class, LENGTH, so,
1472                     (v, t) -> ($vectortype$)super.cast(v)
1473                 );
1474             } else if (o.bitSize() == 512) {
1475                 Float512Vector so = (Float512Vector)o;
1476                 return VectorIntrinsics.cast(
1477                     Float512Vector.class, float.class, so.length(),
1478                     $type$.class, LENGTH, so,
1479                     (v, t) -> ($vectortype$)super.cast(v)
1480                 );
1481             } else {
1482                 throw new InternalError("Unimplemented size");
1483             }
1484         }
1485 
1486         @ForceInline
1487         @SuppressWarnings("unchecked")
1488         private <S extends Shape> $vectortype$ castFromDouble(DoubleVector<S> o) {
1489             if (o.bitSize() == 64) {
1490                 Double64Vector so = (Double64Vector)o;
1491                 return VectorIntrinsics.cast(
1492                     Double64Vector.class, double.class, so.length(),
1493                     $type$.class, LENGTH, so,
1494                     (v, t) -> ($vectortype$)super.cast(v)
1495                 );
1496             } else if (o.bitSize() == 128) {
1497                 Double128Vector so = (Double128Vector)o;
1498                 return VectorIntrinsics.cast(
1499                     Double128Vector.class, double.class, so.length(),
1500                     $type$.class, LENGTH, so,
1501                     (v, t) -> ($vectortype$)super.cast(v)
1502                 );
1503             } else if (o.bitSize() == 256) {
1504                 Double256Vector so = (Double256Vector)o;
1505                 return VectorIntrinsics.cast(
1506                     Double256Vector.class, double.class, so.length(),
1507                     $type$.class, LENGTH, so,
1508                     (v, t) -> ($vectortype$)super.cast(v)
1509                 );
1510             } else if (o.bitSize() == 512) {
1511                 Double512Vector so = (Double512Vector)o;
1512                 return VectorIntrinsics.cast(
1513                     Double512Vector.class, double.class, so.length(),
1514                     $type$.class, LENGTH, so,
1515                     (v, t) -> ($vectortype$)super.cast(v)
1516                 );
1517             } else {
1518                 throw new InternalError("Unimplemented size");
1519             }
1520         }
1521 
1522         @Override
1523         @ForceInline
1524         @SuppressWarnings("unchecked")
1525         public <E, S extends Shape> $vectortype$ cast(Vector<E, S> o) {
1526             Objects.requireNonNull(o);
1527             if (o.elementType() == byte.class) {
1528                 ByteVector<S> so = (ByteVector<S>)o;
1529                 return castFromByte(so);
1530             } else if (o.elementType() == short.class) {
1531                 ShortVector<S> so = (ShortVector<S>)o;
1532                 return castFromShort(so);
1533             } else if (o.elementType() == int.class) {
1534                 IntVector<S> so = (IntVector<S>)o;
1535                 return castFromInt(so);
1536             } else if (o.elementType() == long.class) {
1537                 LongVector<S> so = (LongVector<S>)o;
1538                 return castFromLong(so);
1539             } else if (o.elementType() == float.class) {
1540                 FloatVector<S> so = (FloatVector<S>)o;
1541                 return castFromFloat(so);
1542             } else if (o.elementType() == double.class) {
1543                 DoubleVector<S> so = (DoubleVector<S>)o;
1544                 return castFromDouble(so);
1545             } else {
1546                 throw new InternalError("Unimplemented type");
1547             }
1548         }
1549 
1550         @Override
1551         @ForceInline
1552         @SuppressWarnings("unchecked")
1553         public <F> $vectortype$ rebracket(Vector<F, Shapes.$shape$> o) {
1554             Objects.requireNonNull(o);
1555             if (o.elementType() == byte.class) {
1556                 Byte$bits$Vector so = (Byte$bits$Vector)o;
1557                 return VectorIntrinsics.reinterpret(
1558                     Byte$bits$Vector.class, byte.class, so.length(),
1559                     $type$.class, LENGTH, so,
1560                     (v, t) -> ($vectortype$)reshape(v)
1561                 );
1562             } else if (o.elementType() == short.class) {
1563                 Short$bits$Vector so = (Short$bits$Vector)o;
1564                 return VectorIntrinsics.reinterpret(
1565                     Short$bits$Vector.class, short.class, so.length(),
1566                     $type$.class, LENGTH, so,
1567                     (v, t) -> ($vectortype$)reshape(v)
1568                 );
1569             } else if (o.elementType() == int.class) {
1570                 Int$bits$Vector so = (Int$bits$Vector)o;
1571                 return VectorIntrinsics.reinterpret(
1572                     Int$bits$Vector.class, int.class, so.length(),
1573                     $type$.class, LENGTH, so,
1574                     (v, t) -> ($vectortype$)reshape(v)
1575                 );
1576             } else if (o.elementType() == long.class) {
1577                 Long$bits$Vector so = (Long$bits$Vector)o;
1578                 return VectorIntrinsics.reinterpret(
1579                     Long$bits$Vector.class, long.class, so.length(),
1580                     $type$.class, LENGTH, so,
1581                     (v, t) -> ($vectortype$)reshape(v)
1582                 );
1583             } else if (o.elementType() == float.class) {
1584                 Float$bits$Vector so = (Float$bits$Vector)o;
1585                 return VectorIntrinsics.reinterpret(
1586                     Float$bits$Vector.class, float.class, so.length(),
1587                     $type$.class, LENGTH, so,
1588                     (v, t) -> ($vectortype$)reshape(v)
1589                 );
1590             } else if (o.elementType() == double.class) {
1591                 Double$bits$Vector so = (Double$bits$Vector)o;
1592                 return VectorIntrinsics.reinterpret(
1593                     Double$bits$Vector.class, double.class, so.length(),
1594                     $type$.class, LENGTH, so,
1595                     (v, t) -> ($vectortype$)reshape(v)
1596                 );
1597             } else {
1598                 throw new InternalError("Unimplemented type");
1599             }
1600         }
1601 
1602         @Override
1603         @ForceInline
1604         @SuppressWarnings("unchecked")
1605         public <T extends Shape> $vectortype$ resize(Vector<$Boxtype$, T> o) {
1606             Objects.requireNonNull(o);
1607             if (o.bitSize() == 64) {
1608                 $Type$64Vector so = ($Type$64Vector)o;
1609                 return VectorIntrinsics.reinterpret(
1610                     $Type$64Vector.class, $type$.class, so.length(),
1611                     $type$.class, LENGTH, so,
1612                     (v, t) -> ($vectortype$)reshape(v)
1613                 );
1614             } else if (o.bitSize() == 128) {
1615                 $Type$128Vector so = ($Type$128Vector)o;
1616                 return VectorIntrinsics.reinterpret(
1617                     $Type$128Vector.class, $type$.class, so.length(),
1618                     $type$.class, LENGTH, so,
1619                     (v, t) -> ($vectortype$)reshape(v)
1620                 );
1621             } else if (o.bitSize() == 256) {
1622                 $Type$256Vector so = ($Type$256Vector)o;
1623                 return VectorIntrinsics.reinterpret(
1624                     $Type$256Vector.class, $type$.class, so.length(),
1625                     $type$.class, LENGTH, so,
1626                     (v, t) -> ($vectortype$)reshape(v)
1627                 );
1628             } else if (o.bitSize() == 512) {
1629                 $Type$512Vector so = ($Type$512Vector)o;
1630                 return VectorIntrinsics.reinterpret(
1631                     $Type$512Vector.class, $type$.class, so.length(),
1632                     $type$.class, LENGTH, so,
1633                     (v, t) -> ($vectortype$)reshape(v)
1634                 );
1635             } else {
1636                 throw new InternalError("Unimplemented size");
1637             }
1638         }
1639     }
1640 }