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 #if[intOrFP] 362 @Override 363 @ForceInline 364 public $vectortype$ abs() { 365 return ($vectortype$) VectorIntrinsics.unaryOp( 366 VECTOR_OP_ABS, $vectortype$.class, $type$.class, LENGTH, 367 this, 368 v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.abs(a))); 369 } 370 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 #if[intOrFP] 449 @Override 450 @ForceInline 451 public $vectortype$ add(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 452 // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a + b)); 453 return blend(add(v), m); 454 } 455 456 @Override 457 @ForceInline 458 public $vectortype$ sub(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 459 // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a - b)); 460 return blend(sub(v), m); 461 } 462 463 @Override 464 @ForceInline 465 public $vectortype$ mul(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 466 // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a * b)); 467 return blend(mul(v), m); 468 } 469 #end[intOrFP] 470 471 #if[FP] 472 @Override 473 @ForceInline 474 public $vectortype$ div(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 475 // TODO: use better default impl: bOp(o, m, (i, a, b) -> ($type$)(a / b)); 476 return blend(div(v), m); 477 } 478 #end[FP] 479 480 #if[BITWISE] 481 @Override 482 @ForceInline 483 public $vectortype$ and(Vector<$Boxtype$,Shapes.$shape$> o) { 484 Objects.requireNonNull(o); 485 $vectortype$ v = ($vectortype$)o; 486 return ($vectortype$) VectorIntrinsics.binaryOp( 487 VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH, 488 this, v, 489 (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a & b))); 490 } 491 492 @Override 493 @ForceInline 494 public $vectortype$ or(Vector<$Boxtype$,Shapes.$shape$> o) { 495 Objects.requireNonNull(o); 496 $vectortype$ v = ($vectortype$)o; 497 return ($vectortype$) VectorIntrinsics.binaryOp( 498 VECTOR_OP_OR, $vectortype$.class, $type$.class, LENGTH, 499 this, v, 500 (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(a | b))); 501 } 502 503 @Override 504 @ForceInline 505 public $vectortype$ xor(Vector<$Boxtype$,Shapes.$shape$> o) { 506 Objects.requireNonNull(o); 507 $vectortype$ v = ($vectortype$)o; 508 return ($vectortype$) VectorIntrinsics.binaryOp( 509 VECTOR_OP_XOR, $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$ and(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 517 return blend(and(v), m); 518 } 519 520 @Override 521 @ForceInline 522 public $vectortype$ or(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 523 return blend(or(v), m); 524 } 525 526 @Override 527 @ForceInline 528 public $vectortype$ xor(Vector<$Boxtype$,Shapes.$shape$> v, Mask<$Boxtype$, Shapes.$shape$> m) { 529 return blend(xor(v), m); 530 } 531 532 @Override 533 @ForceInline 534 public $vectortype$ shiftL(int s) { 535 return ($vectortype$) VectorIntrinsics.broadcastInt( 536 VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH, 537 this, s, 538 (v, i) -> v.uOp((__, a) -> ($type$) (a << i))); 539 } 540 541 @Override 542 @ForceInline 543 public $vectortype$ shiftR(int s) { 544 return ($vectortype$) VectorIntrinsics.broadcastInt( 545 VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH, 546 this, s, 547 (v, i) -> v.uOp((__, a) -> ($type$) (a >>> i))); 548 } 549 550 @Override 551 @ForceInline 552 public $vectortype$ aShiftR(int s) { 553 return ($vectortype$) VectorIntrinsics.broadcastInt( 554 VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH, 555 this, s, 556 (v, i) -> v.uOp((__, a) -> ($type$) (a >> i))); 557 } 558 #end[BITWISE] 559 560 // Ternary operations 561 562 #if[FP] 563 @Override 564 @ForceInline 565 public $vectortype$ fma(Vector<$Boxtype$,Shapes.$shape$> o1, Vector<$Boxtype$,Shapes.$shape$> o2) { 566 Objects.requireNonNull(o1); 567 Objects.requireNonNull(o2); 568 $vectortype$ v1 = ($vectortype$)o1; 569 $vectortype$ v2 = ($vectortype$)o2; 570 return ($vectortype$) VectorIntrinsics.ternaryOp( 571 VECTOR_OP_FMA, $vectortype$.class, $type$.class, LENGTH, 572 this, v1, v2, 573 (w1, w2, w3) -> w1.tOp(w2, w3, (i, a, b, c) -> Math.fma(a, b, c))); 574 } 575 #end[FP] 576 577 // Type specific horizontal reductions 578 579 #if[intOrlong] 580 @Override 581 @ForceInline 582 public $type$ addAll() { 583 return ($type$) VectorIntrinsics.reductionCoerced( 584 VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH, 585 this, 586 v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b))); 587 } 588 589 @Override 590 @ForceInline 591 public $type$ mulAll() { 592 return ($type$) VectorIntrinsics.reductionCoerced( 593 VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH, 594 this, 595 v -> (long) v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b))); 596 } 597 598 @Override 599 @ForceInline 600 public $type$ andAll() { 601 return ($type$) VectorIntrinsics.reductionCoerced( 602 VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH, 603 this, 604 v -> (long) v.rOp(($type$) -1, (i, a, b) -> ($type$) (a & b))); 605 } 606 #end[intOrlong] 607 #if[FP] 608 @Override 609 @ForceInline 610 public $type$ addAll() { 611 $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced( 612 VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH, 613 this, 614 v -> { 615 $type$ r = v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b)); 616 return (long)$Type$.$type$To$Bitstype$Bits(r); 617 }); 618 return $Type$.$bitstype$BitsTo$Fptype$(bits); 619 } 620 621 @Override 622 @ForceInline 623 public $type$ mulAll() { 624 $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced( 625 VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH, 626 this, 627 v -> { 628 $type$ r = v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b)); 629 return (long)$Type$.$type$To$Bitstype$Bits(r); 630 }); 631 return $Type$.$bitstype$BitsTo$Fptype$(bits); 632 } 633 #end[FP] 634 635 // Memory operations 636 637 @Override 638 @ForceInline 639 public void intoArray($type$[] a, int ix) { 640 Objects.requireNonNull(a); 641 ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH); 642 VectorIntrinsics.store($vectortype$.class, $type$.class, LENGTH, 643 a, ix, this, 644 (arr, idx, v) -> v.forEach((i, a_) -> (($type$[])arr)[idx + i] = a_)); 645 } 646 647 @Override 648 @ForceInline 649 public void intoArray($type$[] a, int ax, Mask<$Boxtype$, Shapes.$shape$> m) { 650 // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_); 651 $vectortype$ oldVal = SPECIES.fromArray(a, ax); 652 $vectortype$ newVal = oldVal.blend(this, m); 653 newVal.intoArray(a, ax); 654 } 655 656 // 657 658 @Override 659 public String toString() { 660 return Arrays.toString(getElements()); 661 } 662 663 @Override 664 public boolean equals(Object o) { 665 if (this == o) return true; 666 if (o == null || this.getClass() != o.getClass()) return false; 667 668 $vectortype$ that = ($vectortype$) o; 669 return Arrays.equals(this.getElements(), that.getElements()); 670 } 671 672 @Override 673 public int hashCode() { 674 return Arrays.hashCode(vec); 675 } 676 677 // Binary test 678 679 @Override 680 $masktype$ bTest(Vector<$Boxtype$, Shapes.$shape$> o, FBinTest f) { 681 $type$[] vec1 = getElements(); 682 $type$[] vec2 = (($vectortype$)o).getElements(); 683 boolean[] bits = new boolean[length()]; 684 for (int i = 0; i < length(); i++){ 685 bits[i] = f.apply(i, vec1[i], vec2[i]); 686 } 687 return new $masktype$(bits); 688 } 689 690 // Comparisons 691 692 @Override 693 @ForceInline 694 public $masktype$ equal(Vector<$Boxtype$, Shapes.$shape$> o) { 695 Objects.requireNonNull(o); 696 $vectortype$ v = ($vectortype$)o; 697 698 return ($masktype$) VectorIntrinsics.compare( 699 BT_eq, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 700 this, v, 701 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b)); 702 } 703 704 @Override 705 @ForceInline 706 public $masktype$ notEqual(Vector<$Boxtype$, Shapes.$shape$> o) { 707 Objects.requireNonNull(o); 708 $vectortype$ v = ($vectortype$)o; 709 710 return ($masktype$) VectorIntrinsics.compare( 711 BT_ne, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 712 this, v, 713 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b)); 714 } 715 716 @Override 717 @ForceInline 718 public $masktype$ lessThan(Vector<$Boxtype$, Shapes.$shape$> o) { 719 Objects.requireNonNull(o); 720 $vectortype$ v = ($vectortype$)o; 721 722 return ($masktype$) VectorIntrinsics.compare( 723 BT_lt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 724 this, v, 725 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b)); 726 } 727 728 @Override 729 @ForceInline 730 public $masktype$ lessThanEq(Vector<$Boxtype$, Shapes.$shape$> o) { 731 Objects.requireNonNull(o); 732 $vectortype$ v = ($vectortype$)o; 733 734 return ($masktype$) VectorIntrinsics.compare( 735 BT_le, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 736 this, v, 737 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b)); 738 } 739 740 @Override 741 @ForceInline 742 public $masktype$ greaterThan(Vector<$Boxtype$, Shapes.$shape$> o) { 743 Objects.requireNonNull(o); 744 $vectortype$ v = ($vectortype$)o; 745 746 return ($masktype$) VectorIntrinsics.compare( 747 BT_gt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 748 this, v, 749 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b)); 750 } 751 752 @Override 753 @ForceInline 754 public $masktype$ greaterThanEq(Vector<$Boxtype$, Shapes.$shape$> o) { 755 Objects.requireNonNull(o); 756 $vectortype$ v = ($vectortype$)o; 757 758 return ($masktype$) VectorIntrinsics.compare( 759 BT_ge, $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 760 this, v, 761 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b)); 762 } 763 764 // Foreach 765 766 @Override 767 void forEach(FUnCon f) { 768 $type$[] vec = getElements(); 769 for (int i = 0; i < length(); i++) { 770 f.apply(i, vec[i]); 771 } 772 } 773 774 @Override 775 void forEach(Mask<$Boxtype$, Shapes.$shape$> o, FUnCon f) { 776 boolean[] mbits = (($masktype$)o).getBits(); 777 forEach((i, a) -> { 778 if (mbits[i]) { f.apply(i, a); } 779 }); 780 } 781 782 #if[FP] 783 $bitsvectortype$ toBits() { 784 $type$[] vec = getElements(); 785 $bitstype$[] res = new $bitstype$[this.species().length()]; 786 for(int i = 0; i < this.species().length(); i++){ 787 res[i] = $Type$.$type$To$Bitstype$Bits(vec[i]); 788 } 789 return new $bitsvectortype$(res); 790 } 791 #end[FP] 792 793 #if[intOrlong] 794 $fpvectortype$ toFP() { 795 $type$[] vec = getElements(); 796 $fptype$[] res = new $fptype$[this.species().length()]; 797 for(int i = 0; i < this.species().length(); i++){ 798 res[i] = $Boxfptype$.$bitstype$BitsTo$Fptype$(vec[i]); 799 } 800 return new $fpvectortype$(res); 801 } 802 #end[intOrlong] 803 804 @Override 805 public $vectortype$ rotateEL(int j) { 806 $type$[] vec = getElements(); 807 $type$[] res = new $type$[length()]; 808 for (int i = 0; i < length(); i++){ 809 res[j + i % length()] = vec[i]; 810 } 811 return new $vectortype$(res); 812 } 813 814 @Override 815 public $vectortype$ rotateER(int j) { 816 $type$[] vec = getElements(); 817 $type$[] res = new $type$[length()]; 818 for (int i = 0; i < length(); i++){ 819 int z = i - j; 820 if(j < 0) { 821 res[length() + z] = vec[i]; 822 } else { 823 res[z] = vec[i]; 824 } 825 } 826 return new $vectortype$(res); 827 } 828 829 @Override 830 public $vectortype$ shiftEL(int j) { 831 $type$[] vec = getElements(); 832 $type$[] res = new $type$[length()]; 833 for (int i = 0; i < length() - j; i++) { 834 res[i] = vec[i + j]; 835 } 836 return new $vectortype$(res); 837 } 838 839 @Override 840 public $vectortype$ shiftER(int j) { 841 $type$[] vec = getElements(); 842 $type$[] res = new $type$[length()]; 843 for (int i = 0; i < length() - j; i++){ 844 res[i + j] = vec[i]; 845 } 846 return new $vectortype$(res); 847 } 848 849 @Override 850 public $vectortype$ shuffle(Vector<$Boxtype$, Shapes.$shape$> o, Shuffle<$Boxtype$, Shapes.$shape$> s) { 851 $vectortype$ v = ($vectortype$) o; 852 return uOp((i, a) -> { 853 $type$[] vec = this.getElements(); 854 int e = s.getElement(i); 855 if(e >= 0 && e < length()) { 856 //from this 857 return vec[e]; 858 } else if(e < length() * 2) { 859 //from o 860 return v.getElements()[e - length()]; 861 } else { 862 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle"); 863 } 864 }); 865 } 866 867 @Override 868 public $vectortype$ swizzle(Shuffle<$Boxtype$, Shapes.$shape$> s) { 869 return uOp((i, a) -> { 870 $type$[] vec = this.getElements(); 871 int e = s.getElement(i); 872 if(e >= 0 && e < length()) { 873 return vec[e]; 874 } else { 875 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle"); 876 } 877 }); 878 } 879 880 @Override 881 @ForceInline 882 public $vectortype$ blend(Vector<$Boxtype$, Shapes.$shape$> o1, Mask<$Boxtype$, Shapes.$shape$> o2) { 883 Objects.requireNonNull(o1); 884 Objects.requireNonNull(o2); 885 $vectortype$ v = ($vectortype$)o1; 886 $masktype$ m = ($masktype$)o2; 887 888 return ($vectortype$) VectorIntrinsics.blend( 889 $vectortype$.class, $masktype$.class, $type$.class, LENGTH, 890 this, v, m, 891 (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a)); 892 } 893 894 @Override 895 @ForceInline 896 @SuppressWarnings("unchecked") 897 public <F> Vector<F, Shapes.$shape$> rebracket(Species<F, Shapes.$shape$> species) { 898 Objects.requireNonNull(species); 899 // TODO: check proper element type 900 // TODO: update to pass the two species as an arguments and ideally 901 // push down intrinsic call into species implementation 902 return VectorIntrinsics.rebracket( 903 $vectortype$.class, $type$.class, LENGTH, 904 species.elementType(), this, 905 (v, t) -> species.reshape(v) 906 ); 907 } 908 909 // Accessors 910 911 @Override 912 public $type$ get(int i) { 913 $type$[] vec = getElements(); 914 return vec[i]; 915 } 916 917 @Override 918 public $vectortype$ with(int i, $type$ e) { 919 $type$[] res = vec.clone(); 920 res[i] = e; 921 return new $vectortype$(res); 922 } 923 924 // Mask 925 926 static final class $masktype$ extends AbstractMask<$Boxtype$, Shapes.$shape$> { 927 static final $masktype$ TRUE_MASK = new $masktype$(true); 928 static final $masktype$ FALSE_MASK = new $masktype$(false); 929 930 // FIXME: was temporarily put here to simplify rematerialization support in the JVM 931 private final boolean[] bits; // Don't access directly, use getBits() instead. 932 933 public $masktype$(boolean[] bits) { 934 this(bits, 0); 935 } 936 937 public $masktype$(boolean[] bits, int i) { 938 this.bits = Arrays.copyOfRange(bits, i, i + species().length()); 939 } 940 941 public $masktype$(boolean val) { 942 boolean[] bits = new boolean[species().length()]; 943 Arrays.fill(bits, val); 944 this.bits = bits; 945 } 946 947 boolean[] getBits() { 948 return VectorIntrinsics.maybeRebox(this).bits; 949 } 950 951 @Override 952 $masktype$ uOp(MUnOp f) { 953 boolean[] res = new boolean[species().length()]; 954 boolean[] bits = getBits(); 955 for (int i = 0; i < species().length(); i++) { 956 res[i] = f.apply(i, bits[i]); 957 } 958 return new $masktype$(res); 959 } 960 961 @Override 962 $masktype$ bOp(Mask<$Boxtype$, Shapes.$shape$> o, MBinOp f) { 963 boolean[] res = new boolean[species().length()]; 964 boolean[] bits = getBits(); 965 boolean[] mbits = (($masktype$)o).getBits(); 966 for (int i = 0; i < species().length(); i++) { 967 res[i] = f.apply(i, bits[i], mbits[i]); 968 } 969 return new $masktype$(res); 970 } 971 972 @Override 973 public $Type$$bits$Species species() { 974 return SPECIES; 975 } 976 977 @Override 978 public $vectortype$ toVector() { 979 $type$[] res = new $type$[species().length()]; 980 boolean[] bits = getBits(); 981 for (int i = 0; i < species().length(); i++) { 982 res[i] = ($type$) (bits[i] ? -1 : 0); 983 } 984 return new $vectortype$(res); 985 } 986 987 @Override 988 @ForceInline 989 @SuppressWarnings("unchecked") 990 public <Z> Mask<Z, Shapes.$shape$> rebracket(Species<Z, Shapes.$shape$> species) { 991 Objects.requireNonNull(species); 992 // TODO: check proper element type 993 return VectorIntrinsics.rebracket( 994 $masktype$.class, $type$.class, LENGTH, 995 species.elementType(), this, 996 (m, t) -> m.reshape(species) 997 ); 998 } 999 1000 // Unary operations 1001 1002 //Mask<E, S> not(); 1003 1004 // Binary operations 1005 1006 @Override 1007 @ForceInline 1008 public $masktype$ and(Mask<$Boxtype$,Shapes.$shape$> o) { 1009 Objects.requireNonNull(o); 1010 $masktype$ m = ($masktype$)o; 1011 return VectorIntrinsics.binaryOp(VECTOR_OP_AND, $masktype$.class, $bitstype$.class, LENGTH, 1012 this, m, 1013 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b)); 1014 } 1015 1016 @Override 1017 @ForceInline 1018 public $masktype$ or(Mask<$Boxtype$,Shapes.$shape$> o) { 1019 Objects.requireNonNull(o); 1020 $masktype$ m = ($masktype$)o; 1021 return VectorIntrinsics.binaryOp(VECTOR_OP_OR, $masktype$.class, $bitstype$.class, LENGTH, 1022 this, m, 1023 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b)); 1024 } 1025 1026 // Reductions 1027 1028 @Override 1029 @ForceInline 1030 public boolean anyTrue() { 1031 return VectorIntrinsics.test(COND_notZero, $masktype$.class, $bitstype$.class, LENGTH, 1032 this, this, 1033 (m1, m2) -> super.anyTrue()); 1034 } 1035 1036 @Override 1037 @ForceInline 1038 public boolean allTrue() { 1039 return VectorIntrinsics.test(COND_carrySet, $masktype$.class, $bitstype$.class, LENGTH, 1040 this, species().maskAllTrue(), 1041 (m1, m2) -> super.allTrue()); 1042 } 1043 } 1044 1045 // Shuffle 1046 1047 static final class $shuffletype$ extends AbstractShuffle<$Boxtype$, Shapes.$shape$> { 1048 static final IntVector.IntSpecies<Shapes.$shape$> INT_SPECIES = (IntVector.IntSpecies<Shapes.$shape$>) Vector.speciesInstance(Integer.class, Shapes.$Shape$); 1049 1050 public $shuffletype$(int[] reorder) { 1051 super(reorder); 1052 } 1053 1054 public $shuffletype$(int[] reorder, int i) { 1055 super(reorder, i); 1056 } 1057 1058 @Override 1059 public $Type$$bits$Species species() { 1060 return SPECIES; 1061 } 1062 1063 @Override 1064 public IntVector.IntSpecies<Shapes.$shape$> intSpecies() { 1065 return INT_SPECIES; 1066 } 1067 } 1068 1069 // Species 1070 1071 @Override 1072 public $Type$$bits$Species species() { 1073 return SPECIES; 1074 } 1075 1076 static final class $Type$$bits$Species extends $Type$Species<Shapes.$shape$> { 1077 static final int BIT_SIZE = Shapes.$Shape$.bitSize(); 1078 1079 static final int LENGTH = BIT_SIZE / $Boxtype$.SIZE; 1080 1081 @Override 1082 public String toString() { 1083 StringBuilder sb = new StringBuilder("Shape["); 1084 sb.append(bitSize()).append(" bits, "); 1085 sb.append(length()).append(" ").append($type$.class.getSimpleName()).append("s x "); 1086 sb.append(elementSize()).append(" bits"); 1087 sb.append("]"); 1088 return sb.toString(); 1089 } 1090 1091 @Override 1092 public int bitSize() { 1093 return BIT_SIZE; 1094 } 1095 1096 @Override 1097 public int length() { 1098 return LENGTH; 1099 } 1100 1101 @Override 1102 public Class<$Boxtype$> elementType() { 1103 return $Boxtype$.class; 1104 } 1105 1106 @Override 1107 public int elementSize() { 1108 return $Boxtype$.SIZE; 1109 } 1110 1111 @Override 1112 public Shapes.$shape$ shape() { 1113 return Shapes.$Shape$; 1114 } 1115 1116 @Override 1117 $vectortype$ op(FOp f) { 1118 $type$[] res = new $type$[length()]; 1119 for (int i = 0; i < length(); i++) { 1120 res[i] = f.apply(i); 1121 } 1122 return new $vectortype$(res); 1123 } 1124 1125 @Override 1126 $vectortype$ op(Mask<$Boxtype$, Shapes.$shape$> o, FOp f) { 1127 $type$[] res = new $type$[length()]; 1128 boolean[] mbits = (($masktype$)o).getBits(); 1129 for (int i = 0; i < length(); i++) { 1130 if (mbits[i]) { 1131 res[i] = f.apply(i); 1132 } 1133 } 1134 return new $vectortype$(res); 1135 } 1136 1137 // Factories 1138 1139 @Override 1140 public $masktype$ maskFromValues(boolean... bits) { 1141 return new $masktype$(bits); 1142 } 1143 1144 @Override 1145 public $masktype$ maskFromArray(boolean[] bits, int i) { 1146 return new $masktype$(bits, i); 1147 } 1148 1149 @Override 1150 public $shuffletype$ shuffleFromValues(int... ixs) { 1151 return new $shuffletype$(ixs); 1152 } 1153 1154 @Override 1155 public $shuffletype$ shuffleFromArray(int[] ixs, int i) { 1156 return new $shuffletype$(ixs, i); 1157 } 1158 1159 #if[FP] 1160 @Override 1161 @ForceInline 1162 public $vectortype$ zero() { 1163 return VectorIntrinsics.broadcastCoerced($vectortype$.class, $type$.class, LENGTH, 1164 $Type$.$type$To$Bitstype$Bits(0.0f), 1165 (z -> ZERO)); 1166 } 1167 1168 @Override 1169 @ForceInline 1170 public $vectortype$ broadcast($type$ e) { 1171 return VectorIntrinsics.broadcastCoerced( 1172 $vectortype$.class, $type$.class, LENGTH, 1173 $Type$.$type$To$Bitstype$Bits(e), 1174 ((long bits) -> SPECIES.op(i -> $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits)))); 1175 } 1176 #end[FP] 1177 #if[BITWISE] 1178 @Override 1179 @ForceInline 1180 public $vectortype$ zero() { 1181 return VectorIntrinsics.broadcastCoerced($vectortype$.class, $type$.class, LENGTH, 1182 0, 1183 (z -> ZERO)); 1184 } 1185 1186 @Override 1187 @ForceInline 1188 public $vectortype$ broadcast($type$ e) { 1189 return VectorIntrinsics.broadcastCoerced( 1190 $vectortype$.class, $type$.class, LENGTH, 1191 e, 1192 ((long bits) -> SPECIES.op(i -> ($type$)bits))); 1193 } 1194 #end[BITWISE] 1195 1196 @Override 1197 @ForceInline 1198 public $masktype$ maskAllTrue() { 1199 return VectorIntrinsics.broadcastCoerced($masktype$.class, $bitstype$.class, LENGTH, 1200 ($bitstype$)-1, 1201 (z -> $masktype$.TRUE_MASK)); 1202 } 1203 1204 @Override 1205 @ForceInline 1206 public $masktype$ maskAllFalse() { 1207 return VectorIntrinsics.broadcastCoerced($masktype$.class, $bitstype$.class, LENGTH, 1208 0, 1209 (z -> $masktype$.FALSE_MASK)); 1210 } 1211 1212 @Override 1213 @ForceInline 1214 public $vectortype$ fromArray($type$[] a, int ix) { 1215 Objects.requireNonNull(a); 1216 ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH); 1217 return ($vectortype$) VectorIntrinsics.load($vectortype$.class, $type$.class, LENGTH, 1218 a, ix, 1219 (arr, idx) -> super.fromArray(($type$[]) arr, idx)); 1220 } 1221 1222 @Override 1223 @ForceInline 1224 public $vectortype$ fromArray($type$[] a, int ax, Mask<$Boxtype$, Shapes.$shape$> m) { 1225 return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]); 1226 } 1227 } 1228 }