Path: blob/master/src/hotspot/cpu/aarch64/aarch64_sve.ad
64440 views
//
// 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()
%{
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()
%{
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, MUL VL]" %}
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, MUL VL]" %}
interface(MEMORY_INTER) %{
base($reg);
index(0xffffffff);
scale(0x0);
disp($off);
%}
%}
opclass vmemA(indirect, vmemA_indOffI4, vmemA_indOffL4);
source_hpp %{
bool op_sve_supported(int opcode);
%}
source %{
static inline BasicType vector_element_basic_type(const MachNode* n) {
const TypeVect* vt = n->bottom_type()->is_vect();
return vt->element_basic_type();
}
static inline BasicType vector_element_basic_type(const MachNode* use, const MachOper* opnd) {
int def_idx = use->operand_index(opnd);
Node* def = use->in(def_idx);
const TypeVect* vt = def->bottom_type()->is_vect();
return vt->element_basic_type();
}
static Assembler::SIMD_RegVariant elemBytes_to_regVariant(int esize) {
switch(esize) {
case 1:
return Assembler::B;
case 2:
return Assembler::H;
case 4:
return Assembler::S;
case 8:
return Assembler::D;
default:
assert(false, "unsupported");
ShouldNotReachHere();
}
return Assembler::INVALID;
}
static Assembler::SIMD_RegVariant elemType_to_regVariant(BasicType bt) {
return elemBytes_to_regVariant(type2aelembytes(bt));
}
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_predicate(C2_MacroAssembler masm, bool is_store,
FloatRegister reg, PRegister pg, BasicType bt,
int opcode, Register base, int index, int size, int disp) {
sve_mem_insn_predicate insn;
Assembler::SIMD_RegVariant type;
int esize = type2aelembytes(bt);
if (index == -1) {
assert(size == 0, "unsupported address mode: scale size = %d", size);
switch(esize) {
case 1:
insn = is_store ? &C2_MacroAssembler::sve_st1b : &C2_MacroAssembler::sve_ld1b;
type = Assembler::B;
break;
case 2:
insn = is_store ? &C2_MacroAssembler::sve_st1h : &C2_MacroAssembler::sve_ld1h;
type = Assembler::H;
break;
case 4:
insn = is_store ? &C2_MacroAssembler::sve_st1w : &C2_MacroAssembler::sve_ld1w;
type = Assembler::S;
break;
case 8:
insn = is_store ? &C2_MacroAssembler::sve_st1d : &C2_MacroAssembler::sve_ld1d;
type = Assembler::D;
break;
default:
assert(false, "unsupported");
ShouldNotReachHere();
}
(masm.*insn)(reg, type, pg, Address(base, disp / Matcher::scalable_vector_reg_size(T_BYTE)));
} else {
assert(false, "unimplemented");
ShouldNotReachHere();
}
}
bool op_sve_supported(int opcode) {
switch (opcode) {
case Op_MulAddVS2VI:
// No multiply reduction instructions
case Op_MulReductionVD:
case Op_MulReductionVF:
case Op_MulReductionVI:
case Op_MulReductionVL:
// Others
case Op_Extract:
case Op_ExtractB:
case Op_ExtractC:
case Op_ExtractD:
case Op_ExtractF:
case Op_ExtractI:
case Op_ExtractL:
case Op_ExtractS:
case Op_ExtractUB:
// Vector API specific
case Op_AndReductionV:
case Op_OrReductionV:
case Op_XorReductionV:
case Op_MaxReductionV:
case Op_MinReductionV:
case Op_LoadVectorGather:
case Op_StoreVectorScatter:
case Op_VectorBlend:
case Op_VectorCast:
case Op_VectorCastB2X:
case Op_VectorCastD2X:
case Op_VectorCastF2X:
case Op_VectorCastI2X:
case Op_VectorCastL2X:
case Op_VectorCastS2X:
case Op_VectorInsert:
case Op_VectorLoadConst:
case Op_VectorLoadMask:
case Op_VectorLoadShuffle:
case Op_VectorMaskCmp:
case Op_VectorRearrange:
case Op_VectorReinterpret:
case Op_VectorStoreMask:
case Op_VectorTest:
return false;
default:
return true;
}
}
%}
definitions %{
int_def SVE_COST (200, 200);
%}
// All SVE instructions
// vector load/store
// Use predicated vector load/store
instruct loadV(vReg dst, vmemA mem) %{
predicate(UseSVE > 0 && n->as_LoadVector()->memory_size() >= 16);
match(Set dst (LoadVector mem));
ins_cost(SVE_COST);
format %{ "sve_ldr $dst, $mem\t # vector (sve)" %}
ins_encode %{
FloatRegister dst_reg = as_FloatRegister($dst$$reg);
loadStoreA_predicate(C2_MacroAssembler(&cbuf), false, dst_reg, ptrue,
vector_element_basic_type(this), $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);
match(Set mem (StoreVector mem src));
ins_cost(SVE_COST);
format %{ "sve_str $mem, $src\t # vector (sve)" %}
ins_encode %{
FloatRegister src_reg = as_FloatRegister($src$$reg);
loadStoreA_predicate(C2_MacroAssembler(&cbuf), true, src_reg, ptrue,
vector_element_basic_type(this, $src), $mem->opcode(),
as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
%}
ins_pipe(pipe_slow);
%}
// vector abs
instruct vabsB(vReg dst, vReg src) %{
predicate(UseSVE > 0 && n->as_Vector()->length() >= 16 &&
n->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
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()->length() >= 8 &&
n->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
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()->length() >= 4 &&
n->bottom_type()->is_vect()->element_basic_type() == T_INT);
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()->length() >= 2 &&
n->bottom_type()->is_vect()->element_basic_type() == T_LONG);
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()->length() >= 4 &&
n->bottom_type()->is_vect()->element_basic_type() == T_FLOAT);
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()->length() >= 2 &&
n->bottom_type()->is_vect()->element_basic_type() == T_DOUBLE);
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 add
instruct vaddB(vReg dst, vReg src1, vReg src2) %{
predicate(UseSVE > 0 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 and
instruct vand(vReg dst, vReg src1, vReg src2) %{
predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length_in_bytes() >= 16);
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 not
instruct vnotI(vReg dst, vReg src, immI_M1 m1) %{
predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length_in_bytes() >= 16);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 min/max
instruct vmin(vReg dst_src1, vReg src2) %{
predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16);
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 = 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 && n->as_Vector()->length_in_bytes() >= 16);
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 = 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 fmla
// dst_src1 = dst_src1 + src2 * src3
instruct vfmlaF(vReg dst_src1, vReg src2, vReg src3) %{
predicate(UseFMA && UseSVE > 0 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 fneg
instruct vnegF(vReg dst, vReg src) %{
predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16);
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()->length_in_bytes() >= 16);
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);
%}
// popcount vector
instruct vpopcountI(vReg dst, vReg src) %{
predicate(UseSVE > 0 && n->as_Vector()->length() >= 4);
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 add reduction
instruct reduce_addB(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_BYTE);
match(Set dst (AddReductionVI src1 src2));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(SVE_COST);
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (B)\n\t"
"smov $dst, $tmp, B, 0\n\t"
"addw $dst, $dst, $src1\n\t"
"sxtb $dst, $dst\t # add reduction B" %}
ins_encode %{
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ B,
ptrue, as_FloatRegister($src2$$reg));
__ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ B, 0);
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
__ sxtb($dst$$Register, $dst$$Register);
%}
ins_pipe(pipe_slow);
%}
instruct reduce_addS(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
match(Set dst (AddReductionVI src1 src2));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(SVE_COST);
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (H)\n\t"
"smov $dst, $tmp, H, 0\n\t"
"addw $dst, $dst, $src1\n\t"
"sxth $dst, $dst\t # add reduction H" %}
ins_encode %{
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ H,
ptrue, as_FloatRegister($src2$$reg));
__ smov($dst$$Register, as_FloatRegister($tmp$$reg), __ H, 0);
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
__ sxth($dst$$Register, $dst$$Register);
%}
ins_pipe(pipe_slow);
%}
instruct reduce_addI(iRegINoSp dst, iRegIorL2I src1, vReg src2, vRegD tmp) %{
predicate(UseSVE > 0 && n->in(2)->bottom_type()->is_vect()->length_in_bytes() >= 16 &&
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_INT);
match(Set dst (AddReductionVI src1 src2));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(SVE_COST);
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (S)\n\t"
"umov $dst, $tmp, S, 0\n\t"
"addw $dst, $dst, $src1\t # add reduction S" %}
ins_encode %{
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ S,
ptrue, as_FloatRegister($src2$$reg));
__ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ S, 0);
__ addw($dst$$Register, $dst$$Register, $src1$$Register);
%}
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() >= 16 &&
n->in(2)->bottom_type()->is_vect()->element_basic_type() == T_LONG);
match(Set dst (AddReductionVL src1 src2));
effect(TEMP_DEF dst, TEMP tmp);
ins_cost(SVE_COST);
format %{ "sve_uaddv $tmp, $src2\t# vector (sve) (D)\n\t"
"umov $dst, $tmp, D, 0\n\t"
"add $dst, $dst, $src1\t # add reduction D" %}
ins_encode %{
__ sve_uaddv(as_FloatRegister($tmp$$reg), __ D,
ptrue, as_FloatRegister($src2$$reg));
__ umov($dst$$Register, as_FloatRegister($tmp$$reg), __ D, 0);
__ add($dst$$Register, $dst$$Register, $src1$$Register);
%}
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() >= 16);
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() >= 16);
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);
%}
// vector max reduction
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() >= 16);
match(Set dst (MaxReductionV src1 src2));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "sve_fmaxv $dst, $src2 # vector (sve) (S)\n\t"
"fmaxs $dst, $dst, $src1\t # max reduction F" %}
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_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() >= 16);
match(Set dst (MaxReductionV src1 src2));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "sve_fmaxv $dst, $src2 # vector (sve) (S)\n\t"
"fmaxs $dst, $dst, $src1\t # max reduction D" %}
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);
%}
// vector min reduction
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() >= 16);
match(Set dst (MinReductionV src1 src2));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "sve_fminv $dst, $src2 # vector (sve) (S)\n\t"
"fmins $dst, $dst, $src1\t # min reduction F" %}
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_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() >= 16);
match(Set dst (MinReductionV src1 src2));
ins_cost(INSN_COST);
effect(TEMP_DEF dst);
format %{ "sve_fminv $dst, $src2 # vector (sve) (S)\n\t"
"fmins $dst, $dst, $src1\t # min reduction D" %}
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);
%}
// vector Math.rint, floor, ceil
instruct vroundD(vReg dst, vReg src, immI rmode) %{
predicate(UseSVE > 0 && n->as_Vector()->length() >= 2 &&
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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->as_Vector()->length() >= 16 &&
(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->as_Vector()->length() >= 8 &&
(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->as_Vector()->length() >= 4 &&
(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->as_Vector()->length() >= 2 &&
(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 sqrt
instruct vsqrtF(vReg dst, vReg src) %{
predicate(UseSVE > 0 && n->as_Vector()->length_in_bytes() >= 16);
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()->length_in_bytes() >= 16);
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 sub
instruct vsubB(vReg dst, vReg src1, vReg src2) %{
predicate(UseSVE > 0 && n->as_Vector()->length() >= 16);
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 && n->as_Vector()->length() >= 8);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 && n->as_Vector()->length() >= 4);
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 && n->as_Vector()->length() >= 2);
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 mask cast
instruct vmaskcast(vReg dst) %{
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 (VectorMaskCast dst));
ins_cost(0);
format %{ "vmaskcast $dst\t# empty (sve)" %}
ins_encode %{
// empty
%}
ins_pipe(pipe_class_empty);
%}