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