1 /* function_base implementation for SiFive custom 'V' Extension for GNU compiler.
2 Copyright (C) 2024-2025 Free Software Foundation, Inc.
3 Contributed by SiFive and PLCT Lab.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
29 #include "insn-codes.h"
33 #include "basic-block.h"
35 #include "fold-const.h"
37 #include "gimple-iterator.h"
41 #include "tree-vector-builder.h"
42 #include "rtx-vector-builder.h"
43 #include "riscv-vector-builtins.h"
44 #include "riscv-vector-builtins-shapes.h"
45 #include "sifive-vector-builtins-bases.h"
46 #include "riscv-vector-builtins-bases.h"
48 using namespace riscv_vector
;
50 namespace riscv_vector
{
52 /* Implements SiFive vqmacc. */
53 class sf_vqmacc
: public function_base
56 bool has_merge_operand_p () const override
{ return false; }
57 bool apply_mask_policy_p () const override
{ return false; }
58 bool use_mask_predication_p () const override
{ return false; }
59 bool can_be_overloaded_p (enum predication_type_index pred
) const override
61 return pred
== PRED_TYPE_tu
;
64 rtx
expand (function_expander
&e
) const override
66 if (e
.op_info
->op
== OP_TYPE_4x8x4
)
67 return e
.use_widen_ternop_insn (
68 code_for_pred_matrix_mul_plus_qoq (SIGN_EXTEND
, e
.vector_mode ()));
69 if (e
.op_info
->op
== OP_TYPE_2x8x2
)
70 return e
.use_widen_ternop_insn (
71 code_for_pred_matrix_mul_plus_dod (SIGN_EXTEND
, e
.vector_mode ()));
76 /* Implements SiFive vqmaccu. */
77 class sf_vqmaccu
: public function_base
80 bool has_merge_operand_p () const override
{ return false; }
81 bool apply_mask_policy_p () const override
{ return false; }
82 bool use_mask_predication_p () const override
{ return false; }
84 bool can_be_overloaded_p (enum predication_type_index pred
) const override
86 return pred
== PRED_TYPE_tu
;
89 rtx
expand (function_expander
&e
) const override
91 if (e
.op_info
->op
== OP_TYPE_4x8x4
)
92 return e
.use_widen_ternop_insn (
93 code_for_pred_matrix_mul_plus_qoq (ZERO_EXTEND
, e
.vector_mode ()));
94 if (e
.op_info
->op
== OP_TYPE_2x8x2
)
95 return e
.use_widen_ternop_insn (
96 code_for_pred_matrix_mul_plus_dod (ZERO_EXTEND
, e
.vector_mode ()));
101 /* Implements SiFive vqmaccsu. */
102 class sf_vqmaccsu
: public function_base
105 bool has_merge_operand_p () const override
{ return false; }
106 bool apply_mask_policy_p () const override
{ return false; }
107 bool use_mask_predication_p () const override
{ return false; }
109 bool can_be_overloaded_p (enum predication_type_index pred
) const override
111 return pred
== PRED_TYPE_tu
;
114 rtx
expand (function_expander
&e
) const override
116 if (e
.op_info
->op
== OP_TYPE_4x8x4
)
117 return e
.use_widen_ternop_insn (
118 code_for_pred_matrix_mul_plussu_qoq (e
.vector_mode ()));
119 if (e
.op_info
->op
== OP_TYPE_2x8x2
)
120 return e
.use_widen_ternop_insn (
121 code_for_pred_matrix_mul_plussu_dod (e
.vector_mode ()));
126 /* Implements SiFive vqmaccus. */
127 class sf_vqmaccus
: public function_base
130 bool has_merge_operand_p () const override
{ return false; }
131 bool apply_mask_policy_p () const override
{ return false; }
132 bool use_mask_predication_p () const override
{ return false; }
134 bool can_be_overloaded_p (enum predication_type_index pred
) const override
136 return pred
== PRED_TYPE_tu
;
139 rtx
expand (function_expander
&e
) const override
141 if (e
.op_info
->op
== OP_TYPE_4x8x4
)
142 return e
.use_widen_ternop_insn (
143 code_for_pred_matrix_mul_plusus_qoq (e
.vector_mode ()));
144 if (e
.op_info
->op
== OP_TYPE_2x8x2
)
145 return e
.use_widen_ternop_insn (
146 code_for_pred_matrix_mul_plusus_dod (e
.vector_mode ()));
151 /* Implements SiFive vfnrclip. */
152 template <int UNSPEC
, enum frm_op_type FRM_OP
= NO_FRM
>
153 class sf_vfnrclip_x_f_qf
: public function_base
156 bool has_rounding_mode_operand_p () const override
158 return FRM_OP
== HAS_FRM
;
161 bool may_require_frm_p () const override
{ return true; }
163 bool can_be_overloaded_p (enum predication_type_index pred
) const override
165 return pred
!= PRED_TYPE_none
;
168 rtx
expand (function_expander
&e
) const override
170 return e
.use_exact_insn (
171 code_for_pred_sf_vfnrclip_x_f_qf (UNSPEC
, e
.vector_mode ()));
175 template <int UNSPEC
, enum frm_op_type FRM_OP
= NO_FRM
>
176 class sf_vfnrclip_xu_f_qf
: public function_base
179 bool has_rounding_mode_operand_p () const override
181 return FRM_OP
== HAS_FRM
;
184 bool may_require_frm_p () const override
{ return true; }
186 bool can_be_overloaded_p (enum predication_type_index pred
) const override
188 return pred
!= PRED_TYPE_none
;
191 rtx
expand (function_expander
&e
) const override
193 return e
.use_exact_insn (
194 code_for_pred_sf_vfnrclip_x_f_qf (UNSPEC
, e
.vector_mode ()));
198 static CONSTEXPR
const sf_vqmacc sf_vqmacc_obj
;
199 static CONSTEXPR
const sf_vqmaccu sf_vqmaccu_obj
;
200 static CONSTEXPR
const sf_vqmaccsu sf_vqmaccsu_obj
;
201 static CONSTEXPR
const sf_vqmaccus sf_vqmaccus_obj
;
202 static CONSTEXPR
const sf_vfnrclip_x_f_qf
<UNSPEC_SF_VFNRCLIP
> sf_vfnrclip_x_f_qf_obj
;
203 static CONSTEXPR
const sf_vfnrclip_xu_f_qf
<UNSPEC_SF_VFNRCLIPU
> sf_vfnrclip_xu_f_qf_obj
;
205 /* Declare the function base NAME, pointing it to an instance
206 of class <NAME>_obj. */
208 namespace bases { const function_base *const NAME = &NAME##_obj; }
214 BASE (sf_vfnrclip_x_f_qf
)
215 BASE (sf_vfnrclip_xu_f_qf
)
216 } // end namespace riscv_vector