1 /*
   2  * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.vector java.base/jdk.internal.vm.annotation
  27  * @run testng/othervm -XX:-TieredCompilation Byte128VectorLoadStoreTests
  28  *
  29  */
  30 
  31 // -- This file was mechanically generated: Do not edit! -- //
  32 
  33 import java.lang.foreign.MemorySegment;
  34 import java.lang.foreign.Arena;
  35 import java.lang.foreign.ValueLayout;
  36 import jdk.incubator.vector.ByteVector;
  37 import jdk.incubator.vector.VectorMask;
  38 import jdk.incubator.vector.VectorSpecies;
  39 import jdk.incubator.vector.VectorShuffle;
  40 import jdk.internal.vm.annotation.DontInline;
  41 import org.testng.Assert;
  42 import org.testng.annotations.DataProvider;
  43 import org.testng.annotations.Test;
  44 
  45 import java.nio.ByteOrder;
  46 import java.util.List;
  47 import java.util.function.*;
  48 
  49 @Test
  50 public class Byte128VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
  51     static final VectorSpecies<Byte> SPECIES =
  52                 ByteVector.SPECIES_128;
  53 
  54     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  55 
  56     static final ValueLayout.OfByte ELEMENT_LAYOUT = ValueLayout.JAVA_BYTE.withByteAlignment(1);
  57 
  58 
  59     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 128);
  60 
  61     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
  62         int i = 0;
  63         try {
  64             for (; i < a.length; i++) {
  65                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0);
  66             }
  67         } catch (AssertionError e) {
  68             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
  69         }
  70     }
  71 
  72     static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
  73             withToString("byte[i * 5]", (int s) -> {
  74                 return fill(s * BUFFER_REPS,
  75                             i -> (byte)(i * 5));
  76             }),
  77             withToString("byte[i + 1]", (int s) -> {
  78                 return fill(s * BUFFER_REPS,
  79                             i -> (((byte)(i + 1) == 0) ? 1 : (byte)(i + 1)));
  80             })
  81     );
  82 
  83     // Relative to array.length
  84     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
  85             withToString("-1", (int l) -> {
  86                 return -1;
  87             }),
  88             withToString("l", (int l) -> {
  89                 return l;
  90             }),
  91             withToString("l - 1", (int l) -> {
  92                 return l - 1;
  93             }),
  94             withToString("l + 1", (int l) -> {
  95                 return l + 1;
  96             }),
  97             withToString("l - speciesl + 1", (int l) -> {
  98                 return l - SPECIES.length() + 1;
  99             }),
 100             withToString("l + speciesl - 1", (int l) -> {
 101                 return l + SPECIES.length() - 1;
 102             }),
 103             withToString("l + speciesl", (int l) -> {
 104                 return l + SPECIES.length();
 105             }),
 106             withToString("l + speciesl + 1", (int l) -> {
 107                 return l + SPECIES.length() + 1;
 108             })
 109     );
 110 
 111     // Relative to byte[] array.length or MemorySegment.byteSize()
 112     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 113             withToString("-1", (int l) -> {
 114                 return -1;
 115             }),
 116             withToString("l", (int l) -> {
 117                 return l;
 118             }),
 119             withToString("l - 1", (int l) -> {
 120                 return l - 1;
 121             }),
 122             withToString("l + 1", (int l) -> {
 123                 return l + 1;
 124             }),
 125             withToString("l - speciesl*ebsize + 1", (int l) -> {
 126                 return l - SPECIES.vectorByteSize() + 1;
 127             }),
 128             withToString("l + speciesl*ebsize - 1", (int l) -> {
 129                 return l + SPECIES.vectorByteSize() - 1;
 130             }),
 131             withToString("l + speciesl*ebsize", (int l) -> {
 132                 return l + SPECIES.vectorByteSize();
 133             }),
 134             withToString("l + speciesl*ebsize + 1", (int l) -> {
 135                 return l + SPECIES.vectorByteSize() + 1;
 136             })
 137     );
 138 
 139     @DataProvider
 140     public Object[][] byteProvider() {
 141         return BYTE_GENERATORS.stream().
 142                 map(f -> new Object[]{f}).
 143                 toArray(Object[][]::new);
 144     }
 145 
 146     @DataProvider
 147     public Object[][] maskProvider() {
 148         return BOOLEAN_MASK_GENERATORS.stream().
 149                 map(f -> new Object[]{f}).
 150                 toArray(Object[][]::new);
 151     }
 152 
 153     @DataProvider
 154     public Object[][] byteProviderForIOOBE() {
 155         var f = BYTE_GENERATORS.get(0);
 156         return INDEX_GENERATORS.stream().map(fi -> {
 157                     return new Object[] {f, fi};
 158                 }).
 159                 toArray(Object[][]::new);
 160     }
 161 
 162     @DataProvider
 163     public Object[][] byteMaskProvider() {
 164         return BOOLEAN_MASK_GENERATORS.stream().
 165                 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> {
 166                     return new Object[] {fa, fm};
 167                 })).
 168                 toArray(Object[][]::new);
 169     }
 170 
 171     @DataProvider
 172     public Object[][] byteMaskProviderForIOOBE() {
 173         var f = BYTE_GENERATORS.get(0);
 174         return BOOLEAN_MASK_GENERATORS.stream().
 175                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 176                     return new Object[] {f, fi, fm};
 177                 })).
 178                 toArray(Object[][]::new);
 179     }
 180 
 181     @DataProvider
 182     public Object[][] byteMemorySegmentProvider() {
 183         return BYTE_GENERATORS.stream().
 184                 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 185                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 186                             return new Object[]{fa, fb, bo};
 187                         }))).
 188                 toArray(Object[][]::new);
 189     }
 190 
 191     @DataProvider
 192     public Object[][] byteMemorySegmentMaskProvider() {
 193         return BOOLEAN_MASK_GENERATORS.stream().
 194                 flatMap(fm -> BYTE_GENERATORS.stream().
 195                         flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 196                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 197                             return new Object[]{fa, fb, fm, bo};
 198                         })))).
 199                 toArray(Object[][]::new);
 200     }
 201 
 202     @DataProvider
 203     public Object[][] byteByteProviderForIOOBE() {
 204         var f = BYTE_GENERATORS.get(0);
 205         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 206                     return new Object[] {f, fi};
 207                 }).
 208                 toArray(Object[][]::new);
 209     }
 210 
 211     @DataProvider
 212     public Object[][] byteByteMaskProviderForIOOBE() {
 213         var f = BYTE_GENERATORS.get(0);
 214         return BOOLEAN_MASK_GENERATORS.stream().
 215                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 216                     return new Object[] {f, fi, fm};
 217                 })).
 218                 toArray(Object[][]::new);
 219     }
 220 
 221     static MemorySegment toSegment(byte[] a, IntFunction<MemorySegment> fb) {
 222         MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
 223         for (int i = 0; i < a.length; i++) {
 224             ms.set(ELEMENT_LAYOUT, i * SPECIES.elementSize() / 8 , a[i]);
 225         }
 226         return ms;
 227     }
 228 
 229     static byte[] segmentToArray(MemorySegment ms) {
 230         return ms.toArray(ELEMENT_LAYOUT);
 231     }
 232 
 233 
 234     interface ToByteF {
 235         byte apply(int i);
 236     }
 237 
 238     static byte[] fill(int s , ToByteF f) {
 239         return fill(new byte[s], f);
 240     }
 241 
 242     static byte[] fill(byte[] a, ToByteF f) {
 243         for (int i = 0; i < a.length; i++) {
 244             a[i] = f.apply(i);
 245         }
 246         return a;
 247     }
 248 
 249     @DontInline
 250     static ByteVector fromArray(byte[] a, int i) {
 251         return ByteVector.fromArray(SPECIES, a, i);
 252     }
 253 
 254     @DontInline
 255     static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) {
 256         return ByteVector.fromArray(SPECIES, a, i, m);
 257     }
 258 
 259     @DontInline
 260     static void intoArray(ByteVector v, byte[] a, int i) {
 261         v.intoArray(a, i);
 262     }
 263 
 264     @DontInline
 265     static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) {
 266         v.intoArray(a, i, m);
 267     }
 268 
 269     @DontInline
 270     static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
 271         return ByteVector.fromMemorySegment(SPECIES, a, i, bo);
 272     }
 273 
 274     @DontInline
 275     static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) {
 276         return ByteVector.fromMemorySegment(SPECIES, a, i, bo, m);
 277     }
 278 
 279     @DontInline
 280     static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo) {
 281         v.intoMemorySegment(a, i, bo);
 282     }
 283 
 284     @DontInline
 285     static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) {
 286         v.intoMemorySegment(a, i, bo, m);
 287     }
 288 
 289     @Test(dataProvider = "byteProvider")
 290     static void loadStoreArray(IntFunction<byte[]> fa) {
 291         byte[] a = fa.apply(SPECIES.length());
 292         byte[] r = new byte[a.length];
 293 
 294         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 295             for (int i = 0; i < a.length; i += SPECIES.length()) {
 296                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 297                 av.intoArray(r, i);
 298             }
 299         }
 300         Assert.assertEquals(r, a);
 301     }
 302 
 303     @Test(dataProvider = "byteProviderForIOOBE")
 304     static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 305         byte[] a = fa.apply(SPECIES.length());
 306         byte[] r = new byte[a.length];
 307 
 308         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 309             for (int i = 0; i < a.length; i += SPECIES.length()) {
 310                 ByteVector av = fromArray(a, i);
 311                 av.intoArray(r, i);
 312             }
 313         }
 314 
 315         int index = fi.apply(a.length);
 316         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 317         try {
 318             fromArray(a, index);
 319             if (shouldFail) {
 320                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 321             }
 322         } catch (IndexOutOfBoundsException e) {
 323             if (!shouldFail) {
 324                 Assert.fail("Unexpected IndexOutOfBoundsException");
 325             }
 326         }
 327     }
 328 
 329     @Test(dataProvider = "byteProviderForIOOBE")
 330     static void storeArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 331         byte[] a = fa.apply(SPECIES.length());
 332         byte[] r = new byte[a.length];
 333 
 334         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 335             for (int i = 0; i < a.length; i += SPECIES.length()) {
 336                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 337                 intoArray(av, r, i);
 338             }
 339         }
 340 
 341         int index = fi.apply(a.length);
 342         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 343         try {
 344             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 345             intoArray(av, r, index);
 346             if (shouldFail) {
 347                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 348             }
 349         } catch (IndexOutOfBoundsException e) {
 350             if (!shouldFail) {
 351                 Assert.fail("Unexpected IndexOutOfBoundsException");
 352             }
 353         }
 354     }
 355 
 356 
 357     @Test(dataProvider = "byteMaskProvider")
 358     static void loadStoreMaskArray(IntFunction<byte[]> fa,
 359                                    IntFunction<boolean[]> fm) {
 360         byte[] a = fa.apply(SPECIES.length());
 361         byte[] r = new byte[a.length];
 362         boolean[] mask = fm.apply(SPECIES.length());
 363         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 364 
 365         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 366             for (int i = 0; i < a.length; i += SPECIES.length()) {
 367                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, vmask);
 368                 av.intoArray(r, i);
 369             }
 370         }
 371         assertArraysEquals(r, a, mask);
 372 
 373 
 374         r = new byte[a.length];
 375 
 376         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 377             for (int i = 0; i < a.length; i += SPECIES.length()) {
 378                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 379                 av.intoArray(r, i, vmask);
 380             }
 381         }
 382         assertArraysEquals(r, a, mask);
 383     }
 384 
 385     @Test(dataProvider = "byteMaskProviderForIOOBE")
 386     static void loadArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 387         byte[] a = fa.apply(SPECIES.length());
 388         byte[] r = new byte[a.length];
 389         boolean[] mask = fm.apply(SPECIES.length());
 390         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 391 
 392         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 393             for (int i = 0; i < a.length; i += SPECIES.length()) {
 394                 ByteVector av = fromArray(a, i, vmask);
 395                 av.intoArray(r, i);
 396             }
 397         }
 398 
 399         int index = fi.apply(a.length);
 400         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 401         try {
 402             fromArray(a, index, vmask);
 403             if (shouldFail) {
 404                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 405             }
 406         } catch (IndexOutOfBoundsException e) {
 407             if (!shouldFail) {
 408                 Assert.fail("Unexpected IndexOutOfBoundsException");
 409             }
 410         }
 411     }
 412 
 413     @Test(dataProvider = "byteMaskProviderForIOOBE")
 414     static void storeArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 415         byte[] a = fa.apply(SPECIES.length());
 416         byte[] r = new byte[a.length];
 417         boolean[] mask = fm.apply(SPECIES.length());
 418         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 419 
 420         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 421             for (int i = 0; i < a.length; i += SPECIES.length()) {
 422                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 423                 intoArray(av, r, i, vmask);
 424             }
 425         }
 426 
 427         int index = fi.apply(a.length);
 428         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 429         try {
 430             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 431             intoArray(av, a, index, vmask);
 432             if (shouldFail) {
 433                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 434             }
 435         } catch (IndexOutOfBoundsException e) {
 436             if (!shouldFail) {
 437                 Assert.fail("Unexpected IndexOutOfBoundsException");
 438             }
 439         }
 440     }
 441 
 442 
 443     @Test(dataProvider = "byteMaskProvider")
 444     static void loadStoreMask(IntFunction<byte[]> fa,
 445                               IntFunction<boolean[]> fm) {
 446         boolean[] mask = fm.apply(SPECIES.length());
 447         boolean[] r = new boolean[mask.length];
 448 
 449         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 450             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 451                 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i);
 452                 vmask.intoArray(r, i);
 453             }
 454         }
 455         Assert.assertEquals(r, mask);
 456     }
 457 
 458 
 459     @Test(dataProvider = "byteMemorySegmentProvider")
 460     static void loadStoreMemorySegment(IntFunction<byte[]> fa,
 461                                        IntFunction<MemorySegment> fb,
 462                                        ByteOrder bo) {
 463         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb);
 464         MemorySegment r = fb.apply((int) a.byteSize());
 465 
 466         int l = (int) a.byteSize();
 467         int s = SPECIES.vectorByteSize();
 468 
 469         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 470             for (int i = 0; i < l; i += s) {
 471                 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo);
 472                 av.intoMemorySegment(r, i, bo);
 473             }
 474         }
 475         long m = r.mismatch(a);
 476         Assert.assertEquals(m, -1, "Segments not equal");
 477     }
 478 
 479     @Test(dataProvider = "byteByteProviderForIOOBE")
 480     static void loadMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 481         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE));
 482         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE);
 483 
 484         int l = (int) a.byteSize();
 485         int s = SPECIES.vectorByteSize();
 486 
 487         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 488             for (int i = 0; i < l; i += s) {
 489                 ByteVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder());
 490                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 491             }
 492         }
 493 
 494         int index = fi.apply((int) a.byteSize());
 495         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 496         try {
 497             fromMemorySegment(a, index, ByteOrder.nativeOrder());
 498             if (shouldFail) {
 499                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 500             }
 501         } catch (IndexOutOfBoundsException e) {
 502             if (!shouldFail) {
 503                 Assert.fail("Unexpected IndexOutOfBoundsException");
 504             }
 505         }
 506     }
 507 
 508     @Test(dataProvider = "byteByteProviderForIOOBE")
 509     static void storeMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
 510         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE));
 511         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE);
 512 
 513         int l = (int) a.byteSize();
 514         int s = SPECIES.vectorByteSize();
 515 
 516         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 517             for (int i = 0; i < l; i += s) {
 518                 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 519                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder());
 520             }
 521         }
 522 
 523         int index = fi.apply((int) a.byteSize());
 524         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 525         try {
 526             ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 527             intoMemorySegment(av, r, index, ByteOrder.nativeOrder());
 528             if (shouldFail) {
 529                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 530             }
 531         } catch (IndexOutOfBoundsException e) {
 532             if (!shouldFail) {
 533                 Assert.fail("Unexpected IndexOutOfBoundsException");
 534             }
 535         }
 536     }
 537 
 538     @Test(dataProvider = "byteMemorySegmentMaskProvider")
 539     static void loadStoreMemorySegmentMask(IntFunction<byte[]> fa,
 540                                            IntFunction<MemorySegment> fb,
 541                                            IntFunction<boolean[]> fm,
 542                                            ByteOrder bo) {
 543         byte[] _a = fa.apply(SPECIES.length());
 544         MemorySegment a = toSegment(_a, fb);
 545         MemorySegment r = fb.apply((int) a.byteSize());
 546         boolean[] mask = fm.apply(SPECIES.length());
 547         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 548 
 549         int l = (int) a.byteSize();
 550         int s = SPECIES.vectorByteSize();
 551 
 552         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 553             for (int i = 0; i < l; i += s) {
 554                 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo, vmask);
 555                 av.intoMemorySegment(r, i, bo);
 556             }
 557         }
 558         assertArraysEquals(segmentToArray(r), _a, mask);
 559 
 560 
 561         r = fb.apply((int) a.byteSize());
 562 
 563         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 564             for (int i = 0; i < l; i += s) {
 565                 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo);
 566                 av.intoMemorySegment(r, i, bo, vmask);
 567             }
 568         }
 569         assertArraysEquals(segmentToArray(r), _a, mask);
 570     }
 571 
 572     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 573     static void loadMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 574         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE));
 575         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE);
 576         boolean[] mask = fm.apply(SPECIES.length());
 577         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 578 
 579         int l = (int) a.byteSize();
 580         int s = SPECIES.vectorByteSize();
 581 
 582         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 583             for (int i = 0; i < l; i += s) {
 584                 ByteVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
 585                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 586             }
 587         }
 588 
 589         int index = fi.apply((int) a.byteSize());
 590         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 591         try {
 592             fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
 593             if (shouldFail) {
 594                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 595             }
 596         } catch (IndexOutOfBoundsException e) {
 597             if (!shouldFail) {
 598                 Assert.fail("Unexpected IndexOutOfBoundsException");
 599             }
 600         }
 601     }
 602 
 603     @Test(dataProvider = "byteByteMaskProviderForIOOBE")
 604     static void storeMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 605         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE));
 606         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE);
 607         boolean[] mask = fm.apply(SPECIES.length());
 608         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 609 
 610         int l = (int) a.byteSize();
 611         int s = SPECIES.vectorByteSize();
 612 
 613         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 614             for (int i = 0; i < l; i += s) {
 615                 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 616                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask);
 617             }
 618         }
 619 
 620         int index = fi.apply((int) a.byteSize());
 621         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 622         try {
 623             ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 624             intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask);
 625             if (shouldFail) {
 626                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 627             }
 628         } catch (IndexOutOfBoundsException e) {
 629             if (!shouldFail) {
 630                 Assert.fail("Unexpected IndexOutOfBoundsException");
 631             }
 632         }
 633     }
 634 
 635     @Test(dataProvider = "byteMemorySegmentProvider")
 636     static void loadStoreReadonlyMemorySegment(IntFunction<byte[]> fa,
 637                                                IntFunction<MemorySegment> fb,
 638                                                ByteOrder bo) {
 639         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly();
 640 
 641         Assert.assertThrows(
 642                 UnsupportedOperationException.class,
 643                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
 644         );
 645 
 646         Assert.assertThrows(
 647                 UnsupportedOperationException.class,
 648                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
 649         );
 650 
 651         Assert.assertThrows(
 652                 UnsupportedOperationException.class,
 653                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
 654         );
 655 
 656         VectorMask<Byte> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 657                 .laneIsValid();
 658         Assert.assertThrows(
 659                 UnsupportedOperationException.class,
 660                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
 661         );
 662     }
 663 
 664 
 665     @Test(dataProvider = "maskProvider")
 666     static void loadStoreMask(IntFunction<boolean[]> fm) {
 667         boolean[] a = fm.apply(SPECIES.length());
 668         boolean[] r = new boolean[a.length];
 669 
 670         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 671             for (int i = 0; i < a.length; i += SPECIES.length()) {
 672                 VectorMask<Byte> vmask = SPECIES.loadMask(a, i);
 673                 vmask.intoArray(r, i);
 674             }
 675         }
 676         Assert.assertEquals(r, a);
 677     }
 678 
 679 
 680     @Test
 681     static void loadStoreShuffle() {
 682         IntUnaryOperator fn = a -> a + 5;
 683         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 684             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 685             int [] r = shuffle.toArray();
 686 
 687             int [] a = expectedShuffle(SPECIES.length(), fn);
 688             Assert.assertEquals(r, a);
 689        }
 690     }
 691 
 692 
 693 
 694     static void assertArraysEquals(boolean[] r, byte[] a) {
 695         int i = 0;
 696         try {
 697             for (; i < a.length; i++) {
 698                 Assert.assertEquals(r[i], (a[i] & 1) == 1);
 699             }
 700         } catch (AssertionError e) {
 701             Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i);
 702         }
 703     }
 704 
 705     static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) {
 706         int i = 0;
 707         try {
 708             for (; i < a.length; i++) {
 709                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]);
 710             }
 711         } catch (AssertionError e) {
 712             Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i);
 713         }
 714     }
 715 
 716     static boolean[] convertToBooleanArray(byte[] a) {
 717         boolean[] r = new boolean[a.length];
 718 
 719         for (int i = 0; i < a.length; i++) {
 720             r[i] = (a[i] & 1) == 1;
 721         }
 722 
 723         return r;
 724     }
 725 
 726     @Test(dataProvider = "byteProvider")
 727     static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) {
 728         byte[] a = fa.apply(SPECIES.length());
 729         boolean[] r = new boolean[a.length];
 730 
 731         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 732             for (int i = 0; i < a.length; i += SPECIES.length()) {
 733                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 734                 av.intoBooleanArray(r, i);
 735             }
 736         }
 737         assertArraysEquals(r, a);
 738     }
 739 
 740     @Test(dataProvider = "byteProvider")
 741     static void loadStoreBooleanArray(IntFunction<byte[]> fa) {
 742         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 743         boolean[] r = new boolean[a.length];
 744 
 745         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 746             for (int i = 0; i < a.length; i += SPECIES.length()) {
 747                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
 748                 av.intoBooleanArray(r, i);
 749             }
 750         }
 751         Assert.assertEquals(r, a);
 752     }
 753 
 754     @Test(dataProvider = "byteMaskProvider")
 755     static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa,
 756                                           IntFunction<boolean[]> fm) {
 757         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 758         boolean[] r = new boolean[a.length];
 759         boolean[] mask = fm.apply(SPECIES.length());
 760         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
 761 
 762         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 763             for (int i = 0; i < a.length; i += SPECIES.length()) {
 764                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask);
 765                 av.intoBooleanArray(r, i);
 766             }
 767         }
 768         assertArraysEquals(r, a, mask);
 769 
 770 
 771         r = new boolean[a.length];
 772 
 773         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 774             for (int i = 0; i < a.length; i += SPECIES.length()) {
 775                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
 776                 av.intoBooleanArray(r, i, vmask);
 777             }
 778         }
 779         assertArraysEquals(r, a, mask);
 780     }
 781 
 782 
 783     // Gather/Scatter load/store tests
 784 
 785     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap) {
 786         int i = 0;
 787         int j = 0;
 788         try {
 789             for (; i < a.length; i += SPECIES.length()) {
 790                 j = i;
 791                 for (; j < i + SPECIES.length(); j++) {
 792                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
 793                 }
 794             }
 795         } catch (AssertionError e) {
 796             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
 797         }
 798     }
 799 
 800     static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
 801         int i = 0;
 802         int j = 0;
 803         try {
 804             for (; i < a.length; i += SPECIES.length()) {
 805                 j = i;
 806                 for (; j < i + SPECIES.length(); j++) {
 807                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0);
 808                 }
 809             }
 810         } catch (AssertionError e) {
 811             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0, "at index #" + j);
 812         }
 813     }
 814 
 815     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) {
 816         byte[] expected = new byte[r.length];
 817 
 818         // Store before checking, since the same location may be stored to more than once
 819         for (int i = 0; i < a.length; i += SPECIES.length()) {
 820             for (int j = i; j < i + SPECIES.length(); j++) {
 821                 if (mask[j % SPECIES.length()]) {
 822                     expected[i + indexMap[j]] = a[j];
 823                 }
 824             }
 825         }
 826 
 827         Assert.assertEquals(r, expected);
 828     }
 829 
 830     static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap) {
 831         byte[] expected = new byte[r.length];
 832 
 833         // Store before checking, since the same location may be stored to more than once
 834         for (int i = 0; i < a.length; i += SPECIES.length()) {
 835             for (int j = i; j < i + SPECIES.length(); j++) {
 836                 expected[i + indexMap[j]] = a[j];
 837             }
 838         }
 839 
 840         Assert.assertEquals(r, expected);
 841     }
 842 
 843     @DataProvider
 844     public Object[][] gatherScatterProvider() {
 845         return INT_INDEX_GENERATORS.stream().
 846                 flatMap(fs -> BYTE_GENERATORS.stream().map(fa -> {
 847                     return new Object[] {fa, fs};
 848                 })).
 849                 toArray(Object[][]::new);
 850     }
 851 
 852     @DataProvider
 853     public Object[][] gatherScatterMaskProvider() {
 854         return BOOLEAN_MASK_GENERATORS.stream().
 855           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
 856             BYTE_GENERATORS.stream().map(fa -> {
 857                     return new Object[] {fa, fm, fs};
 858             }))).
 859             toArray(Object[][]::new);
 860     }
 861 
 862 
 863     @Test(dataProvider = "gatherScatterProvider")
 864     static void gather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
 865         byte[] a = fa.apply(SPECIES.length());
 866         int[] b = fs.apply(a.length, SPECIES.length());
 867         byte[] r = new byte[a.length];
 868 
 869         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 870             for (int i = 0; i < a.length; i += SPECIES.length()) {
 871                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i);
 872                 av.intoArray(r, i);
 873             }
 874         }
 875 
 876         assertGatherArraysEquals(r, a, b);
 877     }
 878 
 879     @Test(dataProvider = "gatherScatterMaskProvider")
 880     static void gatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
 881         byte[] a = fa.apply(SPECIES.length());
 882         int[] b = fs.apply(a.length, SPECIES.length());
 883         byte[] r = new byte[a.length];
 884         boolean[] mask = fm.apply(SPECIES.length());
 885         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
 886 
 887         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 888             for (int i = 0; i < a.length; i += SPECIES.length()) {
 889                 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i, vmask);
 890                 av.intoArray(r, i);
 891             }
 892         }
 893 
 894         assertGatherArraysEquals(r, a, b, mask);
 895     }
 896 
 897     @Test(dataProvider = "gatherScatterProvider")
 898     static void scatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
 899         byte[] a = fa.apply(SPECIES.length());
 900         int[] b = fs.apply(a.length, SPECIES.length());
 901         byte[] r = new byte[a.length];
 902 
 903         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 904             for (int i = 0; i < a.length; i += SPECIES.length()) {
 905                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 906                 av.intoArray(r, i, b, i);
 907             }
 908         }
 909 
 910         assertScatterArraysEquals(r, a, b);
 911     }
 912 
 913     @Test(dataProvider = "gatherScatterMaskProvider")
 914     static void scatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
 915         byte[] a = fa.apply(SPECIES.length());
 916         int[] b = fs.apply(a.length, SPECIES.length());
 917         byte[] r = new byte[a.length];
 918         boolean[] mask = fm.apply(SPECIES.length());
 919         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
 920 
 921         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 922             for (int i = 0; i < a.length; i += SPECIES.length()) {
 923                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
 924                 av.intoArray(r, i, b, i, vmask);
 925             }
 926         }
 927 
 928         assertScatterArraysEquals(r, a, b, mask);
 929     }
 930 
 931 
 932     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
 933         int i = 0;
 934         int j = 0;
 935         try {
 936             for (; i < a.length; i += SPECIES.length()) {
 937                 j = i;
 938                 for (; j < i + SPECIES.length(); j++) {
 939                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
 940                 }
 941             }
 942         } catch (AssertionError e) {
 943             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
 944         }
 945     }
 946 
 947     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
 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], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false);
 955                 }
 956             }
 957         } catch (AssertionError e) {
 958             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j);
 959         }
 960     }
 961 
 962     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
 963         boolean[] expected = new boolean[r.length];
 964 
 965         // Store before checking, since the same location may be stored to more than once
 966         for (int i = 0; i < a.length; i += SPECIES.length()) {
 967             for (int j = i; j < i + SPECIES.length(); j++) {
 968                 if (mask[j % SPECIES.length()]) {
 969                     expected[i + indexMap[j]] = a[j];
 970                 }
 971             }
 972         }
 973 
 974         Assert.assertEquals(r, expected);
 975     }
 976 
 977     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
 978         boolean[] expected = new boolean[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                 expected[i + indexMap[j]] = a[j];
 984             }
 985         }
 986 
 987         Assert.assertEquals(r, expected);
 988     }
 989 
 990     @Test(dataProvider = "gatherScatterProvider")
 991     static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
 992         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
 993         int[] b = fs.apply(a.length, SPECIES.length());
 994         boolean[] r = new boolean[a.length];
 995 
 996         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 997             for (int i = 0; i < a.length; i += SPECIES.length()) {
 998                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i);
 999                 av.intoBooleanArray(r, i);
1000             }
1001         }
1002 
1003         assertGatherArraysEquals(r, a, b);
1004     }
1005 
1006     @Test(dataProvider = "gatherScatterMaskProvider")
1007     static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1008         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1009         int[] b = fs.apply(a.length, SPECIES.length());
1010         boolean[] r = new boolean[a.length];
1011         boolean[] mask = fm.apply(SPECIES.length());
1012         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1013 
1014         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1015             for (int i = 0; i < a.length; i += SPECIES.length()) {
1016                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i, vmask);
1017                 av.intoBooleanArray(r, i);
1018             }
1019         }
1020 
1021         assertGatherArraysEquals(r, a, b, mask);
1022     }
1023 
1024     @Test(dataProvider = "gatherScatterProvider")
1025     static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1026         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1027         int[] b = fs.apply(a.length, SPECIES.length());
1028         boolean[] r = new boolean[a.length];
1029 
1030         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1031             for (int i = 0; i < a.length; i += SPECIES.length()) {
1032                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1033                 av.intoBooleanArray(r, i, b, i);
1034             }
1035         }
1036 
1037         assertScatterArraysEquals(r, a, b);
1038     }
1039 
1040     @Test(dataProvider = "gatherScatterMaskProvider")
1041     static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1042         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1043         int[] b = fs.apply(a.length, SPECIES.length());
1044         boolean[] r = new boolean[a.length];
1045         boolean[] mask = fm.apply(SPECIES.length());
1046         VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1047 
1048         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1049             for (int i = 0; i < a.length; i += SPECIES.length()) {
1050                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1051                 av.intoBooleanArray(r, i, b, i, vmask);
1052             }
1053         }
1054 
1055         assertScatterArraysEquals(r, a, b, mask);
1056     }
1057 
1058 }