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 Double128Vector extends DoubleVector<Shapes.S128Bit> { 35 static final Double128Species SPECIES = new Double128Species(); 36 37 static final Double128Vector ZERO = new Double128Vector(); 38 39 static final int LENGTH = SPECIES.length(); 40 41 private final double[] vec; // Don't access directly, use getElements() instead. 42 43 private double[] getElements() { 44 return VectorIntrinsics.maybeRebox(this).vec; 45 } 46 47 Double128Vector() { 48 vec = new double[SPECIES.length()]; 49 } 50 51 Double128Vector(double[] v) { 52 vec = v; 53 } 54 55 @Override 56 public int length() { return LENGTH; } 57 58 // Unary operator 59 60 @Override 61 Double128Vector uOp(FUnOp f) { 62 double[] vec = getElements(); 63 double[] res = new double[length()]; 64 for (int i = 0; i < length(); i++) { 65 res[i] = f.apply(i, vec[i]); 66 } 67 return new Double128Vector(res); 68 } 69 70 @Override 71 Double128Vector uOp(Mask<Double, Shapes.S128Bit> o, FUnOp f) { 72 double[] vec = getElements(); 73 double[] res = new double[length()]; 74 boolean[] mbits = ((Double128Mask)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 Double128Vector(res); 79 } 80 81 // Binary operator 82 83 @Override 84 Double128Vector bOp(Vector<Double, Shapes.S128Bit> o, FBinOp f) { 85 double[] res = new double[length()]; 86 double[] vec1 = this.getElements(); 87 double[] vec2 = ((Double128Vector)o).getElements(); 88 for (int i = 0; i < length(); i++) { 89 res[i] = f.apply(i, vec1[i], vec2[i]); 90 } 91 return new Double128Vector(res); 92 } 93 94 @Override 95 Double128Vector bOp(Vector<Double, Shapes.S128Bit> o1, Mask<Double, Shapes.S128Bit> o2, FBinOp f) { 96 double[] res = new double[length()]; 97 double[] vec1 = this.getElements(); 98 double[] vec2 = ((Double128Vector)o1).getElements(); 99 boolean[] mbits = ((Double128Mask)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 Double128Vector(res); 104 } 105 106 // Trinary operator 107 108 @Override 109 Double128Vector tOp(Vector<Double, Shapes.S128Bit> o1, Vector<Double, Shapes.S128Bit> o2, FTriOp f) { 110 double[] res = new double[length()]; 111 double[] vec1 = this.getElements(); 112 double[] vec2 = ((Double128Vector)o1).getElements(); 113 double[] vec3 = ((Double128Vector)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 Double128Vector(res); 118 } 119 120 @Override 121 Double128Vector tOp(Vector<Double, Shapes.S128Bit> o1, Vector<Double, Shapes.S128Bit> o2, Mask<Double, Shapes.S128Bit> o3, FTriOp f) { 122 double[] res = new double[length()]; 123 double[] vec1 = getElements(); 124 double[] vec2 = ((Double128Vector)o1).getElements(); 125 double[] vec3 = ((Double128Vector)o2).getElements(); 126 boolean[] mbits = ((Double128Mask)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 Double128Vector(res); 131 } 132 133 @Override 134 double rOp(double v, FBinOp f) { 135 double[] 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 DoubleVector<Shapes.S128Bit> add(double o) { 147 return add(SPECIES.broadcast(o)); 148 } 149 150 @Override 151 @ForceInline 152 public DoubleVector<Shapes.S128Bit> add(double o, Mask<Double,Shapes.S128Bit> m) { 153 return add(SPECIES.broadcast(o), m); 154 } 155 156 @Override 157 @ForceInline 158 public DoubleVector<Shapes.S128Bit> addSaturate(double o) { 159 return addSaturate(SPECIES.broadcast(o)); 160 } 161 162 @Override 163 @ForceInline 164 public DoubleVector<Shapes.S128Bit> addSaturate(double o, Mask<Double,Shapes.S128Bit> m) { 165 return addSaturate(SPECIES.broadcast(o), m); 166 } 167 168 @Override 169 @ForceInline 170 public DoubleVector<Shapes.S128Bit> sub(double o) { 171 return sub(SPECIES.broadcast(o)); 172 } 173 174 @Override 175 @ForceInline 176 public DoubleVector<Shapes.S128Bit> sub(double o, Mask<Double,Shapes.S128Bit> m) { 177 return sub(SPECIES.broadcast(o), m); 178 } 179 180 @Override 181 @ForceInline 182 public DoubleVector<Shapes.S128Bit> subSaturate(double o) { 183 return subSaturate(SPECIES.broadcast(o)); 184 } 185 186 @Override 187 @ForceInline 188 public DoubleVector<Shapes.S128Bit> subSaturate(double o, Mask<Double,Shapes.S128Bit> m) { 189 return subSaturate(SPECIES.broadcast(o), m); 190 } 191 192 @Override 193 @ForceInline 194 public DoubleVector<Shapes.S128Bit> mul(double o) { 195 return mul(SPECIES.broadcast(o)); 196 } 197 198 @Override 199 @ForceInline 200 public DoubleVector<Shapes.S128Bit> mul(double o, Mask<Double,Shapes.S128Bit> m) { 201 return mul(SPECIES.broadcast(o), m); 202 } 203 204 @Override 205 @ForceInline 206 public DoubleVector<Shapes.S128Bit> min(double o) { 207 return min(SPECIES.broadcast(o)); 208 } 209 210 @Override 211 @ForceInline 212 public DoubleVector<Shapes.S128Bit> max(double o) { 213 return max(SPECIES.broadcast(o)); 214 } 215 216 @Override 217 @ForceInline 218 public Mask<Double, Shapes.S128Bit> equal(double o) { 219 return equal(SPECIES.broadcast(o)); 220 } 221 222 @Override 223 @ForceInline 224 public Mask<Double, Shapes.S128Bit> notEqual(double o) { 225 return notEqual(SPECIES.broadcast(o)); 226 } 227 228 @Override 229 @ForceInline 230 public Mask<Double, Shapes.S128Bit> lessThan(double o) { 231 return lessThan(SPECIES.broadcast(o)); 232 } 233 234 @Override 235 @ForceInline 236 public Mask<Double, Shapes.S128Bit> lessThanEq(double o) { 237 return lessThanEq(SPECIES.broadcast(o)); 238 } 239 240 @Override 241 @ForceInline 242 public Mask<Double, Shapes.S128Bit> greaterThan(double o) { 243 return greaterThan(SPECIES.broadcast(o)); 244 } 245 246 @Override 247 @ForceInline 248 public Mask<Double, Shapes.S128Bit> greaterThanEq(double o) { 249 return greaterThanEq(SPECIES.broadcast(o)); 250 } 251 252 @Override 253 @ForceInline 254 public DoubleVector<Shapes.S128Bit> blend(double o, Mask<Double,Shapes.S128Bit> m) { 255 return blend(SPECIES.broadcast(o), m); 256 } 257 258 @Override 259 @ForceInline 260 public DoubleVector<Shapes.S128Bit> div(double o) { 261 return div(SPECIES.broadcast(o)); 262 } 263 264 @Override 265 @ForceInline 266 public DoubleVector<Shapes.S128Bit> div(double o, Mask<Double,Shapes.S128Bit> m) { 267 return div(SPECIES.broadcast(o), m); 268 } 269 270 @Override 271 @ForceInline 272 public DoubleVector<Shapes.S128Bit> atan2(double o) { 273 return atan2(SPECIES.broadcast(o)); 274 } 275 276 @Override 277 @ForceInline 278 public DoubleVector<Shapes.S128Bit> atan2(double o, Mask<Double,Shapes.S128Bit> m) { 279 return atan2(SPECIES.broadcast(o), m); 280 } 281 282 @Override 283 @ForceInline 284 public DoubleVector<Shapes.S128Bit> pow(double o) { 285 return pow(SPECIES.broadcast(o)); 286 } 287 288 @Override 289 @ForceInline 290 public DoubleVector<Shapes.S128Bit> pow(double o, Mask<Double,Shapes.S128Bit> m) { 291 return pow(SPECIES.broadcast(o), m); 292 } 293 294 @Override 295 @ForceInline 296 public DoubleVector<Shapes.S128Bit> fma(double o1, double o2) { 297 return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2)); 298 } 299 300 @Override 301 @ForceInline 302 public DoubleVector<Shapes.S128Bit> fma(double o1, double o2, Mask<Double,Shapes.S128Bit> m) { 303 return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2), m); 304 } 305 306 @Override 307 @ForceInline 308 public DoubleVector<Shapes.S128Bit> hypot(double o) { 309 return hypot(SPECIES.broadcast(o)); 310 } 311 312 @Override 313 @ForceInline 314 public DoubleVector<Shapes.S128Bit> hypot(double o, Mask<Double,Shapes.S128Bit> m) { 315 return hypot(SPECIES.broadcast(o), m); 316 } 317 318 319 320 // Unary operations 321 322 @Override 323 @ForceInline 324 public Double128Vector abs() { 325 return (Double128Vector) VectorIntrinsics.unaryOp( 326 VECTOR_OP_ABS, Double128Vector.class, double.class, LENGTH, 327 this, 328 v1 -> ((Double128Vector)v1).uOp((i, a) -> (double) Math.abs(a))); 329 } 330 331 @Override 332 @ForceInline 333 public Double128Vector neg() { 334 return (Double128Vector) VectorIntrinsics.unaryOp( 335 VECTOR_OP_NEG, Double128Vector.class, double.class, LENGTH, 336 this, 337 v1 -> ((Double128Vector)v1).uOp((i, a) -> (double) -a)); 338 } 339 340 @Override 341 @ForceInline 342 public Double128Vector div(Vector<Double,Shapes.S128Bit> o) { 343 Objects.requireNonNull(o); 344 Double128Vector v = (Double128Vector)o; 345 return (Double128Vector) VectorIntrinsics.binaryOp( 346 VECTOR_OP_DIV, Double128Vector.class, double.class, LENGTH, 347 this, v, 348 (v1, v2) -> ((Double128Vector)v1).bOp(v2, (i, a, b) -> (double)(a / b))); 349 } 350 351 @Override 352 @ForceInline 353 public Double128Vector sqrt() { 354 return (Double128Vector) VectorIntrinsics.unaryOp( 355 VECTOR_OP_SQRT, Double128Vector.class, double.class, LENGTH, 356 this, 357 v1 -> ((Double128Vector)v1).uOp((i, a) -> (double) Math.sqrt((double) a))); 358 } 359 360 // Binary operations 361 362 @Override 363 @ForceInline 364 public Double128Vector add(Vector<Double,Shapes.S128Bit> o) { 365 Objects.requireNonNull(o); 366 Double128Vector v = (Double128Vector)o; 367 return (Double128Vector) VectorIntrinsics.binaryOp( 368 VECTOR_OP_ADD, Double128Vector.class, double.class, LENGTH, 369 this, v, 370 (v1, v2) -> ((Double128Vector)v1).bOp(v2, (i, a, b) -> (double)(a + b))); 371 } 372 373 @Override 374 @ForceInline 375 public Double128Vector sub(Vector<Double,Shapes.S128Bit> o) { 376 Objects.requireNonNull(o); 377 Double128Vector v = (Double128Vector)o; 378 return (Double128Vector) VectorIntrinsics.binaryOp( 379 VECTOR_OP_SUB, Double128Vector.class, double.class, LENGTH, 380 this, v, 381 (v1, v2) -> ((Double128Vector)v1).bOp(v2, (i, a, b) -> (double)(a - b))); 382 } 383 384 @Override 385 @ForceInline 386 public Double128Vector mul(Vector<Double,Shapes.S128Bit> o) { 387 Objects.requireNonNull(o); 388 Double128Vector v = (Double128Vector)o; 389 return (Double128Vector) VectorIntrinsics.binaryOp( 390 VECTOR_OP_MUL, Double128Vector.class, double.class, LENGTH, 391 this, v, 392 (v1, v2) -> ((Double128Vector)v1).bOp(v2, (i, a, b) -> (double)(a * b))); 393 } 394 395 @Override 396 @ForceInline 397 public Double128Vector add(Vector<Double,Shapes.S128Bit> v, Mask<Double, Shapes.S128Bit> m) { 398 // TODO: use better default impl: bOp(o, m, (i, a, b) -> (double)(a + b)); 399 return blend(add(v), m); 400 } 401 402 @Override 403 @ForceInline 404 public Double128Vector sub(Vector<Double,Shapes.S128Bit> v, Mask<Double, Shapes.S128Bit> m) { 405 // TODO: use better default impl: bOp(o, m, (i, a, b) -> (double)(a - b)); 406 return blend(sub(v), m); 407 } 408 409 @Override 410 @ForceInline 411 public Double128Vector mul(Vector<Double,Shapes.S128Bit> v, Mask<Double, Shapes.S128Bit> m) { 412 // TODO: use better default impl: bOp(o, m, (i, a, b) -> (double)(a * b)); 413 return blend(mul(v), m); 414 } 415 416 @Override 417 @ForceInline 418 public Double128Vector div(Vector<Double,Shapes.S128Bit> v, Mask<Double, Shapes.S128Bit> m) { 419 // TODO: use better default impl: bOp(o, m, (i, a, b) -> (double)(a / b)); 420 return blend(div(v), m); 421 } 422 423 424 // Ternary operations 425 426 @Override 427 @ForceInline 428 public Double128Vector fma(Vector<Double,Shapes.S128Bit> o1, Vector<Double,Shapes.S128Bit> o2) { 429 Objects.requireNonNull(o1); 430 Objects.requireNonNull(o2); 431 Double128Vector v1 = (Double128Vector)o1; 432 Double128Vector v2 = (Double128Vector)o2; 433 return (Double128Vector) VectorIntrinsics.ternaryOp( 434 VECTOR_OP_FMA, Double128Vector.class, double.class, LENGTH, 435 this, v1, v2, 436 (w1, w2, w3) -> w1.tOp(w2, w3, (i, a, b, c) -> Math.fma(a, b, c))); 437 } 438 439 // Type specific horizontal reductions 440 441 @Override 442 @ForceInline 443 public double addAll() { 444 long bits = (long) VectorIntrinsics.reductionCoerced( 445 VECTOR_OP_ADD, Double128Vector.class, double.class, LENGTH, 446 this, 447 v -> { 448 double r = v.rOp((double) 0, (i, a, b) -> (double) (a + b)); 449 return (long)Double.doubleToLongBits(r); 450 }); 451 return Double.longBitsToDouble(bits); 452 } 453 454 @Override 455 @ForceInline 456 public double mulAll() { 457 long bits = (long) VectorIntrinsics.reductionCoerced( 458 VECTOR_OP_MUL, Double128Vector.class, double.class, LENGTH, 459 this, 460 v -> { 461 double r = v.rOp((double) 1, (i, a, b) -> (double) (a * b)); 462 return (long)Double.doubleToLongBits(r); 463 }); 464 return Double.longBitsToDouble(bits); 465 } 466 467 // Memory operations 468 469 @Override 470 @ForceInline 471 public void intoArray(double[] a, int ix) { 472 Objects.requireNonNull(a); 473 ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH); 474 VectorIntrinsics.store(Double128Vector.class, double.class, LENGTH, 475 a, ix, this, 476 (arr, idx, v) -> v.forEach((i, a_) -> ((double[])arr)[idx + i] = a_)); 477 } 478 479 @Override 480 @ForceInline 481 public void intoArray(double[] a, int ax, Mask<Double, Shapes.S128Bit> m) { 482 // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_); 483 Double128Vector oldVal = SPECIES.fromArray(a, ax); 484 Double128Vector newVal = oldVal.blend(this, m); 485 newVal.intoArray(a, ax); 486 } 487 488 // 489 490 @Override 491 public String toString() { 492 return Arrays.toString(getElements()); 493 } 494 495 @Override 496 public boolean equals(Object o) { 497 if (this == o) return true; 498 if (o == null || this.getClass() != o.getClass()) return false; 499 500 Double128Vector that = (Double128Vector) o; 501 return Arrays.equals(this.getElements(), that.getElements()); 502 } 503 504 @Override 505 public int hashCode() { 506 return Arrays.hashCode(vec); 507 } 508 509 // Binary test 510 511 @Override 512 Double128Mask bTest(Vector<Double, Shapes.S128Bit> o, FBinTest f) { 513 double[] vec1 = getElements(); 514 double[] vec2 = ((Double128Vector)o).getElements(); 515 boolean[] bits = new boolean[length()]; 516 for (int i = 0; i < length(); i++){ 517 bits[i] = f.apply(i, vec1[i], vec2[i]); 518 } 519 return new Double128Mask(bits); 520 } 521 522 // Comparisons 523 524 @Override 525 @ForceInline 526 public Double128Mask equal(Vector<Double, Shapes.S128Bit> o) { 527 Objects.requireNonNull(o); 528 Double128Vector v = (Double128Vector)o; 529 530 return (Double128Mask) VectorIntrinsics.compare( 531 BT_eq, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 532 this, v, 533 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b)); 534 } 535 536 @Override 537 @ForceInline 538 public Double128Mask notEqual(Vector<Double, Shapes.S128Bit> o) { 539 Objects.requireNonNull(o); 540 Double128Vector v = (Double128Vector)o; 541 542 return (Double128Mask) VectorIntrinsics.compare( 543 BT_ne, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 544 this, v, 545 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b)); 546 } 547 548 @Override 549 @ForceInline 550 public Double128Mask lessThan(Vector<Double, Shapes.S128Bit> o) { 551 Objects.requireNonNull(o); 552 Double128Vector v = (Double128Vector)o; 553 554 return (Double128Mask) VectorIntrinsics.compare( 555 BT_lt, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 556 this, v, 557 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b)); 558 } 559 560 @Override 561 @ForceInline 562 public Double128Mask lessThanEq(Vector<Double, Shapes.S128Bit> o) { 563 Objects.requireNonNull(o); 564 Double128Vector v = (Double128Vector)o; 565 566 return (Double128Mask) VectorIntrinsics.compare( 567 BT_le, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 568 this, v, 569 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b)); 570 } 571 572 @Override 573 @ForceInline 574 public Double128Mask greaterThan(Vector<Double, Shapes.S128Bit> o) { 575 Objects.requireNonNull(o); 576 Double128Vector v = (Double128Vector)o; 577 578 return (Double128Mask) VectorIntrinsics.compare( 579 BT_gt, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 580 this, v, 581 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b)); 582 } 583 584 @Override 585 @ForceInline 586 public Double128Mask greaterThanEq(Vector<Double, Shapes.S128Bit> o) { 587 Objects.requireNonNull(o); 588 Double128Vector v = (Double128Vector)o; 589 590 return (Double128Mask) VectorIntrinsics.compare( 591 BT_ge, Double128Vector.class, Double128Mask.class, double.class, LENGTH, 592 this, v, 593 (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b)); 594 } 595 596 // Foreach 597 598 @Override 599 void forEach(FUnCon f) { 600 double[] vec = getElements(); 601 for (int i = 0; i < length(); i++) { 602 f.apply(i, vec[i]); 603 } 604 } 605 606 @Override 607 void forEach(Mask<Double, Shapes.S128Bit> o, FUnCon f) { 608 boolean[] mbits = ((Double128Mask)o).getBits(); 609 forEach((i, a) -> { 610 if (mbits[i]) { f.apply(i, a); } 611 }); 612 } 613 614 Long128Vector toBits() { 615 double[] vec = getElements(); 616 long[] res = new long[this.species().length()]; 617 for(int i = 0; i < this.species().length(); i++){ 618 res[i] = Double.doubleToLongBits(vec[i]); 619 } 620 return new Long128Vector(res); 621 } 622 623 624 @Override 625 public Double128Vector rotateEL(int j) { 626 double[] vec = getElements(); 627 double[] res = new double[length()]; 628 for (int i = 0; i < length(); i++){ 629 res[j + i % length()] = vec[i]; 630 } 631 return new Double128Vector(res); 632 } 633 634 @Override 635 public Double128Vector rotateER(int j) { 636 double[] vec = getElements(); 637 double[] res = new double[length()]; 638 for (int i = 0; i < length(); i++){ 639 int z = i - j; 640 if(j < 0) { 641 res[length() + z] = vec[i]; 642 } else { 643 res[z] = vec[i]; 644 } 645 } 646 return new Double128Vector(res); 647 } 648 649 @Override 650 public Double128Vector shiftEL(int j) { 651 double[] vec = getElements(); 652 double[] res = new double[length()]; 653 for (int i = 0; i < length() - j; i++) { 654 res[i] = vec[i + j]; 655 } 656 return new Double128Vector(res); 657 } 658 659 @Override 660 public Double128Vector shiftER(int j) { 661 double[] vec = getElements(); 662 double[] res = new double[length()]; 663 for (int i = 0; i < length() - j; i++){ 664 res[i + j] = vec[i]; 665 } 666 return new Double128Vector(res); 667 } 668 669 @Override 670 public Double128Vector shuffle(Vector<Double, Shapes.S128Bit> o, Shuffle<Double, Shapes.S128Bit> s) { 671 Double128Vector v = (Double128Vector) o; 672 return uOp((i, a) -> { 673 double[] vec = this.getElements(); 674 int e = s.getElement(i); 675 if(e >= 0 && e < length()) { 676 //from this 677 return vec[e]; 678 } else if(e < length() * 2) { 679 //from o 680 return v.getElements()[e - length()]; 681 } else { 682 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle"); 683 } 684 }); 685 } 686 687 @Override 688 public Double128Vector swizzle(Shuffle<Double, Shapes.S128Bit> s) { 689 return uOp((i, a) -> { 690 double[] vec = this.getElements(); 691 int e = s.getElement(i); 692 if(e >= 0 && e < length()) { 693 return vec[e]; 694 } else { 695 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle"); 696 } 697 }); 698 } 699 700 @Override 701 @ForceInline 702 public Double128Vector blend(Vector<Double, Shapes.S128Bit> o1, Mask<Double, Shapes.S128Bit> o2) { 703 Objects.requireNonNull(o1); 704 Objects.requireNonNull(o2); 705 Double128Vector v = (Double128Vector)o1; 706 Double128Mask m = (Double128Mask)o2; 707 708 return (Double128Vector) VectorIntrinsics.blend( 709 Double128Vector.class, Double128Mask.class, double.class, LENGTH, 710 this, v, m, 711 (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a)); 712 } 713 714 @Override 715 @ForceInline 716 @SuppressWarnings("unchecked") 717 public <F> Vector<F, Shapes.S128Bit> rebracket(Species<F, Shapes.S128Bit> species) { 718 Objects.requireNonNull(species); 719 // TODO: check proper element type 720 // TODO: update to pass the two species as an arguments and ideally 721 // push down intrinsic call into species implementation 722 return VectorIntrinsics.reinterpret( 723 Double128Vector.class, double.class, LENGTH, 724 species.elementType(), species.length(), this, 725 (v, t) -> species.reshape(v) 726 ); 727 } 728 729 // Accessors 730 731 @Override 732 public double get(int i) { 733 double[] vec = getElements(); 734 return vec[i]; 735 } 736 737 @Override 738 public Double128Vector with(int i, double e) { 739 double[] res = vec.clone(); 740 res[i] = e; 741 return new Double128Vector(res); 742 } 743 744 // Mask 745 746 static final class Double128Mask extends AbstractMask<Double, Shapes.S128Bit> { 747 static final Double128Mask TRUE_MASK = new Double128Mask(true); 748 static final Double128Mask FALSE_MASK = new Double128Mask(false); 749 750 // FIXME: was temporarily put here to simplify rematerialization support in the JVM 751 private final boolean[] bits; // Don't access directly, use getBits() instead. 752 753 public Double128Mask(boolean[] bits) { 754 this(bits, 0); 755 } 756 757 public Double128Mask(boolean[] bits, int i) { 758 this.bits = Arrays.copyOfRange(bits, i, i + species().length()); 759 } 760 761 public Double128Mask(boolean val) { 762 boolean[] bits = new boolean[species().length()]; 763 Arrays.fill(bits, val); 764 this.bits = bits; 765 } 766 767 boolean[] getBits() { 768 return VectorIntrinsics.maybeRebox(this).bits; 769 } 770 771 @Override 772 Double128Mask uOp(MUnOp f) { 773 boolean[] res = new boolean[species().length()]; 774 boolean[] bits = getBits(); 775 for (int i = 0; i < species().length(); i++) { 776 res[i] = f.apply(i, bits[i]); 777 } 778 return new Double128Mask(res); 779 } 780 781 @Override 782 Double128Mask bOp(Mask<Double, Shapes.S128Bit> o, MBinOp f) { 783 boolean[] res = new boolean[species().length()]; 784 boolean[] bits = getBits(); 785 boolean[] mbits = ((Double128Mask)o).getBits(); 786 for (int i = 0; i < species().length(); i++) { 787 res[i] = f.apply(i, bits[i], mbits[i]); 788 } 789 return new Double128Mask(res); 790 } 791 792 @Override 793 public Double128Species species() { 794 return SPECIES; 795 } 796 797 @Override 798 public Double128Vector toVector() { 799 double[] res = new double[species().length()]; 800 boolean[] bits = getBits(); 801 for (int i = 0; i < species().length(); i++) { 802 res[i] = (double) (bits[i] ? -1 : 0); 803 } 804 return new Double128Vector(res); 805 } 806 807 @Override 808 @ForceInline 809 @SuppressWarnings("unchecked") 810 public <Z> Mask<Z, Shapes.S128Bit> rebracket(Species<Z, Shapes.S128Bit> species) { 811 Objects.requireNonNull(species); 812 // TODO: check proper element type 813 return VectorIntrinsics.reinterpret( 814 Double128Mask.class, double.class, LENGTH, 815 species.elementType(), species.length(), this, 816 (m, t) -> m.reshape(species) 817 ); 818 } 819 820 // Unary operations 821 822 //Mask<E, S> not(); 823 824 // Binary operations 825 826 @Override 827 @ForceInline 828 public Double128Mask and(Mask<Double,Shapes.S128Bit> o) { 829 Objects.requireNonNull(o); 830 Double128Mask m = (Double128Mask)o; 831 return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Double128Mask.class, long.class, LENGTH, 832 this, m, 833 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b)); 834 } 835 836 @Override 837 @ForceInline 838 public Double128Mask or(Mask<Double,Shapes.S128Bit> o) { 839 Objects.requireNonNull(o); 840 Double128Mask m = (Double128Mask)o; 841 return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Double128Mask.class, long.class, LENGTH, 842 this, m, 843 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b)); 844 } 845 846 // Reductions 847 848 @Override 849 @ForceInline 850 public boolean anyTrue() { 851 return VectorIntrinsics.test(COND_notZero, Double128Mask.class, long.class, LENGTH, 852 this, this, 853 (m1, m2) -> super.anyTrue()); 854 } 855 856 @Override 857 @ForceInline 858 public boolean allTrue() { 859 return VectorIntrinsics.test(COND_carrySet, Double128Mask.class, long.class, LENGTH, 860 this, species().maskAllTrue(), 861 (m1, m2) -> super.allTrue()); 862 } 863 } 864 865 // Shuffle 866 867 static final class Double128Shuffle extends AbstractShuffle<Double, Shapes.S128Bit> { 868 static final IntVector.IntSpecies<Shapes.S128Bit> INT_SPECIES = (IntVector.IntSpecies<Shapes.S128Bit>) Vector.speciesInstance(Integer.class, Shapes.S_128_BIT); 869 870 public Double128Shuffle(int[] reorder) { 871 super(reorder); 872 } 873 874 public Double128Shuffle(int[] reorder, int i) { 875 super(reorder, i); 876 } 877 878 @Override 879 public Double128Species species() { 880 return SPECIES; 881 } 882 883 @Override 884 public IntVector.IntSpecies<Shapes.S128Bit> intSpecies() { 885 return INT_SPECIES; 886 } 887 } 888 889 // Species 890 891 @Override 892 public Double128Species species() { 893 return SPECIES; 894 } 895 896 static final class Double128Species extends DoubleSpecies<Shapes.S128Bit> { 897 static final int BIT_SIZE = Shapes.S_128_BIT.bitSize(); 898 899 static final int LENGTH = BIT_SIZE / Double.SIZE; 900 901 @Override 902 public String toString() { 903 StringBuilder sb = new StringBuilder("Shape["); 904 sb.append(bitSize()).append(" bits, "); 905 sb.append(length()).append(" ").append(double.class.getSimpleName()).append("s x "); 906 sb.append(elementSize()).append(" bits"); 907 sb.append("]"); 908 return sb.toString(); 909 } 910 911 @Override 912 @ForceInline 913 public int bitSize() { 914 return BIT_SIZE; 915 } 916 917 @Override 918 @ForceInline 919 public int length() { 920 return LENGTH; 921 } 922 923 @Override 924 @ForceInline 925 public Class<Double> elementType() { 926 return Double.class; 927 } 928 929 @Override 930 @ForceInline 931 public int elementSize() { 932 return Double.SIZE; 933 } 934 935 @Override 936 @ForceInline 937 public Shapes.S128Bit shape() { 938 return Shapes.S_128_BIT; 939 } 940 941 @Override 942 Double128Vector op(FOp f) { 943 double[] res = new double[length()]; 944 for (int i = 0; i < length(); i++) { 945 res[i] = f.apply(i); 946 } 947 return new Double128Vector(res); 948 } 949 950 @Override 951 Double128Vector op(Mask<Double, Shapes.S128Bit> o, FOp f) { 952 double[] res = new double[length()]; 953 boolean[] mbits = ((Double128Mask)o).getBits(); 954 for (int i = 0; i < length(); i++) { 955 if (mbits[i]) { 956 res[i] = f.apply(i); 957 } 958 } 959 return new Double128Vector(res); 960 } 961 962 // Factories 963 964 @Override 965 public Double128Mask maskFromValues(boolean... bits) { 966 return new Double128Mask(bits); 967 } 968 969 @Override 970 public Double128Mask maskFromArray(boolean[] bits, int i) { 971 return new Double128Mask(bits, i); 972 } 973 974 @Override 975 public Double128Shuffle shuffleFromValues(int... ixs) { 976 return new Double128Shuffle(ixs); 977 } 978 979 @Override 980 public Double128Shuffle shuffleFromArray(int[] ixs, int i) { 981 return new Double128Shuffle(ixs, i); 982 } 983 984 @Override 985 @ForceInline 986 public Double128Vector zero() { 987 return VectorIntrinsics.broadcastCoerced(Double128Vector.class, double.class, LENGTH, 988 Double.doubleToLongBits(0.0f), 989 (z -> ZERO)); 990 } 991 992 @Override 993 @ForceInline 994 public Double128Vector broadcast(double e) { 995 return VectorIntrinsics.broadcastCoerced( 996 Double128Vector.class, double.class, LENGTH, 997 Double.doubleToLongBits(e), 998 ((long bits) -> SPECIES.op(i -> Double.longBitsToDouble((long)bits)))); 999 } 1000 1001 @Override 1002 @ForceInline 1003 public Double128Mask maskAllTrue() { 1004 return VectorIntrinsics.broadcastCoerced(Double128Mask.class, long.class, LENGTH, 1005 (long)-1, 1006 (z -> Double128Mask.TRUE_MASK)); 1007 } 1008 1009 @Override 1010 @ForceInline 1011 public Double128Mask maskAllFalse() { 1012 return VectorIntrinsics.broadcastCoerced(Double128Mask.class, long.class, LENGTH, 1013 0, 1014 (z -> Double128Mask.FALSE_MASK)); 1015 } 1016 1017 @Override 1018 @ForceInline 1019 public Double128Vector fromArray(double[] a, int ix) { 1020 Objects.requireNonNull(a); 1021 ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH); 1022 return (Double128Vector) VectorIntrinsics.load(Double128Vector.class, double.class, LENGTH, 1023 a, ix, 1024 (arr, idx) -> super.fromArray((double[]) arr, idx)); 1025 } 1026 1027 @Override 1028 @ForceInline 1029 public Double128Vector fromArray(double[] a, int ax, Mask<Double, Shapes.S128Bit> m) { 1030 return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]); 1031 } 1032 1033 @Override 1034 @ForceInline 1035 @SuppressWarnings("unchecked") 1036 public <T extends Shape> Double128Vector resize(Vector<Double, T> o) { 1037 Objects.requireNonNull(o); 1038 if (o.bitSize() == 64) { 1039 Double64Vector so = (Double64Vector)o; 1040 return VectorIntrinsics.reinterpret( 1041 Double64Vector.class, double.class, so.length(), 1042 Double.class, LENGTH, so, 1043 (v, t) -> (Double128Vector)reshape(v) 1044 ); 1045 } else if (o.bitSize() == 128) { 1046 Double128Vector so = (Double128Vector)o; 1047 return VectorIntrinsics.reinterpret( 1048 Double128Vector.class, double.class, so.length(), 1049 Double.class, LENGTH, so, 1050 (v, t) -> (Double128Vector)reshape(v) 1051 ); 1052 } else if (o.bitSize() == 256) { 1053 Double256Vector so = (Double256Vector)o; 1054 return VectorIntrinsics.reinterpret( 1055 Double256Vector.class, double.class, so.length(), 1056 Double.class, LENGTH, so, 1057 (v, t) -> (Double128Vector)reshape(v) 1058 ); 1059 } else if (o.bitSize() == 512) { 1060 Double512Vector so = (Double512Vector)o; 1061 return VectorIntrinsics.reinterpret( 1062 Double512Vector.class, double.class, so.length(), 1063 Double.class, LENGTH, so, 1064 (v, t) -> (Double128Vector)reshape(v) 1065 ); 1066 } else { 1067 throw new InternalError("Unimplemented size"); 1068 } 1069 } 1070 } 1071 }