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