xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td (revision 02e9120893770924227138ba49df1edb3896112a)
1//===-- RISCVInstrInfoXsf.td - SiFive custom instructions --*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the vendor extensions defined by SiFive.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// XSFVCP extension instructions.
15//===----------------------------------------------------------------------===//
16
17def VCIXVS2    : RISCVVConstraint<VS2Constraint.Value>;
18def VCIXVS2VS1 : RISCVVConstraint<!or(VS2Constraint.Value,
19                                      VS1Constraint.Value)>;
20
21class VCIXType<bits<4> val> {
22  bits<4> Val = val;
23}
24
25def VCIX_X   : VCIXType<0b0000>;
26def VCIX_XV  : VCIXType<0b0010>;
27def VCIX_XVV : VCIXType<0b1010>;
28def VCIX_XVW : VCIXType<0b1111>;
29
30// The payload and timm5 operands are all marked as ImmArg in the IR
31// intrinsic and will be target constant, so use TImmLeaf rather than ImmLeaf.
32def payload1 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<1>(Imm);}]> {
33  let ParserMatchClass = UImmAsmOperand<1>;
34  let DecoderMethod = "decodeUImmOperand<1>";
35  let OperandType = "OPERAND_UIMM1";
36  let OperandNamespace = "RISCVOp";
37}
38
39def payload2 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]> {
40  let ParserMatchClass = UImmAsmOperand<2>;
41  let DecoderMethod = "decodeUImmOperand<2>";
42  let OperandType = "OPERAND_UIMM2";
43  let OperandNamespace = "RISCVOp";
44}
45
46def payload5 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
47  let ParserMatchClass = UImmAsmOperand<5>;
48  let DecoderMethod = "decodeUImmOperand<5>";
49  let OperandType = "OPERAND_UIMM5";
50  let OperandNamespace = "RISCVOp";
51}
52
53def timm5 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isInt<5>(Imm);}]> {
54  let ParserMatchClass = SImmAsmOperand<5>;
55  let EncoderMethod = "getImmOpValue";
56  let DecoderMethod = "decodeSImmOperand<5>";
57  let MCOperandPredicate = [{
58    int64_t Imm;
59    if (MCOp.evaluateAsConstantImm(Imm))
60      return isInt<5>(Imm);
61    return MCOp.isBareSymbolRef();
62  }];
63}
64
65class SwapVCIXIns<dag funct6, dag rd, dag rs2, dag rs1, bit swap> {
66  dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1);
67}
68
69class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
70                      string opcodestr, string argstr>
71    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
72  bits<5> rs2;
73  bits<5> rs1;
74  bits<5> rd;
75  bits<2> funct6_lo2;
76  bit vm;
77
78  let Inst{31-28} = funct6_hi4;
79  let Inst{27-26} = funct6_lo2;
80  let Inst{25} = vm;
81  let Inst{24-20} = rs2;
82  let Inst{19-15} = rs1;
83  let Inst{14-12} = funct3;
84  let Inst{11-7} = rd;
85  let Inst{6-0} = OPC_CUSTOM_2.Value;
86
87  let Uses = [VTYPE, VL];
88  let RVVConstraint = NoConstraint;
89}
90
91class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
92                       string opcodestr, string argstr>
93    : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
94  bits<5> rs2;
95  bits<5> rs1;
96  bits<5> rd;
97  bit funct6_lo1;
98  bit vm;
99
100  let Inst{31-28} = funct6_hi4;
101  let Inst{27} = 1;
102  let Inst{26} = funct6_lo1;
103  let Inst{25} = vm;
104  let Inst{24-20} = rs2;
105  let Inst{19-15} = rs1;
106  let Inst{14-12} = funct3;
107  let Inst{11-7} = rd;
108  let Inst{6-0} = OPC_CUSTOM_2.Value;
109
110  let Uses = [VTYPE, VL];
111  let RVVConstraint = NoConstraint;
112}
113
114class GetFTypeInfo<int sew> {
115  ValueType Scalar = !cond(!eq(sew, 16): f16,
116                           !eq(sew, 32): f32,
117                           !eq(sew, 64): f64);
118  RegisterClass ScalarRegClass = !cond(!eq(sew, 16): FPR16,
119                                       !eq(sew, 32): FPR32,
120                                       !eq(sew, 64): FPR64);
121}
122
123class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd,
124               DAGOperand TyRs2, DAGOperand TyRs1, bit HaveOutputDst> {
125  string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix,
126                                        "sf.vc." # suffix);
127  bits<4> Funct6_hi4 = type.Val;
128  bits<3> Funct3 = !cond(!eq(TyRs1, VR):    0b000,
129                         !eq(TyRs1, GPR):   0b100,
130                         !eq(TyRs1, FPR32): 0b101,
131                         !eq(TyRs1, simm5): 0b011);
132  dag Outs = !if(!not(HaveOutputDst), (outs),
133                 !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)),
134                     (outs TyRd:$rd_wb), (outs TyRd:$rd)));
135  dag Ins = SwapVCIXIns<!if(!ne(TyRs1, FPR32), (ins uimm2:$funct6_lo2),
136                                               (ins uimm1:$funct6_lo1)),
137                        !if(!and(HaveOutputDst, !or(!eq(type, VCIX_X),
138                                                    !eq(type, VCIX_XV))),
139                            (ins), (ins TyRd:$rd)),
140                        (ins TyRs2:$rs2),
141                        (ins TyRs1:$rs1),
142                        !if(!eq(type, VCIX_X), 1, 0)>.Ins;
143  string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1",
144                         !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1",
145                                                "$funct6_lo1, $rd, $rs2, $rs1"));
146  string Constraints = !if(!not(HaveOutputDst), "",
147                           !if(!or(!eq(type, VCIX_XVV),
148                                   !eq(type, VCIX_XVW)), "$rd = $rd_wb", ""));
149  RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst),
150                                           !ne(type, VCIX_XVW)), NoConstraint,
151                                       !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2));
152}
153
154class CustomSiFiveVCIX<VCIXInfo info>
155  : RVInstVCCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
156                    info.Ins, info.OpcodeStr, info.Prototype> {
157  let Constraints = info.Constraints;
158  let RVVConstraint = info.RVVConstraint;
159}
160
161class CustomSiFiveVCIF<VCIXInfo info>
162  : RVInstVCFCustom2<info.Funct6_hi4, info.Funct3, info.Outs,
163                     info.Ins, info.OpcodeStr, info.Prototype> {
164  let Constraints = info.Constraints;
165  let RVVConstraint = info.RVVConstraint;
166}
167
168multiclass CustomSiFiveVCIXorVCIF<string suffix, VCIXType type,
169                                  DAGOperand TyRd, DAGOperand TyRs2,
170                                  DAGOperand TyRs1, bit HaveOutputDst> {
171  defvar info = VCIXInfo<suffix, type, TyRd, TyRs2, TyRs1, HaveOutputDst>;
172  if !eq(TyRs1, FPR32) then {
173    def NAME : CustomSiFiveVCIF<info>;
174  } else {
175    def NAME : CustomSiFiveVCIX<info>;
176  }
177}
178
179multiclass CustomSiFiveVCIX<string suffix, VCIXType type,
180                            DAGOperand InTyRd, DAGOperand InTyRs2,
181                            DAGOperand InTyRs1> {
182  let vm = 1 in
183  defm VC_ # NAME   : CustomSiFiveVCIXorVCIF<suffix, type, InTyRd, InTyRs2,
184                                             InTyRs1, 0>;
185  let vm = 0 in
186  defm VC_V_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, VR, InTyRs2,
187                                             InTyRs1, 1>;
188}
189
190let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0,
191    hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvcp" in {
192  defm X   : CustomSiFiveVCIX<"x",   VCIX_X,   uimm5, uimm5, GPR>,   Sched<[]>;
193  defm I   : CustomSiFiveVCIX<"i",   VCIX_X,   uimm5, uimm5, simm5>, Sched<[]>;
194  defm XV  : CustomSiFiveVCIX<"xv",  VCIX_XV,  uimm5, VR,    GPR>,   Sched<[]>;
195  defm IV  : CustomSiFiveVCIX<"iv",  VCIX_XV,  uimm5, VR,    simm5>, Sched<[]>;
196  defm VV  : CustomSiFiveVCIX<"vv",  VCIX_XV,  uimm5, VR,    VR>,    Sched<[]>;
197  defm FV  : CustomSiFiveVCIX<"fv",  VCIX_XV,  uimm5, VR,    FPR32>, Sched<[]>;
198  defm XVV : CustomSiFiveVCIX<"xvv", VCIX_XVV, VR,    VR,    GPR>,   Sched<[]>;
199  defm IVV : CustomSiFiveVCIX<"ivv", VCIX_XVV, VR,    VR,    simm5>, Sched<[]>;
200  defm VVV : CustomSiFiveVCIX<"vvv", VCIX_XVV, VR,    VR,    VR>,    Sched<[]>;
201  defm FVV : CustomSiFiveVCIX<"fvv", VCIX_XVV, VR,    VR,    FPR32>, Sched<[]>;
202  defm XVW : CustomSiFiveVCIX<"xvw", VCIX_XVW, VR,    VR,    GPR>,   Sched<[]>;
203  defm IVW : CustomSiFiveVCIX<"ivw", VCIX_XVW, VR,    VR,    simm5>, Sched<[]>;
204  defm VVW : CustomSiFiveVCIX<"vvw", VCIX_XVW, VR,    VR,    VR>,    Sched<[]>;
205  defm FVW : CustomSiFiveVCIX<"fvw", VCIX_XVW, VR,    VR,    FPR32>, Sched<[]>;
206}
207
208class VPseudoVC_X<Operand OpClass, DAGOperand RS1Class,
209                  bit HasSideEffect = 1> :
210      Pseudo<(outs),
211             (ins OpClass:$op1, payload5:$rs2, payload5:$rd, RS1Class:$r1,
212                  AVL:$vl, ixlenimm:$sew), []>,
213      RISCVVPseudo {
214  let mayLoad = 0;
215  let mayStore = 0;
216  let HasVLOp = 1;
217  let HasSEWOp = 1;
218  let hasSideEffects = HasSideEffect;
219  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
220}
221
222class VPseudoVC_XV<Operand OpClass, VReg RS2Class, DAGOperand RS1Class,
223                   bit HasSideEffect = 1> :
224      Pseudo<(outs),
225             (ins OpClass:$op1, payload5:$rd, RS2Class:$rs2, RS1Class:$r1,
226                  AVL:$vl, ixlenimm:$sew), []>,
227      RISCVVPseudo {
228  let mayLoad = 0;
229  let mayStore = 0;
230  let HasVLOp = 1;
231  let HasSEWOp = 1;
232  let hasSideEffects = HasSideEffect;
233  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
234}
235
236class VPseudoVC_XVV<Operand OpClass, VReg RDClass, VReg RS2Class,
237                    DAGOperand RS1Class, bit HasSideEffect = 1> :
238      Pseudo<(outs),
239             (ins OpClass:$op1, RDClass:$rd, RS2Class:$rs2, RS1Class:$r1,
240                  AVL:$vl, ixlenimm:$sew), []>,
241      RISCVVPseudo {
242  let mayLoad = 0;
243  let mayStore = 0;
244  let HasVLOp = 1;
245  let HasSEWOp = 1;
246  let hasSideEffects = HasSideEffect;
247  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
248}
249
250class VPseudoVC_V_X<Operand OpClass, VReg RDClass, DAGOperand RS1Class,
251                    bit HasSideEffect = 1> :
252      Pseudo<(outs RDClass:$rd),
253             (ins OpClass:$op1, payload5:$rs2, RS1Class:$r1,
254                  AVL:$vl, ixlenimm:$sew), []>,
255      RISCVVPseudo {
256  let mayLoad = 0;
257  let mayStore = 0;
258  let HasVLOp = 1;
259  let HasSEWOp = 1;
260  let hasSideEffects = HasSideEffect;
261  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
262}
263
264class VPseudoVC_V_XV<Operand OpClass, VReg RDClass, VReg RS2Class,
265                     DAGOperand RS1Class, bit HasSideEffect = 1> :
266      Pseudo<(outs RDClass:$rd),
267             (ins OpClass:$op1, RS2Class:$rs2, RS1Class:$r1,
268                  AVL:$vl, ixlenimm:$sew), []>,
269      RISCVVPseudo {
270  let mayLoad = 0;
271  let mayStore = 0;
272  let HasVLOp = 1;
273  let HasSEWOp = 1;
274  let hasSideEffects = HasSideEffect;
275  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
276}
277
278class VPseudoVC_V_XVV<Operand OpClass, VReg RDClass, VReg RS2Class,
279                      DAGOperand RS1Class, bit HasSideEffect = 1> :
280      Pseudo<(outs RDClass:$rd),
281             (ins OpClass:$op1, RDClass:$rs3, RS2Class:$rs2, RS1Class:$r1,
282                  AVL:$vl, ixlenimm:$sew), []>,
283      RISCVVPseudo {
284  let mayLoad = 0;
285  let mayStore = 0;
286  let HasVLOp = 1;
287  let HasSEWOp = 1;
288  let hasSideEffects = HasSideEffect;
289  let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
290}
291
292multiclass VPseudoVC_X<LMULInfo m, DAGOperand RS1Class,
293                       Operand OpClass = payload2> {
294  let VLMul = m.value in {
295    def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_X<OpClass, RS1Class>;
296    def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class>;
297    def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class, 0>;
298  }
299}
300
301multiclass VPseudoVC_XV<LMULInfo m, DAGOperand RS1Class,
302                        Operand OpClass = payload2> {
303  let VLMul = m.value in {
304    def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XV<OpClass, m.vrclass, RS1Class>;
305    def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class>;
306    def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>;
307  }
308}
309
310multiclass VPseudoVC_XVV<LMULInfo m, DAGOperand RS1Class,
311                         Operand OpClass = payload2> {
312  let VLMul = m.value in {
313    def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>;
314    def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>;
315    def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>;
316  }
317}
318
319multiclass VPseudoVC_XVW<LMULInfo m, DAGOperand RS1Class,
320                         Operand OpClass = payload2> {
321  let VLMul = m.value in {
322    def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>;
323    let Constraints = "@earlyclobber $rd, $rd = $rs3" in {
324      def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>;
325      def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class, 0>;
326    }
327  }
328}
329
330let Predicates = [HasVendorXSfvcp] in {
331  foreach m = MxList in {
332    defm X : VPseudoVC_X<m, GPR>;
333    defm I : VPseudoVC_X<m, timm5>;
334    defm XV : VPseudoVC_XV<m, GPR>;
335    defm IV : VPseudoVC_XV<m, timm5>;
336    defm VV : VPseudoVC_XV<m, m.vrclass>;
337    defm XVV : VPseudoVC_XVV<m, GPR>;
338    defm IVV : VPseudoVC_XVV<m, timm5>;
339    defm VVV : VPseudoVC_XVV<m, m.vrclass>;
340  }
341  foreach f = FPList in {
342    foreach m = f.MxList in {
343    defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>;
344    defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>;
345    }
346  }
347  foreach m = MxListW in {
348    defm XVW : VPseudoVC_XVW<m, GPR>;
349    defm IVW : VPseudoVC_XVW<m, timm5>;
350    defm VVW : VPseudoVC_XVW<m, m.vrclass>;
351  }
352  foreach f = FPListW in {
353    foreach m = f.MxList in
354    defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>;
355  }
356}
357
358class VPatVC_OP4<string intrinsic_name,
359                 string inst,
360                 ValueType op2_type,
361                 ValueType op3_type,
362                 ValueType op4_type,
363                 int sew,
364                 DAGOperand op2_kind,
365                 DAGOperand op3_kind,
366                 DAGOperand op4_kind,
367                 Operand op1_kind = payload2> :
368  Pat<(!cast<Intrinsic>(intrinsic_name)
369       (XLenVT   op1_kind:$op1),
370       (op2_type op2_kind:$op2),
371       (op3_type op3_kind:$op3),
372       (op4_type op4_kind:$op4),
373       VLOpFrag),
374      (!cast<Instruction>(inst)
375       (XLenVT   op1_kind:$op1),
376       (op2_type op2_kind:$op2),
377       (op3_type op3_kind:$op3),
378       (op4_type op4_kind:$op4),
379       GPR:$vl, sew)>;
380
381class VPatVC_V_OP4<string intrinsic_name,
382                   string inst,
383                   ValueType result_type,
384                   ValueType op2_type,
385                   ValueType op3_type,
386                   ValueType op4_type,
387                   int sew,
388                   DAGOperand op2_kind,
389                   DAGOperand op3_kind,
390                   DAGOperand op4_kind,
391                   Operand op1_kind = payload2> :
392  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
393                    (XLenVT   op1_kind:$op1),
394                    (op2_type op2_kind:$op2),
395                    (op3_type op3_kind:$op3),
396                    (op4_type op4_kind:$op4),
397                    VLOpFrag)),
398                   (!cast<Instruction>(inst)
399                    (XLenVT   op1_kind:$op1),
400                    (op2_type op2_kind:$op2),
401                    (op3_type op3_kind:$op3),
402                    (op4_type op4_kind:$op4),
403                    GPR:$vl, sew)>;
404
405class VPatVC_V_OP3<string intrinsic_name,
406                   string inst,
407                   ValueType result_type,
408                   ValueType op2_type,
409                   ValueType op3_type,
410                   int sew,
411                   DAGOperand op2_kind,
412                   DAGOperand op3_kind,
413                   Operand op1_kind = payload2> :
414  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
415                    (XLenVT   op1_kind:$op1),
416                    (op2_type op2_kind:$op2),
417                    (op3_type op3_kind:$op3),
418                    VLOpFrag)),
419                   (!cast<Instruction>(inst)
420                    (XLenVT   op1_kind:$op1),
421                    (op2_type op2_kind:$op2),
422                    (op3_type op3_kind:$op3),
423                    GPR:$vl, sew)>;
424
425multiclass VPatVC_X<string intrinsic_suffix, string instruction_suffix,
426                    VTypeInfo vti, ValueType type, DAGOperand kind> {
427  def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se_e" # vti.SEW # !tolower(vti.LMul.MX),
428                   "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX,
429                   XLenVT, XLenVT, type, vti.Log2SEW,
430                   payload5, payload5, kind>;
431  def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se",
432                     "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX,
433                     vti.Vector, XLenVT, type, vti.Log2SEW,
434                     payload5, kind>;
435  def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix,
436                     "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX,
437                     vti.Vector, XLenVT, type, vti.Log2SEW,
438                     payload5, kind>;
439}
440
441multiclass VPatVC_XV<string intrinsic_suffix, string instruction_suffix,
442                     VTypeInfo vti, ValueType type, DAGOperand kind,
443                     Operand op1_kind = payload2> {
444  def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se",
445                   "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX,
446                   XLenVT, vti.Vector, type, vti.Log2SEW,
447                   payload5, vti.RegClass, kind, op1_kind>;
448  def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se",
449                     "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX,
450                     vti.Vector, vti.Vector, type, vti.Log2SEW,
451                     vti.RegClass, kind, op1_kind>;
452  def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix,
453                     "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX,
454                     vti.Vector, vti.Vector, type, vti.Log2SEW,
455                     vti.RegClass, kind, op1_kind>;
456}
457
458multiclass VPatVC_XVV<string intrinsic_suffix, string instruction_suffix,
459                      VTypeInfo wti, VTypeInfo vti, ValueType type, DAGOperand kind,
460                      Operand op1_kind = payload2> {
461  def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se",
462                   "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX,
463                   wti.Vector, vti.Vector, type, vti.Log2SEW,
464                   wti.RegClass, vti.RegClass, kind, op1_kind>;
465  def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se",
466                     "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX,
467                     wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW,
468                     wti.RegClass, vti.RegClass, kind, op1_kind>;
469  def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix,
470                     "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX,
471                     wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW,
472                     wti.RegClass, vti.RegClass, kind, op1_kind>;
473}
474
475let Predicates = [HasVendorXSfvcp] in {
476  foreach vti = AllIntegerVectors in {
477    defm : VPatVC_X<"x", "X", vti, vti.Scalar, vti.ScalarRegClass>;
478    defm : VPatVC_X<"i", "I", vti, XLenVT, timm5>;
479    defm : VPatVC_XV<"xv", "XV", vti, vti.Scalar, vti.ScalarRegClass>;
480    defm : VPatVC_XV<"iv", "IV", vti, XLenVT, timm5>;
481    defm : VPatVC_XV<"vv", "VV", vti, vti.Vector, vti.RegClass>;
482    defm : VPatVC_XVV<"xvv", "XVV", vti, vti, vti.Scalar, vti.ScalarRegClass>;
483    defm : VPatVC_XVV<"ivv", "IVV", vti, vti, XLenVT, timm5>;
484    defm : VPatVC_XVV<"vvv", "VVV", vti, vti, vti.Vector, vti.RegClass>;
485    if !ge(vti.SEW, 16) then {
486      defm : VPatVC_XV<"fv", "F" # vti.SEW # "V", vti,
487                       GetFTypeInfo<vti.SEW>.Scalar,
488                       GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>;
489      defm : VPatVC_XVV<"fvv", "F" # vti.SEW # "VV", vti, vti,
490                        GetFTypeInfo<vti.SEW>.Scalar,
491                        GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>;
492    }
493  }
494  foreach VtiToWti = AllWidenableIntVectors in {
495    defvar vti = VtiToWti.Vti;
496    defvar wti = VtiToWti.Wti;
497    defm : VPatVC_XVV<"xvw", "XVW", wti, vti, vti.Scalar, vti.ScalarRegClass>;
498    defm : VPatVC_XVV<"ivw", "IVW", wti, vti, XLenVT, timm5>;
499    defm : VPatVC_XVV<"vvw", "VVW", wti, vti, vti.Vector, vti.RegClass>;
500    if !ge(vti.SEW, 16) then {
501      defm : VPatVC_XVV<"fvw", "F" # vti.SEW # "VW", wti, vti,
502                        GetFTypeInfo<vti.SEW>.Scalar,
503                        GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>;
504    }
505  }
506}
507
508let Predicates = [HasVendorXSfcie] in {
509let hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSfcie" in {
510def SF_CFLUSH_D_L1 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "cflush.d.l1","$rs1">,
511                             Sched<[]> {
512  let rd = 0;
513  let imm12 = {0b1111,0b1100,0b0000};
514}
515
516def SF_CDISCARD_D_L1 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "cdiscard.d.l1","$rs1">,
517                               Sched<[]> {
518  let rd = 0;
519  let imm12 = {0b1111,0b1100,0b0010};
520}
521
522def SF_CEASE : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "cease","">,  Sched<[]> {
523  let rs1 = 0;
524  let rd = 0;
525  let imm12 = {0b0011,0b0000,0b0101};
526}
527}
528def : InstAlias<"cflush.d.l1", (SF_CFLUSH_D_L1 X0)>;
529def : InstAlias<"cdiscard.d.l1", (SF_CDISCARD_D_L1 X0)>;
530} // Predicates = [HasVendorXScie]
531