]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/riscv/riscv-vector-builtins-shapes.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / config / riscv / riscv-vector-builtins-shapes.cc
1 /* function_shape implementation for RISC-V 'V' Extension for GNU compiler.
2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
3 Contributed by Ju-Zhe Zhong (juzhe.zhong@rivai.ai), RiVAI Technologies Ltd.
4
5 This file is part of GCC.
6
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)
10 any later version.
11
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.
16
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/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "memmodel.h"
29 #include "insn-codes.h"
30 #include "optabs.h"
31 #include "riscv-vector-builtins.h"
32 #include "riscv-vector-builtins-shapes.h"
33
34 namespace riscv_vector {
35
36 /* Add one function instance for GROUP, using operand suffix at index OI,
37 mode suffix at index PAIR && bi and predication suffix at index pred_idx. */
38 static void
39 build_one (function_builder &b, const function_group_info &group,
40 unsigned int pred_idx, unsigned int vec_type_idx)
41 {
42 /* Byte forms of non-tuple vlxusegei take 21 arguments. */
43 auto_vec<tree, 21> argument_types;
44 function_instance function_instance (group.base_name, *group.base,
45 *group.shape,
46 group.ops_infos.types[vec_type_idx],
47 group.preds[pred_idx], &group.ops_infos);
48 tree return_type = group.ops_infos.ret.get_tree_type (
49 group.ops_infos.types[vec_type_idx].index);
50 b.allocate_argument_types (function_instance, argument_types);
51 b.apply_predication (function_instance, return_type, argument_types);
52 b.add_unique_function (function_instance, (*group.shape), return_type,
53 argument_types);
54 }
55
56 /* Add a function instance for every operand && predicate && args
57 combination in GROUP. Take the function base name from GROUP && operand
58 suffix from operand_suffixes && mode suffix from type_suffixes && predication
59 suffix from predication_suffixes. Use apply_predication to add in
60 the predicate. */
61 static void
62 build_all (function_builder &b, const function_group_info &group)
63 {
64 for (unsigned int pred_idx = 0; group.preds[pred_idx] != NUM_PRED_TYPES;
65 ++pred_idx)
66 for (unsigned int vec_type_idx = 0;
67 group.ops_infos.types[vec_type_idx].index != NUM_VECTOR_TYPES;
68 ++vec_type_idx)
69 build_one (b, group, pred_idx, vec_type_idx);
70 }
71
72 /* Declare the function shape NAME, pointing it to an instance
73 of class <NAME>_def. */
74 #define SHAPE(DEF, VAR) \
75 static CONSTEXPR const DEF##_def VAR##_obj; \
76 namespace shapes { const function_shape *const VAR = &VAR##_obj; }
77
78 /* Base class for for build. */
79 struct build_base : public function_shape
80 {
81 void build (function_builder &b,
82 const function_group_info &group) const override
83 {
84 build_all (b, group);
85 }
86 };
87
88 /* vsetvl_def class. */
89 struct vsetvl_def : public build_base
90 {
91 char *get_name (function_builder &b, const function_instance &instance,
92 bool overloaded_p) const override
93 {
94 /* vsetvl* instruction doesn't have C++ overloaded functions. */
95 if (overloaded_p)
96 return nullptr;
97 b.append_base_name (instance.base_name);
98 b.append_name (type_suffixes[instance.type.index].vsetvl);
99 return b.finish_name ();
100 }
101 };
102
103 /* loadstore_def class. */
104 struct loadstore_def : public build_base
105 {
106 char *get_name (function_builder &b, const function_instance &instance,
107 bool overloaded_p) const override
108 {
109 /* Return nullptr if it can not be overloaded. */
110 if (overloaded_p && !instance.base->can_be_overloaded_p (instance.pred))
111 return nullptr;
112
113 b.append_base_name (instance.base_name);
114
115 tree type = builtin_types[instance.type.index].vector;
116 machine_mode mode = TYPE_MODE (type);
117 int sew = GET_MODE_BITSIZE (GET_MODE_INNER (mode));
118 /* vop --> vop<sew>. */
119 b.append_sew (sew);
120
121 /* vop<sew>_v --> vop<sew>_v_<type>. */
122 if (!overloaded_p)
123 {
124 /* vop<sew> --> vop<sew>_v. */
125 b.append_name (operand_suffixes[instance.op_info->op]);
126 /* vop<sew>_v --> vop<sew>_v_<type>. */
127 b.append_name (type_suffixes[instance.type.index].vector);
128 }
129
130 b.append_name (predication_suffixes[instance.pred]);
131 return b.finish_name ();
132 }
133 };
134
135 SHAPE(vsetvl, vsetvl)
136 SHAPE(vsetvl, vsetvlmax)
137 SHAPE(loadstore, loadstore)
138
139 } // end namespace riscv_vector