[llvm] [RISCV] Refactor the MC layer SiFive VCIX classes. (PR #180433)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 8 19:11:25 PST 2026
================
@@ -49,124 +72,141 @@ def tsimm5 : RISCVOp, TImmLeaf<XLenVT, [{return isInt<5>(Imm);}]> {
let OperandType = "OPERAND_SIMM5";
}
-class SwapVCIXIns<dag funct6, dag rd, dag rs2, dag rs1, bit swap> {
- dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1);
+class VCIXInfo<VCIXType type, VCIXRs1Info rs1info, bit HaveOutputDst> {
+ bit HasOutput = HaveOutputDst;
+ VCIXRs1Info Rs1 = rs1info;
+ defvar suffix = rs1info.Prefix # type.Suffix;
+
+ string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix,
+ "sf.vc." # suffix);
+ bits<4> Funct6_hi4 = type.Val;
+ bits<3> Funct3 = rs1info.Funct3;
+
+ // TyRd is VR when there's an output or vd is a source operand, otherwise uimm5
+ defvar TyRd = !if(!or(HaveOutputDst, type.VdIsSource), VR, uimm5);
+
+ // TyRs2 is uimm5 when vs2 is an immediate, otherwise VR
+ defvar TyRs2 = !if(type.Vs2IsImmediate, uimm5, VR);
+
+ dag Outs = !cond(!not(HaveOutputDst): (outs),
+ type.VdIsSource: (outs TyRd:$vd_wb),
+ true: (outs TyRd:$vd));
+
+ // Vd operand: omitted from ins when HaveOutputDst and not a source operand
+ defvar VdOp = !if(!and(HaveOutputDst, !not(type.VdIsSource)),
+ (ins), (ins TyRd:$vd));
+
+ // Vs2 operand
+ defvar Vs2Op = (ins TyRs2:$vs2);
+
+ // Build Ins DAG: swap vd and vs2 order when vs2 is an immediate
+ dag Ins = !if(type.Vs2IsImmediate,
+ !con(rs1info.Funct6Op, Vs2Op, VdOp, rs1info.Op),
+ !con(rs1info.Funct6Op, VdOp, Vs2Op, rs1info.Op));
+
+ string ArgStr = !if(type.Vs2IsImmediate,
+ rs1info.Funct6Name # ", $vs2, $vd, " # rs1info.Name,
+ rs1info.Funct6Name # ", $vd, $vs2, " # rs1info.Name);
+
+ string Constraints = !if(!and(HaveOutputDst, type.VdIsSource),
+ "$vd = $vd_wb", "");
+
+ RISCVVConstraint RVVConstraint = !if(!and(HaveOutputDst, type.IsWidening),
+ !if(rs1info.IsVR, VCIXVS2VS1, VCIXVS2),
+ NoConstraint);
}
-class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
- string opcodestr, string argstr>
- : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
- bits<5> rs2;
- bits<5> rs1;
- bits<5> rd;
- bits<2> funct6_lo2;
- bit vm;
+// Common base class for VCIX instructions
+class RVInstVCCustom2Base<VCIXInfo info>
+ : RVInst<info.Outs, info.Ins, info.OpcodeStr, info.ArgStr, [], InstFormatR> {
+ bits<5> vs2;
+ bits<5> vd;
- let Inst{31-28} = funct6_hi4;
- let Inst{27-26} = funct6_lo2;
- let Inst{25} = vm;
- let Inst{24-20} = rs2;
- let Inst{19-15} = rs1;
- let Inst{14-12} = funct3;
- let Inst{11-7} = rd;
+ let Inst{31-28} = info.Funct6_hi4;
+ let Inst{25} = !not(info.HasOutput);
+ let Inst{24-20} = vs2;
+ let Inst{14-12} = info.Funct3;
+ let Inst{11-7} = vd;
let Inst{6-0} = OPC_CUSTOM_2.Value;
let Uses = [VL, VTYPE];
- let RVVConstraint = NoConstraint;
+ let Constraints = info.Constraints;
+ let RVVConstraint = info.RVVConstraint;
let ElementsDependOn = EltDepsVLMask;
let ReadsPastVL = 1;
}
-class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
- string opcodestr, string argstr>
- : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
- bits<5> rs2;
+// VCIX instructions with GPR rs1 operand
+class RVInstVCCustom2_X<VCIXInfo info> : RVInstVCCustom2Base<info> {
bits<5> rs1;
- bits<5> rd;
- bit funct6_lo1;
- bit vm;
+ bits<2> funct6_lo2;
- let Inst{31-28} = funct6_hi4;
- let Inst{27} = 1;
- let Inst{26} = funct6_lo1;
- let Inst{25} = vm;
- let Inst{24-20} = rs2;
+ let Inst{27-26} = funct6_lo2;
let Inst{19-15} = rs1;
- let Inst{14-12} = funct3;
- let Inst{11-7} = rd;
- let Inst{6-0} = OPC_CUSTOM_2.Value;
+}
- let Uses = [VL, VTYPE];
- let RVVConstraint = NoConstraint;
- let ElementsDependOn = EltDepsVLMask;
- let ReadsPastVL = 1;
+// VCIX instructions with VR vs1 operand
+class RVInstVCCustom2_V<VCIXInfo info> : RVInstVCCustom2Base<info> {
+ bits<5> vs1;
+ bits<2> funct6_lo2;
+
+ let Inst{27-26} = funct6_lo2;
+ let Inst{19-15} = vs1;
}
-class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd,
- DAGOperand TyRs2, DAGOperand TyRs1, bit HaveOutputDst> {
- string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix,
- "sf.vc." # suffix);
- bits<4> Funct6_hi4 = type.Val;
- bits<3> Funct3 = !cond(!eq(TyRs1, VR): 0b000,
- !eq(TyRs1, GPR): 0b100,
- !eq(TyRs1, FPR32): 0b101,
- !eq(TyRs1, simm5): 0b011);
- dag Outs = !if(!not(HaveOutputDst), (outs),
- !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)),
- (outs TyRd:$rd_wb), (outs TyRd:$rd)));
- dag Ins = SwapVCIXIns<!if(!ne(TyRs1, FPR32), (ins uimm2:$funct6_lo2),
- (ins uimm1:$funct6_lo1)),
- !if(!and(HaveOutputDst, !or(!eq(type, VCIX_X),
- !eq(type, VCIX_XV))),
- (ins), (ins TyRd:$rd)),
- (ins TyRs2:$rs2),
- (ins TyRs1:$rs1),
- !if(!eq(type, VCIX_X), 1, 0)>.Ins;
- string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1",
- !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1",
- "$funct6_lo1, $rd, $rs2, $rs1"));
- string Constraints = !if(!not(HaveOutputDst), "",
- !if(!or(!eq(type, VCIX_XVV),
- !eq(type, VCIX_XVW)), "$rd = $rd_wb", ""));
- RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst),
- !ne(type, VCIX_XVW)), NoConstraint,
- !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2));
-}
-
-class CustomSiFiveVCIX<VCIXInfo info>
- : RVInstVCCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
- info.Ins, info.OpcodeStr, info.Prototype> {
- let Constraints = info.Constraints;
- let RVVConstraint = info.RVVConstraint;
+// VCIX instructions with immediate operand
+class RVInstVCCustom2_I<VCIXInfo info> : RVInstVCCustom2Base<info> {
+ bits<5> imm;
+ bits<2> funct6_lo2;
+
+ let Inst{27-26} = funct6_lo2;
+ let Inst{19-15} = imm;
}
-class CustomSiFiveVCIF<VCIXInfo info>
- : RVInstVCFCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
- info.Ins, info.OpcodeStr, info.Prototype> {
- let Constraints = info.Constraints;
- let RVVConstraint = info.RVVConstraint;
+// VCIX instructions with FPR rs1 operand
+class RVInstVCFCustom2_F<VCIXInfo info> : RVInstVCCustom2Base<info> {
+ bits<5> rs1;
+ bit funct6_lo1;
+
+ let Inst{27} = 1;
+ let Inst{26} = funct6_lo1;
+ let Inst{19-15} = rs1;
}
-multiclass CustomSiFiveVCIXorVCIF<string suffix, VCIXType type,
- DAGOperand TyRd, DAGOperand TyRs2,
- DAGOperand TyRs1, bit HaveOutputDst> {
- defvar info = VCIXInfo<suffix, type, TyRd, TyRs2, TyRs1, HaveOutputDst>;
+multiclass CustomSiFiveVCIXorVCIF<VCIXInfo info> {
+ defvar TyRs1 = info.Rs1.Ty;
if !eq(TyRs1, FPR32) then {
- def NAME : CustomSiFiveVCIF<info>;
+ def NAME : RVInstVCFCustom2_F<info>;
+ } else if !eq(TyRs1, GPR) then {
+ def NAME : RVInstVCCustom2_X<info>;
+ } else if !eq(TyRs1, VR) then {
+ def NAME : RVInstVCCustom2_V<info>;
} else {
- def NAME : CustomSiFiveVCIX<info>;
+ def NAME : RVInstVCCustom2_I<info>;
}
}
-multiclass CustomSiFiveVCIX<string suffix, VCIXType type,
- DAGOperand InTyRd, DAGOperand InTyRs2,
- DAGOperand InTyRs1> {
- let vm = 1 in
- defm SF_VC_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, InTyRd, InTyRs2,
- InTyRs1, 0>;
- let vm = 0 in
- defm SF_VC_V_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, VR, InTyRs2,
- InTyRs1, 1>;
+multiclass CustomSiFiveVCIX<VCIXType type, VCIXRs1Info rs1> {
+ defm SF_VC_ # NAME : CustomSiFiveVCIXorVCIF<VCIXInfo<type, rs1, HaveOutputDst=0>>;
+ defm SF_VC_V_ # NAME : CustomSiFiveVCIXorVCIF<VCIXInfo<type, rs1, HaveOutputDst=1>>;
+}
+
+let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0,
+ hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvector" in {
+ defm X : CustomSiFiveVCIX<VCIX_X, VCIX_GPR>, Sched<[]>;
----------------
topperc wrote:
Yeah. I agree that's confusing. I'll fix it.
https://github.com/llvm/llvm-project/pull/180433
More information about the llvm-commits
mailing list