xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/aarch64/aarch64-c.c (revision 4f645668ed707e1f969c546666f8c8e45e6f8888)
1 /* Target-specific code for C family languages.
2    Copyright (C) 2015-2019 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
7    it 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,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU 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 "input.h"
27 #include "memmodel.h"
28 #include "tm_p.h"
29 #include "flags.h"
30 #include "c-family/c-common.h"
31 #include "cpplib.h"
32 #include "c-family/c-pragma.h"
33 #include "langhooks.h"
34 #include "target.h"
35 
36 
37 #define builtin_define(TXT) cpp_define (pfile, TXT)
38 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
39 
40 
41 static void
42 aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
43 {
44   if (def_p)
45     cpp_define (pfile, macro);
46   else
47     cpp_undef (pfile, macro);
48 }
49 
50 /* Define the macros that we always expect to have on AArch64.  */
51 
52 static void
53 aarch64_define_unconditional_macros (cpp_reader *pfile)
54 {
55   builtin_define ("__aarch64__");
56   builtin_define ("__ARM_64BIT_STATE");
57 
58   builtin_define ("__ARM_ARCH_ISA_A64");
59   builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
60   builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);
61 
62   /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
63      as interoperability with the same arm macro.  */
64   builtin_define ("__ARM_ARCH_8A");
65 
66   builtin_define_with_int_value ("__ARM_ARCH_PROFILE", 'A');
67   builtin_define ("__ARM_FEATURE_CLZ");
68   builtin_define ("__ARM_FEATURE_IDIV");
69   builtin_define ("__ARM_FEATURE_UNALIGNED");
70   builtin_define ("__ARM_PCS_AAPCS64");
71   builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);
72 }
73 
74 /* Undefine/redefine macros that depend on the current backend state and may
75    need to change when a target pragma modifies the backend state.  */
76 
77 static void
78 aarch64_update_cpp_builtins (cpp_reader *pfile)
79 {
80   aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);
81 
82   builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);
83 
84   builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
85 				 flag_short_enums ? 1 : 4);
86   aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
87   aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
88   aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);
89 
90   aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);
91 
92   if (TARGET_FLOAT || TARGET_SIMD)
93     {
94       builtin_define_with_int_value ("__ARM_FP", 0x0E);
95       builtin_define ("__ARM_FP16_FORMAT_IEEE");
96       builtin_define ("__ARM_FP16_ARGS");
97     }
98   else
99     cpp_undef (pfile, "__ARM_FP");
100 
101   aarch64_def_or_undef (TARGET_FP_F16INST,
102 			"__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile);
103   aarch64_def_or_undef (TARGET_SIMD_F16INST,
104 			"__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile);
105 
106   aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
107   aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);
108 
109 
110   aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
111   aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile);
112   aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile);
113 
114   cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
115   cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
116   cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");
117 
118   switch (aarch64_cmodel)
119     {
120       case AARCH64_CMODEL_TINY:
121       case AARCH64_CMODEL_TINY_PIC:
122 	builtin_define ("__AARCH64_CMODEL_TINY__");
123 	break;
124       case AARCH64_CMODEL_SMALL:
125       case AARCH64_CMODEL_SMALL_PIC:
126 	builtin_define ("__AARCH64_CMODEL_SMALL__");
127 	break;
128       case AARCH64_CMODEL_LARGE:
129 	builtin_define ("__AARCH64_CMODEL_LARGE__");
130 	break;
131       default:
132 	break;
133     }
134 
135   aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
136   aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);
137 
138   aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
139   aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile);
140   aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile);
141   cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS");
142   if (TARGET_SVE)
143     {
144       int bits;
145       if (!BITS_PER_SVE_VECTOR.is_constant (&bits))
146 	bits = 0;
147       builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits);
148     }
149 
150   aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile);
151   aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile);
152   aarch64_def_or_undef (TARGET_SHA2, "__ARM_FEATURE_SHA2", pfile);
153   aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA3", pfile);
154   aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA512", pfile);
155   aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM3", pfile);
156   aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile);
157   aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile);
158 
159   /* Not for ACLE, but required to keep "float.h" correct if we switch
160      target between implementations that do or do not support ARMv8.2-A
161      16-bit floating-point extensions.  */
162   cpp_undef (pfile, "__FLT_EVAL_METHOD__");
163   builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
164 				 c_flt_eval_method (true));
165   cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__");
166   builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__",
167 				 c_flt_eval_method (false));
168 }
169 
170 /* Implement TARGET_CPU_CPP_BUILTINS.  */
171 
172 void
173 aarch64_cpu_cpp_builtins (cpp_reader *pfile)
174 {
175   aarch64_define_unconditional_macros (pfile);
176   aarch64_update_cpp_builtins (pfile);
177 }
178 
179 /* Hook to validate the current #pragma GCC target and set the state, and
180    update the macros based on what was changed.  If ARGS is NULL, then
181    POP_TARGET is used to reset the options.  */
182 
183 static bool
184 aarch64_pragma_target_parse (tree args, tree pop_target)
185 {
186   /* If args is not NULL then process it and setup the target-specific
187      information that it specifies.  */
188   if (args)
189     {
190       if (!aarch64_process_target_attr (args))
191 	return false;
192 
193       aarch64_override_options_internal (&global_options);
194     }
195 
196   /* args is NULL, restore to the state described in pop_target.  */
197   else
198     {
199       pop_target = pop_target ? pop_target : target_option_default_node;
200       cl_target_option_restore (&global_options,
201 				TREE_TARGET_OPTION (pop_target));
202     }
203 
204   target_option_current_node
205     = build_target_option_node (&global_options);
206 
207   aarch64_reset_previous_fndecl ();
208   /* For the definitions, ensure all newly defined macros are considered
209      as used for -Wunused-macros.  There is no point warning about the
210      compiler predefined macros.  */
211   cpp_options *cpp_opts = cpp_get_options (parse_in);
212   unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
213   cpp_opts->warn_unused_macros = 0;
214 
215   aarch64_update_cpp_builtins (parse_in);
216 
217   cpp_opts->warn_unused_macros = saved_warn_unused_macros;
218 
219   /* If we're popping or reseting make sure to update the globals so that
220      the optab availability predicates get recomputed.  */
221   if (pop_target)
222     aarch64_save_restore_target_globals (pop_target);
223 
224   /* Initialize SIMD builtins if we haven't already.
225      Set current_target_pragma to NULL for the duration so that
226      the builtin initialization code doesn't try to tag the functions
227      being built with the attributes specified by any current pragma, thus
228      going into an infinite recursion.  */
229   if (TARGET_SIMD)
230     {
231       tree saved_current_target_pragma = current_target_pragma;
232       current_target_pragma = NULL;
233       aarch64_init_simd_builtins ();
234       current_target_pragma = saved_current_target_pragma;
235     }
236 
237   return true;
238 }
239 
240 /* Implement REGISTER_TARGET_PRAGMAS.  */
241 
242 void
243 aarch64_register_pragmas (void)
244 {
245   /* Update pragma hook to allow parsing #pragma GCC target.  */
246   targetm.target_option.pragma_parse = aarch64_pragma_target_parse;
247 }
248