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 jdk.internal.vm.annotation.ForceInline;
  28 
  29 import java.nio.ByteBuffer;
  30 import java.nio.ByteOrder;
  31 #if[!byte]
  32 import java.nio.$Type$Buffer;
  33 #end[!byte]
  34 import java.util.concurrent.ThreadLocalRandom;
  35 
  36 @SuppressWarnings("cast")
  37 public abstract class $abstractvectortype$<S extends Vector.Shape> extends Vector<$Boxtype$,S> {
  38 
  39     $abstractvectortype$() {}
  40 
  41     // Unary operator
  42 
  43     interface FUnOp {
  44         $type$ apply(int i, $type$ a);
  45     }
  46 
  47     abstract $abstractvectortype$<S> uOp(FUnOp f);
  48 
  49     abstract $abstractvectortype$<S> uOp(Mask<$Boxtype$, S> m, FUnOp f);
  50 
  51     // Binary operator
  52 
  53     interface FBinOp {
  54         $type$ apply(int i, $type$ a, $type$ b);
  55     }
  56 
  57     abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> o, FBinOp f);
  58 
  59     abstract $abstractvectortype$<S> bOp(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m, FBinOp f);
  60 
  61     // Trinary operator
  62 
  63     interface FTriOp {
  64         $type$ apply(int i, $type$ a, $type$ b, $type$ c);
  65     }
  66 
  67     abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, FTriOp f);
  68 
  69     abstract $abstractvectortype$<S> tOp(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, Mask<$Boxtype$, S> m, FTriOp f);
  70 
  71     // Reduction operator
  72 
  73     abstract $type$ rOp($type$ v, FBinOp f);
  74 
  75     // Binary test
  76 
  77     interface FBinTest {
  78         boolean apply(int i, $type$ a, $type$ b);
  79     }
  80 
  81     abstract Mask<$Boxtype$, S> bTest(Vector<$Boxtype$,S> o, FBinTest f);
  82 
  83     // Foreach
  84 
  85     interface FUnCon {
  86         void apply(int i, $type$ a);
  87     }
  88 
  89     abstract void forEach(FUnCon f);
  90 
  91     abstract void forEach(Mask<$Boxtype$, S> m, FUnCon f);
  92 
  93     //
  94 
  95     @Override
  96     public $abstractvectortype$<S> add(Vector<$Boxtype$,S> o) {
  97         return bOp(o, (i, a, b) -> ($type$) (a + b));
  98     }
  99 
 100     public abstract $abstractvectortype$<S> add($type$ o);
 101 
 102     @Override
 103     public $abstractvectortype$<S> add(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 104         return bOp(o, m, (i, a, b) -> ($type$) (a + b));
 105     }
 106 
 107     public abstract $abstractvectortype$<S> add($type$ o, Mask<$Boxtype$, S> m);
 108 
 109     @Override
 110     public $abstractvectortype$<S> addSaturate(Vector<$Boxtype$,S> o) {
 111         return bOp(o, (i, a, b) -> ($type$) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b));
 112     }
 113 
 114     public abstract $abstractvectortype$<S> addSaturate($type$ o);
 115 
 116     @Override
 117     public $abstractvectortype$<S> addSaturate(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 118         return bOp(o, m, (i, a, b) -> ($type$) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b));
 119     }
 120 
 121     public abstract $abstractvectortype$<S> addSaturate($type$ o, Mask<$Boxtype$, S> m);
 122 
 123     @Override
 124     public $abstractvectortype$<S> sub(Vector<$Boxtype$,S> o) {
 125         return bOp(o, (i, a, b) -> ($type$) (a - b));
 126     }
 127 
 128     public abstract $abstractvectortype$<S> sub($type$ o);
 129 
 130     @Override
 131     public $abstractvectortype$<S> sub(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 132         return bOp(o, m, (i, a, b) -> ($type$) (a - b));
 133     }
 134 
 135     public abstract $abstractvectortype$<S> sub($type$ o, Mask<$Boxtype$, S> m);
 136 
 137     @Override
 138     public $abstractvectortype$<S> subSaturate(Vector<$Boxtype$,S> o) {
 139         return bOp(o, (i, a, b) -> ($type$) ((a >= $Wideboxtype$.MIN_VALUE || $Wideboxtype$.MIN_VALUE + b > a) ? $Wideboxtype$.MAX_VALUE : a - b));
 140     }
 141 
 142     public abstract $abstractvectortype$<S> subSaturate($type$ o);
 143 
 144     @Override
 145     public $abstractvectortype$<S> subSaturate(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 146         return bOp(o, m, (i, a, b) -> ($type$) ((a >= $Wideboxtype$.MIN_VALUE || $Wideboxtype$.MIN_VALUE + b > a) ? $Wideboxtype$.MAX_VALUE : a - b));
 147     }
 148 
 149     public abstract $abstractvectortype$<S> subSaturate($type$ o, Mask<$Boxtype$, S> m);
 150 
 151     @Override
 152     public $abstractvectortype$<S> mul(Vector<$Boxtype$,S> o) {
 153         return bOp(o, (i, a, b) -> ($type$) (a * b));
 154     }
 155 
 156     public abstract $abstractvectortype$<S> mul($type$ o);
 157 
 158     @Override
 159     public $abstractvectortype$<S> mul(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 160         return bOp(o, m, (i, a, b) -> ($type$) (a * b));
 161     }
 162 
 163     public abstract $abstractvectortype$<S> mul($type$ o, Mask<$Boxtype$, S> m);
 164 
 165     @Override
 166     public $abstractvectortype$<S> neg() {
 167         return uOp((i, a) -> ($type$) (-a));
 168     }
 169 
 170     @Override
 171     public $abstractvectortype$<S> neg(Mask<$Boxtype$, S> m) {
 172         return uOp(m, (i, a) -> ($type$) (-a));
 173     }
 174 
 175     @Override
 176     public $abstractvectortype$<S> abs() {
 177         return uOp((i, a) -> ($type$) Math.abs(a));
 178     }
 179 
 180     @Override
 181     public $abstractvectortype$<S> abs(Mask<$Boxtype$, S> m) {
 182         return uOp(m, (i, a) -> ($type$) Math.abs(a));
 183     }
 184 
 185     @Override
 186     public $abstractvectortype$<S> min(Vector<$Boxtype$,S> o) {
 187         return bOp(o, (i, a, b) -> (a <= b) ? a : b);
 188     }
 189 
 190     public abstract $abstractvectortype$<S> min($type$ o);
 191 
 192     @Override
 193     public $abstractvectortype$<S> max(Vector<$Boxtype$,S> o) {
 194         return bOp(o, (i, a, b) -> (a >= b) ? a : b);
 195     }
 196 
 197     public abstract $abstractvectortype$<S> max($type$ o);
 198 
 199     @Override
 200     public Mask<$Boxtype$, S> equal(Vector<$Boxtype$,S> o) {
 201         return bTest(o, (i, a, b) -> a == b);
 202     }
 203 
 204     public abstract Mask<$Boxtype$, S> equal($type$ o);
 205 
 206     @Override
 207     public Mask<$Boxtype$, S> notEqual(Vector<$Boxtype$,S> o) {
 208         return bTest(o, (i, a, b) -> a != b);
 209     }
 210 
 211     public abstract Mask<$Boxtype$, S> notEqual($type$ o);
 212 
 213     @Override
 214     public Mask<$Boxtype$, S> lessThan(Vector<$Boxtype$,S> o) {
 215         return bTest(o, (i, a, b) -> a < b);
 216     }
 217 
 218     public abstract Mask<$Boxtype$, S> lessThan($type$ o);
 219 
 220     @Override
 221     public Mask<$Boxtype$, S> lessThanEq(Vector<$Boxtype$,S> o) {
 222         return bTest(o, (i, a, b) -> a <= b);
 223     }
 224 
 225     public abstract Mask<$Boxtype$, S> lessThanEq($type$ o);
 226 
 227     @Override
 228     public Mask<$Boxtype$, S> greaterThan(Vector<$Boxtype$,S> o) {
 229         return bTest(o, (i, a, b) -> a > b);
 230     }
 231 
 232     public abstract Mask<$Boxtype$, S> greaterThan($type$ o);
 233 
 234     @Override
 235     public Mask<$Boxtype$, S> greaterThanEq(Vector<$Boxtype$,S> o) {
 236         return bTest(o, (i, a, b) -> a >= b);
 237     }
 238 
 239     public abstract Mask<$Boxtype$, S> greaterThanEq($type$ o);
 240 
 241     @Override
 242     public $abstractvectortype$<S> blend(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 243         return bOp(o, (i, a, b) -> m.getElement(i) ? b : a);
 244     }
 245 
 246     public abstract $abstractvectortype$<S> blend($type$ o, Mask<$Boxtype$, S> m);
 247 
 248     @Override
 249     public abstract $abstractvectortype$<S> shuffle(Vector<$Boxtype$,S> o, Shuffle<$Boxtype$, S> m);
 250 
 251     @Override
 252     public abstract $abstractvectortype$<S> swizzle(Shuffle<$Boxtype$, S> m);
 253 
 254     @Override
 255     @ForceInline
 256     public <T extends Shape> $abstractvectortype$<T> resize(Species<$Boxtype$, T> species) {
 257         return ($abstractvectortype$<T>) species.resize(this);
 258     }
 259 
 260     @Override
 261     public abstract $abstractvectortype$<S> rotateEL(int i);
 262 
 263     @Override
 264     public abstract $abstractvectortype$<S> rotateER(int i);
 265 
 266     @Override
 267     public abstract $abstractvectortype$<S> shiftEL(int i);
 268 
 269     @Override
 270     public abstract $abstractvectortype$<S> shiftER(int i);
 271 
 272 #if[FP]
 273     public $abstractvectortype$<S> div(Vector<$Boxtype$,S> o) {
 274         return bOp(o, (i, a, b) -> ($type$) (a / b));
 275     }
 276 
 277     public abstract $abstractvectortype$<S> div($type$ o);
 278 
 279     public $abstractvectortype$<S> div(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 280         return bOp(o, m, (i, a, b) -> ($type$) (a / b));
 281     }
 282 
 283     public abstract $abstractvectortype$<S> div($type$ o, Mask<$Boxtype$, S> m);
 284 
 285     public $abstractvectortype$<S> sqrt() {
 286         return uOp((i, a) -> ($type$) Math.sqrt((double) a));
 287     }
 288 
 289     public $abstractvectortype$<S> sqrt(Mask<$Boxtype$,S> m) {
 290         return uOp(m, (i, a) -> ($type$) Math.sqrt((double) a));
 291     }
 292 
 293     public $abstractvectortype$<S> tan() {
 294         return uOp((i, a) -> ($type$) Math.tan((double) a));
 295     }
 296 
 297     public $abstractvectortype$<S> tan(Mask<$Boxtype$,S> m) {
 298         return uOp(m, (i, a) -> ($type$) Math.tan((double) a));
 299     }
 300 
 301     public $abstractvectortype$<S> tanh() {
 302         return uOp((i, a) -> ($type$) Math.tanh((double) a));
 303     }
 304 
 305     public $abstractvectortype$<S> tanh(Mask<$Boxtype$,S> m) {
 306         return uOp(m, (i, a) -> ($type$) Math.tanh((double) a));
 307     }
 308 
 309     public $abstractvectortype$<S> sin() {
 310         return uOp((i, a) -> ($type$) Math.sin((double) a));
 311     }
 312 
 313     public $abstractvectortype$<S> sin(Mask<$Boxtype$,S> m) {
 314         return uOp(m, (i, a) -> ($type$) Math.sin((double) a));
 315     }
 316 
 317     public $abstractvectortype$<S> sinh() {
 318         return uOp((i, a) -> ($type$) Math.sinh((double) a));
 319     }
 320 
 321     public $abstractvectortype$<S> sinh(Mask<$Boxtype$,S> m) {
 322         return uOp(m, (i, a) -> ($type$) Math.sinh((double) a));
 323     }
 324 
 325     public $abstractvectortype$<S> cos() {
 326         return uOp((i, a) -> ($type$) Math.cos((double) a));
 327     }
 328 
 329     public $abstractvectortype$<S> cos(Mask<$Boxtype$,S> m) {
 330         return uOp(m, (i, a) -> ($type$) Math.cos((double) a));
 331     }
 332 
 333     public $abstractvectortype$<S> cosh() {
 334         return uOp((i, a) -> ($type$) Math.cosh((double) a));
 335     }
 336 
 337     public $abstractvectortype$<S> cosh(Mask<$Boxtype$,S> m) {
 338         return uOp(m, (i, a) -> ($type$) Math.cosh((double) a));
 339     }
 340 
 341     public $abstractvectortype$<S> asin() {
 342         return uOp((i, a) -> ($type$) Math.asin((double) a));
 343     }
 344 
 345     public $abstractvectortype$<S> asin(Mask<$Boxtype$,S> m) {
 346         return uOp(m, (i, a) -> ($type$) Math.asin((double) a));
 347     }
 348 
 349     public $abstractvectortype$<S> acos() {
 350         return uOp((i, a) -> ($type$) Math.acos((double) a));
 351     }
 352 
 353     public $abstractvectortype$<S> acos(Mask<$Boxtype$,S> m) {
 354         return uOp(m, (i, a) -> ($type$) Math.acos((double) a));
 355     }
 356 
 357     public $abstractvectortype$<S> atan() {
 358         return uOp((i, a) -> ($type$) Math.atan((double) a));
 359     }
 360 
 361     public $abstractvectortype$<S> atan(Mask<$Boxtype$,S> m) {
 362         return uOp(m, (i, a) -> ($type$) Math.atan((double) a));
 363     }
 364 
 365     public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> o) {
 366         return bOp(o, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b));
 367     }
 368 
 369     public abstract $abstractvectortype$<S> atan2($type$ o);
 370 
 371     public $abstractvectortype$<S> atan2(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) {
 372         return bOp(o, m, (i, a, b) -> ($type$) Math.atan2((double) a, (double) b));
 373     }
 374 
 375     public abstract $abstractvectortype$<S> atan2($type$ o, Mask<$Boxtype$,S> m);
 376 
 377     public $abstractvectortype$<S> cbrt() {
 378         return uOp((i, a) -> ($type$) Math.cbrt((double) a));
 379     }
 380 
 381     public $abstractvectortype$<S> cbrt(Mask<$Boxtype$,S> m) {
 382         return uOp(m, (i, a) -> ($type$) Math.cbrt((double) a));
 383     }
 384 
 385     public $abstractvectortype$<S> log() {
 386         return uOp((i, a) -> ($type$) Math.log((double) a));
 387     }
 388 
 389     public $abstractvectortype$<S> log(Mask<$Boxtype$,S> m) {
 390         return uOp(m, (i, a) -> ($type$) Math.log((double) a));
 391     }
 392 
 393     public $abstractvectortype$<S> log10() {
 394         return uOp((i, a) -> ($type$) Math.log10((double) a));
 395     }
 396 
 397     public $abstractvectortype$<S> log10(Mask<$Boxtype$,S> m) {
 398         return uOp(m, (i, a) -> ($type$) Math.log10((double) a));
 399     }
 400 
 401     public $abstractvectortype$<S> log1p() {
 402         return uOp((i, a) -> ($type$) Math.log1p((double) a));
 403     }
 404 
 405     public $abstractvectortype$<S> log1p(Mask<$Boxtype$,S> m) {
 406         return uOp(m, (i, a) -> ($type$) Math.log1p((double) a));
 407     }
 408 
 409     public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> o) {
 410         return bOp(o, (i, a, b) -> ($type$) Math.pow((double) a, (double) b));
 411     }
 412 
 413     public abstract $abstractvectortype$<S> pow($type$ o);
 414 
 415     public $abstractvectortype$<S> pow(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) {
 416         return bOp(o, m, (i, a, b) -> ($type$) Math.pow((double) a, (double) b));
 417     }
 418 
 419     public abstract $abstractvectortype$<S> pow($type$ o, Mask<$Boxtype$,S> m);
 420 
 421     public $abstractvectortype$<S> exp() {
 422         return uOp((i, a) -> ($type$) Math.exp((double) a));
 423     }
 424 
 425     public $abstractvectortype$<S> exp(Mask<$Boxtype$,S> m) {
 426         return uOp(m, (i, a) -> ($type$) Math.exp((double) a));
 427     }
 428 
 429     public $abstractvectortype$<S> expm1() {
 430         return uOp((i, a) -> ($type$) Math.expm1((double) a));
 431     }
 432 
 433     public $abstractvectortype$<S> expm1(Mask<$Boxtype$,S> m) {
 434         return uOp(m, (i, a) -> ($type$) Math.expm1((double) a));
 435     }
 436 
 437     public $abstractvectortype$<S> fma(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2) {
 438         return tOp(o1, o2, (i, a, b, c) -> Math.fma(a, b, c));
 439     }
 440 
 441     public abstract $abstractvectortype$<S> fma($type$ o1, $type$ o2);
 442 
 443     public $abstractvectortype$<S> fma(Vector<$Boxtype$,S> o1, Vector<$Boxtype$,S> o2, Mask<$Boxtype$,S> m) {
 444         return tOp(o1, o2, m, (i, a, b, c) -> Math.fma(a, b, c));
 445     }
 446 
 447     public abstract $abstractvectortype$<S> fma($type$ o1, $type$ o2, Mask<$Boxtype$,S> m);
 448 
 449     public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> o) {
 450         return bOp(o, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b));
 451     }
 452 
 453     public abstract $abstractvectortype$<S> hypot($type$ o);
 454 
 455     public $abstractvectortype$<S> hypot(Vector<$Boxtype$,S> o, Mask<$Boxtype$,S> m) {
 456         return bOp(o, m, (i, a, b) -> ($type$) Math.hypot((double) a, (double) b));
 457     }
 458 
 459     public abstract $abstractvectortype$<S> hypot($type$ o, Mask<$Boxtype$,S> m);
 460 #end[FP]
 461 
 462 #if[BITWISE]
 463     public $abstractvectortype$<S> and(Vector<$Boxtype$,S> o) {
 464         return bOp(o, (i, a, b) -> ($type$) (a & b));
 465     }
 466 
 467     public abstract $abstractvectortype$<S> and($type$ o);
 468 
 469     public $abstractvectortype$<S> and(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 470         return bOp(o, m, (i, a, b) -> ($type$) (a & b));
 471     }
 472 
 473     public abstract $abstractvectortype$<S> and($type$ o, Mask<$Boxtype$, S> m);
 474 
 475     public $abstractvectortype$<S> or(Vector<$Boxtype$,S> o) {
 476         return bOp(o, (i, a, b) -> ($type$) (a | b));
 477     }
 478 
 479     public abstract $abstractvectortype$<S> or($type$ o);
 480 
 481     public $abstractvectortype$<S> or(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 482         return bOp(o, m, (i, a, b) -> ($type$) (a | b));
 483     }
 484 
 485     public abstract $abstractvectortype$<S> or($type$ o, Mask<$Boxtype$, S> m);
 486 
 487     public $abstractvectortype$<S> xor(Vector<$Boxtype$,S> o) {
 488         return bOp(o, (i, a, b) -> ($type$) (a ^ b));
 489     }
 490 
 491     public abstract $abstractvectortype$<S> xor($type$ o);
 492 
 493     public $abstractvectortype$<S> xor(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 494         return bOp(o, m, (i, a, b) -> ($type$) (a ^ b));
 495     }
 496 
 497     public abstract $abstractvectortype$<S> xor($type$ o, Mask<$Boxtype$, S> m);
 498 
 499     public $abstractvectortype$<S> not() {
 500         return uOp((i, a) -> ($type$) (~a));
 501     }
 502 
 503     public $abstractvectortype$<S> not(Mask<$Boxtype$, S> m) {
 504         return uOp(m, (i, a) -> ($type$) (~a));
 505     }
 506 
 507     // logical shift left
 508     public $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> o) {
 509         return bOp(o, (i, a, b) -> ($type$) (a << b));
 510     }
 511 
 512     public $abstractvectortype$<S> shiftL(int s) {
 513         return uOp((i, a) -> ($type$) (a << s));
 514     }
 515 
 516     public $abstractvectortype$<S> shiftL(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 517         return bOp(o, m, (i, a, b) -> ($type$) (a << b));
 518     }
 519 
 520     public $abstractvectortype$<S> shiftL(int s, Mask<$Boxtype$, S> m) {
 521         return uOp(m, (i, a) -> ($type$) (a << s));
 522     }
 523 
 524     // logical, or unsigned, shift right
 525     public $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> o) {
 526         return bOp(o, (i, a, b) -> ($type$) (a >>> b));
 527     }
 528 
 529     public $abstractvectortype$<S> shiftR(int s) {
 530         return uOp((i, a) -> ($type$) (a >>> s));
 531     }
 532 
 533     public $abstractvectortype$<S> shiftR(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 534         return bOp(o, m, (i, a, b) -> ($type$) (a >>> b));
 535     }
 536 
 537     public $abstractvectortype$<S> shiftR(int s, Mask<$Boxtype$, S> m) {
 538         return uOp(m, (i, a) -> ($type$) (a >>> s));
 539     }
 540 
 541     // arithmetic, or signed, shift right
 542     public $abstractvectortype$<S> ashiftR(Vector<$Boxtype$,S> o) {
 543         return bOp(o, (i, a, b) -> ($type$) (a >> b));
 544     }
 545 
 546     public $abstractvectortype$<S> aShiftR(int s) {
 547         return uOp((i, a) -> ($type$) (a >> s));
 548     }
 549 
 550     public $abstractvectortype$<S> ashiftR(Vector<$Boxtype$,S> o, Mask<$Boxtype$, S> m) {
 551         return bOp(o, m, (i, a, b) -> ($type$) (a >> b));
 552     }
 553 
 554     public $abstractvectortype$<S> aShiftR(int s, Mask<$Boxtype$, S> m) {
 555         return uOp(m, (i, a) -> ($type$) (a >> s));
 556     }
 557 
 558     public $abstractvectortype$<S> rotateL(int j) {
 559         return uOp((i, a) -> ($type$) $Wideboxtype$.rotateLeft(a, j));
 560     }
 561 
 562     public $abstractvectortype$<S> rotateR(int j) {
 563         return uOp((i, a) -> ($type$) $Wideboxtype$.rotateRight(a, j));
 564     }
 565 #end[BITWISE]
 566 
 567     @Override
 568     public void intoByteArray(byte[] a, int ix) {
 569         ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 570         intoByteBuffer(bb);
 571     }
 572 
 573     @Override
 574     public void intoByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m) {
 575         ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 576         intoByteBuffer(bb, m);
 577     }
 578 
 579     @Override
 580     public void intoByteBuffer(ByteBuffer bb) {
 581         $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 582         forEach((i, a) -> fb.put(a));
 583     }
 584 
 585     @Override
 586     public void intoByteBuffer(ByteBuffer bb, Mask<$Boxtype$, S> m) {
 587         $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 588         forEach((i, a) -> {
 589             if (m.getElement(i))
 590                 fb.put(a);
 591             else
 592                 fb.position(fb.position() + 1);
 593         });
 594     }
 595 
 596     @Override
 597     public void intoByteBuffer(ByteBuffer bb, int ix) {
 598         bb = bb.duplicate().position(ix);
 599         $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 600         forEach((i, a) -> fb.put(i, a));
 601     }
 602 
 603     @Override
 604     public void intoByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m) {
 605         bb = bb.duplicate().position(ix);
 606         $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 607         forEach(m, (i, a) -> fb.put(i, a));
 608     }
 609 
 610 
 611     // Type specific horizontal reductions
 612 
 613     public $type$ addAll() {
 614         return rOp(($type$) 0, (i, a, b) -> ($type$) (a + b));
 615     }
 616 
 617     public $type$ subAll() {
 618         return rOp(($type$) 0, (i, a, b) -> ($type$) (a - b));
 619     }
 620 
 621     public $type$ mulAll() {
 622         return rOp(($type$) 1, (i, a, b) -> ($type$) (a * b));
 623     }
 624 
 625     public $type$ minAll() {
 626         return rOp($Boxtype$.MAX_VALUE, (i, a, b) -> a > b ? b : a);
 627     }
 628 
 629     public $type$ maxAll() {
 630         return rOp($Boxtype$.MIN_VALUE, (i, a, b) -> a < b ? b : a);
 631     }
 632 
 633 #if[BITWISE]
 634     public $type$ orAll() {
 635         return rOp(($type$) 0, (i, a, b) -> ($type$) (a | b));
 636     }
 637 
 638     public $type$ andAll() {
 639         return rOp(($type$) -1, (i, a, b) -> ($type$) (a & b));
 640     }
 641 
 642     public $type$ xorAll() {
 643         return rOp(($type$) 0, (i, a, b) -> ($type$) (a ^ b));
 644     }
 645 #end[BITWISE]
 646 
 647     // Type specific accessors
 648 
 649     public abstract $type$ get(int i);
 650 
 651     public abstract $abstractvectortype$<S> with(int i, $type$ e);
 652 
 653     // Type specific extractors
 654 
 655     @ForceInline
 656     public $type$[] toArray() {
 657         $type$[] a = new $type$[species().length()];
 658         intoArray(a, 0);
 659         return a;
 660     }
 661 
 662     public void intoArray($type$[] a, int ax) {
 663         forEach((i, a_) -> a[ax + i] = a_);
 664     }
 665 
 666     public void intoArray($type$[] a, int ax, Mask<$Boxtype$, S> m) {
 667         forEach(m, (i, a_) -> a[ax + i] = a_);
 668     }
 669 
 670     public void intoArray($type$[] a, int ax, int[] indexMap, int mx) {
 671         forEach((i, a_) -> a[ax + indexMap[mx + i]] = a_);
 672     }
 673 
 674     public void intoArray($type$[] a, int ax, Mask<$Boxtype$, S> m, int[] indexMap, int mx) {
 675         forEach(m, (i, a_) -> a[ax + indexMap[mx + i]] = a_);
 676     }
 677 
 678     // Species
 679 
 680     @Override
 681     public abstract $Type$Species<S> species();
 682 
 683     public static abstract class $Type$Species<S extends Vector.Shape> extends Vector.Species<$Boxtype$, S> {
 684         interface FOp {
 685             $type$ apply(int i);
 686         }
 687 
 688         abstract $abstractvectortype$<S> op(FOp f);
 689 
 690         abstract $abstractvectortype$<S> op(Mask<$Boxtype$, S> m, FOp f);
 691 
 692         // Factories
 693 
 694         @Override
 695         public $abstractvectortype$<S> zero() {
 696             return op(i -> 0);
 697         }
 698 
 699         public $abstractvectortype$<S> broadcast($type$ e) {
 700             return op(i -> e);
 701         }
 702 
 703         public $abstractvectortype$<S> single($type$ e) {
 704             return op(i -> i == 0 ? e : ($type$) 0);
 705         }
 706 
 707 #if[intOrLong]
 708         public $abstractvectortype$<S> random() {
 709             ThreadLocalRandom r = ThreadLocalRandom.current();
 710             return op(i -> r.next$Type$());
 711         }
 712 #else[intOrLong]
 713 #if[FP]
 714         public $abstractvectortype$<S> random() {
 715             ThreadLocalRandom r = ThreadLocalRandom.current();
 716             return op(i -> r.next$Type$());
 717         }
 718 #else[FP]
 719         public $abstractvectortype$<S> random() {
 720             ThreadLocalRandom r = ThreadLocalRandom.current();
 721             return op(i -> ($type$) r.nextInt());
 722         }
 723 #end[FP]
 724 #end[intOrLong]
 725 
 726         public $abstractvectortype$<S> scalars($type$... es) {
 727             return op(i -> es[i]);
 728         }
 729 
 730         public $abstractvectortype$<S> fromArray($type$[] a, int ax) {
 731             return op(i -> a[ax + i]);
 732         }
 733 
 734         public $abstractvectortype$<S> fromArray($type$[] a, int ax, Mask<$Boxtype$, S> m) {
 735             return op(m, i -> a[ax + i]);
 736         }
 737 
 738         public $abstractvectortype$<S> fromArray($type$[] a, int ax, int[] indexMap, int mx) {
 739             return op(i -> a[ax + indexMap[mx + i]]);
 740         }
 741 
 742         public $abstractvectortype$<S> fromArray($type$[] a, int ax, Mask<$Boxtype$, S> m, int[] indexMap, int mx) {
 743             return op(m, i -> a[ax + indexMap[mx + i]]);
 744         }
 745 
 746         @Override
 747         public $abstractvectortype$<S> fromByteArray(byte[] a, int ix) {
 748             ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 749             return fromByteBuffer(bb);
 750         }
 751 
 752         @Override
 753         public $abstractvectortype$<S> fromByteArray(byte[] a, int ix, Mask<$Boxtype$, S> m) {
 754             ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix);
 755             return fromByteBuffer(bb, m);
 756         }
 757 
 758         @Override
 759         public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb) {
 760             $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 761             return op(i -> fb.get());
 762         }
 763 
 764         @Override
 765         public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, Mask<$Boxtype$, S> m) {
 766             $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 767             return op(i -> {
 768                 if(m.getElement(i))
 769                     return fb.get();
 770                 else {
 771                     fb.position(fb.position() + 1);
 772                     return ($type$) 0;
 773                 }
 774             });
 775         }
 776 
 777         @Override
 778         public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix) {
 779             bb = bb.duplicate().position(ix);
 780             $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 781             return op(i -> fb.get(i));
 782         }
 783 
 784         @Override
 785         public $abstractvectortype$<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$, S> m) {
 786             bb = bb.duplicate().position(ix);
 787             $Type$Buffer fb = bb{#if[byte]?;:.as$Type$Buffer();}
 788             return op(m, i -> fb.get(i));
 789         }
 790 
 791         @Override
 792         @ForceInline
 793         public <F, T extends Shape> $abstractvectortype$<S> reshape(Vector<F, T> o) {
 794             int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE;
 795             ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
 796             o.intoByteBuffer(bb, 0);
 797             return fromByteBuffer(bb, 0);
 798         }
 799 
 800         @Override
 801         @ForceInline
 802         public <F> $abstractvectortype$<S> rebracket(Vector<F, S> o) {
 803             return reshape(o);
 804         }
 805 
 806         @Override
 807         @ForceInline
 808         public <T extends Shape> $abstractvectortype$<S> resize(Vector<$Boxtype$, T> o) {
 809             return reshape(o);
 810         }
 811 
 812         @Override
 813         @SuppressWarnings("unchecked")
 814         public <F, T extends Shape> $abstractvectortype$<S> cast(Vector<F, T> v) {
 815             // Allocate array of required size
 816             $type$[] a = new $type$[length()];
 817 
 818             Class<?> vtype = v.species().elementType();
 819             int limit = Math.min(v.species().length(), length());
 820             if (vtype == Byte.class) {
 821                 ByteVector<T> tv = (ByteVector<T>)v;
 822                 for (int i = 0; i < limit; i++) {
 823                     a[i] = ($type$) tv.get(i);
 824                 }
 825             } else if (vtype == Short.class) {
 826                 ShortVector<T> tv = (ShortVector<T>)v;
 827                 for (int i = 0; i < limit; i++) {
 828                     a[i] = ($type$) tv.get(i);
 829                 }
 830             } else if (vtype == Integer.class) {
 831                 IntVector<T> tv = (IntVector<T>)v;
 832                 for (int i = 0; i < limit; i++) {
 833                     a[i] = ($type$) tv.get(i);
 834                 }
 835             } else if (vtype == Long.class){
 836                 LongVector<T> tv = (LongVector<T>)v;
 837                 for (int i = 0; i < limit; i++) {
 838                     a[i] = ($type$) tv.get(i);
 839                 }
 840             } else if (vtype == Float.class){
 841                 FloatVector<T> tv = (FloatVector<T>)v;
 842                 for (int i = 0; i < limit; i++) {
 843                     a[i] = ($type$) tv.get(i);
 844                 }
 845             } else if (vtype == Double.class){
 846                 DoubleVector<T> tv = (DoubleVector<T>)v;
 847                 for (int i = 0; i < limit; i++) {
 848                     a[i] = ($type$) tv.get(i);
 849                 }
 850             } else {
 851                 throw new UnsupportedOperationException("Bad lane type for casting.");
 852             }
 853 
 854             return scalars(a);
 855         }
 856 
 857     }
 858 }