// // Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. // Copyright (c) 2020, 2021, 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. // // // This file is automatically generated by running "m4 aarch64_sve_ad.m4". Do not edit ---- // AArch64 SVE Architecture Description File // 4 bit signed offset -- for predicated load/store operand vmemA_immIOffset4() %{ // (esize / msize) = 1 predicate(Address::offset_ok_for_sve_immed(n->get_int(), 4, Matcher::scalable_vector_reg_size(T_BYTE))); match(ConI); op_cost(0); format %{ %} interface(CONST_INTER); %} operand vmemA_immLOffset4() %{ // (esize / msize) = 1 predicate(Address::offset_ok_for_sve_immed(n->get_long(), 4, Matcher::scalable_vector_reg_size(T_BYTE))); match(ConL); op_cost(0); format %{ %} interface(CONST_INTER); %} operand vmemA_indOffI4(iRegP reg, vmemA_immIOffset4 off) %{ constraint(ALLOC_IN_RC(ptr_reg)); match(AddP reg off); op_cost(0); format %{ "[$reg, $off]" %} interface(MEMORY_INTER) %{ base($reg); index(0xffffffff); scale(0x0); disp($off); %} %} operand vmemA_indOffL4(iRegP reg, vmemA_immLOffset4 off) %{ constraint(ALLOC_IN_RC(ptr_reg)); match(AddP reg off); op_cost(0); format %{ "[$reg, $off]" %} interface(MEMORY_INTER) %{ base($reg); index(0xffffffff); scale(0x0); disp($off); %} %} // The indOff of vmemA is valid only when the vector element (load to/store from) // size equals to memory element (load from/store to) size. opclass vmemA(indirect, vmemA_indOffI4, vmemA_indOffL4); source_hpp %{ bool op_sve_supported(int opcode, int vlen, BasicType bt); bool masked_op_sve_supported(int opcode, int vlen, BasicType bt); %} source %{ typedef void (C2_MacroAssembler::* sve_mem_insn_predicate)(FloatRegister Rt, Assembler::SIMD_RegVariant T, PRegister Pg, const Address &adr); // Predicated load/store, with optional ptrue to all elements of given predicate register. static void loadStoreA_predicated(C2_MacroAssembler masm, bool is_store, FloatRegister reg, PRegister pg, BasicType mem_elem_bt, BasicType vector_elem_bt, int opcode, Register base, int index, int size, int disp) { sve_mem_insn_predicate insn; int mesize = type2aelembytes(mem_elem_bt); if (index == -1) { assert(size == 0, "unsupported address mode: scale size = %d", size); switch(mesize) { case 1: insn = is_store ? &C2_MacroAssembler::sve_st1b : &C2_MacroAssembler::sve_ld1b; break; case 2: insn = is_store ? &C2_MacroAssembler::sve_st1h : &C2_MacroAssembler::sve_ld1h; break; case 4: insn = is_store ? &C2_MacroAssembler::sve_st1w : &C2_MacroAssembler::sve_ld1w; break; case 8: insn = is_store ? &C2_MacroAssembler::sve_st1d : &C2_MacroAssembler::sve_ld1d; break; default: assert(false, "unsupported"); ShouldNotReachHere(); } int imm4 = disp / mesize / Matcher::scalable_vector_reg_size(vector_elem_bt); (masm.*insn)(reg, Assembler::elemType_to_regVariant(vector_elem_bt), pg, Address(base, imm4)); } else { assert(false, "unimplemented"); ShouldNotReachHere(); } } bool op_sve_supported(int opcode, int vlen, BasicType bt) { int length_in_bytes = vlen * type2aelembytes(bt); switch (opcode) { case Op_MulAddVS2VI: // No multiply reduction instructions case Op_MulReductionVD: case Op_MulReductionVF: case Op_MulReductionVI: case Op_MulReductionVL: // Others case Op_ExtractC: case Op_ExtractUB: return false; // Vector API specific case Op_VectorLoadShuffle: case Op_VectorRearrange: return vlen >= 4 && length_in_bytes <= MaxVectorSize; case Op_LoadVector: case Op_StoreVector: return Matcher::vector_size_supported(bt, vlen); default: break; } // By default, we only support vector operations with no less than 8 bytes and 2 elements. return 8 <= length_in_bytes && length_in_bytes <= MaxVectorSize && vlen >= 2; } bool masked_op_sve_supported(int opcode, int vlen, BasicType bt) { if (opcode == Op_VectorRearrange) { return false; } return op_sve_supported(opcode, vlen, bt); } %} definitions %{ int_def SVE_COST (200, 200); %} // All SVE instructions // vector load/store // Unpredicated vector load/store instruct loadV(vReg dst, vmemA mem) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() >= 16 && n->as_LoadVector()->memory_size() == MaxVectorSize); match(Set dst (LoadVector mem)); ins_cost(4 * SVE_COST); format %{ "sve_ldr $dst, $mem\t# vector (sve)" %} ins_encode %{ FloatRegister dst_reg = as_FloatRegister($dst$$reg); BasicType bt = Matcher::vector_element_basic_type(this); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, dst_reg, ptrue, bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct storeV(vReg src, vmemA mem) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() >= 16 && n->as_StoreVector()->memory_size() == MaxVectorSize); match(Set mem (StoreVector mem src)); ins_cost(4 * SVE_COST); format %{ "sve_str $mem, $src\t# vector (sve)" %} ins_encode %{ FloatRegister src_reg = as_FloatRegister($src$$reg); BasicType bt = Matcher::vector_element_basic_type(this, $src); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, src_reg, ptrue, bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} // Load Vector (16 bits) instruct loadV2_vreg(vReg dst, vmem2 mem) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == 2); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrh $dst,$mem\t# vector (16 bits)" %} ins_encode( aarch64_enc_ldrvH(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Store Vector (16 bits) instruct storeV2_vreg(vReg src, vmem2 mem) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == 2); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strh $mem,$src\t# vector (16 bits)" %} ins_encode( aarch64_enc_strvH(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Load Vector (32 bits) instruct loadV4_vreg(vReg dst, vmem4 mem) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == 4); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrs $dst,$mem\t# vector (32 bits)" %} ins_encode( aarch64_enc_ldrvS(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Store Vector (32 bits) instruct storeV4_vreg(vReg src, vmem4 mem) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == 4); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strs $mem,$src\t# vector (32 bits)" %} ins_encode( aarch64_enc_strvS(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Load Vector (64 bits) instruct loadV8_vreg(vReg dst, vmem8 mem) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == 8); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrd $dst,$mem\t# vector (64 bits)" %} ins_encode( aarch64_enc_ldrvD(dst, mem) ); ins_pipe(vload_reg_mem64); %} // Store Vector (64 bits) instruct storeV8_vreg(vReg src, vmem8 mem) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == 8); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strd $mem,$src\t# vector (64 bits)" %} ins_encode( aarch64_enc_strvD(src, mem) ); ins_pipe(vstore_reg_mem64); %} // Load Vector (128 bits) instruct loadV16_vreg(vReg dst, vmem16 mem) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == 16); match(Set dst (LoadVector mem)); ins_cost(4 * INSN_COST); format %{ "ldrq $dst,$mem\t# vector (128 bits)" %} ins_encode( aarch64_enc_ldrvQ(dst, mem) ); ins_pipe(vload_reg_mem128); %} // Store Vector (128 bits) instruct storeV16_vreg(vReg src, vmem16 mem) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == 16); match(Set mem (StoreVector mem src)); ins_cost(4 * INSN_COST); format %{ "strq $mem,$src\t# vector (128 bits)" %} ins_encode( aarch64_enc_strvQ(src, mem) ); ins_pipe(vstore_reg_mem128); %} // Predicated vector load/store, based on the vector length of the node. // Only load/store values in the range of the memory_size. This is needed // when the memory_size is lower than the hardware supported max vector size. // And this might happen for Vector API mask vector load/store. instruct loadV_partial(vReg dst, vmemA mem, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() > 16 && n->as_LoadVector()->memory_size() < MaxVectorSize); match(Set dst (LoadVector mem)); effect(TEMP pgtmp, KILL cr); ins_cost(6 * SVE_COST); format %{ "sve_whilelo_zr_imm $pgtmp, vector_length\n\t" "sve_ldr $dst, $pgtmp, $mem\t# load vector partial" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); __ sve_whilelo_zr_imm(as_PRegister($pgtmp$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this)); FloatRegister dst_reg = as_FloatRegister($dst$$reg); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, dst_reg, as_PRegister($pgtmp$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct storeV_partial(vReg src, vmemA mem, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() > 16 && n->as_StoreVector()->memory_size() < MaxVectorSize); match(Set mem (StoreVector mem src)); effect(TEMP pgtmp, KILL cr); ins_cost(5 * SVE_COST); format %{ "sve_whilelo_zr_imm $pgtmp, vector_length\n\t" "sve_str $src, $pgtmp, $mem\t# store vector partial" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); __ sve_whilelo_zr_imm(as_PRegister($pgtmp$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this, $src)); FloatRegister src_reg = as_FloatRegister($src$$reg); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, src_reg, as_PRegister($pgtmp$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} // vector load/store - predicated instruct loadV_masked(vReg dst, vmemA mem, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == MaxVectorSize); match(Set dst (LoadVectorMasked mem pg)); ins_cost(4 * SVE_COST); format %{ "sve_ldr $dst, $pg, $mem\t# load vector predicated (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, as_FloatRegister($dst$$reg), as_PRegister($pg$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct loadV_masked_partial(vReg dst, vmemA mem, pRegGov pg, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() < MaxVectorSize); match(Set dst (LoadVectorMasked mem pg)); effect(TEMP pgtmp, KILL cr); ins_cost(6 * SVE_COST); format %{ "sve_ldr $dst, $pg, $mem\t# load vector predicated partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); __ sve_whilelo_zr_imm(as_PRegister($pgtmp$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this)); __ sve_and(as_PRegister($pgtmp$$reg), as_PRegister($pgtmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, as_FloatRegister($dst$$reg), as_PRegister($pgtmp$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct storeV_masked(vReg src, vmemA mem, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == MaxVectorSize); match(Set mem (StoreVectorMasked mem (Binary src pg))); ins_cost(4 * SVE_COST); format %{ "sve_str $mem, $pg, $src\t# store vector predicated (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, as_FloatRegister($src$$reg), as_PRegister($pg$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct storeV_masked_partial(vReg src, vmemA mem, pRegGov pg, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() < MaxVectorSize); match(Set mem (StoreVectorMasked mem (Binary src pg))); effect(TEMP pgtmp, KILL cr); ins_cost(6 * SVE_COST); format %{ "sve_str $mem, $pg, $src\t# store vector predicated partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); __ sve_whilelo_zr_imm(as_PRegister($pgtmp$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this, $src)); __ sve_and(as_PRegister($pgtmp$$reg), as_PRegister($pgtmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, as_FloatRegister($src$$reg), as_PRegister($pgtmp$$reg), bt, bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} // maskAll (full or partial predicate size) instruct vmaskAll_immI(pRegGov dst, immI src) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); ins_cost(SVE_COST); format %{ "sve_ptrue_lanecnt/sve_pfalse $dst\t# mask all (sve) (B/H/S)" %} ins_encode %{ int con = (int)$src$$constant; if (con == 0) { __ sve_pfalse(as_PRegister($dst$$reg)); } else { assert(con == -1, "invalid constant value for mask"); BasicType bt = Matcher::vector_element_basic_type(this); __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this)); } %} ins_pipe(pipe_slow); %} instruct vmaskAllI(pRegGov dst, iRegIorL2I src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); effect(TEMP tmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_dup $tmp, $src\n\t" "sve_ptrue_lanecnt $dst\n\t" "sve_cmpne $dst, $dst, $tmp, 0\t# mask all (sve) (B/H/S)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); uint length_in_bytes = Matcher::vector_length_in_bytes(this); __ sve_dup(as_FloatRegister($tmp$$reg), size, as_Register($src$$reg)); if (length_in_bytes < MaxVectorSize) { __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), size, Matcher::vector_length(this)); __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, as_PRegister($dst$$reg), as_FloatRegister($tmp$$reg), 0); } else { __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); } %} ins_pipe(pipe_slow); %} instruct vmaskAll_immL(pRegGov dst, immL src) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); ins_cost(SVE_COST); format %{ "sve_ptrue_lanecnt/sve_pfalse $dst\t# mask all (sve) (D)" %} ins_encode %{ long con = (long)$src$$constant; if (con == 0) { __ sve_pfalse(as_PRegister($dst$$reg)); } else { assert(con == -1, "invalid constant value for mask"); BasicType bt = Matcher::vector_element_basic_type(this); __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), __ elemType_to_regVariant(bt), Matcher::vector_length(this)); } %} ins_pipe(pipe_slow); %} instruct vmaskAllL(pRegGov dst, iRegL src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (MaskAll src)); effect(TEMP tmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_dup $tmp, $src\n\t" "sve_ptrue_lanecnt $dst\n\t" "sve_cmpne $dst, $dst, $tmp, 0\t# mask all (sve) (D)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); uint length_in_bytes = Matcher::vector_length_in_bytes(this); __ sve_dup(as_FloatRegister($tmp$$reg), size, as_Register($src$$reg)); if (length_in_bytes < MaxVectorSize) { __ sve_ptrue_lanecnt(as_PRegister($dst$$reg), size, Matcher::vector_length(this)); __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, as_PRegister($dst$$reg), as_FloatRegister($tmp$$reg), 0); } else { __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); } %} ins_pipe(pipe_slow); %} // mask logical and/or/xor instruct vmask_and(pRegGov pd, pRegGov pn, pRegGov pm) %{ predicate(UseSVE > 0); match(Set pd (AndVMask pn pm)); ins_cost(SVE_COST); format %{ "sve_and $pd, $pn, $pm\t# predicate (sve)" %} ins_encode %{ __ sve_and(as_PRegister($pd$$reg), ptrue, as_PRegister($pn$$reg), as_PRegister($pm$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_or(pRegGov pd, pRegGov pn, pRegGov pm) %{ predicate(UseSVE > 0); match(Set pd (OrVMask pn pm)); ins_cost(SVE_COST); format %{ "sve_orr $pd, $pn, $pm\t# predicate (sve)" %} ins_encode %{ __ sve_orr(as_PRegister($pd$$reg), ptrue, as_PRegister($pn$$reg), as_PRegister($pm$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_xor(pRegGov pd, pRegGov pn, pRegGov pm) %{ predicate(UseSVE > 0); match(Set pd (XorVMask pn pm)); ins_cost(SVE_COST); format %{ "sve_eor $pd, $pn, $pm\t# predicate (sve)" %} ins_encode %{ __ sve_eor(as_PRegister($pd$$reg), ptrue, as_PRegister($pn$$reg), as_PRegister($pm$$reg)); %} ins_pipe(pipe_slow); %} // mask logical and_not instruct vmask_and_notI(pRegGov pd, pRegGov pn, pRegGov pm, immI_M1 m1) %{ predicate(UseSVE > 0); match(Set pd (AndVMask pn (XorVMask pm (MaskAll m1)))); ins_cost(SVE_COST); format %{ "sve_bic $pd, $pn, $pm\t# predciate (sve) (B/H/S)" %} ins_encode %{ __ sve_bic(as_PRegister($pd$$reg), ptrue, as_PRegister($pn$$reg), as_PRegister($pm$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_and_notL(pRegGov pd, pRegGov pn, pRegGov pm, immL_M1 m1) %{ predicate(UseSVE > 0); match(Set pd (AndVMask pn (XorVMask pm (MaskAll m1)))); ins_cost(SVE_COST); format %{ "sve_bic $pd, $pn, $pm\t# predciate (sve) (D)" %} ins_encode %{ __ sve_bic(as_PRegister($pd$$reg), ptrue, as_PRegister($pn$$reg), as_PRegister($pm$$reg)); %} ins_pipe(pipe_slow); %} // vector reinterpret instruct reinterpret(vReg dst) %{ predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes()); // src == dst match(Set dst (VectorReinterpret dst)); ins_cost(0); format %{ "# reinterpret $dst\t# do nothing" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct reinterpretResize(vReg dst, vReg src, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() != n->in(1)->bottom_type()->is_vect()->length_in_bytes()); // src != dst match(Set dst (VectorReinterpret src)); effect(TEMP_DEF dst, TEMP pgtmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "reinterpretResize $dst, $src\t# vector (sve)" %} ins_encode %{ uint length_in_bytes_src = Matcher::vector_length_in_bytes(this, $src); uint length_in_bytes_dst = Matcher::vector_length_in_bytes(this); uint length_in_bytes_resize = length_in_bytes_src < length_in_bytes_dst ? length_in_bytes_src : length_in_bytes_dst; assert(length_in_bytes_src <= MaxVectorSize && length_in_bytes_dst <= MaxVectorSize, "invalid vector length"); __ sve_whilelo_zr_imm(as_PRegister($pgtmp$$reg), __ B, length_in_bytes_resize); __ sve_dup(as_FloatRegister($dst$$reg), __ B, 0); __ sve_sel(as_FloatRegister($dst$$reg), __ B, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), as_FloatRegister($dst$$reg)); %} ins_pipe(pipe_slow); %} // vector mask reinterpret instruct vmask_reinterpret_same_esize(pRegGov dst_src) %{ predicate(UseSVE > 0 && n->as_Vector()->length() == n->in(1)->bottom_type()->is_vect()->length() && n->as_Vector()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes()); match(Set dst_src (VectorReinterpret dst_src)); ins_cost(0); format %{ "# vmask_reinterpret $dst_src\t# do nothing" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct vmask_reinterpret_diff_esize(pRegGov dst, pRegGov src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length() != n->in(1)->bottom_type()->is_vect()->length() && n->as_Vector()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes()); match(Set dst (VectorReinterpret src)); effect(TEMP tmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "# vmask_reinterpret $dst, $src\t# vector (sve)" %} ins_encode %{ BasicType from_bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant from_size = __ elemType_to_regVariant(from_bt); BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_cpy(as_FloatRegister($tmp$$reg), from_size, as_PRegister($src$$reg), -1, false); __ sve_cmp(Assembler::EQ, as_PRegister($dst$$reg), to_size, ptrue, as_FloatRegister($tmp$$reg), -1); %} ins_pipe(pipe_slow); %} // vector abs instruct vabsB(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVB src)); ins_cost(SVE_COST); format %{ "sve_abs $dst, $src\t# vector (sve) (B)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst$$reg), __ B, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsS(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVS src)); ins_cost(SVE_COST); format %{ "sve_abs $dst, $src\t# vector (sve) (H)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst$$reg), __ H, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsI(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVI src)); ins_cost(SVE_COST); format %{ "sve_abs $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsL(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVL src)); ins_cost(SVE_COST); format %{ "sve_abs $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsF(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVF src)); ins_cost(SVE_COST); format %{ "sve_fabs $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fabs(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (AbsVD src)); ins_cost(SVE_COST); format %{ "sve_fabs $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fabs(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector abs - predicated instruct vabsB_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVB dst_src pg)); ins_cost(SVE_COST); format %{ "sve_abs $dst_src, $pg, $dst_src\t# vector (sve) (B)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst_src$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsS_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVS dst_src pg)); ins_cost(SVE_COST); format %{ "sve_abs $dst_src, $pg, $dst_src\t# vector (sve) (H)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst_src$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsI_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVI dst_src pg)); ins_cost(SVE_COST); format %{ "sve_abs $dst_src, $pg, $dst_src\t# vector (sve) (S)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsL_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVL dst_src pg)); ins_cost(SVE_COST); format %{ "sve_abs $dst_src, $pg, $dst_src\t# vector (sve) (D)" %} ins_encode %{ __ sve_abs(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsF_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVF dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fabs $dst_src, $pg, $dst_src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fabs(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vabsD_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (AbsVD dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fabs $dst_src, $pg, $dst_src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fabs(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} // vector add instruct vaddB(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVB src1 src2)); ins_cost(SVE_COST); format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (B)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddS(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVS src1 src2)); ins_cost(SVE_COST); format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (H)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddI(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVI src1 src2)); ins_cost(SVE_COST); format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddL(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVL src1 src2)); ins_cost(SVE_COST); format %{ "sve_add $dst, $src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddF(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVF src1 src2)); ins_cost(SVE_COST); format %{ "sve_fadd $dst, $src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_fadd(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddD(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AddVD src1 src2)); ins_cost(SVE_COST); format %{ "sve_fadd $dst, $src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_fadd(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector add - predicated instruct vaddB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_add $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_add $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_add $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_add $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_add(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddF_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVF (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fadd $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fadd(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vaddD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVD (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fadd $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fadd(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector add reg imm (unpredicated) instruct vaddImmB(vReg dst_src, immBAddSubV con) %{ predicate(UseSVE > 0); match(Set dst_src (AddVB dst_src (ReplicateB con))); ins_cost(SVE_COST); format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (B)" %} ins_encode %{ int32_t val = $con$$constant; if (val > 0){ __ sve_add(as_FloatRegister($dst_src$$reg), __ B, val); } else if (val < 0){ __ sve_sub(as_FloatRegister($dst_src$$reg), __ B, -val); } %} ins_pipe(pipe_slow); %} instruct vaddImmS(vReg dst_src, immIAddSubV con) %{ predicate(UseSVE > 0); match(Set dst_src (AddVS dst_src (ReplicateS con))); ins_cost(SVE_COST); format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (H)" %} ins_encode %{ int32_t val = $con$$constant; if (val > 0){ __ sve_add(as_FloatRegister($dst_src$$reg), __ H, val); } else if (val < 0){ __ sve_sub(as_FloatRegister($dst_src$$reg), __ H, -val); } %} ins_pipe(pipe_slow); %} instruct vaddImmI(vReg dst_src, immIAddSubV con) %{ predicate(UseSVE > 0); match(Set dst_src (AddVI dst_src (ReplicateI con))); ins_cost(SVE_COST); format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (S)" %} ins_encode %{ int32_t val = $con$$constant; if (val > 0){ __ sve_add(as_FloatRegister($dst_src$$reg), __ S, val); } else if (val < 0){ __ sve_sub(as_FloatRegister($dst_src$$reg), __ S, -val); } %} ins_pipe(pipe_slow); %} instruct vaddImmL(vReg dst_src, immLAddSubV con) %{ predicate(UseSVE > 0); match(Set dst_src (AddVL dst_src (ReplicateL con))); ins_cost(SVE_COST); format %{ "sve_add $dst_src, $dst_src, $con\t # vector (sve) (D)" %} ins_encode %{ int32_t val = $con$$constant; if (val > 0){ __ sve_add(as_FloatRegister($dst_src$$reg), __ D, val); } else if (val < 0){ __ sve_sub(as_FloatRegister($dst_src$$reg), __ D, -val); } %} ins_pipe(pipe_slow); %} // vector binary op reg imm (unpredicated) instruct vandB(vReg dst_src, immBLog con) %{ predicate(UseSVE > 0); match(Set dst_src (AndV dst_src (ReplicateB con))); ins_cost(SVE_COST); format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (B)" %} ins_encode %{ __ sve_and(as_FloatRegister($dst_src$$reg), __ B, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vandH(vReg dst_src, immSLog con) %{ predicate(UseSVE > 0); match(Set dst_src (AndV dst_src (ReplicateS con))); ins_cost(SVE_COST); format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (H)" %} ins_encode %{ __ sve_and(as_FloatRegister($dst_src$$reg), __ H, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vandS(vReg dst_src, immILog con) %{ predicate(UseSVE > 0); match(Set dst_src (AndV dst_src (ReplicateI con))); ins_cost(SVE_COST); format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (S)" %} ins_encode %{ __ sve_and(as_FloatRegister($dst_src$$reg), __ S, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vandD(vReg dst_src, immLLog con) %{ predicate(UseSVE > 0); match(Set dst_src (AndV dst_src (ReplicateL con))); ins_cost(SVE_COST); format %{ "sve_and $dst_src, $dst_src, $con\t # vector (sve) (D)" %} ins_encode %{ __ sve_and(as_FloatRegister($dst_src$$reg), __ D, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vorB(vReg dst_src, immBLog con) %{ predicate(UseSVE > 0); match(Set dst_src (OrV dst_src (ReplicateB con))); ins_cost(SVE_COST); format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (B)" %} ins_encode %{ __ sve_orr(as_FloatRegister($dst_src$$reg), __ B, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vorH(vReg dst_src, immSLog con) %{ predicate(UseSVE > 0); match(Set dst_src (OrV dst_src (ReplicateS con))); ins_cost(SVE_COST); format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (H)" %} ins_encode %{ __ sve_orr(as_FloatRegister($dst_src$$reg), __ H, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vorS(vReg dst_src, immILog con) %{ predicate(UseSVE > 0); match(Set dst_src (OrV dst_src (ReplicateI con))); ins_cost(SVE_COST); format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (S)" %} ins_encode %{ __ sve_orr(as_FloatRegister($dst_src$$reg), __ S, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vorD(vReg dst_src, immLLog con) %{ predicate(UseSVE > 0); match(Set dst_src (OrV dst_src (ReplicateL con))); ins_cost(SVE_COST); format %{ "sve_orr $dst_src, $dst_src, $con\t # vector (sve) (D)" %} ins_encode %{ __ sve_orr(as_FloatRegister($dst_src$$reg), __ D, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vxorB(vReg dst_src, immBLog con) %{ predicate(UseSVE > 0); match(Set dst_src (XorV dst_src (ReplicateB con))); ins_cost(SVE_COST); format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (B)" %} ins_encode %{ __ sve_eor(as_FloatRegister($dst_src$$reg), __ B, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vxorH(vReg dst_src, immSLog con) %{ predicate(UseSVE > 0); match(Set dst_src (XorV dst_src (ReplicateS con))); ins_cost(SVE_COST); format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (H)" %} ins_encode %{ __ sve_eor(as_FloatRegister($dst_src$$reg), __ H, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vxorS(vReg dst_src, immILog con) %{ predicate(UseSVE > 0); match(Set dst_src (XorV dst_src (ReplicateI con))); ins_cost(SVE_COST); format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (S)" %} ins_encode %{ __ sve_eor(as_FloatRegister($dst_src$$reg), __ S, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} instruct vxorD(vReg dst_src, immLLog con) %{ predicate(UseSVE > 0); match(Set dst_src (XorV dst_src (ReplicateL con))); ins_cost(SVE_COST); format %{ "sve_eor $dst_src, $dst_src, $con\t # vector (sve) (D)" %} ins_encode %{ __ sve_eor(as_FloatRegister($dst_src$$reg), __ D, (uint64_t)($con$$constant)); %} ins_pipe(pipe_slow); %} // vector and instruct vand(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (AndV src1 src2)); ins_cost(SVE_COST); format %{ "sve_and $dst, $src1, $src2\t# vector (sve)" %} ins_encode %{ __ sve_and(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector or instruct vor(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (OrV src1 src2)); ins_cost(SVE_COST); format %{ "sve_orr $dst, $src1, $src2\t# vector (sve)" %} ins_encode %{ __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector xor instruct vxor(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (XorV src1 src2)); ins_cost(SVE_COST); format %{ "sve_eor $dst, $src1, $src2\t# vector (sve)" %} ins_encode %{ __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector and - predicated instruct vand_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (AndV (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_and $dst_src1, $pg, $dst_src1, $src2\t # vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_and(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector or - predicated instruct vor_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (OrV (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_orr $dst_src1, $pg, $dst_src1, $src2\t # vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_orr(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector xor - predicated instruct vxor_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (XorV (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_eor $dst_src1, $pg, $dst_src1, $src2\t # vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_eor(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector not instruct vnotI(vReg dst, vReg src, immI_M1 m1) %{ predicate(UseSVE > 0); match(Set dst (XorV src (ReplicateB m1))); match(Set dst (XorV src (ReplicateS m1))); match(Set dst (XorV src (ReplicateI m1))); ins_cost(SVE_COST); format %{ "sve_not $dst, $src\t# vector (sve) B/H/S" %} ins_encode %{ __ sve_not(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vnotL(vReg dst, vReg src, immL_M1 m1) %{ predicate(UseSVE > 0); match(Set dst (XorV src (ReplicateL m1))); ins_cost(SVE_COST); format %{ "sve_not $dst, $src\t# vector (sve) D" %} ins_encode %{ __ sve_not(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector and_not instruct vand_notI(vReg dst, vReg src1, vReg src2, immI_M1 m1) %{ predicate(UseSVE > 0); match(Set dst (AndV src1 (XorV src2 (ReplicateB m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateS m1)))); match(Set dst (AndV src1 (XorV src2 (ReplicateI m1)))); ins_cost(SVE_COST); format %{ "sve_bic $dst, $src1, $src2\t# vector (sve) B/H/S" %} ins_encode %{ __ sve_bic(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vand_notL(vReg dst, vReg src1, vReg src2, immL_M1 m1) %{ predicate(UseSVE > 0); match(Set dst (AndV src1 (XorV src2 (ReplicateL m1)))); ins_cost(SVE_COST); format %{ "sve_bic $dst, $src1, $src2\t# vector (sve) D" %} ins_encode %{ __ sve_bic(as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector float div instruct vdivF(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (DivVF dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_fdiv $dst_src1, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vdivD(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (DivVD dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_fdiv $dst_src1, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector float div - predicated instruct vfdivF_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (DivVF (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fdiv $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vfdivD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (DivVD (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fdiv $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fdiv(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector min/max instruct vmin(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MinV dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_min $dst_src1, $dst_src1, $src2\t # vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); if (is_floating_point_type(bt)) { __ sve_fmin(as_FloatRegister($dst_src1$$reg), size, ptrue, as_FloatRegister($src2$$reg)); } else { assert(is_integral_type(bt), "unsupported type"); __ sve_smin(as_FloatRegister($dst_src1$$reg), size, ptrue, as_FloatRegister($src2$$reg)); } %} ins_pipe(pipe_slow); %} instruct vmax(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MaxV dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_max $dst_src1, $dst_src1, $src2\t # vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); if (is_floating_point_type(bt)) { __ sve_fmax(as_FloatRegister($dst_src1$$reg), size, ptrue, as_FloatRegister($src2$$reg)); } else { assert(is_integral_type(bt), "unsupported type"); __ sve_smax(as_FloatRegister($dst_src1$$reg), size, ptrue, as_FloatRegister($src2$$reg)); } %} ins_pipe(pipe_slow); %} // vector min/max - predicated instruct vmin_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MinV (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_min $dst_src1, $pg, $dst_src1, $src2\t# vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); if (is_floating_point_type(bt)) { __ sve_fmin(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); } else { assert(is_integral_type(bt), "unsupported type"); __ sve_smin(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); } %} ins_pipe(pipe_slow); %} instruct vmax_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MaxV (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_max $dst_src1, $pg, $dst_src1, $src2\t# vector (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); if (is_floating_point_type(bt)) { __ sve_fmax(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); } else { assert(is_integral_type(bt), "unsupported type"); __ sve_smax(as_FloatRegister($dst_src1$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); } %} ins_pipe(pipe_slow); %} // vector fmla // dst_src1 = dst_src1 + src2 * src3 instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVF dst_src1 (Binary src2 src3))); ins_cost(SVE_COST); format %{ "sve_fmla $dst_src1, $src2, $src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_fmla(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 + src2 * src3 instruct vfmlaD(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVD dst_src1 (Binary src2 src3))); ins_cost(SVE_COST); format %{ "sve_fmla $dst_src1, $src2, $src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_fmla(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector fmla - predicated // dst_src1 = dst_src1 * src2 + src3 instruct vfmlaF_masked(vReg dst_src1, vReg src2, vReg src3, pRegGov pg) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVF (Binary dst_src1 src2) (Binary src3 pg))); ins_cost(SVE_COST); format %{ "sve_fmad $dst_src1, $pg, $src2, $src3\t# vector (sve) (S)" %} ins_encode %{ __ sve_fmad(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 * src2 + src3 instruct vfmlaD_masked(vReg dst_src1, vReg src2, vReg src3, pRegGov pg) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVD (Binary dst_src1 src2) (Binary src3 pg))); ins_cost(SVE_COST); format %{ "sve_fmad $dst_src1, $pg, $src2, $src3\t# vector (sve) (D)" %} ins_encode %{ __ sve_fmad(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector fmls // dst_src1 = dst_src1 + -src2 * src3 // dst_src1 = dst_src1 + src2 * -src3 instruct vfmlsF(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVF dst_src1 (Binary (NegVF src2) src3))); match(Set dst_src1 (FmaVF dst_src1 (Binary src2 (NegVF src3)))); ins_cost(SVE_COST); format %{ "sve_fmls $dst_src1, $src2, $src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_fmls(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 + -src2 * src3 // dst_src1 = dst_src1 + src2 * -src3 instruct vfmlsD(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVD dst_src1 (Binary (NegVD src2) src3))); match(Set dst_src1 (FmaVD dst_src1 (Binary src2 (NegVD src3)))); ins_cost(SVE_COST); format %{ "sve_fmls $dst_src1, $src2, $src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_fmls(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector fnmla // dst_src1 = -dst_src1 + -src2 * src3 // dst_src1 = -dst_src1 + src2 * -src3 instruct vfnmlaF(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary (NegVF src2) src3))); match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 (NegVF src3)))); ins_cost(SVE_COST); format %{ "sve_fnmla $dst_src1, $src2, $src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_fnmla(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = -dst_src1 + -src2 * src3 // dst_src1 = -dst_src1 + src2 * -src3 instruct vfnmlaD(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary (NegVD src2) src3))); match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 (NegVD src3)))); ins_cost(SVE_COST); format %{ "sve_fnmla $dst_src1, $src2, $src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_fnmla(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector fnmls // dst_src1 = -dst_src1 + src2 * src3 instruct vfnmlsF(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVF (NegVF dst_src1) (Binary src2 src3))); ins_cost(SVE_COST); format %{ "sve_fnmls $dst_src1, $src2, $src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_fnmls(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = -dst_src1 + src2 * src3 instruct vfnmlsD(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseFMA && UseSVE > 0); match(Set dst_src1 (FmaVD (NegVD dst_src1) (Binary src2 src3))); ins_cost(SVE_COST); format %{ "sve_fnmls $dst_src1, $src2, $src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_fnmls(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector mla // dst_src1 = dst_src1 + src2 * src3 instruct vmlaB(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVB dst_src1 (MulVB src2 src3))); ins_cost(SVE_COST); format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (B)" %} ins_encode %{ __ sve_mla(as_FloatRegister($dst_src1$$reg), __ B, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 + src2 * src3 instruct vmlaS(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVS dst_src1 (MulVS src2 src3))); ins_cost(SVE_COST); format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (H)" %} ins_encode %{ __ sve_mla(as_FloatRegister($dst_src1$$reg), __ H, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 + src2 * src3 instruct vmlaI(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVI dst_src1 (MulVI src2 src3))); ins_cost(SVE_COST); format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_mla(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 + src2 * src3 instruct vmlaL(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (AddVL dst_src1 (MulVL src2 src3))); ins_cost(SVE_COST); format %{ "sve_mla $dst_src1, src2, src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_mla(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector mls // dst_src1 = dst_src1 - src2 * src3 instruct vmlsB(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVB dst_src1 (MulVB src2 src3))); ins_cost(SVE_COST); format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (B)" %} ins_encode %{ __ sve_mls(as_FloatRegister($dst_src1$$reg), __ B, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 - src2 * src3 instruct vmlsS(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVS dst_src1 (MulVS src2 src3))); ins_cost(SVE_COST); format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (H)" %} ins_encode %{ __ sve_mls(as_FloatRegister($dst_src1$$reg), __ H, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 - src2 * src3 instruct vmlsI(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVI dst_src1 (MulVI src2 src3))); ins_cost(SVE_COST); format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (S)" %} ins_encode %{ __ sve_mls(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // dst_src1 = dst_src1 - src2 * src3 instruct vmlsL(vReg dst_src1, vReg src2, vReg src3) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVL dst_src1 (MulVL src2 src3))); ins_cost(SVE_COST); format %{ "sve_mls $dst_src1, src2, src3\t # vector (sve) (D)" %} ins_encode %{ __ sve_mls(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg), as_FloatRegister($src3$$reg)); %} ins_pipe(pipe_slow); %} // vector mul instruct vmulB(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVB dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (B)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ B, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulS(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVS dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (H)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ H, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulI(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVI dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ S, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulL(vReg dst_src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVL dst_src1 src2)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $dst_src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ D, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulF(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (MulVF src1 src2)); ins_cost(SVE_COST); format %{ "sve_fmul $dst, $src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_fmul(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulD(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (MulVD src1 src2)); ins_cost(SVE_COST); format %{ "sve_fmul $dst, $src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_fmul(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector mul - predicated instruct vmulB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_mul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_mul(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulF_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVF (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fmul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fmul(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmulD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (MulVD (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fmul $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fmul(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector fneg instruct vnegF(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (NegVF src)); ins_cost(SVE_COST); format %{ "sve_fneg $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fneg(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vnegD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (NegVD src)); ins_cost(SVE_COST); format %{ "sve_fneg $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fneg(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector fneg - predicated instruct vnegF_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (NegVF dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fneg $dst_src, $pg, $dst_src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fneg(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vnegD_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (NegVD dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fneg $dst_src, $pg, $dst_src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fneg(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} // popcount vector instruct vpopcountI(vReg dst, vReg src) %{ predicate(UseSVE > 0); match(Set dst (PopCountVI src)); format %{ "sve_cnt $dst, $src\t# vector (sve) (S)\n\t" %} ins_encode %{ __ sve_cnt(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector mask compare instruct vmaskcmp(pRegGov dst, vReg src1, vReg src2, immI cond, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (VectorMaskCmp (Binary src1 src2) cond)); effect(KILL cr); ins_cost(SVE_COST); format %{ "sve_cmp $dst, $src1, $src2\t# vector mask cmp (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); __ sve_compare(as_PRegister($dst$$reg), bt, ptrue, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), (int)$cond$$constant); %} ins_pipe(pipe_slow); %} instruct vmaskcmp_masked(pRegGov dst, vReg src1, vReg src2, immI cond, pRegGov pg, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (VectorMaskCmp (Binary src1 src2) (Binary cond pg))); effect(KILL cr); ins_cost(SVE_COST); format %{ "sve_cmp $dst, $pg, $src1, $src2\t# vector mask cmp (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); __ sve_compare(as_PRegister($dst$$reg), bt, as_PRegister($pg$$reg), as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg), (int)$cond$$constant); %} ins_pipe(pipe_slow); %} // vector blend instruct vblend(vReg dst, vReg src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst (VectorBlend (Binary src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_sel $dst, $pg, $src2, $src1\t# vector blend (sve)" %} ins_encode %{ Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(Matcher::vector_element_basic_type(this)); __ sve_sel(as_FloatRegister($dst$$reg), size, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} // vector load mask instruct vloadmaskB(pRegGov dst, vReg src, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadMask src)); effect(KILL cr); ins_cost(SVE_COST); format %{ "vloadmaskB $dst, $src\t# vector load mask (sve) (B)" %} ins_encode %{ __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), __ B, ptrue, as_FloatRegister($src$$reg), 0); %} ins_pipe(pipe_slow); %} instruct vloadmask_extend(pRegGov dst, vReg src, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() != T_BYTE); match(Set dst (VectorLoadMask src)); effect(TEMP tmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "vloadmask $dst, $src\t# vector load mask (sve) (H/S/D)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_vector_extend(as_FloatRegister($tmp$$reg), size, as_FloatRegister($src$$reg), __ B); __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($tmp$$reg), 0); %} ins_pipe(pipe_slow); %} // vector store mask instruct vstoremaskB(vReg dst, pRegGov src, immI_1 size) %{ predicate(UseSVE > 0); match(Set dst (VectorStoreMask src size)); ins_cost(SVE_COST); format %{ "vstoremask $dst, $src\t# vector store mask (sve) (B)" %} ins_encode %{ __ sve_cpy(as_FloatRegister($dst$$reg), __ B, as_PRegister($src$$reg), 1, false); %} ins_pipe(pipe_slow); %} instruct vstoremask_narrow(vReg dst, pRegGov src, vReg tmp, immI_gt_1 size) %{ predicate(UseSVE > 0); match(Set dst (VectorStoreMask src size)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "vstoremask $dst, $src\t# vector store mask (sve) (H/S/D)" %} ins_encode %{ Assembler::SIMD_RegVariant size = __ elemBytes_to_regVariant((int)$size$$constant); __ sve_cpy(as_FloatRegister($dst$$reg), size, as_PRegister($src$$reg), 1, false); __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($dst$$reg), size, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} // Combine LoadVector+VectorLoadMask when the vector element type is not T_BYTE instruct vloadmask_loadV(pRegGov dst, indirect mem, vReg tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() == MaxVectorSize && type2aelembytes(n->bottom_type()->is_vect()->element_basic_type()) > 1); match(Set dst (VectorLoadMask (LoadVector mem))); effect(TEMP tmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_ld1b $tmp, $mem\n\t" "sve_cmpne $dst, $tmp, 0\t# load vector mask (sve) (H/S/D)" %} ins_encode %{ // Load mask values which are boolean type, and extend them to the // expected vector element type. Convert the vector to predicate. BasicType to_vect_bt = Matcher::vector_element_basic_type(this); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, as_FloatRegister($tmp$$reg), ptrue, T_BOOLEAN, to_vect_bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), __ elemType_to_regVariant(to_vect_bt), ptrue, as_FloatRegister($tmp$$reg), 0); %} ins_pipe(pipe_slow); %} instruct vloadmask_loadV_partial(pRegGov dst, indirect mem, vReg vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() > 16 && n->as_Vector()->length_in_bytes() < MaxVectorSize && type2aelembytes(n->bottom_type()->is_vect()->element_basic_type()) > 1); match(Set dst (VectorLoadMask (LoadVector mem))); effect(TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(6 * SVE_COST); format %{ "vloadmask_loadV $dst, $mem\t# load vector mask partial (sve) (H/S/D)" %} ins_encode %{ // Load valid mask values which are boolean type, and extend them to the // expected vector element type. Convert the vector to predicate. BasicType to_vect_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(to_vect_bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this)); loadStoreA_predicated(C2_MacroAssembler(&cbuf), false, as_FloatRegister($vtmp$$reg), as_PRegister($ptmp$$reg), T_BOOLEAN, to_vect_bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); __ sve_cmp(Assembler::NE, as_PRegister($dst$$reg), size, ptrue, as_FloatRegister($vtmp$$reg), 0); %} ins_pipe(pipe_slow); %} // Combine VectorStoreMask+StoreVector when the vector element type is not T_BYTE instruct storeV_vstoremask(indirect mem, pRegGov src, vReg tmp, immI_gt_1 esize) %{ predicate(UseSVE > 0 && Matcher::vector_length_in_bytes(n->as_StoreVector()->in(MemNode::ValueIn)->in(1)) == MaxVectorSize); match(Set mem (StoreVector mem (VectorStoreMask src esize))); effect(TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_cpy $tmp, $src, 1\n\t" "sve_st1b $tmp, $mem\t# store vector mask (sve) (H/S/D)" %} ins_encode %{ BasicType from_vect_bt = Matcher::vector_element_basic_type(this, $src); assert(type2aelembytes(from_vect_bt) == (int)$esize$$constant, "unsupported type."); Assembler::SIMD_RegVariant size = __ elemBytes_to_regVariant($esize$$constant); __ sve_cpy(as_FloatRegister($tmp$$reg), size, as_PRegister($src$$reg), 1, false); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, as_FloatRegister($tmp$$reg), ptrue, T_BOOLEAN, from_vect_bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} instruct storeV_vstoremask_partial(indirect mem, pRegGov src, vReg vtmp, immI_gt_1 esize, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() > 16 && type2aelembytes(n->as_StoreVector()->vect_type()->element_basic_type()) > 1 && Matcher::vector_length_in_bytes(n->as_StoreVector()->in(MemNode::ValueIn)->in(1)) < MaxVectorSize); match(Set mem (StoreVector mem (VectorStoreMask src esize))); effect(TEMP vtmp, TEMP ptmp, KILL cr); format %{ "storeV_vstoremask $src, $mem\t# store vector mask partial (sve) (H/S/D)" %} ins_cost(6 * SVE_COST); ins_encode %{ // Convert the valid src predicate to vector, and store the vector // elements as boolean values. BasicType from_vect_bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(from_vect_bt); __ sve_cpy(as_FloatRegister($vtmp$$reg), size, as_PRegister($src$$reg), 1, false); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this, $src)); loadStoreA_predicated(C2_MacroAssembler(&cbuf), true, as_FloatRegister($vtmp$$reg), as_PRegister($ptmp$$reg), T_BOOLEAN, from_vect_bt, $mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp); %} ins_pipe(pipe_slow); %} // vector add reduction instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AddReductionVI src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_addI $dst, $src1, $src2\t# addI reduction (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AddReductionVL src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_addL $dst, $src1, $src2\t# addL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addF(vRegF src1_dst, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set src1_dst (AddReductionVF src1_dst src2)); ins_cost(SVE_COST); format %{ "sve_fadda $src1_dst, $src1_dst, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ S, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addD(vRegD src1_dst, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set src1_dst (AddReductionVD src1_dst src2)); ins_cost(SVE_COST); format %{ "sve_fadda $src1_dst, $src1_dst, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ D, ptrue, as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AddReductionVI src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_addI $dst, $src1, $src2\t# addI reduction partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AddReductionVL src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_addL $dst, $src1, $src2\t# addL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addF_partial(vRegF src1_dst, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set src1_dst (AddReductionVF src1_dst src2)); ins_cost(SVE_COST); effect(TEMP ptmp, KILL cr); format %{ "sve_reduce_addF $src1_dst, $src1_dst, $src2\t# addF reduction partial (sve) (S)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addD_partial(vRegD src1_dst, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set src1_dst (AddReductionVD src1_dst src2)); ins_cost(SVE_COST); effect(TEMP ptmp, KILL cr); format %{ "sve_reduce_addD $src1_dst, $src1_dst, $src2\t# addD reduction partial (sve) (D)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector add reduction - predicated instruct reduce_addI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AddReductionVI (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_addI $dst, $src1, $pg, $src2\t# addI reduction predicated (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AddReductionVL (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_addL $dst, $src1, $pg, $src2\t# addL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addF_masked(vRegF src1_dst, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set src1_dst (AddReductionVF (Binary src1_dst src2) pg)); ins_cost(SVE_COST); format %{ "sve_reduce_addF $src1_dst, $pg, $src2\t# addF reduction predicated (sve)" %} ins_encode %{ __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addD_masked(vRegD src1_dst, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set src1_dst (AddReductionVD (Binary src1_dst src2) pg)); ins_cost(SVE_COST); format %{ "sve_reduce_addD $src1_dst, $pg, $src2\t# addD reduction predicated (sve)" %} ins_encode %{ __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AddReductionVI (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_addI $dst, $src1, $pg, $src2\t# addI reduction predicated partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AddReductionVL (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_addL $dst, $src1, $pg, $src2\t# addL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addF_masked_partial(vRegF src1_dst, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set src1_dst (AddReductionVF (Binary src1_dst src2) pg)); effect(TEMP ptmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_addF $src1_dst, $pg, $src2\t# addF reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_addD_masked_partial(vRegD src1_dst, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set src1_dst (AddReductionVD (Binary src1_dst src2) pg)); effect(TEMP ptmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_addD $src1_dst, $pg, $src2\t# addD reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fadda(as_FloatRegister($src1_dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector and reduction instruct reduce_andI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AndReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_andI $dst, $src1, $src2\t# andI reduction (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AndReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_andL $dst, $src1, $src2\t# andL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AndReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_andI $dst, $src1, $src2\t# andI reduction partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AndReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_andL $dst, $src1, $src2\t# andL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector and reduction - predicated instruct reduce_andI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AndReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_andI $dst, $src1, $pg, $src2\t# andI reduction predicated (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (AndReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_andL $dst, $src1, $pg, $src2\t# andL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AndReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_andI $dst, $src1, $pg, $src2\t# andI reduction predicated partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_andL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (AndReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_andL $dst, $src1, $pg, $src2\t# andL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector or reduction instruct reduce_orI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (OrReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_orI $dst, $src1, $src2\t# orI reduction (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (OrReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_orL $dst, $src1, $src2\t# orL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (OrReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_orI $dst, $src1, $src2\t# orI reduction partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (OrReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_orL $dst, $src1, $src2\t# orL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector or reduction - predicated instruct reduce_orI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (OrReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_orI $dst, $src1, $pg, $src2\t# orI reduction predicated (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (OrReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_orL $dst, $src1, $pg, $src2\t# orL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (OrReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_orI $dst, $src1, $pg, $src2\t# orI reduction predicated partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_orL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (OrReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_orL $dst, $src1, $pg, $src2\t# orL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector xor reduction instruct reduce_eorI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (XorReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_eorI $dst, $src1, $src2\t# eorI reduction (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (XorReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_eorL $dst, $src1, $src2\t# eorL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (XorReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_eorI $dst, $src1, $src2\t# eorI reduction partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (XorReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_eorL $dst, $src1, $src2\t# eorL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector xor reduction - predicated instruct reduce_eorI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (XorReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_eorI $dst, $src1, $pg, $src2\t# eorI reduction predicated (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (XorReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(SVE_COST); format %{ "sve_reduce_eorL $dst, $src1, $pg, $src2\t# eorL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (XorReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_eorI $dst, $src1, $pg, $src2\t# eorI reduction predicated partial (sve) (may extend)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_eorL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (XorReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_eorL $dst, $src1, $pg, $src2\t# eorL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} // vector max reduction instruct reduce_maxI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MaxReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_maxI $dst, $src1, $src2\t# maxI reduction (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_maxL $dst, $src1, $src2\t# maxL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MaxReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_maxI $dst, $src1, $src2\t# maxI reduction partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_maxL $dst, $src1, $src2\t# maxL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxF(vRegF dst, vRegF src1, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_maxF $dst, $src1, $src2\t# maxF reduction (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src2$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxF_partial(vRegF dst, vRegF src1, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MaxReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); format %{ "sve_reduce_maxF $dst, $src1, $src2\t# maxF reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxD(vRegD dst, vRegD src1, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_maxD $dst, $src1, $src2\t# maxD reduction (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src2$$reg)); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxD_partial(vRegD dst, vRegD src1, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MaxReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); format %{ "sve_reduce_maxD $dst, $src1, $src2\t# maxD reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} // vector max reduction - predicated instruct reduce_maxI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_maxI $dst, $src1, $pg, $src2\t# maxI reduction predicated (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_maxL $dst, $src1, $pg, $src2\t# maxL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_maxI $dst, $src1, $pg, $src2\t# maxI reduction predicated partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_maxL $dst, $src1, $pg, $src2\t# maxL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxF_masked(vRegF dst, vRegF src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_maxF $dst, $src1, $pg, $src2\t# maxF reduction predicated (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxD_masked(vRegD dst, vRegD src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_maxD $dst, $src1, $pg, $src2\t# maxD reduction predicated (sve)" %} ins_encode %{ __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxF_masked_partial(vRegF dst, vRegF src1, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_maxF $dst, $src1, $pg, $src2\t# maxF reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fmaxv(as_FloatRegister($dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmaxs(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_maxD_masked_partial(vRegD dst, vRegD src1, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MaxReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_maxD $dst, $src1, $pg, $src2\t# maxD reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fmaxv(as_FloatRegister($dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmaxd(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} // vector min reduction instruct reduce_minI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MinReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_minI $dst, $src1, $src2\t# minI reduction (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minL(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinReductionV src1 src2)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_minL $dst, $src1, $src2\t# minL reduction (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), ptrue, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minI_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MinReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_minI $dst, $src1, $src2\t# minI reduction partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minL_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinReductionV src1 src2)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_reduce_minL $dst, $src1, $src2\t# minL reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minF(vRegF dst, vRegF src1, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_minF $dst, $src1, $src2\t# minF reduction (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src2$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minF_partial(vRegF dst, vRegF src1, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MinReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); format %{ "sve_reduce_minF $dst, $src1, $src2\t# minF reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_fminv(as_FloatRegister($dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minD(vRegD dst, vRegD src1, vReg src2) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_minD $dst, $src1, $src2\t# minD reduction (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src2$$reg)); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minD_partial(vRegD dst, vRegD src1, vReg src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MinReductionV src1 src2)); ins_cost(INSN_COST); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); format %{ "sve_reduce_minD $dst, $src1, $src2\t# minD reduction partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_fminv(as_FloatRegister($dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} // vector min reduction - predicated instruct reduce_minI_masked(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp, pRegGov pg, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_minI $dst, $src1, $pg, $src2\t# minI reduction predicated (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minL_masked(iRegLNoSp dst, iRegL src1, vReg src2, vRegD tmp, pRegGov pg, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP tmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_reduce_minL $dst, $src1, $pg, $src2\t# minL reduction predicated (sve)" %} ins_encode %{ __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($pg$$reg), as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minI_masked_partial(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() != T_LONG && is_integral_type(n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type())); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_minI $dst, $src1, $pg, $src2\t# minI reduction predicated partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src2); Assembler::SIMD_RegVariant variant = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), variant, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, bt, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minL_masked_partial(iRegLNoSp dst, iRegL src1, vReg src2, vRegD vtmp, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP vtmp, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_minL $dst, $src1, $pg, $src2\t# minL reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_reduce_integral(this->ideal_Opcode(), $dst$$Register, T_LONG, $src1$$Register, as_FloatRegister($src2$$reg), as_PRegister($ptmp$$reg), as_FloatRegister($vtmp$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minF_masked(vRegF dst, vRegF src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_minF $dst, $src1, $pg, $src2\t# minF reduction predicated (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minD_masked(vRegD dst, vRegD src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); ins_cost(SVE_COST); effect(TEMP_DEF dst); format %{ "sve_reduce_minD $dst, $src1, $pg, $src2\t# minD reduction predicated (sve)" %} ins_encode %{ __ sve_fminv(as_FloatRegister($dst$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minF_masked_partial(vRegF dst, vRegF src1, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_minF $dst, $src1, $pg, $src2\t# minF reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fminv(as_FloatRegister($dst$$reg), __ S, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmins(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} instruct reduce_minD_masked_partial(vRegD dst, vRegD src1, vReg src2, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->in(2)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE && n->in(1)->in(2)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (MinReductionV (Binary src1 src2) pg)); effect(TEMP_DEF dst, TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "sve_reduce_minD $dst, $src1, $pg, $src2\t# minD reduction predicated partial (sve)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src2)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_fminv(as_FloatRegister($dst$$reg), __ D, as_PRegister($ptmp$$reg), as_FloatRegister($src2$$reg)); __ fmind(as_FloatRegister($dst$$reg), as_FloatRegister($dst$$reg), as_FloatRegister($src1$$reg)); %} ins_pipe(pipe_slow); %} // vector Math.rint, floor, ceil instruct vroundD(vReg dst, vReg src, immI rmode) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (RoundDoubleModeV src rmode)); format %{ "sve_frint $dst, $src, $rmode\t# vector (sve) (D)" %} ins_encode %{ switch ($rmode$$constant) { case RoundDoubleModeNode::rmode_rint: __ sve_frintn(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); break; case RoundDoubleModeNode::rmode_floor: __ sve_frintm(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); break; case RoundDoubleModeNode::rmode_ceil: __ sve_frintp(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); break; } %} ins_pipe(pipe_slow); %} // vector replicate instruct replicateB(vReg dst, iRegIorL2I src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateB src)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $src\t# vector (sve) (B)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ B, as_Register($src$$reg)); %} ins_pipe(pipe_slow); %} instruct replicateS(vReg dst, iRegIorL2I src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateS src)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $src\t# vector (sve) (H)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ H, as_Register($src$$reg)); %} ins_pipe(pipe_slow); %} instruct replicateI(vReg dst, iRegIorL2I src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateI src)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ S, as_Register($src$$reg)); %} ins_pipe(pipe_slow); %} instruct replicateL(vReg dst, iRegL src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateL src)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ D, as_Register($src$$reg)); %} ins_pipe(pipe_slow); %} instruct replicateB_imm8(vReg dst, immI8 con) %{ predicate(UseSVE > 0); match(Set dst (ReplicateB con)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $con\t# vector (sve) (B)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ B, $con$$constant); %} ins_pipe(pipe_slow); %} instruct replicateS_imm8(vReg dst, immI8_shift8 con) %{ predicate(UseSVE > 0); match(Set dst (ReplicateS con)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $con\t# vector (sve) (H)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ H, $con$$constant); %} ins_pipe(pipe_slow); %} instruct replicateI_imm8(vReg dst, immI8_shift8 con) %{ predicate(UseSVE > 0); match(Set dst (ReplicateI con)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $con\t# vector (sve) (S)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ S, $con$$constant); %} ins_pipe(pipe_slow); %} instruct replicateL_imm8(vReg dst, immL8_shift8 con) %{ predicate(UseSVE > 0); match(Set dst (ReplicateL con)); ins_cost(SVE_COST); format %{ "sve_dup $dst, $con\t# vector (sve) (D)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ D, $con$$constant); %} ins_pipe(pipe_slow); %} instruct replicateF(vReg dst, vRegF src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateF src)); ins_cost(SVE_COST); format %{ "sve_cpy $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_cpy(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct replicateD(vReg dst, vRegD src) %{ predicate(UseSVE > 0); match(Set dst (ReplicateD src)); ins_cost(SVE_COST); format %{ "sve_cpy $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_cpy(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector shift instruct vasrB(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVB dst shift)); ins_cost(SVE_COST); format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (B)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst$$reg), __ B, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrS(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVS dst shift)); ins_cost(SVE_COST); format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (H)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst$$reg), __ H, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrI(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVI dst shift)); ins_cost(SVE_COST); format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (S)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrL(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVL dst shift)); ins_cost(SVE_COST); format %{ "sve_asr $dst, $dst, $shift\t# vector (sve) (D)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslB(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVB dst shift)); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (B)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst$$reg), __ B, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslS(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVS dst shift)); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (H)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst$$reg), __ H, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslI(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVI dst shift)); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (S)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslL(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVL dst shift)); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $dst, $shift\t# vector (sve) (D)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrB(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVB dst shift)); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (B)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst$$reg), __ B, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrS(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVS dst shift)); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (H)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst$$reg), __ H, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrI(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVI dst shift)); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (S)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrL(vReg dst, vReg shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVL dst shift)); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $dst, $shift\t# vector (sve) (D)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($shift$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrB_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVB src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } if (con >= 8) con = 7; __ sve_asr(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrS_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVS src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } if (con >= 16) con = 15; __ sve_asr(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrI_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVI src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_asr(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrL_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (RShiftVL src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_asr $dst, $src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_asr(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrB_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVB src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } if (con >= 8) { __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsr(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrS_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVS src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } if (con >= 16) { __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsr(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrI_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVI src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsr(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrL_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (URShiftVL src (RShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsr $dst, $src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; if (con == 0) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsr(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslB_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVB src (LShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; if (con >= 8) { __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsl(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslS_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVS src (LShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; if (con >= 16) { __ sve_eor(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); return; } __ sve_lsl(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslI_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVI src (LShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; __ sve_lsl(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslL_imm(vReg dst, vReg src, immI shift) %{ predicate(UseSVE > 0); match(Set dst (LShiftVL src (LShiftCntV shift))); ins_cost(SVE_COST); format %{ "sve_lsl $dst, $src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; __ sve_lsl(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), con); %} ins_pipe(pipe_slow); %} instruct vshiftcntB(vReg dst, iRegIorL2I cnt) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE)); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (B)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ B, as_Register($cnt$$reg)); %} ins_pipe(pipe_slow); %} instruct vshiftcntS(vReg dst, iRegIorL2I cnt) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || (n->bottom_type()->is_vect()->element_basic_type() == T_CHAR))); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (H)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ H, as_Register($cnt$$reg)); %} ins_pipe(pipe_slow); %} instruct vshiftcntI(vReg dst, iRegIorL2I cnt) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT)); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (S)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ S, as_Register($cnt$$reg)); %} ins_pipe(pipe_slow); %} instruct vshiftcntL(vReg dst, iRegIorL2I cnt) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG)); match(Set dst (LShiftCntV cnt)); match(Set dst (RShiftCntV cnt)); format %{ "sve_dup $dst, $cnt\t# vector shift count (sve) (D)" %} ins_encode %{ __ sve_dup(as_FloatRegister($dst$$reg), __ D, as_Register($cnt$$reg)); %} ins_pipe(pipe_slow); %} // vector shift - predicated instruct vasrB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (RShiftVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (RShiftVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (RShiftVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (RShiftVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_asr(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (LShiftVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (LShiftVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (LShiftVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlslL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (LShiftVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_lsl(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (URShiftVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (URShiftVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (URShiftVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vlsrL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (URShiftVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_lsr(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vasrB_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (RShiftVB (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 8, "invalid shift immediate"); __ sve_asr(as_FloatRegister($dst_src$$reg), __ B, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrS_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (RShiftVS (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 16, "invalid shift immediate"); __ sve_asr(as_FloatRegister($dst_src$$reg), __ H, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrI_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (RShiftVI (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 32, "invalid shift immediate"); __ sve_asr(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vasrL_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (RShiftVL (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_asr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 64, "invalid shift immediate"); __ sve_asr(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrB_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (URShiftVB (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 8, "invalid shift immediate"); __ sve_lsr(as_FloatRegister($dst_src$$reg), __ B, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrS_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (URShiftVS (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 16, "invalid shift immediate"); __ sve_lsr(as_FloatRegister($dst_src$$reg), __ H, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrI_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (URShiftVI (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 32, "invalid shift immediate"); __ sve_lsr(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlsrL_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (URShiftVL (Binary dst_src (RShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsr $dst_src, $pg, $dst_src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con > 0 && con < 64, "invalid shift immediate"); __ sve_lsr(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslB_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (LShiftVB (Binary dst_src (LShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src, $pg, $dst_src, $shift\t# vector (sve) (B)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con >= 0 && con < 8, "invalid shift immediate"); __ sve_lsl(as_FloatRegister($dst_src$$reg), __ B, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslS_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (LShiftVS (Binary dst_src (LShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src, $pg, $dst_src, $shift\t# vector (sve) (H)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con >= 0 && con < 16, "invalid shift immediate"); __ sve_lsl(as_FloatRegister($dst_src$$reg), __ H, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslI_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (LShiftVI (Binary dst_src (LShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src, $pg, $dst_src, $shift\t# vector (sve) (S)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con >= 0 && con < 32, "invalid shift immediate"); __ sve_lsl(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} instruct vlslL_imm_masked(vReg dst_src, immI shift, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (LShiftVL (Binary dst_src (LShiftCntV shift)) pg)); ins_cost(SVE_COST); format %{ "sve_lsl $dst_src, $pg, $dst_src, $shift\t# vector (sve) (D)" %} ins_encode %{ int con = (int)$shift$$constant; assert(con >= 0 && con < 64, "invalid shift immediate"); __ sve_lsl(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), con); %} ins_pipe(pipe_slow); %} // vector sqrt instruct vsqrtF(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (SqrtVF src)); ins_cost(SVE_COST); format %{ "sve_fsqrt $dst, $src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fsqrt(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vsqrtD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && !n->as_Vector()->is_predicated_vector()); match(Set dst (SqrtVD src)); ins_cost(SVE_COST); format %{ "sve_fsqrt $dst, $src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fsqrt(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg)); %} ins_pipe(pipe_slow); %} // vector sqrt - predicated instruct vsqrtF_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (SqrtVF dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fsqrt $dst_src, $pg, $dst_src\t# vector (sve) (S)" %} ins_encode %{ __ sve_fsqrt(as_FloatRegister($dst_src$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} instruct vsqrtD_masked(vReg dst_src, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src (SqrtVD dst_src pg)); ins_cost(SVE_COST); format %{ "sve_fsqrt $dst_src, $pg, $dst_src\t# vector (sve) (D)" %} ins_encode %{ __ sve_fsqrt(as_FloatRegister($dst_src$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($dst_src$$reg)); %} ins_pipe(pipe_slow); %} // vector sub instruct vsubB(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVB src1 src2)); ins_cost(SVE_COST); format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (B)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubS(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVS src1 src2)); ins_cost(SVE_COST); format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (H)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubI(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVI src1 src2)); ins_cost(SVE_COST); format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubL(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVL src1 src2)); ins_cost(SVE_COST); format %{ "sve_sub $dst, $src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubF(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVF src1 src2)); ins_cost(SVE_COST); format %{ "sve_fsub $dst, $src1, $src2\t # vector (sve) (S)" %} ins_encode %{ __ sve_fsub(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubD(vReg dst, vReg src1, vReg src2) %{ predicate(UseSVE > 0); match(Set dst (SubVD src1 src2)); ins_cost(SVE_COST); format %{ "sve_fsub $dst, $src1, $src2\t # vector (sve) (D)" %} ins_encode %{ __ sve_fsub(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src1$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // vector sub - predicated instruct vsubB_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVB (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_sub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (B)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst_src1$$reg), __ B, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubS_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVS (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_sub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (H)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst_src1$$reg), __ H, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubI_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVI (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_sub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubL_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVL (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_sub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_sub(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubF_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVF (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fsub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (S)" %} ins_encode %{ __ sve_fsub(as_FloatRegister($dst_src1$$reg), __ S, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} instruct vsubD_masked(vReg dst_src1, vReg src2, pRegGov pg) %{ predicate(UseSVE > 0); match(Set dst_src1 (SubVD (Binary dst_src1 src2) pg)); ins_cost(SVE_COST); format %{ "sve_fsub $dst_src1, $pg, $dst_src1, $src2\t# vector (sve) (D)" %} ins_encode %{ __ sve_fsub(as_FloatRegister($dst_src1$$reg), __ D, as_PRegister($pg$$reg), as_FloatRegister($src2$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector mask cast -------------------------- instruct vmaskcast(pRegGov dst_src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->length() == n->in(1)->bottom_type()->is_vect()->length() && n->bottom_type()->is_vect()->length_in_bytes() == n->in(1)->bottom_type()->is_vect()->length_in_bytes()); match(Set dst_src (VectorMaskCast dst_src)); ins_cost(0); format %{ "vmaskcast $dst_src\t# empty (sve)" %} ins_encode %{ // empty %} ins_pipe(pipe_class_empty); %} instruct vmaskcast_extend(pRegGov dst, pReg src) %{ predicate(UseSVE > 0 && (Matcher::vector_length_in_bytes(n) == 2 * Matcher::vector_length_in_bytes(n->in(1)) || Matcher::vector_length_in_bytes(n) == 4 * Matcher::vector_length_in_bytes(n->in(1)) || Matcher::vector_length_in_bytes(n) == 8 * Matcher::vector_length_in_bytes(n->in(1)))); match(Set dst (VectorMaskCast src)); ins_cost(SVE_COST * 3); format %{ "sve_vmaskcast_extend $dst, $src\t# extend predicate $src" %} ins_encode %{ __ sve_vmaskcast_extend(as_PRegister($dst$$reg), as_PRegister($src$$reg), Matcher::vector_length_in_bytes(this), Matcher::vector_length_in_bytes(this, $src)); %} ins_pipe(pipe_slow); %} instruct vmaskcast_narrow(pRegGov dst, pReg src) %{ predicate(UseSVE > 0 && (Matcher::vector_length_in_bytes(n) * 2 == Matcher::vector_length_in_bytes(n->in(1)) || Matcher::vector_length_in_bytes(n) * 4 == Matcher::vector_length_in_bytes(n->in(1)) || Matcher::vector_length_in_bytes(n) * 8 == Matcher::vector_length_in_bytes(n->in(1)))); match(Set dst (VectorMaskCast src)); ins_cost(SVE_COST * 3); format %{ "sve_vmaskcast_narrow $dst, $src\t# narrow predicate $src" %} ins_encode %{ __ sve_vmaskcast_narrow(as_PRegister($dst$$reg), as_PRegister($src$$reg), Matcher::vector_length_in_bytes(this), Matcher::vector_length_in_bytes(this, $src)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector cast ------------------------------- instruct vcvtBtoX_extend(vReg dst, vReg src) %{ predicate(UseSVE > 0); match(Set dst (VectorCastB2X src)); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_b2x $dst, $src\t# convert B to X vector (extend)" %} ins_encode %{ BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_vector_extend(as_FloatRegister($dst$$reg), to_size, as_FloatRegister($src$$reg), __ B); if (to_bt == T_FLOAT || to_bt == T_DOUBLE) { __ sve_scvtf(as_FloatRegister($dst$$reg), to_size, ptrue, as_FloatRegister($dst$$reg), to_size); } %} ins_pipe(pipe_slow); %} instruct vcvtStoB(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorCastS2X src)); effect(TEMP tmp); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_s2b $dst, $src\t# convert H to B vector" %} ins_encode %{ __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), __ H, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtStoX_extend(vReg dst, vReg src) %{ predicate(UseSVE > 0 && type2aelembytes(Matcher::vector_element_basic_type(n)) > 2); match(Set dst (VectorCastS2X src)); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_s2x $dst, $src\t# convert H to X vector (extend)" %} ins_encode %{ BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_vector_extend(as_FloatRegister($dst$$reg), to_size, as_FloatRegister($src$$reg), __ H); if (to_bt == T_FLOAT || to_bt == T_DOUBLE) { __ sve_scvtf(as_FloatRegister($dst$$reg), to_size, ptrue, as_FloatRegister($dst$$reg), to_size); } %} ins_pipe(pipe_slow); %} instruct vcvtItoB(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorCastI2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_vectorcast_i2b $dst, $src\t# convert I to B vector" %} ins_encode %{ __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ B, as_FloatRegister($src$$reg), __ S, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtItoS(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT); match(Set dst (VectorCastI2X src)); effect(TEMP tmp); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_i2s $dst, $src\t# convert I to H vector" %} ins_encode %{ __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ H, as_FloatRegister($src$$reg), __ S, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtItoL(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (VectorCastI2X src)); ins_cost(SVE_COST); format %{ "sve_vectorcast_i2l $dst, $src\t# convert I to L vector" %} ins_encode %{ __ sve_vector_extend(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), __ S); %} ins_pipe(pipe_slow); %} instruct vcvtItoF(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastI2X src)); ins_cost(SVE_COST); format %{ "sve_vectorcast_i2f $dst, $src\t# convert I to F vector" %} ins_encode %{ __ sve_scvtf(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ S); %} ins_pipe(pipe_slow); %} instruct vcvtItoD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastI2X src)); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_i2d $dst, $src\t# convert I to D vector" %} ins_encode %{ __ sve_sunpklo(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg)); __ sve_scvtf(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($dst$$reg), __ D); %} ins_pipe(pipe_slow); %} instruct vcvtLtoX_narrow(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && is_integral_type(Matcher::vector_element_basic_type(n))); match(Set dst (VectorCastL2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_l2x $dst, $src\t# convert L to B/H/S vector (narrow)" %} ins_encode %{ BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_vector_narrow(as_FloatRegister($dst$$reg), to_size, as_FloatRegister($src$$reg), __ D, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtLtoF(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastL2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_vectorcast_l2f $dst, $src\t# convert L to F vector" %} ins_encode %{ __ sve_scvtf(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ D); __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($dst$$reg), __ D, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtLtoD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastL2X src)); ins_cost(SVE_COST); format %{ "sve_vectorcast_l2d $dst, $src\t# convert L to D vector" %} ins_encode %{ __ sve_scvtf(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg), __ D); %} ins_pipe(pipe_slow); %} instruct vcvtFtoX_narrow(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE || n->bottom_type()->is_vect()->element_basic_type() == T_SHORT)); match(Set dst (VectorCastF2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_vectorcast_f2x $dst, $src\t# convert F to B/H vector" %} ins_encode %{ BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_fcvtzs(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ S); __ sve_vector_narrow(as_FloatRegister($dst$$reg), to_size, as_FloatRegister($dst$$reg), __ S, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtFtoI(vReg dst, vReg src) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_INT)); match(Set dst (VectorCastF2X src)); ins_cost(SVE_COST); format %{ "sve_vectorcast_f2x $dst, $src\t# convert F to I vector" %} ins_encode %{ __ sve_fcvtzs(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ S); %} ins_pipe(pipe_slow); %} instruct vcvtFtoL(vReg dst, vReg src) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG)); match(Set dst (VectorCastF2X src)); ins_cost(SVE_COST * 2); format %{ "sve_vectorcast_f2x $dst, $src\t# convert F to L vector" %} ins_encode %{ __ sve_sunpklo(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg)); __ sve_fcvtzs(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($dst$$reg), __ S); %} ins_pipe(pipe_slow); %} instruct vcvtFtoD(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorCastF2X src)); ins_cost(2 * SVE_COST); format %{ "sve_vectorcast_f2d $dst, $dst\t# convert F to D vector" %} ins_encode %{ __ sve_vector_extend(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), __ S); __ sve_fcvt(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($dst$$reg), __ S); %} ins_pipe(pipe_slow); %} instruct vcvtDtoX_narrow(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE || n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || n->bottom_type()->is_vect()->element_basic_type() == T_INT)); match(Set dst (VectorCastD2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_vectorcast_d2x $dst, $src\t# convert D to X vector (narrow)" %} ins_encode %{ BasicType to_bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant to_size = __ elemType_to_regVariant(to_bt); __ sve_fcvtzs(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ D); __ sve_vector_narrow(as_FloatRegister($dst$$reg), to_size, as_FloatRegister($dst$$reg), __ D, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vcvtDtoL(vReg dst, vReg src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (VectorCastD2X src)); ins_cost(SVE_COST); format %{ "sve_vectorcast_d2l $dst, $src\t# convert D to L vector" %} ins_encode %{ __ sve_fcvtzs(as_FloatRegister($dst$$reg), __ D, ptrue, as_FloatRegister($src$$reg), __ D); %} ins_pipe(pipe_slow); %} instruct vcvtDtoF(vReg dst, vReg src, vReg tmp) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorCastD2X src)); effect(TEMP_DEF dst, TEMP tmp); ins_cost(3 * SVE_COST); format %{ "sve_vectorcast_d2f $dst, S, $dst\t# convert D to F vector" %} ins_encode %{ __ sve_fcvt(as_FloatRegister($dst$$reg), __ S, ptrue, as_FloatRegister($src$$reg), __ D); __ sve_vector_narrow(as_FloatRegister($dst$$reg), __ S, as_FloatRegister($dst$$reg), __ D, as_FloatRegister($tmp$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector extract --------------------------------- instruct extractB(iRegINoSp dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractB src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, B, $pgtmp, $src, $idx\n\t" "sbfmw $dst, $dst, 0U, 7U\t# extract from vector(B)" %} ins_encode %{ __ sve_extract(as_Register($dst$$reg), __ B, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 7U); %} ins_pipe(pipe_slow); %} instruct extractS(iRegINoSp dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractS src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, H, $pgtmp, $src, $idx\n\t" "sbfmw $dst, $dst, 0U, 15U\t# extract from vector(S)" %} ins_encode %{ __ sve_extract(as_Register($dst$$reg), __ H, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); __ sbfmw(as_Register($dst$$reg), as_Register($dst$$reg), 0U, 15U); %} ins_pipe(pipe_slow); %} instruct extractI(iRegINoSp dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractI src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, S, $pgtmp, $src, $idx\t# extract from vector(I)" %} ins_encode %{ __ sve_extract(as_Register($dst$$reg), __ S, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); %} ins_pipe(pipe_slow); %} instruct extractL(iRegLNoSp dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractL src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, D, $pgtmp, $src, $idx\t# extract from vector(L)" %} ins_encode %{ __ sve_extract(as_Register($dst$$reg), __ D, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); %} ins_pipe(pipe_slow); %} instruct extractF(vRegF dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractF src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, S, $pgtmp, $src, $idx\t# extract from vector(F)" %} ins_encode %{ __ sve_extract(as_FloatRegister($dst$$reg), __ S, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); %} ins_pipe(pipe_slow); %} instruct extractD(vRegD dst, vReg src, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set dst (ExtractD src idx)); effect(TEMP pgtmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "sve_extract $dst, D, $pgtmp, $src, $idx\t# extract from vector(D)" %} ins_encode %{ __ sve_extract(as_FloatRegister($dst$$reg), __ D, as_PRegister($pgtmp$$reg), as_FloatRegister($src$$reg), (int)($idx$$constant)); %} ins_pipe(pipe_slow); %} // ------------------------------- VectorTest ---------------------------------- instruct vtest_alltrue(iRegINoSp dst, pRegGov src1, pRegGov src2, pReg ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && static_cast(n)->get_predicate() == BoolTest::overflow); match(Set dst (VectorTest src1 src2)); effect(TEMP ptmp, KILL cr); ins_cost(SVE_COST); format %{ "sve_eors $ptmp, $src1, $src2\t# $src2 is all true mask\n" "csetw $dst, EQ\t# VectorTest (sve) - alltrue" %} ins_encode %{ __ sve_eors(as_PRegister($ptmp$$reg), ptrue, as_PRegister($src1$$reg), as_PRegister($src2$$reg)); __ csetw(as_Register($dst$$reg), Assembler::EQ); %} ins_pipe(pipe_slow); %} instruct vtest_anytrue(iRegINoSp dst, pRegGov src1, pRegGov src2, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize && static_cast(n)->get_predicate() == BoolTest::ne); match(Set dst (VectorTest src1 src2)); effect(KILL cr); ins_cost(SVE_COST); format %{ "sve_ptest $src1\n\t" "csetw $dst, NE\t# VectorTest (sve) - anytrue" %} ins_encode %{ // "src2" is not used for sve. __ sve_ptest(ptrue, as_PRegister($src1$$reg)); __ csetw(as_Register($dst$$reg), Assembler::NE); %} ins_pipe(pipe_slow); %} instruct vtest_alltrue_partial(iRegINoSp dst, pRegGov src1, pRegGov src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && static_cast(n)->get_predicate() == BoolTest::overflow); match(Set dst (VectorTest src1 src2)); effect(TEMP ptmp, KILL cr); ins_cost(SVE_COST); format %{ "vtest_alltrue_partial $dst, $src1, $src2\t# VectorTest partial (sve) - alltrue" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src1); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this, $src1)); __ sve_eors(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($src1$$reg), as_PRegister($src2$$reg)); __ csetw(as_Register($dst$$reg), Assembler::EQ); %} ins_pipe(pipe_slow); %} instruct vtest_anytrue_partial(iRegINoSp dst, pRegGov src1, pRegGov src2, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize && static_cast(n)->get_predicate() == BoolTest::ne); match(Set dst (VectorTest src1 src2)); effect(TEMP ptmp, KILL cr); ins_cost(SVE_COST); format %{ "vtest_anytrue_partial $dst, $src1, $src2\t# VectorTest partial (sve) - anytrue" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src1); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this, $src1)); __ sve_ands(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($src1$$reg), as_PRegister($src2$$reg)); __ csetw(as_Register($dst$$reg), Assembler::NE); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector insert --------------------------------- instruct insertI_small(vReg dst, vReg src, iRegIorL2I val, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length() <= 32 && (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE || n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || n->bottom_type()->is_vect()->element_basic_type() == T_INT)); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP pgtmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "sve_index $dst, -16, 1\t# (B/H/S)\n\t" "sve_cmpeq $pgtmp, $dst, ($idx-#16) # shift from [0, 31] to [-16, 15]\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (B/H/S)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_index(as_FloatRegister($dst$$reg), size, -16, 1); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), size, ptrue, as_FloatRegister($dst$$reg), (int)($idx$$constant) - 16); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), size, as_PRegister($pgtmp$$reg), as_Register($val$$reg)); %} ins_pipe(pipe_slow); %} instruct insertF_small(vReg dst, vReg src, vRegF val, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length() <= 32 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP pgtmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "sve_index $dst, S, -16, 1\n\t" "sve_cmpeq $pgtmp, $dst, ($idx-#16) # shift from [0, 31] to [-16, 15]\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (F)" %} ins_encode %{ __ sve_index(as_FloatRegister($dst$$reg), __ S, -16, 1); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), __ S, ptrue, as_FloatRegister($dst$$reg), (int)($idx$$constant) - 16); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), __ S, as_PRegister($pgtmp$$reg), as_FloatRegister($val$$reg)); %} ins_pipe(pipe_slow); %} instruct insertI(vReg dst, vReg src, iRegIorL2I val, immI idx, vReg tmp1, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length() > 32 && (n->bottom_type()->is_vect()->element_basic_type() == T_BYTE || n->bottom_type()->is_vect()->element_basic_type() == T_SHORT || n->bottom_type()->is_vect()->element_basic_type() == T_INT)); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP tmp1, TEMP pgtmp, KILL cr); ins_cost(5 * SVE_COST); format %{ "sve_index $tmp1, 0, 1\t# (B/H/S)\n\t" "sve_dup $dst, $idx\t# (B/H/S)\n\t" "sve_cmpeq $pgtmp, $tmp1, $dst\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (B/H/S)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_index(as_FloatRegister($tmp1$$reg), size, 0, 1); __ sve_dup(as_FloatRegister($dst$$reg), size, (int)($idx$$constant)); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), size, ptrue, as_FloatRegister($tmp1$$reg), as_FloatRegister($dst$$reg)); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), size, as_PRegister($pgtmp$$reg), as_Register($val$$reg)); %} ins_pipe(pipe_slow); %} instruct insertL(vReg dst, vReg src, iRegL val, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_LONG); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP pgtmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "sve_index $dst, D, -16, 1\n\t" "sve_cmpeq $pgtmp, $dst, ($idx-#16) # shift from [0, 31] to [-16, 15]\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (L)" %} ins_encode %{ __ sve_index(as_FloatRegister($dst$$reg), __ D, -16, 1); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), __ D, ptrue, as_FloatRegister($dst$$reg), (int)($idx$$constant) - 16); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), __ D, as_PRegister($pgtmp$$reg), as_Register($val$$reg)); %} ins_pipe(pipe_slow); %} instruct insertD(vReg dst, vReg src, vRegD val, immI idx, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP pgtmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "sve_index $dst, D, -16, 1\n\t" "sve_cmpeq $pgtmp, $dst, ($idx-#16) # shift from [0, 31] to [-16, 15]\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (D)" %} ins_encode %{ __ sve_index(as_FloatRegister($dst$$reg), __ D, -16, 1); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), __ D, ptrue, as_FloatRegister($dst$$reg), (int)($idx$$constant) - 16); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), __ D, as_PRegister($pgtmp$$reg), as_FloatRegister($val$$reg)); %} ins_pipe(pipe_slow); %} instruct insertF(vReg dst, vReg src, vRegF val, immI idx, vReg tmp1, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_Vector()->length() > 32 && n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT); match(Set dst (VectorInsert (Binary src val) idx)); effect(TEMP_DEF dst, TEMP tmp1, TEMP pgtmp, KILL cr); ins_cost(5 * SVE_COST); format %{ "sve_index $tmp1, S, 0, 1\n\t" "sve_dup $dst, S, $idx\n\t" "sve_cmpeq $pgtmp, $tmp1, $dst\n\t" "sve_orr $dst, $src, $src\n\t" "sve_cpy $dst, $pgtmp, $val\t# insert into vector (F)" %} ins_encode %{ __ sve_index(as_FloatRegister($tmp1$$reg), __ S, 0, 1); __ sve_dup(as_FloatRegister($dst$$reg), __ S, (int)($idx$$constant)); __ sve_cmp(Assembler::EQ, as_PRegister($pgtmp$$reg), __ S, ptrue, as_FloatRegister($tmp1$$reg), as_FloatRegister($dst$$reg)); __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); __ sve_cpy(as_FloatRegister($dst$$reg), __ S, as_PRegister($pgtmp$$reg), as_FloatRegister($val$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector shuffle ------------------------------- instruct loadshuffle(vReg dst, vReg src) %{ predicate(UseSVE > 0); match(Set dst (VectorLoadShuffle src)); ins_cost(SVE_COST); format %{ "sve_loadshuffle $dst, $src\t# vector load shuffle (B/H/S/D)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); if (bt == T_BYTE) { if (as_FloatRegister($dst$$reg) != as_FloatRegister($src$$reg)) { __ sve_orr(as_FloatRegister($dst$$reg), as_FloatRegister($src$$reg), as_FloatRegister($src$$reg)); } } else { __ sve_vector_extend(as_FloatRegister($dst$$reg), __ elemType_to_regVariant(bt), as_FloatRegister($src$$reg), __ B); } %} ins_pipe(pipe_slow); %} // ------------------------------ Vector rearrange ------------------------------- instruct rearrange(vReg dst, vReg src, vReg shuffle) %{ predicate(UseSVE > 0); match(Set dst (VectorRearrange src shuffle)); ins_cost(SVE_COST); format %{ "sve_tbl $dst, $src, $shuffle\t# vector rearrange" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_tbl(as_FloatRegister($dst$$reg), size, as_FloatRegister($src$$reg), as_FloatRegister($shuffle$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Load Gather --------------------------------- instruct gatherI(vReg dst, indirect mem, vReg idx) %{ predicate(UseSVE > 0 && n->as_LoadVectorGather()->memory_size() == MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (LoadVectorGather mem idx)); ins_cost(SVE_COST); format %{ "load_vector_gather $dst, $mem, $idx\t# vector load gather (S)" %} ins_encode %{ __ sve_ld1w_gather(as_FloatRegister($dst$$reg), ptrue, as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct gatherL(vReg dst, indirect mem, vReg idx) %{ predicate(UseSVE > 0 && n->as_LoadVectorGather()->memory_size() == MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set dst (LoadVectorGather mem idx)); ins_cost(2 * SVE_COST); format %{ "load_vector_gather $dst, $mem, $idx\t# vector load gather (D)" %} ins_encode %{ __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_ld1d_gather(as_FloatRegister($dst$$reg), ptrue, as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Load Gather Partial------------------------------- instruct gatherI_partial(vReg dst, indirect mem, vReg idx, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVectorGather()->memory_size() < MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (LoadVectorGather mem idx)); effect(TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST + INSN_COST); format %{ "load_vector_gather $dst, $ptmp, $mem, $idx\t# vector load gather partial (S)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this)); __ sve_ld1w_gather(as_FloatRegister($dst$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct gatherL_partial(vReg dst, indirect mem, vReg idx, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVectorGather()->memory_size() < MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set dst (LoadVectorGather mem idx)); effect(TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST + INSN_COST); format %{ "load_vector_gather $dst, $ptmp, $mem, $idx\t# vector load gather partial (D)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this)); __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_ld1d_gather(as_FloatRegister($dst$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Load Gather Predicated ------------------------------- instruct gatherI_masked(vReg dst, indirect mem, vReg idx, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (LoadVectorGatherMasked mem (Binary idx pg))); ins_cost(SVE_COST); format %{ "load_vector_gather $dst, $pg, $mem, $idx\t# vector load gather predicated (S)" %} ins_encode %{ __ sve_ld1w_gather(as_FloatRegister($dst$$reg), as_PRegister($pg$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct gatherL_masked(vReg dst, indirect mem, vReg idx, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() == MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set dst (LoadVectorGatherMasked mem (Binary idx pg))); ins_cost(2 * SVE_COST); format %{ "load_vector_gather $dst, $pg, $mem, $idx\t# vector load gather predicated (D)" %} ins_encode %{ __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_ld1d_gather(as_FloatRegister($dst$$reg), as_PRegister($pg$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Load Gather Predicated Partial ------------------------------- instruct gatherI_masked_partial(vReg dst, indirect mem, vReg idx, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() < MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_INT || n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set dst (LoadVectorGatherMasked mem (Binary idx pg))); effect(TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "load_vector_gather $dst, $pg, $mem, $idx\t# vector load gather predicated partial (S)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_ld1w_gather(as_FloatRegister($dst$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct gatherL_masked_partial(vReg dst, indirect mem, vReg idx, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() < MaxVectorSize && (n->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set dst (LoadVectorGatherMasked mem (Binary idx pg))); effect(TEMP ptmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "load_vector_gather $dst, $pg, $mem, $idx\t# vector load gather predicated partial (D)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_ld1d_gather(as_FloatRegister($dst$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Store Scatter ------------------------------- instruct scatterI(indirect mem, vReg src, vReg idx) %{ predicate(UseSVE > 0 && n->as_StoreVectorScatter()->memory_size() == MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_INT || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set mem (StoreVectorScatter mem (Binary src idx))); ins_cost(SVE_COST); format %{ "store_vector_scatter $mem, $idx, $src\t# vector store scatter (S)" %} ins_encode %{ __ sve_st1w_scatter(as_FloatRegister($src$$reg), ptrue, as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct scatterL(indirect mem, vReg src, vReg idx) %{ predicate(UseSVE > 0 && n->as_StoreVectorScatter()->memory_size() == MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set mem (StoreVectorScatter mem (Binary src idx))); ins_cost(2 * SVE_COST); format %{ "store_vector_scatter $mem, $idx, $src\t# vector store scatter (D)" %} ins_encode %{ __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_st1d_scatter(as_FloatRegister($src$$reg), ptrue, as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Store Scatter Partial ------------------------------- instruct scatterI_partial(indirect mem, vReg src, vReg idx, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVectorScatter()->memory_size() < MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_INT || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set mem (StoreVectorScatter mem (Binary src idx))); effect(TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST + INSN_COST); format %{ "store_vector_scatter $mem, $ptmp, $idx, $src\t# vector store scatter partial (S)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src)); __ sve_st1w_scatter(as_FloatRegister($src$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct scatterL_partial(indirect mem, vReg src, vReg idx, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVectorScatter()->memory_size() < MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set mem (StoreVectorScatter mem (Binary src idx))); effect(TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST + INSN_COST); format %{ "store_vector_scatter $mem, $ptmp, $idx, $src\t# vector store scatter partial (D)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src)); __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_st1d_scatter(as_FloatRegister($src$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Store Scatter Predicated ------------------------------- instruct scatterI_masked(indirect mem, vReg src, vReg idx, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_INT || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx pg)))); ins_cost(SVE_COST); format %{ "store_vector_scatter $mem, $pg, $idx, $src\t# vector store scatter predicate (S)" %} ins_encode %{ __ sve_st1w_scatter(as_FloatRegister($src$$reg), as_PRegister($pg$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct scatterL_masked(indirect mem, vReg src, vReg idx, pRegGov pg) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() == MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx pg)))); ins_cost(2 * SVE_COST); format %{ "store_vector_scatter $mem, $pg, $idx, $src\t# vector store scatter predicated (D)" %} ins_encode %{ __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_st1d_scatter(as_FloatRegister($src$$reg), as_PRegister($pg$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Store Scatter Predicated Partial ------------------------------- instruct scatterI_masked_partial(indirect mem, vReg src, vReg idx, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() < MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_INT || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_FLOAT)); match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx pg)))); effect(TEMP ptmp, KILL cr); ins_cost(3 * SVE_COST); format %{ "store_vector_scatter $mem, $pg, $idx, $src\t# vector store scatter predicated partial (S)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ S, Matcher::vector_length(this, $src)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_st1w_scatter(as_FloatRegister($src$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} instruct scatterL_masked_partial(indirect mem, vReg src, vReg idx, pRegGov pg, pRegGov ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->as_StoreVector()->memory_size() < MaxVectorSize && (n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_LONG || n->in(3)->in(1)->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE)); match(Set mem (StoreVectorScatterMasked mem (Binary src (Binary idx pg)))); effect(TEMP ptmp, KILL cr); ins_cost(4 * SVE_COST); format %{ "store_vector_scatter $mem, $pg, $idx, $src\t# vector store scatter predicated partial (D)" %} ins_encode %{ __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), __ D, Matcher::vector_length(this, $src)); __ sve_and(as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg), as_PRegister($pg$$reg), as_PRegister($pg$$reg)); __ sve_uunpklo(as_FloatRegister($idx$$reg), __ D, as_FloatRegister($idx$$reg)); __ sve_st1d_scatter(as_FloatRegister($src$$reg), as_PRegister($ptmp$$reg), as_Register($mem$$base), as_FloatRegister($idx$$reg)); %} ins_pipe(pipe_slow); %} // ------------------------------ Vector Load Const ------------------------------- instruct loadconB(vReg dst, immI0 src) %{ predicate(UseSVE > 0 && n->bottom_type()->is_vect()->element_basic_type() == T_BYTE); match(Set dst (VectorLoadConst src)); ins_cost(SVE_COST); format %{ "sve_index $dst, 0, 1\t# generate iota indices" %} ins_encode %{ __ sve_index(as_FloatRegister($dst$$reg), __ B, 0, 1); %} ins_pipe(pipe_slow); %} // Intrisics for String.indexOf(char) instruct stringL_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, iRegI_R0 result, vReg ztmp1, vReg ztmp2, pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); predicate((UseSVE > 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} ins_encode %{ __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, as_FloatRegister($ztmp1$$reg), as_FloatRegister($ztmp2$$reg), as_PRegister($pgtmp$$reg), as_PRegister($ptmp$$reg), true /* isL */); %} ins_pipe(pipe_class_memory); %} instruct stringU_indexof_char_sve(iRegP_R1 str1, iRegI_R2 cnt1, iRegI_R3 ch, iRegI_R0 result, vReg ztmp1, vReg ztmp2, pRegGov pgtmp, pReg ptmp, rFlagsReg cr) %{ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); predicate((UseSVE > 0) && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); effect(TEMP ztmp1, TEMP ztmp2, TEMP pgtmp, TEMP ptmp, KILL cr); format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result # use sve" %} ins_encode %{ __ string_indexof_char_sve($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, as_FloatRegister($ztmp1$$reg), as_FloatRegister($ztmp2$$reg), as_PRegister($pgtmp$$reg), as_PRegister($ptmp$$reg), false /* isL */); %} ins_pipe(pipe_class_memory); %} // ---------------------------- Vector mask reductions --------------------------- instruct vmask_truecount(iRegINoSp dst, pReg src) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (VectorMaskTrueCount src)); ins_cost(SVE_COST); format %{ "vmask_truecount $dst, $src\t# vector mask truecount (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_cntp($dst$$Register, size, ptrue, as_PRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_firsttrue(iRegINoSp dst, pReg src, pReg ptmp) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (VectorMaskFirstTrue src)); effect(TEMP ptmp); ins_cost(2 * SVE_COST); format %{ "vmask_firsttrue $dst, $src\t# vector mask firsttrue (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_brkb(as_PRegister($ptmp$$reg), ptrue, as_PRegister($src$$reg), false); __ sve_cntp($dst$$Register, size, ptrue, as_PRegister($ptmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_lasttrue(iRegINoSp dst, pReg src, pReg ptmp) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() == MaxVectorSize); match(Set dst (VectorMaskLastTrue src)); effect(TEMP ptmp); ins_cost(3 * SVE_COST); format %{ "vmask_lasttrue $dst, $src\t# vector mask lasttrue (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); __ sve_vmask_lasttrue($dst$$Register, bt, as_PRegister($src$$reg), as_PRegister($ptmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_truecount_partial(iRegINoSp dst, pReg src, pReg ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (VectorMaskTrueCount src)); effect(TEMP ptmp, KILL cr); ins_cost(2 * SVE_COST); format %{ "vmask_truecount_partial $dst, $src\t# vector mask truecount partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this, $src)); __ sve_cntp($dst$$Register, size, as_PRegister($ptmp$$reg), as_PRegister($src$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_firsttrue_partial(iRegINoSp dst, pReg src, pReg ptmp1, pReg ptmp2, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (VectorMaskFirstTrue src)); effect(TEMP ptmp1, TEMP ptmp2, KILL cr); ins_cost(3 * SVE_COST); format %{ "vmask_firsttrue_partial $dst, $src\t# vector mask firsttrue partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp1$$reg), size, Matcher::vector_length(this, $src)); __ sve_brkb(as_PRegister($ptmp2$$reg), as_PRegister($ptmp1$$reg), as_PRegister($src$$reg), false); __ sve_cntp($dst$$Register, size, as_PRegister($ptmp1$$reg), as_PRegister($ptmp2$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_lasttrue_partial(iRegINoSp dst, pReg src, pReg ptmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length_in_bytes() < MaxVectorSize); match(Set dst (VectorMaskLastTrue src)); effect(TEMP ptmp, KILL cr); ins_cost(5 * SVE_COST); format %{ "vmask_lasttrue_partial $dst, $src\t# vector mask lasttrue partial (sve)" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this, $src); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo_zr_imm(as_PRegister($ptmp$$reg), size, Matcher::vector_length(this, $src)); __ sve_and(as_PRegister($ptmp$$reg), ptrue, as_PRegister($ptmp$$reg), as_PRegister($src$$reg)); __ sve_vmask_lasttrue($dst$$Register, bt, as_PRegister($ptmp$$reg), as_PRegister($ptmp$$reg)); %} ins_pipe(pipe_slow); %} instruct vmask_tolong(iRegLNoSp dst, pReg src, vReg vtmp1, vReg vtmp2, pRegGov pgtmp, rFlagsReg cr) %{ predicate(UseSVE > 0 && n->in(1)->bottom_type()->is_vect()->length() <= 64); match(Set dst (VectorMaskToLong src)); effect(TEMP vtmp1, TEMP vtmp2, TEMP pgtmp, KILL cr); ins_cost(13 * SVE_COST); format %{ "vmask_tolong $dst, $src\t# vector mask tolong (sve)" %} ins_encode %{ __ sve_vmask_tolong(as_Register($dst$$reg), as_PRegister($src$$reg), Matcher::vector_element_basic_type(this, $src), Matcher::vector_length(this, $src), as_FloatRegister($vtmp1$$reg), as_FloatRegister($vtmp2$$reg), as_PRegister($pgtmp$$reg)); %} ins_pipe(pipe_slow); %} // ---------------------------- Vector mask generation --------------------------- instruct vmask_gen(pRegGov pg, iRegL len, rFlagsReg cr) %{ predicate(UseSVE > 0); match(Set pg (VectorMaskGen len)); effect(KILL cr); ins_cost(SVE_COST); format %{ "sve_whilelo $pg, zr, $len\t # sve" %} ins_encode %{ BasicType bt = Matcher::vector_element_basic_type(this); Assembler::SIMD_RegVariant size = __ elemType_to_regVariant(bt); __ sve_whilelo(as_PRegister($pg$$reg), size, zr, as_Register($len$$reg)); %} ins_pipe(pipe_slow); %}