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