1 /*
   2  * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation
  27 #if[MaxBit]
  28  * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
  29  *      -XX:-TieredCompilation $vectorteststype$
  30 #else[MaxBit]
  31  * @run testng/othervm -XX:-TieredCompilation $vectorteststype$
  32 #end[MaxBit]
  33  *
  34  */
  35 
  36 #warn This file is preprocessed before being compiled
  37 
  38 import jdk.incubator.vector.$Type$Vector;
  39 import jdk.incubator.vector.VectorMask;
  40 #if[MaxBit]
  41 import jdk.incubator.vector.VectorShape;
  42 #end[MaxBit]
  43 import jdk.incubator.vector.VectorSpecies;
  44 import jdk.incubator.vector.VectorShuffle;
  45 import jdk.internal.vm.annotation.DontInline;
  46 import org.testng.Assert;
  47 import org.testng.annotations.DataProvider;
  48 import org.testng.annotations.Test;
  49 
  50 #if[MaxBit]
  51 import java.lang.invoke.MethodHandles;
  52 import java.lang.invoke.VarHandle;
  53 #end[MaxBit]
  54 import java.nio.ByteBuffer;
  55 #if[!byte]
  56 import java.nio.$Type$Buffer;
  57 #end[!byte]
  58 import java.nio.ByteOrder;
  59 import java.nio.ReadOnlyBufferException;
  60 import java.util.List;
  61 import java.util.function.*;
  62 
  63 @Test
  64 public class $vectorteststype$ extends AbstractVectorLoadStoreTest {
  65 #if[MaxBit]
  66     static final VectorSpecies<$Wideboxtype$> SPECIES =
  67                 $Type$Vector.SPECIES_MAX;
  68 #else[MaxBit]
  69     static final VectorSpecies<$Wideboxtype$> SPECIES =
  70                 $Type$Vector.SPECIES_$bits$;
  71 #end[MaxBit]
  72 
  73     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  74 
  75 #if[MaxBit]
  76     static VectorShape getMaxBit() {
  77         return VectorShape.S_Max_BIT;
  78     }
  79 
  80     private static final int Max = 256;  // juts so we can do N/$bits$
  81 #end[MaxBit]
  82 
  83     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$);
  84 
  85     static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask) {
  86         int i = 0;
  87         try {
  88             for (; i < a.length; i++) {
  89                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0);
  90             }
  91         } catch (AssertionError e) {
  92             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0, "at index #" + i);
  93         }
  94     }
  95 
  96 #if[!byte]
  97     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
  98         int i = 0;
  99         try {
 100             for (; i < a.length; i++) {
 101                 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0);
 102             }
 103         } catch (AssertionError e) {
 104             Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
 105         }
 106     }
 107 #end[!byte]
 108 
 109     static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
 110             withToString("$type$[i * 5]", (int s) -> {
 111                 return fill(s * BUFFER_REPS,
 112                             i -> ($type$)(i * 5));
 113             }),
 114             withToString("$type$[i + 1]", (int s) -> {
 115                 return fill(s * BUFFER_REPS,
 116                             i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
 117             })
 118     );
 119 
 120     // Relative to array.length
 121     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
 122             withToString("-1", (int l) -> {
 123                 return -1;
 124             }),
 125             withToString("l", (int l) -> {
 126                 return l;
 127             }),
 128             withToString("l - 1", (int l) -> {
 129                 return l - 1;
 130             }),
 131             withToString("l + 1", (int l) -> {
 132                 return l + 1;
 133             }),
 134             withToString("l - speciesl + 1", (int l) -> {
 135                 return l - SPECIES.length() + 1;
 136             }),
 137             withToString("l + speciesl - 1", (int l) -> {
 138                 return l + SPECIES.length() - 1;
 139             }),
 140             withToString("l + speciesl", (int l) -> {
 141                 return l + SPECIES.length();
 142             }),
 143             withToString("l + speciesl + 1", (int l) -> {
 144                 return l + SPECIES.length() + 1;
 145             })
 146     );
 147 
 148     // Relative to byte[] array.length or ByteBuffer.limit()
 149     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 150             withToString("-1", (int l) -> {
 151                 return -1;
 152             }),
 153             withToString("l", (int l) -> {
 154                 return l;
 155             }),
 156             withToString("l - 1", (int l) -> {
 157                 return l - 1;
 158             }),
 159             withToString("l + 1", (int l) -> {
 160                 return l + 1;
 161             }),
 162             withToString("l - speciesl*ebsize + 1", (int l) -> {
 163                 return l - SPECIES.vectorByteSize() + 1;
 164             }),
 165             withToString("l + speciesl*ebsize - 1", (int l) -> {
 166                 return l + SPECIES.vectorByteSize() - 1;
 167             }),
 168             withToString("l + speciesl*ebsize", (int l) -> {
 169                 return l + SPECIES.vectorByteSize();
 170             }),
 171             withToString("l + speciesl*ebsize + 1", (int l) -> {
 172                 return l + SPECIES.vectorByteSize() + 1;
 173             })
 174     );
 175 
 176     @DataProvider
 177     public Object[][] $type$Provider() {
 178         return $TYPE$_GENERATORS.stream().
 179                 map(f -> new Object[]{f}).
 180                 toArray(Object[][]::new);
 181     }
 182 
 183     @DataProvider
 184     public Object[][] maskProvider() {
 185         return BOOLEAN_MASK_GENERATORS.stream().
 186                 map(f -> new Object[]{f}).
 187                 toArray(Object[][]::new);
 188     }
 189 
 190     @DataProvider
 191     public Object[][] $type$ProviderForIOOBE() {
 192         var f = $TYPE$_GENERATORS.get(0);
 193         return INDEX_GENERATORS.stream().map(fi -> {
 194                     return new Object[] {f, fi};
 195                 }).
 196                 toArray(Object[][]::new);
 197     }
 198 
 199     @DataProvider
 200     public Object[][] $type$MaskProvider() {
 201         return BOOLEAN_MASK_GENERATORS.stream().
 202                 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
 203                     return new Object[] {fa, fm};
 204                 })).
 205                 toArray(Object[][]::new);
 206     }
 207 
 208     @DataProvider
 209     public Object[][] $type$MaskProviderForIOOBE() {
 210         var f = $TYPE$_GENERATORS.get(0);
 211         return BOOLEAN_MASK_GENERATORS.stream().
 212                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 213                     return new Object[] {f, fi, fm};
 214                 })).
 215                 toArray(Object[][]::new);
 216     }
 217 
 218     @DataProvider
 219     public Object[][] $type$ByteBufferProvider() {
 220         return $TYPE$_GENERATORS.stream().
 221                 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 222                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 223                             return new Object[]{fa, fb, bo};
 224                         }))).
 225                 toArray(Object[][]::new);
 226     }
 227 
 228     @DataProvider
 229     public Object[][] $type$ByteBufferMaskProvider() {
 230         return BOOLEAN_MASK_GENERATORS.stream().
 231                 flatMap(fm -> $TYPE$_GENERATORS.stream().
 232                         flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 233                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 234                             return new Object[]{fa, fb, fm, bo};
 235                         })))).
 236                 toArray(Object[][]::new);
 237     }
 238 
 239     @DataProvider
 240     public Object[][] $type$ByteArrayProvider() {
 241         return $TYPE$_GENERATORS.stream().
 242                 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 243                     return new Object[]{fa, bo};
 244                 })).
 245                 toArray(Object[][]::new);
 246     }
 247 
 248     @DataProvider
 249     public Object[][] $type$ByteArrayMaskProvider() {
 250         return BOOLEAN_MASK_GENERATORS.stream().
 251                 flatMap(fm -> $TYPE$_GENERATORS.stream().
 252                     flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 253                         return new Object[]{fa, fm, bo};
 254                     }))).
 255                 toArray(Object[][]::new);
 256     }
 257 
 258     @DataProvider
 259     public Object[][] $type$ByteProviderForIOOBE() {
 260         var f = $TYPE$_GENERATORS.get(0);
 261         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 262                     return new Object[] {f, fi};
 263                 }).
 264                 toArray(Object[][]::new);
 265     }
 266 
 267     @DataProvider
 268     public Object[][] $type$ByteMaskProviderForIOOBE() {
 269         var f = $TYPE$_GENERATORS.get(0);
 270         return BOOLEAN_MASK_GENERATORS.stream().
 271                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 272                     return new Object[] {f, fi, fm};
 273                 })).
 274                 toArray(Object[][]::new);
 275     }
 276 
 277     static ByteBuffer toBuffer($type$[] a, IntFunction<ByteBuffer> fb) {
 278         ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
 279         for ($type$ v : a) {
 280             bb.{#if[byte]?put(v):put$Type$(v)};
 281         }
 282         return bb.clear();
 283     }
 284 
 285     static $type$[] bufferToArray(ByteBuffer bb) {
 286         $Type$Buffer db = bb{#if[byte]?;:.as$Type$Buffer();}
 287         $type$[] d = new $type$[db.capacity()];
 288         db.get(0, d);
 289         return d;
 290     }
 291 
 292     static byte[] toByteArray($type$[] a, IntFunction<byte[]> fb, ByteOrder bo) {
 293         byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
 294 #if[byte]
 295         $Type$Buffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo);
 296 #else[byte]
 297         $Type$Buffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).as$Type$Buffer();
 298 #end[byte]
 299         for ($type$ v : a) {
 300             bb.put(v);
 301         }
 302         return b;
 303     }
 304 
 305 
 306     interface To$Type$F {
 307         $type$ apply(int i);
 308     }
 309 
 310     static $type$[] fill(int s , To$Type$F f) {
 311         return fill(new $type$[s], f);
 312     }
 313 
 314     static $type$[] fill($type$[] a, To$Type$F f) {
 315         for (int i = 0; i < a.length; i++) {
 316             a[i] = f.apply(i);
 317         }
 318         return a;
 319     }
 320 
 321     @DontInline
 322     static $abstractvectortype$ fromArray($type$[] a, int i) {
 323         return $abstractvectortype$.fromArray(SPECIES, a, i);
 324     }
 325 
 326     @DontInline
 327     static $abstractvectortype$ fromArray($type$[] a, int i, VectorMask<$Boxtype$> m) {
 328         return $abstractvectortype$.fromArray(SPECIES, a, i, m);
 329     }
 330 
 331     @DontInline
 332     static void intoArray($abstractvectortype$ v, $type$[] a, int i) {
 333         v.intoArray(a, i);
 334     }
 335 
 336     @DontInline
 337     static void intoArray($abstractvectortype$ v, $type$[] a, int i, VectorMask<$Boxtype$> m) {
 338         v.intoArray(a, i, m);
 339     }
 340 
 341     @DontInline
 342     static $abstractvectortype$ fromByteArray(byte[] a, int i, ByteOrder bo) {
 343         return $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
 344     }
 345 
 346     @DontInline
 347     static $abstractvectortype$ fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 348         return $abstractvectortype$.fromByteArray(SPECIES, a, i, bo, m);
 349     }
 350 
 351     @DontInline
 352     static void intoByteArray($abstractvectortype$ v, byte[] a, int i, ByteOrder bo) {
 353         v.intoByteArray(a, i, bo);
 354     }
 355 
 356     @DontInline
 357     static void intoByteArray($abstractvectortype$ v, byte[] a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 358         v.intoByteArray(a, i, bo, m);
 359     }
 360 
 361     @DontInline
 362     static $abstractvectortype$ fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
 363         return $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
 364     }
 365 
 366     @DontInline
 367     static $abstractvectortype$ fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 368         return $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo, m);
 369     }
 370 
 371     @DontInline
 372     static void intoByteBuffer($abstractvectortype$ v, ByteBuffer a, int i, ByteOrder bo) {
 373         v.intoByteBuffer(a, i, bo);
 374     }
 375 
 376     @DontInline
 377     static void intoByteBuffer($abstractvectortype$ v, ByteBuffer a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 378         v.intoByteBuffer(a, i, bo, m);
 379     }
 380 
 381 
 382     @Test(dataProvider = "$type$Provider")
 383     static void loadStoreArray(IntFunction<$type$[]> fa) {
 384         $type$[] a = fa.apply(SPECIES.length());
 385         $type$[] r = new $type$[a.length];
 386 
 387         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 388             for (int i = 0; i < a.length; i += SPECIES.length()) {
 389                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 390                 av.intoArray(r, i);
 391             }
 392         }
 393         Assert.assertEquals(r, a);
 394     }
 395 
 396     @Test(dataProvider = "$type$ProviderForIOOBE")
 397     static void loadArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 398         $type$[] a = fa.apply(SPECIES.length());
 399         $type$[] r = new $type$[a.length];
 400 
 401         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 402             for (int i = 0; i < a.length; i += SPECIES.length()) {
 403                 $abstractvectortype$ av = fromArray(a, i);
 404                 av.intoArray(r, i);
 405             }
 406         }
 407 
 408         int index = fi.apply(a.length);
 409         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 410         try {
 411             fromArray(a, index);
 412             if (shouldFail) {
 413                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 414             }
 415         } catch (IndexOutOfBoundsException e) {
 416             if (!shouldFail) {
 417                 Assert.fail("Unexpected IndexOutOfBoundsException");
 418             }
 419         }
 420     }
 421 
 422     @Test(dataProvider = "$type$ProviderForIOOBE")
 423     static void storeArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 424         $type$[] a = fa.apply(SPECIES.length());
 425         $type$[] r = new $type$[a.length];
 426 
 427         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 428             for (int i = 0; i < a.length; i += SPECIES.length()) {
 429                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 430                 intoArray(av, r, i);
 431             }
 432         }
 433 
 434         int index = fi.apply(a.length);
 435         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 436         try {
 437             $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0);
 438             intoArray(av, r, index);
 439             if (shouldFail) {
 440                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 441             }
 442         } catch (IndexOutOfBoundsException e) {
 443             if (!shouldFail) {
 444                 Assert.fail("Unexpected IndexOutOfBoundsException");
 445             }
 446         }
 447     }
 448 
 449 
 450     @Test(dataProvider = "$type$MaskProvider")
 451     static void loadStoreMaskArray(IntFunction<$type$[]> fa,
 452                                    IntFunction<boolean[]> fm) {
 453         $type$[] a = fa.apply(SPECIES.length());
 454         $type$[] r = new $type$[a.length];
 455         boolean[] mask = fm.apply(SPECIES.length());
 456         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 457 
 458         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 459             for (int i = 0; i < a.length; i += SPECIES.length()) {
 460                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, vmask);
 461                 av.intoArray(r, i);
 462             }
 463         }
 464         assertArraysEquals(r, a, mask);
 465 
 466 
 467         r = new $type$[a.length];
 468 
 469         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 470             for (int i = 0; i < a.length; i += SPECIES.length()) {
 471                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 472                 av.intoArray(r, i, vmask);
 473             }
 474         }
 475         assertArraysEquals(r, a, mask);
 476     }
 477 
 478     @Test(dataProvider = "$type$MaskProviderForIOOBE")
 479     static void loadArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 480         $type$[] a = fa.apply(SPECIES.length());
 481         $type$[] r = new $type$[a.length];
 482         boolean[] mask = fm.apply(SPECIES.length());
 483         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 484 
 485         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 486             for (int i = 0; i < a.length; i += SPECIES.length()) {
 487                 $abstractvectortype$ av = fromArray(a, i, vmask);
 488                 av.intoArray(r, i);
 489             }
 490         }
 491 
 492         int index = fi.apply(a.length);
 493         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 494         try {
 495             fromArray(a, index, vmask);
 496             if (shouldFail) {
 497                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 498             }
 499         } catch (IndexOutOfBoundsException e) {
 500             if (!shouldFail) {
 501                 Assert.fail("Unexpected IndexOutOfBoundsException");
 502             }
 503         }
 504     }
 505 
 506     @Test(dataProvider = "$type$MaskProviderForIOOBE")
 507     static void storeArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 508         $type$[] a = fa.apply(SPECIES.length());
 509         $type$[] r = new $type$[a.length];
 510         boolean[] mask = fm.apply(SPECIES.length());
 511         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 512 
 513         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 514             for (int i = 0; i < a.length; i += SPECIES.length()) {
 515                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 516                 intoArray(av, r, i, vmask);
 517             }
 518         }
 519 
 520         int index = fi.apply(a.length);
 521         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 522         try {
 523             $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0);
 524             intoArray(av, a, index, vmask);
 525             if (shouldFail) {
 526                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 527             }
 528         } catch (IndexOutOfBoundsException e) {
 529             if (!shouldFail) {
 530                 Assert.fail("Unexpected IndexOutOfBoundsException");
 531             }
 532         }
 533     }
 534 
 535 
 536     @Test(dataProvider = "$type$MaskProvider")
 537     static void loadStoreMask(IntFunction<$type$[]> fa,
 538                               IntFunction<boolean[]> fm) {
 539         boolean[] mask = fm.apply(SPECIES.length());
 540         boolean[] r = new boolean[mask.length];
 541 
 542         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 543             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 544                 VectorMask<$Boxtype$> vmask = VectorMask.fromArray(SPECIES, mask, i);
 545                 vmask.intoArray(r, i);
 546             }
 547         }
 548         Assert.assertEquals(r, mask);
 549     }
 550 
 551 
 552     @Test(dataProvider = "$type$ByteBufferProvider")
 553     static void loadStoreByteBuffer(IntFunction<$type$[]> fa,
 554                                     IntFunction<ByteBuffer> fb,
 555                                     ByteOrder bo) {
 556         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
 557         ByteBuffer r = fb.apply(a.limit());
 558 
 559         int l = a.limit();
 560         int s = SPECIES.vectorByteSize();
 561 
 562         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 563             for (int i = 0; i < l; i += s) {
 564                 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
 565                 av.intoByteBuffer(r, i, bo);
 566             }
 567         }
 568         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 569         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 570         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 571         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 572         Assert.assertEquals(r, a, "Buffers not equal");
 573     }
 574 
 575     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 576     static void loadByteBufferIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 577         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 578         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 579 
 580         int l = a.limit();
 581         int s = SPECIES.vectorByteSize();
 582 
 583         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 584             for (int i = 0; i < l; i += s) {
 585                 $abstractvectortype$ av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
 586                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 587             }
 588         }
 589 
 590         int index = fi.apply(a.limit());
 591         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 592         try {
 593             fromByteBuffer(a, index, ByteOrder.nativeOrder());
 594             if (shouldFail) {
 595                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 596             }
 597         } catch (IndexOutOfBoundsException e) {
 598             if (!shouldFail) {
 599                 Assert.fail("Unexpected IndexOutOfBoundsException");
 600             }
 601         }
 602     }
 603 
 604     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 605     static void storeByteBufferIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 606         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 607         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 608 
 609         int l = a.limit();
 610         int s = SPECIES.vectorByteSize();
 611 
 612         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 613             for (int i = 0; i < l; i += s) {
 614                 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 615                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
 616             }
 617         }
 618 
 619         int index = fi.apply(a.limit());
 620         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 621         try {
 622             $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 623             intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
 624             if (shouldFail) {
 625                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 626             }
 627         } catch (IndexOutOfBoundsException e) {
 628             if (!shouldFail) {
 629                 Assert.fail("Unexpected IndexOutOfBoundsException");
 630             }
 631         }
 632     }
 633 
 634 
 635     @Test(dataProvider = "$type$ByteBufferMaskProvider")
 636     static void loadStoreByteBufferMask(IntFunction<$type$[]> fa,
 637                                         IntFunction<ByteBuffer> fb,
 638                                         IntFunction<boolean[]> fm,
 639                                         ByteOrder bo) {
 640         $type$[] _a = fa.apply(SPECIES.length());
 641         ByteBuffer a = toBuffer(_a, fb);
 642         ByteBuffer r = fb.apply(a.limit());
 643         boolean[] mask = fm.apply(SPECIES.length());
 644         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 645 
 646         int l = a.limit();
 647         int s = SPECIES.vectorByteSize();
 648 
 649         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 650             for (int i = 0; i < l; i += s) {
 651                 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo, vmask);
 652                 av.intoByteBuffer(r, i, bo);
 653             }
 654         }
 655         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 656         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 657         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 658         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 659         assertArraysEquals(bufferToArray(r), _a, mask);
 660 
 661 
 662         r = fb.apply(a.limit());
 663 
 664         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 665             for (int i = 0; i < l; i += s) {
 666                 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
 667                 av.intoByteBuffer(r, i, bo, vmask);
 668             }
 669         }
 670         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 671         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 672         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 673         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 674         assertArraysEquals(bufferToArray(r), _a, mask);
 675     }
 676 
 677     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 678     static void loadByteBufferMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 679         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 680         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 681         boolean[] mask = fm.apply(SPECIES.length());
 682         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 683 
 684         int l = a.limit();
 685         int s = SPECIES.vectorByteSize();
 686 
 687         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 688             for (int i = 0; i < l; i += s) {
 689                 $abstractvectortype$ av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
 690                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 691             }
 692         }
 693 
 694         int index = fi.apply(a.limit());
 695         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 696         try {
 697             fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
 698             if (shouldFail) {
 699                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 700             }
 701         } catch (IndexOutOfBoundsException e) {
 702             if (!shouldFail) {
 703                 Assert.fail("Unexpected IndexOutOfBoundsException");
 704             }
 705         }
 706     }
 707 
 708     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 709     static void storeByteBufferMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 710         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 711         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 712         boolean[] mask = fm.apply(SPECIES.length());
 713         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 714 
 715         int l = a.limit();
 716         int s = SPECIES.vectorByteSize();
 717 
 718         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 719             for (int i = 0; i < l; i += s) {
 720                 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 721                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
 722             }
 723         }
 724 
 725         int index = fi.apply(a.limit());
 726         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 727         try {
 728             $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 729             intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
 730             if (shouldFail) {
 731                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 732             }
 733         } catch (IndexOutOfBoundsException e) {
 734             if (!shouldFail) {
 735                 Assert.fail("Unexpected IndexOutOfBoundsException");
 736             }
 737         }
 738     }
 739 
 740 
 741     @Test(dataProvider = "$type$ByteBufferProvider")
 742     static void loadStoreReadonlyByteBuffer(IntFunction<$type$[]> fa,
 743                                     IntFunction<ByteBuffer> fb,
 744                                     ByteOrder bo) {
 745         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
 746 
 747         try {
 748             SPECIES.zero().intoByteBuffer(a, 0, bo);
 749             Assert.fail("ReadOnlyBufferException expected");
 750         } catch (ReadOnlyBufferException e) {
 751         }
 752 
 753         try {
 754             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
 755             Assert.fail("ReadOnlyBufferException expected");
 756         } catch (ReadOnlyBufferException e) {
 757         }
 758 
 759         try {
 760             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
 761             Assert.fail("ReadOnlyBufferException expected");
 762         } catch (ReadOnlyBufferException e) {
 763         }
 764 
 765         try {
 766             VectorMask<$Boxtype$> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 767                     .laneIsValid();
 768             SPECIES.zero().intoByteBuffer(a, 0, bo, m);
 769             Assert.fail("ReadOnlyBufferException expected");
 770         } catch (ReadOnlyBufferException e) {
 771         }
 772     }
 773 
 774 
 775     @Test(dataProvider = "$type$ByteArrayProvider")
 776     static void loadStoreByteArray(IntFunction<$type$[]> fa,
 777                                     ByteOrder bo) {
 778         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 779         byte[] r = new byte[a.length];
 780 
 781         int s = SPECIES.vectorByteSize();
 782         int l = a.length;
 783 
 784         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 785             for (int i = 0; i < l; i += s) {
 786                 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
 787                 av.intoByteArray(r, i, bo);
 788             }
 789         }
 790         Assert.assertEquals(r, a, "Byte arrays not equal");
 791     }
 792 
 793     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 794     static void loadByteArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 795         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 796         byte[] r = new byte[a.length];
 797 
 798         int s = SPECIES.vectorByteSize();
 799         int l = a.length;
 800 
 801         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 802             for (int i = 0; i < l; i += s) {
 803                 $abstractvectortype$ av = fromByteArray(a, i, ByteOrder.nativeOrder());
 804                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 805             }
 806         }
 807 
 808         int index = fi.apply(a.length);
 809         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 810         try {
 811             fromByteArray(a, index, ByteOrder.nativeOrder());
 812             if (shouldFail) {
 813                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 814             }
 815         } catch (IndexOutOfBoundsException e) {
 816             if (!shouldFail) {
 817                 Assert.fail("Unexpected IndexOutOfBoundsException");
 818             }
 819         }
 820     }
 821 
 822     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 823     static void storeByteArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 824         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 825         byte[] r = new byte[a.length];
 826 
 827         int s = SPECIES.vectorByteSize();
 828         int l = a.length;
 829 
 830         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 831             for (int i = 0; i < l; i += s) {
 832                 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 833                 intoByteArray(av, r, i, ByteOrder.nativeOrder());
 834             }
 835         }
 836 
 837         int index = fi.apply(a.length);
 838         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 839         try {
 840             $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 841             intoByteArray(av, r, index, ByteOrder.nativeOrder());
 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 
 853     @Test(dataProvider = "$type$ByteArrayMaskProvider")
 854     static void loadStoreByteArrayMask(IntFunction<$type$[]> fa,
 855                                   IntFunction<boolean[]> fm,
 856                                   ByteOrder bo) {
 857         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 858         byte[] r = new byte[a.length];
 859         boolean[] mask = fm.apply(SPECIES.length());
 860         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 861 
 862         int s = SPECIES.vectorByteSize();
 863         int l = a.length;
 864 
 865         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 866           for (int i = 0; i < l; i += s) {
 867               $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo, vmask);
 868               av.intoByteArray(r, i, bo);
 869           }
 870         }
 871         assertArraysEquals(r, a, mask);
 872 
 873 
 874         r = new byte[a.length];
 875 
 876         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 877             for (int i = 0; i < l; i += s) {
 878                 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
 879                 av.intoByteArray(r, i, bo, vmask);
 880             }
 881         }
 882         assertArraysEquals(r, a, mask);
 883     }
 884 
 885     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 886     static void loadByteArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 887         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 888         byte[] r = new byte[a.length];
 889         boolean[] mask = fm.apply(SPECIES.length());
 890         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 891 
 892         int s = SPECIES.vectorByteSize();
 893         int l = a.length;
 894 
 895         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 896             for (int i = 0; i < l; i += s) {
 897                 $abstractvectortype$ av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
 898                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 899             }
 900         }
 901 
 902         int index = fi.apply(a.length);
 903         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 904         try {
 905             fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
 906             if (shouldFail) {
 907                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 908             }
 909         } catch (IndexOutOfBoundsException e) {
 910             if (!shouldFail) {
 911                 Assert.fail("Unexpected IndexOutOfBoundsException");
 912             }
 913         }
 914     }
 915 
 916     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 917     static void storeByteArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 918         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 919         byte[] r = new byte[a.length];
 920         boolean[] mask = fm.apply(SPECIES.length());
 921         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 922 
 923         int s = SPECIES.vectorByteSize();
 924         int l = a.length;
 925 
 926         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 927             for (int i = 0; i < l; i += s) {
 928                 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 929                 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
 930             }
 931         }
 932 
 933         int index = fi.apply(a.length);
 934         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 935         try {
 936             $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 937             intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
 938             if (shouldFail) {
 939                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 940             }
 941         } catch (IndexOutOfBoundsException e) {
 942             if (!shouldFail) {
 943                 Assert.fail("Unexpected IndexOutOfBoundsException");
 944             }
 945         }
 946     }
 947 
 948     @Test(dataProvider = "maskProvider")
 949     static void loadStoreMask(IntFunction<boolean[]> fm) {
 950         boolean[] a = fm.apply(SPECIES.length());
 951         boolean[] r = new boolean[a.length];
 952 
 953         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 954             for (int i = 0; i < a.length; i += SPECIES.length()) {
 955                 VectorMask<$Boxtype$> vmask = SPECIES.loadMask(a, i);
 956                 vmask.intoArray(r, i);
 957             }
 958         }
 959         Assert.assertEquals(r, a);
 960     }
 961 
 962     @Test
 963     static void loadStoreShuffle() {
 964         IntUnaryOperator fn = a -> a + 5;
 965         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 966             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 967             int [] r = shuffle.toArray();
 968 
 969             int [] a = expectedShuffle(SPECIES.length(), fn);
 970             Assert.assertEquals(r, a);
 971        }
 972     }
 973 
 974 
 975 #if[short]
 976     static void assertArraysEquals(char[] a, char[] r, boolean[] mask) {
 977         int i = 0;
 978         try {
 979             for (; i < a.length; i++) {
 980                 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]);
 981             }
 982         } catch (AssertionError e) {
 983             Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i);
 984         }
 985     }
 986 
 987     static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of(
 988             withToString("char[i * 5]", (int s) -> {
 989                 return fillChar(s * BUFFER_REPS,
 990                             i -> (char)(i * 5));
 991             }),
 992             withToString("char[i + 1]", (int s) -> {
 993                 return fillChar(s * BUFFER_REPS,
 994                             i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1)));
 995             })
 996     );
 997 
 998     @DataProvider
 999     public Object[][] charProvider() {
1000         return CHAR_GENERATORS.stream().
1001                 map(f -> new Object[]{f}).
1002                 toArray(Object[][]::new);
1003     }
1004 
1005     @DataProvider
1006     public Object[][] charProviderForIOOBE() {
1007         var f = CHAR_GENERATORS.get(0);
1008         return INDEX_GENERATORS.stream().map(fi -> {
1009                     return new Object[] {f, fi};
1010                 }).
1011                 toArray(Object[][]::new);
1012     }
1013 
1014     @DataProvider
1015     public Object[][] charMaskProvider() {
1016         return BOOLEAN_MASK_GENERATORS.stream().
1017                 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> {
1018                     return new Object[] {fa, fm};
1019                 })).
1020                 toArray(Object[][]::new);
1021     }
1022 
1023     @DataProvider
1024     public Object[][] charMaskProviderForIOOBE() {
1025         var f = CHAR_GENERATORS.get(0);
1026         return BOOLEAN_MASK_GENERATORS.stream().
1027                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
1028                     return new Object[] {f, fi, fm};
1029                 })).
1030                 toArray(Object[][]::new);
1031     }
1032 
1033     interface ToCharF {
1034         char apply(int i);
1035     }
1036 
1037     static char[] fillChar(int s , ToCharF f) {
1038         return fillChar(new char[s], f);
1039     }
1040 
1041     static char[] fillChar(char[] a, ToCharF f) {
1042         for (int i = 0; i < a.length; i++) {
1043             a[i] = f.apply(i);
1044         }
1045         return a;
1046     }
1047 
1048     @DontInline
1049     static $abstractvectortype$ fromCharArray(char[] a, int i) {
1050         return $abstractvectortype$.fromCharArray(SPECIES, a, i);
1051     }
1052 
1053     @DontInline
1054     static $abstractvectortype$ fromCharArray(char[] a, int i, VectorMask<$Boxtype$> m) {
1055         return $abstractvectortype$.fromCharArray(SPECIES, a, i, m);
1056     }
1057 
1058     @DontInline
1059     static void intoCharArray($abstractvectortype$ v, char[] a, int i) {
1060         v.intoCharArray(a, i);
1061     }
1062 
1063     @DontInline
1064     static void intoCharArray($abstractvectortype$ v, char[] a, int i, VectorMask<$Boxtype$> m) {
1065         v.intoCharArray(a, i, m);
1066     }
1067 
1068     @Test(dataProvider = "charProvider")
1069     static void loadStoreCharArray(IntFunction<char[]> fa) {
1070         char[] a = fa.apply(SPECIES.length());
1071         char[] r = new char[a.length];
1072 
1073         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1074             for (int i = 0; i < a.length; i += SPECIES.length()) {
1075                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1076                 av.intoCharArray(r, i);
1077             }
1078         }
1079         Assert.assertEquals(a, r);
1080     }
1081 
1082     @Test(dataProvider = "charProviderForIOOBE")
1083     static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
1084         char[] a = fa.apply(SPECIES.length());
1085         char[] r = new char[a.length];
1086 
1087         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1088             for (int i = 0; i < a.length; i += SPECIES.length()) {
1089                 $abstractvectortype$ av = fromCharArray(a, i);
1090                 av.intoCharArray(r, i);
1091             }
1092         }
1093 
1094         int index = fi.apply(a.length);
1095         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
1096         try {
1097             fromCharArray(a, index);
1098             if (shouldFail) {
1099                 Assert.fail("Failed to throw IndexOutOfBoundsException");
1100             }
1101         } catch (IndexOutOfBoundsException e) {
1102             if (!shouldFail) {
1103                 Assert.fail("Unexpected IndexOutOfBoundsException");
1104             }
1105         }
1106     }
1107 
1108     @Test(dataProvider = "charProviderForIOOBE")
1109     static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
1110         char[] a = fa.apply(SPECIES.length());
1111         char[] r = new char[a.length];
1112 
1113         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1114             for (int i = 0; i < a.length; i += SPECIES.length()) {
1115                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1116                 intoCharArray(av, r, i);
1117             }
1118         }
1119 
1120         int index = fi.apply(a.length);
1121         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
1122         try {
1123             $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0);
1124             intoCharArray(av, r, index);
1125             if (shouldFail) {
1126                 Assert.fail("Failed to throw IndexOutOfBoundsException");
1127             }
1128         } catch (IndexOutOfBoundsException e) {
1129             if (!shouldFail) {
1130                 Assert.fail("Unexpected IndexOutOfBoundsException");
1131             }
1132         }
1133     }
1134 
1135     @Test(dataProvider = "charMaskProvider")
1136     static void loadStoreMaskCharArray(IntFunction<char[]> fa,
1137                                        IntFunction<boolean[]> fm) {
1138         char[] a = fa.apply(SPECIES.length());
1139         char[] r = new char[a.length];
1140         boolean[] mask = fm.apply(SPECIES.length());
1141         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
1142 
1143         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1144             for (int i = 0; i < a.length; i += SPECIES.length()) {
1145                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, vmask);
1146                 av.intoCharArray(r, i);
1147             }
1148         }
1149         assertArraysEquals(a, r, mask);
1150 
1151 
1152         r = new char[a.length];
1153 
1154         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1155             for (int i = 0; i < a.length; i += SPECIES.length()) {
1156                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1157                 av.intoCharArray(r, i, vmask);
1158             }
1159         }
1160         assertArraysEquals(a, r, mask);
1161     }
1162 
1163     @Test(dataProvider = "charMaskProviderForIOOBE")
1164     static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
1165         char[] a = fa.apply(SPECIES.length());
1166         char[] r = new char[a.length];
1167         boolean[] mask = fm.apply(SPECIES.length());
1168         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
1169 
1170         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1171             for (int i = 0; i < a.length; i += SPECIES.length()) {
1172                 $abstractvectortype$ av = fromCharArray(a, i, vmask);
1173                 av.intoCharArray(r, i);
1174             }
1175         }
1176 
1177         int index = fi.apply(a.length);
1178         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
1179         try {
1180             fromCharArray(a, index, vmask);
1181             if (shouldFail) {
1182                 Assert.fail("Failed to throw IndexOutOfBoundsException");
1183             }
1184         } catch (IndexOutOfBoundsException e) {
1185             if (!shouldFail) {
1186                 Assert.fail("Unexpected IndexOutOfBoundsException");
1187             }
1188         }
1189     }
1190 
1191     @Test(dataProvider = "charMaskProviderForIOOBE")
1192     static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
1193         char[] a = fa.apply(SPECIES.length());
1194         char[] r = new char[a.length];
1195         boolean[] mask = fm.apply(SPECIES.length());
1196         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
1197 
1198         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1199             for (int i = 0; i < a.length; i += SPECIES.length()) {
1200                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1201                 intoCharArray(av, r, i, vmask);
1202             }
1203         }
1204 
1205         int index = fi.apply(a.length);
1206         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
1207         try {
1208             $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0);
1209             intoCharArray(av, a, index, vmask);
1210             if (shouldFail) {
1211                 Assert.fail("Failed to throw IndexOutOfBoundsException");
1212             }
1213         } catch (IndexOutOfBoundsException e) {
1214             if (!shouldFail) {
1215                 Assert.fail("Unexpected IndexOutOfBoundsException");
1216             }
1217         }
1218     }
1219 
1220 #end[short]
1221 
1222 #if[byte]
1223     static void assertArraysEquals(boolean[] r, byte[] a) {
1224         int i = 0;
1225         try {
1226             for (; i < a.length; i++) {
1227                 Assert.assertEquals(r[i], (a[i] & 1) == 1);
1228             }
1229         } catch (AssertionError e) {
1230             Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i);
1231         }
1232     }
1233 
1234     static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) {
1235         int i = 0;
1236         try {
1237             for (; i < a.length; i++) {
1238                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]);
1239             }
1240         } catch (AssertionError e) {
1241             Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i);
1242         }
1243     }
1244 
1245     static boolean[] convertToBooleanArray(byte[] a) {
1246         boolean[] r = new boolean[a.length];
1247 
1248         for (int i = 0; i < a.length; i++) {
1249             r[i] = (a[i] & 1) == 1;
1250         }
1251 
1252         return r;
1253     }
1254 
1255     @Test(dataProvider = "byteProvider")
1256     static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) {
1257         byte[] a = fa.apply(SPECIES.length());
1258         boolean[] r = new boolean[a.length];
1259 
1260         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1261             for (int i = 0; i < a.length; i += SPECIES.length()) {
1262                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1263                 av.intoBooleanArray(r, i);
1264             }
1265         }
1266         assertArraysEquals(r, a);
1267     }
1268 
1269     @Test(dataProvider = "byteProvider")
1270     static void loadStoreBooleanArray(IntFunction<byte[]> fa) {
1271         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1272         boolean[] r = new boolean[a.length];
1273 
1274         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1275             for (int i = 0; i < a.length; i += SPECIES.length()) {
1276                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1277                 av.intoBooleanArray(r, i);
1278             }
1279         }
1280         Assert.assertEquals(r, a);
1281     }
1282 
1283     @Test(dataProvider = "byteMaskProvider")
1284     static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa,
1285                                           IntFunction<boolean[]> fm) {
1286         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1287         boolean[] r = new boolean[a.length];
1288         boolean[] mask = fm.apply(SPECIES.length());
1289         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
1290 
1291         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1292             for (int i = 0; i < a.length; i += SPECIES.length()) {
1293                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask);
1294                 av.intoBooleanArray(r, i);
1295             }
1296         }
1297         assertArraysEquals(r, a, mask);
1298 
1299 
1300         r = new boolean[a.length];
1301 
1302         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1303             for (int i = 0; i < a.length; i += SPECIES.length()) {
1304                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1305                 av.intoBooleanArray(r, i, vmask);
1306             }
1307         }
1308         assertArraysEquals(r, a, mask);
1309     }
1310 #end[byte]
1311 
1312 
1313     // Gather/Scatter load/store tests
1314 
1315     static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap) {
1316         int i = 0;
1317         int j = 0;
1318         try {
1319             for (; i < a.length; i += SPECIES.length()) {
1320                 j = i;
1321                 for (; j < i + SPECIES.length(); j++) {
1322                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1323                 }
1324             }
1325         } catch (AssertionError e) {
1326             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1327         }
1328     }
1329 
1330     static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) {
1331         int i = 0;
1332         int j = 0;
1333         try {
1334             for (; i < a.length; i += SPECIES.length()) {
1335                 j = i;
1336                 for (; j < i + SPECIES.length(); j++) {
1337                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0);
1338                 }
1339             }
1340         } catch (AssertionError e) {
1341             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0, "at index #" + j);
1342         }
1343     }
1344 
1345     static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) {
1346         $type$[] expected = new $type$[r.length];
1347 
1348         // Store before checking, since the same location may be stored to more than once
1349         for (int i = 0; i < a.length; i += SPECIES.length()) {
1350             for (int j = i; j < i + SPECIES.length(); j++) {
1351                 if (mask[j % SPECIES.length()]) {
1352                     expected[i + indexMap[j]] = a[j];
1353                 }
1354             }
1355         }
1356 
1357         Assert.assertEquals(r, expected);
1358     }
1359 
1360     static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap) {
1361         $type$[] expected = new $type$[r.length];
1362 
1363         // Store before checking, since the same location may be stored to more than once
1364         for (int i = 0; i < a.length; i += SPECIES.length()) {
1365             for (int j = i; j < i + SPECIES.length(); j++) {
1366                 expected[i + indexMap[j]] = a[j];
1367             }
1368         }
1369 
1370         Assert.assertEquals(r, expected);
1371     }
1372 
1373     @DataProvider
1374     public Object[][] gatherScatterProvider() {
1375         return INT_INDEX_GENERATORS.stream().
1376                 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1377                     return new Object[] {fa, fs};
1378                 })).
1379                 toArray(Object[][]::new);
1380     }
1381 
1382     @DataProvider
1383     public Object[][] gatherScatterMaskProvider() {
1384         return BOOLEAN_MASK_GENERATORS.stream().
1385           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1386             $TYPE$_GENERATORS.stream().map(fa -> {
1387                     return new Object[] {fa, fm, fs};
1388             }))).
1389             toArray(Object[][]::new);
1390     }
1391 
1392 
1393     @Test(dataProvider = "gatherScatterProvider")
1394     static void gather(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1395         $type$[] a = fa.apply(SPECIES.length());
1396         int[] b = fs.apply(a.length, SPECIES.length());
1397         $type$[] r = new $type$[a.length];
1398 
1399         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1400             for (int i = 0; i < a.length; i += SPECIES.length()) {
1401                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i);
1402                 av.intoArray(r, i);
1403             }
1404         }
1405 
1406         assertGatherArraysEquals(r, a, b);
1407     }
1408 
1409     @Test(dataProvider = "gatherScatterMaskProvider")
1410     static void gatherMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1411         $type$[] a = fa.apply(SPECIES.length());
1412         int[] b = fs.apply(a.length, SPECIES.length());
1413         $type$[] r = new $type$[a.length];
1414         boolean[] mask = fm.apply(SPECIES.length());
1415         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1416 
1417         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1418             for (int i = 0; i < a.length; i += SPECIES.length()) {
1419                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i, vmask);
1420                 av.intoArray(r, i);
1421             }
1422         }
1423 
1424         assertGatherArraysEquals(r, a, b, mask);
1425     }
1426 
1427     @Test(dataProvider = "gatherScatterProvider")
1428     static void scatter(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1429         $type$[] a = fa.apply(SPECIES.length());
1430         int[] b = fs.apply(a.length, SPECIES.length());
1431         $type$[] r = new $type$[a.length];
1432 
1433         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1434             for (int i = 0; i < a.length; i += SPECIES.length()) {
1435                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
1436                 av.intoArray(r, i, b, i);
1437             }
1438         }
1439 
1440         assertScatterArraysEquals(r, a, b);
1441     }
1442 
1443     @Test(dataProvider = "gatherScatterMaskProvider")
1444     static void scatterMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1445         $type$[] a = fa.apply(SPECIES.length());
1446         int[] b = fs.apply(a.length, SPECIES.length());
1447         $type$[] r = new $type$[a.length];
1448         boolean[] mask = fm.apply(SPECIES.length());
1449         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1450 
1451         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1452             for (int i = 0; i < a.length; i += SPECIES.length()) {
1453                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
1454                 av.intoArray(r, i, b, i, vmask);
1455             }
1456         }
1457 
1458         assertScatterArraysEquals(r, a, b, mask);
1459     }
1460 
1461 #if[short]
1462     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) {
1463         int i = 0;
1464         int j = 0;
1465         try {
1466             for (; i < a.length; i += SPECIES.length()) {
1467                 j = i;
1468                 for (; j < i + SPECIES.length(); j++) {
1469                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1470                 }
1471             }
1472         } catch (AssertionError e) {
1473             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1474         }
1475     }
1476 
1477     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1478         int i = 0;
1479         int j = 0;
1480         try {
1481             for (; i < a.length; i += SPECIES.length()) {
1482                 j = i;
1483                 for (; j < i + SPECIES.length(); j++) {
1484                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0);
1485                 }
1486             }
1487         } catch (AssertionError e) {
1488             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j);
1489         }
1490     }
1491 
1492     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1493         char[] expected = new char[r.length];
1494 
1495         // Store before checking, since the same location may be stored to more than once
1496         for (int i = 0; i < a.length; i += SPECIES.length()) {
1497             for (int j = i; j < i + SPECIES.length(); j++) {
1498                 if (mask[j % SPECIES.length()]) {
1499                     expected[i + indexMap[j]] = a[j];
1500                 }
1501             }
1502         }
1503 
1504         Assert.assertEquals(r, expected);
1505     }
1506 
1507     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) {
1508         char[] expected = new char[r.length];
1509 
1510         // Store before checking, since the same location may be stored to more than once
1511         for (int i = 0; i < a.length; i += SPECIES.length()) {
1512             for (int j = i; j < i + SPECIES.length(); j++) {
1513                 expected[i + indexMap[j]] = a[j];
1514             }
1515         }
1516 
1517         Assert.assertEquals(r, expected);
1518     }
1519 
1520     @DataProvider
1521     public Object[][] charGatherScatterProvider() {
1522         return INT_INDEX_GENERATORS.stream().
1523                 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> {
1524                     return new Object[] {fa, fs};
1525                 })).
1526                 toArray(Object[][]::new);
1527     }
1528 
1529     @DataProvider
1530     public Object[][] charGatherScatterMaskProvider() {
1531         return BOOLEAN_MASK_GENERATORS.stream().
1532           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1533             CHAR_GENERATORS.stream().map(fa -> {
1534                     return new Object[] {fa, fm, fs};
1535             }))).
1536             toArray(Object[][]::new);
1537     }
1538 
1539 
1540     @Test(dataProvider = "charGatherScatterProvider")
1541     static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1542         char[] a = fa.apply(SPECIES.length());
1543         int[] b = fs.apply(a.length, SPECIES.length());
1544         char[] r = new char[a.length];
1545 
1546         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1547             for (int i = 0; i < a.length; i += SPECIES.length()) {
1548                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i);
1549                 av.intoCharArray(r, i);
1550             }
1551         }
1552 
1553         assertGatherArraysEquals(r, a, b);
1554     }
1555 
1556     @Test(dataProvider = "charGatherScatterMaskProvider")
1557     static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1558         char[] a = fa.apply(SPECIES.length());
1559         int[] b = fs.apply(a.length, SPECIES.length());
1560         char[] r = new char[a.length];
1561         boolean[] mask = fm.apply(SPECIES.length());
1562         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1563 
1564         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1565             for (int i = 0; i < a.length; i += SPECIES.length()) {
1566                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i, vmask);
1567                 av.intoCharArray(r, i);
1568             }
1569         }
1570 
1571         assertGatherArraysEquals(r, a, b, mask);
1572     }
1573 
1574     @Test(dataProvider = "charGatherScatterProvider")
1575     static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1576         char[] a = fa.apply(SPECIES.length());
1577         int[] b = fs.apply(a.length, SPECIES.length());
1578         char[] r = new char[a.length];
1579 
1580         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1581             for (int i = 0; i < a.length; i += SPECIES.length()) {
1582                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1583                 av.intoCharArray(r, i, b, i);
1584             }
1585         }
1586 
1587         assertScatterArraysEquals(r, a, b);
1588     }
1589 
1590     @Test(dataProvider = "charGatherScatterMaskProvider")
1591     static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1592         char[] a = fa.apply(SPECIES.length());
1593         int[] b = fs.apply(a.length, SPECIES.length());
1594         char[] r = new char[a.length];
1595         boolean[] mask = fm.apply(SPECIES.length());
1596         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1597 
1598         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1599             for (int i = 0; i < a.length; i += SPECIES.length()) {
1600                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1601                 av.intoCharArray(r, i, b, i, vmask);
1602             }
1603         }
1604 
1605         assertScatterArraysEquals(r, a, b, mask);
1606     }
1607 #end[short]
1608 
1609 #if[byte]
1610     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1611         int i = 0;
1612         int j = 0;
1613         try {
1614             for (; i < a.length; i += SPECIES.length()) {
1615                 j = i;
1616                 for (; j < i + SPECIES.length(); j++) {
1617                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1618                 }
1619             }
1620         } catch (AssertionError e) {
1621             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1622         }
1623     }
1624 
1625     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1626         int i = 0;
1627         int j = 0;
1628         try {
1629             for (; i < a.length; i += SPECIES.length()) {
1630                 j = i;
1631                 for (; j < i + SPECIES.length(); j++) {
1632                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false);
1633                 }
1634             }
1635         } catch (AssertionError e) {
1636             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j);
1637         }
1638     }
1639 
1640     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1641         boolean[] expected = new boolean[r.length];
1642 
1643         // Store before checking, since the same location may be stored to more than once
1644         for (int i = 0; i < a.length; i += SPECIES.length()) {
1645             for (int j = i; j < i + SPECIES.length(); j++) {
1646                 if (mask[j % SPECIES.length()]) {
1647                     expected[i + indexMap[j]] = a[j];
1648                 }
1649             }
1650         }
1651 
1652         Assert.assertEquals(r, expected);
1653     }
1654 
1655     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1656         boolean[] expected = new boolean[r.length];
1657 
1658         // Store before checking, since the same location may be stored to more than once
1659         for (int i = 0; i < a.length; i += SPECIES.length()) {
1660             for (int j = i; j < i + SPECIES.length(); j++) {
1661                 expected[i + indexMap[j]] = a[j];
1662             }
1663         }
1664 
1665         Assert.assertEquals(r, expected);
1666     }
1667 
1668     @Test(dataProvider = "gatherScatterProvider")
1669     static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1670         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1671         int[] b = fs.apply(a.length, SPECIES.length());
1672         boolean[] r = new boolean[a.length];
1673 
1674         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1675             for (int i = 0; i < a.length; i += SPECIES.length()) {
1676                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i);
1677                 av.intoBooleanArray(r, i);
1678             }
1679         }
1680 
1681         assertGatherArraysEquals(r, a, b);
1682     }
1683 
1684     @Test(dataProvider = "gatherScatterMaskProvider")
1685     static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1686         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1687         int[] b = fs.apply(a.length, SPECIES.length());
1688         boolean[] r = new boolean[a.length];
1689         boolean[] mask = fm.apply(SPECIES.length());
1690         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1691 
1692         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1693             for (int i = 0; i < a.length; i += SPECIES.length()) {
1694                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i, vmask);
1695                 av.intoBooleanArray(r, i);
1696             }
1697         }
1698 
1699         assertGatherArraysEquals(r, a, b, mask);
1700     }
1701 
1702     @Test(dataProvider = "gatherScatterProvider")
1703     static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1704         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1705         int[] b = fs.apply(a.length, SPECIES.length());
1706         boolean[] r = new boolean[a.length];
1707 
1708         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1709             for (int i = 0; i < a.length; i += SPECIES.length()) {
1710                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i);
1711                 av.intoBooleanArray(r, i, b, i);
1712             }
1713         }
1714 
1715         assertScatterArraysEquals(r, a, b);
1716     }
1717 
1718     @Test(dataProvider = "gatherScatterMaskProvider")
1719     static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1720         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1721         int[] b = fs.apply(a.length, SPECIES.length());
1722         boolean[] r = new boolean[a.length];
1723         boolean[] mask = fm.apply(SPECIES.length());
1724         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1725 
1726         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1727             for (int i = 0; i < a.length; i += SPECIES.length()) {
1728                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i);
1729                 av.intoBooleanArray(r, i, b, i, vmask);
1730             }
1731         }
1732 
1733         assertScatterArraysEquals(r, a, b, mask);
1734     }
1735 #end[byte]
1736 
1737 }