diff --git a/src/hotspot/cpu/aarch64/aarch64_vector.ad b/src/hotspot/cpu/aarch64/aarch64_vector.ad index a0df8fc3c973c..d4fc0611b30e3 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector.ad +++ b/src/hotspot/cpu/aarch64/aarch64_vector.ad @@ -3748,6 +3748,69 @@ instruct reinterpret_resize_gt128b(vReg dst, vReg src, pReg ptmp, rFlagsReg cr) ins_pipe(pipe_slow); %} +// ---------------------------- Vector zero extend -------------------------------- + +instruct vzeroExtBtoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastB2X src)); + format %{ "vzeroExtBtoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_SHORT || bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4B to 4S/4I, 8B to 8S + __ neon_vector_extend($dst$$FloatRegister, bt, length_in_bytes, + $src$$FloatRegister, T_BYTE, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_vector_extend($dst$$FloatRegister, size, + $src$$FloatRegister, __ B, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtStoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastS2X src)); + format %{ "vzeroExtStoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4S to 4I + __ neon_vector_extend($dst$$FloatRegister, T_INT, length_in_bytes, + $src$$FloatRegister, T_SHORT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_vector_extend($dst$$FloatRegister, size, + $src$$FloatRegister, __ H, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtItoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastI2X src)); + format %{ "vzeroExtItoX $dst, $src" %} + ins_encode %{ + assert(Matcher::vector_element_basic_type(this) == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 2I to 2L + __ neon_vector_extend($dst$$FloatRegister, T_LONG, length_in_bytes, + $src$$FloatRegister, T_INT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ D, + $src$$FloatRegister, __ S, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector cast ---------------------------------- // VectorCastB2X diff --git a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 index cb22e96dc8f03..41537d0e21178 100644 --- a/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 +++ b/src/hotspot/cpu/aarch64/aarch64_vector_ad.m4 @@ -2320,6 +2320,69 @@ instruct reinterpret_resize_gt128b(vReg dst, vReg src, pReg ptmp, rFlagsReg cr) ins_pipe(pipe_slow); %} +// ---------------------------- Vector zero extend -------------------------------- + +instruct vzeroExtBtoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastB2X src)); + format %{ "vzeroExtBtoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_SHORT || bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4B to 4S/4I, 8B to 8S + __ neon_vector_extend($dst$$FloatRegister, bt, length_in_bytes, + $src$$FloatRegister, T_BYTE, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_vector_extend($dst$$FloatRegister, size, + $src$$FloatRegister, __ B, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtStoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastS2X src)); + format %{ "vzeroExtStoX $dst, $src" %} + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + assert(bt == T_INT || bt == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 4S to 4I + __ neon_vector_extend($dst$$FloatRegister, T_INT, length_in_bytes, + $src$$FloatRegister, T_SHORT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); + __ sve_vector_extend($dst$$FloatRegister, size, + $src$$FloatRegister, __ H, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + +instruct vzeroExtItoX(vReg dst, vReg src) %{ + match(Set dst (VectorUCastI2X src)); + format %{ "vzeroExtItoX $dst, $src" %} + ins_encode %{ + assert(Matcher::vector_element_basic_type(this) == T_LONG, "must be"); + uint length_in_bytes = Matcher::vector_length_in_bytes(this); + if (VM_Version::use_neon_for_vector(length_in_bytes)) { + // 2I to 2L + __ neon_vector_extend($dst$$FloatRegister, T_LONG, length_in_bytes, + $src$$FloatRegister, T_INT, /* is_unsigned */ true); + } else { + assert(UseSVE > 0, "must be sve"); + __ sve_vector_extend($dst$$FloatRegister, __ D, + $src$$FloatRegister, __ S, /* is_unsigned */ true); + } + %} + ins_pipe(pipe_slow); +%} + // ------------------------------ Vector cast ---------------------------------- // VectorCastB2X diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 5338eff0134f8..5df7785e8b5b8 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -1337,29 +1337,33 @@ void C2_MacroAssembler::sve_vmask_lasttrue(Register dst, BasicType bt, PRegister subw(dst, rscratch1, dst); } +typedef void (C2_MacroAssembler::* xtl_insn)(FloatRegister Vd, Assembler::SIMD_Arrangement Ta, + FloatRegister Vn, Assembler::SIMD_Arrangement Tb); + // Extend integer vector src to dst with the same lane count // but larger element size, e.g. 4B -> 4I void C2_MacroAssembler::neon_vector_extend(FloatRegister dst, BasicType dst_bt, unsigned dst_vlen_in_bytes, - FloatRegister src, BasicType src_bt) { + FloatRegister src, BasicType src_bt, bool is_unsigned) { + xtl_insn ext = is_unsigned ? &C2_MacroAssembler::uxtl : &C2_MacroAssembler::sxtl; if (src_bt == T_BYTE) { if (dst_bt == T_SHORT) { // 4B/8B to 4S/8S assert(dst_vlen_in_bytes == 8 || dst_vlen_in_bytes == 16, "unsupported"); - sxtl(dst, T8H, src, T8B); + (this->*ext)(dst, T8H, src, T8B); } else { // 4B to 4I assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported"); - sxtl(dst, T8H, src, T8B); - sxtl(dst, T4S, dst, T4H); + (this->*ext)(dst, T8H, src, T8B); + (this->*ext)(dst, T4S, dst, T4H); } } else if (src_bt == T_SHORT) { // 4S to 4I assert(dst_vlen_in_bytes == 16 && dst_bt == T_INT, "unsupported"); - sxtl(dst, T4S, src, T4H); + (this->*ext)(dst, T4S, src, T4H); } else if (src_bt == T_INT) { // 2I to 2L assert(dst_vlen_in_bytes == 16 && dst_bt == T_LONG, "unsupported"); - sxtl(dst, T2D, src, T2S); + (this->*ext)(dst, T2D, src, T2S); } else { ShouldNotReachHere(); } @@ -1392,35 +1396,42 @@ void C2_MacroAssembler::neon_vector_narrow(FloatRegister dst, BasicType dst_bt, } } +typedef void (C2_MacroAssembler::* unpklo_insn)(FloatRegister Zd, Assembler::SIMD_RegVariant T, + FloatRegister Zn); + void C2_MacroAssembler::sve_vector_extend(FloatRegister dst, SIMD_RegVariant dst_size, - FloatRegister src, SIMD_RegVariant src_size) { + FloatRegister src, SIMD_RegVariant src_size, + bool is_unsigned) { assert(dst_size > src_size && dst_size <= D && src_size <= S, "invalid element size"); + + unpklo_insn unpklo = is_unsigned ? &C2_MacroAssembler::sve_uunpklo : &C2_MacroAssembler::sve_sunpklo; + if (src_size == B) { switch (dst_size) { case H: - sve_sunpklo(dst, H, src); + (this->*unpklo)(dst, H, src); break; case S: - sve_sunpklo(dst, H, src); - sve_sunpklo(dst, S, dst); + (this->*unpklo)(dst, H, src); + (this->*unpklo)(dst, S, dst); break; case D: - sve_sunpklo(dst, H, src); - sve_sunpklo(dst, S, dst); - sve_sunpklo(dst, D, dst); + (this->*unpklo)(dst, H, src); + (this->*unpklo)(dst, S, dst); + (this->*unpklo)(dst, D, dst); break; default: ShouldNotReachHere(); } } else if (src_size == H) { if (dst_size == S) { - sve_sunpklo(dst, S, src); + (this->*unpklo)(dst, S, src); } else { // D - sve_sunpklo(dst, S, src); - sve_sunpklo(dst, D, dst); + (this->*unpklo)(dst, S, src); + (this->*unpklo)(dst, D, dst); } } else if (src_size == S) { - sve_sunpklo(dst, D, src); + (this->*unpklo)(dst, D, src); } } diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp index f342ca3c977b9..dfa7d88cb93fe 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp @@ -94,13 +94,13 @@ // Vector cast void neon_vector_extend(FloatRegister dst, BasicType dst_bt, unsigned dst_vlen_in_bytes, - FloatRegister src, BasicType src_bt); + FloatRegister src, BasicType src_bt, bool is_unsigned = false); void neon_vector_narrow(FloatRegister dst, BasicType dst_bt, FloatRegister src, BasicType src_bt, unsigned src_vlen_in_bytes); void sve_vector_extend(FloatRegister dst, SIMD_RegVariant dst_size, - FloatRegister src, SIMD_RegVariant src_size); + FloatRegister src, SIMD_RegVariant src_size, bool is_unsigned = false); void sve_vector_narrow(FloatRegister dst, SIMD_RegVariant dst_size, FloatRegister src, SIMD_RegVariant src_size, FloatRegister tmp); diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index fbe9b939991e2..5d3fa3405d08d 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -1614,26 +1614,31 @@ class VectorCastD2XNode : public VectorCastNode { virtual int Opcode() const; }; -class RoundVFNode : public VectorNode { +class VectorCastHF2FNode : public VectorCastNode { public: - RoundVFNode(Node* in, const TypeVect* vt) :VectorNode(in, vt) { - assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); + VectorCastHF2FNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); } virtual int Opcode() const; }; -class VectorUCastB2XNode : public VectorCastNode { +class VectorCastF2HFNode : public VectorCastNode { public: - VectorUCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { - assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); + VectorCastF2HFNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); } virtual int Opcode() const; }; -class RoundVDNode : public VectorNode { +// So far, VectorUCastNode can only be used in Vector API unsigned extensions +// between integral types. E.g., extending byte to float is not supported now. +class VectorUCastB2XNode : public VectorCastNode { public: - RoundVDNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { - assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); + VectorUCastB2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_BYTE, "must be byte"); + assert(vt->element_basic_type() == T_SHORT || + vt->element_basic_type() == T_INT || + vt->element_basic_type() == T_LONG, "must be"); } virtual int Opcode() const; }; @@ -1642,30 +1647,33 @@ class VectorUCastS2XNode : public VectorCastNode { public: VectorUCastS2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); + assert(vt->element_basic_type() == T_INT || + vt->element_basic_type() == T_LONG, "must be"); } virtual int Opcode() const; }; -class VectorCastHF2FNode : public VectorCastNode { +class VectorUCastI2XNode : public VectorCastNode { public: - VectorCastHF2FNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { - assert(in->bottom_type()->is_vect()->element_basic_type() == T_SHORT, "must be short"); + VectorUCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); + assert(vt->element_basic_type() == T_LONG, "must be"); } virtual int Opcode() const; }; -class VectorCastF2HFNode : public VectorCastNode { +class RoundVFNode : public VectorNode { public: - VectorCastF2HFNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { + RoundVFNode(Node* in, const TypeVect* vt) :VectorNode(in, vt) { assert(in->bottom_type()->is_vect()->element_basic_type() == T_FLOAT, "must be float"); } virtual int Opcode() const; }; -class VectorUCastI2XNode : public VectorCastNode { +class RoundVDNode : public VectorNode { public: - VectorUCastI2XNode(Node* in, const TypeVect* vt) : VectorCastNode(in, vt) { - assert(in->bottom_type()->is_vect()->element_basic_type() == T_INT, "must be int"); + RoundVDNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) { + assert(in->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE, "must be double"); } virtual int Opcode() const; }; diff --git a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java index 2c1c765f4bfbc..032ed40de9861 100644 --- a/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java +++ b/test/hotspot/jtreg/compiler/vectorapi/reshape/utils/TestCastMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,7 +228,74 @@ public class TestCastMethods { makePair(DSPEC512, LSPEC512), makePair(DSPEC128, FSPEC64), makePair(DSPEC256, FSPEC128), - makePair(DSPEC512, FSPEC256) + makePair(DSPEC512, FSPEC256), + + makePair(BSPEC64, SSPEC64, true), + makePair(BSPEC64, SSPEC128, true), + makePair(BSPEC64, SSPEC256, true), + makePair(BSPEC64, SSPEC512, true), + makePair(BSPEC64, ISPEC128, true), + makePair(BSPEC64, ISPEC256, true), + makePair(BSPEC64, ISPEC512, true), + makePair(BSPEC64, LSPEC256, true), + makePair(BSPEC64, LSPEC512, true), + makePair(BSPEC128, SSPEC64, true), + makePair(BSPEC128, SSPEC128, true), + makePair(BSPEC128, SSPEC256, true), + makePair(BSPEC128, SSPEC512, true), + makePair(BSPEC128, ISPEC128, true), + makePair(BSPEC128, ISPEC256, true), + makePair(BSPEC128, ISPEC512, true), + makePair(BSPEC128, LSPEC256, true), + makePair(BSPEC128, LSPEC512, true), + makePair(BSPEC256, SSPEC64, true), + makePair(BSPEC256, SSPEC128, true), + makePair(BSPEC256, SSPEC256, true), + makePair(BSPEC256, SSPEC512, true), + makePair(BSPEC256, ISPEC128, true), + makePair(BSPEC256, ISPEC256, true), + makePair(BSPEC256, ISPEC512, true), + makePair(BSPEC256, LSPEC256, true), + makePair(BSPEC256, LSPEC512, true), + makePair(BSPEC512, SSPEC64, true), + makePair(BSPEC512, SSPEC128, true), + makePair(BSPEC512, SSPEC256, true), + makePair(BSPEC512, SSPEC512, true), + makePair(BSPEC512, ISPEC128, true), + makePair(BSPEC512, ISPEC256, true), + makePair(BSPEC512, ISPEC512, true), + makePair(BSPEC512, LSPEC256, true), + makePair(BSPEC512, LSPEC512, true), + + makePair(SSPEC64, ISPEC128, true), + makePair(SSPEC64, ISPEC256, true), + makePair(SSPEC64, ISPEC512, true), + makePair(SSPEC64, LSPEC256, true), + makePair(SSPEC64, LSPEC512, true), + makePair(SSPEC128, ISPEC128, true), + makePair(SSPEC128, ISPEC256, true), + makePair(SSPEC128, ISPEC512, true), + makePair(SSPEC128, LSPEC256, true), + makePair(SSPEC128, LSPEC512, true), + makePair(SSPEC256, ISPEC128, true), + makePair(SSPEC256, ISPEC256, true), + makePair(SSPEC256, ISPEC512, true), + makePair(SSPEC256, LSPEC256, true), + makePair(SSPEC256, LSPEC512, true), + makePair(SSPEC512, ISPEC128, true), + makePair(SSPEC512, ISPEC256, true), + makePair(SSPEC512, ISPEC512, true), + makePair(SSPEC512, LSPEC256, true), + makePair(SSPEC512, LSPEC512, true), + + makePair(ISPEC64, LSPEC128, true), + makePair(ISPEC64, LSPEC256, true), + makePair(ISPEC128, LSPEC128, true), + makePair(ISPEC128, LSPEC256, true), + makePair(ISPEC256, LSPEC128, true), + makePair(ISPEC256, LSPEC256, true), + makePair(ISPEC512, LSPEC128, true), + makePair(ISPEC512, LSPEC256, true) ); public static final List NEON_CAST_TESTS = List.of( @@ -257,6 +324,16 @@ public class TestCastMethods { makePair(FSPEC64, DSPEC128), makePair(DSPEC128, ISPEC64), makePair(DSPEC128, LSPEC128), - makePair(DSPEC128, FSPEC64) + makePair(DSPEC128, FSPEC64), + + makePair(BSPEC64, SSPEC64, true), + makePair(BSPEC64, SSPEC128, true), + makePair(BSPEC64, ISPEC128, true), + makePair(BSPEC128, SSPEC64, true), + makePair(BSPEC128, SSPEC128, true), + makePair(BSPEC128, ISPEC128, true), + makePair(SSPEC64, ISPEC128, true), + makePair(SSPEC128, ISPEC128, true), + makePair(ISPEC64, LSPEC128, true) ); } diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java new file mode 100644 index 0000000000000..503d80356da96 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorZeroExtend.java @@ -0,0 +1,115 @@ +// +// Copyright (c) 2023, Arm Limited. All rights reserved. +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +// +// This code is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License version 2 only, as +// published by the Free Software Foundation. +// +// This code is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// version 2 for more details (a copy is included in the LICENSE file that +// accompanied this code). +// +// You should have received a copy of the GNU General Public License version +// 2 along with this work; if not, write to the Free Software Foundation, +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +// or visit www.oracle.com if you need additional information or have any +// questions. +// +// +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.concurrent.TimeUnit; +import java.util.Random; +import jdk.incubator.vector.*; +import org.openjdk.jmh.annotations.*; + +import static jdk.incubator.vector.VectorOperators.*; + +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@Fork(jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class VectorZeroExtend { + private static final VectorSpecies B_SPECIES = ByteVector.SPECIES_PREFERRED; + private static final VectorSpecies S_SPECIES = ShortVector.SPECIES_PREFERRED; + private static final VectorSpecies I_SPECIES = IntVector.SPECIES_PREFERRED; + private static final VectorSpecies L_SPECIES = LongVector.SPECIES_PREFERRED; + private static final int LENGTH = 128; + private static final Random RD = new Random(); + private static byte[] ba; + private static short[] sa; + private static int[] ia; + private static long[] la; + + static { + ba = new byte[LENGTH]; + sa = new short[LENGTH]; + ia = new int[LENGTH]; + la = new long[LENGTH]; + + for (int i = 0; i < LENGTH; i++) { + ba[i] = (byte) RD.nextInt(); + sa[i] = (short) RD.nextInt(); + ia[i] = RD.nextInt(); + la[i] = RD.nextLong(); + } + } + + @Benchmark + public void byte2Short() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + ShortVector vb = (ShortVector) va.convertShape(ZERO_EXTEND_B2S, S_SPECIES, 0); + vb.intoArray(sa, 0); + } + } + + @Benchmark + public void byte2Int() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + IntVector vb = (IntVector) va.convertShape(ZERO_EXTEND_B2I, I_SPECIES, 0); + vb.intoArray(ia, 0); + } + } + + @Benchmark + public void byte2Long() { + for (int i = 0; i < B_SPECIES.loopBound(LENGTH); i += B_SPECIES.length()) { + ByteVector va = ByteVector.fromArray(B_SPECIES, ba, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_B2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } + + @Benchmark + public void short2Int() { + for (int i = 0; i < S_SPECIES.loopBound(LENGTH); i += S_SPECIES.length()) { + ShortVector va = ShortVector.fromArray(S_SPECIES, sa, i); + IntVector vb = (IntVector) va.convertShape(ZERO_EXTEND_S2I, I_SPECIES, 0); + vb.intoArray(ia, 0); + } + } + + @Benchmark + public void short2Long() { + for (int i = 0; i < S_SPECIES.loopBound(LENGTH); i += S_SPECIES.length()) { + ShortVector va = ShortVector.fromArray(S_SPECIES, sa, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_S2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } + + @Benchmark + public void int2Long() { + for (int i = 0; i < I_SPECIES.loopBound(LENGTH); i += I_SPECIES.length()) { + IntVector va = IntVector.fromArray(I_SPECIES, ia, i); + LongVector vb = (LongVector) va.convertShape(ZERO_EXTEND_I2L, L_SPECIES, 0); + vb.intoArray(la, 0); + } + } +}