1 /*
   2  * Copyright (c) 2018, 2021, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation
  27  * @run testng/othervm -XX:-TieredCompilation Byte64VectorLoadStoreTests
  28  *
  29  */
  30 
  31 // -- This file was mechanically generated: Do not edit! -- //
  32 
  33 import jdk.incubator.vector.ByteVector;
  34 import jdk.incubator.vector.VectorMask;
  35 import jdk.incubator.vector.VectorSpecies;
  36 import jdk.incubator.vector.VectorShuffle;
  37 import jdk.internal.vm.annotation.DontInline;
  38 import org.testng.Assert;
  39 import org.testng.annotations.DataProvider;
  40 import org.testng.annotations.Test;
  41 
  42 import java.nio.ByteBuffer;
  43 import java.nio.ByteOrder;
  44 import java.nio.ReadOnlyBufferException;
  45 import java.util.List;
  46 import java.util.function.*;
  47 
  48 @Test
  49 public class Byte64VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
  50     static final VectorSpecies<Byte> SPECIES =
  51                 ByteVector.SPECIES_64;
  52 
  53     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  54 
  55 
  56     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 64);
  57 
  58     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
  59         int i = 0;
  60         try {
  61             for (; i < a.length; i++) {
  62                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0);
  63             }
  64         } catch (AssertionError e) {
  65             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
  66         }
  67     }
  68 
  69 
  70     static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
  71             withToString("byte[i * 5]", (int s) -> {
  72                 return fill(s * BUFFER_REPS,
  73                             i -> (byte)(i * 5));
  74             }),
  75             withToString("byte[i + 1]", (int s) -> {
  76                 return fill(s * BUFFER_REPS,
  77                             i -> (((byte)(i + 1) == 0) ? 1 : (byte)(i + 1)));
  78             })
  79     );
  80 
  81     // Relative to array.length
  82     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
  83             withToString("-1", (int l) -> {
  84                 return -1;
  85             }),
  86             withToString("l", (int l) -> {
  87                 return l;
  88             }),
  89             withToString("l - 1", (int l) -> {
  90                 return l - 1;
  91             }),
  92             withToString("l + 1", (int l) -> {
  93                 return l + 1;
  94             }),
  95             withToString("l - speciesl + 1", (int l) -> {
  96                 return l - SPECIES.length() + 1;
  97             }),
  98             withToString("l + speciesl - 1", (int l) -> {
  99                 return l + SPECIES.length() - 1;
 100             }),
 101             withToString("l + speciesl", (int l) -> {
 102                 return l + SPECIES.length();
 103             }),
 104             withToString("l + speciesl + 1", (int l) -> {
 105                 return l + SPECIES.length() + 1;
 106             })
 107     );
 108 
 109     // Relative to byte[] array.length or ByteBuffer.limit()
 110     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 111             withToString("-1", (int l) -> {
 112                 return -1;
 113             }),
 114             withToString("l", (int l) -> {
 115                 return l;
 116             }),
 117             withToString("l - 1", (int l) -> {
 118                 return l - 1;
 119             }),
 120             withToString("l + 1", (int l) -> {
 121                 return l + 1;
 122             }),
 123             withToString("l - speciesl*ebsize + 1", (int l) -> {
 124                 return l - SPECIES.vectorByteSize() + 1;
 125             }),
 126             withToString("l + speciesl*ebsize - 1", (int l) -> {
 127                 return l + SPECIES.vectorByteSize() - 1;
 128             }),
 129             withToString("l + speciesl*ebsize", (int l) -> {
 130                 return l + SPECIES.vectorByteSize();
 131             }),
 132             withToString("l + speciesl*ebsize + 1", (int l) -> {
 133                 return l + SPECIES.vectorByteSize() + 1;
 134             })
 135     );
 136 
 137     @DataProvider
 138     public Object[][] byteProvider() {
 139         return BYTE_GENERATORS.stream().
 140                 map(f -> new Object[]{f}).
 141                 toArray(Object[][]::new);
 142     }
 143 
 144     @DataProvider
 145     public Object[][] maskProvider() {
 146         return BOOLEAN_MASK_GENERATORS.stream().
 147                 map(f -> new Object[]{f}).
 148                 toArray(Object[][]::new);
 149     }
 150 
 151     @DataProvider
 152     public Object[][] byteProviderForIOOBE() {
 153         var f = BYTE_GENERATORS.get(0);
 154         return INDEX_GENERATORS.stream().map(fi -> {
 155                     return new Object[] {f, fi};
 156                 }).
 157                 toArray(Object[][]::new);
 158     }
 159 
 160     @DataProvider
 161     public Object[][] byteMaskProvider() {
 162         return BOOLEAN_MASK_GENERATORS.stream().
 163                 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> {
 164                     return new Object[] {fa, fm};
 165                 })).
 166                 toArray(Object[][]::new);
 167     }
 168 
 169     @DataProvider
 170     public Object[][] byteMaskProviderForIOOBE() {
 171         var f = BYTE_GENERATORS.get(0);
 172         return BOOLEAN_MASK_GENERATORS.stream().
 173                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 174                     return new Object[] {f, fi, fm};
 175                 })).
 176                 toArray(Object[][]::new);
 177     }
 178 
 179     @DataProvider
 180     public Object[][] byteByteBufferProvider() {
 181         return BYTE_GENERATORS.stream().
 182                 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 183                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 184                             return new Object[]{fa, fb, bo};
 185                         }))).
 186                 toArray(Object[][]::new);
 187     }
 188 
 189     @DataProvider
 190     public Object[][] byteByteBufferMaskProvider() {
 191         return BOOLEAN_MASK_GENERATORS.stream().
 192                 flatMap(fm -> BYTE_GENERATORS.stream().
 193                         flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 194                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 195                             return new Object[]{fa, fb, fm, bo};
 196                         })))).
 197                 toArray(Object[][]::new);
 198     }
 199 
 200     @DataProvider
 201     public Object[][] byteByteArrayProvider() {
 202         return BYTE_GENERATORS.stream().
 203                 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 204                     return new Object[]{fa, bo};
 205                 })).
 206                 toArray(Object[][]::new);
 207     }
 208 
 209     @DataProvider
 210     public Object[][] byteByteArrayMaskProvider() {
 211         return BOOLEAN_MASK_GENERATORS.stream().
 212                 flatMap(fm -> BYTE_GENERATORS.stream().
 213                     flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 214                         return new Object[]{fa, fm, bo};
 215                     }))).
 216                 toArray(Object[][]::new);
 217     }
 218 
 219     @DataProvider
 220     public Object[][] byteByteProviderForIOOBE() {
 221         var f = BYTE_GENERATORS.get(0);
 222         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 223                     return new Object[] {f, fi};
 224                 }).
 225                 toArray(Object[][]::new);
 226     }
 227 
 228     @DataProvider
 229     public Object[][] byteByteMaskProviderForIOOBE() {
 230         var f = BYTE_GENERATORS.get(0);
 231         return BOOLEAN_MASK_GENERATORS.stream().
 232                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 233                     return new Object[] {f, fi, fm};
 234                 })).
 235                 toArray(Object[][]::new);
 236     }
 237 
 238     static ByteBuffer toBuffer(byte[] a, IntFunction<ByteBuffer> fb) {
 239         ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
 240         for (byte v : a) {
 241             bb.put(v);
 242         }
 243         return bb.clear();
 244     }
 245 
 246     static byte[] bufferToArray(ByteBuffer bb) {
 247         ByteBuffer db = bb;
 248         byte[] d = new byte[db.capacity()];
 249         db.get(0, d);
 250         return d;
 251     }
 252 
 253     static byte[] toByteArray(byte[] a, IntFunction<byte[]> fb, ByteOrder bo) {
 254         byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
 255         ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo);
 256         for (byte v : a) {
 257             bb.put(v);
 258         }
 259         return b;
 260     }
 261 
 262 
 263     interface ToByteF {
 264         byte apply(int i);
 265     }
 266 
 267     static byte[] fill(int s , ToByteF f) {
 268         return fill(new byte[s], f);
 269     }
 270 
 271     static byte[] fill(byte[] a, ToByteF f) {
 272         for (int i = 0; i < a.length; i++) {
 273             a[i] = f.apply(i);
 274         }
 275         return a;
 276     }
 277 
 278     @DontInline
 279     static ByteVector fromArray(byte[] a, int i) {
 280         return ByteVector.fromArray(SPECIES, a, i);
 281     }
 282 
 283     @DontInline
 284     static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) {
 285         return ByteVector.fromArray(SPECIES, a, i, m);
 286     }
 287 
 288     @DontInline
 289     static void intoArray(ByteVector v, byte[] a, int i) {
 290         v.intoArray(a, i);
 291     }
 292 
 293     @DontInline
 294     static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) {
 295         v.intoArray(a, i, m);
 296     }
 297 
 298     @DontInline
 299     static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo) {
 300         return ByteVector.fromByteArray(SPECIES, a, i, bo);
 301     }
 302 
 303     @DontInline
 304     static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
 305         return ByteVector.fromByteArray(SPECIES, a, i, bo, m);
 306     }
 307 
 308     @DontInline
 309     static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo) {
 310         v.intoByteArray(a, i, bo);
 311     }
 312 
 313     @DontInline
 314     static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
 315         v.intoByteArray(a, i, bo, m);
 316     }
 317 
 318     @DontInline
 319     static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
 320         return ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 321     }
 322 
 323     @DontInline
 324     static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
 325         return ByteVector.fromByteBuffer(SPECIES, a, i, bo, m);
 326     }
 327 
 328     @DontInline
 329     static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo) {
 330         v.intoByteBuffer(a, i, bo);
 331     }
 332 
 333     @DontInline
 334     static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
 335         v.intoByteBuffer(a, i, bo, m);
 336     }
 337 
 338 
 339     @Test(dataProvider = "byteProvider")
 340     static void loadStoreArray(IntFunction<byte[]> fa) {
 341         byte[] a = fa.apply(SPECIES.length());
 342         byte[] r = new byte[a.length];
 343 
 344         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 345             for (int i = 0; i < a.length; i += SPECIES.length()) {
 346                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 347                 av.intoArray(r, i);
 348             }
 349         }
 350         Assert.assertEquals(r, a);
 351     }
 352 
 353     @Test(dataProvider = "byteProviderForIOOBE")
 354     static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 355         byte[] a = fa.apply(SPECIES.length());
 356         byte[] r = new byte[a.length];
 357 
 358         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 359             for (int i = 0; i < a.length; i += SPECIES.length()) {
 360                 ByteVector av = fromArray(a, i);
 361                 av.intoArray(r, i);
 362             }
 363         }
 364 
 365         int index = fi.apply(a.length);
 366         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 367         try {
 368             fromArray(a, index);
 369             if (shouldFail) {
 370                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 371             }
 372         } catch (IndexOutOfBoundsException e) {
 373             if (!shouldFail) {
 374                 Assert.fail("Unexpected IndexOutOfBoundsException");
 375             }
 376         }
 377     }
 378 
 379     @Test(dataProvider = "byteProviderForIOOBE")
 380     static void storeArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 381         byte[] a = fa.apply(SPECIES.length());
 382         byte[] r = new byte[a.length];
 383 
 384         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 385             for (int i = 0; i < a.length; i += SPECIES.length()) {
 386                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 387                 intoArray(av, r, i);
 388             }
 389         }
 390 
 391         int index = fi.apply(a.length);
 392         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 393         try {
 394             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 395             intoArray(av, r, index);
 396             if (shouldFail) {
 397                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 398             }
 399         } catch (IndexOutOfBoundsException e) {
 400             if (!shouldFail) {
 401                 Assert.fail("Unexpected IndexOutOfBoundsException");
 402             }
 403         }
 404     }
 405 
 406 
 407     @Test(dataProvider = "byteMaskProvider")
 408     static void loadStoreMaskArray(IntFunction<byte[]> fa,
 409                                    IntFunction<boolean[]> fm) {
 410         byte[] a = fa.apply(SPECIES.length());
 411         byte[] r = new byte[a.length];
 412         boolean[] mask = fm.apply(SPECIES.length());
 413         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 414 
 415         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 416             for (int i = 0; i < a.length; i += SPECIES.length()) {
 417                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, vmask);
 418                 av.intoArray(r, i);
 419             }
 420         }
 421         assertArraysEquals(r, a, mask);
 422 
 423 
 424         r = new byte[a.length];
 425 
 426         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 427             for (int i = 0; i < a.length; i += SPECIES.length()) {
 428                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 429                 av.intoArray(r, i, vmask);
 430             }
 431         }
 432         assertArraysEquals(r, a, mask);
 433     }
 434 
 435     @Test(dataProvider = "byteMaskProviderForIOOBE")
 436     static void loadArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 437         byte[] a = fa.apply(SPECIES.length());
 438         byte[] r = new byte[a.length];
 439         boolean[] mask = fm.apply(SPECIES.length());
 440         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 441 
 442         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 443             for (int i = 0; i < a.length; i += SPECIES.length()) {
 444                 ByteVector av = fromArray(a, i, vmask);
 445                 av.intoArray(r, i);
 446             }
 447         }
 448 
 449         int index = fi.apply(a.length);
 450         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 451         try {
 452             fromArray(a, index, vmask);
 453             if (shouldFail) {
 454                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 455             }
 456         } catch (IndexOutOfBoundsException e) {
 457             if (!shouldFail) {
 458                 Assert.fail("Unexpected IndexOutOfBoundsException");
 459             }
 460         }
 461     }
 462 
 463     @Test(dataProvider = "byteMaskProviderForIOOBE")
 464     static void storeArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 465         byte[] a = fa.apply(SPECIES.length());
 466         byte[] r = new byte[a.length];
 467         boolean[] mask = fm.apply(SPECIES.length());
 468         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 469 
 470         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 471             for (int i = 0; i < a.length; i += SPECIES.length()) {
 472                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 473                 intoArray(av, r, i, vmask);
 474             }
 475         }
 476 
 477         int index = fi.apply(a.length);
 478         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 479         try {
 480             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 481             intoArray(av, a, index, vmask);
 482             if (shouldFail) {
 483                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 484             }
 485         } catch (IndexOutOfBoundsException e) {
 486             if (!shouldFail) {
 487                 Assert.fail("Unexpected IndexOutOfBoundsException");
 488             }
 489         }
 490     }
 491 
 492 
 493     @Test(dataProvider = "byteMaskProvider")
 494     static void loadStoreMask(IntFunction<byte[]> fa,
 495                               IntFunction<boolean[]> fm) {
 496         boolean[] mask = fm.apply(SPECIES.length());
 497         boolean[] r = new boolean[mask.length];
 498 
 499         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 500             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 501                 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i);
 502                 vmask.intoArray(r, i);
 503             }
 504         }
 505         Assert.assertEquals(r, mask);
 506     }
 507 
 508 
 509     @Test(dataProvider = "byteByteBufferProvider")
 510     static void loadStoreByteBuffer(IntFunction<byte[]> fa,
 511                                     IntFunction<ByteBuffer> fb,
 512                                     ByteOrder bo) {
 513         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
 514         ByteBuffer r = fb.apply(a.limit());
 515 
 516         int l = a.limit();
 517         int s = SPECIES.vectorByteSize();
 518 
 519         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 520             for (int i = 0; i < l; i += s) {
 521                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 522                 av.intoByteBuffer(r, i, bo);
 523             }
 524         }
 525         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 526         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 527         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 528         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 529         Assert.assertEquals(r, a, "Buffers not equal");
 530     }
 531 
 532     @Test(dataProvider = "byteByteProviderForIOOBE")
 533     static void loadByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 534         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 535         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 536 
 537         int l = a.limit();
 538         int s = SPECIES.vectorByteSize();
 539 
 540         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 541             for (int i = 0; i < l; i += s) {
 542                 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
 543                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 544             }
 545         }
 546 
 547         int index = fi.apply(a.limit());
 548         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 549         try {
 550             fromByteBuffer(a, index, ByteOrder.nativeOrder());
 551             if (shouldFail) {
 552                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 553             }
 554         } catch (IndexOutOfBoundsException e) {
 555             if (!shouldFail) {
 556                 Assert.fail("Unexpected IndexOutOfBoundsException");
 557             }
 558         }
 559     }
 560 
 561     @Test(dataProvider = "byteByteProviderForIOOBE")
 562     static void storeByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 563         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 564         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 565 
 566         int l = a.limit();
 567         int s = SPECIES.vectorByteSize();
 568 
 569         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 570             for (int i = 0; i < l; i += s) {
 571                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 572                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
 573             }
 574         }
 575 
 576         int index = fi.apply(a.limit());
 577         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 578         try {
 579             ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 580             intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
 581             if (shouldFail) {
 582                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 583             }
 584         } catch (IndexOutOfBoundsException e) {
 585             if (!shouldFail) {
 586                 Assert.fail("Unexpected IndexOutOfBoundsException");
 587             }
 588         }
 589     }
 590 
 591 
 592     @Test(dataProvider = "byteByteBufferMaskProvider")
 593     static void loadStoreByteBufferMask(IntFunction<byte[]> fa,
 594                                         IntFunction<ByteBuffer> fb,
 595                                         IntFunction<boolean[]> fm,
 596                                         ByteOrder bo) {
 597         byte[] _a = fa.apply(SPECIES.length());
 598         ByteBuffer a = toBuffer(_a, fb);
 599         ByteBuffer r = fb.apply(a.limit());
 600         boolean[] mask = fm.apply(SPECIES.length());
 601         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 602 
 603         int l = a.limit();
 604         int s = SPECIES.vectorByteSize();
 605 
 606         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 607             for (int i = 0; i < l; i += s) {
 608                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
 609                 av.intoByteBuffer(r, i, bo);
 610             }
 611         }
 612         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 613         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 614         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 615         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 616         assertArraysEquals(bufferToArray(r), _a, mask);
 617 
 618 
 619         r = fb.apply(a.limit());
 620 
 621         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 622             for (int i = 0; i < l; i += s) {
 623                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 624                 av.intoByteBuffer(r, i, bo, vmask);
 625             }
 626         }
 627         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 628         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 629         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 630         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 631         assertArraysEquals(bufferToArray(r), _a, mask);
 632     }
 633 
 634     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 635     static void loadByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 636         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 637         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 638         boolean[] mask = fm.apply(SPECIES.length());
 639         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 640 
 641         int l = a.limit();
 642         int s = SPECIES.vectorByteSize();
 643 
 644         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 645             for (int i = 0; i < l; i += s) {
 646                 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
 647                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 648             }
 649         }
 650 
 651         int index = fi.apply(a.limit());
 652         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 653         try {
 654             fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
 655             if (shouldFail) {
 656                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 657             }
 658         } catch (IndexOutOfBoundsException e) {
 659             if (!shouldFail) {
 660                 Assert.fail("Unexpected IndexOutOfBoundsException");
 661             }
 662         }
 663     }
 664 
 665     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 666     static void storeByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 667         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 668         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 669         boolean[] mask = fm.apply(SPECIES.length());
 670         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 671 
 672         int l = a.limit();
 673         int s = SPECIES.vectorByteSize();
 674 
 675         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 676             for (int i = 0; i < l; i += s) {
 677                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 678                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
 679             }
 680         }
 681 
 682         int index = fi.apply(a.limit());
 683         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 684         try {
 685             ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 686             intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
 687             if (shouldFail) {
 688                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 689             }
 690         } catch (IndexOutOfBoundsException e) {
 691             if (!shouldFail) {
 692                 Assert.fail("Unexpected IndexOutOfBoundsException");
 693             }
 694         }
 695     }
 696 
 697 
 698     @Test(dataProvider = "byteByteBufferProvider")
 699     static void loadStoreReadonlyByteBuffer(IntFunction<byte[]> fa,
 700                                     IntFunction<ByteBuffer> fb,
 701                                     ByteOrder bo) {
 702         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
 703 
 704         try {
 705             SPECIES.zero().intoByteBuffer(a, 0, bo);
 706             Assert.fail("ReadOnlyBufferException expected");
 707         } catch (ReadOnlyBufferException e) {
 708         }
 709 
 710         try {
 711             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
 712             Assert.fail("ReadOnlyBufferException expected");
 713         } catch (ReadOnlyBufferException e) {
 714         }
 715 
 716         try {
 717             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
 718             Assert.fail("ReadOnlyBufferException expected");
 719         } catch (ReadOnlyBufferException e) {
 720         }
 721 
 722         try {
 723             VectorMask<Byte> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 724                     .laneIsValid();
 725             SPECIES.zero().intoByteBuffer(a, 0, bo, m);
 726             Assert.fail("ReadOnlyBufferException expected");
 727         } catch (ReadOnlyBufferException e) {
 728         }
 729     }
 730 
 731 
 732     @Test(dataProvider = "byteByteArrayProvider")
 733     static void loadStoreByteArray(IntFunction<byte[]> fa,
 734                                     ByteOrder bo) {
 735         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 736         byte[] r = new byte[a.length];
 737 
 738         int s = SPECIES.vectorByteSize();
 739         int l = a.length;
 740 
 741         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 742             for (int i = 0; i < l; i += s) {
 743                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
 744                 av.intoByteArray(r, i, bo);
 745             }
 746         }
 747         Assert.assertEquals(r, a, "Byte arrays not equal");
 748     }
 749 
 750     @Test(dataProvider = "byteByteProviderForIOOBE")
 751     static void loadByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 752         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 753         byte[] r = new byte[a.length];
 754 
 755         int s = SPECIES.vectorByteSize();
 756         int l = a.length;
 757 
 758         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 759             for (int i = 0; i < l; i += s) {
 760                 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
 761                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 762             }
 763         }
 764 
 765         int index = fi.apply(a.length);
 766         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 767         try {
 768             fromByteArray(a, index, ByteOrder.nativeOrder());
 769             if (shouldFail) {
 770                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 771             }
 772         } catch (IndexOutOfBoundsException e) {
 773             if (!shouldFail) {
 774                 Assert.fail("Unexpected IndexOutOfBoundsException");
 775             }
 776         }
 777     }
 778 
 779     @Test(dataProvider = "byteByteProviderForIOOBE")
 780     static void storeByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 781         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 782         byte[] r = new byte[a.length];
 783 
 784         int s = SPECIES.vectorByteSize();
 785         int l = a.length;
 786 
 787         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 788             for (int i = 0; i < l; i += s) {
 789                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 790                 intoByteArray(av, r, i, ByteOrder.nativeOrder());
 791             }
 792         }
 793 
 794         int index = fi.apply(a.length);
 795         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 796         try {
 797             ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 798             intoByteArray(av, r, index, ByteOrder.nativeOrder());
 799             if (shouldFail) {
 800                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 801             }
 802         } catch (IndexOutOfBoundsException e) {
 803             if (!shouldFail) {
 804                 Assert.fail("Unexpected IndexOutOfBoundsException");
 805             }
 806         }
 807     }
 808 
 809 
 810     @Test(dataProvider = "byteByteArrayMaskProvider")
 811     static void loadStoreByteArrayMask(IntFunction<byte[]> fa,
 812                                   IntFunction<boolean[]> fm,
 813                                   ByteOrder bo) {
 814         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 815         byte[] r = new byte[a.length];
 816         boolean[] mask = fm.apply(SPECIES.length());
 817         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 818 
 819         int s = SPECIES.vectorByteSize();
 820         int l = a.length;
 821 
 822         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 823           for (int i = 0; i < l; i += s) {
 824               ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo, vmask);
 825               av.intoByteArray(r, i, bo);
 826           }
 827         }
 828         assertArraysEquals(r, a, mask);
 829 
 830 
 831         r = new byte[a.length];
 832 
 833         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 834             for (int i = 0; i < l; i += s) {
 835                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
 836                 av.intoByteArray(r, i, bo, vmask);
 837             }
 838         }
 839         assertArraysEquals(r, a, mask);
 840     }
 841 
 842     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 843     static void loadByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 844         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 845         byte[] r = new byte[a.length];
 846         boolean[] mask = fm.apply(SPECIES.length());
 847         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 848 
 849         int s = SPECIES.vectorByteSize();
 850         int l = a.length;
 851 
 852         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 853             for (int i = 0; i < l; i += s) {
 854                 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
 855                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 856             }
 857         }
 858 
 859         int index = fi.apply(a.length);
 860         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 861         try {
 862             fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
 863             if (shouldFail) {
 864                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 865             }
 866         } catch (IndexOutOfBoundsException e) {
 867             if (!shouldFail) {
 868                 Assert.fail("Unexpected IndexOutOfBoundsException");
 869             }
 870         }
 871     }
 872 
 873     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 874     static void storeByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 875         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 876         byte[] r = new byte[a.length];
 877         boolean[] mask = fm.apply(SPECIES.length());
 878         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 879 
 880         int s = SPECIES.vectorByteSize();
 881         int l = a.length;
 882 
 883         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 884             for (int i = 0; i < l; i += s) {
 885                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 886                 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
 887             }
 888         }
 889 
 890         int index = fi.apply(a.length);
 891         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 892         try {
 893             ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 894             intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
 895             if (shouldFail) {
 896                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 897             }
 898         } catch (IndexOutOfBoundsException e) {
 899             if (!shouldFail) {
 900                 Assert.fail("Unexpected IndexOutOfBoundsException");
 901             }
 902         }
 903     }
 904 
 905     @Test(dataProvider = "maskProvider")
 906     static void loadStoreMask(IntFunction<boolean[]> fm) {
 907         boolean[] a = fm.apply(SPECIES.length());
 908         boolean[] r = new boolean[a.length];
 909 
 910         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 911             for (int i = 0; i < a.length; i += SPECIES.length()) {
 912                 VectorMask<Byte> vmask = SPECIES.loadMask(a, i);
 913                 vmask.intoArray(r, i);
 914             }
 915         }
 916         Assert.assertEquals(r, a);
 917     }
 918 
 919     @Test
 920     static void loadStoreShuffle() {
 921         IntUnaryOperator fn = a -> a + 5;
 922         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 923             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 924             int [] r = shuffle.toArray();
 925 
 926             int [] a = expectedShuffle(SPECIES.length(), fn);
 927             Assert.assertEquals(r, a);
 928        }
 929     }
 930 
 931 
 932 
 933     static void assertArraysEquals(boolean[] r, byte[] a) {
 934         int i = 0;
 935         try {
 936             for (; i < a.length; i++) {
 937                 Assert.assertEquals(r[i], (a[i] & 1) == 1);
 938             }
 939         } catch (AssertionError e) {
 940             Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i);
 941         }
 942     }
 943 
 944     static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) {
 945         int i = 0;
 946         try {
 947             for (; i < a.length; i++) {
 948                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]);
 949             }
 950         } catch (AssertionError e) {
 951             Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i);
 952         }
 953     }
 954 
 955     static boolean[] convertToBooleanArray(byte[] a) {
 956         boolean[] r = new boolean[a.length];
 957 
 958         for (int i = 0; i < a.length; i++) {
 959             r[i] = (a[i] & 1) == 1;
 960         }
 961 
 962         return r;
 963     }
 964 
 965     @Test(dataProvider = "byteProvider")
 966     static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) {
 967         byte[] a = fa.apply(SPECIES.length());
 968         boolean[] r = new boolean[a.length];
 969 
 970         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 971             for (int i = 0; i < a.length; i += SPECIES.length()) {
 972                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 973                 av.intoBooleanArray(r, i);
 974             }
 975         }
 976         assertArraysEquals(r, a);
 977     }
 978 
 979     @Test(dataProvider = "byteProvider")
 980     static void loadStoreBooleanArray(IntFunction<byte[]> fa) {
 981         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 982         boolean[] r = new boolean[a.length];
 983 
 984         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 985             for (int i = 0; i < a.length; i += SPECIES.length()) {
 986                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
 987                 av.intoBooleanArray(r, i);
 988             }
 989         }
 990         Assert.assertEquals(r, a);
 991     }
 992 
 993     @Test(dataProvider = "byteMaskProvider")
 994     static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa,
 995                                           IntFunction<boolean[]> fm) {
 996         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 997         boolean[] r = new boolean[a.length];
 998         boolean[] mask = fm.apply(SPECIES.length());
 999         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
1000 
1001         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1002             for (int i = 0; i < a.length; i += SPECIES.length()) {
1003                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask);
1004                 av.intoBooleanArray(r, i);
1005             }
1006         }
1007         assertArraysEquals(r, a, mask);
1008 
1009 
1010         r = new boolean[a.length];
1011 
1012         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1013             for (int i = 0; i < a.length; i += SPECIES.length()) {
1014                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1015                 av.intoBooleanArray(r, i, vmask);
1016             }
1017         }
1018         assertArraysEquals(r, a, mask);
1019     }
1020 
1021 
1022     // Gather/Scatter load/store tests
1023 
1024     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap) {
1025         int i = 0;
1026         int j = 0;
1027         try {
1028             for (; i < a.length; i += SPECIES.length()) {
1029                 j = i;
1030                 for (; j < i + SPECIES.length(); j++) {
1031                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1032                 }
1033             }
1034         } catch (AssertionError e) {
1035             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1036         }
1037     }
1038 
1039     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
1040         int i = 0;
1041         int j = 0;
1042         try {
1043             for (; i < a.length; i += SPECIES.length()) {
1044                 j = i;
1045                 for (; j < i + SPECIES.length(); j++) {
1046                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0);
1047                 }
1048             }
1049         } catch (AssertionError e) {
1050             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0, "at index #" + j);
1051         }
1052     }
1053 
1054     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
1055         byte[] expected = new byte[r.length];
1056 
1057         // Store before checking, since the same location may be stored to more than once
1058         for (int i = 0; i < a.length; i += SPECIES.length()) {
1059             for (int j = i; j < i + SPECIES.length(); j++) {
1060                 if (mask[j % SPECIES.length()]) {
1061                     expected[i + indexMap[j]] = a[j];
1062                 }
1063             }
1064         }
1065 
1066         Assert.assertEquals(r, expected);
1067     }
1068 
1069     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap) {
1070         byte[] expected = new byte[r.length];
1071 
1072         // Store before checking, since the same location may be stored to more than once
1073         for (int i = 0; i < a.length; i += SPECIES.length()) {
1074             for (int j = i; j < i + SPECIES.length(); j++) {
1075                 expected[i + indexMap[j]] = a[j];
1076             }
1077         }
1078 
1079         Assert.assertEquals(r, expected);
1080     }
1081 
1082     @DataProvider
1083     public Object[][] gatherScatterProvider() {
1084         return INT_INDEX_GENERATORS.stream().
1085                 flatMap(fs -> BYTE_GENERATORS.stream().map(fa -> {
1086                     return new Object[] {fa, fs};
1087                 })).
1088                 toArray(Object[][]::new);
1089     }
1090 
1091     @DataProvider
1092     public Object[][] gatherScatterMaskProvider() {
1093         return BOOLEAN_MASK_GENERATORS.stream().
1094           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1095             BYTE_GENERATORS.stream().map(fa -> {
1096                     return new Object[] {fa, fm, fs};
1097             }))).
1098             toArray(Object[][]::new);
1099     }
1100 
1101 
1102     @Test(dataProvider = "gatherScatterProvider")
1103     static void gather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1104         byte[] a = fa.apply(SPECIES.length());
1105         int[] b = fs.apply(a.length, SPECIES.length());
1106         byte[] r = new byte[a.length];
1107 
1108         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1109             for (int i = 0; i < a.length; i += SPECIES.length()) {
1110                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i);
1111                 av.intoArray(r, i);
1112             }
1113         }
1114 
1115         assertGatherArraysEquals(r, a, b);
1116     }
1117 
1118     @Test(dataProvider = "gatherScatterMaskProvider")
1119     static void gatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1120         byte[] a = fa.apply(SPECIES.length());
1121         int[] b = fs.apply(a.length, SPECIES.length());
1122         byte[] r = new byte[a.length];
1123         boolean[] mask = fm.apply(SPECIES.length());
1124         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1125 
1126         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1127             for (int i = 0; i < a.length; i += SPECIES.length()) {
1128                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i, vmask);
1129                 av.intoArray(r, i);
1130             }
1131         }
1132 
1133         assertGatherArraysEquals(r, a, b, mask);
1134     }
1135 
1136     @Test(dataProvider = "gatherScatterProvider")
1137     static void scatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1138         byte[] a = fa.apply(SPECIES.length());
1139         int[] b = fs.apply(a.length, SPECIES.length());
1140         byte[] r = new byte[a.length];
1141 
1142         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1143             for (int i = 0; i < a.length; i += SPECIES.length()) {
1144                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1145                 av.intoArray(r, i, b, i);
1146             }
1147         }
1148 
1149         assertScatterArraysEquals(r, a, b);
1150     }
1151 
1152     @Test(dataProvider = "gatherScatterMaskProvider")
1153     static void scatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1154         byte[] a = fa.apply(SPECIES.length());
1155         int[] b = fs.apply(a.length, SPECIES.length());
1156         byte[] r = new byte[a.length];
1157         boolean[] mask = fm.apply(SPECIES.length());
1158         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1159 
1160         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1161             for (int i = 0; i < a.length; i += SPECIES.length()) {
1162                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1163                 av.intoArray(r, i, b, i, vmask);
1164             }
1165         }
1166 
1167         assertScatterArraysEquals(r, a, b, mask);
1168     }
1169 
1170 
1171     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1172         int i = 0;
1173         int j = 0;
1174         try {
1175             for (; i < a.length; i += SPECIES.length()) {
1176                 j = i;
1177                 for (; j < i + SPECIES.length(); j++) {
1178                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1179                 }
1180             }
1181         } catch (AssertionError e) {
1182             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1183         }
1184     }
1185 
1186     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1187         int i = 0;
1188         int j = 0;
1189         try {
1190             for (; i < a.length; i += SPECIES.length()) {
1191                 j = i;
1192                 for (; j < i + SPECIES.length(); j++) {
1193                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false);
1194                 }
1195             }
1196         } catch (AssertionError e) {
1197             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j);
1198         }
1199     }
1200 
1201     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1202         boolean[] expected = new boolean[r.length];
1203 
1204         // Store before checking, since the same location may be stored to more than once
1205         for (int i = 0; i < a.length; i += SPECIES.length()) {
1206             for (int j = i; j < i + SPECIES.length(); j++) {
1207                 if (mask[j % SPECIES.length()]) {
1208                     expected[i + indexMap[j]] = a[j];
1209                 }
1210             }
1211         }
1212 
1213         Assert.assertEquals(r, expected);
1214     }
1215 
1216     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1217         boolean[] expected = new boolean[r.length];
1218 
1219         // Store before checking, since the same location may be stored to more than once
1220         for (int i = 0; i < a.length; i += SPECIES.length()) {
1221             for (int j = i; j < i + SPECIES.length(); j++) {
1222                 expected[i + indexMap[j]] = a[j];
1223             }
1224         }
1225 
1226         Assert.assertEquals(r, expected);
1227     }
1228 
1229     @Test(dataProvider = "gatherScatterProvider")
1230     static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1231         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1232         int[] b = fs.apply(a.length, SPECIES.length());
1233         boolean[] r = new boolean[a.length];
1234 
1235         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1236             for (int i = 0; i < a.length; i += SPECIES.length()) {
1237                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i);
1238                 av.intoBooleanArray(r, i);
1239             }
1240         }
1241 
1242         assertGatherArraysEquals(r, a, b);
1243     }
1244 
1245     @Test(dataProvider = "gatherScatterMaskProvider")
1246     static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1247         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1248         int[] b = fs.apply(a.length, SPECIES.length());
1249         boolean[] r = new boolean[a.length];
1250         boolean[] mask = fm.apply(SPECIES.length());
1251         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1252 
1253         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1254             for (int i = 0; i < a.length; i += SPECIES.length()) {
1255                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i, vmask);
1256                 av.intoBooleanArray(r, i);
1257             }
1258         }
1259 
1260         assertGatherArraysEquals(r, a, b, mask);
1261     }
1262 
1263     @Test(dataProvider = "gatherScatterProvider")
1264     static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1265         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1266         int[] b = fs.apply(a.length, SPECIES.length());
1267         boolean[] r = new boolean[a.length];
1268 
1269         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1270             for (int i = 0; i < a.length; i += SPECIES.length()) {
1271                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1272                 av.intoBooleanArray(r, i, b, i);
1273             }
1274         }
1275 
1276         assertScatterArraysEquals(r, a, b);
1277     }
1278 
1279     @Test(dataProvider = "gatherScatterMaskProvider")
1280     static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1281         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1282         int[] b = fs.apply(a.length, SPECIES.length());
1283         boolean[] r = new boolean[a.length];
1284         boolean[] mask = fm.apply(SPECIES.length());
1285         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1286 
1287         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1288             for (int i = 0; i < a.length; i += SPECIES.length()) {
1289                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1290                 av.intoBooleanArray(r, i, b, i, vmask);
1291             }
1292         }
1293 
1294         assertScatterArraysEquals(r, a, b, mask);
1295     }
1296 
1297 }