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