diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2276,40 +2276,59 @@ unsigned DestReg = Inst.getOperand(0).getReg(); // Operands[1] will be the first operand, DestReg. SMLoc Loc = Operands[1]->getStartLoc(); + unsigned Src2Idx = 1; + unsigned Src1Idx = 2; + unsigned MaskIdx; + // Masked instructions have 5 operands. vd, maskedoff, vs2, vs1, mask. + // Non-masked instructions have 3 operands. vd, vs2, vs1. + if (Inst.getNumOperands() == 5) { + Src2Idx = 2; + Src1Idx = 3; + MaskIdx = 4; + } if ((TargetFlags == RISCV::WidenV) || (TargetFlags == RISCV::WidenW) || - (TargetFlags == RISCV::SlideUp) || (TargetFlags == RISCV::Vrgather) || - (TargetFlags == RISCV::Vcompress)) { + (TargetFlags == RISCV::SlideUp) || (TargetFlags == RISCV::Vrgather)) { if (TargetFlags != RISCV::WidenW) { - unsigned Src2Reg = Inst.getOperand(1).getReg(); + unsigned Src2Reg = Inst.getOperand(Src2Idx).getReg(); if (DestReg == Src2Reg) return Error(Loc, "The destination vector register group cannot overlap" " the source vector register group."); } - if (Inst.getOperand(2).isReg()) { - unsigned Src1Reg = Inst.getOperand(2).getReg(); + if (Inst.getOperand(Src1Idx).isReg()) { + unsigned Src1Reg = Inst.getOperand(Src1Idx).getReg(); if (DestReg == Src1Reg) return Error(Loc, "The destination vector register group cannot overlap" " the source vector register group."); } - if (Inst.getNumOperands() == 4) { - unsigned MaskReg = Inst.getOperand(3).getReg(); + if (Inst.getNumOperands() == 5) { + unsigned MaskReg = Inst.getOperand(MaskIdx).getReg(); if (DestReg == MaskReg) return Error(Loc, "The destination vector register group cannot overlap" " the mask register."); } } else if (TargetFlags == RISCV::Narrow) { - unsigned Src2Reg = Inst.getOperand(1).getReg(); + unsigned Src2Reg = Inst.getOperand(Src2Idx).getReg(); + if (DestReg == Src2Reg) + return Error(Loc, "The destination vector register group cannot overlap" + " the source vector register group."); + } else if (TargetFlags == RISCV::Vcompress) { + unsigned Src2Reg = Inst.getOperand(2).getReg(); if (DestReg == Src2Reg) return Error(Loc, "The destination vector register group cannot overlap" " the source vector register group."); - } else if (TargetFlags == RISCV::WidenCvt || TargetFlags == RISCV::Iota) { - unsigned Src2Reg = Inst.getOperand(1).getReg(); + unsigned Src1Reg = Inst.getOperand(3).getReg(); + if (DestReg == Src1Reg) + return Error(Loc, "The destination vector register group cannot overlap" + " the source vector register group."); + } else if (TargetFlags == RISCV::WidenCvt || TargetFlags == RISCV::NarrowCvt || + TargetFlags == RISCV::Iota) { + unsigned Src2Reg = Inst.getOperand(2).getReg(); if (DestReg == Src2Reg) return Error(Loc, "The destination vector register group cannot overlap" " the source vector register group."); - if (Inst.getNumOperands() == 3) { - unsigned MaskReg = Inst.getOperand(2).getReg(); + if (Inst.getNumOperands() == 4) { + unsigned MaskReg = Inst.getOperand(3).getReg(); if (DestReg == MaskReg) return Error(Loc, "The destination vector register group cannot overlap" diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td --- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td +++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td @@ -58,10 +58,11 @@ def WidenCvt : RISCVVConstraint<3>; def QuadWiden : RISCVVConstraint<4>; def Narrow : RISCVVConstraint<5>; -def Iota : RISCVVConstraint<6>; -def SlideUp : RISCVVConstraint<7>; -def Vrgather : RISCVVConstraint<8>; -def Vcompress : RISCVVConstraint<9>; +def NarrowCvt : RISCVVConstraint<6>; +def Iota : RISCVVConstraint<7>; +def SlideUp : RISCVVConstraint<8>; +def Vrgather : RISCVVConstraint<9>; +def Vcompress : RISCVVConstraint<10>; // The following opcode names match those given in Table 19.1 in the // RISC-V User-level ISA specification ("RISC-V base opcode map"). diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.h b/llvm/lib/Target/RISCV/RISCVInstrInfo.h --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.h +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.h @@ -143,10 +143,11 @@ WidenCvt = 3, QuadWiden = 4, Narrow = 5, - Iota = 6, - SlideUp = 7, - Vrgather = 8, - Vcompress = 9, + NarrowCvt = 6, + Iota = 7, + SlideUp = 8, + Vrgather = 9, + Vcompress = 10, ConstraintOffset = 5, ConstraintMask = 0b1111 diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -97,19 +97,26 @@ class VUnitStrideLoad : RVInstVLU<0b000, mop, lumop, width, (outs VRegOp:$vd), - (ins GPR:$rs1, VMaskOp:$vm), opcodestr, "$vd, (${rs1})$vm">; + (ins VRegOp:$maskedoff, GPR:$rs1, VMaskOp:$vm), + opcodestr, "$vd, (${rs1})$vm"> { + let Constraints = "$vd = $maskedoff"; +} // load vd, (rs1), rs2, vm class VStridedLoad : RVInstVLS<0b000, mop, width, (outs VRegOp:$vd), - (ins GPR:$rs1, GPR:$rs2, VMaskOp:$vm), opcodestr, - "$vd, (${rs1}), $rs2$vm">; + (ins VRegOp:$maskedoff, GPR:$rs1, GPR:$rs2, VMaskOp:$vm), + opcodestr, "$vd, (${rs1}), $rs2$vm"> { + let Constraints = "$vd = $maskedoff"; +} // load vd, (rs1), vs2, vm class VIndexedLoad : RVInstVLX<0b000, mop, width, (outs VRegOp:$vd), - (ins GPR:$rs1, VRegOp:$vs2, VMaskOp:$vm), opcodestr, - "$vd, (${rs1}), $vs2$vm">; + (ins VRegOp:$maskedoff, GPR:$rs1, VRegOp:$vs2, VMaskOp:$vm), + opcodestr, "$vd, (${rs1}), $vs2$vm"> { + let Constraints = "$vd = $maskedoff"; +} // vlr.v vd, (rs1) class VWholeLoad nf, string opcodestr> @@ -153,10 +160,14 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { // op vd, vs2, vs1, vm -class VALUVV funct6, RISCVVFormat opv, string opcodestr> +class VALUVV funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVV; + (ins VRegOp:$maskedoff, VRegOp:$vs2, VRegOp:$vs1, VMaskOp:$vm), + opcodestr, "$vd, $vs2, $vs1$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs2, vs1, v0 (without mask, use v0 as carry input) class VALUmVV funct6, RISCVVFormat opv, string opcodestr> @@ -167,10 +178,14 @@ } // op vd, vs1, vs2, vm (reverse the order of vs1 and vs2) -class VALUrVV funct6, RISCVVFormat opv, string opcodestr> +class VALUrVV funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVV; + (ins VRegOp:$maskedoff, VRegOp:$vs1, VRegOp:$vs2, VMaskOp:$vm), + opcodestr, "$vd, $vs1, $vs2$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs1, vs2 class VALUVVNoVm funct6, RISCVVFormat opv, string opcodestr> @@ -180,25 +195,46 @@ let vm = 1; } +class VALUVVNoVmMaskedOff funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> + : RVInstVV { + let vm = 1; + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} + // op vd, vs2, rs1, vm -class VALUVX funct6, RISCVVFormat opv, string opcodestr> +class VALUVX funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVX; + (ins VRegOp:$maskedoff, VRegOp:$vs2, GPR:$rs1, VMaskOp:$vm), + opcodestr, "$vd, $vs2, $rs1$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs2, rs1, v0 (without mask, use v0 as carry input) -class VALUmVX funct6, RISCVVFormat opv, string opcodestr> +class VALUmVX funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVX { let vm = 0; + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); } // op vd, rs1, vs2, vm (reverse the order of rs1 and vs2) -class VALUrVX funct6, RISCVVFormat opv, string opcodestr> +class VALUrVX funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVX; + (ins VRegOp:$maskedoff, GPR:$rs1, VRegOp:$vs2, VMaskOp:$vm), + opcodestr, "$vd, $rs1, $vs2$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs1, vs2 class VALUVXNoVm funct6, RISCVVFormat opv, string opcodestr> @@ -209,10 +245,14 @@ } // op vd, vs2, imm, vm -class VALUVI funct6, string opcodestr, Operand optype = simm5> +class VALUVI funct6, string opcodestr, string constraints = "", + Operand optype = simm5> : RVInstIVI; + (ins VRegOp:$maskedoff, VRegOp:$vs2, optype:$imm, VMaskOp:$vm), + opcodestr, "$vd, $vs2, $imm$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs2, imm, v0 (without mask, use v0 as carry input) class VALUmVI funct6, string opcodestr, Operand optype = simm5> @@ -231,32 +271,45 @@ } // op vd, vs2, rs1, vm (Float) -class VALUVF funct6, RISCVVFormat opv, string opcodestr> +class VALUVF funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVX; + (ins VRegOp:$maskedoff, VRegOp:$vs2, FPR32:$rs1, VMaskOp:$vm), + opcodestr, "$vd, $vs2, $rs1$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, rs1, vs2, vm (Float) (with mask, reverse the order of rs1 and vs2) -class VALUrVF funct6, RISCVVFormat opv, string opcodestr> +class VALUrVF funct6, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstVX; + (ins VRegOp:$maskedoff, FPR32:$rs1, VRegOp:$vs2, VMaskOp:$vm), + opcodestr, "$vd, $rs1, $vs2$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} // op vd, vs2, vm (use vs1 as instruction encoding) -class VALUVs2 funct6, bits<5> vs1, RISCVVFormat opv, string opcodestr> +class VALUVs2 funct6, bits<5> vs1, RISCVVFormat opv, string opcodestr, + string constraints = ""> : RVInstV; + (ins VRegOp:$maskedoff, VRegOp:$vs2, VMaskOp:$vm), + opcodestr, "$vd, $vs2$vm"> { + let Constraints = !if(!eq(constraints, ""), "$vd = $maskedoff", + constraints#",$vd = $maskedoff"); +} } // hasSideEffects = 0, mayLoad = 0, mayStore = 0 //===----------------------------------------------------------------------===// // Combination of instruction classes. // Use these multiclasses to define instructions more easily. //===----------------------------------------------------------------------===// -multiclass VALU_IV_V_X_I funct6, Operand optype = simm5, string vw = "v"> { - def V : VALUVV; - def X : VALUVX; - def I : VALUVI; +multiclass VALU_IV_V_X_I funct6, Operand optype = simm5, + string constraints = "", string vw = "v"> { + def V : VALUVV; + def X : VALUVX; + def I : VALUVI; } multiclass VALU_IV_V_X funct6, string vw = "v"> { @@ -269,22 +322,24 @@ def X : VALUrVX; } -multiclass VALU_IV_X_I funct6, Operand optype = simm5, string vw = "v"> { - def X : VALUVX; - def I : VALUVI; +multiclass VALU_IV_X_I funct6, Operand optype = simm5, + string constraints = "", string vw = "v"> { + def X : VALUVX; + def I : VALUVI; } -multiclass VALU_IV_V funct6> { - def _VS : VALUVV; +multiclass VALU_IV_V funct6, string constraints> { + def _VS : VALUVV; } multiclass VALUr_IV_X funct6, string vw = "v"> { def X : VALUrVX; } -multiclass VALU_MV_V_X funct6, string vw = "v"> { - def V : VALUVV; - def X : VALUVX; +multiclass VALU_MV_V_X funct6, string constraints = "", + string vw = "v"> { + def V : VALUVV; + def X : VALUVX; } multiclass VALU_MV_V funct6> { @@ -295,21 +350,30 @@ def M : VALUVVNoVm; } -multiclass VALU_MV_X funct6, string vw = "v"> { - def X : VALUVX; +multiclass VALU_MV_Compress funct6, + string constraints> { + def M : VALUVVNoVmMaskedOff; } -multiclass VALUr_MV_V_X funct6, string vw = "v"> { - def V : VALUrVV; - def X : VALUrVX; +multiclass VALU_MV_X funct6, string constraints = "", + string vw = "v"> { + def X : VALUVX; } -multiclass VALUr_MV_X funct6, string vw = "v"> { - def X : VALUrVX; +multiclass VALUr_MV_V_X funct6, string constraints = "", + string vw = "v"> { + def V : VALUrVV; + def X : VALUrVX; } -multiclass VALU_MV_VS2 funct6, bits<5> vs1> { - def "" : VALUVs2; +multiclass VALUr_MV_X funct6, string constraints> { + def X : VALUrVX; +} + +multiclass VALU_MV_VS2 funct6, bits<5> vs1, + string constraints = ""> { + def "" : VALUVs2; } multiclass VALUm_IV_V_X_I funct6> { @@ -334,31 +398,36 @@ def X : VALUVXNoVm; } -multiclass VALU_FV_V_F funct6, string vw = "v"> { - def V : VALUVV; - def F : VALUVF; +multiclass VALU_FV_V_F funct6, string constraints = "", + string vw = "v"> { + def V : VALUVV; + def F : VALUVF; } -multiclass VALU_FV_F funct6, string vw = "v"> { +multiclass VALU_FV_F funct6, string constraints = "", + string vw = "v"> { def F : VALUVF; } -multiclass VALUr_FV_V_F funct6, string vw = "v"> { - def V : VALUrVV; - def F : VALUrVF; +multiclass VALUr_FV_V_F funct6, string constraints = "", + string vw = "v"> { + def V : VALUrVV; + def F : VALUrVF; } -multiclass VALU_FV_V funct6> { - def _VS : VALUVV; +multiclass VALU_FV_V funct6, string constraints = ""> { + def _VS : VALUVV; } -multiclass VALU_FV_VS2 funct6, bits<5> vs1> { - def "" : VALUVs2; +multiclass VALU_FV_VS2 funct6, bits<5> vs1, + string constraints = ""> { + def "" : VALUVs2; } //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// +defvar earlyclobber = "@earlyclobber $vd"; let Predicates = [HasStdExtV] in { let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in { @@ -446,24 +515,22 @@ // The destination vector register group cannot overlap a source vector // register group of a different element width (including the mask register // if masked), otherwise an illegal instruction exception is raised. -let Constraints = "@earlyclobber $vd" in { let RVVConstraint = WidenV in { -defm VWADDU_V : VALU_MV_V_X<"vwaddu", 0b110000>; -defm VWSUBU_V : VALU_MV_V_X<"vwsubu", 0b110010>; -defm VWADD_V : VALU_MV_V_X<"vwadd", 0b110001>; -defm VWSUB_V : VALU_MV_V_X<"vwsub", 0b110011>; +defm VWADDU_V : VALU_MV_V_X<"vwaddu", 0b110000, earlyclobber>; +defm VWSUBU_V : VALU_MV_V_X<"vwsubu", 0b110010, earlyclobber>; +defm VWADD_V : VALU_MV_V_X<"vwadd", 0b110001, earlyclobber>; +defm VWSUB_V : VALU_MV_V_X<"vwsub", 0b110011, earlyclobber>; } // RVVConstraint = WidenV // Set earlyclobber for following instructions for second and mask operands. // This has the downside that the earlyclobber constraint is too coarse and // will impose unnecessary restrictions by not allowing the destination to // overlap with the first (wide) operand. let RVVConstraint = WidenW in { -defm VWADDU_W : VALU_MV_V_X<"vwaddu", 0b110100, "w">; -defm VWSUBU_W : VALU_MV_V_X<"vwsubu", 0b110110, "w">; -defm VWADD_W : VALU_MV_V_X<"vwadd", 0b110101, "w">; -defm VWSUB_W : VALU_MV_V_X<"vwsub", 0b110111, "w">; +defm VWADDU_W : VALU_MV_V_X<"vwaddu", 0b110100, earlyclobber, "w">; +defm VWSUBU_W : VALU_MV_V_X<"vwsubu", 0b110110, earlyclobber, "w">; +defm VWADD_W : VALU_MV_V_X<"vwadd", 0b110101, earlyclobber, "w">; +defm VWSUB_W : VALU_MV_V_X<"vwsub", 0b110111, earlyclobber, "w">; } // RVVConstraint = WidenW -} // Constraints = "@earlyclobber $vd" def : InstAlias<"vwcvt.x.x.v $vd, $vs$vm", (VWADD_VX VRegOp:$vd, VRegOp:$vs, X0, VMaskOp:$vm)>; @@ -496,10 +563,10 @@ // The destination vector register group cannot overlap the first source // vector register group (specified by vs2). The destination vector register // group cannot overlap the mask register if used, unless LMUL=1. -let Constraints = "@earlyclobber $vd", RVVConstraint = Narrow in { -defm VNSRL_W : VALU_IV_V_X_I<"vnsrl", 0b101100, uimm5, "w">; -defm VNSRA_W : VALU_IV_V_X_I<"vnsra", 0b101101, uimm5, "w">; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Narrow +let RVVConstraint = Narrow in { +defm VNSRL_W : VALU_IV_V_X_I<"vnsrl", 0b101100, uimm5, earlyclobber, "w">; +defm VNSRA_W : VALU_IV_V_X_I<"vnsra", 0b101101, uimm5, earlyclobber, "w">; +} // RVVConstraint = Narrow // Vector Integer Comparison Instructions defm VMSEQ_V : VALU_IV_V_X_I<"vmseq", 0b011000>; @@ -551,11 +618,11 @@ defm VREM_V : VALU_MV_V_X<"vrem", 0b100011>; // Vector Widening Integer Multiply Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in { -defm VWMUL_V : VALU_MV_V_X<"vwmul", 0b111011>; -defm VWMULU_V : VALU_MV_V_X<"vwmulu", 0b111000>; -defm VWMULSU_V : VALU_MV_V_X<"vwmulsu", 0b111010>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV +let RVVConstraint = WidenV in { +defm VWMUL_V : VALU_MV_V_X<"vwmul", 0b111011, earlyclobber>; +defm VWMULU_V : VALU_MV_V_X<"vwmulu", 0b111000, earlyclobber>; +defm VWMULSU_V : VALU_MV_V_X<"vwmulsu", 0b111010, earlyclobber>; +} // RVVConstraint = WidenV // Vector Single-Width Integer Multiply-Add Instructions defm VMACC_V : VALUr_MV_V_X<"vmacc", 0b101101>; @@ -564,12 +631,12 @@ defm VNMSUB_V : VALUr_MV_V_X<"vnmsub", 0b101011>; // Vector Widening Integer Multiply-Add Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in { -defm VWMACCU_V : VALUr_MV_V_X<"vwmaccu", 0b111100>; -defm VWMACC_V : VALUr_MV_V_X<"vwmacc", 0b111101>; -defm VWMACCSU_V : VALUr_MV_V_X<"vwmaccsu", 0b111111>; -defm VWMACCUS_V : VALUr_MV_X<"vwmaccus", 0b111110>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV +let RVVConstraint = WidenV in { +defm VWMACCU_V : VALUr_MV_V_X<"vwmaccu", 0b111100, earlyclobber>; +defm VWMACC_V : VALUr_MV_V_X<"vwmacc", 0b111101, earlyclobber>; +defm VWMACCSU_V : VALUr_MV_V_X<"vwmaccsu", 0b111111, earlyclobber>; +defm VWMACCUS_V : VALUr_MV_X<"vwmaccus", 0b111110, earlyclobber>; +} // RVVConstraint = WidenV // Vector Integer Merge Instructions defm VMERGE_V : VALUm_IV_V_X_I<"vmerge", 0b010111>; @@ -607,10 +674,10 @@ defm VSSRA_V : VALU_IV_V_X_I<"vssra", 0b101011, uimm5>; // Vector Narrowing Fixed-Point Clip Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = Narrow in { -defm VNCLIPU_W : VALU_IV_V_X_I<"vnclipu", 0b101110, uimm5, "w">; -defm VNCLIP_W : VALU_IV_V_X_I<"vnclip", 0b101111, uimm5, "w">; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Narrow +let RVVConstraint = Narrow in { +defm VNCLIPU_W : VALU_IV_V_X_I<"vnclipu", 0b101110, uimm5, earlyclobber, "w">; +defm VNCLIP_W : VALU_IV_V_X_I<"vnclip", 0b101111, uimm5, earlyclobber, "w">; +} // RVVConstraint = Narrow // Vector Single-Width Floating-Point Add/Subtract Instructions defm VFADD_V : VALU_FV_V_F<"vfadd", 0b000000>; @@ -618,20 +685,18 @@ defm VFRSUB_V : VALU_FV_F<"vfrsub", 0b100111>; // Vector Widening Floating-Point Add/Subtract Instructions -let Constraints = "@earlyclobber $vd" in { let RVVConstraint = WidenV in { -defm VFWADD_V : VALU_FV_V_F<"vfwadd", 0b110000>; -defm VFWSUB_V : VALU_FV_V_F<"vfwsub", 0b110010>; +defm VFWADD_V : VALU_FV_V_F<"vfwadd", 0b110000, earlyclobber>; +defm VFWSUB_V : VALU_FV_V_F<"vfwsub", 0b110010, earlyclobber>; } // RVVConstraint = WidenV // Set earlyclobber for following instructions for second and mask operands. // This has the downside that the earlyclobber constraint is too coarse and // will impose unnecessary restrictions by not allowing the destination to // overlap with the first (wide) operand. let RVVConstraint = WidenW in { -defm VFWADD_W : VALU_FV_V_F<"vfwadd", 0b110100, "w">; -defm VFWSUB_W : VALU_FV_V_F<"vfwsub", 0b110110, "w">; +defm VFWADD_W : VALU_FV_V_F<"vfwadd", 0b110100, earlyclobber, "w">; +defm VFWSUB_W : VALU_FV_V_F<"vfwsub", 0b110110, earlyclobber, "w">; } // RVVConstraint = WidenW -} // Constraints = "@earlyclobber $vd" // Vector Single-Width Floating-Point Multiply/Divide Instructions defm VFMUL_V : VALU_FV_V_F<"vfmul", 0b100100>; @@ -639,9 +704,9 @@ defm VFRDIV_V : VALU_FV_F<"vfrdiv", 0b100001>; // Vector Widening Floating-Point Multiply -let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in { -defm VFWMUL_V : VALU_FV_V_F<"vfwmul", 0b111000>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV +let RVVConstraint = WidenV in { +defm VFWMUL_V : VALU_FV_V_F<"vfwmul", 0b111000, earlyclobber>; +} // RVVConstraint = WidenV // Vector Single-Width Floating-Point Fused Multiply-Add Instructions defm VFMACC_V : VALUr_FV_V_F<"vfmacc", 0b101100>; @@ -654,12 +719,12 @@ defm VFNMSUB_V : VALUr_FV_V_F<"vfnmsub", 0b101011>; // Vector Widening Floating-Point Fused Multiply-Add Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in { -defm VFWMACC_V : VALUr_FV_V_F<"vfwmacc", 0b111100>; -defm VFWNMACC_V : VALUr_FV_V_F<"vfwnmacc", 0b111101>; -defm VFWMSAC_V : VALUr_FV_V_F<"vfwmsac", 0b111110>; -defm VFWNMSAC_V : VALUr_FV_V_F<"vfwnmsac", 0b111111>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenV +let RVVConstraint = WidenV in { +defm VFWMACC_V : VALUr_FV_V_F<"vfwmacc", 0b111100, earlyclobber>; +defm VFWNMACC_V : VALUr_FV_V_F<"vfwnmacc", 0b111101, earlyclobber>; +defm VFWMSAC_V : VALUr_FV_V_F<"vfwmsac", 0b111110, earlyclobber>; +defm VFWNMSAC_V : VALUr_FV_V_F<"vfwnmsac", 0b111111, earlyclobber>; +} // RVVConstraint = WidenV // Vector Floating-Point Square-Root Instruction defm VFSQRT_V : VALU_FV_VS2<"vfsqrt.v", 0b100011, 0b00000>; @@ -712,23 +777,23 @@ defm VFCVT_F_X_V : VALU_FV_VS2<"vfcvt.f.x.v", 0b100010, 0b00011>; // Widening Floating-Point/Integer Type-Convert Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = WidenCvt in { -defm VFWCVT_XU_F_V : VALU_FV_VS2<"vfwcvt.xu.f.v", 0b100010, 0b01000>; -defm VFWCVT_X_F_V : VALU_FV_VS2<"vfwcvt.x.f.v", 0b100010, 0b01001>; -defm VFWCVT_F_XU_V : VALU_FV_VS2<"vfwcvt.f.xu.v", 0b100010, 0b01010>; -defm VFWCVT_F_X_V : VALU_FV_VS2<"vfwcvt.f.x.v", 0b100010, 0b01011>; -defm VFWCVT_F_F_V : VALU_FV_VS2<"vfwcvt.f.f.v", 0b100010, 0b01100>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = WidenCvt +let RVVConstraint = WidenCvt in { +defm VFWCVT_XU_F_V : VALU_FV_VS2<"vfwcvt.xu.f.v", 0b100010, 0b01000, earlyclobber>; +defm VFWCVT_X_F_V : VALU_FV_VS2<"vfwcvt.x.f.v", 0b100010, 0b01001, earlyclobber>; +defm VFWCVT_F_XU_V : VALU_FV_VS2<"vfwcvt.f.xu.v", 0b100010, 0b01010, earlyclobber>; +defm VFWCVT_F_X_V : VALU_FV_VS2<"vfwcvt.f.x.v", 0b100010, 0b01011, earlyclobber>; +defm VFWCVT_F_F_V : VALU_FV_VS2<"vfwcvt.f.f.v", 0b100010, 0b01100, earlyclobber>; +} // RVVConstraint = WidenCvt // Narrowing Floating-Point/Integer Type-Convert Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = Narrow in { -defm VFNCVT_XU_F_W : VALU_FV_VS2<"vfncvt.xu.f.w", 0b100010, 0b10000>; -defm VFNCVT_X_F_W : VALU_FV_VS2<"vfncvt.x.f.w", 0b100010, 0b10001>; -defm VFNCVT_F_XU_W : VALU_FV_VS2<"vfncvt.f.xu.w", 0b100010, 0b10010>; -defm VFNCVT_F_X_W : VALU_FV_VS2<"vfncvt.f.x.w", 0b100010, 0b10011>; -defm VFNCVT_F_F_W : VALU_FV_VS2<"vfncvt.f.f.w", 0b100010, 0b10100>; -defm VFNCVT_ROD_F_F_W : VALU_FV_VS2<"vfncvt.rod.f.f.w", 0b100010, 0b10101>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Narrow +let RVVConstraint = NarrowCvt in { +defm VFNCVT_XU_F_W : VALU_FV_VS2<"vfncvt.xu.f.w", 0b100010, 0b10000, earlyclobber>; +defm VFNCVT_X_F_W : VALU_FV_VS2<"vfncvt.x.f.w", 0b100010, 0b10001, earlyclobber>; +defm VFNCVT_F_XU_W : VALU_FV_VS2<"vfncvt.f.xu.w", 0b100010, 0b10010, earlyclobber>; +defm VFNCVT_F_X_W : VALU_FV_VS2<"vfncvt.f.x.w", 0b100010, 0b10011, earlyclobber>; +defm VFNCVT_F_F_W : VALU_FV_VS2<"vfncvt.f.f.w", 0b100010, 0b10100, earlyclobber>; +defm VFNCVT_ROD_F_F_W : VALU_FV_VS2<"vfncvt.rod.f.f.w", 0b100010, 0b10101, earlyclobber>; +} // RVVConstraint = NarrowCvt // Vector Single-Width Integer Reduction Instructions defm VREDSUM : VALU_MV_V<"vredsum", 0b000000>; @@ -741,14 +806,12 @@ defm VREDXOR : VALU_MV_V<"vredxor", 0b000011>; // Vector Widening Integer Reduction Instructions -let Constraints = "@earlyclobber $vd" in { // Set earlyclobber for following instructions for second and mask operands. // This has the downside that the earlyclobber constraint is too coarse and // will impose unnecessary restrictions by not allowing the destination to // overlap with the first (wide) operand. -defm VWREDSUMU : VALU_IV_V<"vwredsumu", 0b110000>; -defm VWREDSUM : VALU_IV_V<"vwredsum", 0b110001>; -} // Constraints = "@earlyclobber $vd" +defm VWREDSUMU : VALU_IV_V<"vwredsumu", 0b110000, earlyclobber>; +defm VWREDSUM : VALU_IV_V<"vwredsum", 0b110001, earlyclobber>; // Vector Single-Width Floating-Point Reduction Instructions defm VFREDOSUM : VALU_FV_V<"vfredosum", 0b000011>; @@ -757,14 +820,12 @@ defm VFREDMIN : VALU_FV_V<"vfredmin", 0b000101>; // Vector Widening Floating-Point Reduction Instructions -let Constraints = "@earlyclobber $vd" in { // Set earlyclobber for following instructions for second and mask operands. // This has the downside that the earlyclobber constraint is too coarse and // will impose unnecessary restrictions by not allowing the destination to // overlap with the first (wide) operand. -defm VFWREDOSUM : VALU_FV_V<"vfwredosum", 0b110011>; -defm VFWREDSUM : VALU_FV_V<"vfwredsum", 0b110001>; -} // Constraints = "@earlyclobber $vd" +defm VFWREDOSUM : VALU_FV_V<"vfwredosum", 0b110011, earlyclobber>; +defm VFWREDSUM : VALU_FV_V<"vfwredsum", 0b110001, earlyclobber>; // Vector Mask-Register Logical Instructions defm VMAND_M : VALU_MV_Mask<"vmand", 0b011001, "m">; @@ -807,9 +868,9 @@ defm VMSOF_M : VALU_MV_VS2<"vmsof.m", 0b010100, 0b00010>; // Vector Iota Instruction -let Constraints = "@earlyclobber $vd", RVVConstraint = Iota in { -defm VIOTA_M : VALU_MV_VS2<"viota.m", 0b010100, 0b10000>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Iota +let RVVConstraint = Iota in { +defm VIOTA_M : VALU_MV_VS2<"viota.m", 0b010100, 0b10000, earlyclobber>; +} // RVVConstraint = Iota // Vector Element Index Instruction let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { @@ -838,25 +899,25 @@ } // hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1 // Vector Slide Instructions -let Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp in { -defm VSLIDEUP_V : VALU_IV_X_I<"vslideup", 0b001110, uimm5>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp +let RVVConstraint = SlideUp in { +defm VSLIDEUP_V : VALU_IV_X_I<"vslideup", 0b001110, uimm5, earlyclobber>; +} // RVVConstraint = SlideUp defm VSLIDEDOWN_V : VALU_IV_X_I<"vslidedown", 0b001111, uimm5>; -let Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp in { -defm VSLIDE1UP_V : VALU_MV_X<"vslide1up", 0b001110>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp +let RVVConstraint = SlideUp in { +defm VSLIDE1UP_V : VALU_MV_X<"vslide1up", 0b001110, earlyclobber>; +} // RVVConstraint = SlideUp defm VSLIDE1DOWN_V : VALU_MV_X<"vslide1down", 0b001111>; // Vector Register Gather Instruction -let Constraints = "@earlyclobber $vd", RVVConstraint = Vrgather in { -defm VRGATHER_V : VALU_IV_V_X_I<"vrgather", 0b001100, uimm5>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Vrgather +let RVVConstraint = Vrgather in { +defm VRGATHER_V : VALU_IV_V_X_I<"vrgather", 0b001100, uimm5, earlyclobber>; +} // RVVConstraint = Vrgather // Vector Compress Instruction -let Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress in { -defm VCOMPRESS_V : VALU_MV_Mask<"vcompress", 0b010111>; -} // Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress +let RVVConstraint = Vcompress in { +defm VCOMPRESS_V : VALU_MV_Compress<"vcompress", 0b010111, earlyclobber>; +} // RVVConstraint = Vcompress let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { foreach nf = [1, 2, 4, 8] in {