1 /* Copyright (C) 2007-2020 Free Software Foundation, Inc.
2 
3    This file is part of GCC.
4 
5    GCC is free software; you can redistribute it and/or modify it under
6    the terms of the GNU General Public License as published by the Free
7    Software Foundation; either version 3, or (at your option) any later
8    version.
9 
10    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11    WARRANTY; without even the implied warranty of MERCHANTABILITY or
12    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13    for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with GCC; see the file COPYING3.  If not see
17    <http://www.gnu.org/licenses/>.  */
18 
19 #define IN_TARGET_CODE 1
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "target.h"
25 #include "c-family/c-common.h"
26 #include "memmodel.h"
27 #include "tm_p.h"
28 #include "c-family/c-pragma.h"
29 #include "stringpool.h"
30 #include "arm-builtins.h"
31 
32 tree
arm_resolve_cde_builtin(location_t loc,tree fndecl,void * arglist)33 arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
34 {
35   vec<tree, va_gc> *params = static_cast<vec<tree, va_gc> *> (arglist);
36   unsigned param_num = params ? params->length() : 0;
37   unsigned num_args = list_length (TYPE_ARG_TYPES (TREE_TYPE (fndecl))) - 1;
38   /* Ensure this function has the correct number of arguments.
39      This won't happen when using the intrinsics defined by the ACLE, since
40      they're exposed to the user via a wrapper in the arm_cde.h header that has
41      the correct number of arguments ... hence the compiler would already catch
42      an incorrect number of arguments there.
43 
44      It is still possible to get here if the user tries to call the __bulitin_*
45      functions directly.  We could print some error message in this function,
46      but instead we leave it to the rest of the code to catch this problem in
47      the same way that other __builtin_* functions catch it.
48 
49      This does mean an odd error message, but it's consistent with the rest of
50      the builtins.  */
51   if (param_num != num_args)
52     return NULL_TREE;
53 
54   tree to_return = NULL_TREE;
55   /* Take the functions return type since that's the same type as the arguments
56      this function needs (the types of the builtin function all come from the
57      machine mode of the RTL pattern, and they're all the same and calculated
58      in the same way).  */
59   tree pattern_type = TREE_TYPE (TREE_TYPE (fndecl));
60 
61   unsigned i;
62   /* Hard coding the number of parameters we don't want to cast at the end of
63      the builtin.  This is the  easiest approach for the CDE intrinsics, and
64      introducing a parameter to store in the builtins.def macros seems overkill
65      when they're only relevant here.  */
66   unsigned end_args = arm_cde_end_args (fndecl);
67   unsigned cast_param_end = param_num - end_args;
68   /* For the vcx1q patterns that don't need any casts.  */
69   if (cast_param_end == 1)
70     return NULL_TREE;
71 
72   /* In order to check all arguments rather than complaining on the first
73      invalid one we record whether *any* arguments are invalid using this
74      boolean variable.  */
75   bool invalid = false;
76   for (i = 1; i < cast_param_end; i++)
77     {
78       tree this_param = (*params)[i];
79       if (TREE_CODE (this_param) == ERROR_MARK)
80 	{
81 	  invalid = true;
82 	  continue;
83 	}
84       tree param_type = TREE_TYPE (this_param);
85 
86       /* Return value is cast to type that second argument originally was.
87 	 All non-constant arguments are cast to the return type calculated from
88 	 the RTL pattern.
89 
90 	 Set the return type to an unqualified version of the type of the first
91 	 parameter.  The first parameter since that is how the intrinsics are
92 	 defined -- to always return the same type as the first polymorphic
93 	 argument.  Unqualified version of the type since we don't want passing
94 	 a constant parameter to mean that the return value of the builtin is
95 	 also constant.  */
96       if (i == 1)
97 	to_return = build_qualified_type (param_type, 0 MEM_STAT_INFO);
98 
99       /* The only requirement of these intrinsics on the type of the variable
100 	 is that it's 128 bits wide.  All other types are valid and we simply
101 	 VIEW_CONVERT_EXPR them to the type of the underlying builtin.  */
102       tree type_size = TYPE_SIZE (param_type);
103       if (! tree_fits_shwi_p (type_size)
104 	  || tree_to_shwi (type_size) != 128)
105 	{
106 	  error_at (loc,
107 		    "argument %u to function %qE is of type %qT which is not "
108 		    "known to be 128 bits wide",
109 		    i + 1, fndecl, param_type);
110 	  invalid = true;
111 	  continue;
112 	}
113 
114       /* Only convert the argument if we actually need to.  */
115       if (! check_base_type (pattern_type, param_type))
116 	(*params)[i] = build1 (VIEW_CONVERT_EXPR, pattern_type, this_param);
117     }
118   if (invalid)
119     return NULL_TREE;
120 
121   /* We know it's safe to call this since this builtin is here to implement an
122      ACLE function, and those functions are only for C/C++.  */
123   tree call_expr = build_function_call_vec (loc, vNULL, fndecl, params,
124 					    NULL, fndecl);
125 
126   gcc_assert (to_return != NULL_TREE);
127   if (! check_base_type (to_return, pattern_type))
128     return build1 (VIEW_CONVERT_EXPR, to_return, call_expr);
129   return call_expr;
130 }
131 
132 /* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN.  This is currently only
133    used for the MVE related builtins for the CDE extension.
134    Here we ensure the type of arguments is such that the size is correct, and
135    then return a tree that describes the same function call but with the
136    relevant types cast as necessary.  */
137 tree
arm_resolve_overloaded_builtin(location_t loc,tree fndecl,void * arglist)138 arm_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist)
139 {
140   if (arm_describe_resolver (fndecl) == arm_cde_resolver)
141     return arm_resolve_cde_builtin (loc, fndecl, arglist);
142   return NULL_TREE;
143 }
144 
145 /* Output C specific EABI object attributes.  These cannot be done in
146    arm.c because they require information from the C frontend.  */
147 
148 static void
arm_output_c_attributes(void)149 arm_output_c_attributes (void)
150 {
151   int wchar_size = (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT);
152   arm_emit_eabi_attribute ("Tag_ABI_PCS_wchar_t", 18, wchar_size);
153 }
154 
155 
156 /* Setup so that common code calls arm_output_c_attributes.  */
157 
158 void
arm_lang_object_attributes_init(void)159 arm_lang_object_attributes_init (void)
160 {
161   arm_lang_output_object_attributes_hook = arm_output_c_attributes;
162 }
163 
164 #define builtin_define(TXT) cpp_define (pfile, TXT)
165 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
166 
167 /* Define or undefine macros based on the current target.  If the user does
168    #pragma GCC target, we need to adjust the macros dynamically.  */
169 
170 static void
def_or_undef_macro(struct cpp_reader * pfile,const char * name,bool def_p)171 def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p)
172 {
173   if (def_p)
174     cpp_define (pfile, name);
175   else
176     cpp_undef (pfile, name);
177 }
178 
179 static void
arm_cpu_builtins(struct cpp_reader * pfile)180 arm_cpu_builtins (struct cpp_reader* pfile)
181 {
182   def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", TARGET_DSP_MULTIPLY);
183   def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", TARGET_ARM_QBIT);
184   def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", TARGET_ARM_SAT);
185   def_or_undef_macro (pfile, "__ARM_FEATURE_CRYPTO", TARGET_CRYPTO);
186 
187   def_or_undef_macro (pfile, "__ARM_FEATURE_UNALIGNED", unaligned_access);
188 
189   def_or_undef_macro (pfile, "__ARM_FEATURE_QRDMX", TARGET_NEON_RDMA);
190 
191   def_or_undef_macro (pfile, "__ARM_FEATURE_CRC32", TARGET_CRC32);
192   def_or_undef_macro (pfile, "__ARM_FEATURE_DOTPROD", TARGET_DOTPROD);
193   def_or_undef_macro (pfile, "__ARM_FEATURE_COMPLEX", TARGET_COMPLEX);
194   def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT);
195 
196   cpp_undef (pfile, "__ARM_FEATURE_MVE");
197   if (TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT)
198     {
199       builtin_define_with_int_value ("__ARM_FEATURE_MVE", 3);
200     }
201   else if (TARGET_HAVE_MVE)
202     {
203       builtin_define_with_int_value ("__ARM_FEATURE_MVE", 1);
204     }
205 
206   cpp_undef (pfile, "__ARM_FEATURE_CMSE");
207   if (arm_arch8 && !arm_arch_notm)
208     {
209       if (arm_arch_cmse && use_cmse)
210 	builtin_define_with_int_value ("__ARM_FEATURE_CMSE", 3);
211       else
212 	builtin_define ("__ARM_FEATURE_CMSE");
213     }
214 
215   cpp_undef (pfile, "__ARM_FEATURE_LDREX");
216   if (TARGET_ARM_FEATURE_LDREX)
217     builtin_define_with_int_value ("__ARM_FEATURE_LDREX",
218 				   TARGET_ARM_FEATURE_LDREX);
219 
220   def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ",
221 		      ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB)
222 		       || TARGET_ARM_ARCH_ISA_THUMB >=2));
223 
224   def_or_undef_macro (pfile, "__ARM_FEATURE_NUMERIC_MAXMIN",
225 		      TARGET_ARM_ARCH >= 8 && TARGET_NEON && TARGET_VFP5);
226 
227   def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD);
228 
229   builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
230 				 flag_short_enums ? 1 : 4);
231   builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node);
232 
233   cpp_undef (pfile, "__ARM_ARCH_PROFILE");
234   if (TARGET_ARM_ARCH_PROFILE)
235     builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
236 				   TARGET_ARM_ARCH_PROFILE);
237 
238   /* Define __arm__ even when in thumb mode, for
239      consistency with armcc.  */
240   builtin_define ("__arm__");
241   if (TARGET_ARM_ARCH)
242     {
243       cpp_undef (pfile, "__ARM_ARCH");
244       builtin_define_with_int_value ("__ARM_ARCH", TARGET_ARM_ARCH);
245     }
246   if (arm_arch_notm)
247     builtin_define ("__ARM_ARCH_ISA_ARM");
248   builtin_define ("__APCS_32__");
249 
250   def_or_undef_macro (pfile, "__GCC_ASM_FLAG_OUTPUTS__", !TARGET_THUMB1);
251 
252   def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB);
253   def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2);
254   if (TARGET_BIG_END)
255     def_or_undef_macro (pfile, "__THUMBEB__", TARGET_THUMB);
256   else
257     def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB);
258 
259   cpp_undef (pfile, "__ARM_ARCH_ISA_THUMB");
260   if (TARGET_ARM_ARCH_ISA_THUMB)
261     builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB",
262 				   TARGET_ARM_ARCH_ISA_THUMB);
263 
264   if (TARGET_BIG_END)
265     {
266       builtin_define ("__ARMEB__");
267       builtin_define ("__ARM_BIG_ENDIAN");
268     }
269   else
270     {
271       builtin_define ("__ARMEL__");
272     }
273 
274   if (TARGET_SOFT_FLOAT)
275     builtin_define ("__SOFTFP__");
276 
277   builtin_define ("__VFP_FP__");
278 
279   cpp_undef (pfile, "__ARM_FP");
280   if (TARGET_ARM_FP)
281     builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP);
282 
283   def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
284 		      arm_fp16_format == ARM_FP16_FORMAT_IEEE);
285   def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
286 		      arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
287   def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
288 		      arm_fp16_format != ARM_FP16_FORMAT_NONE);
289 
290   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_SCALAR_ARITHMETIC",
291 		      TARGET_VFP_FP16INST);
292   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_VECTOR_ARITHMETIC",
293 		      TARGET_NEON_FP16INST);
294   def_or_undef_macro (pfile, "__ARM_FEATURE_FP16_FML", TARGET_FP16FML);
295 
296   def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
297   def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
298   def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON);
299 
300   cpp_undef (pfile, "__ARM_NEON_FP");
301   if (TARGET_NEON_FP)
302     builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP);
303 
304   /* Add a define for interworking. Needed when building libgcc.a.  */
305   if (arm_cpp_interwork)
306     builtin_define ("__THUMB_INTERWORK__");
307 
308   builtin_define (arm_arch_name);
309   if (arm_arch_xscale)
310     builtin_define ("__XSCALE__");
311   if (arm_arch_iwmmxt)
312     {
313       builtin_define ("__IWMMXT__");
314       builtin_define ("__ARM_WMMX");
315     }
316   if (arm_arch_iwmmxt2)
317     builtin_define ("__IWMMXT2__");
318   /* ARMv6KZ was originally identified as the misspelled __ARM_ARCH_6ZK__.  To
319      preserve the existing behavior, the misspelled feature macro must still be
320      defined.  */
321   if (arm_arch6kz)
322     builtin_define ("__ARM_ARCH_6ZK__");
323   if (TARGET_AAPCS_BASED)
324     {
325       if (arm_pcs_default == ARM_PCS_AAPCS_VFP)
326 	builtin_define ("__ARM_PCS_VFP");
327       else if (arm_pcs_default == ARM_PCS_AAPCS)
328 	builtin_define ("__ARM_PCS");
329       builtin_define ("__ARM_EABI__");
330     }
331 
332   def_or_undef_macro (pfile, "__FDPIC__", TARGET_FDPIC);
333 
334   def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV);
335   def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV);
336 
337   def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
338 
339   cpp_undef (pfile, "__ARM_FEATURE_COPROC");
340   if (TARGET_32BIT && arm_arch4 && !(arm_arch8 && arm_arch_notm))
341     {
342       int coproc_level = 0x1;
343 
344       if (arm_arch5t)
345 	coproc_level |= 0x2;
346       if (arm_arch5te)
347 	coproc_level |= 0x4;
348       if (arm_arch6)
349 	coproc_level |= 0x8;
350 
351       builtin_define_with_int_value ("__ARM_FEATURE_COPROC", coproc_level);
352     }
353 
354   def_or_undef_macro (pfile, "__ARM_FEATURE_CDE", TARGET_CDE);
355   cpp_undef (pfile, "__ARM_FEATURE_CDE_COPROC");
356   if (TARGET_CDE)
357     builtin_define_with_int_value ("__ARM_FEATURE_CDE_COPROC",
358 				   arm_arch_cde_coproc);
359 
360   def_or_undef_macro (pfile, "__ARM_FEATURE_MATMUL_INT8", TARGET_I8MM);
361   def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_SCALAR_ARITHMETIC",
362 		      TARGET_BF16_FP);
363   def_or_undef_macro (pfile, "__ARM_FEATURE_BF16_VECTOR_ARITHMETIC",
364 		      TARGET_BF16_SIMD);
365   def_or_undef_macro (pfile, "__ARM_BF16_FORMAT_ALTERNATIVE",
366 		      TARGET_BF16_FP || TARGET_BF16_SIMD);
367 }
368 
369 void
arm_cpu_cpp_builtins(struct cpp_reader * pfile)370 arm_cpu_cpp_builtins (struct cpp_reader * pfile)
371 {
372   builtin_assert ("cpu=arm");
373   builtin_assert ("machine=arm");
374 
375   arm_cpu_builtins (pfile);
376 }
377 
378 /* Hook to validate the current #pragma GCC target and set the arch custom
379    mode state.  If ARGS is NULL, then POP_TARGET is used to reset
380    the options.  */
381 
382 static bool
arm_pragma_target_parse(tree args,tree pop_target)383 arm_pragma_target_parse (tree args, tree pop_target)
384 {
385   tree prev_tree = target_option_current_node;
386   tree cur_tree;
387   struct cl_target_option *prev_opt;
388   struct cl_target_option *cur_opt;
389 
390   if (! args)
391     {
392       cur_tree = ((pop_target) ? pop_target : target_option_default_node);
393       cl_target_option_restore (&global_options,
394 				TREE_TARGET_OPTION (cur_tree));
395     }
396   else
397     {
398       cur_tree = arm_valid_target_attribute_tree (args, &global_options,
399 						  &global_options_set);
400       if (cur_tree == NULL_TREE)
401 	{
402 	  cl_target_option_restore (&global_options,
403 				    TREE_TARGET_OPTION (prev_tree));
404 	  return false;
405 	}
406 
407       /* handle_pragma_pop_options and handle_pragma_reset_options will set
408        target_option_current_node, but not handle_pragma_target.  */
409       target_option_current_node = cur_tree;
410       arm_configure_build_target (&arm_active_target,
411 				  TREE_TARGET_OPTION (cur_tree),
412 				  &global_options_set, false);
413     }
414 
415   /* Update macros if target_node changes. The global state will be restored
416      by arm_set_current_function.  */
417   prev_opt = TREE_TARGET_OPTION (prev_tree);
418   cur_opt  = TREE_TARGET_OPTION (cur_tree);
419 
420   gcc_assert (prev_opt);
421   gcc_assert (cur_opt);
422 
423   if (cur_opt != prev_opt)
424     {
425       /* For the definitions, ensure all newly defined macros are considered
426 	 as used for -Wunused-macros.  There is no point warning about the
427 	 compiler predefined macros.  */
428       cpp_options *cpp_opts = cpp_get_options (parse_in);
429       unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
430 
431       cpp_opts->warn_unused_macros = 0;
432 
433       /* Update macros.  */
434       gcc_assert (cur_opt->x_target_flags == target_flags);
435 
436       /* Don't warn for macros that have context sensitive values depending on
437 	 other attributes.
438 	 See warn_of_redefinition, reset after cpp_create_definition.  */
439       tree acond_macro = get_identifier ("__ARM_NEON_FP");
440       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL ;
441 
442       acond_macro = get_identifier ("__ARM_FP");
443       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
444 
445       acond_macro = get_identifier ("__ARM_FEATURE_LDREX");
446       C_CPP_HASHNODE (acond_macro)->flags |= NODE_CONDITIONAL;
447 
448       arm_cpu_builtins (parse_in);
449 
450       cpp_opts->warn_unused_macros = saved_warn_unused_macros;
451 
452       /* Make sure that target_reinit is called for next function, since
453 	 TREE_TARGET_OPTION might change with the #pragma even if there is
454 	 no target attribute attached to the function.  */
455       arm_reset_previous_fndecl ();
456 
457       /* If going to the default mode, we restore the initial states.
458 	 if cur_tree is a new target, states will be saved/restored on a per
459 	 function basis in arm_set_current_function.  */
460       if (cur_tree == target_option_default_node)
461 	save_restore_target_globals (cur_tree);
462     }
463 
464   return true;
465 }
466 
467 /* Register target pragmas.  We need to add the hook for parsing #pragma GCC
468    option here rather than in arm.c since it will pull in various preprocessor
469    functions, and those are not present in languages like fortran without a
470    preprocessor.  */
471 
472 void
arm_register_target_pragmas(void)473 arm_register_target_pragmas (void)
474 {
475   /* Update pragma hook to allow parsing #pragma GCC target.  */
476   targetm.target_option.pragma_parse = arm_pragma_target_parse;
477   targetm.resolve_overloaded_builtin = arm_resolve_overloaded_builtin;
478 
479 #ifdef REGISTER_SUBTARGET_PRAGMAS
480   REGISTER_SUBTARGET_PRAGMAS ();
481 #endif
482 }
483