Daily bump.
[official-gcc.git] / gcc / config / riscv / riscv-c.cc
blob7912b1069f7947c814e7bd46ea39bc1941fb4b9d
1 /* RISC-V-specific code for C family languages.
2 Copyright (C) 2011-2025 Free Software Foundation, Inc.
3 Contributed by Andrew Waterman (andrew@sifive.com).
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it 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.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU 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/>. */
21 #define IN_TARGET_CODE 1
23 #define INCLUDE_STRING
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "c-family/c-common.h"
29 #include "cpplib.h"
30 #include "c-family/c-pragma.h"
31 #include "target.h"
32 #include "tm_p.h"
33 #include "riscv-subset.h"
35 #define builtin_define(TXT) cpp_define (pfile, TXT)
37 struct pragma_intrinsic_flags
39 int intrinsic_target_flags;
41 int intrinsic_riscv_vector_elen_flags;
42 int intrinsic_riscv_zvl_flags;
43 int intrinsic_riscv_zvb_subext;
44 int intrinsic_riscv_zvk_subext;
47 static void
48 riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
50 flags->intrinsic_target_flags = target_flags;
51 flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
52 flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
53 flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
54 flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
56 target_flags = target_flags
57 | MASK_VECTOR;
59 riscv_zvl_flags = riscv_zvl_flags
60 | MASK_ZVL32B
61 | MASK_ZVL64B
62 | MASK_ZVL128B
63 | MASK_ZVL256B
64 | MASK_ZVL512B
65 | MASK_ZVL1024B
66 | MASK_ZVL2048B
67 | MASK_ZVL4096B;
69 riscv_vector_elen_flags = riscv_vector_elen_flags
70 | MASK_VECTOR_ELEN_32
71 | MASK_VECTOR_ELEN_64
72 | MASK_VECTOR_ELEN_FP_16
73 | MASK_VECTOR_ELEN_FP_32
74 | MASK_VECTOR_ELEN_FP_64;
76 riscv_zvb_subext = riscv_zvb_subext
77 | MASK_ZVBB
78 | MASK_ZVBC
79 | MASK_ZVKB;
81 riscv_zvk_subext = riscv_zvk_subext
82 | MASK_ZVKG
83 | MASK_ZVKNED
84 | MASK_ZVKNHA
85 | MASK_ZVKNHB
86 | MASK_ZVKSED
87 | MASK_ZVKSH
88 | MASK_ZVKN
89 | MASK_ZVKNC
90 | MASK_ZVKNG
91 | MASK_ZVKS
92 | MASK_ZVKSC
93 | MASK_ZVKSG
94 | MASK_ZVKT;
97 static void
98 riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
100 target_flags = flags->intrinsic_target_flags;
102 riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
103 riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
104 riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
105 riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
108 static int
109 riscv_ext_version_value (unsigned major, unsigned minor)
111 return (major * RISCV_MAJOR_VERSION_BASE)
112 + (minor * RISCV_MINOR_VERSION_BASE);
115 /* Implement TARGET_CPU_CPP_BUILTINS. */
117 void
118 riscv_cpu_cpp_builtins (cpp_reader *pfile)
120 builtin_define ("__riscv");
122 if (TARGET_RVC || TARGET_ZCA)
123 builtin_define ("__riscv_compressed");
125 if (TARGET_RVE)
126 builtin_define (TARGET_64BIT ? "__riscv_64e" : "__riscv_32e");
128 if (TARGET_ATOMIC)
129 builtin_define ("__riscv_atomic");
131 if (TARGET_MUL)
132 builtin_define ("__riscv_mul");
133 if (TARGET_DIV)
134 builtin_define ("__riscv_div");
135 if (TARGET_DIV && TARGET_MUL)
136 builtin_define ("__riscv_muldiv");
138 builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8);
139 if (TARGET_HARD_FLOAT)
140 builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8);
142 if ((TARGET_HARD_FLOAT || TARGET_ZFINX) && TARGET_FDIV)
144 builtin_define ("__riscv_fdiv");
145 builtin_define ("__riscv_fsqrt");
148 switch (riscv_abi)
150 case ABI_ILP32E:
151 case ABI_LP64E:
152 builtin_define ("__riscv_abi_rve");
153 gcc_fallthrough ();
155 case ABI_ILP32:
156 case ABI_LP64:
157 builtin_define ("__riscv_float_abi_soft");
158 break;
160 case ABI_ILP32F:
161 case ABI_LP64F:
162 builtin_define ("__riscv_float_abi_single");
163 break;
165 case ABI_ILP32D:
166 case ABI_LP64D:
167 builtin_define ("__riscv_float_abi_double");
168 break;
171 switch (riscv_cmodel)
173 case CM_MEDLOW:
174 builtin_define ("__riscv_cmodel_medlow");
175 break;
177 case CM_LARGE:
178 builtin_define ("__riscv_cmodel_large");
179 break;
181 case CM_PIC:
182 case CM_MEDANY:
183 builtin_define ("__riscv_cmodel_medany");
184 break;
187 if (riscv_user_wants_strict_align)
188 builtin_define_with_int_value ("__riscv_misaligned_avoid", 1);
189 else if (riscv_slow_unaligned_access_p)
190 builtin_define_with_int_value ("__riscv_misaligned_slow", 1);
191 else
192 builtin_define_with_int_value ("__riscv_misaligned_fast", 1);
194 if (TARGET_MIN_VLEN != 0)
195 builtin_define_with_int_value ("__riscv_v_min_vlen", TARGET_MIN_VLEN);
197 if (TARGET_VECTOR_ELEN_64)
198 builtin_define_with_int_value ("__riscv_v_elen", 64);
199 else if (TARGET_VECTOR_ELEN_32)
200 builtin_define_with_int_value ("__riscv_v_elen", 32);
202 if (TARGET_VECTOR_ELEN_FP_64)
203 builtin_define_with_int_value ("__riscv_v_elen_fp", 64);
204 else if (TARGET_VECTOR_ELEN_FP_32)
205 builtin_define_with_int_value ("__riscv_v_elen_fp", 32);
206 else if (TARGET_MIN_VLEN != 0)
207 builtin_define_with_int_value ("__riscv_v_elen_fp", 0);
209 if (TARGET_MIN_VLEN)
211 builtin_define ("__riscv_vector");
212 builtin_define_with_int_value ("__riscv_v_intrinsic",
213 riscv_ext_version_value (0, 12));
215 if (rvv_vector_bits == RVV_VECTOR_BITS_ZVL)
216 builtin_define_with_int_value ("__riscv_v_fixed_vlen", TARGET_MIN_VLEN);
219 if (TARGET_XTHEADVECTOR)
220 builtin_define_with_int_value ("__riscv_th_v_intrinsic",
221 riscv_ext_version_value (0, 11));
223 /* Define architecture extension test macros. */
224 builtin_define_with_int_value ("__riscv_arch_test", 1);
226 if (TARGET_ZICFISS && ((flag_cf_protection & CF_RETURN) == CF_RETURN))
227 builtin_define ("__riscv_shadow_stack");
229 if (TARGET_ZICFILP && ((flag_cf_protection & CF_BRANCH) == CF_BRANCH))
231 builtin_define ("__riscv_landing_pad");
232 builtin_define ("__riscv_landing_pad_unlabeled");
235 const riscv_subset_list *subset_list = riscv_cmdline_subset_list ();
236 if (!subset_list)
237 return;
239 size_t max_ext_len = 0;
241 /* Figure out the max length of extension name for reserving buffer. */
242 for (const riscv_subset_t *subset = subset_list->begin ();
243 subset != subset_list->end ();
244 subset = subset->next)
245 max_ext_len = MAX (max_ext_len, subset->name.length ());
247 char *buf = (char *)alloca (max_ext_len + 10 /* For __riscv_ and '\0'. */);
249 for (const riscv_subset_t *subset = subset_list->begin ();
250 subset != subset_list->end ();
251 subset = subset->next)
253 int version_value = riscv_ext_version_value (subset->major_version,
254 subset->minor_version);
255 /* Special rule for zicsr and zifencei, it's used for ISA spec 2.2 or
256 earlier. */
257 if ((subset->name == "zicsr" || subset->name == "zifencei")
258 && version_value == 0)
259 version_value = riscv_ext_version_value (2, 0);
261 sprintf (buf, "__riscv_%s", subset->name.c_str ());
262 builtin_define_with_int_value (buf, version_value);
266 /* Implement "#pragma riscv intrinsic". */
268 static void
269 riscv_pragma_intrinsic (cpp_reader *)
271 tree x;
273 if (pragma_lex (&x) != CPP_STRING)
275 error ("%<#pragma riscv intrinsic%> requires a string parameter");
276 return;
279 const char *name = TREE_STRING_POINTER (x);
281 if (strcmp (name, "vector") == 0
282 || strcmp (name, "xtheadvector") == 0)
284 struct pragma_intrinsic_flags backup_flags;
286 riscv_pragma_intrinsic_flags_pollute (&backup_flags);
288 riscv_option_override ();
289 init_adjust_machine_modes ();
290 riscv_vector::reinit_builtins ();
291 riscv_vector::handle_pragma_vector ();
293 riscv_pragma_intrinsic_flags_restore (&backup_flags);
295 /* Re-initialize after the flags are restored. */
296 riscv_option_override ();
297 init_adjust_machine_modes ();
299 else
300 error ("unknown %<#pragma riscv intrinsic%> option %qs", name);
303 /* Implement TARGET_CHECK_BUILTIN_CALL. */
304 static bool
305 riscv_check_builtin_call (location_t loc, vec<location_t> arg_loc, tree fndecl,
306 tree, unsigned int nargs, tree *args, bool)
308 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
309 unsigned int subcode = code >> RISCV_BUILTIN_SHIFT;
310 switch (code & RISCV_BUILTIN_CLASS)
312 case RISCV_BUILTIN_GENERAL:
313 return true;
315 case RISCV_BUILTIN_VECTOR:
316 return riscv_vector::check_builtin_call (loc, arg_loc, subcode,
317 fndecl, nargs, args);
319 gcc_unreachable ();
322 /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. */
323 static tree
324 riscv_resolve_overloaded_builtin (location_t loc, tree fndecl,
325 void *uncast_arglist, bool)
327 vec<tree, va_gc> empty = {};
328 vec<tree, va_gc> *arglist = (vec<tree, va_gc> *) uncast_arglist;
329 unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
330 unsigned int subcode = code >> RISCV_BUILTIN_SHIFT;
331 tree new_fndecl = NULL_TREE;
333 if (!arglist)
334 arglist = &empty;
336 switch (code & RISCV_BUILTIN_CLASS)
338 case RISCV_BUILTIN_GENERAL:
339 break;
340 case RISCV_BUILTIN_VECTOR:
341 new_fndecl = riscv_vector::resolve_overloaded_builtin (loc, subcode,
342 fndecl, arglist);
343 break;
344 default:
345 gcc_unreachable ();
348 if (new_fndecl == NULL_TREE)
349 return new_fndecl;
351 return build_function_call_vec (loc, vNULL, new_fndecl, arglist, NULL,
352 fndecl);
355 /* Implement REGISTER_TARGET_PRAGMAS. */
357 void
358 riscv_register_pragmas (void)
360 targetm.resolve_overloaded_builtin = riscv_resolve_overloaded_builtin;
361 targetm.check_builtin_call = riscv_check_builtin_call;
362 c_register_pragma ("riscv", "intrinsic", riscv_pragma_intrinsic);