1//===- IntrinsicsRISCVXsf.td - SiFive intrinsics -----------*- 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 defines all of the SiFive vendor intrinsics for RISC-V.
10//
11//===----------------------------------------------------------------------===//
12
13class VCIXSuffix<string range> {
14  list<string> suffix = !cond(!eq(range, "c"): ["e8mf8", "e8mf4", "e8mf2", "e8m1", "e8m2", "e8m4", "e8m8"],
15                              !eq(range, "s"): ["e16mf4", "e16mf2", "e16m1", "e16m2", "e16m4", "e16m8"],
16                              !eq(range, "i"): ["e32mf2", "e32m1", "e32m2", "e32m4", "e32m8"],
17                              !eq(range, "l"): ["e64m1", "e64m2", "e64m4", "e64m8"]);
18}
19
20let TargetPrefix = "riscv" in {
21  // Output: (vector_out)
22  // Input: (bit<27-26>, bit<24-20>, scalar_in, vl) or
23  class RISCVSFCustomVC_X<bit HasSE, bit ImmScalar>
24        : Intrinsic<[llvm_anyvector_ty],
25                    [llvm_anyint_ty, LLVMMatchType<1>, llvm_any_ty, llvm_anyint_ty],
26                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>],    // bit<27-26> and bit<24-20>
27                                !if(ImmScalar, [ImmArg<ArgIndex<2>>], []),                // ScalarOperand
28                                !if(HasSE, [IntrHasSideEffects], []))>,
29          RISCVVIntrinsic {
30    let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
31                              true: 2);
32    let VLOperand = 3;
33  }
34  // Output: ()
35  // Input: (bit<27-26>, bit<24-20>, bit<11-7>, scalar_in, sew, log2lmul, vl)
36  class RISCVSFCustomVC_X_WO_Suffix<bit ImmScalar>
37        : Intrinsic<[],
38                    [llvm_anyint_ty, LLVMMatchType<0>, LLVMMatchType<0>,
39                     llvm_any_ty, LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyint_ty],
40                    !listconcat([IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<0>>,
41                                 ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>,
42                                 ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>],    // bit<27-26>, bit<24-20>, bit<11-7>, sew, log2lmul
43                                !if(ImmScalar, [ImmArg<ArgIndex<3>>], []))>,   // ScalarOperand
44          RISCVVIntrinsic {
45    let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
46                              true: 3);
47    let VLOperand = 6;
48  }
49  // Output: (vector_out) or ()
50  // Input: (bit<27-26>, vector_in, vector_in/scalar_in, vl) or
51  //        (bit<27-26>, bit<11-7>, vector_in, vector_in/scalar_in, vl)
52  class RISCVSFCustomVC_XV<bit HasDst, bit HasSE, bit ImmScalar>
53        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
54                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty],
55                                            [llvm_anyint_ty, LLVMMatchType<0>, llvm_anyvector_ty]),
56                                [llvm_any_ty, llvm_anyint_ty]),
57                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
58                                !if(HasDst, [], [ImmArg<ArgIndex<1>>]),                  // Vd or bit<11-7>
59                                !if(ImmScalar, !if(HasDst, [ImmArg<ArgIndex<2>>],
60                                                           [ImmArg<ArgIndex<3>>]), []),  // ScalarOperand
61                                !if(HasSE, [IntrHasSideEffects], []))>,
62          RISCVVIntrinsic {
63    let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
64                              HasDst: 2,
65                              true: 3);
66    let VLOperand = !if(HasDst, 3, 4);
67  }
68  // Output: (vector_out) or ()
69  // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
70  //        (bit<27-26>, vector_in, vector_in, vector_in/scalar_in, vl)
71  class RISCVSFCustomVC_XVV<bit HasDst, bit HasSE, bit ImmScalar>
72        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
73                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty],
74                                            [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty]),
75                                [llvm_any_ty, llvm_anyint_ty]),
76                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
77                                !if(ImmScalar, [ImmArg<ArgIndex<3>>], []),               // ScalarOperand
78                                !if(HasSE, [IntrHasSideEffects], []))>,
79          RISCVVIntrinsic {
80    let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
81    let VLOperand = 4;
82  }
83  // Output: (wvector_out) or ()
84  // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
85  //        (bit<27-26>, wvector_in, vector_in, vector_in/scalar_in, vl)
86  class RISCVSFCustomVC_XVW<bit HasDst, bit HasSE, bit ImmScalar>
87        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
88                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty],
89                                            [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty]),
90                                [llvm_any_ty, llvm_anyint_ty]),
91                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
92                                !if(ImmScalar, [ImmArg<ArgIndex<3>>], []),               // ScalarOperand
93                                !if(HasSE, [IntrHasSideEffects], []))>,
94          RISCVVIntrinsic {
95    let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
96    let VLOperand = 4;
97  }
98
99  multiclass RISCVSFCustomVC_X<list<string> type> {
100    foreach t = type in {
101      defvar ImmScalar = !eq(t, "i");
102      def "int_riscv_sf_vc_" # t # "_se"   : RISCVSFCustomVC_X_WO_Suffix<ImmScalar=ImmScalar>;
103      def "int_riscv_sf_vc_v_" # t # "_se" : RISCVSFCustomVC_X<HasSE=1, ImmScalar=ImmScalar>;
104      def "int_riscv_sf_vc_v_" # t         : RISCVSFCustomVC_X<HasSE=0, ImmScalar=ImmScalar>;
105    }
106  }
107
108  multiclass RISCVSFCustomVC_XV<list<string> type> {
109    foreach t = type in {
110      defvar ImmScalar = !eq(t, "i");
111      def "int_riscv_sf_vc_" # t # "v_se"   : RISCVSFCustomVC_XV<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
112      def "int_riscv_sf_vc_v_" # t # "v_se" : RISCVSFCustomVC_XV<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
113      def "int_riscv_sf_vc_v_" # t # "v"    : RISCVSFCustomVC_XV<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
114    }
115  }
116
117  multiclass RISCVSFCustomVC_XVV<list<string> type> {
118    foreach t = type in {
119      defvar ImmScalar = !eq(t, "i");
120      def "int_riscv_sf_vc_" # t # "vv_se"   : RISCVSFCustomVC_XVV<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
121      def "int_riscv_sf_vc_v_" # t # "vv_se" : RISCVSFCustomVC_XVV<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
122      def "int_riscv_sf_vc_v_" # t # "vv"    : RISCVSFCustomVC_XVV<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
123    }
124  }
125
126  multiclass RISCVSFCustomVC_XVW<list<string> type> {
127    foreach t = type in {
128      defvar ImmScalar = !eq(t, "i");
129      def "int_riscv_sf_vc_" # t # "vw_se"   : RISCVSFCustomVC_XVW<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
130      def "int_riscv_sf_vc_v_" # t # "vw_se" : RISCVSFCustomVC_XVW<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
131      def "int_riscv_sf_vc_v_" # t # "vw"    : RISCVSFCustomVC_XVW<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
132    }
133  }
134
135  class RISCVSFCustomVMACC
136      : DefaultAttrsIntrinsic< [llvm_anyvector_ty],
137                   [LLVMMatchType<0>, llvm_anyvector_ty, llvm_anyvector_ty,
138                    llvm_anyint_ty, LLVMMatchType<3>],
139                   [ImmArg<ArgIndex<4>>, IntrNoMem] >, RISCVVIntrinsic {
140    let VLOperand = 3;
141  }
142
143  // Input: (passthru, vector_in, scalar_in, frm, vl)
144  class RISCVSFCustomVFNRCLIPUnMasked
145        : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
146                    [LLVMMatchType<0>, llvm_anyfloat_ty, LLVMVectorElementType<1>,
147                     llvm_anyint_ty, LLVMMatchType<2>],
148                    [ImmArg<ArgIndex<3>>, IntrNoMem]>, RISCVVIntrinsic {
149    let VLOperand = 4;
150  }
151
152  // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
153  class RISCVSFCustomVFNRCLIPMasked
154       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
155                   [LLVMMatchType<0>, llvm_anyfloat_ty, LLVMVectorElementType<1>,
156                    LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty,
157                    LLVMMatchType<2>, LLVMMatchType<2>],
158                   [ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<6>>, IntrNoMem]>, RISCVVIntrinsic {
159    let VLOperand = 5;
160  }
161
162  multiclass RISCVSFCustomVFNRCLIP {
163    def NAME : RISCVSFCustomVFNRCLIPUnMasked;
164    def NAME # "_mask" : RISCVSFCustomVFNRCLIPMasked;
165  }
166
167  defm "" : RISCVSFCustomVC_X<["x", "i"]>;
168  defm "" : RISCVSFCustomVC_XV<["x", "i", "v", "f"]>;
169  defm "" : RISCVSFCustomVC_XVV<["x", "i", "v", "f"]>;
170  defm "" : RISCVSFCustomVC_XVW<["x", "i", "v", "f"]>;
171
172  // XSfvqmaccdod
173  def int_riscv_sf_vqmaccu_2x8x2  : RISCVSFCustomVMACC;
174  def int_riscv_sf_vqmacc_2x8x2   : RISCVSFCustomVMACC;
175  def int_riscv_sf_vqmaccus_2x8x2 : RISCVSFCustomVMACC;
176  def int_riscv_sf_vqmaccsu_2x8x2 : RISCVSFCustomVMACC;
177
178  // XSfvqmaccqoq
179  def int_riscv_sf_vqmaccu_4x8x4  : RISCVSFCustomVMACC;
180  def int_riscv_sf_vqmacc_4x8x4   : RISCVSFCustomVMACC;
181  def int_riscv_sf_vqmaccus_4x8x4 : RISCVSFCustomVMACC;
182  def int_riscv_sf_vqmaccsu_4x8x4 : RISCVSFCustomVMACC;
183
184  // XSfvfwmaccqqq
185  def int_riscv_sf_vfwmacc_4x4x4 : RISCVSFCustomVMACC;
186
187  // XSfvfnrclipxfqf
188  defm int_riscv_sf_vfnrclip_x_f_qf : RISCVSFCustomVFNRCLIP;
189  defm int_riscv_sf_vfnrclip_xu_f_qf : RISCVSFCustomVFNRCLIP;
190} // TargetPrefix = "riscv"
191