]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm-mve-builtins.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arm / arm-mve-builtins.cc
1 /* ACLE support for Arm MVE
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #define IN_TARGET_CODE 1
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "fold-const.h"
28 #include "langhooks.h"
29 #include "stringpool.h"
30 #include "attribs.h"
31 #include "diagnostic.h"
32 #include "arm-protos.h"
33 #include "arm-builtins.h"
34 #include "arm-mve-builtins.h"
35
36 namespace arm_mve {
37
38 /* Static information about each single-predicate or single-vector
39 ACLE type. */
40 struct vector_type_info
41 {
42 /* The name of the type as declared by arm_mve.h. */
43 const char *acle_name;
44
45 /* Whether the type requires a floating point abi. */
46 const bool requires_float;
47 };
48
49 /* Flag indicating whether the arm MVE types have been handled. */
50 static bool handle_arm_mve_types_p;
51
52 /* Information about each single-predicate or single-vector type. */
53 static CONSTEXPR const vector_type_info vector_types[] = {
54 #define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
55 { #ACLE_NAME, REQUIRES_FLOAT },
56 #include "arm-mve-builtins.def"
57 #undef DEF_MVE_TYPE
58 };
59
60 /* The scalar type associated with each vector type. */
61 GTY(()) tree scalar_types[NUM_VECTOR_TYPES];
62
63 /* The single-predicate and single-vector types, with their built-in
64 "__simd128_..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
65 yields a null tree. */
66 static GTY(()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];
67
68 /* Same, but with the arm_mve.h names. */
69 GTY(()) tree acle_vector_types[3][NUM_VECTOR_TYPES + 1];
70
71 /* Return the MVE abi type with element of type TYPE. */
72 static tree
73 arm_mve_type_for_scalar_type (tree eltype)
74 {
75 for (unsigned int i = 0; i < __TYPE_FINAL; ++i)
76 if (arm_simd_types[i].eltype == eltype
77 && GET_MODE_SIZE (arm_simd_types[i].mode) == 16)
78 return arm_simd_types[i].itype;
79
80 gcc_unreachable ();
81 }
82
83 /* Register the built-in MVE ABI vector types, such as uint32x4_t. */
84 static void
85 register_builtin_types ()
86 {
87 #define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
88 scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
89 #include "arm-mve-builtins.def"
90 #undef DEF_MVE_TYPE
91 for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
92 {
93 if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
94 continue;
95 tree eltype = scalar_types[i];
96 tree vectype;
97 if (eltype == boolean_type_node)
98 {
99 vectype = get_typenode_from_name (UINT16_TYPE);
100 gcc_assert (GET_MODE_SIZE (TYPE_MODE (vectype)) == 2);
101 }
102 else
103 {
104 vectype = arm_mve_type_for_scalar_type (eltype);
105 gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype))
106 && GET_MODE_SIZE (TYPE_MODE (vectype)) == 16);
107 }
108 abi_vector_types[i] = vectype;
109 }
110 }
111
112 /* Register vector type TYPE under its arm_mve.h name. */
113 static void
114 register_vector_type (vector_type_index type)
115 {
116 if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
117 return;
118 tree vectype = abi_vector_types[type];
119 tree id = get_identifier (vector_types[type].acle_name);
120 tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
121 decl = lang_hooks.decls.pushdecl (decl);
122
123 /* Record the new ACLE type if pushdecl succeeded without error. Use
124 the ABI type otherwise, so that the type we record at least has the
125 right form, even if it doesn't have the right name. This should give
126 better error recovery behavior than installing error_mark_node or
127 installing an incorrect type. */
128 if (decl
129 && TREE_CODE (decl) == TYPE_DECL
130 && TREE_TYPE (decl) != error_mark_node
131 && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
132 vectype = TREE_TYPE (decl);
133 acle_vector_types[0][type] = vectype;
134 }
135
136 /* Register tuple type TYPE with NUM_VECTORS arity under its
137 arm_mve_types.h name. */
138 static void
139 register_builtin_tuple_types (vector_type_index type)
140 {
141 const vector_type_info* info = &vector_types[type];
142 if (scalar_types[type] == boolean_type_node
143 || (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
144 return;
145 const char *vector_type_name = info->acle_name;
146 char buffer[sizeof ("float32x4x2_t")];
147 for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
148 {
149 snprintf (buffer, sizeof (buffer), "%.*sx%d_t",
150 (int) strlen (vector_type_name) - 2, vector_type_name,
151 num_vectors);
152
153 tree vectype = acle_vector_types[0][type];
154 tree arrtype = build_array_type_nelts (vectype, num_vectors);
155 gcc_assert (TYPE_MODE_RAW (arrtype) == TYPE_MODE (arrtype));
156 tree field = build_decl (input_location, FIELD_DECL,
157 get_identifier ("val"), arrtype);
158
159 tree t = lang_hooks.types.simulate_record_decl (input_location, buffer,
160 make_array_slice (&field,
161 1));
162 gcc_assert (TYPE_MODE_RAW (t) == TYPE_MODE (t));
163 acle_vector_types[num_vectors >> 1][type] = TREE_TYPE (t);
164 }
165 }
166
167 /* Implement #pragma GCC arm "arm_mve_types.h". */
168 void
169 handle_arm_mve_types_h ()
170 {
171 if (handle_arm_mve_types_p)
172 {
173 error ("duplicate definition of %qs", "arm_mve_types.h");
174 return;
175 }
176 handle_arm_mve_types_p = true;
177 if (!TARGET_HAVE_MVE)
178 {
179 error ("this definition requires the MVE ISA extension");
180 return;
181 }
182 register_builtin_types ();
183 for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
184 {
185 vector_type_index type = vector_type_index (type_i);
186 register_vector_type (type);
187 if (type_i != VECTOR_TYPE_mve_pred16_t)
188 register_builtin_tuple_types (type);
189 }
190 }
191
192 } /* end namespace arm_mve */
193
194 using namespace arm_mve;
195
196 #include "gt-arm-mve-builtins.h"