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