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