1 /* 2 * Copyright (c) 2017, 2019, 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.nio.ByteOrder; 29 import java.util.Arrays; 30 import java.util.Objects; 31 import java.util.function.BinaryOperator; 32 import java.util.function.IntUnaryOperator; 33 import java.util.function.Function; 34 import java.util.function.UnaryOperator; 35 import java.util.concurrent.ThreadLocalRandom; 36 37 import jdk.internal.misc.Unsafe; 38 import jdk.internal.vm.annotation.ForceInline; 39 40 import static jdk.incubator.vector.VectorIntrinsics.*; 41 import static jdk.incubator.vector.VectorOperators.*; 42 43 // -- This file was mechanically generated: Do not edit! -- // 44 45 /** 46 * A specialized {@link Vector} representing an ordered immutable sequence of 47 * {@code byte} values. 48 */ 49 @SuppressWarnings("cast") // warning: redundant cast 50 public abstract class ByteVector extends AbstractVector<Byte> { 51 52 ByteVector() {} 53 54 static final int FORBID_OPCODE_KIND = VO_ONLYFP; 55 56 @ForceInline 57 static int opCode(Operator op) { 58 return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); 59 } 60 @ForceInline 61 static int opCode(Operator op, int requireKind) { 62 requireKind |= VO_OPCODE_VALID; 63 return VectorOperators.opCode(op, requireKind, FORBID_OPCODE_KIND); 64 } 65 @ForceInline 66 static boolean opKind(Operator op, int bit) { 67 return VectorOperators.opKind(op, bit); 68 } 69 70 // Virtualized factories and operators, 71 // coded with portable definitions. 72 // These are all @ForceInline in case 73 // they need to be used performantly. 74 // The various shape-specific subclasses 75 // also specialize them by wrapping 76 // them in a call like this: 77 // return (Byte128Vector) 78 // super.bOp((Byte128Vector) o); 79 // The purpose of that is to forcibly inline 80 // the generic definition from this file 81 // into a sharply type- and size-specific 82 // wrapper in the subclass file, so that 83 // the JIT can specialize the code. 84 // The code is only inlined and expanded 85 // if it gets hot. Think of it as a cheap 86 // and lazy version of C++ templates. 87 88 // Virtualized getter 89 90 /*package-private*/ 91 abstract byte[] getElements(); 92 93 // Virtualized constructors 94 95 /** 96 * Build a vector directly using my own constructor. 97 * It is an error if the array is aliased elsewhere. 98 */ 99 /*package-private*/ 100 abstract ByteVector vectorFactory(byte[] vec); 101 102 /** 103 * Build a mask directly using my species. 104 * It is an error if the array is aliased elsewhere. 105 */ 106 /*package-private*/ 107 @ForceInline 108 final 109 AbstractMask<Byte> maskFactory(boolean[] bits) { 110 return vspecies().maskFactory(bits); 111 } 112 113 // Constant loader (takes dummy as vector arg) 114 interface FVOp { 115 byte apply(int i); 116 } 117 118 /*package-private*/ 119 @ForceInline 120 final 121 ByteVector vOp(FVOp f) { 122 byte[] res = new byte[length()]; 123 for (int i = 0; i < res.length; i++) { 124 res[i] = f.apply(i); 125 } 126 return vectorFactory(res); 127 } 128 129 @ForceInline 130 final 131 ByteVector vOp(VectorMask<Byte> m, FVOp f) { 132 byte[] res = new byte[length()]; 133 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 134 for (int i = 0; i < res.length; i++) { 135 if (mbits[i]) { 136 res[i] = f.apply(i); 137 } 138 } 139 return vectorFactory(res); 140 } 141 142 // Unary operator 143 144 /*package-private*/ 145 interface FUnOp { 146 byte apply(int i, byte a); 147 } 148 149 /*package-private*/ 150 abstract 151 ByteVector uOp(FUnOp f); 152 @ForceInline 153 final 154 ByteVector uOpTemplate(FUnOp f) { 155 byte[] vec = getElements(); 156 byte[] res = new byte[length()]; 157 for (int i = 0; i < res.length; i++) { 158 res[i] = f.apply(i, vec[i]); 159 } 160 return vectorFactory(res); 161 } 162 163 /*package-private*/ 164 abstract 165 ByteVector uOp(VectorMask<Byte> m, 166 FUnOp f); 167 @ForceInline 168 final 169 ByteVector uOpTemplate(VectorMask<Byte> m, 170 FUnOp f) { 171 byte[] vec = getElements(); 172 byte[] res = new byte[length()]; 173 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 174 for (int i = 0; i < res.length; i++) { 175 res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i]; 176 } 177 return vectorFactory(res); 178 } 179 180 // Binary operator 181 182 /*package-private*/ 183 interface FBinOp { 184 byte apply(int i, byte a, byte b); 185 } 186 187 /*package-private*/ 188 abstract 189 ByteVector bOp(Vector<Byte> o, 190 FBinOp f); 191 @ForceInline 192 final 193 ByteVector bOpTemplate(Vector<Byte> o, 194 FBinOp f) { 195 byte[] res = new byte[length()]; 196 byte[] vec1 = this.getElements(); 197 byte[] vec2 = ((ByteVector)o).getElements(); 198 for (int i = 0; i < res.length; i++) { 199 res[i] = f.apply(i, vec1[i], vec2[i]); 200 } 201 return vectorFactory(res); 202 } 203 204 /*package-private*/ 205 abstract 206 ByteVector bOp(Vector<Byte> o, 207 VectorMask<Byte> m, 208 FBinOp f); 209 @ForceInline 210 final 211 ByteVector bOpTemplate(Vector<Byte> o, 212 VectorMask<Byte> m, 213 FBinOp f) { 214 byte[] res = new byte[length()]; 215 byte[] vec1 = this.getElements(); 216 byte[] vec2 = ((ByteVector)o).getElements(); 217 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 218 for (int i = 0; i < res.length; i++) { 219 res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i]; 220 } 221 return vectorFactory(res); 222 } 223 224 // Ternary operator 225 226 /*package-private*/ 227 interface FTriOp { 228 byte apply(int i, byte a, byte b, byte c); 229 } 230 231 /*package-private*/ 232 abstract 233 ByteVector tOp(Vector<Byte> o1, 234 Vector<Byte> o2, 235 FTriOp f); 236 @ForceInline 237 final 238 ByteVector tOpTemplate(Vector<Byte> o1, 239 Vector<Byte> o2, 240 FTriOp f) { 241 byte[] res = new byte[length()]; 242 byte[] vec1 = this.getElements(); 243 byte[] vec2 = ((ByteVector)o1).getElements(); 244 byte[] vec3 = ((ByteVector)o2).getElements(); 245 for (int i = 0; i < res.length; i++) { 246 res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]); 247 } 248 return vectorFactory(res); 249 } 250 251 /*package-private*/ 252 abstract 253 ByteVector tOp(Vector<Byte> o1, 254 Vector<Byte> o2, 255 VectorMask<Byte> m, 256 FTriOp f); 257 @ForceInline 258 final 259 ByteVector tOpTemplate(Vector<Byte> o1, 260 Vector<Byte> o2, 261 VectorMask<Byte> m, 262 FTriOp f) { 263 byte[] res = new byte[length()]; 264 byte[] vec1 = this.getElements(); 265 byte[] vec2 = ((ByteVector)o1).getElements(); 266 byte[] vec3 = ((ByteVector)o2).getElements(); 267 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 268 for (int i = 0; i < res.length; i++) { 269 res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i]; 270 } 271 return vectorFactory(res); 272 } 273 274 // Reduction operator 275 276 /*package-private*/ 277 abstract 278 byte rOp(byte v, FBinOp f); 279 @ForceInline 280 final 281 byte rOpTemplate(byte v, FBinOp f) { 282 byte[] vec = getElements(); 283 for (int i = 0; i < vec.length; i++) { 284 v = f.apply(i, v, vec[i]); 285 } 286 return v; 287 } 288 289 // Memory reference 290 291 /*package-private*/ 292 interface FLdOp<M> { 293 byte apply(M memory, int offset, int i); 294 } 295 296 /*package-private*/ 297 @ForceInline 298 final 299 <M> ByteVector ldOp(M memory, int offset, 300 FLdOp<M> f) { 301 //dummy; no vec = getElements(); 302 byte[] res = new byte[length()]; 303 for (int i = 0; i < res.length; i++) { 304 res[i] = f.apply(memory, offset, i); 305 } 306 return vectorFactory(res); 307 } 308 309 /*package-private*/ 310 @ForceInline 311 final 312 <M> ByteVector ldOp(M memory, int offset, 313 VectorMask<Byte> m, 314 FLdOp<M> f) { 315 //byte[] vec = getElements(); 316 byte[] res = new byte[length()]; 317 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 318 for (int i = 0; i < res.length; i++) { 319 if (mbits[i]) { 320 res[i] = f.apply(memory, offset, i); 321 } 322 } 323 return vectorFactory(res); 324 } 325 326 interface FStOp<M> { 327 void apply(M memory, int offset, int i, byte a); 328 } 329 330 /*package-private*/ 331 @ForceInline 332 final 333 <M> void stOp(M memory, int offset, 334 FStOp<M> f) { 335 byte[] vec = getElements(); 336 for (int i = 0; i < vec.length; i++) { 337 f.apply(memory, offset, i, vec[i]); 338 } 339 } 340 341 /*package-private*/ 342 @ForceInline 343 final 344 <M> void stOp(M memory, int offset, 345 VectorMask<Byte> m, 346 FStOp<M> f) { 347 byte[] vec = getElements(); 348 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 349 for (int i = 0; i < vec.length; i++) { 350 if (mbits[i]) { 351 f.apply(memory, offset, i, vec[i]); 352 } 353 } 354 } 355 356 // Binary test 357 358 /*package-private*/ 359 interface FBinTest { 360 boolean apply(int cond, int i, byte a, byte b); 361 } 362 363 /*package-private*/ 364 @ForceInline 365 final 366 AbstractMask<Byte> bTest(int cond, 367 Vector<Byte> o, 368 FBinTest f) { 369 byte[] vec1 = getElements(); 370 byte[] vec2 = ((ByteVector)o).getElements(); 371 boolean[] bits = new boolean[length()]; 372 for (int i = 0; i < length(); i++){ 373 bits[i] = f.apply(cond, i, vec1[i], vec2[i]); 374 } 375 return maskFactory(bits); 376 } 377 378 /*package-private*/ 379 @ForceInline 380 static boolean doBinTest(int cond, byte a, byte b) { 381 switch (cond) { 382 case BT_eq: return a == b; 383 case BT_ne: return a != b; 384 case BT_lt: return a < b; 385 case BT_le: return a <= b; 386 case BT_gt: return a > b; 387 case BT_ge: return a >= b; 388 } 389 throw new AssertionError(Integer.toHexString(cond)); 390 } 391 392 /*package-private*/ 393 @Override 394 abstract ByteSpecies vspecies(); 395 396 /*package-private*/ 397 @ForceInline 398 static long toBits(byte e) { 399 return e; 400 } 401 402 /*package-private*/ 403 @ForceInline 404 static byte fromBits(long bits) { 405 return ((byte)bits); 406 } 407 408 // Static factories (other than memory operations) 409 410 // Note: A surprising behavior in javadoc 411 // sometimes makes a lone /** {@inheritDoc} */ 412 // comment drop the method altogether, 413 // apparently if the method mentions an 414 // parameter or return type of Vector<Byte> 415 // instead of Vector<E> as originally specified. 416 // Adding an empty HTML fragment appears to 417 // nudge javadoc into providing the desired 418 // inherited documentation. We use the HTML 419 // comment <!--workaround--> for this. 420 421 /** 422 * {@inheritDoc} <!--workaround--> 423 */ 424 @ForceInline 425 public static ByteVector zero(VectorSpecies<Byte> species) { 426 ByteSpecies vsp = (ByteSpecies) species; 427 return VectorIntrinsics.broadcastCoerced(vsp.vectorType(), byte.class, species.length(), 428 0, vsp, 429 ((bits_, s_) -> s_.rvOp(i -> bits_))); 430 } 431 432 /** 433 * Returns a vector of the same species as this one 434 * where all lane elements are set to 435 * the primitive value {@code e}. 436 * 437 * The contents of the current vector are discarded; 438 * only the species is relevant to this operation. 439 * 440 * <p> This method returns the value of this expression: 441 * {@code ByteVector.broadcast(this.species(), e)}. 442 * 443 * @apiNote 444 * Unlike the similar method named {@code broadcast()} 445 * in the supertype {@code Vector}, this method does not 446 * need to validate its argument, and cannot throw 447 * {@code IllegalArgumentException}. This method is 448 * therefore preferable to the supertype method. 449 * 450 * @param e the value to broadcast 451 * @return a vector where all lane elements are set to 452 * the primitive value {@code e} 453 * @see #broadcast(VectorSpecies,long) 454 * @see Vector#broadcast(long) 455 * @see VectorSpecies#broadcast(long) 456 */ 457 public abstract ByteVector broadcast(byte e); 458 459 /** 460 * Returns a vector of the given species 461 * where all lane elements are set to 462 * the primitive value {@code e}. 463 * 464 * @param species species of the desired vector 465 * @param e the value to broadcast 466 * @return a vector where all lane elements are set to 467 * the primitive value {@code e} 468 * @see #broadcast(long) 469 * @see Vector#broadcast(long) 470 * @see VectorSpecies#broadcast(long) 471 */ 472 public static ByteVector broadcast(VectorSpecies<Byte> species, byte e) { 473 ByteSpecies vsp = (ByteSpecies) species; 474 return vsp.broadcast(e); 475 } 476 477 /*package-private*/ 478 @ForceInline 479 final ByteVector broadcastTemplate(byte e) { 480 ByteSpecies vsp = vspecies(); 481 return vsp.broadcast(e); 482 } 483 484 /** 485 * {@inheritDoc} <!--workaround--> 486 * @apiNote 487 * When working with vector subtypes like {@code ByteVector}, 488 * {@linkplain #broadcast(byte) the more strongly typed method} 489 * is typically selected. It can be explicitly selected 490 * using a cast: {@code v.broadcast((byte)e)}. 491 * The two expressions will produce numerically identical results. 492 */ 493 @Override 494 public abstract ByteVector broadcast(long e); 495 496 /** 497 * Returns a vector of the given species 498 * where all lane elements are set to 499 * the primitive value {@code e}. 500 * 501 * The {@code long} value must be accurately representable 502 * by the {@code ETYPE} of the vector species, so that 503 * {@code e==(long)(ETYPE)e}. 504 * 505 * @param species species of the desired vector 506 * @param e the value to broadcast 507 * @return a vector where all lane elements are set to 508 * the primitive value {@code e} 509 * @throws IllegalArgumentException 510 * if the given {@code long} value cannot 511 * be represented by the vector's {@code ETYPE} 512 * @see #broadcast(VectorSpecies,byte) 513 * @see VectorSpecies#checkValue(VectorSpecies,byte) 514 */ 515 public static ByteVector broadcast(VectorSpecies<Byte> species, long e) { 516 ByteSpecies vsp = (ByteSpecies) species; 517 return vsp.broadcast(e); 518 } 519 520 /*package-private*/ 521 @ForceInline 522 final ByteVector broadcastTemplate(long e) { 523 return vspecies().broadcast(e); 524 } 525 526 /** 527 * Returns a vector where each lane element is set to given 528 * primitive values. 529 * <p> 530 * For each vector lane, where {@code N} is the vector lane index, the 531 * the primitive value at index {@code N} is placed into the resulting 532 * vector at lane index {@code N}. 533 * 534 * @param species species of the desired vector 535 * @param es the given primitive values 536 * @return a vector where each lane element is set to given primitive 537 * values 538 * @throws IllegalArgumentException 539 * if {@code es.length != species.length()} 540 */ 541 @ForceInline 542 @SuppressWarnings("unchecked") 543 public static ByteVector fromValues(VectorSpecies<Byte> species, byte... es) { 544 ByteSpecies vsp = (ByteSpecies) species; 545 int vlength = vsp.laneCount(); 546 VectorIntrinsics.requireLength(es.length, vlength); 547 // Get an unaliased copy and use it directly: 548 return vsp.vectorFactory(Arrays.copyOf(es, vlength)); 549 } 550 551 /** 552 * Returns a vector where the first lane element is set to the primtive 553 * value {@code e}, all other lane elements are set to the default 554 * value. 555 * 556 * @param species species of the desired vector 557 * @param e the value 558 * @return a vector where the first lane element is set to the primitive 559 * value {@code e} 560 */ 561 // FIXME: Does this carry its weight? 562 @ForceInline 563 public static ByteVector single(VectorSpecies<Byte> species, byte e) { 564 return zero(species).withLane(0, e); 565 } 566 567 /** 568 * Returns a vector where each lane element is set to a randomly 569 * generated primitive value. 570 * 571 * The semantics are equivalent to calling 572 * {@code (byte)}{@link ThreadLocalRandom#nextInt()} 573 * for each lane, from first to last. 574 * 575 * @param species species of the desired vector 576 * @return a vector where each lane elements is set to a randomly 577 * generated primitive value 578 */ 579 public static ByteVector random(VectorSpecies<Byte> species) { 580 ByteSpecies vsp = (ByteSpecies) species; 581 ThreadLocalRandom r = ThreadLocalRandom.current(); 582 return vsp.vOp(i -> nextRandom(r)); 583 } 584 private static byte nextRandom(ThreadLocalRandom r) { 585 return (byte) r.nextInt(); 586 } 587 588 // Unary lanewise support 589 590 /** 591 * {@inheritDoc} <!--workaround--> 592 */ 593 public abstract 594 ByteVector lanewise(VectorOperators.Unary op); 595 596 @ForceInline 597 final 598 ByteVector lanewiseTemplate(VectorOperators.Unary op) { 599 if (opKind(op, VO_SPECIAL)) { 600 if (op == ZOMO) { 601 return blend(broadcast(-1), compare(NE, 0)); 602 } 603 if (op == NEG) { 604 // FIXME: Support this in the JIT. 605 return broadcast(0).lanewiseTemplate(SUB, this); 606 } 607 } 608 int opc = opCode(op); 609 return VectorIntrinsics.unaryOp( 610 opc, getClass(), byte.class, length(), 611 this, 612 UN_IMPL.find(op, opc, (opc_) -> { 613 switch (opc_) { 614 case VECTOR_OP_NEG: return v0 -> 615 v0.uOp((i, a) -> (byte) -a); 616 case VECTOR_OP_ABS: return v0 -> 617 v0.uOp((i, a) -> (byte) Math.abs(a)); 618 case VECTOR_OP_NOT: return v0 -> 619 v0.uOp((i, a) -> (byte) ~a); 620 default: return null; 621 }})); 622 } 623 private static final 624 ImplCache<Unary,UnaryOperator<ByteVector>> UN_IMPL 625 = new ImplCache<>(Unary.class, ByteVector.class); 626 627 /** 628 * {@inheritDoc} <!--workaround--> 629 */ 630 @ForceInline 631 public final 632 ByteVector lanewise(VectorOperators.Unary op, 633 VectorMask<Byte> m) { 634 return blend(lanewise(op), m); 635 } 636 637 // Binary lanewise support 638 639 /** 640 * {@inheritDoc} <!--workaround--> 641 * @see #lanewise(VectorOperators.Binary,byte) 642 * @see #lanewise(VectorOperators.Binary,byte,VectorMask) 643 */ 644 @Override 645 public abstract 646 ByteVector lanewise(VectorOperators.Binary op, 647 Vector<Byte> v); 648 @ForceInline 649 final 650 ByteVector lanewiseTemplate(VectorOperators.Binary op, 651 Vector<Byte> v) { 652 ByteVector that = (ByteVector) v; 653 that.check(this); 654 if (opKind(op, VO_SPECIAL | VO_SHIFT)) { 655 if (op == FIRST_NONZERO) { 656 // FIXME: Support this in the JIT. 657 VectorMask<Byte> thisNZ 658 = this.viewAsIntegralLanes().compare(NE, (byte) 0); 659 that = that.blend((byte) 0, thisNZ.cast(vspecies())); 660 op = OR_UNCHECKED; 661 } 662 if (opKind(op, VO_SHIFT)) { 663 // As per shift specification for Java, mask the shift count. 664 // This allows the JIT to ignore some ISA details. 665 that = that.lanewise(AND, SHIFT_MASK); 666 } 667 if (op == ROR || op == ROL) { // FIXME: JIT should do this 668 ByteVector neg = that.lanewise(NEG); 669 ByteVector hi = this.lanewise(LSHL, (op == ROR) ? neg : that); 670 ByteVector lo = this.lanewise(LSHR, (op == ROR) ? that : neg); 671 return hi.lanewise(OR, lo); 672 } else if (op == ANDC2) { 673 // FIXME: Support this in the JIT. 674 that = that.lanewise(NOT); 675 op = AND; 676 } else if (op == DIV) { 677 VectorMask<Byte> eqz = that.eq((byte)0); 678 if (eqz.anyTrue()) { 679 throw that.divZeroException(); 680 } 681 } 682 } 683 int opc = opCode(op); 684 return VectorIntrinsics.binaryOp( 685 opc, getClass(), byte.class, length(), 686 this, that, 687 BIN_IMPL.find(op, opc, (opc_) -> { 688 switch (opc_) { 689 case VECTOR_OP_ADD: return (v0, v1) -> 690 v0.bOp(v1, (i, a, b) -> (byte)(a + b)); 691 case VECTOR_OP_SUB: return (v0, v1) -> 692 v0.bOp(v1, (i, a, b) -> (byte)(a - b)); 693 case VECTOR_OP_MUL: return (v0, v1) -> 694 v0.bOp(v1, (i, a, b) -> (byte)(a * b)); 695 case VECTOR_OP_DIV: return (v0, v1) -> 696 v0.bOp(v1, (i, a, b) -> (byte)(a / b)); 697 case VECTOR_OP_MAX: return (v0, v1) -> 698 v0.bOp(v1, (i, a, b) -> (byte)Math.max(a, b)); 699 case VECTOR_OP_MIN: return (v0, v1) -> 700 v0.bOp(v1, (i, a, b) -> (byte)Math.min(a, b)); 701 case VECTOR_OP_FIRST_NONZERO: return (v0, v1) -> 702 v0.bOp(v1, (i, a, b) -> toBits(a) != 0 ? a : b); 703 case VECTOR_OP_AND: return (v0, v1) -> 704 v0.bOp(v1, (i, a, b) -> (byte)(a & b)); 705 case VECTOR_OP_OR: return (v0, v1) -> 706 v0.bOp(v1, (i, a, b) -> (byte)(a | b)); 707 case VECTOR_OP_ANDC2: return (v0, v1) -> 708 v0.bOp(v1, (i, a, b) -> (byte)(a & ~b)); 709 case VECTOR_OP_XOR: return (v0, v1) -> 710 v0.bOp(v1, (i, a, b) -> (byte)(a ^ b)); 711 case VECTOR_OP_LSHIFT: return (v0, v1) -> 712 v0.bOp(v1, (i, a, n) -> (byte)(a << n)); 713 case VECTOR_OP_RSHIFT: return (v0, v1) -> 714 v0.bOp(v1, (i, a, n) -> (byte)(a >> n)); 715 case VECTOR_OP_URSHIFT: return (v0, v1) -> 716 v0.bOp(v1, (i, a, n) -> (byte)((a & LSHR_SETUP_MASK) >>> n)); 717 case VECTOR_OP_LROTATE: return (v0, v1) -> 718 v0.bOp(v1, (i, a, n) -> (byte)((a << n)|(a >> -n))); 719 case VECTOR_OP_RROTATE: return (v0, v1) -> 720 v0.bOp(v1, (i, a, n) -> (byte)((a >> n)|(a << -n))); 721 default: return null; 722 }})); 723 } 724 private static final 725 ImplCache<Binary,BinaryOperator<ByteVector>> BIN_IMPL 726 = new ImplCache<>(Binary.class, ByteVector.class); 727 728 /** 729 * {@inheritDoc} <!--workaround--> 730 * @see #lanewise(VectorOperators.Binary,byte,VectorMask) 731 */ 732 @ForceInline 733 public final 734 ByteVector lanewise(VectorOperators.Binary op, 735 Vector<Byte> v, 736 VectorMask<Byte> m) { 737 ByteVector that = (ByteVector) v; 738 if (op == DIV) { 739 // suppress div/0 exceptions in unset lanes 740 that = that.lanewise(NOT, that.eq((byte)0)); 741 return blend(lanewise(DIV, that), m); 742 } 743 return blend(lanewise(op, v), m); 744 } 745 // FIXME: Maybe all of the public final methods in this file (the 746 // simple ones that just call lanewise) should be pushed down to 747 // the X-VectorBits template. They can't optimize properly at 748 // this level, and must rely on inlining. Does it work? 749 // (If it works, of course keep the code here.) 750 751 /** 752 * Combines the lane values of this vector 753 * with the value of a broadcast scalar. 754 * 755 * This is a lane-wise binary operation which applies 756 * the selected operation to each lane. 757 * The return value will be equal to this expression: 758 * {@code this.lanewise(op, this.broadcast(e))}. 759 * 760 * @param e the input scalar 761 * @return the result of applying the operation lane-wise 762 * to the two input vectors 763 * @throws UnsupportedOperationException if this vector does 764 * not support the requested operation 765 * @see #lanewise(VectorOperators.Binary,Vector) 766 * @see #lanewise(VectorOperators.Binary,byte,VectorMask) 767 */ 768 @ForceInline 769 public final 770 ByteVector lanewise(VectorOperators.Binary op, 771 byte e) { 772 int opc = opCode(op); 773 if (opKind(op, VO_SHIFT) && (byte)(int)e == e) { 774 return lanewiseShift(op, (int) e); 775 } 776 if (op == ANDC2) { 777 op = AND; e = (byte) ~e; 778 } 779 return lanewise(op, broadcast(e)); 780 } 781 782 /** 783 * Combines the lane values of this vector 784 * with the value of a broadcast scalar, 785 * with selection of lane elements controlled by a mask. 786 * 787 * This is a masked lane-wise binary operation which applies 788 * the selected operation to each lane. 789 * The return value will be equal to this expression: 790 * {@code this.lanewise(op, this.broadcast(e), m)}. 791 * 792 * @param e the input scalar 793 * @param m the mask controlling lane selection 794 * @return the result of applying the operation lane-wise 795 * to the input vector and the scalar 796 * @throws UnsupportedOperationException if this vector does 797 * not support the requested operation 798 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 799 * @see #lanewise(VectorOperators.Binary,byte) 800 */ 801 @ForceInline 802 public final 803 ByteVector lanewise(VectorOperators.Binary op, 804 byte e, 805 VectorMask<Byte> m) { 806 return blend(lanewise(op, e), m); 807 } 808 809 /** 810 * {@inheritDoc} <!--workaround--> 811 * @apiNote 812 * When working with vector subtypes like {@code ByteVector}, 813 * {@linkplain #lanewise(VectorOperators.Binary,byte) 814 * the more strongly typed method} 815 * is typically selected. It can be explicitly selected 816 * using a cast: {@code v.lanewise(op,(byte)e)}. 817 * The two expressions will produce numerically identical results. 818 */ 819 @ForceInline 820 public final 821 ByteVector lanewise(VectorOperators.Binary op, 822 long e) { 823 byte e1 = (byte) e; 824 if ((long)e1 != e 825 // allow shift ops to clip down their int parameters 826 && !(opKind(op, VO_SHIFT) && (int)e1 == e) 827 ) { 828 vspecies().checkValue(e); // for exception 829 } 830 return lanewise(op, e1); 831 } 832 833 /** 834 * {@inheritDoc} <!--workaround--> 835 * @apiNote 836 * When working with vector subtypes like {@code ByteVector}, 837 * {@linkplain #lanewise(VectorOperators.Binary,byte,VectorMask) 838 * the more strongly typed method} 839 * is typically selected. It can be explicitly selected 840 * using a cast: {@code v.lanewise(op,(byte)e,m)}. 841 * The two expressions will produce numerically identical results. 842 */ 843 @ForceInline 844 public final 845 ByteVector lanewise(VectorOperators.Binary op, 846 long e, VectorMask<Byte> m) { 847 return blend(lanewise(op, e), m); 848 } 849 850 /*package-private*/ 851 abstract ByteVector 852 lanewiseShift(VectorOperators.Binary op, int e); 853 854 /*package-private*/ 855 @ForceInline 856 final ByteVector 857 lanewiseShiftTemplate(VectorOperators.Binary op, int e) { 858 // Special handling for these. FIXME: Refactor? 859 int opc = opCode(op); 860 assert(opKind(op, VO_SHIFT)); 861 // As per shift specification for Java, mask the shift count. 862 e &= SHIFT_MASK; 863 if (op == ROR || op == ROL) { // FIXME: JIT should do this 864 ByteVector hi = this.lanewise(LSHL, (op == ROR) ? -e : e); 865 ByteVector lo = this.lanewise(LSHR, (op == ROR) ? e : -e); 866 return hi.lanewise(OR, lo); 867 } 868 return VectorIntrinsics.broadcastInt( 869 opc, getClass(), byte.class, length(), 870 this, e, 871 BIN_INT_IMPL.find(op, opc, (opc_) -> { 872 switch (opc_) { 873 case VECTOR_OP_LSHIFT: return (v, n) -> 874 v.uOp((i, a) -> (byte)(a << n)); 875 case VECTOR_OP_RSHIFT: return (v, n) -> 876 v.uOp((i, a) -> (byte)(a >> n)); 877 case VECTOR_OP_URSHIFT: return (v, n) -> 878 v.uOp((i, a) -> (byte)((a & LSHR_SETUP_MASK) >>> n)); 879 case VECTOR_OP_LROTATE: return (v, n) -> 880 v.uOp((i, a) -> (byte)((a << n)|(a >> -n))); 881 case VECTOR_OP_RROTATE: return (v, n) -> 882 v.uOp((i, a) -> (byte)((a >> n)|(a << -n))); 883 default: return null; 884 }})); 885 } 886 private static final 887 ImplCache<Binary,VectorBroadcastIntOp<ByteVector>> BIN_INT_IMPL 888 = new ImplCache<>(Binary.class, ByteVector.class); 889 890 // As per shift specification for Java, mask the shift count. 891 // We mask 0X3F (long), 0X1F (int), 0x0F (short), 0x7 (byte). 892 // The latter two maskings go beyond the JLS, but seem reasonable 893 // since our lane types are first-class types, not just dressed 894 // up ints. 895 private static final int SHIFT_MASK = (Byte.SIZE - 1); 896 // Also simulate >>> on sub-word variables with a mask. 897 private static final int LSHR_SETUP_MASK = ((1 << Byte.SIZE) - 1); 898 899 // Ternary lanewise support 900 901 // Ternary operators come in eight variations: 902 // lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2]) 903 // lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask) 904 905 // It is annoying to support all of these variations of masking 906 // and broadcast, but it would be more surprising not to continue 907 // the obvious pattern started by unary and binary. 908 909 /** 910 * {@inheritDoc} <!--workaround--> 911 * @see #lanewise(VectorOperators.Ternary,byte,byte,VectorMask) 912 * @see #lanewise(VectorOperators.Ternary,Vector,byte,VectorMask) 913 * @see #lanewise(VectorOperators.Ternary,byte,Vector,VectorMask) 914 * @see #lanewise(VectorOperators.Ternary,byte,byte) 915 * @see #lanewise(VectorOperators.Ternary,Vector,byte) 916 * @see #lanewise(VectorOperators.Ternary,byte,Vector) 917 */ 918 @Override 919 public abstract 920 ByteVector lanewise(VectorOperators.Ternary op, 921 Vector<Byte> v1, 922 Vector<Byte> v2); 923 @ForceInline 924 final 925 ByteVector lanewiseTemplate(VectorOperators.Ternary op, 926 Vector<Byte> v1, 927 Vector<Byte> v2) { 928 ByteVector that = (ByteVector) v1; 929 ByteVector tother = (ByteVector) v2; 930 // It's a word: https://www.dictionary.com/browse/tother 931 // See also Chapter 11 of Dickens, Our Mutual Friend: 932 // "Totherest Governor," replied Mr Riderhood... 933 that.check(this); 934 tother.check(this); 935 if (op == BITWISE_BLEND) { 936 // FIXME: Support this in the JIT. 937 that = this.lanewise(XOR, that).lanewise(AND, tother); 938 return this.lanewise(XOR, that); 939 } 940 int opc = opCode(op); 941 return VectorIntrinsics.ternaryOp( 942 opc, getClass(), byte.class, length(), 943 this, that, tother, 944 TERN_IMPL.find(op, opc, (opc_) -> { 945 switch (opc_) { 946 case VECTOR_OP_BITWISE_BLEND: return (v0, v1_, v2_) -> 947 v0.tOp(v1_, v2_, (i, a, b, c) -> (byte)(a^((a^b)&c))); 948 default: return null; 949 }})); 950 } 951 private static final 952 ImplCache<Ternary,TernaryOperation<ByteVector>> TERN_IMPL 953 = new ImplCache<>(Ternary.class, ByteVector.class); 954 955 /** 956 * {@inheritDoc} <!--workaround--> 957 * @see #lanewise(VectorOperators.Ternary,byte,byte,VectorMask) 958 * @see #lanewise(VectorOperators.Ternary,Vector,byte,VectorMask) 959 * @see #lanewise(VectorOperators.Ternary,byte,Vector,VectorMask) 960 */ 961 @ForceInline 962 public final 963 ByteVector lanewise(VectorOperators.Ternary op, 964 Vector<Byte> v1, 965 Vector<Byte> v2, 966 VectorMask<Byte> m) { 967 return blend(lanewise(op, v1, v2), m); 968 } 969 970 /** 971 * Combines the lane values of this vector 972 * with the values of two broadcast scalars. 973 * 974 * This is a lane-wise ternary operation which applies 975 * the selected operation to each lane. 976 * The return value will be equal to this expression: 977 * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}. 978 * 979 * @param e1 the first input scalar 980 * @param e2 the second input scalar 981 * @return the result of applying the operation lane-wise 982 * to the input vector and the scalars 983 * @throws UnsupportedOperationException if this vector does 984 * not support the requested operation 985 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 986 * @see #lanewise(VectorOperators.Ternary,byte,byte,VectorMask) 987 */ 988 @ForceInline 989 public final 990 ByteVector lanewise(VectorOperators.Ternary op, //(op,e1,e2) 991 byte e1, 992 byte e2) { 993 return lanewise(op, broadcast(e1), broadcast(e1)); 994 } 995 996 /** 997 * Combines the lane values of this vector 998 * with the values of two broadcast scalars, 999 * with selection of lane elements controlled by a mask. 1000 * 1001 * This is a masked lane-wise ternary operation which applies 1002 * the selected operation to each lane. 1003 * The return value will be equal to this expression: 1004 * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}. 1005 * 1006 * @param e1 the first input scalar 1007 * @param e2 the second input scalar 1008 * @param m the mask controlling lane selection 1009 * @return the result of applying the operation lane-wise 1010 * to the input vector and the scalars 1011 * @throws UnsupportedOperationException if this vector does 1012 * not support the requested operation 1013 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 1014 * @see #lanewise(VectorOperators.Ternary,byte,byte) 1015 */ 1016 @ForceInline 1017 public final 1018 ByteVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m) 1019 byte e1, 1020 byte e2, 1021 VectorMask<Byte> m) { 1022 return blend(lanewise(op, e1, e2), m); 1023 } 1024 1025 /** 1026 * Combines the lane values of this vector 1027 * with the values of another vector and a broadcast scalar. 1028 * 1029 * This is a lane-wise ternary operation which applies 1030 * the selected operation to each lane. 1031 * The return value will be equal to this expression: 1032 * {@code this.lanewise(op, v1, this.broadcast(e2))}. 1033 * 1034 * @param v1 the other input vector 1035 * @param e2 the input scalar 1036 * @return the result of applying the operation lane-wise 1037 * to the input vectors and the scalar 1038 * @throws UnsupportedOperationException if this vector does 1039 * not support the requested operation 1040 * @see #lanewise(VectorOperators.Ternary,byte,byte) 1041 * @see #lanewise(VectorOperators.Ternary,Vector,byte,VectorMask) 1042 */ 1043 @ForceInline 1044 public final 1045 ByteVector lanewise(VectorOperators.Ternary op, //(op,v1,e2) 1046 Vector<Byte> v1, 1047 byte e2) { 1048 return lanewise(op, v1, broadcast(e2)); 1049 } 1050 1051 /** 1052 * Combines the lane values of this vector 1053 * with the values of another vector and a broadcast scalar, 1054 * with selection of lane elements controlled by a mask. 1055 * 1056 * This is a masked lane-wise ternary operation which applies 1057 * the selected operation to each lane. 1058 * The return value will be equal to this expression: 1059 * {@code this.lanewise(op, v1, this.broadcast(e2), m)}. 1060 * 1061 * @param v1 the other input vector 1062 * @param e2 the input scalar 1063 * @param m the mask controlling lane selection 1064 * @return the result of applying the operation lane-wise 1065 * to the input vectors and the scalar 1066 * @throws UnsupportedOperationException if this vector does 1067 * not support the requested operation 1068 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 1069 * @see #lanewise(VectorOperators.Ternary,byte,byte,VectorMask) 1070 * @see #lanewise(VectorOperators.Ternary,Vector,byte) 1071 */ 1072 @ForceInline 1073 public final 1074 ByteVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m) 1075 Vector<Byte> v1, 1076 byte e2, 1077 VectorMask<Byte> m) { 1078 return blend(lanewise(op, v1, e2), m); 1079 } 1080 1081 /** 1082 * Combines the lane values of this vector 1083 * with the values of another vector and a broadcast scalar. 1084 * 1085 * This is a lane-wise ternary operation which applies 1086 * the selected operation to each lane. 1087 * The return value will be equal to this expression: 1088 * {@code this.lanewise(op, this.broadcast(e1), v2)}. 1089 * 1090 * @param e1 the input scalar 1091 * @param v2 the other input vector 1092 * @return the result of applying the operation lane-wise 1093 * to the input vectors and the scalar 1094 * @throws UnsupportedOperationException if this vector does 1095 * not support the requested operation 1096 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 1097 * @see #lanewise(VectorOperators.Ternary,byte,Vector,VectorMask) 1098 */ 1099 @ForceInline 1100 public final 1101 ByteVector lanewise(VectorOperators.Ternary op, //(op,e1,v2) 1102 byte e1, 1103 Vector<Byte> v2) { 1104 return lanewise(op, broadcast(e1), v2); 1105 } 1106 1107 /** 1108 * Combines the lane values of this vector 1109 * with the values of another vector and a broadcast scalar, 1110 * with selection of lane elements controlled by a mask. 1111 * 1112 * This is a masked lane-wise ternary operation which applies 1113 * the selected operation to each lane. 1114 * The return value will be equal to this expression: 1115 * {@code this.lanewise(op, this.broadcast(e1), v2, m)}. 1116 * 1117 * @param e1 the input scalar 1118 * @param v2 the other input vector 1119 * @param m the mask controlling lane selection 1120 * @return the result of applying the operation lane-wise 1121 * to the input vectors and the scalar 1122 * @throws UnsupportedOperationException if this vector does 1123 * not support the requested operation 1124 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 1125 * @see #lanewise(VectorOperators.Ternary,byte,Vector) 1126 */ 1127 @ForceInline 1128 public final 1129 ByteVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m) 1130 byte e1, 1131 Vector<Byte> v2, 1132 VectorMask<Byte> m) { 1133 return blend(lanewise(op, e1, v2), m); 1134 } 1135 1136 // (Thus endeth the Great and Mighty Ternary Ogdoad.) 1137 // https://en.wikipedia.org/wiki/Ogdoad 1138 1139 /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV 1140 // 1141 // These include masked and non-masked versions. 1142 // This subclass adds broadcast (masked or not). 1143 1144 /** 1145 * {@inheritDoc} <!--workaround--> 1146 * @see #add(byte) 1147 */ 1148 @Override 1149 @ForceInline 1150 public final ByteVector add(Vector<Byte> v) { 1151 return lanewise(ADD, v); 1152 } 1153 1154 /** 1155 * Adds this vector to the broadcast of an input scalar. 1156 * 1157 * This is a lane-wise binary operation which applies 1158 * the primitive addition operation ({@code +}) to each lane. 1159 * 1160 * This method is also equivalent to the expression 1161 * {@link #lanewise(VectorOperators.Binary,byte) 1162 * lanewise}{@code (}{@link VectorOperators#ADD 1163 * ADD}{@code , e)}. 1164 * 1165 * @param e the input scalar 1166 * @return the result of adding each lane of this vector to the scalar 1167 * @see #add(Vector) 1168 * @see #broadcast(byte) 1169 * @see #add(int,VectorMask) 1170 * @see VectorOperators#ADD 1171 * @see #lanewise(VectorOperators.Binary,Vector) 1172 * @see #lanewise(VectorOperators.Binary,byte) 1173 */ 1174 @ForceInline 1175 public final 1176 ByteVector add(byte e) { 1177 return lanewise(ADD, e); 1178 } 1179 1180 /** 1181 * {@inheritDoc} <!--workaround--> 1182 * @see #add(byte,VectorMask) 1183 */ 1184 @Override 1185 @ForceInline 1186 public final ByteVector add(Vector<Byte> v, 1187 VectorMask<Byte> m) { 1188 return lanewise(ADD, v, m); 1189 } 1190 1191 /** 1192 * Adds this vector to the broadcast of an input scalar, 1193 * selecting lane elements controlled by a mask. 1194 * 1195 * This is a masked lane-wise binary operation which applies 1196 * the primitive addition operation ({@code +}) to each lane. 1197 * 1198 * This method is also equivalent to the expression 1199 * {@link #lanewise(VectorOperators.Binary,byte,VectorMask) 1200 * lanewise}{@code (}{@link VectorOperators#ADD 1201 * ADD}{@code , s, m)}. 1202 * 1203 * @param e the input scalar 1204 * @param m the mask controlling lane selection 1205 * @return the result of adding each lane of this vector to the scalar 1206 * @see #add(Vector,VectorMask) 1207 * @see #broadcast(byte) 1208 * @see #add(int) 1209 * @see VectorOperators#ADD 1210 * @see #lanewise(VectorOperators.Binary,Vector) 1211 * @see #lanewise(VectorOperators.Binary,byte) 1212 */ 1213 @ForceInline 1214 public final ByteVector add(byte e, 1215 VectorMask<Byte> m) { 1216 return lanewise(ADD, e, m); 1217 } 1218 1219 /** 1220 * {@inheritDoc} <!--workaround--> 1221 * @see #sub(byte) 1222 */ 1223 @Override 1224 @ForceInline 1225 public final ByteVector sub(Vector<Byte> v) { 1226 return lanewise(SUB, v); 1227 } 1228 1229 /** 1230 * Subtracts an input scalar from this vector. 1231 * 1232 * This is a masked lane-wise binary operation which applies 1233 * the primitive subtraction operation ({@code -}) to each lane. 1234 * 1235 * This method is also equivalent to the expression 1236 * {@link #lanewise(VectorOperators.Binary,byte) 1237 * lanewise}{@code (}{@link VectorOperators#SUB 1238 * SUB}{@code , e)}. 1239 * 1240 * @param e the input scalar 1241 * @return the result of subtracting the scalar from each lane of this vector 1242 * @see #sub(Vector) 1243 * @see #broadcast(byte) 1244 * @see #sub(int,VectorMask) 1245 * @see VectorOperators#SUB 1246 * @see #lanewise(VectorOperators.Binary,Vector) 1247 * @see #lanewise(VectorOperators.Binary,byte) 1248 */ 1249 @ForceInline 1250 public final ByteVector sub(byte e) { 1251 return lanewise(SUB, e); 1252 } 1253 1254 /** 1255 * {@inheritDoc} <!--workaround--> 1256 * @see #sub(byte,VectorMask) 1257 */ 1258 @Override 1259 @ForceInline 1260 public final ByteVector sub(Vector<Byte> v, 1261 VectorMask<Byte> m) { 1262 return lanewise(SUB, v, m); 1263 } 1264 1265 /** 1266 * Subtracts an input scalar from this vector 1267 * under the control of a mask. 1268 * 1269 * This is a masked lane-wise binary operation which applies 1270 * the primitive subtraction operation ({@code -}) to each lane. 1271 * 1272 * This method is also equivalent to the expression 1273 * {@link #lanewise(VectorOperators.Binary,byte,VectorMask) 1274 * lanewise}{@code (}{@link VectorOperators#SUB 1275 * SUB}{@code , s, m)}. 1276 * 1277 * @param e the input scalar 1278 * @param m the mask controlling lane selection 1279 * @return the result of subtracting the scalar from each lane of this vector 1280 * @see #sub(Vector,VectorMask) 1281 * @see #broadcast(byte) 1282 * @see #sub(int) 1283 * @see VectorOperators#SUB 1284 * @see #lanewise(VectorOperators.Binary,Vector) 1285 * @see #lanewise(VectorOperators.Binary,byte) 1286 */ 1287 @ForceInline 1288 public final ByteVector sub(byte e, 1289 VectorMask<Byte> m) { 1290 return lanewise(SUB, e, m); 1291 } 1292 1293 /** 1294 * {@inheritDoc} <!--workaround--> 1295 * @see #mul(byte) 1296 */ 1297 @Override 1298 @ForceInline 1299 public final ByteVector mul(Vector<Byte> v) { 1300 return lanewise(MUL, v); 1301 } 1302 1303 /** 1304 * Multiplies this vector by the broadcast of an input scalar. 1305 * 1306 * This is a lane-wise binary operation which applies 1307 * the primitive multiplication operation ({@code *}) to each lane. 1308 * 1309 * This method is also equivalent to the expression 1310 * {@link #lanewise(VectorOperators.Binary,byte) 1311 * lanewise}{@code (}{@link VectorOperators#MUL 1312 * MUL}{@code , e)}. 1313 * 1314 * @param e the input scalar 1315 * @return the result of multiplying this vector by the given scalar 1316 * @see #mul(Vector) 1317 * @see #broadcast(byte) 1318 * @see #mul(int,VectorMask) 1319 * @see VectorOperators#MUL 1320 * @see #lanewise(VectorOperators.Binary,Vector) 1321 * @see #lanewise(VectorOperators.Binary,byte) 1322 */ 1323 @ForceInline 1324 public final ByteVector mul(byte e) { 1325 return lanewise(MUL, e); 1326 } 1327 1328 /** 1329 * {@inheritDoc} <!--workaround--> 1330 * @see #mul(byte,VectorMask) 1331 */ 1332 @Override 1333 @ForceInline 1334 public final ByteVector mul(Vector<Byte> v, 1335 VectorMask<Byte> m) { 1336 return lanewise(MUL, v, m); 1337 } 1338 1339 /** 1340 * Multiplies this vector by the broadcast of an input scalar, 1341 * selecting lane elements controlled by a mask. 1342 * 1343 * This is a masked lane-wise binary operation which applies 1344 * the primitive multiplication operation ({@code *}) to each lane. 1345 * 1346 * This method is also equivalent to the expression 1347 * {@link #lanewise(VectorOperators.Binary,byte,VectorMask) 1348 * lanewise}{@code (}{@link VectorOperators#MUL 1349 * MUL}{@code , s, m)}. 1350 * 1351 * @param e the input scalar 1352 * @param m the mask controlling lane selection 1353 * @return the result of muling each lane of this vector to the scalar 1354 * @see #mul(Vector,VectorMask) 1355 * @see #broadcast(byte) 1356 * @see #mul(int) 1357 * @see VectorOperators#MUL 1358 * @see #lanewise(VectorOperators.Binary,Vector) 1359 * @see #lanewise(VectorOperators.Binary,byte) 1360 */ 1361 @ForceInline 1362 public final ByteVector mul(byte e, 1363 VectorMask<Byte> m) { 1364 return lanewise(MUL, e, m); 1365 } 1366 1367 /** 1368 * {@inheritDoc} <!--workaround--> 1369 * @see #div(byte) 1370 */ 1371 @Override 1372 @ForceInline 1373 public final ByteVector div(Vector<Byte> v) { 1374 return lanewise(DIV, v); 1375 } 1376 1377 /** 1378 * Divides this vector by the broadcast of an input scalar. 1379 * 1380 * This is a lane-wise binary operation which applies 1381 * the primitive division operation ({@code /}) to each lane. 1382 * 1383 * This method is also equivalent to the expression 1384 * {@link #lanewise(VectorOperators.Binary,byte) 1385 * lanewise}{@code (}{@link VectorOperators#DIV 1386 * DIV}{@code , e)}. 1387 * 1388 * <p> 1389 * If the underlying scalar operator does not support 1390 * division by zero, but is presented with a zero divisor, 1391 * an {@code ArithmeticException} will be thrown. 1392 * 1393 * @param e the input scalar 1394 * @return the result of dividing each lane of this vector by the scalar 1395 * @see #div(Vector) 1396 * @see #broadcast(byte) 1397 * @see #div(int,VectorMask) 1398 * @see VectorOperators#DIV 1399 * @see #lanewise(VectorOperators.Binary,Vector) 1400 * @see #lanewise(VectorOperators.Binary,byte) 1401 */ 1402 @ForceInline 1403 public final ByteVector div(byte e) { 1404 return lanewise(DIV, e); 1405 } 1406 1407 /** 1408 /** 1409 * {@inheritDoc} <!--workaround--> 1410 * @see #div(byte,VectorMask) 1411 */ 1412 @Override 1413 @ForceInline 1414 public final ByteVector div(Vector<Byte> v, 1415 VectorMask<Byte> m) { 1416 return lanewise(DIV, v, m); 1417 } 1418 1419 /** 1420 * Divides this vector by the broadcast of an input scalar, 1421 * selecting lane elements controlled by a mask. 1422 * 1423 * This is a masked lane-wise binary operation which applies 1424 * the primitive division operation ({@code /}) to each lane. 1425 * 1426 * This method is also equivalent to the expression 1427 * {@link #lanewise(VectorOperators.Binary,byte,VectorMask) 1428 * lanewise}{@code (}{@link VectorOperators#DIV 1429 * DIV}{@code , s, m)}. 1430 * 1431 * <p> 1432 * If the underlying scalar operator does not support 1433 * division by zero, but is presented with a zero divisor, 1434 * an {@code ArithmeticException} will be thrown. 1435 * 1436 * @param e the input scalar 1437 * @param m the mask controlling lane selection 1438 * @return the result of dividing each lane of this vector by the scalar 1439 * @see #div(Vector,VectorMask) 1440 * @see #broadcast(byte) 1441 * @see #div(int) 1442 * @see VectorOperators#DIV 1443 * @see #lanewise(VectorOperators.Binary,Vector) 1444 * @see #lanewise(VectorOperators.Binary,byte) 1445 */ 1446 @ForceInline 1447 public final ByteVector div(byte e, 1448 VectorMask<Byte> m) { 1449 return lanewise(DIV, e, m); 1450 } 1451 1452 /// END OF FULL-SERVICE BINARY METHODS 1453 1454 /// SECOND-TIER BINARY METHODS 1455 // 1456 // There are no masked versions. 1457 1458 /** 1459 * {@inheritDoc} <!--workaround--> 1460 */ 1461 @Override 1462 @ForceInline 1463 public final ByteVector min(Vector<Byte> v) { 1464 return lanewise(MIN, v); 1465 } 1466 1467 // FIXME: "broadcast of an input scalar" is really wordy. Reduce? 1468 /** 1469 * Computes the smaller of this vector and the broadcast of an input scalar. 1470 * 1471 * This is a lane-wise binary operation which appliesthe 1472 * operation {@code (a, b) -> a < b ? a : b} to each pair of 1473 * corresponding lane values. 1474 * 1475 * This method is also equivalent to the expression 1476 * {@link #lanewise(VectorOperators.Binary,byte) 1477 * lanewise}{@code (}{@link VectorOperators#MIN 1478 * MIN}{@code , e)}. 1479 * 1480 * @param e the input scalar 1481 * @return the result of multiplying this vector by the given scalar 1482 * @see #min(Vector) 1483 * @see #broadcast(byte) 1484 * @see VectorOperators#MIN 1485 * @see #lanewise(VectorOperators.Binary,byte,VectorMask) 1486 */ 1487 @ForceInline 1488 public final ByteVector min(byte e) { 1489 return lanewise(MIN, e); 1490 } 1491 1492 /** 1493 * {@inheritDoc} <!--workaround--> 1494 */ 1495 @Override 1496 @ForceInline 1497 public final ByteVector max(Vector<Byte> v) { 1498 return lanewise(MAX, v); 1499 } 1500 1501 /** 1502 * Computes the larger of this vector and the broadcast of an input scalar. 1503 * 1504 * This is a lane-wise binary operation which appliesthe 1505 * operation {@code (a, b) -> a > b ? a : b} to each pair of 1506 * corresponding lane values. 1507 * 1508 * This method is also equivalent to the expression 1509 * {@link #lanewise(VectorOperators.Binary,byte) 1510 * lanewise}{@code (}{@link VectorOperators#MAX 1511 * MAX}{@code , e)}. 1512 * 1513 * @param e the input scalar 1514 * @return the result of multiplying this vector by the given scalar 1515 * @see #max(Vector) 1516 * @see #broadcast(byte) 1517 * @see VectorOperators#MAX 1518 * @see #lanewise(VectorOperators.Binary,byte,VectorMask) 1519 */ 1520 @ForceInline 1521 public final ByteVector max(byte e) { 1522 return lanewise(MAX, e); 1523 } 1524 1525 // common bitwise operators: and, or, not (with scalar versions) 1526 /** 1527 * Computes the bitwise logical conjunction ({@code &}) 1528 * of this vector and a second input vector. 1529 * 1530 * This is a lane-wise binary operation which applies the 1531 * the primitive bitwise "and" operation ({@code &}) 1532 * to each pair of corresponding lane values. 1533 * 1534 * This method is also equivalent to the expression 1535 * {@link #lanewise(VectorOperators.Binary,Vector) 1536 * lanewise}{@code (}{@link VectorOperators#AND 1537 * AND}{@code , v)}. 1538 * 1539 * <p> 1540 * This is not a full-service named operation like 1541 * {@link #add(Vector) add}. A masked version of 1542 * version of this operation is not directly available 1543 * but may be obtained via the masked version of 1544 * {@code lanewise}. 1545 * 1546 * @param v a second input vector 1547 * @return the bitwise {@code &} of this vector and the second input vector 1548 * @see #and(byte) 1549 * @see #or(Vector) 1550 * @see #not() 1551 * @see VectorOperators#AND 1552 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1553 */ 1554 @ForceInline 1555 public final ByteVector and(Vector<Byte> v) { 1556 return lanewise(AND, v); 1557 } 1558 1559 /** 1560 * Computes the bitwise logical conjunction ({@code &}) 1561 * of this vector and a scalar. 1562 * 1563 * This is a lane-wise binary operation which applies the 1564 * the primitive bitwise "and" operation ({@code &}) 1565 * to each pair of corresponding lane values. 1566 * 1567 * This method is also equivalent to the expression 1568 * {@link #lanewise(VectorOperators.Binary,Vector) 1569 * lanewise}{@code (}{@link VectorOperators#AND 1570 * AND}{@code , e)}. 1571 * 1572 * @param e an input scalar 1573 * @return the bitwise {@code &} of this vector and scalar 1574 * @see #and(Vector) 1575 * @see VectorOperators#AND 1576 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1577 */ 1578 @ForceInline 1579 public final ByteVector and(byte e) { 1580 return lanewise(AND, e); 1581 } 1582 1583 /** 1584 * Computes the bitwise logical disjunction ({@code |}) 1585 * of this vector and a second input vector. 1586 * 1587 * This is a lane-wise binary operation which applies the 1588 * the primitive bitwise "or" operation ({@code |}) 1589 * to each pair of corresponding lane values. 1590 * 1591 * This method is also equivalent to the expression 1592 * {@link #lanewise(VectorOperators.Binary,Vector) 1593 * lanewise}{@code (}{@link VectorOperators#OR 1594 * AND}{@code , v)}. 1595 * 1596 * <p> 1597 * This is not a full-service named operation like 1598 * {@link #add(Vector) add}. A masked version of 1599 * version of this operation is not directly available 1600 * but may be obtained via the masked version of 1601 * {@code lanewise}. 1602 * 1603 * @param v a second input vector 1604 * @return the bitwise {@code |} of this vector and the second input vector 1605 * @see #or(byte) 1606 * @see #and(Vector) 1607 * @see #not() 1608 * @see VectorOperators#OR 1609 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1610 */ 1611 @ForceInline 1612 public final ByteVector or(Vector<Byte> v) { 1613 return lanewise(OR, v); 1614 } 1615 1616 /** 1617 * Computes the bitwise logical disjunction ({@code |}) 1618 * of this vector and a scalar. 1619 * 1620 * This is a lane-wise binary operation which applies the 1621 * the primitive bitwise "or" operation ({@code |}) 1622 * to each pair of corresponding lane values. 1623 * 1624 * This method is also equivalent to the expression 1625 * {@link #lanewise(VectorOperators.Binary,Vector) 1626 * lanewise}{@code (}{@link VectorOperators#OR 1627 * OR}{@code , e)}. 1628 * 1629 * @param e an input scalar 1630 * @return the bitwise {@code |} of this vector and scalar 1631 * @see #or(Vector) 1632 * @see VectorOperators#OR 1633 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1634 */ 1635 @ForceInline 1636 public final ByteVector or(byte e) { 1637 return lanewise(OR, e); 1638 } 1639 1640 1641 1642 /// UNARY METHODS 1643 1644 /** 1645 * {@inheritDoc} <!--workaround--> 1646 */ 1647 @Override 1648 @ForceInline 1649 public final 1650 ByteVector neg() { 1651 return lanewise(NEG); 1652 } 1653 1654 /** 1655 * {@inheritDoc} <!--workaround--> 1656 */ 1657 @Override 1658 @ForceInline 1659 public final 1660 ByteVector abs() { 1661 return lanewise(ABS); 1662 } 1663 1664 // not (~) 1665 /** 1666 * Computes the bitwise logical complement ({@code ~}) 1667 * of this vector. 1668 * 1669 * This is a lane-wise binary operation which applies the 1670 * the primitive bitwise "not" operation ({@code ~}) 1671 * to each lane value. 1672 * 1673 * This method is also equivalent to the expression 1674 * {@link #lanewise(VectorOperators.Unary,Vector) 1675 * lanewise}{@code (}{@link VectorOperators#NOT 1676 * NOT}{@code )}. 1677 * 1678 * <p> 1679 * This is not a full-service named operation like 1680 * {@link #add(Vector) add}. A masked version of 1681 * version of this operation is not directly available 1682 * but may be obtained via the masked version of 1683 * {@code lanewise}. 1684 * 1685 * @return the bitwise complement {@code ~} of this vector 1686 * @see #and(Vector) 1687 * @see VectorOperators#NOT 1688 * @see #lanewise(VectorOperators.Unary,Vector,VectorMask) 1689 */ 1690 @ForceInline 1691 public final ByteVector not() { 1692 return lanewise(NOT); 1693 } 1694 1695 1696 /// COMPARISONS 1697 1698 /** 1699 * {@inheritDoc} <!--workaround--> 1700 */ 1701 @Override 1702 @ForceInline 1703 public final 1704 VectorMask<Byte> eq(Vector<Byte> v) { 1705 return compare(EQ, v); 1706 } 1707 1708 /** 1709 * Tests if this vector is equal to an input scalar. 1710 * 1711 * This is a lane-wise binary test operation which applies 1712 * the primitive equals operation ({@code ==}) to each lane. 1713 * The result is the same as {@code compare(VectorOperators.Comparison.EQ, e)}. 1714 * 1715 * @param e the input scalar 1716 * @return the result mask of testing if this vector 1717 * is equal to {@code e} 1718 * @see #compare(VectorOperators.Comparison,byte) 1719 */ 1720 @ForceInline 1721 public final 1722 VectorMask<Byte> eq(byte e) { 1723 return compare(EQ, e); 1724 } 1725 1726 /** 1727 * {@inheritDoc} <!--workaround--> 1728 */ 1729 @Override 1730 @ForceInline 1731 public final 1732 VectorMask<Byte> lt(Vector<Byte> v) { 1733 return compare(LT, v); 1734 } 1735 1736 /** 1737 * Tests if this vector is less than an input scalar. 1738 * 1739 * This is a lane-wise binary test operation which applies 1740 * the primitive less than operation ({@code <}) to each lane. 1741 * The result is the same as {@code compare(VectorOperators.LT, e)}. 1742 * 1743 * @param e the input scalar 1744 * @return the mask result of testing if this vector 1745 * is less than the input scalar 1746 * @see #compare(VectorOperators.Comparison,byte) 1747 */ 1748 @ForceInline 1749 public final 1750 VectorMask<Byte> lt(byte e) { 1751 return compare(LT, e); 1752 } 1753 1754 /** 1755 * {@inheritDoc} <!--workaround--> 1756 */ 1757 @Override 1758 public abstract 1759 VectorMask<Byte> compare(VectorOperators.Comparison op, Vector<Byte> v); 1760 1761 /*package-private*/ 1762 @ForceInline 1763 final 1764 <M extends VectorMask<Byte>> 1765 M compareTemplate(Class<M> maskType, Comparison op, Vector<Byte> v) { 1766 Objects.requireNonNull(v); 1767 ByteSpecies vsp = vspecies(); 1768 int opc = opCode(op); 1769 return VectorIntrinsics.compare( 1770 opc, getClass(), maskType, byte.class, length(), 1771 this, (ByteVector) v, 1772 (cond, v0, v1) -> { 1773 AbstractMask<Byte> m 1774 = v0.bTest(cond, v1, (cond_, i, a, b) 1775 -> compareWithOp(cond, a, b)); 1776 @SuppressWarnings("unchecked") 1777 M m2 = (M) m; 1778 return m2; 1779 }); 1780 } 1781 1782 @ForceInline 1783 private static 1784 boolean compareWithOp(int cond, byte a, byte b) { 1785 switch (cond) { 1786 case VectorIntrinsics.BT_eq: return a == b; 1787 case VectorIntrinsics.BT_ne: return a != b; 1788 case VectorIntrinsics.BT_lt: return a < b; 1789 case VectorIntrinsics.BT_le: return a <= b; 1790 case VectorIntrinsics.BT_gt: return a > b; 1791 case VectorIntrinsics.BT_ge: return a >= b; 1792 } 1793 throw new AssertionError(); 1794 } 1795 1796 /** 1797 * {@inheritDoc} <!--workaround--> 1798 */ 1799 @Override 1800 @ForceInline 1801 public final 1802 VectorMask<Byte> compare(VectorOperators.Comparison op, 1803 Vector<Byte> v, 1804 VectorMask<Byte> m) { 1805 return compare(op, v).and(m); 1806 } 1807 1808 /** 1809 * Tests this vector by comparing it with an input scalar, 1810 * according to the given comparison operation. 1811 * 1812 * This is a lane-wise binary test operation which applies 1813 * the comparison operation to each lane. 1814 * <p> 1815 * The result is the same as 1816 * {@code compare(op, broadcast(species(), e))}. 1817 * That is, the scalar may be regarded as broadcast to 1818 * a vector of the same species, and then compared 1819 * against the original vector, using the selected 1820 * comparison operation. 1821 * 1822 * @param e the input scalar 1823 * @return the mask result of testing lane-wise if this vector 1824 * compares to the input, according to the selected 1825 * comparison operator 1826 * @see ByteVector#compare(VectorOperators.Comparison,Vector) 1827 * @see #eq(byte) 1828 * @see #lessThan(byte) 1829 */ 1830 public abstract 1831 VectorMask<Byte> compare(Comparison op, byte e); 1832 1833 /*package-private*/ 1834 @ForceInline 1835 final 1836 <M extends VectorMask<Byte>> 1837 M compareTemplate(Class<M> maskType, Comparison op, byte e) { 1838 return compareTemplate(maskType, op, broadcast(e)); 1839 } 1840 1841 /** 1842 * Tests this vector by comparing it with an input scalar, 1843 * according to the given comparison operation, 1844 * in lanes selected by a mask. 1845 * 1846 * This is a masked lane-wise binary test operation which applies 1847 * to each pair of corresponding lane values. 1848 * 1849 * The returned result is equal to the expression 1850 * {@code compare(op,s).and(m)}. 1851 * 1852 * @param e the input scalar 1853 * @param m the mask controlling lane selection 1854 * @return the mask result of testing lane-wise if this vector 1855 * compares to the input, according to the selected 1856 * comparison operator, 1857 * and only in the lanes selected by the mask 1858 * @see ByteVector#compare(VectorOperators.Comparison,Vector,VectorMask) 1859 */ 1860 @ForceInline 1861 public final VectorMask<Byte> compare(VectorOperators.Comparison op, 1862 byte e, 1863 VectorMask<Byte> m) { 1864 return compare(op, e).and(m); 1865 } 1866 1867 /** 1868 * {@inheritDoc} <!--workaround--> 1869 */ 1870 @Override 1871 public abstract 1872 VectorMask<Byte> compare(Comparison op, long e); 1873 1874 /*package-private*/ 1875 @ForceInline 1876 final 1877 <M extends VectorMask<Byte>> 1878 M compareTemplate(Class<M> maskType, Comparison op, long e) { 1879 return compareTemplate(maskType, op, broadcast(e)); 1880 } 1881 1882 /** 1883 * {@inheritDoc} <!--workaround--> 1884 */ 1885 @Override 1886 @ForceInline 1887 public final 1888 VectorMask<Byte> compare(Comparison op, long e, VectorMask<Byte> m) { 1889 return compare(op, broadcast(e), m); 1890 } 1891 1892 1893 1894 /** 1895 * {@inheritDoc} <!--workaround--> 1896 */ 1897 @Override public abstract 1898 ByteVector blend(Vector<Byte> v, VectorMask<Byte> m); 1899 1900 /*package-private*/ 1901 @ForceInline 1902 final 1903 <M extends VectorMask<Byte>> 1904 ByteVector 1905 blendTemplate(Class<M> maskType, ByteVector v, M m) { 1906 v.check(this); 1907 return VectorIntrinsics.blend( 1908 getClass(), maskType, byte.class, length(), 1909 this, v, m, 1910 (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); 1911 } 1912 1913 /** 1914 * {@inheritDoc} <!--workaround--> 1915 */ 1916 @Override public abstract ByteVector addIndex(int scale); 1917 1918 /*package-private*/ 1919 @ForceInline 1920 final ByteVector addIndexTemplate(int scale) { 1921 ByteSpecies vsp = vspecies(); 1922 // make sure VLENGTH*scale doesn't overflow: 1923 vsp.checkScale(scale); 1924 return VectorIntrinsics.indexVector( 1925 getClass(), byte.class, length(), 1926 this, scale, vsp, 1927 (v, scale_, s) 1928 -> { 1929 // If the platform doesn't support an INDEX 1930 // instruction directly, load IOTA from memory 1931 // and multiply. 1932 ByteVector iota = s.iota(); 1933 byte sc = (byte) scale_; 1934 return v.add(sc == 1 ? iota : iota.mul(sc)); 1935 }); 1936 } 1937 1938 /** 1939 * Replaces selected lanes of this vector with 1940 * a scalar value 1941 * under the control of a mask. 1942 * 1943 * This is a masked lane-wise binary operation which 1944 * selects each lane value from one or the other input. 1945 * 1946 * The returned result is equal to the expression 1947 * {@code blend(broadcast(e),m)}. 1948 * 1949 * @param e the input scalar, containing the replacement lane value 1950 * @param m the mask controlling lane selection of the scalar 1951 * @return the result of blending the lane elements of this vector with 1952 * the scalar value 1953 */ 1954 @ForceInline 1955 public final ByteVector blend(byte e, 1956 VectorMask<Byte> m) { 1957 return blend(broadcast(e), m); 1958 } 1959 1960 /** 1961 * Replaces selected lanes of this vector with 1962 * a scalar value 1963 * under the control of a mask. 1964 * 1965 * This is a masked lane-wise binary operation which 1966 * selects each lane value from one or the other input. 1967 * 1968 * The returned result is equal to the expression 1969 * {@code blend(broadcast(e),m)}. 1970 * 1971 * @param e the input scalar, containing the replacement lane value 1972 * @param m the mask controlling lane selection of the scalar 1973 * @return the result of blending the lane elements of this vector with 1974 * the scalar value 1975 */ 1976 @ForceInline 1977 public final ByteVector blend(long e, 1978 VectorMask<Byte> m) { 1979 return blend(broadcast(e), m); 1980 } 1981 1982 /** 1983 * {@inheritDoc} <!--workaround--> 1984 */ 1985 @Override 1986 public abstract 1987 ByteVector slice(int origin, Vector<Byte> v1); 1988 1989 /*package-private*/ 1990 final 1991 @ForceInline 1992 ByteVector sliceTemplate(int origin, Vector<Byte> v1) { 1993 ByteVector that = (ByteVector) v1; 1994 that.check(this); 1995 byte[] a0 = this.getElements(); 1996 byte[] a1 = that.getElements(); 1997 byte[] res = new byte[a0.length]; 1998 int vlen = res.length; 1999 int firstPart = vlen - origin; 2000 System.arraycopy(a0, origin, res, 0, firstPart); 2001 System.arraycopy(a1, 0, res, firstPart, origin); 2002 return vectorFactory(res); 2003 } 2004 2005 /** 2006 * {@inheritDoc} <!--workaround--> 2007 */ 2008 @Override 2009 @ForceInline 2010 public final 2011 ByteVector slice(int origin, 2012 Vector<Byte> w, 2013 VectorMask<Byte> m) { 2014 return broadcast(0).blend(slice(origin, w), m); 2015 } 2016 2017 /** 2018 * {@inheritDoc} <!--workaround--> 2019 */ 2020 @Override 2021 public abstract 2022 ByteVector slice(int origin); 2023 2024 /** 2025 * {@inheritDoc} <!--workaround--> 2026 */ 2027 @Override 2028 public abstract 2029 ByteVector unslice(int origin, Vector<Byte> w, int part); 2030 2031 /*package-private*/ 2032 final 2033 @ForceInline 2034 ByteVector 2035 unsliceTemplate(int origin, Vector<Byte> w, int part) { 2036 ByteVector that = (ByteVector) w; 2037 that.check(this); 2038 byte[] slice = this.getElements(); 2039 byte[] res = that.getElements(); 2040 int vlen = res.length; 2041 int firstPart = vlen - origin; 2042 switch (part) { 2043 case 0: 2044 System.arraycopy(slice, 0, res, origin, firstPart); 2045 break; 2046 case 1: 2047 System.arraycopy(slice, firstPart, res, 0, origin); 2048 break; 2049 default: 2050 throw wrongPartForSlice(part); 2051 } 2052 return vectorFactory(res); 2053 } 2054 2055 /*package-private*/ 2056 final 2057 @ForceInline 2058 <M extends VectorMask<Byte>> 2059 ByteVector 2060 unsliceTemplate(Class<M> maskType, int origin, Vector<Byte> w, int part, M m) { 2061 ByteVector that = (ByteVector) w; 2062 that.check(this); 2063 ByteVector slice = that.sliceTemplate(origin, that); 2064 slice = slice.blendTemplate(maskType, this, m); 2065 return slice.unsliceTemplate(origin, w, part); 2066 } 2067 2068 /** 2069 * {@inheritDoc} <!--workaround--> 2070 */ 2071 @Override 2072 public abstract 2073 ByteVector unslice(int origin, Vector<Byte> w, int part, VectorMask<Byte> m); 2074 2075 /** 2076 * {@inheritDoc} <!--workaround--> 2077 */ 2078 @Override 2079 public abstract 2080 ByteVector unslice(int origin); 2081 2082 private ArrayIndexOutOfBoundsException 2083 wrongPartForSlice(int part) { 2084 String msg = String.format("bad part number %d for slice operation", 2085 part); 2086 return new ArrayIndexOutOfBoundsException(msg); 2087 } 2088 2089 /** 2090 * {@inheritDoc} <!--workaround--> 2091 */ 2092 @Override 2093 public abstract 2094 ByteVector rearrange(VectorShuffle<Byte> m); 2095 2096 /*package-private*/ 2097 @ForceInline 2098 final 2099 <S extends VectorShuffle<Byte>> 2100 ByteVector rearrangeTemplate(Class<S> shuffletype, S shuffle) { 2101 shuffle.checkIndexes(); 2102 return VectorIntrinsics.rearrangeOp( 2103 getClass(), shuffletype, byte.class, length(), 2104 this, shuffle, 2105 (v1, s_) -> v1.uOp((i, a) -> { 2106 int ei = s_.laneSource(i); 2107 return v1.lane(ei); 2108 })); 2109 } 2110 2111 /** 2112 * {@inheritDoc} <!--workaround--> 2113 */ 2114 @Override 2115 public abstract 2116 ByteVector rearrange(VectorShuffle<Byte> s, 2117 VectorMask<Byte> m); 2118 2119 /*package-private*/ 2120 @ForceInline 2121 final 2122 <S extends VectorShuffle<Byte>> 2123 ByteVector rearrangeTemplate(Class<S> shuffletype, 2124 S shuffle, 2125 VectorMask<Byte> m) { 2126 ByteVector unmasked = 2127 VectorIntrinsics.rearrangeOp( 2128 getClass(), shuffletype, byte.class, length(), 2129 this, shuffle, 2130 (v1, s_) -> v1.uOp((i, a) -> { 2131 int ei = s_.laneSource(i); 2132 return ei < 0 ? 0 : v1.lane(ei); 2133 })); 2134 VectorMask<Byte> valid = shuffle.laneIsValid(); 2135 if (m.andNot(valid).anyTrue()) { 2136 shuffle.checkIndexes(); 2137 throw new AssertionError(); 2138 } 2139 return broadcast((byte)0).blend(unmasked, valid); 2140 } 2141 2142 /** 2143 * {@inheritDoc} <!--workaround--> 2144 */ 2145 @Override 2146 public abstract 2147 ByteVector rearrange(VectorShuffle<Byte> s, 2148 Vector<Byte> v); 2149 2150 /*package-private*/ 2151 @ForceInline 2152 final 2153 <S extends VectorShuffle<Byte>> 2154 ByteVector rearrangeTemplate(Class<S> shuffletype, 2155 S shuffle, 2156 ByteVector v) { 2157 VectorMask<Byte> valid = shuffle.laneIsValid(); 2158 VectorShuffle<Byte> ws = shuffle.wrapIndexes(); 2159 ByteVector r1 = 2160 VectorIntrinsics.rearrangeOp( 2161 getClass(), shuffletype, byte.class, length(), 2162 this, shuffle, 2163 (v1, s_) -> v1.uOp((i, a) -> { 2164 int ei = s_.laneSource(i); 2165 return v1.lane(ei); 2166 })); 2167 ByteVector r2 = 2168 VectorIntrinsics.rearrangeOp( 2169 getClass(), shuffletype, byte.class, length(), 2170 v, shuffle, 2171 (v1, s_) -> v1.uOp((i, a) -> { 2172 int ei = s_.laneSource(i); 2173 return v1.lane(ei); 2174 })); 2175 return r2.blend(r1, valid); 2176 } 2177 2178 /** 2179 * {@inheritDoc} <!--workaround--> 2180 */ 2181 @Override 2182 public abstract 2183 ByteVector selectFrom(Vector<Byte> v); 2184 2185 /*package-private*/ 2186 @ForceInline 2187 final ByteVector selectFromTemplate(ByteVector v) { 2188 return v.rearrange(this.toShuffle()); 2189 } 2190 2191 /** 2192 * {@inheritDoc} <!--workaround--> 2193 */ 2194 @Override 2195 public abstract 2196 ByteVector selectFrom(Vector<Byte> s, VectorMask<Byte> m); 2197 2198 /*package-private*/ 2199 @ForceInline 2200 final ByteVector selectFromTemplate(ByteVector v, 2201 AbstractMask<Byte> m) { 2202 return v.rearrange(this.toShuffle(), m); 2203 } 2204 2205 /// Ternary operations 2206 2207 /** 2208 * Blends together the bits of two vectors under 2209 * the control of a third, which supplies mask bits. 2210 * 2211 * 2212 * This is a lane-wise ternary operation which performs 2213 * a bitwise blending operation {@code (a&~c)|(b&c)} 2214 * to each lane. 2215 * 2216 * This method is also equivalent to the expression 2217 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2218 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2219 * BITWISE_BLEND}{@code , bits, mask)}. 2220 * 2221 * @param bits input bits to blend into the current vector 2222 * @param mask a bitwise mask to enable blending of the input bits 2223 * @return the bitwise blend of the given bits into the current vector, 2224 * under control of the bitwise mask 2225 * @see #bitwiseBlend(byte,byte) 2226 * @see #bitwiseBlend(byte,Vector) 2227 * @see #bitwiseBlend(Vector,byte) 2228 * @see VectorOperators#BITWISE_BLEND 2229 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 2230 */ 2231 @ForceInline 2232 public final 2233 ByteVector bitwiseBlend(Vector<Byte> bits, Vector<Byte> mask) { 2234 return lanewise(BITWISE_BLEND, bits, mask); 2235 } 2236 2237 /** 2238 * Blends together the bits of a vector and a scalar under 2239 * the control of another scalar, which supplies mask bits. 2240 * 2241 * 2242 * This is a lane-wise ternary operation which performs 2243 * a bitwise blending operation {@code (a&~c)|(b&c)} 2244 * to each lane. 2245 * 2246 * This method is also equivalent to the expression 2247 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2248 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2249 * BITWISE_BLEND}{@code , bits, mask)}. 2250 * 2251 * @param bits input bits to blend into the current vector 2252 * @param mask a bitwise mask to enable blending of the input bits 2253 * @return the bitwise blend of the given bits into the current vector, 2254 * under control of the bitwise mask 2255 * @see #bitwiseBlend(Vector,Vector) 2256 * @see VectorOperators#BITWISE_BLEND 2257 * @see #lanewise(VectorOperators.Ternary,byte,byte,VectorMask) 2258 */ 2259 @ForceInline 2260 public final 2261 ByteVector bitwiseBlend(byte bits, byte mask) { 2262 return lanewise(BITWISE_BLEND, bits, mask); 2263 } 2264 2265 /** 2266 * Blends together the bits of a vector and a scalar under 2267 * the control of another vector, which supplies mask bits. 2268 * 2269 * 2270 * This is a lane-wise ternary operation which performs 2271 * a bitwise blending operation {@code (a&~c)|(b&c)} 2272 * to each lane. 2273 * 2274 * This method is also equivalent to the expression 2275 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2276 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2277 * BITWISE_BLEND}{@code , bits, mask)}. 2278 * 2279 * @param bits input bits to blend into the current vector 2280 * @param mask a bitwise mask to enable blending of the input bits 2281 * @return the bitwise blend of the given bits into the current vector, 2282 * under control of the bitwise mask 2283 * @see #bitwiseBlend(Vector,Vector) 2284 * @see VectorOperators#BITWISE_BLEND 2285 * @see #lanewise(VectorOperators.Ternary,byte,Vector,VectorMask) 2286 */ 2287 @ForceInline 2288 public final 2289 ByteVector bitwiseBlend(byte bits, Vector<Byte> mask) { 2290 return lanewise(BITWISE_BLEND, bits, mask); 2291 } 2292 2293 /** 2294 * Blends together the bits of two vectors scalar under 2295 * the control of a scalar, which supplies mask bits. 2296 * 2297 * 2298 * This is a lane-wise ternary operation which performs 2299 * a bitwise blending operation {@code (a&~c)|(b&c)} 2300 * to each lane. 2301 * 2302 * This method is also equivalent to the expression 2303 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2304 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2305 * BITWISE_BLEND}{@code , bits, mask)}. 2306 * 2307 * @param bits input bits to blend into the current vector 2308 * @param mask a bitwise mask to enable blending of the input bits 2309 * @return the bitwise blend of the given bits into the current vector, 2310 * under control of the bitwise mask 2311 * @see #bitwiseBlend(Vector,Vector) 2312 * @see VectorOperators#BITWISE_BLEND 2313 * @see #lanewise(VectorOperators.Ternary,Vector,byte,VectorMask) 2314 */ 2315 @ForceInline 2316 public final 2317 ByteVector bitwiseBlend(Vector<Byte> bits, byte mask) { 2318 return lanewise(BITWISE_BLEND, bits, mask); 2319 } 2320 2321 2322 // Type specific horizontal reductions 2323 2324 /** 2325 * Returns a value accumulated from all the lanes of this vector. 2326 * 2327 * This is an associative cross-lane reduction operation which 2328 * applies the specified operation to all the lane elements. 2329 * 2330 * <p> 2331 * A few reduction operations do not support arbitrary reordering 2332 * of their operands, yet are included here because of their 2333 * usefulness. 2334 * 2335 * <ul> 2336 * <li> 2337 * In the case of {@code FIRST_NONZERO}, the reduction returns 2338 * the value from the lowest-numbered non-zero lane. 2339 * 2340 * 2341 * <li> 2342 * In the case of floating point addition and multiplication, the 2343 * precise result will reflect the choice of an arbitrary order 2344 * of operations, which may even vary over time. 2345 * 2346 * <li> 2347 * All other reduction operations are fully commutative and 2348 * associative. The implementation can choose any order of 2349 * processing, yet it will always produce the same result. 2350 * 2351 * </ul> 2352 * 2353 * 2354 * @param op the operation used to combine lane values 2355 * @return the accumulated result 2356 * @throws UnsupportedOperationException if this vector does 2357 * not support the requested operation 2358 * @see #reduceLanes(VectorOperators.Associative,VectorMask) 2359 * @see #add(Vector) 2360 * @see #mul(Vector) 2361 * @see #min(Vector) 2362 * @see #max(Vector) 2363 * @see #and(Vector) 2364 * @see #or(Vector) 2365 * @see VectorOperators#XOR 2366 * @see VectorOperators#FIRST_NONZERO 2367 */ 2368 public abstract byte reduceLanes(VectorOperators.Associative op); 2369 2370 /** 2371 * Returns a value accumulated from selected lanes of this vector, 2372 * controlled by a mask. 2373 * 2374 * This is an associative cross-lane reduction operation which 2375 * applies the specified operation to the selected lane elements. 2376 * <p> 2377 * If no elements are selected, an operation-specific identity 2378 * value is returned. 2379 * <ul> 2380 * <li> 2381 * If the operation is 2382 * {@code ADD}, {@code XOR}, {@code OR}, 2383 * or {@code FIRST_NONZERO}, 2384 * then the identity value is zero, the default {@code byte} value. 2385 * <li> 2386 * If the operation is {@code MUL}, 2387 * then the identity value is one. 2388 * <li> 2389 * If the operation is {@code AND}, 2390 * then the identity value is minus one (all bits set). 2391 * <li> 2392 * If the operation is {@code MAX}, 2393 * then the identity value is {@code Byte.MIN_VALUE}. 2394 * <li> 2395 * If the operation is {@code MIN}, 2396 * then the identity value is {@code Byte.MAX_VALUE}. 2397 * </ul> 2398 * 2399 * @param op the operation used to combine lane values 2400 * @param m the mask controlling lane selection 2401 * @return the reduced result accumulated from the selected lane values 2402 * @throws UnsupportedOperationException if this vector does 2403 * not support the requested operation 2404 * @see #reduceLanes(VectorOperators.Associative) 2405 */ 2406 public abstract byte reduceLanes(VectorOperators.Associative op, 2407 VectorMask<Byte> m); 2408 2409 /*package-private*/ 2410 @ForceInline 2411 final 2412 byte reduceLanesTemplate(VectorOperators.Associative op, 2413 VectorMask<Byte> m) { 2414 ByteVector v = reduceIdentityVector(op).blend(this, m); 2415 return v.reduceLanesTemplate(op); 2416 } 2417 2418 /*package-private*/ 2419 @ForceInline 2420 final 2421 byte reduceLanesTemplate(VectorOperators.Associative op) { 2422 if (op == FIRST_NONZERO) { 2423 // FIXME: The JIT should handle this, and other scan ops alos. 2424 VectorMask<Byte> thisNZ 2425 = this.viewAsIntegralLanes().compare(NE, (byte) 0); 2426 return this.lane(thisNZ.firstTrue()); 2427 } 2428 int opc = opCode(op); 2429 return fromBits(VectorIntrinsics.reductionCoerced( 2430 opc, getClass(), byte.class, length(), 2431 this, 2432 REDUCE_IMPL.find(op, opc, (opc_) -> { 2433 switch (opc_) { 2434 case VECTOR_OP_ADD: return v -> 2435 toBits(v.rOp((byte)0, (i, a, b) -> (byte)(a + b))); 2436 case VECTOR_OP_MUL: return v -> 2437 toBits(v.rOp((byte)1, (i, a, b) -> (byte)(a * b))); 2438 case VECTOR_OP_MIN: return v -> 2439 toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (byte) Math.min(a, b))); 2440 case VECTOR_OP_MAX: return v -> 2441 toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (byte) Math.max(a, b))); 2442 case VECTOR_OP_FIRST_NONZERO: return v -> 2443 toBits(v.rOp((byte)0, (i, a, b) -> toBits(a) != 0 ? a : b)); 2444 case VECTOR_OP_AND: return v -> 2445 toBits(v.rOp((byte)-1, (i, a, b) -> (byte)(a & b))); 2446 case VECTOR_OP_OR: return v -> 2447 toBits(v.rOp((byte)0, (i, a, b) -> (byte)(a | b))); 2448 case VECTOR_OP_XOR: return v -> 2449 toBits(v.rOp((byte)0, (i, a, b) -> (byte)(a ^ b))); 2450 default: return null; 2451 }}))); 2452 } 2453 private static final 2454 ImplCache<Associative,Function<ByteVector,Long>> REDUCE_IMPL 2455 = new ImplCache<>(Associative.class, ByteVector.class); 2456 2457 private 2458 @ForceInline 2459 ByteVector reduceIdentityVector(VectorOperators.Associative op) { 2460 int opc = opCode(op); 2461 UnaryOperator<ByteVector> fn 2462 = REDUCE_ID_IMPL.find(op, opc, (opc_) -> { 2463 switch (opc_) { 2464 case VECTOR_OP_ADD: 2465 case VECTOR_OP_OR: 2466 case VECTOR_OP_XOR: 2467 case VECTOR_OP_FIRST_NONZERO: 2468 return v -> v.broadcast(0); 2469 case VECTOR_OP_MUL: 2470 return v -> v.broadcast(1); 2471 case VECTOR_OP_AND: 2472 return v -> v.broadcast(-1); 2473 case VECTOR_OP_MIN: 2474 return v -> v.broadcast(MAX_OR_INF); 2475 case VECTOR_OP_MAX: 2476 return v -> v.broadcast(MIN_OR_INF); 2477 default: return null; 2478 } 2479 }); 2480 return fn.apply(this); 2481 } 2482 private static final 2483 ImplCache<Associative,UnaryOperator<ByteVector>> REDUCE_ID_IMPL 2484 = new ImplCache<>(Associative.class, ByteVector.class); 2485 2486 private static final byte MIN_OR_INF = Byte.MIN_VALUE; 2487 private static final byte MAX_OR_INF = Byte.MAX_VALUE; 2488 2489 public @Override abstract long reduceLanesToLong(VectorOperators.Associative op); 2490 public @Override abstract long reduceLanesToLong(VectorOperators.Associative op, 2491 VectorMask<Byte> m); 2492 2493 // Type specific accessors 2494 2495 /** 2496 * Gets the lane element at lane index {@code i} 2497 * 2498 * @param i the lane index 2499 * @return the lane element at lane index {@code i} 2500 * @throws IllegalArgumentException if the index is is out of range 2501 * ({@code < 0 || >= length()}) 2502 */ 2503 public abstract byte lane(int i); 2504 2505 /** 2506 * Replaces the lane element of this vector at lane index {@code i} with 2507 * value {@code e}. 2508 * 2509 * This is a cross-lane operation and behaves as if it returns the result 2510 * of blending this vector with an input vector that is the result of 2511 * broadcasting {@code e} and a mask that has only one lane set at lane 2512 * index {@code i}. 2513 * 2514 * @param i the lane index of the lane element to be replaced 2515 * @param e the value to be placed 2516 * @return the result of replacing the lane element of this vector at lane 2517 * index {@code i} with value {@code e}. 2518 * @throws IllegalArgumentException if the index is is out of range 2519 * ({@code < 0 || >= length()}) 2520 */ 2521 public abstract ByteVector withLane(int i, byte e); 2522 2523 // Memory load operations 2524 2525 /** 2526 * Returns an array of type {@code byte[]} 2527 * containing all the lane values. 2528 * The array length is the same as the vector length. 2529 * The array elements are stored in lane order. 2530 * <p> 2531 * This method behaves as if it stores 2532 * this vector into an allocated array 2533 * (using {@link #intoArray(byte[], int) intoArray}) 2534 * and returns the array as follows: 2535 * <pre>{@code 2536 * byte[] a = new byte[this.length()]; 2537 * this.intoArray(a, 0); 2538 * return a; 2539 * }</pre> 2540 * 2541 * @return an array containing the lane values of this vector 2542 */ 2543 @ForceInline 2544 @Override 2545 public final byte[] toArray() { 2546 byte[] a = new byte[vspecies().laneCount()]; 2547 intoArray(a, 0); 2548 return a; 2549 } 2550 2551 /** {@inheritDoc} <!--workaround--> 2552 * @implNote 2553 * When this method is used on used on vectors 2554 * of type {@code ByteVector}, 2555 * there will be no loss of precision or range. 2556 */ 2557 @ForceInline 2558 @Override 2559 public final long[] toLongArray() { 2560 byte[] a = toArray(); 2561 long[] res = new long[a.length]; 2562 for (int i = 0; i < a.length; i++) { 2563 res[i] = (long) a[i]; 2564 } 2565 return res; 2566 } 2567 2568 /** {@inheritDoc} <!--workaround--> 2569 * @implNote 2570 * When this method is used on used on vectors 2571 * of type {@code ByteVector}, 2572 * there will be no loss of precision. 2573 */ 2574 @ForceInline 2575 @Override 2576 public final double[] toDoubleArray() { 2577 byte[] a = toArray(); 2578 double[] res = new double[a.length]; 2579 for (int i = 0; i < a.length; i++) { 2580 res[i] = (double) a[i]; 2581 } 2582 return res; 2583 } 2584 2585 /** 2586 * Loads a vector from a byte array starting at an offset. 2587 * Bytes are composed into primitive lane elements according 2588 * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering. 2589 * The vector is arranged into lanes according to 2590 * <a href="Vector.html#lane-order">memory ordering</a>. 2591 * <p> 2592 * This method behaves as if it returns the result of calling 2593 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2594 * fromByteBuffer()} as follows: 2595 * <pre>{@code 2596 * var bb = ByteBuffer.wrap(a); 2597 * var bo = ByteOrder.LITTLE_ENDIAN; 2598 * var m = species.maskAll(true); 2599 * return fromByteBuffer(species, bb, offset, m, bo); 2600 * }</pre> 2601 * 2602 * @param species species of desired vector 2603 * @param a the byte array 2604 * @param offset the offset into the array 2605 * @return a vector loaded from a byte array 2606 * @throws IndexOutOfBoundsException 2607 * if {@code offset+N*ESIZE < 0} 2608 * or {@code offset+(N+1)*ESIZE > a.length} 2609 * for any lane {@code N} in the vector 2610 */ 2611 @ForceInline 2612 public static 2613 ByteVector fromByteArray(VectorSpecies<Byte> species, 2614 byte[] a, int offset) { 2615 return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN); 2616 } 2617 2618 /** 2619 * Loads a vector from a byte array starting at an offset. 2620 * Bytes are composed into primitive lane elements according 2621 * to the specified byte order. 2622 * The vector is arranged into lanes according to 2623 * <a href="Vector.html#lane-order">memory ordering</a>. 2624 * <p> 2625 * This method behaves as if it returns the result of calling 2626 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2627 * fromByteBuffer()} as follows: 2628 * <pre>{@code 2629 * var bb = ByteBuffer.wrap(a); 2630 * var m = species.maskAll(true); 2631 * return fromByteBuffer(species, bb, offset, m, bo); 2632 * }</pre> 2633 * 2634 * @param species species of desired vector 2635 * @param a the byte array 2636 * @param offset the offset into the array 2637 * @param bo the intended byte order 2638 * @return a vector loaded from a byte array 2639 * @throws IndexOutOfBoundsException 2640 * if {@code offset+N*ESIZE < 0} 2641 * or {@code offset+(N+1)*ESIZE > a.length} 2642 * for any lane {@code N} in the vector 2643 */ 2644 @ForceInline 2645 public static 2646 ByteVector fromByteArray(VectorSpecies<Byte> species, 2647 byte[] a, int offset, 2648 ByteOrder bo) { 2649 ByteSpecies vsp = (ByteSpecies) species; 2650 offset = checkFromIndexSize(offset, 2651 vsp.vectorBitSize() / Byte.SIZE, 2652 a.length); 2653 return vsp.dummyVector() 2654 .fromByteArray0(a, offset).maybeSwap(bo); 2655 } 2656 2657 /** 2658 * Loads a vector from a byte array starting at an offset 2659 * and using a mask. 2660 * Lanes where the mask is unset are filled with the default 2661 * value of {@code byte} (zero). 2662 * Bytes are composed into primitive lane elements according 2663 * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering. 2664 * The vector is arranged into lanes according to 2665 * <a href="Vector.html#lane-order">memory ordering</a>. 2666 * <p> 2667 * This method behaves as if it returns the result of calling 2668 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2669 * fromByteBuffer()} as follows: 2670 * <pre>{@code 2671 * var bb = ByteBuffer.wrap(a); 2672 * var bo = ByteOrder.LITTLE_ENDIAN; 2673 * return fromByteBuffer(species, bb, offset, bo, m); 2674 * }</pre> 2675 * 2676 * @param species species of desired vector 2677 * @param a the byte array 2678 * @param offset the offset into the array 2679 * @param m the mask controlling lane selection 2680 * @return a vector loaded from a byte array 2681 * @throws IndexOutOfBoundsException 2682 * if {@code offset+N*ESIZE < 0} 2683 * or {@code offset+(N+1)*ESIZE > a.length} 2684 * for any lane {@code N} in the vector 2685 */ 2686 @ForceInline 2687 public static 2688 ByteVector fromByteArray(VectorSpecies<Byte> species, 2689 byte[] a, int offset, 2690 VectorMask<Byte> m) { 2691 return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN, m); 2692 } 2693 2694 /** 2695 * Loads a vector from a byte array starting at an offset 2696 * and using a mask. 2697 * Lanes where the mask is unset are filled with the default 2698 * value of {@code byte} (zero). 2699 * Bytes are composed into primitive lane elements according 2700 * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering. 2701 * The vector is arranged into lanes according to 2702 * <a href="Vector.html#lane-order">memory ordering</a>. 2703 * <p> 2704 * This method behaves as if it returns the result of calling 2705 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2706 * fromByteBuffer()} as follows: 2707 * <pre>{@code 2708 * var bb = ByteBuffer.wrap(a); 2709 * return fromByteBuffer(species, bb, offset, m, bo); 2710 * }</pre> 2711 * 2712 * @param species species of desired vector 2713 * @param a the byte array 2714 * @param offset the offset into the array 2715 * @param bo the intended byte order 2716 * @param m the mask controlling lane selection 2717 * @return a vector loaded from a byte array 2718 * @throws IndexOutOfBoundsException 2719 * if {@code offset+N*ESIZE < 0} 2720 * or {@code offset+(N+1)*ESIZE > a.length} 2721 * for any lane {@code N} in the vector 2722 * where the mask is set 2723 */ 2724 @ForceInline 2725 public static 2726 ByteVector fromByteArray(VectorSpecies<Byte> species, 2727 byte[] a, int offset, 2728 ByteOrder bo, 2729 VectorMask<Byte> m) { 2730 ByteSpecies vsp = (ByteSpecies) species; 2731 ByteVector zero = vsp.zero(); 2732 ByteVector iota = zero.addIndex(1); 2733 ((AbstractMask<Byte>)m) 2734 .checkIndexByLane(offset, a.length, iota, 1); 2735 ByteVector v = zero.fromByteArray0(a, offset); 2736 return zero.blend(v.maybeSwap(bo), m); 2737 } 2738 2739 /** 2740 * Loads a vector from an array of type {@code byte[]} 2741 * starting at an offset. 2742 * For each vector lane, where {@code N} is the vector lane index, the 2743 * array element at index {@code offset + N} is placed into the 2744 * resulting vector at lane index {@code N}. 2745 * 2746 * @param species species of desired vector 2747 * @param a the array 2748 * @param offset the offset into the array 2749 * @return the vector loaded from an array 2750 * @throws IndexOutOfBoundsException 2751 * if {@code offset+N < 0} or {@code offset+N >= a.length} 2752 * for any lane {@code N} in the vector 2753 */ 2754 @ForceInline 2755 public static 2756 ByteVector fromArray(VectorSpecies<Byte> species, 2757 byte[] a, int offset) { 2758 ByteSpecies vsp = (ByteSpecies) species; 2759 offset = checkFromIndexSize(offset, 2760 vsp.laneCount(), 2761 a.length); 2762 return vsp.dummyVector().fromArray0(a, offset); 2763 } 2764 2765 /** 2766 * Loads a vector from an array of type {@code byte[]} 2767 * starting at an offset and using a mask. 2768 * Lanes where the mask is unset are filled with the default 2769 * value of {@code byte} (zero). 2770 * For each vector lane, where {@code N} is the vector lane index, 2771 * if the mask lane at index {@code N} is set then the array element at 2772 * index {@code offset + N} is placed into the resulting vector at lane index 2773 * {@code N}, otherwise the default element value is placed into the 2774 * resulting vector at lane index {@code N}. 2775 * 2776 * @param species species of desired vector 2777 * @param a the array 2778 * @param offset the offset into the array 2779 * @param m the mask controlling lane selection 2780 * @return the vector loaded from an array 2781 * @throws IndexOutOfBoundsException 2782 * if {@code offset+N < 0} or {@code offset+N >= a.length} 2783 * for any lane {@code N} in the vector 2784 * where the mask is set 2785 */ 2786 @ForceInline 2787 public static 2788 ByteVector fromArray(VectorSpecies<Byte> species, 2789 byte[] a, int offset, 2790 VectorMask<Byte> m) { 2791 ByteSpecies vsp = (ByteSpecies) species; 2792 ByteVector zero = vsp.zero(); 2793 ByteVector iota = vsp.iota(); 2794 ((AbstractMask<Byte>)m) 2795 .checkIndexByLane(offset, a.length, iota, 1); 2796 return zero.blend(zero.fromArray0(a, offset), m); 2797 } 2798 2799 /** 2800 * FIXME: EDIT THIS 2801 * Loads a vector from an array using indexes obtained from an index 2802 * map. 2803 * <p> 2804 * For each vector lane, where {@code N} is the vector lane index, the 2805 * array element at index {@code offset + indexMap[mapOffset + N]} is placed into the 2806 * resulting vector at lane index {@code N}. 2807 * 2808 * @param species species of desired vector 2809 * @param a the array 2810 * @param offset the offset into the array, may be negative if relative 2811 * indexes in the index map compensate to produce a value within the 2812 * array bounds 2813 * @param indexMap the index map 2814 * @param mapOffset the offset into the index map 2815 * @return the vector loaded from an array 2816 * @throws IndexOutOfBoundsException if {@code mapOffset < 0}, or 2817 * {@code mapOffset > indexMap.length - species.length()}, 2818 * or for any vector lane index {@code N} the result of 2819 * {@code offset + indexMap[mapOffset + N]} is {@code < 0} or {@code >= a.length} 2820 */ 2821 public static 2822 ByteVector fromArray(VectorSpecies<Byte> species, 2823 byte[] a, int offset, 2824 int[] indexMap, int mapOffset) { 2825 ByteSpecies vsp = (ByteSpecies) species; 2826 return vsp.vOp(n -> a[offset + indexMap[mapOffset + n]]); 2827 } 2828 2829 /** 2830 * Loads a vector from an array using indexes obtained from an index 2831 * map and using a mask. 2832 * FIXME: EDIT THIS 2833 * <p> 2834 * For each vector lane, where {@code N} is the vector lane index, 2835 * if the mask lane at index {@code N} is set then the array element at 2836 * index {@code offset + indexMap[mapOffset + N]} is placed into the resulting vector 2837 * at lane index {@code N}. 2838 * 2839 * @param species species of desired vector 2840 * @param a the array 2841 * @param offset the offset into the array, may be negative if relative 2842 * indexes in the index map compensate to produce a value within the 2843 * array bounds 2844 * @param indexMap the index map 2845 * @param mapOffset the offset into the index map 2846 * @param m the mask controlling lane selection 2847 * @return the vector loaded from an array 2848 * @throws IndexOutOfBoundsException if {@code mapOffset < 0}, or 2849 * {@code mapOffset > indexMap.length - species.length()}, 2850 * or for any vector lane index {@code N} where the mask at lane 2851 * {@code N} is set the result of {@code offset + indexMap[mapOffset + N]} is 2852 * {@code < 0} or {@code >= a.length} 2853 */ 2854 public static 2855 ByteVector fromArray(VectorSpecies<Byte> species, 2856 byte[] a, int offset, 2857 int[] indexMap, int mapOffset, 2858 VectorMask<Byte> m) { 2859 ByteSpecies vsp = (ByteSpecies) species; 2860 2861 // Do it the slow way. 2862 return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]); 2863 2864 } 2865 2866 /** 2867 * Loads a vector from a {@linkplain ByteBuffer byte buffer} 2868 * starting at an offset into the byte buffer. 2869 * <p> 2870 * This method behaves as if it returns the result of calling 2871 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2872 * fromByteBuffer()} as follows: 2873 * <pre>{@code 2874 * var bb = ByteBuffer.wrap(a); 2875 * var bo = ByteOrder.LITTLE_ENDIAN; 2876 * var m = species.maskAll(true); 2877 * return fromByteBuffer(species, bb, offset, m, bo); 2878 * }</pre> 2879 * 2880 * @param species species of desired vector 2881 * @param bb the byte buffer 2882 * @param offset the offset into the byte buffer 2883 * @return a vector loaded from a byte buffer 2884 * @throws IndexOutOfBoundsException 2885 * if {@code offset+N*1 < 0} 2886 * or {@code offset+N**1 >= bb.limit()} 2887 * for any lane {@code N} in the vector 2888 */ 2889 @ForceInline 2890 public static 2891 ByteVector fromByteBuffer(VectorSpecies<Byte> species, 2892 ByteBuffer bb, int offset, 2893 ByteOrder bo) { 2894 ByteSpecies vsp = (ByteSpecies) species; 2895 offset = checkFromIndexSize(offset, 2896 vsp.laneCount(), 2897 bb.limit()); 2898 return vsp.dummyVector() 2899 .fromByteBuffer0(bb, offset).maybeSwap(bo); 2900 } 2901 2902 /** 2903 * Loads a vector from a {@linkplain ByteBuffer byte buffer} 2904 * starting at an offset into the byte buffer 2905 * and using a mask. 2906 * <p> 2907 * This method behaves as if it returns the result of calling 2908 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2909 * fromByteBuffer()} as follows: 2910 * <pre>{@code 2911 * var bb = ByteBuffer.wrap(a); 2912 * var bo = ByteOrder.LITTLE_ENDIAN; 2913 * var m = species.maskAll(true); 2914 * return fromByteBuffer(species, bb, offset, m, bo); 2915 * }</pre> 2916 * 2917 * @param species species of desired vector 2918 * @param bb the byte buffer 2919 * @param offset the offset into the byte buffer 2920 * @param m the mask controlling lane selection 2921 * @return a vector loaded from a byte buffer 2922 * @throws IndexOutOfBoundsException 2923 * if {@code offset+N*1 < 0} 2924 * or {@code offset+N**1 >= bb.limit()} 2925 * for any lane {@code N} in the vector 2926 * where the mask is set 2927 */ 2928 @ForceInline 2929 public static 2930 ByteVector fromByteBuffer(VectorSpecies<Byte> species, 2931 ByteBuffer bb, int offset, 2932 ByteOrder bo, 2933 VectorMask<Byte> m) { 2934 if (m.allTrue()) { 2935 return fromByteBuffer(species, bb, offset, bo); 2936 } 2937 ByteSpecies vsp = (ByteSpecies) species; 2938 checkMaskFromIndexSize(offset, 2939 vsp, m, 1, 2940 bb.limit()); 2941 ByteVector zero = zero(vsp); 2942 ByteVector v = zero.fromByteBuffer0(bb, offset); 2943 return zero.blend(v.maybeSwap(bo), m); 2944 } 2945 2946 // Memory store operations 2947 2948 /** 2949 * Stores this vector into an array of type {@code byte[]} 2950 * starting at an offset. 2951 * <p> 2952 * For each vector lane, where {@code N} is the vector lane index, 2953 * the lane element at index {@code N} is stored into the array 2954 * element {@code a[offset+N]}. 2955 * 2956 * @param a the array, of type {@code byte[]} 2957 * @param offset the offset into the array 2958 * @throws IndexOutOfBoundsException 2959 * if {@code offset+N < 0} or {@code offset+N >= a.length} 2960 * for any lane {@code N} in the vector 2961 */ 2962 @ForceInline 2963 public final 2964 void intoArray(byte[] a, int offset) { 2965 ByteSpecies vsp = vspecies(); 2966 offset = checkFromIndexSize(offset, 2967 vsp.laneCount(), 2968 a.length); 2969 VectorIntrinsics.store( 2970 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 2971 a, arrayAddress(a, offset), 2972 this, 2973 a, offset, 2974 (arr, off, v) 2975 -> v.stOp(arr, off, 2976 (arr_, off_, i, e) -> arr_[off_ + i] = e)); 2977 } 2978 2979 /** 2980 * Stores this vector into an array of {@code byte} 2981 * starting at offset and using a mask. 2982 * <p> 2983 * For each vector lane, where {@code N} is the vector lane index, 2984 * the lane element at index {@code N} is stored into the array 2985 * element {@code a[offset+N]}. 2986 * If the mask lane at {@code N} is unset then the corresponding 2987 * array element {@code a[offset+N]} is left unchanged. 2988 * <p> 2989 * Array range checking is done for lanes where the mask is set. 2990 * Lanes where the mask is unset are not stored and do not need 2991 * to correspond to legitimate elements of {@code a}. 2992 * That is, unset lanes may correspond to array indexes less than 2993 * zero or beyond the end of the array. 2994 * 2995 * @param a the array, of type {@code byte[]} 2996 * @param offset the offset into the array 2997 * @param m the mask controlling lane storage 2998 * @throws IndexOutOfBoundsException 2999 * if {@code offset+N < 0} or {@code offset+N >= a.length} 3000 * for any lane {@code N} in the vector 3001 * where the mask is set 3002 */ 3003 @ForceInline 3004 public final 3005 void intoArray(byte[] a, int offset, 3006 VectorMask<Byte> m) { 3007 if (m.allTrue()) { 3008 intoArray(a, offset); 3009 } else { 3010 // FIXME: Cannot vectorize yet, if there's a mask. 3011 stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v); 3012 } 3013 } 3014 3015 /** 3016 * Stores this vector into an array of type {@code byte[]} 3017 * using indexes obtained from an index map 3018 * and using a mask. 3019 * <p> 3020 * For each vector lane, where {@code N} is the vector lane index, 3021 * if the mask lane at index {@code N} is set then 3022 * the lane element at index {@code N} is stored into the array 3023 * element {@code a[f(N)]}, where {@code f(N)} is the 3024 * index mapping expression 3025 * {@code offset + indexMap[mapOffset + N]]}. 3026 * 3027 * @param a the array 3028 * @param offset an offset to combine with the index map offsets 3029 * @param indexMap the index map 3030 * @param mapOffset the offset into the index map 3031 * @param m the mask 3032 * @returns a vector of the values {@code m ? a[f(N)] : 0}, 3033 * {@code f(N) = offset + indexMap[mapOffset + N]]}. 3034 * @throws IndexOutOfBoundsException 3035 * if {@code mapOffset+N < 0} 3036 * or if {@code mapOffset+N >= indexMap.length}, 3037 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 3038 * is an invalid index into {@code a}, 3039 * for any lane {@code N} in the vector 3040 * where the mask is set 3041 */ 3042 @ForceInline 3043 public final 3044 void intoArray(byte[] a, int offset, 3045 int[] indexMap, int mapOffset) { 3046 ByteSpecies vsp = vspecies(); 3047 if (length() == 1) { 3048 intoArray(a, offset + indexMap[mapOffset]); 3049 return; 3050 } 3051 IntVector.IntSpecies isp = (IntVector.IntSpecies) vsp.indexSpecies(); 3052 if (isp.laneCount() != vsp.laneCount()) { 3053 stOp(a, offset, 3054 (arr, off, i, e) -> { 3055 int j = indexMap[mapOffset + i]; 3056 arr[off + j] = e; 3057 }); 3058 return; 3059 } 3060 3061 // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] 3062 IntVector vix = IntVector 3063 .fromArray(isp, indexMap, mapOffset) 3064 .add(offset); 3065 3066 vix = VectorIntrinsics.checkIndex(vix, a.length); 3067 3068 VectorIntrinsics.storeWithMap( 3069 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3070 isp.vectorType(), 3071 a, arrayAddress(a, 0), vix, 3072 this, 3073 a, offset, indexMap, mapOffset, 3074 (arr, off, v, map, mo) 3075 -> v.stOp(arr, off, 3076 (arr_, off_, i, e) -> { 3077 int j = map[mo + i]; 3078 arr[off + j] = e; 3079 })); 3080 } 3081 3082 /** 3083 * Stores this vector into an array of type {@code byte[]} 3084 * using indexes obtained from an index map 3085 * and using a mask. 3086 * <p> 3087 * For each vector lane, where {@code N} is the vector lane index, 3088 * if the mask lane at index {@code N} is set then 3089 * the lane element at index {@code N} is stored into the array 3090 * element {@code a[f(N)]}, where {@code f(N)} is the 3091 * index mapping expression 3092 * {@code offset + indexMap[mapOffset + N]]}. 3093 * 3094 * @param a the array 3095 * @param offset an offset to combine with the index map offsets 3096 * @param indexMap the index map 3097 * @param mapOffset the offset into the index map 3098 * @param m the mask 3099 * @returns a vector of the values {@code m ? a[f(N)] : 0}, 3100 * {@code f(N) = offset + indexMap[mapOffset + N]]}. 3101 * @throws IndexOutOfBoundsException 3102 * if {@code mapOffset+N < 0} 3103 * or if {@code mapOffset+N >= indexMap.length}, 3104 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 3105 * is an invalid index into {@code a}, 3106 * for any lane {@code N} in the vector 3107 * where the mask is set 3108 */ 3109 @ForceInline 3110 public final 3111 void intoArray(byte[] a, int offset, 3112 int[] indexMap, int mapOffset, 3113 VectorMask<Byte> m) { 3114 ByteSpecies vsp = vspecies(); 3115 if (m.allTrue()) { 3116 intoArray(a, offset, indexMap, mapOffset); 3117 return; 3118 } 3119 throw new AssertionError("fixme"); 3120 } 3121 3122 /** 3123 * {@inheritDoc} <!--workaround--> 3124 */ 3125 @Override 3126 @ForceInline 3127 public final 3128 void intoByteArray(byte[] a, int offset) { 3129 offset = checkFromIndexSize(offset, 3130 bitSize() / Byte.SIZE, 3131 a.length); 3132 this.maybeSwap(ByteOrder.LITTLE_ENDIAN) 3133 .intoByteArray0(a, offset); 3134 } 3135 3136 /** 3137 * {@inheritDoc} <!--workaround--> 3138 */ 3139 @Override 3140 @ForceInline 3141 public final 3142 void intoByteArray(byte[] a, int offset, 3143 VectorMask<Byte> m) { 3144 if (m.allTrue()) { 3145 intoByteArray(a, offset); 3146 return; 3147 } 3148 ByteSpecies vsp = vspecies(); 3149 checkMaskFromIndexSize(offset, vsp, m, 1, a.length); 3150 conditionalStoreNYI(offset, vsp, m, 1, a.length); 3151 var oldVal = fromByteArray0(a, offset); 3152 var newVal = oldVal.blend(this, m); 3153 newVal.intoByteArray0(a, offset); 3154 } 3155 3156 /** 3157 * {@inheritDoc} <!--workaround--> 3158 */ 3159 @Override 3160 @ForceInline 3161 public final 3162 void intoByteArray(byte[] a, int offset, 3163 ByteOrder bo, 3164 VectorMask<Byte> m) { 3165 maybeSwap(bo).intoByteArray(a, offset, m); 3166 } 3167 3168 /** 3169 * {@inheritDoc} <!--workaround--> 3170 */ 3171 @Override 3172 @ForceInline 3173 public final 3174 void intoByteBuffer(ByteBuffer bb, int offset, 3175 ByteOrder bo) { 3176 maybeSwap(bo).intoByteBuffer0(bb, offset); 3177 } 3178 3179 /** 3180 * {@inheritDoc} <!--workaround--> 3181 */ 3182 @Override 3183 @ForceInline 3184 public final 3185 void intoByteBuffer(ByteBuffer bb, int offset, 3186 ByteOrder bo, 3187 VectorMask<Byte> m) { 3188 if (m.allTrue()) { 3189 intoByteBuffer(bb, offset, bo); 3190 return; 3191 } 3192 ByteSpecies vsp = vspecies(); 3193 checkMaskFromIndexSize(offset, vsp, m, 1, bb.limit()); 3194 conditionalStoreNYI(offset, vsp, m, 1, bb.limit()); 3195 var oldVal = fromByteBuffer0(bb, offset); 3196 var newVal = oldVal.blend(this.maybeSwap(bo), m); 3197 newVal.intoByteBuffer0(bb, offset); 3198 } 3199 3200 // ================================================ 3201 3202 // Low-level memory operations. 3203 // 3204 // Note that all of these operations *must* inline into a context 3205 // where the exact species of the involved vector is a 3206 // compile-time constant. Otherwise, the intrinsic generation 3207 // will fail and performance will suffer. 3208 // 3209 // In many cases this is achieved by re-deriving a version of the 3210 // method in each concrete subclass (per species). The re-derived 3211 // method simply calls one of these generic methods, with exact 3212 // parameters for the controlling metadata, which is either a 3213 // typed vector or constant species instance. 3214 3215 // Unchecked loading operations in native byte order. 3216 // Caller is reponsible for applying index checks, masking, and 3217 // byte swapping. 3218 3219 /*package-private*/ 3220 abstract 3221 ByteVector fromArray0(byte[] a, int offset); 3222 @ForceInline 3223 final 3224 ByteVector fromArray0Template(byte[] a, int offset) { 3225 ByteSpecies vsp = vspecies(); 3226 return VectorIntrinsics.load( 3227 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3228 a, arrayAddress(a, offset), 3229 a, offset, vsp, 3230 (arr, off, s) -> s.ldOp(arr, off, 3231 (arr_, off_, i) -> arr_[off_ + i])); 3232 } 3233 3234 @Override 3235 abstract 3236 ByteVector fromByteArray0(byte[] a, int offset); 3237 @ForceInline 3238 final 3239 ByteVector fromByteArray0Template(byte[] a, int offset) { 3240 ByteSpecies vsp = vspecies(); 3241 return VectorIntrinsics.load( 3242 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3243 a, byteArrayAddress(a, offset), 3244 a, offset, vsp, 3245 (arr, off, s) -> { 3246 ByteBuffer tb = wrapper(arr, off, NATIVE_ENDIAN); 3247 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i)); 3248 }); 3249 } 3250 3251 abstract 3252 ByteVector fromByteBuffer0(ByteBuffer bb, int offset); 3253 @ForceInline 3254 final 3255 ByteVector fromByteBuffer0Template(ByteBuffer bb, int offset) { 3256 ByteSpecies vsp = vspecies(); 3257 return VectorIntrinsics.load( 3258 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3259 bufferBase(bb), bufferAddress(bb, offset), 3260 bb, offset, vsp, 3261 (buf, off, s) -> { 3262 ByteBuffer tb = wrapper(buf, off, NATIVE_ENDIAN); 3263 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i)); 3264 }); 3265 } 3266 3267 // Unchecked storing operations in native byte order. 3268 // Caller is reponsible for applying index checks, masking, and 3269 // byte swapping. 3270 3271 abstract 3272 void intoArray0(byte[] a, int offset); 3273 @ForceInline 3274 final 3275 void intoArray0Template(byte[] a, int offset) { 3276 ByteSpecies vsp = vspecies(); 3277 VectorIntrinsics.store( 3278 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3279 a, arrayAddress(a, offset), 3280 this, a, offset, 3281 (arr, off, v) 3282 -> v.stOp(arr, off, 3283 (arr_, off_, i, e) -> arr_[off_+i] = e)); 3284 } 3285 3286 abstract 3287 void intoByteArray0(byte[] a, int offset); 3288 @ForceInline 3289 final 3290 void intoByteArray0Template(byte[] a, int offset) { 3291 ByteSpecies vsp = vspecies(); 3292 VectorIntrinsics.store( 3293 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3294 a, byteArrayAddress(a, offset), 3295 this, a, offset, 3296 (arr, off, v) -> { 3297 ByteBuffer tb = wrapper(arr, off, NATIVE_ENDIAN); 3298 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e)); 3299 }); 3300 } 3301 3302 @ForceInline 3303 final 3304 void intoByteBuffer0(ByteBuffer bb, int offset) { 3305 ByteSpecies vsp = vspecies(); 3306 VectorIntrinsics.store( 3307 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3308 bufferBase(bb), bufferAddress(bb, offset), 3309 this, bb, offset, 3310 (buf, off, v) -> { 3311 ByteBuffer tb = wrapper(buf, off, NATIVE_ENDIAN); 3312 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e)); 3313 }); 3314 } 3315 3316 // End of low-level memory operations. 3317 3318 private static 3319 void checkMaskFromIndexSize(int offset, 3320 ByteSpecies vsp, 3321 VectorMask<Byte> m, 3322 int scale, 3323 int limit) { 3324 ((AbstractMask<Byte>)m) 3325 .checkIndexByLane(offset, limit, vsp.iota(), scale); 3326 } 3327 3328 @ForceInline 3329 private void conditionalStoreNYI(int offset, 3330 ByteSpecies vsp, 3331 VectorMask<Byte> m, 3332 int scale, 3333 int limit) { 3334 if (offset < 0 || offset + vsp.laneCount() * scale > limit) { 3335 String msg = 3336 String.format("unimplemented: store @%d in [0..%d), %s in %s", 3337 offset, limit, m, vsp); 3338 throw new AssertionError(msg); 3339 } 3340 } 3341 3342 /*package-private*/ 3343 @Override 3344 @ForceInline 3345 final 3346 ByteVector maybeSwap(ByteOrder bo) { 3347 return this; 3348 } 3349 3350 static final int ARRAY_SHIFT = 3351 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE); 3352 static final long ARRAY_BASE = 3353 Unsafe.ARRAY_BYTE_BASE_OFFSET; 3354 3355 @ForceInline 3356 static long arrayAddress(byte[] a, int index) { 3357 return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); 3358 } 3359 3360 @ForceInline 3361 static long byteArrayAddress(byte[] a, int index) { 3362 return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; 3363 } 3364 3365 // Byte buffer wrappers. 3366 private static ByteBuffer wrapper(ByteBuffer bb, int offset, 3367 ByteOrder bo) { 3368 return bb.duplicate().position(offset).slice() 3369 .order(bo); 3370 } 3371 private static ByteBuffer wrapper(byte[] a, int offset, 3372 ByteOrder bo) { 3373 return ByteBuffer.wrap(a, offset, a.length - offset) 3374 .order(bo); 3375 } 3376 3377 // ================================================ 3378 3379 /// Reinterpreting view methods: 3380 // lanewise reinterpret: viewAsXVector() 3381 // keep shape, redraw lanes: reinterpretAsEs() 3382 3383 /** 3384 * {@inheritDoc} <!--workaround--> 3385 */ 3386 @ForceInline 3387 @Override 3388 public final ByteVector reinterpretAsBytes() { 3389 return this; 3390 } 3391 3392 /** 3393 * {@inheritDoc} <!--workaround--> 3394 */ 3395 @ForceInline 3396 @Override 3397 public final ByteVector viewAsIntegralLanes() { 3398 return this; 3399 } 3400 3401 /** 3402 * {@inheritDoc} <!--workaround--> 3403 * 3404 * @implNote This method always throws 3405 * {@code IllegalArgumentException}, because there is no floating 3406 * point type of the same size as {@code byte}. The return type 3407 * of this method is arbitrarily designated as 3408 * {@code Vector<?>}. Future versions of this API may change the return 3409 * type if additional floating point types become available. 3410 */ 3411 @ForceInline 3412 @Override 3413 public final 3414 Vector<?> 3415 viewAsFloatingLanes() { 3416 LaneType flt = LaneType.BYTE.asFloating(); 3417 throw new AssertionError(); // should already throw IAE 3418 } 3419 3420 // ================================================ 3421 3422 /// Object methods: toString, equals, hashCode 3423 // 3424 // Object methods are defined as if via Arrays.toString, etc., 3425 // is applied to the array of elements. Two equal vectors 3426 // are required to have equal species and equal lane values. 3427 3428 /** 3429 * Returns a string representation of this vector, of the form 3430 * {@code "[0,1,2...]"}, reporting the lane values of this vector, 3431 * in lane order. 3432 * 3433 * The string is produced as if by a call to {@link 3434 * java.util.Arrays#toString(byte[]) Arrays.toString()}, 3435 * as appropriate to the {@code byte} array returned by 3436 * {@link #toArray this.toArray()}. 3437 * 3438 * @return a string of the form {@code "[0,1,2...]"} 3439 * reporting the lane values of this vector 3440 */ 3441 @Override 3442 @ForceInline 3443 public final 3444 String toString() { 3445 // now that toArray is strongly typed, we can define this 3446 return Arrays.toString(toArray()); 3447 } 3448 3449 /** 3450 * {@inheritDoc} <!--workaround--> 3451 */ 3452 @Override 3453 @ForceInline 3454 public final 3455 boolean equals(Object obj) { 3456 if (obj instanceof Vector) { 3457 Vector<?> that = (Vector<?>) obj; 3458 if (this.species().equals(that.species())) { 3459 return this.eq(that.check(this.species())).allTrue(); 3460 } 3461 } 3462 return false; 3463 } 3464 3465 /** 3466 * {@inheritDoc} <!--workaround--> 3467 */ 3468 @Override 3469 @ForceInline 3470 public final 3471 int hashCode() { 3472 // now that toArray is strongly typed, we can define this 3473 return Objects.hash(species(), Arrays.hashCode(toArray())); 3474 } 3475 3476 // ================================================ 3477 3478 // Species 3479 3480 /** 3481 * Class representing {@link ByteVector}'s of the same {@link VectorShape VectorShape}. 3482 */ 3483 /*package-private*/ 3484 static final class ByteSpecies extends AbstractSpecies<Byte> { 3485 private ByteSpecies(VectorShape shape, 3486 Class<? extends ByteVector> vectorType, 3487 Class<? extends AbstractMask<Byte>> maskType, 3488 Function<Object, ByteVector> vectorFactory) { 3489 super(shape, LaneType.of(byte.class), 3490 vectorType, maskType, 3491 vectorFactory); 3492 assert(this.elementSize() == Byte.SIZE); 3493 } 3494 3495 // Specializing overrides: 3496 3497 @Override 3498 @ForceInline 3499 public final Class<Byte> elementType() { 3500 return byte.class; 3501 } 3502 3503 @Override 3504 @ForceInline 3505 public final Class<Byte> genericElementType() { 3506 return Byte.class; 3507 } 3508 3509 @Override 3510 @ForceInline 3511 public final Class<byte[]> arrayType() { 3512 return byte[].class; 3513 } 3514 3515 @SuppressWarnings("unchecked") 3516 @Override 3517 @ForceInline 3518 public final Class<? extends ByteVector> vectorType() { 3519 return (Class<? extends ByteVector>) vectorType; 3520 } 3521 3522 @Override 3523 @ForceInline 3524 public final long checkValue(long e) { 3525 longToElementBits(e); // only for exception 3526 return e; 3527 } 3528 3529 /*package-private*/ 3530 @Override 3531 @ForceInline 3532 final ByteVector broadcastBits(long bits) { 3533 return (ByteVector) 3534 VectorIntrinsics.broadcastCoerced( 3535 vectorType, byte.class, laneCount, 3536 bits, this, 3537 (bits_, s_) -> s_.rvOp(i -> bits_)); 3538 } 3539 3540 /*package-private*/ 3541 @ForceInline 3542 3543 final ByteVector broadcast(byte e) { 3544 return broadcastBits(toBits(e)); 3545 } 3546 3547 @Override 3548 @ForceInline 3549 public final ByteVector broadcast(long e) { 3550 return broadcastBits(longToElementBits(e)); 3551 } 3552 3553 /*package-private*/ 3554 final @Override 3555 @ForceInline 3556 long longToElementBits(long value) { 3557 // Do the conversion, and then test it for failure. 3558 byte e = (byte) value; 3559 if ((long) e != value) { 3560 throw badElementBits(value, e); 3561 } 3562 return toBits(e); 3563 } 3564 3565 @Override 3566 @ForceInline 3567 public final ByteVector fromValues(long... values) { 3568 VectorIntrinsics.requireLength(values.length, laneCount); 3569 byte[] va = new byte[laneCount()]; 3570 for (int i = 0; i < va.length; i++) { 3571 long lv = values[i]; 3572 byte v = (byte) lv; 3573 va[i] = v; 3574 if ((long)v != lv) { 3575 throw badElementBits(lv, v); 3576 } 3577 } 3578 return dummyVector().fromArray0(va, 0); 3579 } 3580 3581 /* this non-public one is for internal conversions */ 3582 @Override 3583 @ForceInline 3584 final ByteVector fromIntValues(int[] values) { 3585 VectorIntrinsics.requireLength(values.length, laneCount); 3586 byte[] va = new byte[laneCount()]; 3587 for (int i = 0; i < va.length; i++) { 3588 int lv = values[i]; 3589 byte v = (byte) lv; 3590 va[i] = v; 3591 if ((int)v != lv) { 3592 throw badElementBits(lv, v); 3593 } 3594 } 3595 return dummyVector().fromArray0(va, 0); 3596 } 3597 3598 // Virtual constructors 3599 3600 @ForceInline 3601 @Override final 3602 public ByteVector fromArray(Object a, int offset) { 3603 // User entry point: Be careful with inputs. 3604 return ByteVector 3605 .fromArray(this, (byte[]) a, offset); 3606 } 3607 3608 @Override final 3609 ByteVector dummyVector() { 3610 return (ByteVector) super.dummyVector(); 3611 } 3612 3613 final 3614 ByteVector vectorFactory(byte[] vec) { 3615 // Species delegates all factory requests to its dummy 3616 // vector. The dummy knows all about it. 3617 return dummyVector().vectorFactory(vec); 3618 } 3619 3620 /*package-private*/ 3621 final @Override 3622 @ForceInline 3623 ByteVector rvOp(RVOp f) { 3624 byte[] res = new byte[laneCount()]; 3625 for (int i = 0; i < res.length; i++) { 3626 byte bits = (byte) f.apply(i); 3627 res[i] = fromBits(bits); 3628 } 3629 return dummyVector().vectorFactory(res); 3630 } 3631 3632 ByteVector vOp(FVOp f) { 3633 byte[] res = new byte[laneCount()]; 3634 for (int i = 0; i < res.length; i++) { 3635 res[i] = f.apply(i); 3636 } 3637 return dummyVector().vectorFactory(res); 3638 } 3639 3640 ByteVector vOp(VectorMask<Byte> m, FVOp f) { 3641 byte[] res = new byte[laneCount()]; 3642 boolean[] mbits = ((AbstractMask<Byte>)m).getBits(); 3643 for (int i = 0; i < res.length; i++) { 3644 if (mbits[i]) { 3645 res[i] = f.apply(i); 3646 } 3647 } 3648 return dummyVector().vectorFactory(res); 3649 } 3650 3651 /*package-private*/ 3652 @ForceInline 3653 <M> ByteVector ldOp(M memory, int offset, 3654 FLdOp<M> f) { 3655 return dummyVector().ldOp(memory, offset, f); 3656 } 3657 3658 /*package-private*/ 3659 @ForceInline 3660 <M> ByteVector ldOp(M memory, int offset, 3661 AbstractMask<Byte> m, 3662 FLdOp<M> f) { 3663 return dummyVector().ldOp(memory, offset, m, f); 3664 } 3665 3666 /*package-private*/ 3667 @ForceInline 3668 <M> void stOp(M memory, int offset, FStOp<M> f) { 3669 dummyVector().stOp(memory, offset, f); 3670 } 3671 3672 /*package-private*/ 3673 @ForceInline 3674 <M> void stOp(M memory, int offset, 3675 AbstractMask<Byte> m, 3676 FStOp<M> f) { 3677 dummyVector().stOp(memory, offset, m, f); 3678 } 3679 3680 // N.B. Make sure these constant vectors and 3681 // masks load up correctly into registers. 3682 // 3683 // Also, see if we can avoid all that switching. 3684 // Could we cache both vectors and both masks in 3685 // this species object? 3686 3687 // Zero and iota vector access 3688 @Override 3689 @ForceInline 3690 public final ByteVector zero() { 3691 if ((Class<?>) vectorType() == ByteMaxVector.class) 3692 return ByteMaxVector.ZERO; 3693 switch (vectorBitSize()) { 3694 case 64: return Byte64Vector.ZERO; 3695 case 128: return Byte128Vector.ZERO; 3696 case 256: return Byte256Vector.ZERO; 3697 case 512: return Byte512Vector.ZERO; 3698 } 3699 throw new AssertionError(); 3700 } 3701 3702 @Override 3703 @ForceInline 3704 public final ByteVector iota() { 3705 if ((Class<?>) vectorType() == ByteMaxVector.class) 3706 return ByteMaxVector.IOTA; 3707 switch (vectorBitSize()) { 3708 case 64: return Byte64Vector.IOTA; 3709 case 128: return Byte128Vector.IOTA; 3710 case 256: return Byte256Vector.IOTA; 3711 case 512: return Byte512Vector.IOTA; 3712 } 3713 throw new AssertionError(); 3714 } 3715 3716 // Mask access 3717 @Override 3718 @ForceInline 3719 public final VectorMask<Byte> maskAll(boolean bit) { 3720 if ((Class<?>) vectorType() == ByteMaxVector.class) 3721 return ByteMaxVector.ByteMaxMask.maskAll(bit); 3722 switch (vectorBitSize()) { 3723 case 64: return Byte64Vector.Byte64Mask.maskAll(bit); 3724 case 128: return Byte128Vector.Byte128Mask.maskAll(bit); 3725 case 256: return Byte256Vector.Byte256Mask.maskAll(bit); 3726 case 512: return Byte512Vector.Byte512Mask.maskAll(bit); 3727 } 3728 throw new AssertionError(); 3729 } 3730 } 3731 3732 /** 3733 * Finds a species for an element type of {@code byte} and shape. 3734 * 3735 * @param s the shape 3736 * @return a species for an element type of {@code byte} and shape 3737 * @throws IllegalArgumentException if no such species exists for the shape 3738 */ 3739 static ByteSpecies species(VectorShape s) { 3740 Objects.requireNonNull(s); 3741 switch (s) { 3742 case S_64_BIT: return (ByteSpecies) SPECIES_64; 3743 case S_128_BIT: return (ByteSpecies) SPECIES_128; 3744 case S_256_BIT: return (ByteSpecies) SPECIES_256; 3745 case S_512_BIT: return (ByteSpecies) SPECIES_512; 3746 case S_Max_BIT: return (ByteSpecies) SPECIES_MAX; 3747 default: throw new IllegalArgumentException("Bad shape: " + s); 3748 } 3749 } 3750 3751 /** Species representing {@link ByteVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 3752 public static final VectorSpecies<Byte> SPECIES_64 3753 = new ByteSpecies(VectorShape.S_64_BIT, 3754 Byte64Vector.class, 3755 Byte64Vector.Byte64Mask.class, 3756 Byte64Vector::new); 3757 3758 /** Species representing {@link ByteVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 3759 public static final VectorSpecies<Byte> SPECIES_128 3760 = new ByteSpecies(VectorShape.S_128_BIT, 3761 Byte128Vector.class, 3762 Byte128Vector.Byte128Mask.class, 3763 Byte128Vector::new); 3764 3765 /** Species representing {@link ByteVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 3766 public static final VectorSpecies<Byte> SPECIES_256 3767 = new ByteSpecies(VectorShape.S_256_BIT, 3768 Byte256Vector.class, 3769 Byte256Vector.Byte256Mask.class, 3770 Byte256Vector::new); 3771 3772 /** Species representing {@link ByteVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 3773 public static final VectorSpecies<Byte> SPECIES_512 3774 = new ByteSpecies(VectorShape.S_512_BIT, 3775 Byte512Vector.class, 3776 Byte512Vector.Byte512Mask.class, 3777 Byte512Vector::new); 3778 3779 /** Species representing {@link ByteVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 3780 public static final VectorSpecies<Byte> SPECIES_MAX 3781 = new ByteSpecies(VectorShape.S_Max_BIT, 3782 ByteMaxVector.class, 3783 ByteMaxVector.ByteMaxMask.class, 3784 ByteMaxVector::new); 3785 3786 /** 3787 * Preferred species for {@link ByteVector}s. 3788 * A preferred species is a species of maximal bit-size for the platform. 3789 */ 3790 public static final VectorSpecies<Byte> SPECIES_PREFERRED 3791 = (ByteSpecies) VectorSpecies.ofPreferred(byte.class); 3792 3793 3794 // ==== JROSE NAME CHANGES ==== 3795 3796 /** Use lanewise(NEG, m). */ 3797 @Deprecated 3798 public final ByteVector neg(VectorMask<Byte> m) { 3799 return lanewise(NEG, m); 3800 } 3801 3802 /** Use lanewise(ABS, m). */ 3803 @Deprecated 3804 public final ByteVector abs(VectorMask<Byte> m) { 3805 return lanewise(ABS, m); 3806 } 3807 3808 /** Use explicit argument of ByteOrder.LITTLE_ENDIAN */ 3809 @Deprecated 3810 public static 3811 ByteVector fromByteBuffer(VectorSpecies<Byte> species, 3812 ByteBuffer bb, int offset) { 3813 ByteOrder bo = ByteOrder.LITTLE_ENDIAN; 3814 if (bb.order() != bo) throw new IllegalArgumentException(); 3815 return fromByteBuffer(species, bb, offset, bo); 3816 } 3817 3818 /** Use explicit argument of ByteOrder.LITTLE_ENDIAN */ 3819 @Deprecated 3820 public static 3821 ByteVector fromByteBuffer(VectorSpecies<Byte> species, 3822 ByteBuffer bb, int offset, 3823 VectorMask<Byte> m) { 3824 ByteOrder bo = ByteOrder.LITTLE_ENDIAN; 3825 if (bb.order() != bo) throw new IllegalArgumentException(); 3826 return fromByteBuffer(species, bb, offset, bo, m); 3827 } 3828 3829 /** Use fromValues(s, value...) */ 3830 @Deprecated 3831 public static 3832 ByteVector scalars(VectorSpecies<Byte> species, 3833 byte... values) { 3834 return fromValues(species, values); 3835 } 3836 3837 @Deprecated public final byte addLanes() { return reduceLanes(ADD); } 3838 @Deprecated public final byte addLanes(VectorMask<Byte> m) { return reduceLanes(ADD, m); } 3839 @Deprecated public final byte mulLanes() { return reduceLanes(MUL); } 3840 @Deprecated public final byte mulLanes(VectorMask<Byte> m) { return reduceLanes(MUL, m); } 3841 @Deprecated public final byte minLanes() { return reduceLanes(MIN); } 3842 @Deprecated public final byte minLanes(VectorMask<Byte> m) { return reduceLanes(MIN, m); } 3843 @Deprecated public final byte maxLanes() { return reduceLanes(MAX); } 3844 @Deprecated public final byte maxLanes(VectorMask<Byte> m) { return reduceLanes(MAX, m); } 3845 @Deprecated public final byte orLanes() { return reduceLanes(OR); } 3846 @Deprecated public final byte orLanes(VectorMask<Byte> m) { return reduceLanes(OR, m); } 3847 @Deprecated public final byte andLanes() { return reduceLanes(AND); } 3848 @Deprecated public final byte andLanes(VectorMask<Byte> m) { return reduceLanes(AND, m); } 3849 @Deprecated public final byte xorLanes() { return reduceLanes(XOR); } 3850 @Deprecated public final byte xorLanes(VectorMask<Byte> m) { return reduceLanes(XOR, m); } 3851 @Deprecated public final ByteVector sqrt(VectorMask<Byte> m) { return lanewise(SQRT, m); } 3852 @Deprecated public final ByteVector tan() { return lanewise(TAN); } 3853 @Deprecated public final ByteVector tan(VectorMask<Byte> m) { return lanewise(TAN, m); } 3854 @Deprecated public final ByteVector tanh() { return lanewise(TANH); } 3855 @Deprecated public final ByteVector tanh(VectorMask<Byte> m) { return lanewise(TANH, m); } 3856 @Deprecated public final ByteVector sin() { return lanewise(SIN); } 3857 @Deprecated public final ByteVector sin(VectorMask<Byte> m) { return lanewise(SIN, m); } 3858 @Deprecated public final ByteVector sinh() { return lanewise(SINH); } 3859 @Deprecated public final ByteVector sinh(VectorMask<Byte> m) { return lanewise(SINH, m); } 3860 @Deprecated public final ByteVector cos() { return lanewise(COS); } 3861 @Deprecated public final ByteVector cos(VectorMask<Byte> m) { return lanewise(COS, m); } 3862 @Deprecated public final ByteVector cosh() { return lanewise(COSH); } 3863 @Deprecated public final ByteVector cosh(VectorMask<Byte> m) { return lanewise(COSH, m); } 3864 @Deprecated public final ByteVector asin() { return lanewise(ASIN); } 3865 @Deprecated public final ByteVector asin(VectorMask<Byte> m) { return lanewise(ASIN, m); } 3866 @Deprecated public final ByteVector acos() { return lanewise(ACOS); } 3867 @Deprecated public final ByteVector acos(VectorMask<Byte> m) { return lanewise(ACOS, m); } 3868 @Deprecated public final ByteVector atan() { return lanewise(ATAN); } 3869 @Deprecated public final ByteVector atan(VectorMask<Byte> m) { return lanewise(ATAN, m); } 3870 @Deprecated public final ByteVector atan2(Vector<Byte> v) { return lanewise(ATAN2, v); } 3871 @Deprecated public final ByteVector atan2(byte s) { return lanewise(ATAN2, s); } 3872 @Deprecated public final ByteVector atan2(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(ATAN2, v, m); } 3873 @Deprecated public final ByteVector atan2(byte s, VectorMask<Byte> m) { return lanewise(ATAN2, s, m); } 3874 @Deprecated public final ByteVector cbrt() { return lanewise(CBRT); } 3875 @Deprecated public final ByteVector cbrt(VectorMask<Byte> m) { return lanewise(CBRT, m); } 3876 @Deprecated public final ByteVector log() { return lanewise(LOG); } 3877 @Deprecated public final ByteVector log(VectorMask<Byte> m) { return lanewise(LOG, m); } 3878 @Deprecated public final ByteVector log10() { return lanewise(LOG10); } 3879 @Deprecated public final ByteVector log10(VectorMask<Byte> m) { return lanewise(LOG10, m); } 3880 @Deprecated public final ByteVector log1p() { return lanewise(LOG1P); } 3881 @Deprecated public final ByteVector log1p(VectorMask<Byte> m) { return lanewise(LOG1P, m); } 3882 @Deprecated public final ByteVector pow(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(POW, v, m); } 3883 @Deprecated public final ByteVector pow(byte s, VectorMask<Byte> m) { return lanewise(POW, s, m); } 3884 @Deprecated public final ByteVector exp() { return lanewise(EXP); } 3885 @Deprecated public final ByteVector exp(VectorMask<Byte> m) { return lanewise(EXP, m); } 3886 @Deprecated public final ByteVector expm1() { return lanewise(EXPM1); } 3887 @Deprecated public final ByteVector expm1(VectorMask<Byte> m) { return lanewise(EXPM1, m); } 3888 @Deprecated public final ByteVector hypot(Vector<Byte> v) { return lanewise(HYPOT, v); } 3889 @Deprecated public final ByteVector hypot(byte s) { return lanewise(HYPOT, s); } 3890 @Deprecated public final ByteVector hypot(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(HYPOT, v, m); } 3891 @Deprecated public final ByteVector hypot(byte s, VectorMask<Byte> m) { return lanewise(HYPOT, s, m); } 3892 @Deprecated public final ByteVector and(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(AND, v, m); } 3893 @Deprecated public final ByteVector and(byte s, VectorMask<Byte> m) { return lanewise(AND, s, m); } 3894 @Deprecated public final ByteVector or(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(OR, v, m); } 3895 @Deprecated public final ByteVector or(byte s, VectorMask<Byte> m) { return lanewise(OR, s, m); } 3896 @Deprecated public final ByteVector xor(Vector<Byte> v) { return lanewise(XOR, v); } 3897 @Deprecated public final ByteVector xor(byte s) { return lanewise(XOR, s); } 3898 @Deprecated public final ByteVector xor(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(XOR, v, m); } 3899 @Deprecated public final ByteVector xor(byte s, VectorMask<Byte> m) { return lanewise(XOR, s, m); } 3900 @Deprecated public final ByteVector not(VectorMask<Byte> m) { return lanewise(NOT, m); } 3901 @Deprecated public final ByteVector shiftLeft(int s) { return lanewise(LSHL, (byte) s); } 3902 @Deprecated public final ByteVector shiftLeft(int s, VectorMask<Byte> m) { return lanewise(LSHL, (byte) s, m); } 3903 @Deprecated public final ByteVector shiftLeft(Vector<Byte> v) { return lanewise(LSHL, v); } 3904 @Deprecated public final ByteVector shiftLeft(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(LSHL, v, m); } 3905 @Deprecated public final ByteVector shiftRight(int s) { return lanewise(LSHR, (byte) s); } 3906 @Deprecated public final ByteVector shiftRight(int s, VectorMask<Byte> m) { return lanewise(LSHR, (byte) s, m); } 3907 @Deprecated public final ByteVector shiftRight(Vector<Byte> v) { return lanewise(LSHR, v); } 3908 @Deprecated public final ByteVector shiftRight(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(LSHR, v, m); } 3909 @Deprecated public final ByteVector shiftArithmeticRight(int s) { return lanewise(ASHR, (byte) s); } 3910 @Deprecated public final ByteVector shiftArithmeticRight(int s, VectorMask<Byte> m) { return lanewise(ASHR, (byte) s, m); } 3911 @Deprecated public final ByteVector shiftArithmeticRight(Vector<Byte> v) { return lanewise(ASHR, v); } 3912 @Deprecated public final ByteVector shiftArithmeticRight(Vector<Byte> v, VectorMask<Byte> m) { return lanewise(ASHR, v, m); } 3913 @Deprecated public final ByteVector rotateLeft(int s) { return lanewise(ROL, (byte) s); } 3914 @Deprecated public final ByteVector rotateLeft(int s, VectorMask<Byte> m) { return lanewise(ROL, (byte) s, m); } 3915 @Deprecated public final ByteVector rotateRight(int s) { return lanewise(ROR, (byte) s); } 3916 @Deprecated public final ByteVector rotateRight(int s, VectorMask<Byte> m) { return lanewise(ROR, (byte) s, m); } 3917 @Deprecated @Override public ByteVector rotateLanesLeft(int i) { return (ByteVector) super.rotateLanesLeft(i); } 3918 @Deprecated @Override public ByteVector rotateLanesRight(int i) { return (ByteVector) super.rotateLanesRight(i); } 3919 @Deprecated @Override public ByteVector shiftLanesLeft(int i) { return (ByteVector) super.shiftLanesLeft(i); } 3920 @Deprecated @Override public ByteVector shiftLanesRight(int i) { return (ByteVector) super.shiftLanesRight(i); } 3921 @Deprecated public ByteVector with(int i, byte e) { return withLane(i, e); } 3922 }