1 //===- IntrinsicsRISCVXsf.td - SiFive intrinsics -----------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines all of the SiFive vendor intrinsics for RISC-V.
11 //===----------------------------------------------------------------------===//
13 class 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"]);
20 let TargetPrefix = "riscv" in {
21 // Output: (vector_out) or ()
22 // Input: (bit<27-26>, bit<24-20>, scalar_in, vl) or
23 // (bit<27-26>, bit<24-20>, bit<11-7>, scalar_in, vl)
24 class RISCVSFCustomVC_X<bit HasDst, bit HasSE, bit ImmScalar>
25 : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
26 !listconcat(!if(HasDst, [llvm_anyint_ty, LLVMMatchType<1>],
27 [llvm_anyint_ty, LLVMMatchType<0>, LLVMMatchType<0>]),
28 [llvm_any_ty, llvm_anyint_ty]),
29 !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>], // bit<27-26> and bit<24-20>
30 !if(HasDst, [], [ImmArg<ArgIndex<2>>]), // Vd or bit<11-7>
31 !if(ImmScalar, !if(HasDst, [ImmArg<ArgIndex<2>>],
32 [ImmArg<ArgIndex<3>>]), []), // ScalarOperand
33 !if(HasSE, [IntrHasSideEffects], []))>,
35 let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
38 let VLOperand = !if(HasDst, 3, 4);
40 // Output: (vector_out) or ()
41 // Input: (bit<27-26>, vector_in, vector_in/scalar_in, vl) or
42 // (bit<27-26>, bit<11-7>, vector_in, vector_in/scalar_in, vl)
43 class RISCVSFCustomVC_XV<bit HasDst, bit HasSE, bit ImmScalar>
44 : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
45 !listconcat(!if(HasDst, [llvm_anyint_ty, LLVMMatchType<0>],
46 [llvm_anyint_ty, LLVMMatchType<0>, llvm_anyvector_ty]),
47 [llvm_any_ty, llvm_anyint_ty]),
48 !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>], // bit<27-26>
49 !if(HasDst, [], [ImmArg<ArgIndex<1>>]), // Vd or bit<11-7>
50 !if(ImmScalar, !if(HasDst, [ImmArg<ArgIndex<2>>],
51 [ImmArg<ArgIndex<3>>]), []), // ScalarOperand
52 !if(HasSE, [IntrHasSideEffects], []))>,
54 let ScalarOperand = !cond(ImmScalar: NoScalarOperand,
57 let VLOperand = !if(HasDst, 3, 4);
59 // Output: (vector_out) or ()
60 // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
61 // (bit<27-26>, vector_in, vector_in, vector_in/scalar_in, vl)
62 class RISCVSFCustomVC_XVV<bit HasDst, bit HasSE, bit ImmScalar>
63 : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
64 !listconcat(!if(HasDst, [llvm_anyint_ty, LLVMMatchType<0>, LLVMMatchType<0>],
65 [llvm_anyint_ty, llvm_anyvector_ty, LLVMMatchType<1>]),
66 [llvm_any_ty, llvm_anyint_ty]),
67 !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>], // bit<27-26>
68 !if(ImmScalar, [ImmArg<ArgIndex<3>>], []), // ScalarOperand
69 !if(HasSE, [IntrHasSideEffects], []))>,
71 let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
74 // Output: (wvector_out) or ()
75 // Input: (bit<27-26>, passthru, vector_in, vector_in/scalar_in, vl) or
76 // (bit<27-26>, wvector_in, vector_in, vector_in/scalar_in, vl)
77 class RISCVSFCustomVC_XVW<bit HasDst, bit HasSE, bit ImmScalar>
78 : Intrinsic<!if(HasDst, [llvm_anyvector_ty], []),
79 !listconcat(!if(HasDst, [llvm_anyint_ty, LLVMMatchType<0>, llvm_anyvector_ty],
80 [llvm_anyint_ty, llvm_anyvector_ty, llvm_anyvector_ty]),
81 [llvm_any_ty, llvm_anyint_ty]),
82 !listconcat([IntrNoMem, ImmArg<ArgIndex<0>>], // bit<27-26>
83 !if(ImmScalar, [ImmArg<ArgIndex<3>>], []), // ScalarOperand
84 !if(HasSE, [IntrHasSideEffects], []))>,
86 let ScalarOperand = !if(ImmScalar, NoScalarOperand, 3);
90 multiclass RISCVSFCustomVC_X<list<string> type> {
92 defvar ImmScalar = !eq(t, "i");
93 defvar range = ["c", "s", "i", "l"];
94 foreach r = range in {
95 foreach s = VCIXSuffix<r>.suffix in {
96 def "int_riscv_sf_vc_" # t # "_se_" # s : RISCVSFCustomVC_X</*HasDst*/0, /*HasSE*/1, ImmScalar>;
99 def "int_riscv_sf_vc_v_" # t # "_se" : RISCVSFCustomVC_X</*HasDst*/1, /*HasSE*/1, ImmScalar>;
100 def "int_riscv_sf_vc_v_" # t : RISCVSFCustomVC_X</*HasDst*/1, /*HasSE*/0, ImmScalar>;
104 multiclass RISCVSFCustomVC_XV<list<string> type> {
105 foreach t = type in {
106 defvar ImmScalar = !eq(t, "i");
107 def "int_riscv_sf_vc_" # t # "v_se" : RISCVSFCustomVC_XV</*HasDst*/0, /*HasSE*/1, ImmScalar>;
108 def "int_riscv_sf_vc_v_" # t # "v_se" : RISCVSFCustomVC_XV</*HasDst*/1, /*HasSE*/1, ImmScalar>;
109 def "int_riscv_sf_vc_v_" # t # "v" : RISCVSFCustomVC_XV</*HasDst*/1, /*HasSE*/0, ImmScalar>;
113 multiclass RISCVSFCustomVC_XVV<list<string> type> {
114 foreach t = type in {
115 defvar ImmScalar = !eq(t, "i");
116 def "int_riscv_sf_vc_" # t # "vv_se" : RISCVSFCustomVC_XVV</*HasDst*/0, /*HasSE*/1, ImmScalar>;
117 def "int_riscv_sf_vc_v_" # t # "vv_se" : RISCVSFCustomVC_XVV</*HasDst*/1, /*HasSE*/1, ImmScalar>;
118 def "int_riscv_sf_vc_v_" # t # "vv" : RISCVSFCustomVC_XVV</*HasDst*/1, /*HasSE*/0, ImmScalar>;
122 multiclass RISCVSFCustomVC_XVW<list<string> type> {
123 foreach t = type in {
124 defvar ImmScalar = !eq(t, "i");
125 def "int_riscv_sf_vc_" # t # "vw_se" : RISCVSFCustomVC_XVW</*HasDst*/0, /*HasSE*/1, ImmScalar>;
126 def "int_riscv_sf_vc_v_" # t # "vw_se" : RISCVSFCustomVC_XVW</*HasDst*/1, /*HasSE*/1, ImmScalar>;
127 def "int_riscv_sf_vc_v_" # t # "vw" : RISCVSFCustomVC_XVW</*HasDst*/1, /*HasSE*/0, ImmScalar>;
131 defm "" : RISCVSFCustomVC_X<["x", "i"]>;
132 defm "" : RISCVSFCustomVC_XV<["x", "i", "v", "f"]>;
133 defm "" : RISCVSFCustomVC_XVV<["x", "i", "v", "f"]>;
134 defm "" : RISCVSFCustomVC_XVW<["x", "i", "v", "f"]>;
135 } // TargetPrefix = "riscv"