106c3fb27SDimitry Andric//===- IntrinsicsRISCVXsf.td - SiFive intrinsics -----------*- tablegen -*-===//
206c3fb27SDimitry Andric//
306c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric//
706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric//
906c3fb27SDimitry Andric// This file defines all of the SiFive vendor intrinsics for RISC-V.
1006c3fb27SDimitry Andric//
1106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1206c3fb27SDimitry Andric
1306c3fb27SDimitry Andricclass VCIXSuffix<string range> {
1406c3fb27SDimitry Andric  list<string> suffix = !cond(!eq(range, "c"): ["e8mf8", "e8mf4", "e8mf2", "e8m1", "e8m2", "e8m4", "e8m8"],
1506c3fb27SDimitry Andric                              !eq(range, "s"): ["e16mf4", "e16mf2", "e16m1", "e16m2", "e16m4", "e16m8"],
1606c3fb27SDimitry Andric                              !eq(range, "i"): ["e32mf2", "e32m1", "e32m2", "e32m4", "e32m8"],
1706c3fb27SDimitry Andric                              !eq(range, "l"): ["e64m1", "e64m2", "e64m4", "e64m8"]);
1806c3fb27SDimitry Andric}
1906c3fb27SDimitry Andric
2006c3fb27SDimitry Andriclet TargetPrefix = "riscv" in {
2106c3fb27SDimitry Andric  // Output: (vector_out) or ()
2206c3fb27SDimitry Andric  // Input: (bit<27-26>, bit<24-20>, scalar_in, vl) or
2306c3fb27SDimitry Andric  //        (bit<27-26>, bit<24-20>, bit<11-7>, scalar_in, vl)
2406c3fb27SDimitry Andric  class RISCVSFCustomVC_X<bit HasDst, bit HasSE, bit ImmScalar>
2506c3fb27SDimitry Andric        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
2606c3fb27SDimitry Andric                    !listconcat(!if(HasDst, [llvm_anyint_ty, LLVMMatchType<1>],
2706c3fb27SDimitry Andric                                            [llvm_anyint_ty, LLVMMatchType<0>, LLVMMatchType<0>]),
2806c3fb27SDimitry Andric                                [llvm_any_ty, llvm_anyint_ty]),
2906c3fb27SDimitry Andric                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>],    // bit<27-26> and bit<24-20>
3006c3fb27SDimitry Andric                                !if(HasDst, [], [ImmArg<ArgIndex<2>>]),                   // Vd or bit<11-7>
3106c3fb27SDimitry Andric                                !if(ImmScalar, !if(HasDst, [ImmArg<ArgIndex<2>>],
3206c3fb27SDimitry Andric                                                           [ImmArg<ArgIndex<3>>]), []),   // ScalarOperand
3306c3fb27SDimitry Andric                                !if(HasSE, [IntrHasSideEffects], []))>,
3406c3fb27SDimitry Andric          RISCVVIntrinsic {
3506c3fb27SDimitry Andric    let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
3606c3fb27SDimitry Andric                              HasDst: 2,
3706c3fb27SDimitry Andric                              true: 3);
3806c3fb27SDimitry Andric    let VLOperand = !if(HasDst, 3, 4);
3906c3fb27SDimitry Andric  }
4006c3fb27SDimitry Andric  // Output: (vector_out) or ()
4106c3fb27SDimitry Andric  // Input: (bit<27-26>, vector_in, vector_in/scalar_in, vl) or
4206c3fb27SDimitry Andric  //        (bit<27-26>, bit<11-7>, vector_in, vector_in/scalar_in, vl)
4306c3fb27SDimitry Andric  class RISCVSFCustomVC_XV<bit HasDst, bit HasSE, bit ImmScalar>
4406c3fb27SDimitry Andric        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
45*5f757f3fSDimitry Andric                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty],
4606c3fb27SDimitry Andric                                            [llvm_anyint_ty, LLVMMatchType<0>, llvm_anyvector_ty]),
4706c3fb27SDimitry Andric                                [llvm_any_ty, llvm_anyint_ty]),
4806c3fb27SDimitry Andric                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
4906c3fb27SDimitry Andric                                !if(HasDst, [], [ImmArg<ArgIndex<1>>]),                  // Vd or bit<11-7>
5006c3fb27SDimitry Andric                                !if(ImmScalar, !if(HasDst, [ImmArg<ArgIndex<2>>],
5106c3fb27SDimitry Andric                                                           [ImmArg<ArgIndex<3>>]), []),  // ScalarOperand
5206c3fb27SDimitry Andric                                !if(HasSE, [IntrHasSideEffects], []))>,
5306c3fb27SDimitry Andric          RISCVVIntrinsic {
5406c3fb27SDimitry Andric    let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
5506c3fb27SDimitry Andric                              HasDst: 2,
5606c3fb27SDimitry Andric                              true: 3);
5706c3fb27SDimitry Andric    let VLOperand = !if(HasDst, 3, 4);
5806c3fb27SDimitry Andric  }
5906c3fb27SDimitry Andric  // Output: (vector_out) or ()
6006c3fb27SDimitry Andric  // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
6106c3fb27SDimitry Andric  //        (bit<27-26>, vector_in, vector_in, vector_in/scalar_in, vl)
6206c3fb27SDimitry Andric  class RISCVSFCustomVC_XVV<bit HasDst, bit HasSE, bit ImmScalar>
6306c3fb27SDimitry Andric        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
64*5f757f3fSDimitry Andric                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty],
65*5f757f3fSDimitry Andric                                            [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty]),
6606c3fb27SDimitry Andric                                [llvm_any_ty, llvm_anyint_ty]),
6706c3fb27SDimitry Andric                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
6806c3fb27SDimitry Andric                                !if(ImmScalar, [ImmArg<ArgIndex<3>>], []),               // ScalarOperand
6906c3fb27SDimitry Andric                                !if(HasSE, [IntrHasSideEffects], []))>,
7006c3fb27SDimitry Andric          RISCVVIntrinsic {
7106c3fb27SDimitry Andric    let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
7206c3fb27SDimitry Andric    let VLOperand = 4;
7306c3fb27SDimitry Andric  }
7406c3fb27SDimitry Andric  // Output: (wvector_out) or ()
7506c3fb27SDimitry Andric  // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
7606c3fb27SDimitry Andric  //        (bit<27-26>, wvector_in, vector_in, vector_in/scalar_in, vl)
7706c3fb27SDimitry Andric  class RISCVSFCustomVC_XVW<bit HasDst, bit HasSE, bit ImmScalar>
7806c3fb27SDimitry Andric        : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
79*5f757f3fSDimitry Andric                    !listconcat(!if(HasDst, [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty],
8006c3fb27SDimitry Andric                                            [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty]),
8106c3fb27SDimitry Andric                                [llvm_any_ty, llvm_anyint_ty]),
8206c3fb27SDimitry Andric                    !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>],                        // bit<27-26>
8306c3fb27SDimitry Andric                                !if(ImmScalar, [ImmArg<ArgIndex<3>>], []),               // ScalarOperand
8406c3fb27SDimitry Andric                                !if(HasSE, [IntrHasSideEffects], []))>,
8506c3fb27SDimitry Andric          RISCVVIntrinsic {
8606c3fb27SDimitry Andric    let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
8706c3fb27SDimitry Andric    let VLOperand = 4;
8806c3fb27SDimitry Andric  }
8906c3fb27SDimitry Andric
9006c3fb27SDimitry Andric  multiclass RISCVSFCustomVC_X<list<string> type> {
9106c3fb27SDimitry Andric    foreach t = type in {
9206c3fb27SDimitry Andric      defvar ImmScalar = !eq(t, "i");
9306c3fb27SDimitry Andric      defvar range = ["c", "s", "i", "l"];
9406c3fb27SDimitry Andric      foreach r = range in {
9506c3fb27SDimitry Andric        foreach s = VCIXSuffix<r>.suffix in {
96*5f757f3fSDimitry Andric          def "int_riscv_sf_vc_" # t # "_se_" # s : RISCVSFCustomVC_X<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
9706c3fb27SDimitry Andric        }
9806c3fb27SDimitry Andric      }
99*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "_se" : RISCVSFCustomVC_X<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
100*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t         : RISCVSFCustomVC_X<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
10106c3fb27SDimitry Andric    }
10206c3fb27SDimitry Andric  }
10306c3fb27SDimitry Andric
10406c3fb27SDimitry Andric  multiclass RISCVSFCustomVC_XV<list<string> type> {
10506c3fb27SDimitry Andric    foreach t = type in {
10606c3fb27SDimitry Andric      defvar ImmScalar = !eq(t, "i");
107*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_" # t # "v_se"   : RISCVSFCustomVC_XV<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
108*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "v_se" : RISCVSFCustomVC_XV<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
109*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "v"    : RISCVSFCustomVC_XV<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
11006c3fb27SDimitry Andric    }
11106c3fb27SDimitry Andric  }
11206c3fb27SDimitry Andric
11306c3fb27SDimitry Andric  multiclass RISCVSFCustomVC_XVV<list<string> type> {
11406c3fb27SDimitry Andric    foreach t = type in {
11506c3fb27SDimitry Andric      defvar ImmScalar = !eq(t, "i");
116*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_" # t # "vv_se"   : RISCVSFCustomVC_XVV<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
117*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "vv_se" : RISCVSFCustomVC_XVV<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
118*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "vv"    : RISCVSFCustomVC_XVV<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
11906c3fb27SDimitry Andric    }
12006c3fb27SDimitry Andric  }
12106c3fb27SDimitry Andric
12206c3fb27SDimitry Andric  multiclass RISCVSFCustomVC_XVW<list<string> type> {
12306c3fb27SDimitry Andric    foreach t = type in {
12406c3fb27SDimitry Andric      defvar ImmScalar = !eq(t, "i");
125*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_" # t # "vw_se"   : RISCVSFCustomVC_XVW<HasDst=0, HasSE=1, ImmScalar=ImmScalar>;
126*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "vw_se" : RISCVSFCustomVC_XVW<HasDst=1, HasSE=1, ImmScalar=ImmScalar>;
127*5f757f3fSDimitry Andric      def "int_riscv_sf_vc_v_" # t # "vw"    : RISCVSFCustomVC_XVW<HasDst=1, HasSE=0, ImmScalar=ImmScalar>;
12806c3fb27SDimitry Andric    }
12906c3fb27SDimitry Andric  }
13006c3fb27SDimitry Andric
131*5f757f3fSDimitry Andric  class RISCVSFCustomVMACC
132*5f757f3fSDimitry Andric      : DefaultAttrsIntrinsic< [llvm_anyvector_ty],
133*5f757f3fSDimitry Andric                   [LLVMMatchType<0>, llvm_anyvector_ty, llvm_anyvector_ty,
134*5f757f3fSDimitry Andric                    llvm_anyint_ty, LLVMMatchType<3>],
135*5f757f3fSDimitry Andric                   [ImmArg<ArgIndex<4>>, IntrNoMem] >, RISCVVIntrinsic {
136*5f757f3fSDimitry Andric    let VLOperand = 3;
137*5f757f3fSDimitry Andric  }
138*5f757f3fSDimitry Andric
139*5f757f3fSDimitry Andric  // Input: (passthru, vector_in, scalar_in, frm, vl)
140*5f757f3fSDimitry Andric  class RISCVSFCustomVFNRCLIPUnMasked
141*5f757f3fSDimitry Andric        : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
142*5f757f3fSDimitry Andric                    [LLVMMatchType<0>, llvm_anyfloat_ty, LLVMVectorElementType<1>,
143*5f757f3fSDimitry Andric                     llvm_anyint_ty, LLVMMatchType<2>],
144*5f757f3fSDimitry Andric                    [ImmArg<ArgIndex<3>>, IntrNoMem]>, RISCVVIntrinsic {
145*5f757f3fSDimitry Andric    let VLOperand = 4;
146*5f757f3fSDimitry Andric  }
147*5f757f3fSDimitry Andric
148*5f757f3fSDimitry Andric  // Input: (maskedoff, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
149*5f757f3fSDimitry Andric  class RISCVSFCustomVFNRCLIPMasked
150*5f757f3fSDimitry Andric       : DefaultAttrsIntrinsic<[llvm_anyvector_ty],
151*5f757f3fSDimitry Andric                   [LLVMMatchType<0>, llvm_anyfloat_ty, LLVMVectorElementType<1>,
152*5f757f3fSDimitry Andric                    LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, llvm_anyint_ty,
153*5f757f3fSDimitry Andric                    LLVMMatchType<2>, LLVMMatchType<2>],
154*5f757f3fSDimitry Andric                   [ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<6>>, IntrNoMem]>, RISCVVIntrinsic {
155*5f757f3fSDimitry Andric    let VLOperand = 5;
156*5f757f3fSDimitry Andric  }
157*5f757f3fSDimitry Andric
158*5f757f3fSDimitry Andric  multiclass RISCVSFCustomVFNRCLIP {
159*5f757f3fSDimitry Andric    def NAME : RISCVSFCustomVFNRCLIPUnMasked;
160*5f757f3fSDimitry Andric    def NAME # "_mask" : RISCVSFCustomVFNRCLIPMasked;
161*5f757f3fSDimitry Andric  }
162*5f757f3fSDimitry Andric
16306c3fb27SDimitry Andric  defm "" : RISCVSFCustomVC_X<["x", "i"]>;
16406c3fb27SDimitry Andric  defm "" : RISCVSFCustomVC_XV<["x", "i", "v", "f"]>;
16506c3fb27SDimitry Andric  defm "" : RISCVSFCustomVC_XVV<["x", "i", "v", "f"]>;
16606c3fb27SDimitry Andric  defm "" : RISCVSFCustomVC_XVW<["x", "i", "v", "f"]>;
167*5f757f3fSDimitry Andric
168*5f757f3fSDimitry Andric  // XSfvqmaccdod
169*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccu_2x8x2  : RISCVSFCustomVMACC;
170*5f757f3fSDimitry Andric  def int_riscv_sf_vqmacc_2x8x2   : RISCVSFCustomVMACC;
171*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccus_2x8x2 : RISCVSFCustomVMACC;
172*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccsu_2x8x2 : RISCVSFCustomVMACC;
173*5f757f3fSDimitry Andric
174*5f757f3fSDimitry Andric  // XSfvqmaccqoq
175*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccu_4x8x4  : RISCVSFCustomVMACC;
176*5f757f3fSDimitry Andric  def int_riscv_sf_vqmacc_4x8x4   : RISCVSFCustomVMACC;
177*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccus_4x8x4 : RISCVSFCustomVMACC;
178*5f757f3fSDimitry Andric  def int_riscv_sf_vqmaccsu_4x8x4 : RISCVSFCustomVMACC;
179*5f757f3fSDimitry Andric
180*5f757f3fSDimitry Andric  // XSfvfwmaccqqq
181*5f757f3fSDimitry Andric  def int_riscv_sf_vfwmacc_4x4x4 : RISCVSFCustomVMACC;
182*5f757f3fSDimitry Andric
183*5f757f3fSDimitry Andric  // XSfvfnrclipxfqf
184*5f757f3fSDimitry Andric  defm int_riscv_sf_vfnrclip_x_f_qf : RISCVSFCustomVFNRCLIP;
185*5f757f3fSDimitry Andric  defm int_riscv_sf_vfnrclip_xu_f_qf : RISCVSFCustomVFNRCLIP;
18606c3fb27SDimitry Andric} // TargetPrefix = "riscv"
187