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 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
  28  *      -XX:-TieredCompilation ShortMaxVectorLoadStoreTests
  29  *
  30  */
  31 
  32 // -- This file was mechanically generated: Do not edit! -- //
  33 
  34 import jdk.incubator.foreign.MemorySegment;
  35 import jdk.incubator.foreign.ResourceScope;
  36 import jdk.incubator.foreign.ValueLayout;
  37 import jdk.incubator.vector.ShortVector;
  38 import jdk.incubator.vector.VectorMask;
  39 import jdk.incubator.vector.VectorShape;
  40 import jdk.incubator.vector.VectorSpecies;
  41 import jdk.incubator.vector.VectorShuffle;
  42 import jdk.internal.vm.annotation.DontInline;
  43 import org.testng.Assert;
  44 import org.testng.annotations.DataProvider;
  45 import org.testng.annotations.Test;
  46 




  47 import java.nio.ByteOrder;

  48 import java.util.List;
  49 import java.util.function.*;
  50 
  51 @Test
  52 public class ShortMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest {
  53     static final VectorSpecies<Short> SPECIES =
  54                 ShortVector.SPECIES_MAX;
  55 
  56     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  57 
  58     static VectorShape getMaxBit() {
  59         return VectorShape.S_Max_BIT;
  60     }
  61 
  62     private static final int Max = 256;  // juts so we can do N/Max
  63 
  64     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max);
  65 
  66     static void assertArraysEquals(short[] r, short[] a, boolean[] mask) {
  67         int i = 0;
  68         try {
  69             for (; i < a.length; i++) {
  70                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0);
  71             }
  72         } catch (AssertionError e) {
  73             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0, "at index #" + i);
  74         }
  75     }
  76 











  77     static final List<IntFunction<short[]>> SHORT_GENERATORS = List.of(
  78             withToString("short[i * 5]", (int s) -> {
  79                 return fill(s * BUFFER_REPS,
  80                             i -> (short)(i * 5));
  81             }),
  82             withToString("short[i + 1]", (int s) -> {
  83                 return fill(s * BUFFER_REPS,
  84                             i -> (((short)(i + 1) == 0) ? 1 : (short)(i + 1)));
  85             })
  86     );
  87 
  88     // Relative to array.length
  89     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
  90             withToString("-1", (int l) -> {
  91                 return -1;
  92             }),
  93             withToString("l", (int l) -> {
  94                 return l;
  95             }),
  96             withToString("l - 1", (int l) -> {
  97                 return l - 1;
  98             }),
  99             withToString("l + 1", (int l) -> {
 100                 return l + 1;
 101             }),
 102             withToString("l - speciesl + 1", (int l) -> {
 103                 return l - SPECIES.length() + 1;
 104             }),
 105             withToString("l + speciesl - 1", (int l) -> {
 106                 return l + SPECIES.length() - 1;
 107             }),
 108             withToString("l + speciesl", (int l) -> {
 109                 return l + SPECIES.length();
 110             }),
 111             withToString("l + speciesl + 1", (int l) -> {
 112                 return l + SPECIES.length() + 1;
 113             })
 114     );
 115 
 116     // Relative to byte[] array.length or MemorySegment.byteSize()
 117     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 118             withToString("-1", (int l) -> {
 119                 return -1;
 120             }),
 121             withToString("l", (int l) -> {
 122                 return l;
 123             }),
 124             withToString("l - 1", (int l) -> {
 125                 return l - 1;
 126             }),
 127             withToString("l + 1", (int l) -> {
 128                 return l + 1;
 129             }),
 130             withToString("l - speciesl*ebsize + 1", (int l) -> {
 131                 return l - SPECIES.vectorByteSize() + 1;
 132             }),
 133             withToString("l + speciesl*ebsize - 1", (int l) -> {
 134                 return l + SPECIES.vectorByteSize() - 1;
 135             }),
 136             withToString("l + speciesl*ebsize", (int l) -> {
 137                 return l + SPECIES.vectorByteSize();
 138             }),
 139             withToString("l + speciesl*ebsize + 1", (int l) -> {
 140                 return l + SPECIES.vectorByteSize() + 1;
 141             })
 142     );
 143 
 144     @DataProvider
 145     public Object[][] shortProvider() {
 146         return SHORT_GENERATORS.stream().
 147                 map(f -> new Object[]{f}).
 148                 toArray(Object[][]::new);
 149     }
 150 
 151     @DataProvider
 152     public Object[][] maskProvider() {
 153         return BOOLEAN_MASK_GENERATORS.stream().
 154                 map(f -> new Object[]{f}).
 155                 toArray(Object[][]::new);
 156     }
 157 
 158     @DataProvider
 159     public Object[][] shortProviderForIOOBE() {
 160         var f = SHORT_GENERATORS.get(0);
 161         return INDEX_GENERATORS.stream().map(fi -> {
 162                     return new Object[] {f, fi};
 163                 }).
 164                 toArray(Object[][]::new);
 165     }
 166 
 167     @DataProvider
 168     public Object[][] shortMaskProvider() {
 169         return BOOLEAN_MASK_GENERATORS.stream().
 170                 flatMap(fm -> SHORT_GENERATORS.stream().map(fa -> {
 171                     return new Object[] {fa, fm};
 172                 })).
 173                 toArray(Object[][]::new);
 174     }
 175 
 176     @DataProvider
 177     public Object[][] shortMaskProviderForIOOBE() {
 178         var f = SHORT_GENERATORS.get(0);
 179         return BOOLEAN_MASK_GENERATORS.stream().
 180                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 181                     return new Object[] {f, fi, fm};
 182                 })).
 183                 toArray(Object[][]::new);
 184     }
 185 
 186     @DataProvider
 187     public Object[][] shortMemorySegmentProvider() {
 188         return SHORT_GENERATORS.stream().
 189                 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 190                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 191                             return new Object[]{fa, fb, bo};
 192                         }))).
 193                 toArray(Object[][]::new);
 194     }
 195 
 196     @DataProvider
 197     public Object[][] shortMemorySegmentMaskProvider() {
 198         return BOOLEAN_MASK_GENERATORS.stream().
 199                 flatMap(fm -> SHORT_GENERATORS.stream().
 200                         flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 201                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 202                             return new Object[]{fa, fb, fm, bo};
 203                         })))).
 204                 toArray(Object[][]::new);
 205     }
 206 



















 207     @DataProvider
 208     public Object[][] shortByteProviderForIOOBE() {
 209         var f = SHORT_GENERATORS.get(0);
 210         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 211                     return new Object[] {f, fi};
 212                 }).
 213                 toArray(Object[][]::new);
 214     }
 215 
 216     @DataProvider
 217     public Object[][] shortByteMaskProviderForIOOBE() {
 218         var f = SHORT_GENERATORS.get(0);
 219         return BOOLEAN_MASK_GENERATORS.stream().
 220                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 221                     return new Object[] {f, fi, fm};
 222                 })).
 223                 toArray(Object[][]::new);
 224     }
 225 
 226     static MemorySegment toSegment(short[] a, IntFunction<MemorySegment> fb) {
 227         MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
 228         for (int i = 0; i < a.length; i++) {
 229             ms.set(ValueLayout.JAVA_SHORT, i * SPECIES.elementSize() / 8 , a[i]);
 230         }
 231         return ms;
 232     }
 233 
 234     static short[] segmentToArray(MemorySegment ms) {
 235         return ms.toArray(ValueLayout.JAVA_SHORT);












 236     }
 237 
 238 
 239     interface ToShortF {
 240         short apply(int i);
 241     }
 242 
 243     static short[] fill(int s , ToShortF f) {
 244         return fill(new short[s], f);
 245     }
 246 
 247     static short[] fill(short[] a, ToShortF f) {
 248         for (int i = 0; i < a.length; i++) {
 249             a[i] = f.apply(i);
 250         }
 251         return a;
 252     }
 253 
 254     @DontInline
 255     static ShortVector fromArray(short[] a, int i) {
 256         return ShortVector.fromArray(SPECIES, a, i);
 257     }
 258 
 259     @DontInline
 260     static ShortVector fromArray(short[] a, int i, VectorMask<Short> m) {
 261         return ShortVector.fromArray(SPECIES, a, i, m);
 262     }
 263 
 264     @DontInline
 265     static void intoArray(ShortVector v, short[] a, int i) {
 266         v.intoArray(a, i);
 267     }
 268 
 269     @DontInline
 270     static void intoArray(ShortVector v, short[] a, int i, VectorMask<Short> m) {
 271         v.intoArray(a, i, m);
 272     }
 273 
 274     @DontInline
 275     static ShortVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
 276         return ShortVector.fromMemorySegment(SPECIES, a, i, bo);




















 277     }
 278 
 279     @DontInline
 280     static ShortVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Short> m) {
 281         return ShortVector.fromMemorySegment(SPECIES, a, i, bo, m);
 282     }
 283 
 284     @DontInline
 285     static void intoMemorySegment(ShortVector v, MemorySegment a, int i, ByteOrder bo) {
 286         v.intoMemorySegment(a, i, bo);
 287     }
 288 
 289     @DontInline
 290     static void intoMemorySegment(ShortVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Short> m) {
 291         v.intoMemorySegment(a, i, bo, m);
 292     }
 293 

 294     @Test(dataProvider = "shortProvider")
 295     static void loadStoreArray(IntFunction<short[]> fa) {
 296         short[] a = fa.apply(SPECIES.length());
 297         short[] r = new short[a.length];
 298 
 299         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 300             for (int i = 0; i < a.length; i += SPECIES.length()) {
 301                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
 302                 av.intoArray(r, i);
 303             }
 304         }
 305         Assert.assertEquals(r, a);
 306     }
 307 
 308     @Test(dataProvider = "shortProviderForIOOBE")
 309     static void loadArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) {
 310         short[] a = fa.apply(SPECIES.length());
 311         short[] r = new short[a.length];
 312 
 313         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 314             for (int i = 0; i < a.length; i += SPECIES.length()) {
 315                 ShortVector av = fromArray(a, i);
 316                 av.intoArray(r, i);
 317             }
 318         }
 319 
 320         int index = fi.apply(a.length);
 321         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 322         try {
 323             fromArray(a, index);
 324             if (shouldFail) {
 325                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 326             }
 327         } catch (IndexOutOfBoundsException e) {
 328             if (!shouldFail) {
 329                 Assert.fail("Unexpected IndexOutOfBoundsException");
 330             }
 331         }
 332     }
 333 
 334     @Test(dataProvider = "shortProviderForIOOBE")
 335     static void storeArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) {
 336         short[] a = fa.apply(SPECIES.length());
 337         short[] r = new short[a.length];
 338 
 339         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 340             for (int i = 0; i < a.length; i += SPECIES.length()) {
 341                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
 342                 intoArray(av, r, i);
 343             }
 344         }
 345 
 346         int index = fi.apply(a.length);
 347         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 348         try {
 349             ShortVector av = ShortVector.fromArray(SPECIES, a, 0);
 350             intoArray(av, r, index);
 351             if (shouldFail) {
 352                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 353             }
 354         } catch (IndexOutOfBoundsException e) {
 355             if (!shouldFail) {
 356                 Assert.fail("Unexpected IndexOutOfBoundsException");
 357             }
 358         }
 359     }
 360 
 361 
 362     @Test(dataProvider = "shortMaskProvider")
 363     static void loadStoreMaskArray(IntFunction<short[]> fa,
 364                                    IntFunction<boolean[]> fm) {
 365         short[] a = fa.apply(SPECIES.length());
 366         short[] r = new short[a.length];
 367         boolean[] mask = fm.apply(SPECIES.length());
 368         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 369 
 370         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 371             for (int i = 0; i < a.length; i += SPECIES.length()) {
 372                 ShortVector av = ShortVector.fromArray(SPECIES, a, i, vmask);
 373                 av.intoArray(r, i);
 374             }
 375         }
 376         assertArraysEquals(r, a, mask);
 377 
 378 
 379         r = new short[a.length];
 380 
 381         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 382             for (int i = 0; i < a.length; i += SPECIES.length()) {
 383                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
 384                 av.intoArray(r, i, vmask);
 385             }
 386         }
 387         assertArraysEquals(r, a, mask);
 388     }
 389 
 390     @Test(dataProvider = "shortMaskProviderForIOOBE")
 391     static void loadArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 392         short[] a = fa.apply(SPECIES.length());
 393         short[] r = new short[a.length];
 394         boolean[] mask = fm.apply(SPECIES.length());
 395         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 396 
 397         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 398             for (int i = 0; i < a.length; i += SPECIES.length()) {
 399                 ShortVector av = fromArray(a, i, vmask);
 400                 av.intoArray(r, i);
 401             }
 402         }
 403 
 404         int index = fi.apply(a.length);
 405         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 406         try {
 407             fromArray(a, index, vmask);
 408             if (shouldFail) {
 409                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 410             }
 411         } catch (IndexOutOfBoundsException e) {
 412             if (!shouldFail) {
 413                 Assert.fail("Unexpected IndexOutOfBoundsException");
 414             }
 415         }
 416     }
 417 
 418     @Test(dataProvider = "shortMaskProviderForIOOBE")
 419     static void storeArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 420         short[] a = fa.apply(SPECIES.length());
 421         short[] r = new short[a.length];
 422         boolean[] mask = fm.apply(SPECIES.length());
 423         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 424 
 425         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 426             for (int i = 0; i < a.length; i += SPECIES.length()) {
 427                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
 428                 intoArray(av, r, i, vmask);
 429             }
 430         }
 431 
 432         int index = fi.apply(a.length);
 433         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 434         try {
 435             ShortVector av = ShortVector.fromArray(SPECIES, a, 0);
 436             intoArray(av, a, index, vmask);
 437             if (shouldFail) {
 438                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 439             }
 440         } catch (IndexOutOfBoundsException e) {
 441             if (!shouldFail) {
 442                 Assert.fail("Unexpected IndexOutOfBoundsException");
 443             }
 444         }
 445     }
 446 
 447 
 448     @Test(dataProvider = "shortMaskProvider")
 449     static void loadStoreMask(IntFunction<short[]> fa,
 450                               IntFunction<boolean[]> fm) {
 451         boolean[] mask = fm.apply(SPECIES.length());
 452         boolean[] r = new boolean[mask.length];
 453 
 454         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 455             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 456                 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, i);
 457                 vmask.intoArray(r, i);
 458             }
 459         }
 460         Assert.assertEquals(r, mask);
 461     }
 462 
 463 
 464     @Test(dataProvider = "shortMemorySegmentProvider")
 465     static void loadStoreMemorySegment(IntFunction<short[]> fa,
 466                                        IntFunction<MemorySegment> fb,
 467                                        ByteOrder bo) {
 468         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb);
 469         MemorySegment r = fb.apply((int) a.byteSize());
 470 
 471         int l = (int) a.byteSize();
 472         int s = SPECIES.vectorByteSize();
 473 
 474         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 475             for (int i = 0; i < l; i += s) {
 476                 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo);
 477                 av.intoMemorySegment(r, i, bo);
 478             }
 479         }
 480         long m = r.mismatch(a);
 481         Assert.assertEquals(m, -1, "Segments not equal");



 482     }
 483 
 484     @Test(dataProvider = "shortByteProviderForIOOBE")
 485     static void loadMemorySegmentIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) {
 486         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
 487         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
 488 
 489         int l = (int) a.byteSize();
 490         int s = SPECIES.vectorByteSize();
 491 
 492         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 493             for (int i = 0; i < l; i += s) {
 494                 ShortVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder());
 495                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 496             }
 497         }
 498 
 499         int index = fi.apply((int) a.byteSize());
 500         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 501         try {
 502             fromMemorySegment(a, index, ByteOrder.nativeOrder());
 503             if (shouldFail) {
 504                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 505             }
 506         } catch (IndexOutOfBoundsException e) {
 507             if (!shouldFail) {
 508                 Assert.fail("Unexpected IndexOutOfBoundsException");
 509             }
 510         }
 511     }
 512 
 513     @Test(dataProvider = "shortByteProviderForIOOBE")
 514     static void storeMemorySegmentIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) {
 515         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
 516         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
 517 
 518         int l = (int) a.byteSize();
 519         int s = SPECIES.vectorByteSize();
 520 
 521         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 522             for (int i = 0; i < l; i += s) {
 523                 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 524                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder());
 525             }
 526         }
 527 
 528         int index = fi.apply((int) a.byteSize());
 529         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 530         try {
 531             ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 532             intoMemorySegment(av, r, index, ByteOrder.nativeOrder());
 533             if (shouldFail) {
 534                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 535             }
 536         } catch (IndexOutOfBoundsException e) {
 537             if (!shouldFail) {
 538                 Assert.fail("Unexpected IndexOutOfBoundsException");
 539             }
 540         }
 541     }
 542 
 543     @Test(dataProvider = "shortMemorySegmentMaskProvider")
 544     static void loadStoreMemorySegmentMask(IntFunction<short[]> fa,
 545                                            IntFunction<MemorySegment> fb,
 546                                            IntFunction<boolean[]> fm,
 547                                            ByteOrder bo) {

 548         short[] _a = fa.apply(SPECIES.length());
 549         MemorySegment a = toSegment(_a, fb);
 550         MemorySegment r = fb.apply((int) a.byteSize());
 551         boolean[] mask = fm.apply(SPECIES.length());
 552         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 553 
 554         int l = (int) a.byteSize();
 555         int s = SPECIES.vectorByteSize();
 556 
 557         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 558             for (int i = 0; i < l; i += s) {
 559                 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo, vmask);
 560                 av.intoMemorySegment(r, i, bo);
 561             }
 562         }
 563         assertArraysEquals(segmentToArray(r), _a, mask);




 564 
 565 
 566         r = fb.apply((int) a.byteSize());
 567 
 568         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 569             for (int i = 0; i < l; i += s) {
 570                 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo);
 571                 av.intoMemorySegment(r, i, bo, vmask);
 572             }
 573         }
 574         assertArraysEquals(segmentToArray(r), _a, mask);




 575     }
 576 
 577     @Test(dataProvider = "shortByteMaskProviderForIOOBE")
 578     static void loadMemorySegmentMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 579         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
 580         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
 581         boolean[] mask = fm.apply(SPECIES.length());
 582         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 583 
 584         int l = (int) a.byteSize();
 585         int s = SPECIES.vectorByteSize();
 586 
 587         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 588             for (int i = 0; i < l; i += s) {
 589                 ShortVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
 590                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 591             }
 592         }
 593 
 594         int index = fi.apply((int) a.byteSize());
 595         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 596         try {
 597             fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
 598             if (shouldFail) {
 599                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 600             }
 601         } catch (IndexOutOfBoundsException e) {
 602             if (!shouldFail) {
 603                 Assert.fail("Unexpected IndexOutOfBoundsException");
 604             }
 605         }
 606     }
 607 
 608     @Test(dataProvider = "shortByteMaskProviderForIOOBE")
 609     static void storeMemorySegmentMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 610         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
 611         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
 612         boolean[] mask = fm.apply(SPECIES.length());
 613         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 614 
 615         int l = (int) a.byteSize();


















































































 616         int s = SPECIES.vectorByteSize();

 617 
 618         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 619             for (int i = 0; i < l; i += s) {
 620                 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 621                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask);
 622             }
 623         }
 624 
 625         int index = fi.apply((int) a.byteSize());
 626         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 627         try {
 628             ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 629             intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask);
 630             if (shouldFail) {
 631                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 632             }
 633         } catch (IndexOutOfBoundsException e) {
 634             if (!shouldFail) {
 635                 Assert.fail("Unexpected IndexOutOfBoundsException");
 636             }
 637         }
 638     }
 639 
 640     @Test(dataProvider = "shortMemorySegmentProvider")
 641     static void loadStoreReadonlyMemorySegment(IntFunction<short[]> fa,
 642                                                IntFunction<MemorySegment> fb,
 643                                                ByteOrder bo) {
 644         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly();

























































 645 
 646         Assert.assertThrows(
 647                 UnsupportedOperationException.class,
 648                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
 649         );


 650 
 651         Assert.assertThrows(
 652                 UnsupportedOperationException.class,
 653                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
 654         );
 655 
 656         Assert.assertThrows(
 657                 UnsupportedOperationException.class,
 658                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
 659         );


 660 
 661         VectorMask<Short> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 662                 .laneIsValid();
 663         Assert.assertThrows(
 664                 UnsupportedOperationException.class,
 665                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
 666         );






 667     }
 668 































 669 
 670     @Test(dataProvider = "maskProvider")
 671     static void loadStoreMask(IntFunction<boolean[]> fm) {
 672         boolean[] a = fm.apply(SPECIES.length());
 673         boolean[] r = new boolean[a.length];
 674 
 675         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 676             for (int i = 0; i < a.length; i += SPECIES.length()) {
 677                 VectorMask<Short> vmask = SPECIES.loadMask(a, i);
 678                 vmask.intoArray(r, i);
 679             }
 680         }
 681         Assert.assertEquals(r, a);
 682     }
 683 
 684 
 685     @Test
 686     static void loadStoreShuffle() {
 687         IntUnaryOperator fn = a -> a + 5;
 688         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 689             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 690             int [] r = shuffle.toArray();
 691 
 692             int [] a = expectedShuffle(SPECIES.length(), fn);
 693             Assert.assertEquals(r, a);
 694        }
 695     }
 696 
 697 
 698     static void assertArraysEquals(char[] a, char[] r, boolean[] mask) {
 699         int i = 0;
 700         try {
 701             for (; i < a.length; i++) {
 702                 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]);
 703             }
 704         } catch (AssertionError e) {
 705             Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i);
 706         }
 707     }
 708 
 709     static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of(
 710             withToString("char[i * 5]", (int s) -> {
 711                 return fillChar(s * BUFFER_REPS,
 712                             i -> (char)(i * 5));
 713             }),
 714             withToString("char[i + 1]", (int s) -> {
 715                 return fillChar(s * BUFFER_REPS,
 716                             i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1)));
 717             })
 718     );
 719 
 720     @DataProvider
 721     public Object[][] charProvider() {
 722         return CHAR_GENERATORS.stream().
 723                 map(f -> new Object[]{f}).
 724                 toArray(Object[][]::new);
 725     }
 726 
 727     @DataProvider
 728     public Object[][] charProviderForIOOBE() {
 729         var f = CHAR_GENERATORS.get(0);
 730         return INDEX_GENERATORS.stream().map(fi -> {
 731                     return new Object[] {f, fi};
 732                 }).
 733                 toArray(Object[][]::new);
 734     }
 735 
 736     @DataProvider
 737     public Object[][] charMaskProvider() {
 738         return BOOLEAN_MASK_GENERATORS.stream().
 739                 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> {
 740                     return new Object[] {fa, fm};
 741                 })).
 742                 toArray(Object[][]::new);
 743     }
 744 
 745     @DataProvider
 746     public Object[][] charMaskProviderForIOOBE() {
 747         var f = CHAR_GENERATORS.get(0);
 748         return BOOLEAN_MASK_GENERATORS.stream().
 749                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 750                     return new Object[] {f, fi, fm};
 751                 })).
 752                 toArray(Object[][]::new);
 753     }
 754 
 755     interface ToCharF {
 756         char apply(int i);
 757     }
 758 
 759     static char[] fillChar(int s , ToCharF f) {
 760         return fillChar(new char[s], f);
 761     }
 762 
 763     static char[] fillChar(char[] a, ToCharF f) {
 764         for (int i = 0; i < a.length; i++) {
 765             a[i] = f.apply(i);
 766         }
 767         return a;
 768     }
 769 
 770     @DontInline
 771     static ShortVector fromCharArray(char[] a, int i) {
 772         return ShortVector.fromCharArray(SPECIES, a, i);
 773     }
 774 
 775     @DontInline
 776     static ShortVector fromCharArray(char[] a, int i, VectorMask<Short> m) {
 777         return ShortVector.fromCharArray(SPECIES, a, i, m);
 778     }
 779 
 780     @DontInline
 781     static void intoCharArray(ShortVector v, char[] a, int i) {
 782         v.intoCharArray(a, i);
 783     }
 784 
 785     @DontInline
 786     static void intoCharArray(ShortVector v, char[] a, int i, VectorMask<Short> m) {
 787         v.intoCharArray(a, i, m);
 788     }
 789 
 790     @Test(dataProvider = "charProvider")
 791     static void loadStoreCharArray(IntFunction<char[]> fa) {
 792         char[] a = fa.apply(SPECIES.length());
 793         char[] r = new char[a.length];
 794 
 795         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 796             for (int i = 0; i < a.length; i += SPECIES.length()) {
 797                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
 798                 av.intoCharArray(r, i);
 799             }
 800         }
 801         Assert.assertEquals(a, r);
 802     }
 803 
 804     @Test(dataProvider = "charProviderForIOOBE")
 805     static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
 806         char[] a = fa.apply(SPECIES.length());
 807         char[] r = new char[a.length];
 808 
 809         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 810             for (int i = 0; i < a.length; i += SPECIES.length()) {
 811                 ShortVector av = fromCharArray(a, i);
 812                 av.intoCharArray(r, i);
 813             }
 814         }
 815 
 816         int index = fi.apply(a.length);
 817         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 818         try {
 819             fromCharArray(a, index);
 820             if (shouldFail) {
 821                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 822             }
 823         } catch (IndexOutOfBoundsException e) {
 824             if (!shouldFail) {
 825                 Assert.fail("Unexpected IndexOutOfBoundsException");
 826             }
 827         }
 828     }
 829 
 830     @Test(dataProvider = "charProviderForIOOBE")
 831     static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
 832         char[] a = fa.apply(SPECIES.length());
 833         char[] r = new char[a.length];
 834 
 835         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 836             for (int i = 0; i < a.length; i += SPECIES.length()) {
 837                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
 838                 intoCharArray(av, r, i);
 839             }
 840         }
 841 
 842         int index = fi.apply(a.length);
 843         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 844         try {
 845             ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0);
 846             intoCharArray(av, r, index);
 847             if (shouldFail) {
 848                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 849             }
 850         } catch (IndexOutOfBoundsException e) {
 851             if (!shouldFail) {
 852                 Assert.fail("Unexpected IndexOutOfBoundsException");
 853             }
 854         }
 855     }
 856 
 857     @Test(dataProvider = "charMaskProvider")
 858     static void loadStoreMaskCharArray(IntFunction<char[]> fa,
 859                                        IntFunction<boolean[]> fm) {
 860         char[] a = fa.apply(SPECIES.length());
 861         char[] r = new char[a.length];
 862         boolean[] mask = fm.apply(SPECIES.length());
 863         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 864 
 865         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 866             for (int i = 0; i < a.length; i += SPECIES.length()) {
 867                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask);
 868                 av.intoCharArray(r, i);
 869             }
 870         }
 871         assertArraysEquals(a, r, mask);
 872 
 873 
 874         r = new char[a.length];
 875 
 876         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 877             for (int i = 0; i < a.length; i += SPECIES.length()) {
 878                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
 879                 av.intoCharArray(r, i, vmask);
 880             }
 881         }
 882         assertArraysEquals(a, r, mask);
 883     }
 884 
 885     @Test(dataProvider = "charMaskProviderForIOOBE")
 886     static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 887         char[] a = fa.apply(SPECIES.length());
 888         char[] r = new char[a.length];
 889         boolean[] mask = fm.apply(SPECIES.length());
 890         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 891 
 892         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 893             for (int i = 0; i < a.length; i += SPECIES.length()) {
 894                 ShortVector av = fromCharArray(a, i, vmask);
 895                 av.intoCharArray(r, i);
 896             }
 897         }
 898 
 899         int index = fi.apply(a.length);
 900         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 901         try {
 902             fromCharArray(a, index, vmask);
 903             if (shouldFail) {
 904                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 905             }
 906         } catch (IndexOutOfBoundsException e) {
 907             if (!shouldFail) {
 908                 Assert.fail("Unexpected IndexOutOfBoundsException");
 909             }
 910         }
 911     }
 912 
 913     @Test(dataProvider = "charMaskProviderForIOOBE")
 914     static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 915         char[] a = fa.apply(SPECIES.length());
 916         char[] r = new char[a.length];
 917         boolean[] mask = fm.apply(SPECIES.length());
 918         VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask);
 919 
 920         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 921             for (int i = 0; i < a.length; i += SPECIES.length()) {
 922                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
 923                 intoCharArray(av, r, i, vmask);
 924             }
 925         }
 926 
 927         int index = fi.apply(a.length);
 928         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 929         try {
 930             ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0);
 931             intoCharArray(av, a, index, vmask);
 932             if (shouldFail) {
 933                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 934             }
 935         } catch (IndexOutOfBoundsException e) {
 936             if (!shouldFail) {
 937                 Assert.fail("Unexpected IndexOutOfBoundsException");
 938             }
 939         }
 940     }
 941 
 942 
 943 
 944 
 945     // Gather/Scatter load/store tests
 946 
 947     static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap) {
 948         int i = 0;
 949         int j = 0;
 950         try {
 951             for (; i < a.length; i += SPECIES.length()) {
 952                 j = i;
 953                 for (; j < i + SPECIES.length(); j++) {
 954                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
 955                 }
 956             }
 957         } catch (AssertionError e) {
 958             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
 959         }
 960     }
 961 
 962     static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) {
 963         int i = 0;
 964         int j = 0;
 965         try {
 966             for (; i < a.length; i += SPECIES.length()) {
 967                 j = i;
 968                 for (; j < i + SPECIES.length(); j++) {
 969                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0);
 970                 }
 971             }
 972         } catch (AssertionError e) {
 973             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0, "at index #" + j);
 974         }
 975     }
 976 
 977     static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) {
 978         short[] expected = new short[r.length];
 979 
 980         // Store before checking, since the same location may be stored to more than once
 981         for (int i = 0; i < a.length; i += SPECIES.length()) {
 982             for (int j = i; j < i + SPECIES.length(); j++) {
 983                 if (mask[j % SPECIES.length()]) {
 984                     expected[i + indexMap[j]] = a[j];
 985                 }
 986             }
 987         }
 988 
 989         Assert.assertEquals(r, expected);
 990     }
 991 
 992     static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap) {
 993         short[] expected = new short[r.length];
 994 
 995         // Store before checking, since the same location may be stored to more than once
 996         for (int i = 0; i < a.length; i += SPECIES.length()) {
 997             for (int j = i; j < i + SPECIES.length(); j++) {
 998                 expected[i + indexMap[j]] = a[j];
 999             }
1000         }
1001 
1002         Assert.assertEquals(r, expected);
1003     }
1004 
1005     @DataProvider
1006     public Object[][] gatherScatterProvider() {
1007         return INT_INDEX_GENERATORS.stream().
1008                 flatMap(fs -> SHORT_GENERATORS.stream().map(fa -> {
1009                     return new Object[] {fa, fs};
1010                 })).
1011                 toArray(Object[][]::new);
1012     }
1013 
1014     @DataProvider
1015     public Object[][] gatherScatterMaskProvider() {
1016         return BOOLEAN_MASK_GENERATORS.stream().
1017           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1018             SHORT_GENERATORS.stream().map(fa -> {
1019                     return new Object[] {fa, fm, fs};
1020             }))).
1021             toArray(Object[][]::new);
1022     }
1023 
1024 
1025     @Test(dataProvider = "gatherScatterProvider")
1026     static void gather(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1027         short[] a = fa.apply(SPECIES.length());
1028         int[] b = fs.apply(a.length, SPECIES.length());
1029         short[] r = new short[a.length];
1030 
1031         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1032             for (int i = 0; i < a.length; i += SPECIES.length()) {
1033                 ShortVector av = ShortVector.fromArray(SPECIES, a, i, b, i);
1034                 av.intoArray(r, i);
1035             }
1036         }
1037 
1038         assertGatherArraysEquals(r, a, b);
1039     }
1040 
1041     @Test(dataProvider = "gatherScatterMaskProvider")
1042     static void gatherMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1043         short[] a = fa.apply(SPECIES.length());
1044         int[] b = fs.apply(a.length, SPECIES.length());
1045         short[] r = new short[a.length];
1046         boolean[] mask = fm.apply(SPECIES.length());
1047         VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1048 
1049         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1050             for (int i = 0; i < a.length; i += SPECIES.length()) {
1051                 ShortVector av = ShortVector.fromArray(SPECIES, a, i, b, i, vmask);
1052                 av.intoArray(r, i);
1053             }
1054         }
1055 
1056         assertGatherArraysEquals(r, a, b, mask);
1057     }
1058 
1059     @Test(dataProvider = "gatherScatterProvider")
1060     static void scatter(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1061         short[] a = fa.apply(SPECIES.length());
1062         int[] b = fs.apply(a.length, SPECIES.length());
1063         short[] r = new short[a.length];
1064 
1065         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1066             for (int i = 0; i < a.length; i += SPECIES.length()) {
1067                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
1068                 av.intoArray(r, i, b, i);
1069             }
1070         }
1071 
1072         assertScatterArraysEquals(r, a, b);
1073     }
1074 
1075     @Test(dataProvider = "gatherScatterMaskProvider")
1076     static void scatterMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1077         short[] a = fa.apply(SPECIES.length());
1078         int[] b = fs.apply(a.length, SPECIES.length());
1079         short[] r = new short[a.length];
1080         boolean[] mask = fm.apply(SPECIES.length());
1081         VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1082 
1083         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1084             for (int i = 0; i < a.length; i += SPECIES.length()) {
1085                 ShortVector av = ShortVector.fromArray(SPECIES, a, i);
1086                 av.intoArray(r, i, b, i, vmask);
1087             }
1088         }
1089 
1090         assertScatterArraysEquals(r, a, b, mask);
1091     }
1092 
1093     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) {
1094         int i = 0;
1095         int j = 0;
1096         try {
1097             for (; i < a.length; i += SPECIES.length()) {
1098                 j = i;
1099                 for (; j < i + SPECIES.length(); j++) {
1100                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1101                 }
1102             }
1103         } catch (AssertionError e) {
1104             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1105         }
1106     }
1107 
1108     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1109         int i = 0;
1110         int j = 0;
1111         try {
1112             for (; i < a.length; i += SPECIES.length()) {
1113                 j = i;
1114                 for (; j < i + SPECIES.length(); j++) {
1115                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0);
1116                 }
1117             }
1118         } catch (AssertionError e) {
1119             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j);
1120         }
1121     }
1122 
1123     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1124         char[] expected = new char[r.length];
1125 
1126         // Store before checking, since the same location may be stored to more than once
1127         for (int i = 0; i < a.length; i += SPECIES.length()) {
1128             for (int j = i; j < i + SPECIES.length(); j++) {
1129                 if (mask[j % SPECIES.length()]) {
1130                     expected[i + indexMap[j]] = a[j];
1131                 }
1132             }
1133         }
1134 
1135         Assert.assertEquals(r, expected);
1136     }
1137 
1138     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) {
1139         char[] expected = new char[r.length];
1140 
1141         // Store before checking, since the same location may be stored to more than once
1142         for (int i = 0; i < a.length; i += SPECIES.length()) {
1143             for (int j = i; j < i + SPECIES.length(); j++) {
1144                 expected[i + indexMap[j]] = a[j];
1145             }
1146         }
1147 
1148         Assert.assertEquals(r, expected);
1149     }
1150 
1151     @DataProvider
1152     public Object[][] charGatherScatterProvider() {
1153         return INT_INDEX_GENERATORS.stream().
1154                 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> {
1155                     return new Object[] {fa, fs};
1156                 })).
1157                 toArray(Object[][]::new);
1158     }
1159 
1160     @DataProvider
1161     public Object[][] charGatherScatterMaskProvider() {
1162         return BOOLEAN_MASK_GENERATORS.stream().
1163           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1164             CHAR_GENERATORS.stream().map(fa -> {
1165                     return new Object[] {fa, fm, fs};
1166             }))).
1167             toArray(Object[][]::new);
1168     }
1169 
1170 
1171     @Test(dataProvider = "charGatherScatterProvider")
1172     static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1173         char[] a = fa.apply(SPECIES.length());
1174         int[] b = fs.apply(a.length, SPECIES.length());
1175         char[] r = new char[a.length];
1176 
1177         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1178             for (int i = 0; i < a.length; i += SPECIES.length()) {
1179                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i);
1180                 av.intoCharArray(r, i);
1181             }
1182         }
1183 
1184         assertGatherArraysEquals(r, a, b);
1185     }
1186 
1187     @Test(dataProvider = "charGatherScatterMaskProvider")
1188     static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1189         char[] a = fa.apply(SPECIES.length());
1190         int[] b = fs.apply(a.length, SPECIES.length());
1191         char[] r = new char[a.length];
1192         boolean[] mask = fm.apply(SPECIES.length());
1193         VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1194 
1195         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1196             for (int i = 0; i < a.length; i += SPECIES.length()) {
1197                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i, vmask);
1198                 av.intoCharArray(r, i);
1199             }
1200         }
1201 
1202         assertGatherArraysEquals(r, a, b, mask);
1203     }
1204 
1205     @Test(dataProvider = "charGatherScatterProvider")
1206     static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1207         char[] a = fa.apply(SPECIES.length());
1208         int[] b = fs.apply(a.length, SPECIES.length());
1209         char[] r = new char[a.length];
1210 
1211         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1212             for (int i = 0; i < a.length; i += SPECIES.length()) {
1213                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
1214                 av.intoCharArray(r, i, b, i);
1215             }
1216         }
1217 
1218         assertScatterArraysEquals(r, a, b);
1219     }
1220 
1221     @Test(dataProvider = "charGatherScatterMaskProvider")
1222     static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1223         char[] a = fa.apply(SPECIES.length());
1224         int[] b = fs.apply(a.length, SPECIES.length());
1225         char[] r = new char[a.length];
1226         boolean[] mask = fm.apply(SPECIES.length());
1227         VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1228 
1229         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1230             for (int i = 0; i < a.length; i += SPECIES.length()) {
1231                 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i);
1232                 av.intoCharArray(r, i, b, i, vmask);
1233             }
1234         }
1235 
1236         assertScatterArraysEquals(r, a, b, mask);
1237     }
1238 
1239 
1240 }
--- EOF ---