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 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
  28  *      -XX:-TieredCompilation ByteMaxVectorLoadStoreTests
  29  *
  30  */
  31 
  32 // -- This file was mechanically generated: Do not edit! -- //
  33 



  34 import jdk.incubator.vector.ByteVector;
  35 import jdk.incubator.vector.VectorMask;
  36 import jdk.incubator.vector.VectorShape;
  37 import jdk.incubator.vector.VectorSpecies;
  38 import jdk.incubator.vector.VectorShuffle;
  39 import jdk.internal.vm.annotation.DontInline;
  40 import org.testng.Assert;
  41 import org.testng.annotations.DataProvider;
  42 import org.testng.annotations.Test;
  43 
  44 import java.lang.invoke.MethodHandles;
  45 import java.lang.invoke.VarHandle;
  46 import java.nio.ByteBuffer;
  47 import java.nio.ByteOrder;
  48 import java.nio.ReadOnlyBufferException;
  49 import java.util.List;
  50 import java.util.function.*;
  51 
  52 @Test
  53 public class ByteMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest {
  54     static final VectorSpecies<Byte> SPECIES =
  55                 ByteVector.SPECIES_MAX;
  56 
  57     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  58 
  59     static VectorShape getMaxBit() {
  60         return VectorShape.S_Max_BIT;
  61     }
  62 
  63     private static final int Max = 256;  // juts so we can do N/Max
  64 
  65     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max);
  66 
  67     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
  68         int i = 0;
  69         try {
  70             for (; i < a.length; i++) {
  71                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0);
  72             }
  73         } catch (AssertionError e) {
  74             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
  75         }
  76     }
  77 
  78 
  79     static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
  80             withToString("byte[i * 5]", (int s) -> {
  81                 return fill(s * BUFFER_REPS,
  82                             i -> (byte)(i * 5));
  83             }),
  84             withToString("byte[i + 1]", (int s) -> {
  85                 return fill(s * BUFFER_REPS,
  86                             i -> (((byte)(i + 1) == 0) ? 1 : (byte)(i + 1)));
  87             })
  88     );
  89 
  90     // Relative to array.length
  91     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
  92             withToString("-1", (int l) -> {
  93                 return -1;
  94             }),
  95             withToString("l", (int l) -> {
  96                 return l;
  97             }),
  98             withToString("l - 1", (int l) -> {
  99                 return l - 1;
 100             }),
 101             withToString("l + 1", (int l) -> {
 102                 return l + 1;
 103             }),
 104             withToString("l - speciesl + 1", (int l) -> {
 105                 return l - SPECIES.length() + 1;
 106             }),
 107             withToString("l + speciesl - 1", (int l) -> {
 108                 return l + SPECIES.length() - 1;
 109             }),
 110             withToString("l + speciesl", (int l) -> {
 111                 return l + SPECIES.length();
 112             }),
 113             withToString("l + speciesl + 1", (int l) -> {
 114                 return l + SPECIES.length() + 1;
 115             })
 116     );
 117 
 118     // Relative to byte[] array.length or ByteBuffer.limit()
 119     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 120             withToString("-1", (int l) -> {
 121                 return -1;
 122             }),
 123             withToString("l", (int l) -> {
 124                 return l;
 125             }),
 126             withToString("l - 1", (int l) -> {
 127                 return l - 1;
 128             }),
 129             withToString("l + 1", (int l) -> {
 130                 return l + 1;
 131             }),
 132             withToString("l - speciesl*ebsize + 1", (int l) -> {
 133                 return l - SPECIES.vectorByteSize() + 1;
 134             }),
 135             withToString("l + speciesl*ebsize - 1", (int l) -> {
 136                 return l + SPECIES.vectorByteSize() - 1;
 137             }),
 138             withToString("l + speciesl*ebsize", (int l) -> {
 139                 return l + SPECIES.vectorByteSize();
 140             }),
 141             withToString("l + speciesl*ebsize + 1", (int l) -> {
 142                 return l + SPECIES.vectorByteSize() + 1;
 143             })
 144     );
 145 
 146     @DataProvider
 147     public Object[][] byteProvider() {
 148         return BYTE_GENERATORS.stream().
 149                 map(f -> new Object[]{f}).
 150                 toArray(Object[][]::new);
 151     }
 152 
 153     @DataProvider
 154     public Object[][] maskProvider() {
 155         return BOOLEAN_MASK_GENERATORS.stream().
 156                 map(f -> new Object[]{f}).
 157                 toArray(Object[][]::new);
 158     }
 159 
 160     @DataProvider
 161     public Object[][] byteProviderForIOOBE() {
 162         var f = BYTE_GENERATORS.get(0);
 163         return INDEX_GENERATORS.stream().map(fi -> {
 164                     return new Object[] {f, fi};
 165                 }).
 166                 toArray(Object[][]::new);
 167     }
 168 
 169     @DataProvider
 170     public Object[][] byteMaskProvider() {
 171         return BOOLEAN_MASK_GENERATORS.stream().
 172                 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> {
 173                     return new Object[] {fa, fm};
 174                 })).
 175                 toArray(Object[][]::new);
 176     }
 177 
 178     @DataProvider
 179     public Object[][] byteMaskProviderForIOOBE() {
 180         var f = BYTE_GENERATORS.get(0);
 181         return BOOLEAN_MASK_GENERATORS.stream().
 182                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 183                     return new Object[] {f, fi, fm};
 184                 })).
 185                 toArray(Object[][]::new);
 186     }
 187 
 188     @DataProvider
 189     public Object[][] byteByteBufferProvider() {
 190         return BYTE_GENERATORS.stream().
 191                 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 192                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 193                             return new Object[]{fa, fb, bo};
 194                         }))).
 195                 toArray(Object[][]::new);
 196     }
 197 
 198     @DataProvider
 199     public Object[][] byteByteBufferMaskProvider() {
 200         return BOOLEAN_MASK_GENERATORS.stream().
 201                 flatMap(fm -> BYTE_GENERATORS.stream().
 202                         flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 203                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 204                             return new Object[]{fa, fb, fm, bo};
 205                         })))).
 206                 toArray(Object[][]::new);
 207     }
 208 
 209     @DataProvider
 210     public Object[][] byteByteArrayProvider() {
 211         return BYTE_GENERATORS.stream().
 212                 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 213                     return new Object[]{fa, bo};
 214                 })).
 215                 toArray(Object[][]::new);
 216     }
 217 
 218     @DataProvider
 219     public Object[][] byteByteArrayMaskProvider() {
 220         return BOOLEAN_MASK_GENERATORS.stream().
 221                 flatMap(fm -> BYTE_GENERATORS.stream().
 222                     flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 223                         return new Object[]{fa, fm, bo};
 224                     }))).
 225                 toArray(Object[][]::new);
 226     }
 227 
 228     @DataProvider
 229     public Object[][] byteByteProviderForIOOBE() {
 230         var f = BYTE_GENERATORS.get(0);
 231         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 232                     return new Object[] {f, fi};
 233                 }).
 234                 toArray(Object[][]::new);
 235     }
 236 
 237     @DataProvider
 238     public Object[][] byteByteMaskProviderForIOOBE() {
 239         var f = BYTE_GENERATORS.get(0);
 240         return BOOLEAN_MASK_GENERATORS.stream().
 241                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 242                     return new Object[] {f, fi, fm};
 243                 })).
 244                 toArray(Object[][]::new);
 245     }
 246 
 247     static ByteBuffer toBuffer(byte[] a, IntFunction<ByteBuffer> fb) {
 248         ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
 249         for (byte v : a) {
 250             bb.put(v);
 251         }
 252         return bb.clear();
 253     }
 254 
 255     static byte[] bufferToArray(ByteBuffer bb) {
 256         ByteBuffer db = bb;
 257         byte[] d = new byte[db.capacity()];
 258         db.get(0, d);
 259         return d;
 260     }
 261 
 262     static byte[] toByteArray(byte[] a, IntFunction<byte[]> fb, ByteOrder bo) {
 263         byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
 264         ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo);
 265         for (byte v : a) {
 266             bb.put(v);
 267         }
 268         return b;
 269     }
 270 
 271 
 272     interface ToByteF {
 273         byte apply(int i);
 274     }
 275 
 276     static byte[] fill(int s , ToByteF f) {
 277         return fill(new byte[s], f);
 278     }
 279 
 280     static byte[] fill(byte[] a, ToByteF f) {
 281         for (int i = 0; i < a.length; i++) {
 282             a[i] = f.apply(i);
 283         }
 284         return a;
 285     }
 286 
 287     @DontInline
 288     static ByteVector fromArray(byte[] a, int i) {
 289         return ByteVector.fromArray(SPECIES, a, i);
 290     }
 291 
 292     @DontInline
 293     static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) {
 294         return ByteVector.fromArray(SPECIES, a, i, m);
 295     }
 296 
 297     @DontInline
 298     static void intoArray(ByteVector v, byte[] a, int i) {
 299         v.intoArray(a, i);
 300     }
 301 
 302     @DontInline
 303     static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) {
 304         v.intoArray(a, i, m);
 305     }
 306 
 307     @DontInline
 308     static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo) {
 309         return ByteVector.fromByteArray(SPECIES, a, i, bo);
 310     }
 311 
 312     @DontInline
 313     static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
 314         return ByteVector.fromByteArray(SPECIES, a, i, bo, m);
 315     }
 316 
 317     @DontInline
 318     static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo) {
 319         v.intoByteArray(a, i, bo);
 320     }
 321 
 322     @DontInline
 323     static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
 324         v.intoByteArray(a, i, bo, m);
 325     }
 326 
 327     @DontInline
 328     static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
 329         return ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 330     }
 331 
 332     @DontInline
 333     static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
 334         return ByteVector.fromByteBuffer(SPECIES, a, i, bo, m);
 335     }
 336 
 337     @DontInline
 338     static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo) {
 339         v.intoByteBuffer(a, i, bo);
 340     }
 341 
 342     @DontInline
 343     static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
 344         v.intoByteBuffer(a, i, bo, m);
 345     }
 346 
 347 
 348     @Test(dataProvider = "byteProvider")
 349     static void loadStoreArray(IntFunction<byte[]> fa) {
 350         byte[] a = fa.apply(SPECIES.length());
 351         byte[] r = new byte[a.length];
 352 
 353         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 354             for (int i = 0; i < a.length; i += SPECIES.length()) {
 355                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 356                 av.intoArray(r, i);
 357             }
 358         }
 359         Assert.assertEquals(r, a);
 360     }
 361 
 362     @Test(dataProvider = "byteProviderForIOOBE")
 363     static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 364         byte[] a = fa.apply(SPECIES.length());
 365         byte[] r = new byte[a.length];
 366 
 367         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 368             for (int i = 0; i < a.length; i += SPECIES.length()) {
 369                 ByteVector av = fromArray(a, i);
 370                 av.intoArray(r, i);
 371             }
 372         }
 373 
 374         int index = fi.apply(a.length);
 375         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 376         try {
 377             fromArray(a, index);
 378             if (shouldFail) {
 379                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 380             }
 381         } catch (IndexOutOfBoundsException e) {
 382             if (!shouldFail) {
 383                 Assert.fail("Unexpected IndexOutOfBoundsException");
 384             }
 385         }
 386     }
 387 
 388     @Test(dataProvider = "byteProviderForIOOBE")
 389     static void storeArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 390         byte[] a = fa.apply(SPECIES.length());
 391         byte[] r = new byte[a.length];
 392 
 393         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 394             for (int i = 0; i < a.length; i += SPECIES.length()) {
 395                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 396                 intoArray(av, r, i);
 397             }
 398         }
 399 
 400         int index = fi.apply(a.length);
 401         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 402         try {
 403             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 404             intoArray(av, r, index);
 405             if (shouldFail) {
 406                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 407             }
 408         } catch (IndexOutOfBoundsException e) {
 409             if (!shouldFail) {
 410                 Assert.fail("Unexpected IndexOutOfBoundsException");
 411             }
 412         }
 413     }
 414 
 415 
 416     @Test(dataProvider = "byteMaskProvider")
 417     static void loadStoreMaskArray(IntFunction<byte[]> fa,
 418                                    IntFunction<boolean[]> fm) {
 419         byte[] a = fa.apply(SPECIES.length());
 420         byte[] r = new byte[a.length];
 421         boolean[] mask = fm.apply(SPECIES.length());
 422         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 423 
 424         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 425             for (int i = 0; i < a.length; i += SPECIES.length()) {
 426                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, vmask);
 427                 av.intoArray(r, i);
 428             }
 429         }
 430         assertArraysEquals(r, a, mask);
 431 
 432 
 433         r = new byte[a.length];
 434 
 435         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 436             for (int i = 0; i < a.length; i += SPECIES.length()) {
 437                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 438                 av.intoArray(r, i, vmask);
 439             }
 440         }
 441         assertArraysEquals(r, a, mask);
 442     }
 443 
 444     @Test(dataProvider = "byteMaskProviderForIOOBE")
 445     static void loadArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 446         byte[] a = fa.apply(SPECIES.length());
 447         byte[] r = new byte[a.length];
 448         boolean[] mask = fm.apply(SPECIES.length());
 449         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 450 
 451         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 452             for (int i = 0; i < a.length; i += SPECIES.length()) {
 453                 ByteVector av = fromArray(a, i, vmask);
 454                 av.intoArray(r, i);
 455             }
 456         }
 457 
 458         int index = fi.apply(a.length);
 459         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 460         try {
 461             fromArray(a, index, vmask);
 462             if (shouldFail) {
 463                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 464             }
 465         } catch (IndexOutOfBoundsException e) {
 466             if (!shouldFail) {
 467                 Assert.fail("Unexpected IndexOutOfBoundsException");
 468             }
 469         }
 470     }
 471 
 472     @Test(dataProvider = "byteMaskProviderForIOOBE")
 473     static void storeArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 474         byte[] a = fa.apply(SPECIES.length());
 475         byte[] r = new byte[a.length];
 476         boolean[] mask = fm.apply(SPECIES.length());
 477         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 478 
 479         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 480             for (int i = 0; i < a.length; i += SPECIES.length()) {
 481                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 482                 intoArray(av, r, i, vmask);
 483             }
 484         }
 485 
 486         int index = fi.apply(a.length);
 487         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 488         try {
 489             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 490             intoArray(av, a, index, vmask);
 491             if (shouldFail) {
 492                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 493             }
 494         } catch (IndexOutOfBoundsException e) {
 495             if (!shouldFail) {
 496                 Assert.fail("Unexpected IndexOutOfBoundsException");
 497             }
 498         }
 499     }
 500 
 501 
 502     @Test(dataProvider = "byteMaskProvider")
 503     static void loadStoreMask(IntFunction<byte[]> fa,
 504                               IntFunction<boolean[]> fm) {
 505         boolean[] mask = fm.apply(SPECIES.length());
 506         boolean[] r = new boolean[mask.length];
 507 
 508         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 509             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 510                 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i);
 511                 vmask.intoArray(r, i);
 512             }
 513         }
 514         Assert.assertEquals(r, mask);
 515     }
 516 
 517 
 518     @Test(dataProvider = "byteByteBufferProvider")
 519     static void loadStoreByteBuffer(IntFunction<byte[]> fa,
 520                                     IntFunction<ByteBuffer> fb,
 521                                     ByteOrder bo) {
 522         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
 523         ByteBuffer r = fb.apply(a.limit());
 524 
 525         int l = a.limit();
 526         int s = SPECIES.vectorByteSize();
 527 
 528         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 529             for (int i = 0; i < l; i += s) {
 530                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 531                 av.intoByteBuffer(r, i, bo);
 532             }
 533         }
 534         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 535         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 536         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 537         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 538         Assert.assertEquals(r, a, "Buffers not equal");
 539     }
 540 
 541     @Test(dataProvider = "byteByteProviderForIOOBE")
 542     static void loadByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 543         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 544         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 545 
 546         int l = a.limit();
 547         int s = SPECIES.vectorByteSize();
 548 
 549         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 550             for (int i = 0; i < l; i += s) {
 551                 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
 552                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 553             }
 554         }
 555 
 556         int index = fi.apply(a.limit());
 557         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 558         try {
 559             fromByteBuffer(a, index, ByteOrder.nativeOrder());
 560             if (shouldFail) {
 561                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 562             }
 563         } catch (IndexOutOfBoundsException e) {
 564             if (!shouldFail) {
 565                 Assert.fail("Unexpected IndexOutOfBoundsException");
 566             }
 567         }
 568     }
 569 
 570     @Test(dataProvider = "byteByteProviderForIOOBE")
 571     static void storeByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 572         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 573         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 574 
 575         int l = a.limit();
 576         int s = SPECIES.vectorByteSize();
 577 
 578         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 579             for (int i = 0; i < l; i += s) {
 580                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 581                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
 582             }
 583         }
 584 
 585         int index = fi.apply(a.limit());
 586         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 587         try {
 588             ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 589             intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
 590             if (shouldFail) {
 591                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 592             }
 593         } catch (IndexOutOfBoundsException e) {
 594             if (!shouldFail) {
 595                 Assert.fail("Unexpected IndexOutOfBoundsException");
 596             }
 597         }
 598     }
 599 
 600 
 601     @Test(dataProvider = "byteByteBufferMaskProvider")
 602     static void loadStoreByteBufferMask(IntFunction<byte[]> fa,
 603                                         IntFunction<ByteBuffer> fb,
 604                                         IntFunction<boolean[]> fm,
 605                                         ByteOrder bo) {
 606         byte[] _a = fa.apply(SPECIES.length());
 607         ByteBuffer a = toBuffer(_a, fb);
 608         ByteBuffer r = fb.apply(a.limit());
 609         boolean[] mask = fm.apply(SPECIES.length());
 610         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 611 
 612         int l = a.limit();
 613         int s = SPECIES.vectorByteSize();
 614 
 615         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 616             for (int i = 0; i < l; i += s) {
 617                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
 618                 av.intoByteBuffer(r, i, bo);
 619             }
 620         }
 621         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 622         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 623         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 624         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 625         assertArraysEquals(bufferToArray(r), _a, mask);
 626 
 627 
 628         r = fb.apply(a.limit());
 629 
 630         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 631             for (int i = 0; i < l; i += s) {
 632                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
 633                 av.intoByteBuffer(r, i, bo, vmask);
 634             }
 635         }
 636         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 637         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 638         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 639         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 640         assertArraysEquals(bufferToArray(r), _a, mask);
 641     }
 642 
 643     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 644     static void loadByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 645         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 646         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 647         boolean[] mask = fm.apply(SPECIES.length());
 648         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 649 
 650         int l = a.limit();
 651         int s = SPECIES.vectorByteSize();
 652 
 653         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 654             for (int i = 0; i < l; i += s) {
 655                 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
 656                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 657             }
 658         }
 659 
 660         int index = fi.apply(a.limit());
 661         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 662         try {
 663             fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
 664             if (shouldFail) {
 665                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 666             }
 667         } catch (IndexOutOfBoundsException e) {
 668             if (!shouldFail) {
 669                 Assert.fail("Unexpected IndexOutOfBoundsException");
 670             }
 671         }
 672     }
 673 
 674     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 675     static void storeByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 676         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 677         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 678         boolean[] mask = fm.apply(SPECIES.length());
 679         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 680 
 681         int l = a.limit();
 682         int s = SPECIES.vectorByteSize();
 683 
 684         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 685             for (int i = 0; i < l; i += s) {
 686                 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 687                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
 688             }
 689         }
 690 
 691         int index = fi.apply(a.limit());
 692         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 693         try {
 694             ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 695             intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
 696             if (shouldFail) {
 697                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 698             }
 699         } catch (IndexOutOfBoundsException e) {
 700             if (!shouldFail) {
 701                 Assert.fail("Unexpected IndexOutOfBoundsException");
 702             }
 703         }
 704     }
 705 
 706 
 707     @Test(dataProvider = "byteByteBufferProvider")
 708     static void loadStoreReadonlyByteBuffer(IntFunction<byte[]> fa,
 709                                     IntFunction<ByteBuffer> fb,
 710                                     ByteOrder bo) {
 711         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
 712 
 713         try {
 714             SPECIES.zero().intoByteBuffer(a, 0, bo);
 715             Assert.fail("ReadOnlyBufferException expected");
 716         } catch (ReadOnlyBufferException e) {
 717         }
 718 
 719         try {
 720             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
 721             Assert.fail("ReadOnlyBufferException expected");
 722         } catch (ReadOnlyBufferException e) {
 723         }
 724 
 725         try {
 726             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
 727             Assert.fail("ReadOnlyBufferException expected");
 728         } catch (ReadOnlyBufferException e) {
 729         }
 730 
 731         try {
 732             VectorMask<Byte> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 733                     .laneIsValid();
 734             SPECIES.zero().intoByteBuffer(a, 0, bo, m);
 735             Assert.fail("ReadOnlyBufferException expected");
 736         } catch (ReadOnlyBufferException e) {
 737         }
 738     }
 739 
 740 
 741     @Test(dataProvider = "byteByteArrayProvider")
 742     static void loadStoreByteArray(IntFunction<byte[]> fa,
 743                                     ByteOrder bo) {
 744         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 745         byte[] r = new byte[a.length];
 746 
 747         int s = SPECIES.vectorByteSize();
 748         int l = a.length;
 749 
 750         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 751             for (int i = 0; i < l; i += s) {
 752                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
 753                 av.intoByteArray(r, i, bo);
 754             }
 755         }
 756         Assert.assertEquals(r, a, "Byte arrays not equal");
 757     }
 758 
 759     @Test(dataProvider = "byteByteProviderForIOOBE")
 760     static void loadByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 761         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 762         byte[] r = new byte[a.length];
 763 
 764         int s = SPECIES.vectorByteSize();
 765         int l = a.length;
 766 
 767         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 768             for (int i = 0; i < l; i += s) {
 769                 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
 770                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 771             }
 772         }
 773 
 774         int index = fi.apply(a.length);
 775         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 776         try {
 777             fromByteArray(a, index, ByteOrder.nativeOrder());
 778             if (shouldFail) {
 779                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 780             }
 781         } catch (IndexOutOfBoundsException e) {
 782             if (!shouldFail) {
 783                 Assert.fail("Unexpected IndexOutOfBoundsException");
 784             }
 785         }
 786     }
 787 
 788     @Test(dataProvider = "byteByteProviderForIOOBE")
 789     static void storeByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 790         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 791         byte[] r = new byte[a.length];
 792 
 793         int s = SPECIES.vectorByteSize();
 794         int l = a.length;
 795 
 796         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 797             for (int i = 0; i < l; i += s) {
 798                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 799                 intoByteArray(av, r, i, ByteOrder.nativeOrder());
 800             }
 801         }
 802 
 803         int index = fi.apply(a.length);
 804         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 805         try {
 806             ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 807             intoByteArray(av, r, index, ByteOrder.nativeOrder());
 808             if (shouldFail) {
 809                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 810             }
 811         } catch (IndexOutOfBoundsException e) {
 812             if (!shouldFail) {
 813                 Assert.fail("Unexpected IndexOutOfBoundsException");
 814             }
 815         }
 816     }
 817 





 818 
 819     @Test(dataProvider = "byteByteArrayMaskProvider")
 820     static void loadStoreByteArrayMask(IntFunction<byte[]> fa,
 821                                   IntFunction<boolean[]> fm,
 822                                   ByteOrder bo) {
 823         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 824         byte[] r = new byte[a.length];
 825         boolean[] mask = fm.apply(SPECIES.length());
 826         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 827 
 828         int s = SPECIES.vectorByteSize();
 829         int l = a.length;
 830 
 831         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 832           for (int i = 0; i < l; i += s) {
 833               ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo, vmask);
 834               av.intoByteArray(r, i, bo);
 835           }
 836         }
 837         assertArraysEquals(r, a, mask);
 838 
 839 
 840         r = new byte[a.length];
 841 
 842         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 843             for (int i = 0; i < l; i += s) {
 844                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
 845                 av.intoByteArray(r, i, bo, vmask);
 846             }
 847         }
 848         assertArraysEquals(r, a, mask);
 849     }
 850 
 851     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 852     static void loadByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 853         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 854         byte[] r = new byte[a.length];
 855         boolean[] mask = fm.apply(SPECIES.length());
 856         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 857 
 858         int s = SPECIES.vectorByteSize();
 859         int l = a.length;


 860 
 861         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 862             for (int i = 0; i < l; i += s) {
 863                 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
 864                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 865             }
 866         }
 867 
 868         int index = fi.apply(a.length);
 869         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 870         try {
 871             fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
 872             if (shouldFail) {
 873                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 874             }
 875         } catch (IndexOutOfBoundsException e) {
 876             if (!shouldFail) {
 877                 Assert.fail("Unexpected IndexOutOfBoundsException");
 878             }
 879         }
 880     }
 881 
 882     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 883     static void storeByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 884         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 885         byte[] r = new byte[a.length];
 886         boolean[] mask = fm.apply(SPECIES.length());
 887         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 888 
 889         int s = SPECIES.vectorByteSize();
 890         int l = a.length;
 891 
 892         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 893             for (int i = 0; i < l; i += s) {
 894                 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 895                 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
 896             }
 897         }
 898 
 899         int index = fi.apply(a.length);
 900         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 901         try {
 902             ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 903             intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
 904             if (shouldFail) {
 905                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 906             }
 907         } catch (IndexOutOfBoundsException e) {
 908             if (!shouldFail) {
 909                 Assert.fail("Unexpected IndexOutOfBoundsException");
 910             }
 911         }
 912     }
 913 
 914     @Test(dataProvider = "maskProvider")
 915     static void loadStoreMask(IntFunction<boolean[]> fm) {
 916         boolean[] a = fm.apply(SPECIES.length());
 917         boolean[] r = new boolean[a.length];
 918 
 919         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 920             for (int i = 0; i < a.length; i += SPECIES.length()) {
 921                 VectorMask<Byte> vmask = SPECIES.loadMask(a, i);
 922                 vmask.intoArray(r, i);
 923             }
 924         }
 925         Assert.assertEquals(r, a);
 926     }
 927 

 928     @Test
 929     static void loadStoreShuffle() {
 930         IntUnaryOperator fn = a -> a + 5;
 931         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 932             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 933             int [] r = shuffle.toArray();
 934 
 935             int [] a = expectedShuffle(SPECIES.length(), fn);
 936             Assert.assertEquals(r, a);
 937        }
 938     }
 939 
 940 
 941 
 942     static void assertArraysEquals(boolean[] r, byte[] a) {
 943         int i = 0;
 944         try {
 945             for (; i < a.length; i++) {
 946                 Assert.assertEquals(r[i], (a[i] & 1) == 1);
 947             }
 948         } catch (AssertionError e) {
 949             Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i);
 950         }
 951     }
 952 
 953     static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) {
 954         int i = 0;
 955         try {
 956             for (; i < a.length; i++) {
 957                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]);
 958             }
 959         } catch (AssertionError e) {
 960             Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i);
 961         }
 962     }
 963 
 964     static boolean[] convertToBooleanArray(byte[] a) {
 965         boolean[] r = new boolean[a.length];
 966 
 967         for (int i = 0; i < a.length; i++) {
 968             r[i] = (a[i] & 1) == 1;
 969         }
 970 
 971         return r;
 972     }
 973 
 974     @Test(dataProvider = "byteProvider")
 975     static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) {
 976         byte[] a = fa.apply(SPECIES.length());
 977         boolean[] r = new boolean[a.length];
 978 
 979         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 980             for (int i = 0; i < a.length; i += SPECIES.length()) {
 981                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 982                 av.intoBooleanArray(r, i);
 983             }
 984         }
 985         assertArraysEquals(r, a);
 986     }
 987 
 988     @Test(dataProvider = "byteProvider")
 989     static void loadStoreBooleanArray(IntFunction<byte[]> fa) {
 990         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 991         boolean[] r = new boolean[a.length];
 992 
 993         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 994             for (int i = 0; i < a.length; i += SPECIES.length()) {
 995                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
 996                 av.intoBooleanArray(r, i);
 997             }
 998         }
 999         Assert.assertEquals(r, a);
1000     }
1001 
1002     @Test(dataProvider = "byteMaskProvider")
1003     static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa,
1004                                           IntFunction<boolean[]> fm) {
1005         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1006         boolean[] r = new boolean[a.length];
1007         boolean[] mask = fm.apply(SPECIES.length());
1008         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
1009 
1010         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1011             for (int i = 0; i < a.length; i += SPECIES.length()) {
1012                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask);
1013                 av.intoBooleanArray(r, i);
1014             }
1015         }
1016         assertArraysEquals(r, a, mask);
1017 
1018 
1019         r = new boolean[a.length];
1020 
1021         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1022             for (int i = 0; i < a.length; i += SPECIES.length()) {
1023                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1024                 av.intoBooleanArray(r, i, vmask);
1025             }
1026         }
1027         assertArraysEquals(r, a, mask);
1028     }
1029 
1030 
1031     // Gather/Scatter load/store tests
1032 
1033     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap) {
1034         int i = 0;
1035         int j = 0;
1036         try {
1037             for (; i < a.length; i += SPECIES.length()) {
1038                 j = i;
1039                 for (; j < i + SPECIES.length(); j++) {
1040                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1041                 }
1042             }
1043         } catch (AssertionError e) {
1044             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1045         }
1046     }
1047 
1048     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
1049         int i = 0;
1050         int j = 0;
1051         try {
1052             for (; i < a.length; i += SPECIES.length()) {
1053                 j = i;
1054                 for (; j < i + SPECIES.length(); j++) {
1055                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0);
1056                 }
1057             }
1058         } catch (AssertionError e) {
1059             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0, "at index #" + j);
1060         }
1061     }
1062 
1063     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
1064         byte[] expected = new byte[r.length];
1065 
1066         // Store before checking, since the same location may be stored to more than once
1067         for (int i = 0; i < a.length; i += SPECIES.length()) {
1068             for (int j = i; j < i + SPECIES.length(); j++) {
1069                 if (mask[j % SPECIES.length()]) {
1070                     expected[i + indexMap[j]] = a[j];
1071                 }
1072             }
1073         }
1074 
1075         Assert.assertEquals(r, expected);
1076     }
1077 
1078     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap) {
1079         byte[] expected = new byte[r.length];
1080 
1081         // Store before checking, since the same location may be stored to more than once
1082         for (int i = 0; i < a.length; i += SPECIES.length()) {
1083             for (int j = i; j < i + SPECIES.length(); j++) {
1084                 expected[i + indexMap[j]] = a[j];
1085             }
1086         }
1087 
1088         Assert.assertEquals(r, expected);
1089     }
1090 
1091     @DataProvider
1092     public Object[][] gatherScatterProvider() {
1093         return INT_INDEX_GENERATORS.stream().
1094                 flatMap(fs -> BYTE_GENERATORS.stream().map(fa -> {
1095                     return new Object[] {fa, fs};
1096                 })).
1097                 toArray(Object[][]::new);
1098     }
1099 
1100     @DataProvider
1101     public Object[][] gatherScatterMaskProvider() {
1102         return BOOLEAN_MASK_GENERATORS.stream().
1103           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1104             BYTE_GENERATORS.stream().map(fa -> {
1105                     return new Object[] {fa, fm, fs};
1106             }))).
1107             toArray(Object[][]::new);
1108     }
1109 
1110 
1111     @Test(dataProvider = "gatherScatterProvider")
1112     static void gather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1113         byte[] a = fa.apply(SPECIES.length());
1114         int[] b = fs.apply(a.length, SPECIES.length());
1115         byte[] r = new byte[a.length];
1116 
1117         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1118             for (int i = 0; i < a.length; i += SPECIES.length()) {
1119                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i);
1120                 av.intoArray(r, i);
1121             }
1122         }
1123 
1124         assertGatherArraysEquals(r, a, b);
1125     }
1126 
1127     @Test(dataProvider = "gatherScatterMaskProvider")
1128     static void gatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1129         byte[] a = fa.apply(SPECIES.length());
1130         int[] b = fs.apply(a.length, SPECIES.length());
1131         byte[] r = new byte[a.length];
1132         boolean[] mask = fm.apply(SPECIES.length());
1133         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1134 
1135         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1136             for (int i = 0; i < a.length; i += SPECIES.length()) {
1137                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i, vmask);
1138                 av.intoArray(r, i);
1139             }
1140         }
1141 
1142         assertGatherArraysEquals(r, a, b, mask);
1143     }
1144 
1145     @Test(dataProvider = "gatherScatterProvider")
1146     static void scatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1147         byte[] a = fa.apply(SPECIES.length());
1148         int[] b = fs.apply(a.length, SPECIES.length());
1149         byte[] r = new byte[a.length];
1150 
1151         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1152             for (int i = 0; i < a.length; i += SPECIES.length()) {
1153                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1154                 av.intoArray(r, i, b, i);
1155             }
1156         }
1157 
1158         assertScatterArraysEquals(r, a, b);
1159     }
1160 
1161     @Test(dataProvider = "gatherScatterMaskProvider")
1162     static void scatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1163         byte[] a = fa.apply(SPECIES.length());
1164         int[] b = fs.apply(a.length, SPECIES.length());
1165         byte[] r = new byte[a.length];
1166         boolean[] mask = fm.apply(SPECIES.length());
1167         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1168 
1169         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1170             for (int i = 0; i < a.length; i += SPECIES.length()) {
1171                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1172                 av.intoArray(r, i, b, i, vmask);
1173             }
1174         }
1175 
1176         assertScatterArraysEquals(r, a, b, mask);
1177     }
1178 
1179 
1180     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1181         int i = 0;
1182         int j = 0;
1183         try {
1184             for (; i < a.length; i += SPECIES.length()) {
1185                 j = i;
1186                 for (; j < i + SPECIES.length(); j++) {
1187                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1188                 }
1189             }
1190         } catch (AssertionError e) {
1191             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1192         }
1193     }
1194 
1195     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1196         int i = 0;
1197         int j = 0;
1198         try {
1199             for (; i < a.length; i += SPECIES.length()) {
1200                 j = i;
1201                 for (; j < i + SPECIES.length(); j++) {
1202                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false);
1203                 }
1204             }
1205         } catch (AssertionError e) {
1206             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j);
1207         }
1208     }
1209 
1210     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1211         boolean[] expected = new boolean[r.length];
1212 
1213         // Store before checking, since the same location may be stored to more than once
1214         for (int i = 0; i < a.length; i += SPECIES.length()) {
1215             for (int j = i; j < i + SPECIES.length(); j++) {
1216                 if (mask[j % SPECIES.length()]) {
1217                     expected[i + indexMap[j]] = a[j];
1218                 }
1219             }
1220         }
1221 
1222         Assert.assertEquals(r, expected);
1223     }
1224 
1225     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1226         boolean[] expected = new boolean[r.length];
1227 
1228         // Store before checking, since the same location may be stored to more than once
1229         for (int i = 0; i < a.length; i += SPECIES.length()) {
1230             for (int j = i; j < i + SPECIES.length(); j++) {
1231                 expected[i + indexMap[j]] = a[j];
1232             }
1233         }
1234 
1235         Assert.assertEquals(r, expected);
1236     }
1237 
1238     @Test(dataProvider = "gatherScatterProvider")
1239     static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1240         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1241         int[] b = fs.apply(a.length, SPECIES.length());
1242         boolean[] r = new boolean[a.length];
1243 
1244         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1245             for (int i = 0; i < a.length; i += SPECIES.length()) {
1246                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i);
1247                 av.intoBooleanArray(r, i);
1248             }
1249         }
1250 
1251         assertGatherArraysEquals(r, a, b);
1252     }
1253 
1254     @Test(dataProvider = "gatherScatterMaskProvider")
1255     static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1256         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1257         int[] b = fs.apply(a.length, SPECIES.length());
1258         boolean[] r = new boolean[a.length];
1259         boolean[] mask = fm.apply(SPECIES.length());
1260         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1261 
1262         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1263             for (int i = 0; i < a.length; i += SPECIES.length()) {
1264                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i, vmask);
1265                 av.intoBooleanArray(r, i);
1266             }
1267         }
1268 
1269         assertGatherArraysEquals(r, a, b, mask);
1270     }
1271 
1272     @Test(dataProvider = "gatherScatterProvider")
1273     static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1274         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1275         int[] b = fs.apply(a.length, SPECIES.length());
1276         boolean[] r = new boolean[a.length];
1277 
1278         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1279             for (int i = 0; i < a.length; i += SPECIES.length()) {
1280                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1281                 av.intoBooleanArray(r, i, b, i);
1282             }
1283         }
1284 
1285         assertScatterArraysEquals(r, a, b);
1286     }
1287 
1288     @Test(dataProvider = "gatherScatterMaskProvider")
1289     static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1290         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1291         int[] b = fs.apply(a.length, SPECIES.length());
1292         boolean[] r = new boolean[a.length];
1293         boolean[] mask = fm.apply(SPECIES.length());
1294         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1295 
1296         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1297             for (int i = 0; i < a.length; i += SPECIES.length()) {
1298                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1299                 av.intoBooleanArray(r, i, b, i, vmask);
1300             }
1301         }
1302 
1303         assertScatterArraysEquals(r, a, b, mask);
1304     }
1305 
1306 }
--- EOF ---