Line data Source code
1 : /* Copyright (C) 1988-2026 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
6 : it under the terms of the GNU General Public License as published by
7 : the Free Software Foundation; either version 3, or (at your option)
8 : any later version.
9 :
10 : GCC is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU General Public License 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 "backend.h"
25 : #include "rtl.h"
26 : #include "tree.h"
27 : #include "memmodel.h"
28 : #include "gimple.h"
29 : #include "cfghooks.h"
30 : #include "cfgloop.h"
31 : #include "df.h"
32 : #include "tm_p.h"
33 : #include "stringpool.h"
34 : #include "expmed.h"
35 : #include "optabs.h"
36 : #include "regs.h"
37 : #include "emit-rtl.h"
38 : #include "recog.h"
39 : #include "cgraph.h"
40 : #include "diagnostic.h"
41 : #include "cfgbuild.h"
42 : #include "alias.h"
43 : #include "fold-const.h"
44 : #include "attribs.h"
45 : #include "calls.h"
46 : #include "stor-layout.h"
47 : #include "varasm.h"
48 : #include "output.h"
49 : #include "insn-attr.h"
50 : #include "flags.h"
51 : #include "except.h"
52 : #include "explow.h"
53 : #include "expr.h"
54 : #include "cfgrtl.h"
55 : #include "common/common-target.h"
56 : #include "langhooks.h"
57 : #include "reload.h"
58 : #include "gimplify.h"
59 : #include "dwarf2.h"
60 : #include "tm-constrs.h"
61 : #include "cselib.h"
62 : #include "sched-int.h"
63 : #include "opts.h"
64 : #include "tree-pass.h"
65 : #include "context.h"
66 : #include "pass_manager.h"
67 : #include "target-globals.h"
68 : #include "gimple-iterator.h"
69 : #include "shrink-wrap.h"
70 : #include "builtins.h"
71 : #include "rtl-iter.h"
72 : #include "tree-iterator.h"
73 : #include "dbgcnt.h"
74 : #include "case-cfn-macros.h"
75 : #include "dojump.h"
76 : #include "fold-const-call.h"
77 : #include "tree-vrp.h"
78 : #include "tree-ssanames.h"
79 : #include "selftest.h"
80 : #include "selftest-rtl.h"
81 : #include "print-rtl.h"
82 : #include "intl.h"
83 : #include "ifcvt.h"
84 : #include "symbol-summary.h"
85 : #include "sreal.h"
86 : #include "ipa-cp.h"
87 : #include "ipa-prop.h"
88 : #include "ipa-fnsummary.h"
89 : #include "wide-int-bitmask.h"
90 : #include "tree-vector-builder.h"
91 : #include "debug.h"
92 : #include "dwarf2out.h"
93 : #include "i386-options.h"
94 :
95 : #include "x86-tune-costs.h"
96 :
97 : #ifndef SUBTARGET32_DEFAULT_CPU
98 : #define SUBTARGET32_DEFAULT_CPU "i386"
99 : #endif
100 :
101 : /* Processor feature/optimization bitmasks. */
102 : #define m_NONE HOST_WIDE_INT_0U
103 : #define m_ALL (~HOST_WIDE_INT_0U)
104 : #define m_386 (HOST_WIDE_INT_1U<<PROCESSOR_I386)
105 : #define m_486 (HOST_WIDE_INT_1U<<PROCESSOR_I486)
106 : #define m_PENT (HOST_WIDE_INT_1U<<PROCESSOR_PENTIUM)
107 : #define m_LAKEMONT (HOST_WIDE_INT_1U<<PROCESSOR_LAKEMONT)
108 : #define m_PPRO (HOST_WIDE_INT_1U<<PROCESSOR_PENTIUMPRO)
109 : #define m_PENT4 (HOST_WIDE_INT_1U<<PROCESSOR_PENTIUM4)
110 : #define m_NOCONA (HOST_WIDE_INT_1U<<PROCESSOR_NOCONA)
111 : #define m_P4_NOCONA (m_PENT4 | m_NOCONA)
112 : #define m_CORE2 (HOST_WIDE_INT_1U<<PROCESSOR_CORE2)
113 : #define m_NEHALEM (HOST_WIDE_INT_1U<<PROCESSOR_NEHALEM)
114 : #define m_SANDYBRIDGE (HOST_WIDE_INT_1U<<PROCESSOR_SANDYBRIDGE)
115 : #define m_HASWELL (HOST_WIDE_INT_1U<<PROCESSOR_HASWELL)
116 : #define m_BONNELL (HOST_WIDE_INT_1U<<PROCESSOR_BONNELL)
117 : #define m_SILVERMONT (HOST_WIDE_INT_1U<<PROCESSOR_SILVERMONT)
118 : #define m_SKYLAKE (HOST_WIDE_INT_1U<<PROCESSOR_SKYLAKE)
119 : #define m_SKYLAKE_AVX512 (HOST_WIDE_INT_1U<<PROCESSOR_SKYLAKE_AVX512)
120 : #define m_CANNONLAKE (HOST_WIDE_INT_1U<<PROCESSOR_CANNONLAKE)
121 : #define m_ICELAKE_CLIENT (HOST_WIDE_INT_1U<<PROCESSOR_ICELAKE_CLIENT)
122 : #define m_ICELAKE_SERVER (HOST_WIDE_INT_1U<<PROCESSOR_ICELAKE_SERVER)
123 : #define m_CASCADELAKE (HOST_WIDE_INT_1U<<PROCESSOR_CASCADELAKE)
124 : #define m_TIGERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_TIGERLAKE)
125 : #define m_COOPERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_COOPERLAKE)
126 : #define m_SAPPHIRERAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_SAPPHIRERAPIDS)
127 : #define m_ALDERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_ALDERLAKE)
128 : #define m_ROCKETLAKE (HOST_WIDE_INT_1U<<PROCESSOR_ROCKETLAKE)
129 : #define m_GRANITERAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_GRANITERAPIDS)
130 : #define m_GRANITERAPIDS_D (HOST_WIDE_INT_1U<<PROCESSOR_GRANITERAPIDS_D)
131 : #define m_ARROWLAKE (HOST_WIDE_INT_1U<<PROCESSOR_ARROWLAKE)
132 : #define m_ARROWLAKE_S (HOST_WIDE_INT_1U<<PROCESSOR_ARROWLAKE_S)
133 : #define m_PANTHERLAKE (HOST_WIDE_INT_1U<<PROCESSOR_PANTHERLAKE)
134 : #define m_DIAMONDRAPIDS (HOST_WIDE_INT_1U<<PROCESSOR_DIAMONDRAPIDS)
135 : #define m_NOVALAKE (HOST_WIDE_INT_1U<<PROCESSOR_NOVALAKE)
136 : #define m_CORE_AVX512 (m_SKYLAKE_AVX512 | m_CANNONLAKE \
137 : | m_ICELAKE_CLIENT | m_ICELAKE_SERVER | m_CASCADELAKE \
138 : | m_TIGERLAKE | m_COOPERLAKE | m_SAPPHIRERAPIDS \
139 : | m_ROCKETLAKE | m_GRANITERAPIDS | m_GRANITERAPIDS_D \
140 : | m_DIAMONDRAPIDS)
141 : #define m_CORE_AVX2 (m_HASWELL | m_SKYLAKE | m_CORE_AVX512)
142 : #define m_CORE_ALL (m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_CORE_AVX2)
143 : #define m_CORE_HYBRID (m_ALDERLAKE | m_ARROWLAKE | m_ARROWLAKE_S \
144 : | m_PANTHERLAKE | m_NOVALAKE)
145 : #define m_GOLDMONT (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT)
146 : #define m_GOLDMONT_PLUS (HOST_WIDE_INT_1U<<PROCESSOR_GOLDMONT_PLUS)
147 : #define m_TREMONT (HOST_WIDE_INT_1U<<PROCESSOR_TREMONT)
148 : #define m_SIERRAFOREST (HOST_WIDE_INT_1U<<PROCESSOR_SIERRAFOREST)
149 : #define m_GRANDRIDGE (HOST_WIDE_INT_1U<<PROCESSOR_GRANDRIDGE)
150 : #define m_CLEARWATERFOREST (HOST_WIDE_INT_1U<<PROCESSOR_CLEARWATERFOREST)
151 : #define m_CORE_ATOM (m_SIERRAFOREST | m_GRANDRIDGE | m_CLEARWATERFOREST)
152 : #define m_INTEL (HOST_WIDE_INT_1U<<PROCESSOR_INTEL)
153 : /* Gather Data Sampling / CVE-2022-40982 / INTEL-SA-00828.
154 : Software mitigation. */
155 : #define m_GDS (m_SKYLAKE | m_SKYLAKE_AVX512 | m_CANNONLAKE \
156 : | m_ICELAKE_CLIENT | m_ICELAKE_SERVER | m_CASCADELAKE \
157 : | m_TIGERLAKE | m_COOPERLAKE | m_ROCKETLAKE)
158 :
159 : #define m_LUJIAZUI (HOST_WIDE_INT_1U<<PROCESSOR_LUJIAZUI)
160 : #define m_YONGFENG (HOST_WIDE_INT_1U<<PROCESSOR_YONGFENG)
161 : #define m_SHIJIDADAO (HOST_WIDE_INT_1U<<PROCESSOR_SHIJIDADAO)
162 : #define m_ZHAOXIN (m_LUJIAZUI | m_YONGFENG | m_SHIJIDADAO)
163 :
164 : #define m_GEODE (HOST_WIDE_INT_1U<<PROCESSOR_GEODE)
165 : #define m_K6 (HOST_WIDE_INT_1U<<PROCESSOR_K6)
166 : #define m_K6_GEODE (m_K6 | m_GEODE)
167 : #define m_K8 (HOST_WIDE_INT_1U<<PROCESSOR_K8)
168 : #define m_ATHLON (HOST_WIDE_INT_1U<<PROCESSOR_ATHLON)
169 : #define m_ATHLON_K8 (m_K8 | m_ATHLON)
170 : #define m_AMDFAM10 (HOST_WIDE_INT_1U<<PROCESSOR_AMDFAM10)
171 : #define m_BDVER1 (HOST_WIDE_INT_1U<<PROCESSOR_BDVER1)
172 : #define m_BDVER2 (HOST_WIDE_INT_1U<<PROCESSOR_BDVER2)
173 : #define m_BDVER3 (HOST_WIDE_INT_1U<<PROCESSOR_BDVER3)
174 : #define m_BDVER4 (HOST_WIDE_INT_1U<<PROCESSOR_BDVER4)
175 : #define m_ZNVER1 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER1)
176 : #define m_ZNVER2 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER2)
177 : #define m_ZNVER3 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER3)
178 : #define m_ZNVER4 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER4)
179 : #define m_ZNVER5 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER5)
180 : #define m_ZNVER6 (HOST_WIDE_INT_1U<<PROCESSOR_ZNVER6)
181 : #define m_BTVER1 (HOST_WIDE_INT_1U<<PROCESSOR_BTVER1)
182 : #define m_BTVER2 (HOST_WIDE_INT_1U<<PROCESSOR_BTVER2)
183 : #define m_BDVER (m_BDVER1 | m_BDVER2 | m_BDVER3 | m_BDVER4)
184 : #define m_BTVER (m_BTVER1 | m_BTVER2)
185 : #define m_ZNVER (m_ZNVER1 | m_ZNVER2 | m_ZNVER3 | m_ZNVER4 | m_ZNVER5 | m_ZNVER6)
186 : #define m_AMD_MULTIPLE (m_ATHLON_K8 | m_AMDFAM10 | m_BDVER | m_BTVER \
187 : | m_ZNVER)
188 :
189 : #define m_GENERIC (HOST_WIDE_INT_1U<<PROCESSOR_GENERIC)
190 :
191 : const char* ix86_tune_feature_names[X86_TUNE_LAST] = {
192 : #undef DEF_TUNE
193 : #define DEF_TUNE(tune, name, selector) name,
194 : #include "x86-tune.def"
195 : #undef DEF_TUNE
196 : };
197 :
198 : /* Feature tests against the various tunings. */
199 : unsigned char ix86_tune_features[X86_TUNE_LAST];
200 :
201 : /* Feature tests against the various tunings used to create ix86_tune_features
202 : based on the processor mask. */
203 : static unsigned HOST_WIDE_INT initial_ix86_tune_features[X86_TUNE_LAST] = {
204 : #undef DEF_TUNE
205 : #define DEF_TUNE(tune, name, selector) selector,
206 : #include "x86-tune.def"
207 : #undef DEF_TUNE
208 : };
209 :
210 : /* Feature tests against the various architecture variations. */
211 : unsigned char ix86_arch_features[X86_ARCH_LAST];
212 :
213 : struct ix86_target_opts
214 : {
215 : const char *option; /* option string */
216 : HOST_WIDE_INT mask; /* isa mask options */
217 : };
218 :
219 : /* This table is ordered so that options like -msse4.2 that imply other
220 : ISAs come first. Target string will be displayed in the same order. */
221 : static struct ix86_target_opts isa2_opts[] =
222 : {
223 : { "-mcx16", OPTION_MASK_ISA2_CX16 },
224 : { "-mvaes", OPTION_MASK_ISA2_VAES },
225 : { "-mrdpid", OPTION_MASK_ISA2_RDPID },
226 : { "-mpconfig", OPTION_MASK_ISA2_PCONFIG },
227 : { "-mwbnoinvd", OPTION_MASK_ISA2_WBNOINVD },
228 : { "-mavx512vp2intersect", OPTION_MASK_ISA2_AVX512VP2INTERSECT },
229 : { "-msgx", OPTION_MASK_ISA2_SGX },
230 : { "-mhle", OPTION_MASK_ISA2_HLE },
231 : { "-mmovbe", OPTION_MASK_ISA2_MOVBE },
232 : { "-mclzero", OPTION_MASK_ISA2_CLZERO },
233 : { "-mmwaitx", OPTION_MASK_ISA2_MWAITX },
234 : { "-mmwait", OPTION_MASK_ISA2_MWAIT },
235 : { "-mmovdir64b", OPTION_MASK_ISA2_MOVDIR64B },
236 : { "-mwaitpkg", OPTION_MASK_ISA2_WAITPKG },
237 : { "-mcldemote", OPTION_MASK_ISA2_CLDEMOTE },
238 : { "-mptwrite", OPTION_MASK_ISA2_PTWRITE },
239 : { "-mavx512bf16", OPTION_MASK_ISA2_AVX512BF16 },
240 : { "-menqcmd", OPTION_MASK_ISA2_ENQCMD },
241 : { "-mserialize", OPTION_MASK_ISA2_SERIALIZE },
242 : { "-mtsxldtrk", OPTION_MASK_ISA2_TSXLDTRK },
243 : { "-mamx-tile", OPTION_MASK_ISA2_AMX_TILE },
244 : { "-mamx-int8", OPTION_MASK_ISA2_AMX_INT8 },
245 : { "-mamx-bf16", OPTION_MASK_ISA2_AMX_BF16 },
246 : { "-muintr", OPTION_MASK_ISA2_UINTR },
247 : { "-mhreset", OPTION_MASK_ISA2_HRESET },
248 : { "-mkl", OPTION_MASK_ISA2_KL },
249 : { "-mwidekl", OPTION_MASK_ISA2_WIDEKL },
250 : { "-mavxvnni", OPTION_MASK_ISA2_AVXVNNI },
251 : { "-mavx512fp16", OPTION_MASK_ISA2_AVX512FP16 },
252 : { "-mavxifma", OPTION_MASK_ISA2_AVXIFMA },
253 : { "-mavxvnniint8", OPTION_MASK_ISA2_AVXVNNIINT8 },
254 : { "-mavxneconvert", OPTION_MASK_ISA2_AVXNECONVERT },
255 : { "-mcmpccxadd", OPTION_MASK_ISA2_CMPCCXADD },
256 : { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 },
257 : { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI },
258 : { "-mraoint", OPTION_MASK_ISA2_RAOINT },
259 : { "-mamx-complex", OPTION_MASK_ISA2_AMX_COMPLEX },
260 : { "-mavxvnniint16", OPTION_MASK_ISA2_AVXVNNIINT16 },
261 : { "-msm3", OPTION_MASK_ISA2_SM3 },
262 : { "-msha512", OPTION_MASK_ISA2_SHA512 },
263 : { "-msm4", OPTION_MASK_ISA2_SM4 },
264 : { "-musermsr", OPTION_MASK_ISA2_USER_MSR },
265 : { "-mavx10.1", OPTION_MASK_ISA2_AVX10_1 },
266 : { "-mavx10.2", OPTION_MASK_ISA2_AVX10_2 },
267 : { "-mamx-avx512", OPTION_MASK_ISA2_AMX_AVX512 },
268 : { "-mamx-tf32", OPTION_MASK_ISA2_AMX_TF32 },
269 : { "-mamx-fp8", OPTION_MASK_ISA2_AMX_FP8 },
270 : { "-mmovrs", OPTION_MASK_ISA2_MOVRS },
271 : { "-mamx-movrs", OPTION_MASK_ISA2_AMX_MOVRS },
272 : { "-mavx512bmm", OPTION_MASK_ISA2_AVX512BMM }
273 : };
274 : static struct ix86_target_opts isa_opts[] =
275 : {
276 : { "-mavx512vpopcntdq", OPTION_MASK_ISA_AVX512VPOPCNTDQ },
277 : { "-mavx512bitalg", OPTION_MASK_ISA_AVX512BITALG },
278 : { "-mvpclmulqdq", OPTION_MASK_ISA_VPCLMULQDQ },
279 : { "-mgfni", OPTION_MASK_ISA_GFNI },
280 : { "-mavx512vnni", OPTION_MASK_ISA_AVX512VNNI },
281 : { "-mavx512vbmi2", OPTION_MASK_ISA_AVX512VBMI2 },
282 : { "-mavx512vbmi", OPTION_MASK_ISA_AVX512VBMI },
283 : { "-mavx512ifma", OPTION_MASK_ISA_AVX512IFMA },
284 : { "-mavx512vl", OPTION_MASK_ISA_AVX512VL },
285 : { "-mavx512bw", OPTION_MASK_ISA_AVX512BW },
286 : { "-mavx512dq", OPTION_MASK_ISA_AVX512DQ },
287 : { "-mavx512cd", OPTION_MASK_ISA_AVX512CD },
288 : { "-mavx512f", OPTION_MASK_ISA_AVX512F },
289 : { "-mavx2", OPTION_MASK_ISA_AVX2 },
290 : { "-mfma", OPTION_MASK_ISA_FMA },
291 : { "-mxop", OPTION_MASK_ISA_XOP },
292 : { "-mfma4", OPTION_MASK_ISA_FMA4 },
293 : { "-mf16c", OPTION_MASK_ISA_F16C },
294 : { "-mavx", OPTION_MASK_ISA_AVX },
295 : /*{ "-msse4" OPTION_MASK_ISA_SSE4 }, */
296 : { "-msse4.2", OPTION_MASK_ISA_SSE4_2 },
297 : { "-msse4.1", OPTION_MASK_ISA_SSE4_1 },
298 : { "-msse4a", OPTION_MASK_ISA_SSE4A },
299 : { "-mssse3", OPTION_MASK_ISA_SSSE3 },
300 : { "-msse3", OPTION_MASK_ISA_SSE3 },
301 : { "-maes", OPTION_MASK_ISA_AES },
302 : { "-msha", OPTION_MASK_ISA_SHA },
303 : { "-mpclmul", OPTION_MASK_ISA_PCLMUL },
304 : { "-msse2", OPTION_MASK_ISA_SSE2 },
305 : { "-msse", OPTION_MASK_ISA_SSE },
306 : { "-m3dnowa", OPTION_MASK_ISA_3DNOW_A },
307 : { "-m3dnow", OPTION_MASK_ISA_3DNOW },
308 : { "-mmmx", OPTION_MASK_ISA_MMX },
309 : { "-mrtm", OPTION_MASK_ISA_RTM },
310 : { "-mprfchw", OPTION_MASK_ISA_PRFCHW },
311 : { "-mrdseed", OPTION_MASK_ISA_RDSEED },
312 : { "-madx", OPTION_MASK_ISA_ADX },
313 : { "-mclflushopt", OPTION_MASK_ISA_CLFLUSHOPT },
314 : { "-mxsaves", OPTION_MASK_ISA_XSAVES },
315 : { "-mxsavec", OPTION_MASK_ISA_XSAVEC },
316 : { "-mxsaveopt", OPTION_MASK_ISA_XSAVEOPT },
317 : { "-mxsave", OPTION_MASK_ISA_XSAVE },
318 : { "-mabm", OPTION_MASK_ISA_ABM },
319 : { "-mbmi", OPTION_MASK_ISA_BMI },
320 : { "-mbmi2", OPTION_MASK_ISA_BMI2 },
321 : { "-mlzcnt", OPTION_MASK_ISA_LZCNT },
322 : { "-mtbm", OPTION_MASK_ISA_TBM },
323 : { "-mpopcnt", OPTION_MASK_ISA_POPCNT },
324 : { "-msahf", OPTION_MASK_ISA_SAHF },
325 : { "-mcrc32", OPTION_MASK_ISA_CRC32 },
326 : { "-mfsgsbase", OPTION_MASK_ISA_FSGSBASE },
327 : { "-mrdrnd", OPTION_MASK_ISA_RDRND },
328 : { "-mpku", OPTION_MASK_ISA_PKU },
329 : { "-mlwp", OPTION_MASK_ISA_LWP },
330 : { "-mfxsr", OPTION_MASK_ISA_FXSR },
331 : { "-mclwb", OPTION_MASK_ISA_CLWB },
332 : { "-mshstk", OPTION_MASK_ISA_SHSTK },
333 : { "-mmovdiri", OPTION_MASK_ISA_MOVDIRI }
334 : };
335 :
336 : /* Return 1 if TRAIT NAME is present in the OpenMP context's
337 : device trait set, return 0 if not present in any OpenMP context in the
338 : whole translation unit, or -1 if not present in the current OpenMP context
339 : but might be present in another OpenMP context in the same TU. */
340 :
341 : int
342 1939 : ix86_omp_device_kind_arch_isa (enum omp_device_kind_arch_isa trait,
343 : const char *name)
344 : {
345 1939 : switch (trait)
346 : {
347 363 : case omp_device_kind:
348 363 : return strcmp (name, "cpu") == 0;
349 760 : case omp_device_arch:
350 760 : if (strcmp (name, "x86") == 0)
351 : return 1;
352 756 : if (TARGET_64BIT)
353 : {
354 756 : if (TARGET_X32)
355 0 : return strcmp (name, "x32") == 0;
356 : else
357 756 : return strcmp (name, "x86_64") == 0;
358 : }
359 0 : if (strcmp (name, "ia32") == 0 || strcmp (name, "i386") == 0)
360 : return 1;
361 0 : if (strcmp (name, "i486") == 0)
362 0 : return ix86_arch != PROCESSOR_I386 ? 1 : -1;
363 0 : if (strcmp (name, "i586") == 0)
364 0 : return (ix86_arch != PROCESSOR_I386
365 0 : && ix86_arch != PROCESSOR_I486) ? 1 : -1;
366 0 : if (strcmp (name, "i686") == 0)
367 0 : return (ix86_arch != PROCESSOR_I386
368 0 : && ix86_arch != PROCESSOR_I486
369 0 : && ix86_arch != PROCESSOR_LAKEMONT
370 0 : && ix86_arch != PROCESSOR_PENTIUM) ? 1 : -1;
371 : return 0;
372 : case omp_device_isa:
373 914 : for (int i = 0; i < 2; i++)
374 : {
375 865 : struct ix86_target_opts *opts = i ? isa2_opts : isa_opts;
376 865 : size_t nopts = i ? ARRAY_SIZE (isa2_opts) : ARRAY_SIZE (isa_opts);
377 865 : HOST_WIDE_INT mask = i ? ix86_isa_flags2 : ix86_isa_flags;
378 16172 : for (size_t n = 0; n < nopts; n++)
379 : {
380 : /* Handle sse4 as an alias to sse4.2. */
381 16074 : if (opts[n].mask == OPTION_MASK_ISA_SSE4_2)
382 : {
383 227 : if (strcmp (name, "sse4") == 0)
384 38 : return (mask & opts[n].mask) != 0 ? 1 : -1;
385 : }
386 16045 : if (strcmp (name, opts[n].option + 2) == 0)
387 1014 : return (mask & opts[n].mask) != 0 ? 1 : -1;
388 : }
389 : }
390 : return 0;
391 0 : default:
392 0 : gcc_unreachable ();
393 : }
394 : }
395 :
396 : /* Return a string that documents the current -m options. The caller is
397 : responsible for freeing the string. */
398 :
399 : char *
400 23 : ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
401 : int flags, int flags2,
402 : const char *arch, const char *tune,
403 : enum fpmath_unit fpmath,
404 : enum prefer_vector_width pvw,
405 : enum prefer_vector_width move_max,
406 : bool add_nl_p, bool add_abi_p)
407 : {
408 : /* Flag options. */
409 23 : static struct ix86_target_opts flag_opts[] =
410 : {
411 : { "-m128bit-long-double", MASK_128BIT_LONG_DOUBLE },
412 : { "-mlong-double-128", MASK_LONG_DOUBLE_128 },
413 : { "-mlong-double-64", MASK_LONG_DOUBLE_64 },
414 : { "-m80387", MASK_80387 },
415 : { "-maccumulate-outgoing-args", MASK_ACCUMULATE_OUTGOING_ARGS },
416 : { "-malign-double", MASK_ALIGN_DOUBLE },
417 : { "-mcld", MASK_CLD },
418 : { "-mfp-ret-in-387", MASK_FLOAT_RETURNS },
419 : { "-mieee-fp", MASK_IEEE_FP },
420 : { "-minline-all-stringops", MASK_INLINE_ALL_STRINGOPS },
421 : { "-minline-stringops-dynamically", MASK_INLINE_STRINGOPS_DYNAMICALLY },
422 : { "-mms-bitfields", MASK_MS_BITFIELD_LAYOUT },
423 : { "-mno-align-stringops", MASK_NO_ALIGN_STRINGOPS },
424 : { "-mno-fancy-math-387", MASK_NO_FANCY_MATH_387 },
425 : { "-mno-push-args", MASK_NO_PUSH_ARGS },
426 : { "-mno-red-zone", MASK_NO_RED_ZONE },
427 : { "-momit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER },
428 : { "-mrecip", MASK_RECIP },
429 : { "-mrtd", MASK_RTD },
430 : { "-msseregparm", MASK_SSEREGPARM },
431 : { "-mstack-arg-probe", MASK_STACK_PROBE },
432 : { "-mtls-direct-seg-refs", MASK_TLS_DIRECT_SEG_REFS },
433 : { "-mvect8-ret-in-mem", MASK_VECT8_RETURNS },
434 : { "-m8bit-idiv", MASK_USE_8BIT_IDIV },
435 : { "-mvzeroupper", MASK_VZEROUPPER },
436 : { "-mstv", MASK_STV },
437 : { "-mavx256-split-unaligned-load", MASK_AVX256_SPLIT_UNALIGNED_LOAD },
438 : { "-mavx256-split-unaligned-store", MASK_AVX256_SPLIT_UNALIGNED_STORE },
439 : { "-mcall-ms2sysv-xlogues", MASK_CALL_MS2SYSV_XLOGUES },
440 : { "-mrelax-cmpxchg-loop", MASK_RELAX_CMPXCHG_LOOP }
441 : };
442 :
443 : /* Additional flag options. */
444 23 : static struct ix86_target_opts flag2_opts[] =
445 : {
446 : { "-mgeneral-regs-only", OPTION_MASK_GENERAL_REGS_ONLY }
447 : };
448 :
449 23 : const char *opts[ARRAY_SIZE (isa_opts) + ARRAY_SIZE (isa2_opts)
450 : + ARRAY_SIZE (flag_opts) + ARRAY_SIZE (flag2_opts) + 6][2];
451 :
452 23 : char isa_other[40];
453 23 : char isa2_other[40];
454 23 : char flags_other[40];
455 23 : char flags2_other[40];
456 23 : unsigned num = 0;
457 23 : unsigned i, j;
458 23 : char *ret;
459 23 : char *ptr;
460 23 : size_t len;
461 23 : size_t line_len;
462 23 : size_t sep_len;
463 23 : const char *abi;
464 :
465 23 : memset (opts, '\0', sizeof (opts));
466 :
467 : /* Add -march= option. */
468 23 : if (arch)
469 : {
470 0 : opts[num][0] = "-march=";
471 0 : opts[num++][1] = arch;
472 : }
473 :
474 : /* Add -mtune= option. */
475 23 : if (tune)
476 : {
477 0 : opts[num][0] = "-mtune=";
478 0 : opts[num++][1] = tune;
479 : }
480 :
481 : /* Add -m32/-m64/-mx32. */
482 23 : if (add_abi_p)
483 : {
484 2 : if ((isa & OPTION_MASK_ISA_64BIT) != 0)
485 : {
486 2 : if ((isa & OPTION_MASK_ABI_64) != 0)
487 : abi = "-m64";
488 : else
489 0 : abi = "-mx32";
490 : }
491 : else
492 : abi = "-m32";
493 2 : opts[num++][0] = abi;
494 : }
495 23 : isa &= ~(OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64 | OPTION_MASK_ABI_X32);
496 :
497 : /* Pick out the options in isa2 options. */
498 1173 : for (i = 0; i < ARRAY_SIZE (isa2_opts); i++)
499 : {
500 1150 : if ((isa2 & isa2_opts[i].mask) != 0)
501 : {
502 5 : opts[num++][0] = isa2_opts[i].option;
503 5 : isa2 &= ~ isa2_opts[i].mask;
504 : }
505 : }
506 :
507 23 : if (isa2 && add_nl_p)
508 : {
509 0 : opts[num++][0] = isa2_other;
510 0 : sprintf (isa2_other, "(other isa2: %#" HOST_WIDE_INT_PRINT "x)", isa2);
511 : }
512 :
513 : /* Pick out the options in isa options. */
514 1334 : for (i = 0; i < ARRAY_SIZE (isa_opts); i++)
515 : {
516 1311 : if ((isa & isa_opts[i].mask) != 0)
517 : {
518 36 : opts[num++][0] = isa_opts[i].option;
519 36 : isa &= ~ isa_opts[i].mask;
520 : }
521 : }
522 :
523 23 : if (isa && add_nl_p)
524 : {
525 0 : opts[num++][0] = isa_other;
526 0 : sprintf (isa_other, "(other isa: %#" HOST_WIDE_INT_PRINT "x)", isa);
527 : }
528 :
529 : /* Add flag options. */
530 713 : for (i = 0; i < ARRAY_SIZE (flag_opts); i++)
531 : {
532 690 : if ((flags & flag_opts[i].mask) != 0)
533 : {
534 0 : opts[num++][0] = flag_opts[i].option;
535 0 : flags &= ~ flag_opts[i].mask;
536 : }
537 : }
538 :
539 23 : if (flags && add_nl_p)
540 : {
541 0 : opts[num++][0] = flags_other;
542 0 : sprintf (flags_other, "(other flags: %#x)", flags);
543 : }
544 :
545 : /* Add additional flag options. */
546 46 : for (i = 0; i < ARRAY_SIZE (flag2_opts); i++)
547 : {
548 23 : if ((flags2 & flag2_opts[i].mask) != 0)
549 : {
550 0 : opts[num++][0] = flag2_opts[i].option;
551 0 : flags2 &= ~ flag2_opts[i].mask;
552 : }
553 : }
554 :
555 23 : if (flags2 && add_nl_p)
556 : {
557 0 : opts[num++][0] = flags2_other;
558 0 : sprintf (flags2_other, "(other flags2: %#x)", flags2);
559 : }
560 :
561 : /* Add -mfpmath= option. */
562 23 : if (fpmath)
563 : {
564 0 : opts[num][0] = "-mfpmath=";
565 0 : switch ((int) fpmath)
566 : {
567 0 : case FPMATH_387:
568 0 : opts[num++][1] = "387";
569 0 : break;
570 :
571 0 : case FPMATH_SSE:
572 0 : opts[num++][1] = "sse";
573 0 : break;
574 :
575 0 : case FPMATH_387 | FPMATH_SSE:
576 0 : opts[num++][1] = "sse+387";
577 0 : break;
578 :
579 0 : default:
580 0 : gcc_unreachable ();
581 : }
582 : }
583 :
584 23 : auto add_vector_width = [&opts, &num] (prefer_vector_width pvw,
585 : const char *cmd)
586 : {
587 0 : opts[num][0] = cmd;
588 0 : switch ((int) pvw)
589 : {
590 0 : case PVW_AVX128:
591 0 : opts[num++][1] = "128";
592 0 : break;
593 :
594 0 : case PVW_AVX256:
595 0 : opts[num++][1] = "256";
596 0 : break;
597 :
598 0 : case PVW_AVX512:
599 0 : opts[num++][1] = "512";
600 0 : break;
601 :
602 0 : default:
603 0 : gcc_unreachable ();
604 : }
605 23 : };
606 :
607 : /* Add -mprefer-vector-width= option. */
608 23 : if (pvw)
609 0 : add_vector_width (pvw, "-mprefer-vector-width=");
610 :
611 : /* Add -mmove-max= option. */
612 23 : if (move_max)
613 0 : add_vector_width (move_max, "-mmove-max=");
614 :
615 : /* Any options? */
616 23 : if (num == 0)
617 : return NULL;
618 :
619 23 : gcc_assert (num < ARRAY_SIZE (opts));
620 :
621 : /* Size the string. */
622 23 : len = 0;
623 23 : sep_len = (add_nl_p) ? 3 : 1;
624 66 : for (i = 0; i < num; i++)
625 : {
626 43 : len += sep_len;
627 129 : for (j = 0; j < 2; j++)
628 86 : if (opts[i][j])
629 43 : len += strlen (opts[i][j]);
630 : }
631 :
632 : /* Build the string. */
633 23 : ret = ptr = (char *) xmalloc (len);
634 23 : line_len = 0;
635 :
636 66 : for (i = 0; i < num; i++)
637 : {
638 : size_t len2[2];
639 :
640 129 : for (j = 0; j < 2; j++)
641 86 : len2[j] = (opts[i][j]) ? strlen (opts[i][j]) : 0;
642 :
643 43 : if (i != 0)
644 : {
645 20 : *ptr++ = ' ';
646 20 : line_len++;
647 :
648 20 : if (add_nl_p && line_len + len2[0] + len2[1] > 70)
649 : {
650 0 : *ptr++ = '\\';
651 0 : *ptr++ = '\n';
652 0 : line_len = 0;
653 : }
654 : }
655 :
656 129 : for (j = 0; j < 2; j++)
657 86 : if (opts[i][j])
658 : {
659 43 : memcpy (ptr, opts[i][j], len2[j]);
660 43 : ptr += len2[j];
661 43 : line_len += len2[j];
662 : }
663 : }
664 :
665 23 : *ptr = '\0';
666 23 : gcc_assert (ret + len >= ptr);
667 :
668 : return ret;
669 : }
670 :
671 : /* Function that is callable from the debugger to print the current
672 : options. */
673 : void ATTRIBUTE_UNUSED
674 0 : ix86_debug_options (void)
675 : {
676 0 : char *opts = ix86_target_string (ix86_isa_flags, ix86_isa_flags2,
677 : target_flags, ix86_target_flags,
678 : ix86_arch_string, ix86_tune_string,
679 : ix86_fpmath, prefer_vector_width_type,
680 : ix86_move_max, true, true);
681 :
682 0 : if (opts)
683 : {
684 0 : fprintf (stderr, "%s\n\n", opts);
685 0 : free (opts);
686 : }
687 : else
688 0 : fputs ("<no options>\n\n", stderr);
689 :
690 0 : return;
691 : }
692 :
693 : /* Save the current options */
694 :
695 : void
696 75295323 : ix86_function_specific_save (struct cl_target_option *ptr,
697 : struct gcc_options *opts,
698 : struct gcc_options */* opts_set */)
699 : {
700 75295323 : ptr->arch = ix86_arch;
701 75295323 : ptr->schedule = ix86_schedule;
702 75295323 : ptr->prefetch_sse = ix86_prefetch_sse;
703 75295323 : ptr->tune = ix86_tune;
704 75295323 : ptr->branch_cost = ix86_branch_cost;
705 75295323 : ptr->tune_defaulted = ix86_tune_defaulted;
706 75295323 : ptr->arch_specified = ix86_arch_specified;
707 75295323 : ptr->x_ix86_apx_features = opts->x_ix86_apx_features;
708 75295323 : ptr->x_ix86_isa_flags_explicit = opts->x_ix86_isa_flags_explicit;
709 75295323 : ptr->x_ix86_isa_flags2_explicit = opts->x_ix86_isa_flags2_explicit;
710 75295323 : ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
711 75295323 : ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
712 75295323 : ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
713 75295323 : ptr->x_ix86_asm_dialect = opts->x_ix86_asm_dialect;
714 75295323 : ptr->x_ix86_branch_cost = opts->x_ix86_branch_cost;
715 75295323 : ptr->x_ix86_dump_tunes = opts->x_ix86_dump_tunes;
716 75295323 : ptr->x_ix86_force_align_arg_pointer = opts->x_ix86_force_align_arg_pointer;
717 75295323 : ptr->x_ix86_force_drap = opts->x_ix86_force_drap;
718 75295323 : ptr->x_ix86_recip_name = opts->x_ix86_recip_name;
719 75295323 : ptr->x_ix86_section_threshold = opts->x_ix86_section_threshold;
720 75295323 : ptr->x_ix86_sse2avx = opts->x_ix86_sse2avx;
721 75295323 : ptr->x_ix86_stack_protector_guard = opts->x_ix86_stack_protector_guard;
722 75295323 : ptr->x_ix86_stringop_alg = opts->x_ix86_stringop_alg;
723 75295323 : ptr->x_ix86_tls_dialect = opts->x_ix86_tls_dialect;
724 75295323 : ptr->x_ix86_tune_ctrl_string = opts->x_ix86_tune_ctrl_string;
725 75295323 : ptr->x_ix86_tune_memcpy_strategy = opts->x_ix86_tune_memcpy_strategy;
726 75295323 : ptr->x_ix86_tune_memset_strategy = opts->x_ix86_tune_memset_strategy;
727 75295323 : ptr->x_ix86_tune_no_default = opts->x_ix86_tune_no_default;
728 :
729 : /* The fields are char but the variables are not; make sure the
730 : values fit in the fields. */
731 75295323 : gcc_assert (ptr->arch == ix86_arch);
732 75295323 : gcc_assert (ptr->schedule == ix86_schedule);
733 75295323 : gcc_assert (ptr->tune == ix86_tune);
734 75295323 : gcc_assert (ptr->branch_cost == ix86_branch_cost);
735 75295323 : }
736 :
737 : /* Feature tests against the various architecture variations, used to create
738 : ix86_arch_features based on the processor mask. */
739 : static unsigned HOST_WIDE_INT initial_ix86_arch_features[X86_ARCH_LAST] = {
740 : /* X86_ARCH_CMOV: Conditional move was added for pentiumpro. */
741 : ~(m_386 | m_486 | m_PENT | m_LAKEMONT | m_K6),
742 :
743 : /* X86_ARCH_CMPXCHG: Compare and exchange was added for 80486. */
744 : ~m_386,
745 :
746 : /* X86_ARCH_CMPXCHG8B: Compare and exchange 8 bytes was added for pentium. */
747 : ~(m_386 | m_486),
748 :
749 : /* X86_ARCH_XADD: Exchange and add was added for 80486. */
750 : ~m_386,
751 :
752 : /* X86_ARCH_BSWAP: Byteswap was added for 80486. */
753 : ~m_386,
754 : };
755 :
756 : /* This table must be in sync with enum processor_type in i386.h. */
757 : static const struct processor_costs *processor_cost_table[] =
758 : {
759 : &generic_cost, /* PROCESSOR_GENERIC. */
760 : &i386_cost, /* PROCESSOR_I386. */
761 : &i486_cost, /* PROCESSOR_I486. */
762 : &pentium_cost, /* PROCESSOR_PENTIUM. */
763 : &lakemont_cost, /* PROCESSOR_LAKEMONT. */
764 : &pentiumpro_cost, /* PROCESSOR_PENTIUMPRO. */
765 : &pentium4_cost, /* PROCESSOR_PENTIUM4. */
766 : &nocona_cost, /* PROCESSOR_NOCONA. */
767 : &core_cost, /* PROCESSOR_CORE2. */
768 : &core_cost, /* PROCESSOR_NEHALEM. */
769 : &core_cost, /* PROCESSOR_SANDYBRIDGE. */
770 : &core_cost, /* PROCESSOR_HASWELL. */
771 : &atom_cost, /* PROCESSOR_BONNELL. */
772 : &slm_cost, /* PROCESSOR_SILVERMONT. */
773 : &slm_cost, /* PROCESSOR_GOLDMONT. */
774 : &slm_cost, /* PROCESSOR_GOLDMONT_PLUS. */
775 : &tremont_cost, /* PROCESSOR_TREMONT. */
776 : &alderlake_cost, /* PROCESSOR_SIERRAFOREST. */
777 : &alderlake_cost, /* PROCESSOR_GRANDRIDGE. */
778 : &alderlake_cost, /* PROCESSOR_CLEARWATERFOREST. */
779 : &skylake_cost, /* PROCESSOR_SKYLAKE. */
780 : &skylake_cost, /* PROCESSOR_SKYLAKE_AVX512. */
781 : &icelake_cost, /* PROCESSOR_CANNONLAKE. */
782 : &icelake_cost, /* PROCESSOR_ICELAKE_CLIENT. */
783 : &icelake_cost, /* PROCESSOR_ICELAKE_SERVER. */
784 : &skylake_cost, /* PROCESSOR_CASCADELAKE. */
785 : &icelake_cost, /* PROCESSOR_TIGERLAKE. */
786 : &skylake_cost, /* PROCESSOR_COOPERLAKE. */
787 : &icelake_cost, /* PROCESSOR_SAPPHIRERAPIDS. */
788 : &alderlake_cost, /* PROCESSOR_ALDERLAKE. */
789 : &icelake_cost, /* PROCESSOR_ROCKETLAKE. */
790 : &icelake_cost, /* PROCESSOR_GRANITERAPIDS. */
791 : &icelake_cost, /* PROCESSOR_GRANITERAPIDS_D. */
792 : &alderlake_cost, /* PROCESSOR_ARROWLAKE. */
793 : &alderlake_cost, /* PROCESSOR_ARROWLAKE_S. */
794 : &alderlake_cost, /* PROCESSOR_PANTHERLAKE. */
795 : &icelake_cost, /* PROCESSOR_DIAMONDRAPIDS. */
796 : &alderlake_cost, /* PROCESSOR_NOVALAKE. */
797 : &alderlake_cost, /* PROCESSOR_INTEL. */
798 : &lujiazui_cost, /* PROCESSOR_LUJIAZUI. */
799 : &yongfeng_cost, /* PROCESSOR_YONGFENG. */
800 : &shijidadao_cost, /* PROCESSOR_SHIJIDADAO. */
801 : &geode_cost, /* PROCESSOR_GEODE. */
802 : &k6_cost, /* PROCESSOR_K6. */
803 : &athlon_cost, /* PROCESSOR_ATHLON. */
804 : &k8_cost, /* PROCESSOR_K8. */
805 : &amdfam10_cost, /* PROCESSOR_AMDFAM10. */
806 : &bdver_cost, /* PROCESSOR_BDVER1. */
807 : &bdver_cost, /* PROCESSOR_BDVER2. */
808 : &bdver_cost, /* PROCESSOR_BDVER3. */
809 : &bdver_cost, /* PROCESSOR_BDVER4. */
810 : &btver1_cost, /* PROCESSOR_BTVER1. */
811 : &btver2_cost, /* PROCESSOR_BTVER2. */
812 : &znver1_cost, /* PROCESSOR_ZNVER1. */
813 : &znver2_cost, /* PROCESSOR_ZNVER2. */
814 : &znver3_cost, /* PROCESSOR_ZNVER3. */
815 : &znver4_cost, /* PROCESSOR_ZNVER4. */
816 : &znver5_cost, /* PROCESSOR_ZNVER5. */
817 : &znver5_cost /* PROCESSOR_ZNVER6. */
818 : };
819 :
820 : /* Guarantee that the array is aligned with enum processor_type. */
821 : STATIC_ASSERT (ARRAY_SIZE (processor_cost_table) == PROCESSOR_max);
822 :
823 : static bool
824 : ix86_option_override_internal (bool main_args_p,
825 : struct gcc_options *opts,
826 : struct gcc_options *opts_set);
827 : static void
828 : set_ix86_tune_features (struct gcc_options *opts,
829 : enum processor_type ix86_tune, bool dump);
830 :
831 : /* Restore the current options */
832 :
833 : void
834 52697650 : ix86_function_specific_restore (struct gcc_options *opts,
835 : struct gcc_options */* opts_set */,
836 : struct cl_target_option *ptr)
837 : {
838 52697650 : enum processor_type old_tune = ix86_tune;
839 52697650 : enum processor_type old_arch = ix86_arch;
840 52697650 : unsigned HOST_WIDE_INT ix86_arch_mask;
841 52697650 : int i;
842 :
843 : /* We don't change -fPIC. */
844 52697650 : opts->x_flag_pic = flag_pic;
845 :
846 52697650 : ix86_arch = (enum processor_type) ptr->arch;
847 52697650 : ix86_schedule = (enum attr_cpu) ptr->schedule;
848 52697650 : ix86_tune = (enum processor_type) ptr->tune;
849 52697650 : ix86_prefetch_sse = ptr->prefetch_sse;
850 52697650 : ix86_tune_defaulted = ptr->tune_defaulted;
851 52697650 : ix86_arch_specified = ptr->arch_specified;
852 52697650 : opts->x_ix86_apx_features = ptr->x_ix86_apx_features;
853 52697650 : opts->x_ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
854 52697650 : opts->x_ix86_isa_flags2_explicit = ptr->x_ix86_isa_flags2_explicit;
855 52697650 : opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
856 52697650 : opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
857 52697650 : opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
858 52697650 : opts->x_ix86_asm_dialect = ptr->x_ix86_asm_dialect;
859 52697650 : opts->x_ix86_branch_cost = ptr->x_ix86_branch_cost;
860 52697650 : opts->x_ix86_dump_tunes = ptr->x_ix86_dump_tunes;
861 52697650 : opts->x_ix86_force_align_arg_pointer = ptr->x_ix86_force_align_arg_pointer;
862 52697650 : opts->x_ix86_force_drap = ptr->x_ix86_force_drap;
863 52697650 : opts->x_ix86_recip_name = ptr->x_ix86_recip_name;
864 52697650 : opts->x_ix86_section_threshold = ptr->x_ix86_section_threshold;
865 52697650 : opts->x_ix86_sse2avx = ptr->x_ix86_sse2avx;
866 52697650 : opts->x_ix86_stack_protector_guard = ptr->x_ix86_stack_protector_guard;
867 52697650 : opts->x_ix86_stringop_alg = ptr->x_ix86_stringop_alg;
868 52697650 : opts->x_ix86_tls_dialect = ptr->x_ix86_tls_dialect;
869 52697650 : opts->x_ix86_tune_ctrl_string = ptr->x_ix86_tune_ctrl_string;
870 52697650 : opts->x_ix86_tune_memcpy_strategy = ptr->x_ix86_tune_memcpy_strategy;
871 52697650 : opts->x_ix86_tune_memset_strategy = ptr->x_ix86_tune_memset_strategy;
872 52697650 : opts->x_ix86_tune_no_default = ptr->x_ix86_tune_no_default;
873 52697650 : ix86_tune_cost = processor_cost_table[ix86_tune];
874 : /* TODO: ix86_cost should be chosen at instruction or function granuality
875 : so for cold code we use size_cost even in !optimize_size compilation. */
876 52697650 : if (opts->x_optimize_size)
877 702016 : ix86_cost = &ix86_size_cost;
878 : else
879 51995634 : ix86_cost = ix86_tune_cost;
880 :
881 : /* Recreate the arch feature tests if the arch changed */
882 52697650 : if (old_arch != ix86_arch)
883 : {
884 33328 : ix86_arch_mask = HOST_WIDE_INT_1U << ix86_arch;
885 199968 : for (i = 0; i < X86_ARCH_LAST; ++i)
886 166640 : ix86_arch_features[i]
887 166640 : = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
888 : }
889 :
890 : /* Recreate the tune optimization tests */
891 52697650 : if (old_tune != ix86_tune)
892 33571 : set_ix86_tune_features (opts, ix86_tune, false);
893 52697650 : }
894 :
895 : /* Adjust target options after streaming them in. This is mainly about
896 : reconciling them with global options. */
897 :
898 : void
899 21248 : ix86_function_specific_post_stream_in (struct cl_target_option *ptr)
900 : {
901 : /* flag_pic is a global option, but ix86_cmodel is target saved option
902 : partly computed from flag_pic. If flag_pic is on, adjust x_ix86_cmodel
903 : for PIC, or error out. */
904 21248 : if (flag_pic)
905 338 : switch (ptr->x_ix86_cmodel)
906 : {
907 90 : case CM_SMALL:
908 90 : ptr->x_ix86_cmodel = CM_SMALL_PIC;
909 90 : break;
910 :
911 0 : case CM_MEDIUM:
912 0 : ptr->x_ix86_cmodel = CM_MEDIUM_PIC;
913 0 : break;
914 :
915 0 : case CM_LARGE:
916 0 : ptr->x_ix86_cmodel = CM_LARGE_PIC;
917 0 : break;
918 :
919 0 : case CM_KERNEL:
920 0 : error ("code model %s does not support PIC mode", "kernel");
921 0 : break;
922 :
923 : default:
924 : break;
925 : }
926 : else
927 20910 : switch (ptr->x_ix86_cmodel)
928 : {
929 99 : case CM_SMALL_PIC:
930 99 : ptr->x_ix86_cmodel = CM_SMALL;
931 99 : break;
932 :
933 0 : case CM_MEDIUM_PIC:
934 0 : ptr->x_ix86_cmodel = CM_MEDIUM;
935 0 : break;
936 :
937 0 : case CM_LARGE_PIC:
938 0 : ptr->x_ix86_cmodel = CM_LARGE;
939 0 : break;
940 :
941 : default:
942 : break;
943 : }
944 21248 : }
945 :
946 : /* Print the current options */
947 :
948 : void
949 0 : ix86_function_specific_print (FILE *file, int indent,
950 : struct cl_target_option *ptr)
951 : {
952 0 : char *target_string
953 0 : = ix86_target_string (ptr->x_ix86_isa_flags, ptr->x_ix86_isa_flags2,
954 : ptr->x_target_flags, ptr->x_ix86_target_flags,
955 : NULL, NULL, ptr->x_ix86_fpmath,
956 : ptr->x_prefer_vector_width_type,
957 : ptr->x_ix86_move_max, false, true);
958 :
959 0 : gcc_assert (ptr->arch < PROCESSOR_max);
960 0 : fprintf (file, "%*sarch = %d (%s)\n",
961 : indent, "",
962 0 : ptr->arch, processor_names[ptr->arch]);
963 :
964 0 : gcc_assert (ptr->tune < PROCESSOR_max);
965 0 : fprintf (file, "%*stune = %d (%s)\n",
966 : indent, "",
967 0 : ptr->tune, processor_names[ptr->tune]);
968 :
969 0 : fprintf (file, "%*sbranch_cost = %d\n", indent, "", ptr->branch_cost);
970 :
971 0 : if (target_string)
972 : {
973 0 : fprintf (file, "%*s%s\n", indent, "", target_string);
974 0 : free (target_string);
975 : }
976 0 : }
977 :
978 :
979 : /* Inner function to process the attribute((target(...))), take an argument and
980 : set the current options from the argument. If we have a list, recursively go
981 : over the list. */
982 :
983 : static bool
984 98089938 : ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
985 : struct gcc_options *opts,
986 : struct gcc_options *opts_set,
987 : struct gcc_options *enum_opts_set,
988 : bool target_clone_attr)
989 : {
990 98089938 : char *next_optstr;
991 98089938 : bool ret = true;
992 :
993 : #define IX86_ATTR_ISA(S,O) { S, sizeof (S)-1, ix86_opt_isa, O, 0 }
994 : #define IX86_ATTR_STR(S,O) { S, sizeof (S)-1, ix86_opt_str, O, 0 }
995 : #define IX86_ATTR_ENUM(S,O) { S, sizeof (S)-1, ix86_opt_enum, O, 0 }
996 : #define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M }
997 : #define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M }
998 : #define IX86_ATTR_IX86_YES(S,O,M) \
999 : { S, sizeof (S)-1, ix86_opt_ix86_yes, O, M }
1000 : #define IX86_ATTR_IX86_NO(S,O,M) \
1001 : { S, sizeof (S)-1, ix86_opt_ix86_no, O, M }
1002 :
1003 98089938 : enum ix86_opt_type
1004 : {
1005 : ix86_opt_unknown,
1006 : ix86_opt_yes,
1007 : ix86_opt_no,
1008 : ix86_opt_ix86_yes,
1009 : ix86_opt_ix86_no,
1010 : ix86_opt_str,
1011 : ix86_opt_enum,
1012 : ix86_opt_isa
1013 : };
1014 :
1015 98089938 : static const struct
1016 : {
1017 : const char *string;
1018 : size_t len;
1019 : enum ix86_opt_type type;
1020 : int opt;
1021 : int mask;
1022 : } attrs[] = {
1023 : /* isa options */
1024 : IX86_ATTR_ISA ("pconfig", OPT_mpconfig),
1025 : IX86_ATTR_ISA ("wbnoinvd", OPT_mwbnoinvd),
1026 : IX86_ATTR_ISA ("sgx", OPT_msgx),
1027 : IX86_ATTR_ISA ("avx512vpopcntdq", OPT_mavx512vpopcntdq),
1028 : IX86_ATTR_ISA ("avx512vbmi2", OPT_mavx512vbmi2),
1029 : IX86_ATTR_ISA ("avx512vnni", OPT_mavx512vnni),
1030 : IX86_ATTR_ISA ("avx512bitalg", OPT_mavx512bitalg),
1031 : IX86_ATTR_ISA ("avx512vp2intersect", OPT_mavx512vp2intersect),
1032 :
1033 : IX86_ATTR_ISA ("avx512vbmi", OPT_mavx512vbmi),
1034 : IX86_ATTR_ISA ("avx512ifma", OPT_mavx512ifma),
1035 : IX86_ATTR_ISA ("avx512vl", OPT_mavx512vl),
1036 : IX86_ATTR_ISA ("avx512bw", OPT_mavx512bw),
1037 : IX86_ATTR_ISA ("avx512dq", OPT_mavx512dq),
1038 : IX86_ATTR_ISA ("avx512cd", OPT_mavx512cd),
1039 : IX86_ATTR_ISA ("avx512f", OPT_mavx512f),
1040 : IX86_ATTR_ISA ("avx2", OPT_mavx2),
1041 : IX86_ATTR_ISA ("fma", OPT_mfma),
1042 : IX86_ATTR_ISA ("xop", OPT_mxop),
1043 : IX86_ATTR_ISA ("fma4", OPT_mfma4),
1044 : IX86_ATTR_ISA ("f16c", OPT_mf16c),
1045 : IX86_ATTR_ISA ("avx", OPT_mavx),
1046 : IX86_ATTR_ISA ("sse4", OPT_msse4),
1047 : IX86_ATTR_ISA ("sse4.2", OPT_msse4_2),
1048 : IX86_ATTR_ISA ("sse4.1", OPT_msse4_1),
1049 : IX86_ATTR_ISA ("sse4a", OPT_msse4a),
1050 : IX86_ATTR_ISA ("ssse3", OPT_mssse3),
1051 : IX86_ATTR_ISA ("sse3", OPT_msse3),
1052 : IX86_ATTR_ISA ("aes", OPT_maes),
1053 : IX86_ATTR_ISA ("sha", OPT_msha),
1054 : IX86_ATTR_ISA ("pclmul", OPT_mpclmul),
1055 : IX86_ATTR_ISA ("sse2", OPT_msse2),
1056 : IX86_ATTR_ISA ("sse", OPT_msse),
1057 : IX86_ATTR_ISA ("3dnowa", OPT_m3dnowa),
1058 : IX86_ATTR_ISA ("3dnow", OPT_m3dnow),
1059 : IX86_ATTR_ISA ("mmx", OPT_mmmx),
1060 : IX86_ATTR_ISA ("rtm", OPT_mrtm),
1061 : IX86_ATTR_ISA ("prfchw", OPT_mprfchw),
1062 : IX86_ATTR_ISA ("rdseed", OPT_mrdseed),
1063 : IX86_ATTR_ISA ("adx", OPT_madx),
1064 : IX86_ATTR_ISA ("clflushopt", OPT_mclflushopt),
1065 : IX86_ATTR_ISA ("xsaves", OPT_mxsaves),
1066 : IX86_ATTR_ISA ("xsavec", OPT_mxsavec),
1067 : IX86_ATTR_ISA ("xsaveopt", OPT_mxsaveopt),
1068 : IX86_ATTR_ISA ("xsave", OPT_mxsave),
1069 : IX86_ATTR_ISA ("abm", OPT_mabm),
1070 : IX86_ATTR_ISA ("bmi", OPT_mbmi),
1071 : IX86_ATTR_ISA ("bmi2", OPT_mbmi2),
1072 : IX86_ATTR_ISA ("lzcnt", OPT_mlzcnt),
1073 : IX86_ATTR_ISA ("tbm", OPT_mtbm),
1074 : IX86_ATTR_ISA ("popcnt", OPT_mpopcnt),
1075 : IX86_ATTR_ISA ("cx16", OPT_mcx16),
1076 : IX86_ATTR_ISA ("sahf", OPT_msahf),
1077 : IX86_ATTR_ISA ("movbe", OPT_mmovbe),
1078 : IX86_ATTR_ISA ("crc32", OPT_mcrc32),
1079 : IX86_ATTR_ISA ("fsgsbase", OPT_mfsgsbase),
1080 : IX86_ATTR_ISA ("rdrnd", OPT_mrdrnd),
1081 : IX86_ATTR_ISA ("mwaitx", OPT_mmwaitx),
1082 : IX86_ATTR_ISA ("mwait", OPT_mmwait),
1083 : IX86_ATTR_ISA ("clzero", OPT_mclzero),
1084 : IX86_ATTR_ISA ("pku", OPT_mpku),
1085 : IX86_ATTR_ISA ("lwp", OPT_mlwp),
1086 : IX86_ATTR_ISA ("hle", OPT_mhle),
1087 : IX86_ATTR_ISA ("fxsr", OPT_mfxsr),
1088 : IX86_ATTR_ISA ("clwb", OPT_mclwb),
1089 : IX86_ATTR_ISA ("rdpid", OPT_mrdpid),
1090 : IX86_ATTR_ISA ("gfni", OPT_mgfni),
1091 : IX86_ATTR_ISA ("shstk", OPT_mshstk),
1092 : IX86_ATTR_ISA ("vaes", OPT_mvaes),
1093 : IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),
1094 : IX86_ATTR_ISA ("movdiri", OPT_mmovdiri),
1095 : IX86_ATTR_ISA ("movdir64b", OPT_mmovdir64b),
1096 : IX86_ATTR_ISA ("waitpkg", OPT_mwaitpkg),
1097 : IX86_ATTR_ISA ("cldemote", OPT_mcldemote),
1098 : IX86_ATTR_ISA ("uintr", OPT_muintr),
1099 : IX86_ATTR_ISA ("ptwrite", OPT_mptwrite),
1100 : IX86_ATTR_ISA ("kl", OPT_mkl),
1101 : IX86_ATTR_ISA ("widekl", OPT_mwidekl),
1102 : IX86_ATTR_ISA ("avx512bf16", OPT_mavx512bf16),
1103 : IX86_ATTR_ISA ("enqcmd", OPT_menqcmd),
1104 : IX86_ATTR_ISA ("serialize", OPT_mserialize),
1105 : IX86_ATTR_ISA ("tsxldtrk", OPT_mtsxldtrk),
1106 : IX86_ATTR_ISA ("amx-tile", OPT_mamx_tile),
1107 : IX86_ATTR_ISA ("amx-int8", OPT_mamx_int8),
1108 : IX86_ATTR_ISA ("amx-bf16", OPT_mamx_bf16),
1109 : IX86_ATTR_ISA ("hreset", OPT_mhreset),
1110 : IX86_ATTR_ISA ("avxvnni", OPT_mavxvnni),
1111 : IX86_ATTR_ISA ("avx512fp16", OPT_mavx512fp16),
1112 : IX86_ATTR_ISA ("avxifma", OPT_mavxifma),
1113 : IX86_ATTR_ISA ("avxvnniint8", OPT_mavxvnniint8),
1114 : IX86_ATTR_ISA ("avxneconvert", OPT_mavxneconvert),
1115 : IX86_ATTR_ISA ("cmpccxadd", OPT_mcmpccxadd),
1116 : IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16),
1117 : IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi),
1118 : IX86_ATTR_ISA ("raoint", OPT_mraoint),
1119 : IX86_ATTR_ISA ("amx-complex", OPT_mamx_complex),
1120 : IX86_ATTR_ISA ("avxvnniint16", OPT_mavxvnniint16),
1121 : IX86_ATTR_ISA ("sm3", OPT_msm3),
1122 : IX86_ATTR_ISA ("sha512", OPT_msha512),
1123 : IX86_ATTR_ISA ("sm4", OPT_msm4),
1124 : IX86_ATTR_ISA ("apxf", OPT_mapxf),
1125 : IX86_ATTR_ISA ("usermsr", OPT_musermsr),
1126 : IX86_ATTR_ISA ("avx10.1", OPT_mavx10_1),
1127 : IX86_ATTR_ISA ("avx10.2", OPT_mavx10_2),
1128 : IX86_ATTR_ISA ("amx-avx512", OPT_mamx_avx512),
1129 : IX86_ATTR_ISA ("amx-tf32", OPT_mamx_tf32),
1130 : IX86_ATTR_ISA ("amx-fp8", OPT_mamx_fp8),
1131 : IX86_ATTR_ISA ("movrs", OPT_mmovrs),
1132 : IX86_ATTR_ISA ("amx-movrs", OPT_mamx_movrs),
1133 : IX86_ATTR_ISA ("avx512bmm", OPT_mavx512bmm),
1134 :
1135 : /* enum options */
1136 : IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_),
1137 : IX86_ATTR_ENUM ("prefer-vector-width=", OPT_mprefer_vector_width_),
1138 :
1139 : /* string options */
1140 : IX86_ATTR_STR ("arch=", IX86_FUNCTION_SPECIFIC_ARCH),
1141 : IX86_ATTR_STR ("tune=", IX86_FUNCTION_SPECIFIC_TUNE),
1142 :
1143 : /* flag options */
1144 : IX86_ATTR_YES ("cld",
1145 : OPT_mcld,
1146 : MASK_CLD),
1147 :
1148 : IX86_ATTR_NO ("fancy-math-387",
1149 : OPT_mfancy_math_387,
1150 : MASK_NO_FANCY_MATH_387),
1151 :
1152 : IX86_ATTR_YES ("ieee-fp",
1153 : OPT_mieee_fp,
1154 : MASK_IEEE_FP),
1155 :
1156 : IX86_ATTR_YES ("inline-all-stringops",
1157 : OPT_minline_all_stringops,
1158 : MASK_INLINE_ALL_STRINGOPS),
1159 :
1160 : IX86_ATTR_YES ("inline-stringops-dynamically",
1161 : OPT_minline_stringops_dynamically,
1162 : MASK_INLINE_STRINGOPS_DYNAMICALLY),
1163 :
1164 : IX86_ATTR_NO ("align-stringops",
1165 : OPT_mno_align_stringops,
1166 : MASK_NO_ALIGN_STRINGOPS),
1167 :
1168 : IX86_ATTR_YES ("recip",
1169 : OPT_mrecip,
1170 : MASK_RECIP),
1171 :
1172 : IX86_ATTR_YES ("80387",
1173 : OPT_m80387,
1174 : MASK_80387),
1175 :
1176 : IX86_ATTR_IX86_YES ("general-regs-only",
1177 : OPT_mgeneral_regs_only,
1178 : OPTION_MASK_GENERAL_REGS_ONLY),
1179 :
1180 : IX86_ATTR_YES ("relax-cmpxchg-loop",
1181 : OPT_mrelax_cmpxchg_loop,
1182 : MASK_RELAX_CMPXCHG_LOOP),
1183 : };
1184 :
1185 98089938 : location_t loc
1186 98089938 : = fndecl == NULL ? UNKNOWN_LOCATION : DECL_SOURCE_LOCATION (fndecl);
1187 98089938 : const char *attr_name = target_clone_attr ? "target_clone" : "target";
1188 :
1189 : /* If this is a list, recurse to get the options. */
1190 98089938 : if (TREE_CODE (args) == TREE_LIST)
1191 : {
1192 98085105 : for (; args; args = TREE_CHAIN (args))
1193 49836188 : if (TREE_VALUE (args)
1194 49836188 : && !ix86_valid_target_attribute_inner_p (fndecl, TREE_VALUE (args),
1195 : p_strings, opts, opts_set,
1196 : enum_opts_set,
1197 : target_clone_attr))
1198 : ret = false;
1199 :
1200 : return ret;
1201 : }
1202 :
1203 49841021 : else if (TREE_CODE (args) != STRING_CST)
1204 : {
1205 9 : error_at (loc, "attribute %qs argument is not a string", attr_name);
1206 9 : return false;
1207 : }
1208 :
1209 : /* Handle multiple arguments separated by commas. */
1210 49841012 : next_optstr = ASTRDUP (TREE_STRING_POINTER (args));
1211 :
1212 116191734 : while (next_optstr && *next_optstr != '\0')
1213 : {
1214 66350724 : char *p = next_optstr;
1215 66350724 : char *orig_p = p;
1216 66350724 : char *comma = strchr (next_optstr, ',');
1217 66350724 : size_t len, opt_len;
1218 66350724 : int opt;
1219 66350724 : bool opt_set_p;
1220 66350724 : char ch;
1221 66350724 : unsigned i;
1222 66350724 : enum ix86_opt_type type = ix86_opt_unknown;
1223 66350724 : int mask = 0;
1224 :
1225 66350724 : if (comma)
1226 : {
1227 16509723 : *comma = '\0';
1228 16509723 : len = comma - next_optstr;
1229 16509723 : next_optstr = comma + 1;
1230 : }
1231 : else
1232 : {
1233 49841001 : len = strlen (p);
1234 49841001 : next_optstr = NULL;
1235 : }
1236 :
1237 : /* Recognize no-xxx. */
1238 66350724 : if (len > 3 && p[0] == 'n' && p[1] == 'o' && p[2] == '-')
1239 : {
1240 1586 : opt_set_p = false;
1241 1586 : p += 3;
1242 1586 : len -= 3;
1243 : }
1244 : else
1245 : opt_set_p = true;
1246 :
1247 : /* Find the option. */
1248 66350724 : ch = *p;
1249 66350724 : opt = N_OPTS;
1250 2746638425 : for (i = 0; i < ARRAY_SIZE (attrs); i++)
1251 : {
1252 2746638309 : type = attrs[i].type;
1253 2746638309 : opt_len = attrs[i].len;
1254 2746638309 : if (ch == attrs[i].string[0]
1255 860109110 : && ((type != ix86_opt_str && type != ix86_opt_enum)
1256 860109110 : ? len == opt_len
1257 : : len > opt_len)
1258 154205318 : && memcmp (p, attrs[i].string, opt_len) == 0)
1259 : {
1260 66350608 : opt = attrs[i].opt;
1261 66350608 : mask = attrs[i].mask;
1262 66350608 : break;
1263 : }
1264 : }
1265 :
1266 : /* Process the option. */
1267 66350724 : if (opt == N_OPTS)
1268 : {
1269 116 : error_at (loc, "attribute %qs argument %qs is unknown",
1270 : attr_name, orig_p);
1271 116 : ret = false;
1272 : }
1273 :
1274 66350608 : else if (type == ix86_opt_isa)
1275 : {
1276 64362190 : struct cl_decoded_option decoded;
1277 :
1278 64362190 : generate_option (opt, NULL, opt_set_p, CL_TARGET, &decoded);
1279 64362190 : ix86_handle_option (opts, opts_set,
1280 : &decoded, input_location);
1281 : }
1282 :
1283 : else if (type == ix86_opt_yes || type == ix86_opt_no)
1284 : {
1285 51 : opts_set->x_target_flags |= mask;
1286 :
1287 51 : if (type == ix86_opt_no)
1288 12 : opt_set_p = !opt_set_p;
1289 :
1290 51 : if (opt_set_p)
1291 42 : opts->x_target_flags |= mask;
1292 : else
1293 9 : opts->x_target_flags &= ~mask;
1294 : }
1295 :
1296 : else if (type == ix86_opt_ix86_yes || type == ix86_opt_ix86_no)
1297 : {
1298 1967887 : if (mask == OPTION_MASK_GENERAL_REGS_ONLY)
1299 : {
1300 1967887 : if (!opt_set_p)
1301 : {
1302 2 : error_at (loc, "pragma or attribute %<target(\"%s\")%> "
1303 : "does not allow a negated form", p);
1304 2 : return false;
1305 : }
1306 :
1307 1967885 : if (type != ix86_opt_ix86_yes)
1308 0 : gcc_unreachable ();
1309 :
1310 1967885 : opts->x_ix86_target_flags |= mask;
1311 :
1312 1967885 : struct cl_decoded_option decoded;
1313 1967885 : generate_option (opt, NULL, opt_set_p, CL_TARGET,
1314 : &decoded);
1315 1967885 : ix86_handle_option (opts, opts_set, &decoded,
1316 : input_location);
1317 : }
1318 : else
1319 : {
1320 0 : if (type == ix86_opt_ix86_no)
1321 0 : opt_set_p = !opt_set_p;
1322 :
1323 0 : if (opt_set_p)
1324 0 : opts->x_ix86_target_flags |= mask;
1325 : else
1326 0 : opts->x_ix86_target_flags &= ~mask;
1327 : }
1328 : }
1329 :
1330 : else if (type == ix86_opt_str)
1331 : {
1332 20293 : if (p_strings[opt])
1333 : {
1334 1 : error_at (loc, "attribute value %qs was already specified "
1335 : "in %qs attribute", orig_p, attr_name);
1336 1 : ret = false;
1337 : }
1338 : else
1339 : {
1340 20292 : p_strings[opt] = xstrdup (p + opt_len);
1341 20292 : if (opt == IX86_FUNCTION_SPECIFIC_ARCH)
1342 : {
1343 : /* If arch= is set, clear all bits in x_ix86_isa_flags,
1344 : except for ISA_64BIT, ABI_64, ABI_X32, and CODE16
1345 : and all bits in x_ix86_isa_flags2. */
1346 20262 : opts->x_ix86_isa_flags &= (OPTION_MASK_ISA_64BIT
1347 : | OPTION_MASK_ABI_64
1348 : | OPTION_MASK_ABI_X32
1349 : | OPTION_MASK_CODE16);
1350 20262 : opts->x_ix86_isa_flags_explicit &= (OPTION_MASK_ISA_64BIT
1351 : | OPTION_MASK_ABI_64
1352 : | OPTION_MASK_ABI_X32
1353 : | OPTION_MASK_CODE16);
1354 20262 : opts->x_ix86_isa_flags2 = 0;
1355 20262 : opts->x_ix86_isa_flags2_explicit = 0;
1356 : }
1357 : }
1358 : }
1359 :
1360 : else if (type == ix86_opt_enum)
1361 : {
1362 187 : bool arg_ok;
1363 187 : int value;
1364 :
1365 187 : arg_ok = opt_enum_arg_to_value (opt, p + opt_len, &value, CL_TARGET);
1366 187 : if (arg_ok)
1367 187 : set_option (opts, enum_opts_set, opt, value,
1368 : p + opt_len,
1369 : static_cast<int> (diagnostics::kind::unspecified),
1370 : input_location,
1371 : global_dc);
1372 : else
1373 : {
1374 0 : error_at (loc, "attribute value %qs is unknown in %qs attribute",
1375 : orig_p, attr_name);
1376 0 : ret = false;
1377 : }
1378 : }
1379 :
1380 : else
1381 0 : gcc_unreachable ();
1382 : }
1383 :
1384 : return ret;
1385 : }
1386 :
1387 : /* Release allocated strings. */
1388 : static void
1389 48253114 : release_options_strings (char **option_strings)
1390 : {
1391 : /* Free up memory allocated to hold the strings */
1392 144759342 : for (unsigned i = 0; i < IX86_FUNCTION_SPECIFIC_MAX; i++)
1393 96506228 : free (option_strings[i]);
1394 48253114 : }
1395 :
1396 : /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
1397 :
1398 : tree
1399 48253750 : ix86_valid_target_attribute_tree (tree fndecl, tree args,
1400 : struct gcc_options *opts,
1401 : struct gcc_options *opts_set,
1402 : bool target_clone_attr)
1403 : {
1404 48253750 : const char *orig_arch_string = opts->x_ix86_arch_string;
1405 48253750 : const char *orig_tune_string = opts->x_ix86_tune_string;
1406 48253750 : enum fpmath_unit orig_fpmath_set = opts_set->x_ix86_fpmath;
1407 48253750 : enum prefer_vector_width orig_pvw_set = opts_set->x_prefer_vector_width_type;
1408 48253750 : enum prefer_vector_width orig_ix86_move_max_set
1409 : = opts_set->x_ix86_move_max;
1410 48253750 : int orig_tune_defaulted = ix86_tune_defaulted;
1411 48253750 : int orig_arch_specified = ix86_arch_specified;
1412 48253750 : char *option_strings[IX86_FUNCTION_SPECIFIC_MAX] = { NULL, NULL };
1413 48253750 : tree t = NULL_TREE;
1414 48253750 : struct cl_target_option *def
1415 48253750 : = TREE_TARGET_OPTION (target_option_default_node);
1416 48253750 : struct gcc_options enum_opts_set;
1417 :
1418 48253750 : memset (&enum_opts_set, 0, sizeof (enum_opts_set));
1419 :
1420 : /* Process each of the options on the chain. */
1421 48253750 : if (!ix86_valid_target_attribute_inner_p (fndecl, args, option_strings, opts,
1422 : opts_set, &enum_opts_set,
1423 : target_clone_attr))
1424 125 : return error_mark_node;
1425 :
1426 : /* If the changed options are different from the default, rerun
1427 : ix86_option_override_internal, and then save the options away.
1428 : The string options are attribute options, and will be undone
1429 : when we copy the save structure. */
1430 48253625 : if (opts->x_ix86_isa_flags != def->x_ix86_isa_flags
1431 1885700 : || opts->x_ix86_isa_flags2 != def->x_ix86_isa_flags2
1432 1879 : || opts->x_target_flags != def->x_target_flags
1433 723 : || option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
1434 723 : || option_strings[IX86_FUNCTION_SPECIFIC_TUNE]
1435 693 : || enum_opts_set.x_ix86_fpmath
1436 524 : || enum_opts_set.x_prefer_vector_width_type)
1437 : {
1438 : /* If we are using the default tune= or arch=, undo the string assigned,
1439 : and use the default. */
1440 48253114 : if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH])
1441 20261 : opts->x_ix86_arch_string
1442 20261 : = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]);
1443 48232853 : else if (!orig_arch_specified)
1444 0 : opts->x_ix86_arch_string = NULL;
1445 :
1446 48253114 : if (option_strings[IX86_FUNCTION_SPECIFIC_TUNE])
1447 30 : opts->x_ix86_tune_string
1448 30 : = ggc_strdup (option_strings[IX86_FUNCTION_SPECIFIC_TUNE]);
1449 : /* If we have explicit arch string and no tune string specified, set
1450 : tune_string to NULL and later it will be overriden by arch_string
1451 : so target clones can get proper optimization. */
1452 48253084 : else if (option_strings[IX86_FUNCTION_SPECIFIC_ARCH]
1453 48232823 : || orig_tune_defaulted)
1454 20261 : opts->x_ix86_tune_string = NULL;
1455 :
1456 : /* If fpmath= is not set, and we now have sse2 on 32-bit, use it. */
1457 48253114 : if (enum_opts_set.x_ix86_fpmath)
1458 169 : opts_set->x_ix86_fpmath = (enum fpmath_unit) 1;
1459 48253114 : if (enum_opts_set.x_prefer_vector_width_type)
1460 17 : opts_set->x_prefer_vector_width_type = (enum prefer_vector_width) 1;
1461 :
1462 : /* Do any overrides, such as arch=xxx, or tune=xxx support. */
1463 48253114 : bool r = ix86_option_override_internal (false, opts, opts_set);
1464 48253114 : if (!r)
1465 : {
1466 3 : release_options_strings (option_strings);
1467 3 : return error_mark_node;
1468 : }
1469 :
1470 : /* Add any builtin functions with the new isa if any. */
1471 48253111 : ix86_add_new_builtins (opts->x_ix86_isa_flags, opts->x_ix86_isa_flags2);
1472 :
1473 48253111 : enum excess_precision orig_ix86_excess_precision
1474 : = opts->x_ix86_excess_precision;
1475 48253111 : bool orig_ix86_unsafe_math_optimizations
1476 : = opts->x_ix86_unsafe_math_optimizations;
1477 48253111 : opts->x_ix86_excess_precision = opts->x_flag_excess_precision;
1478 48253111 : opts->x_ix86_unsafe_math_optimizations
1479 48253111 : = opts->x_flag_unsafe_math_optimizations;
1480 :
1481 : /* Save the current options unless we are validating options for
1482 : #pragma. */
1483 48253111 : t = build_target_option_node (opts, opts_set);
1484 :
1485 48253111 : opts->x_ix86_arch_string = orig_arch_string;
1486 48253111 : opts->x_ix86_tune_string = orig_tune_string;
1487 48253111 : opts_set->x_ix86_fpmath = orig_fpmath_set;
1488 48253111 : opts_set->x_prefer_vector_width_type = orig_pvw_set;
1489 48253111 : opts_set->x_ix86_move_max = orig_ix86_move_max_set;
1490 48253111 : opts->x_ix86_excess_precision = orig_ix86_excess_precision;
1491 48253111 : opts->x_ix86_unsafe_math_optimizations
1492 48253111 : = orig_ix86_unsafe_math_optimizations;
1493 :
1494 48253111 : release_options_strings (option_strings);
1495 : }
1496 :
1497 : return t;
1498 : }
1499 :
1500 : static GTY(()) tree target_attribute_cache[3];
1501 :
1502 : /* Hook to validate attribute((target("string"))). */
1503 :
1504 : bool
1505 47691420 : ix86_valid_target_attribute_p (tree fndecl,
1506 : tree ARG_UNUSED (name),
1507 : tree args,
1508 : int flags)
1509 : {
1510 47691420 : struct gcc_options func_options, func_options_set;
1511 47691420 : tree new_target, new_optimize;
1512 47691420 : bool ret = true;
1513 :
1514 : /* attribute((target("default"))) does nothing, beyond
1515 : affecting multi-versioning. */
1516 47691420 : if (TREE_VALUE (args)
1517 47691420 : && TREE_CODE (TREE_VALUE (args)) == STRING_CST
1518 47691414 : && TREE_CHAIN (args) == NULL_TREE
1519 93836749 : && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0)
1520 : return true;
1521 :
1522 47691210 : if ((DECL_FUNCTION_SPECIFIC_TARGET (fndecl) == target_attribute_cache[1]
1523 47688888 : || DECL_FUNCTION_SPECIFIC_TARGET (fndecl) == NULL_TREE)
1524 6486 : && (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl)
1525 6486 : == target_attribute_cache[2]
1526 440 : || DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) == NULL_TREE)
1527 47697662 : && simple_cst_list_equal (args, target_attribute_cache[0]))
1528 : {
1529 1306 : DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = target_attribute_cache[1];
1530 1306 : DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl)
1531 1306 : = target_attribute_cache[2];
1532 1306 : return true;
1533 : }
1534 :
1535 47689904 : tree old_optimize = build_optimization_node (&global_options,
1536 : &global_options_set);
1537 :
1538 : /* Get the optimization options of the current function. */
1539 47689904 : tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
1540 :
1541 47689904 : if (!func_optimize)
1542 5146 : func_optimize = old_optimize;
1543 :
1544 : /* Init func_options. */
1545 47689904 : memset (&func_options, 0, sizeof (func_options));
1546 47689904 : init_options_struct (&func_options, NULL);
1547 47689904 : lang_hooks.init_options_struct (&func_options);
1548 47689904 : memset (&func_options_set, 0, sizeof (func_options_set));
1549 :
1550 47689904 : cl_optimization_restore (&func_options, &func_options_set,
1551 47689904 : TREE_OPTIMIZATION (func_optimize));
1552 :
1553 : /* Initialize func_options to the default before its target options can
1554 : be set. */
1555 47689904 : tree old_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
1556 47689904 : if (old_target == NULL_TREE)
1557 5176 : old_target = target_option_default_node;
1558 47689904 : cl_target_option_restore (&func_options, &func_options_set,
1559 47689904 : TREE_TARGET_OPTION (old_target));
1560 :
1561 : /* FLAGS == 1 is used for target_clones attribute. */
1562 47689904 : new_target
1563 47689904 : = ix86_valid_target_attribute_tree (fndecl, args, &func_options,
1564 : &func_options_set, flags == 1);
1565 :
1566 47689904 : new_optimize = build_optimization_node (&func_options, &func_options_set);
1567 :
1568 47689904 : if (new_target == error_mark_node)
1569 : ret = false;
1570 :
1571 47689780 : else if (new_target)
1572 : {
1573 47689534 : if (DECL_FUNCTION_SPECIFIC_TARGET (fndecl) == NULL_TREE
1574 47689534 : && DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) == NULL_TREE)
1575 : {
1576 4793 : target_attribute_cache[0] = copy_list (args);
1577 4793 : target_attribute_cache[1] = new_target;
1578 4793 : target_attribute_cache[2]
1579 9128 : = old_optimize != new_optimize ? new_optimize : NULL_TREE;
1580 : }
1581 :
1582 47689534 : DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
1583 :
1584 47689534 : if (old_optimize != new_optimize)
1585 15242 : DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
1586 : }
1587 :
1588 : return ret;
1589 : }
1590 :
1591 : const char *stringop_alg_names[] = {
1592 : #define DEF_ALG(alg, name) #name,
1593 : #include "stringop.def"
1594 : #undef DEF_ALG
1595 : };
1596 :
1597 : /* Parse parameter string passed to -mmemcpy-strategy= or -mmemset-strategy=.
1598 : The string is of the following form (or comma separated list of it):
1599 :
1600 : strategy_alg:max_size:[align|noalign]
1601 :
1602 : where the full size range for the strategy is either [0, max_size] or
1603 : [min_size, max_size], in which min_size is the max_size + 1 of the
1604 : preceding range. The last size range must have max_size == -1.
1605 :
1606 : Examples:
1607 :
1608 : 1.
1609 : -mmemcpy-strategy=libcall:-1:noalign
1610 :
1611 : this is equivalent to (for known size memcpy) -mstringop-strategy=libcall
1612 :
1613 :
1614 : 2.
1615 : -mmemset-strategy=rep_8byte:16:noalign,vector_loop:2048:align,libcall:-1:noalign
1616 :
1617 : This is to tell the compiler to use the following strategy for memset
1618 : 1) when the expected size is between [1, 16], use rep_8byte strategy;
1619 : 2) when the size is between [17, 2048], use vector_loop;
1620 : 3) when the size is > 2048, use libcall. */
1621 :
1622 : struct stringop_size_range
1623 : {
1624 : int max;
1625 : stringop_alg alg;
1626 : bool noalign;
1627 : };
1628 :
1629 : static void
1630 52 : ix86_parse_stringop_strategy_string (char *strategy_str, bool is_memset)
1631 : {
1632 52 : const struct stringop_algs *default_algs;
1633 52 : stringop_size_range input_ranges[MAX_STRINGOP_ALGS];
1634 52 : char *curr_range_str, *next_range_str;
1635 52 : const char *opt = is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=";
1636 52 : int i = 0, n = 0;
1637 :
1638 52 : if (is_memset)
1639 34 : default_algs = &ix86_cost->memset[TARGET_64BIT != 0];
1640 : else
1641 18 : default_algs = &ix86_cost->memcpy[TARGET_64BIT != 0];
1642 :
1643 52 : curr_range_str = strategy_str;
1644 :
1645 94 : do
1646 : {
1647 94 : int maxs;
1648 94 : char alg_name[128];
1649 94 : char align[16];
1650 94 : next_range_str = strchr (curr_range_str, ',');
1651 94 : if (next_range_str)
1652 42 : *next_range_str++ = '\0';
1653 :
1654 94 : if (sscanf (curr_range_str, "%20[^:]:%d:%10s", alg_name, &maxs,
1655 : align) != 3)
1656 : {
1657 0 : error ("wrong argument %qs to option %qs", curr_range_str, opt);
1658 1 : return;
1659 : }
1660 :
1661 94 : if (n > 0 && (maxs < (input_ranges[n - 1].max + 1) && maxs != -1))
1662 : {
1663 0 : error ("size ranges of option %qs should be increasing", opt);
1664 0 : return;
1665 : }
1666 :
1667 471 : for (i = 0; i < last_alg; i++)
1668 470 : if (!strcmp (alg_name, stringop_alg_names[i]))
1669 : break;
1670 :
1671 93 : if (i == last_alg)
1672 : {
1673 1 : error ("wrong strategy name %qs specified for option %qs",
1674 : alg_name, opt);
1675 :
1676 1 : auto_vec <const char *> candidates;
1677 10 : for (i = 0; i < last_alg; i++)
1678 9 : if ((stringop_alg) i != rep_prefix_8_byte || TARGET_64BIT)
1679 9 : candidates.safe_push (stringop_alg_names[i]);
1680 :
1681 1 : char *s;
1682 1 : const char *hint
1683 1 : = candidates_list_and_hint (alg_name, s, candidates);
1684 1 : if (hint)
1685 1 : inform (input_location,
1686 : "valid arguments to %qs are: %s; did you mean %qs?",
1687 : opt, s, hint);
1688 : else
1689 0 : inform (input_location, "valid arguments to %qs are: %s",
1690 : opt, s);
1691 1 : XDELETEVEC (s);
1692 1 : return;
1693 1 : }
1694 :
1695 93 : if ((stringop_alg) i == rep_prefix_8_byte
1696 3 : && !TARGET_64BIT)
1697 : {
1698 : /* rep; movq isn't available in 32-bit code. */
1699 0 : error ("strategy name %qs specified for option %qs "
1700 : "not supported for 32-bit code", alg_name, opt);
1701 0 : return;
1702 : }
1703 :
1704 93 : input_ranges[n].max = maxs;
1705 93 : input_ranges[n].alg = (stringop_alg) i;
1706 93 : if (!strcmp (align, "align"))
1707 18 : input_ranges[n].noalign = false;
1708 75 : else if (!strcmp (align, "noalign"))
1709 75 : input_ranges[n].noalign = true;
1710 : else
1711 : {
1712 0 : error ("unknown alignment %qs specified for option %qs", align, opt);
1713 0 : return;
1714 : }
1715 93 : n++;
1716 93 : curr_range_str = next_range_str;
1717 : }
1718 93 : while (curr_range_str);
1719 :
1720 51 : if (input_ranges[n - 1].max != -1)
1721 : {
1722 0 : error ("the max value for the last size range should be -1"
1723 : " for option %qs", opt);
1724 0 : return;
1725 : }
1726 :
1727 51 : if (n > MAX_STRINGOP_ALGS)
1728 : {
1729 0 : error ("too many size ranges specified in option %qs", opt);
1730 0 : return;
1731 : }
1732 :
1733 : /* Now override the default algs array. */
1734 144 : for (i = 0; i < n; i++)
1735 : {
1736 93 : *const_cast<int *>(&default_algs->size[i].max) = input_ranges[i].max;
1737 93 : *const_cast<stringop_alg *>(&default_algs->size[i].alg)
1738 93 : = input_ranges[i].alg;
1739 93 : *const_cast<int *>(&default_algs->size[i].noalign)
1740 93 : = input_ranges[i].noalign;
1741 : }
1742 : }
1743 :
1744 :
1745 : /* parse -mtune-ctrl= option. When DUMP is true,
1746 : print the features that are explicitly set. */
1747 :
1748 : static void
1749 48572398 : parse_mtune_ctrl_str (struct gcc_options *opts, bool dump)
1750 : {
1751 48572398 : if (!opts->x_ix86_tune_ctrl_string)
1752 : return;
1753 :
1754 58318 : char *next_feature_string = NULL;
1755 58318 : char *curr_feature_string = xstrdup (opts->x_ix86_tune_ctrl_string);
1756 58318 : char *orig = curr_feature_string;
1757 58384 : int i;
1758 58384 : do
1759 : {
1760 58384 : bool clear = false;
1761 :
1762 58384 : next_feature_string = strchr (curr_feature_string, ',');
1763 58384 : if (next_feature_string)
1764 66 : *next_feature_string++ = '\0';
1765 58384 : if (*curr_feature_string == '^')
1766 : {
1767 87 : curr_feature_string++;
1768 87 : clear = true;
1769 : }
1770 :
1771 58384 : if (!strcmp (curr_feature_string, "use_gather"))
1772 : {
1773 4 : ix86_tune_features[X86_TUNE_USE_GATHER_2PARTS] = !clear;
1774 4 : ix86_tune_features[X86_TUNE_USE_GATHER_4PARTS] = !clear;
1775 4 : ix86_tune_features[X86_TUNE_USE_GATHER_8PARTS] = !clear;
1776 4 : if (dump)
1777 0 : fprintf (stderr, "Explicitly %s features use_gather_2parts,"
1778 : " use_gather_4parts, use_gather_8parts\n",
1779 : clear ? "clear" : "set");
1780 :
1781 : }
1782 58380 : else if (!strcmp (curr_feature_string, "use_scatter"))
1783 : {
1784 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_2PARTS] = !clear;
1785 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_4PARTS] = !clear;
1786 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_8PARTS] = !clear;
1787 0 : if (dump)
1788 0 : fprintf (stderr, "Explicitly %s features use_scatter_2parts,"
1789 : " use_scatter_4parts, use_scatter_8parts\n",
1790 : clear ? "clear" : "set");
1791 : }
1792 : else
1793 : {
1794 1434400 : for (i = 0; i < X86_TUNE_LAST; i++)
1795 : {
1796 1434400 : if (!strcmp (curr_feature_string, ix86_tune_feature_names[i]))
1797 : {
1798 58380 : ix86_tune_features[i] = !clear;
1799 58380 : if (dump)
1800 0 : fprintf (stderr, "Explicitly %s feature %s\n",
1801 : clear ? "clear" : "set", ix86_tune_feature_names[i]);
1802 : break;
1803 : }
1804 : }
1805 :
1806 58380 : if (i == X86_TUNE_LAST)
1807 0 : error ("unknown parameter to option %<-mtune-ctrl%>: %s",
1808 : clear ? curr_feature_string - 1 : curr_feature_string);
1809 : }
1810 58384 : curr_feature_string = next_feature_string;
1811 : }
1812 58384 : while (curr_feature_string);
1813 58318 : free (orig);
1814 : }
1815 :
1816 : /* Helper function to set ix86_tune_features. IX86_TUNE is the
1817 : processor type. */
1818 :
1819 : static void
1820 48572398 : set_ix86_tune_features (struct gcc_options *opts,
1821 : enum processor_type ix86_tune, bool dump)
1822 : {
1823 48572398 : unsigned HOST_WIDE_INT ix86_tune_mask = HOST_WIDE_INT_1U << ix86_tune;
1824 48572398 : int i;
1825 :
1826 5974404954 : for (i = 0; i < X86_TUNE_LAST; ++i)
1827 : {
1828 5925832556 : if (ix86_tune_no_default)
1829 0 : ix86_tune_features[i] = 0;
1830 : else
1831 5925832556 : ix86_tune_features[i]
1832 5925832556 : = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
1833 : }
1834 :
1835 48572398 : if (dump)
1836 : {
1837 0 : fprintf (stderr, "List of x86 specific tuning parameter names:\n");
1838 0 : for (i = 0; i < X86_TUNE_LAST; i++)
1839 0 : fprintf (stderr, "%s : %s\n", ix86_tune_feature_names[i],
1840 0 : ix86_tune_features[i] ? "on" : "off");
1841 : }
1842 :
1843 48572398 : parse_mtune_ctrl_str (opts, dump);
1844 :
1845 : /* mgather/mscatter option would overwrite -mtune-crtl option. */
1846 48572398 : if (OPTION_SET_P (ix86_use_gather))
1847 : {
1848 98227 : ix86_tune_features[X86_TUNE_USE_GATHER_2PARTS] = ix86_use_gather;
1849 98227 : ix86_tune_features[X86_TUNE_USE_GATHER_4PARTS] = ix86_use_gather;
1850 98227 : ix86_tune_features[X86_TUNE_USE_GATHER_8PARTS] = ix86_use_gather;
1851 : }
1852 :
1853 48572398 : if (OPTION_SET_P (ix86_use_scatter))
1854 : {
1855 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_2PARTS] = ix86_use_scatter;
1856 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_4PARTS] = ix86_use_scatter;
1857 0 : ix86_tune_features[X86_TUNE_USE_SCATTER_8PARTS] = ix86_use_scatter;
1858 : }
1859 48572398 : }
1860 :
1861 :
1862 : /* Default align_* from the processor table. */
1863 :
1864 : static void
1865 100817974 : ix86_default_align (struct gcc_options *opts)
1866 : {
1867 : /* -falign-foo without argument: supply one. */
1868 100817974 : if (opts->x_flag_align_loops && !opts->x_str_align_loops)
1869 131833 : opts->x_str_align_loops = processor_cost_table[ix86_tune]->align_loop;
1870 100817974 : if (opts->x_flag_align_jumps && !opts->x_str_align_jumps)
1871 131834 : opts->x_str_align_jumps = processor_cost_table[ix86_tune]->align_jump;
1872 100817974 : if (opts->x_flag_align_labels && !opts->x_str_align_labels)
1873 131834 : opts->x_str_align_labels = processor_cost_table[ix86_tune]->align_label;
1874 100817974 : if (opts->x_flag_align_functions && !opts->x_str_align_functions)
1875 131829 : opts->x_str_align_functions = processor_cost_table[ix86_tune]->align_func;
1876 100817974 : }
1877 :
1878 : #ifndef USE_IX86_FRAME_POINTER
1879 : #define USE_IX86_FRAME_POINTER 0
1880 : #endif
1881 :
1882 : /* (Re)compute option overrides affected by optimization levels in
1883 : target-specific ways. */
1884 :
1885 : static void
1886 100817974 : ix86_recompute_optlev_based_flags (struct gcc_options *opts,
1887 : struct gcc_options *opts_set)
1888 : {
1889 : /* Set the default values for switches whose default depends on TARGET_64BIT
1890 : in case they weren't overwritten by command line options. */
1891 100817974 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
1892 : {
1893 98882798 : if (opts->x_optimize >= 1)
1894 94890870 : SET_OPTION_IF_UNSET (opts, opts_set, flag_omit_frame_pointer,
1895 : !USE_IX86_FRAME_POINTER);
1896 98882798 : if (opts->x_flag_asynchronous_unwind_tables
1897 98882798 : && TARGET_64BIT_MS_ABI)
1898 273032 : SET_OPTION_IF_UNSET (opts, opts_set, flag_unwind_tables, 1);
1899 98882798 : if (opts->x_flag_asynchronous_unwind_tables == 2)
1900 278516 : opts->x_flag_unwind_tables
1901 278516 : = opts->x_flag_asynchronous_unwind_tables = 1;
1902 98882798 : if (opts->x_flag_pcc_struct_return == 2)
1903 278546 : opts->x_flag_pcc_struct_return = 0;
1904 : }
1905 : else
1906 : {
1907 1935176 : if (opts->x_optimize >= 1)
1908 1934672 : SET_OPTION_IF_UNSET (opts, opts_set, flag_omit_frame_pointer,
1909 : !(USE_IX86_FRAME_POINTER || opts->x_optimize_size));
1910 1935176 : if (opts->x_flag_asynchronous_unwind_tables == 2)
1911 7154 : opts->x_flag_asynchronous_unwind_tables = !USE_IX86_FRAME_POINTER;
1912 1935176 : if (opts->x_flag_pcc_struct_return == 2)
1913 : {
1914 : /* Intel MCU psABI specifies that -freg-struct-return should
1915 : be on. Instead of setting DEFAULT_PCC_STRUCT_RETURN to 0,
1916 : we check -miamcu so that -freg-struct-return is always
1917 : turned on if -miamcu is used. */
1918 7160 : if (TARGET_IAMCU_P (opts->x_target_flags))
1919 0 : opts->x_flag_pcc_struct_return = 0;
1920 : else
1921 7160 : opts->x_flag_pcc_struct_return = DEFAULT_PCC_STRUCT_RETURN;
1922 : }
1923 : }
1924 :
1925 : /* Keep nonleaf frame pointers. */
1926 100817974 : if (opts->x_flag_omit_frame_pointer)
1927 96336770 : opts->x_target_flags &= ~MASK_OMIT_LEAF_FRAME_POINTER;
1928 4481204 : else if (TARGET_OMIT_LEAF_FRAME_POINTER_P (opts->x_target_flags))
1929 0 : opts->x_flag_omit_frame_pointer = 1;
1930 100817974 : }
1931 :
1932 : /* Implement part of TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook. */
1933 :
1934 : static void
1935 100817974 : ix86_override_options_after_change_1 (struct gcc_options *opts,
1936 : struct gcc_options *opts_set)
1937 : {
1938 : #define OPTS_SET_P(OPTION) opts_set->x_ ## OPTION
1939 : #define OPTS(OPTION) opts->x_ ## OPTION
1940 :
1941 : /* Disable unrolling small loops when there's explicit
1942 : -f{,no}unroll-loop. */
1943 100817974 : if ((OPTS_SET_P (flag_unroll_loops))
1944 100097131 : || (OPTS_SET_P (flag_unroll_all_loops)
1945 126 : && OPTS (flag_unroll_all_loops)))
1946 : {
1947 720969 : if (!OPTS_SET_P (ix86_unroll_only_small_loops))
1948 720969 : OPTS (ix86_unroll_only_small_loops) = 0;
1949 : /* Re-enable -frename-registers and -fweb if funroll-loops
1950 : enabled. */
1951 720969 : if (!OPTS_SET_P (flag_web))
1952 720961 : OPTS (flag_web) = OPTS (flag_unroll_loops);
1953 720969 : if (!OPTS_SET_P (flag_rename_registers))
1954 720967 : OPTS (flag_rename_registers) = OPTS (flag_unroll_loops);
1955 : /* -fcunroll-grow-size default follws -f[no]-unroll-loops. */
1956 720969 : if (!OPTS_SET_P (flag_cunroll_grow_size))
1957 720969 : OPTS (flag_cunroll_grow_size)
1958 1441938 : = (OPTS (flag_unroll_loops)
1959 44 : || OPTS (flag_peel_loops)
1960 1441938 : || OPTS (optimize) >= 3);
1961 : }
1962 : else
1963 : {
1964 100097005 : if (!OPTS_SET_P (flag_cunroll_grow_size))
1965 100097005 : OPTS (flag_cunroll_grow_size)
1966 200194010 : = (OPTS (flag_peel_loops)
1967 104216445 : || OPTS (optimize) >= 3);
1968 : }
1969 :
1970 : #undef OPTS
1971 : #undef OPTS_SET_P
1972 100817974 : }
1973 :
1974 : /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook. */
1975 :
1976 : void
1977 52279147 : ix86_override_options_after_change (void)
1978 : {
1979 52279147 : ix86_default_align (&global_options);
1980 :
1981 52279147 : ix86_recompute_optlev_based_flags (&global_options, &global_options_set);
1982 :
1983 52279147 : ix86_override_options_after_change_1 (&global_options, &global_options_set);
1984 52279147 : }
1985 :
1986 : /* Clear stack slot assignments remembered from previous functions.
1987 : This is called from INIT_EXPANDERS once before RTL is emitted for each
1988 : function. */
1989 :
1990 : static struct machine_function *
1991 203695612 : ix86_init_machine_status (void)
1992 : {
1993 203695612 : struct machine_function *f;
1994 :
1995 203695612 : f = ggc_cleared_alloc<machine_function> ();
1996 203695612 : f->call_abi = ix86_abi;
1997 203695612 : f->stack_frame_required = true;
1998 203695612 : f->silent_p = true;
1999 :
2000 203695612 : return f;
2001 : }
2002 :
2003 : /* Override various settings based on options. If MAIN_ARGS_P, the
2004 : options are from the command line, otherwise they are from
2005 : attributes. Return true if there's an error related to march
2006 : option. */
2007 :
2008 : static bool
2009 48538831 : ix86_option_override_internal (bool main_args_p,
2010 : struct gcc_options *opts,
2011 : struct gcc_options *opts_set)
2012 : {
2013 48538831 : unsigned int i;
2014 48538831 : unsigned HOST_WIDE_INT ix86_arch_mask;
2015 48538831 : const bool ix86_tune_specified = (opts->x_ix86_tune_string != NULL);
2016 :
2017 : /* -mrecip options. */
2018 48538831 : static struct
2019 : {
2020 : const char *string; /* option name */
2021 : unsigned int mask; /* mask bits to set */
2022 : }
2023 : const recip_options[] =
2024 : {
2025 : { "all", RECIP_MASK_ALL },
2026 : { "none", RECIP_MASK_NONE },
2027 : { "div", RECIP_MASK_DIV },
2028 : { "sqrt", RECIP_MASK_SQRT },
2029 : { "vec-div", RECIP_MASK_VEC_DIV },
2030 : { "vec-sqrt", RECIP_MASK_VEC_SQRT },
2031 : };
2032 :
2033 : /* Turn off both OPTION_MASK_ABI_64 and OPTION_MASK_ABI_X32 if
2034 : TARGET_64BIT_DEFAULT is true and TARGET_64BIT is false. */
2035 48538831 : if (TARGET_64BIT_DEFAULT && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
2036 612335 : opts->x_ix86_isa_flags &= ~(OPTION_MASK_ABI_64 | OPTION_MASK_ABI_X32);
2037 : #ifdef TARGET_BI_ARCH
2038 : else
2039 : {
2040 : #if TARGET_BI_ARCH == 1
2041 : /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ABI_64
2042 : is on and OPTION_MASK_ABI_X32 is off. We turn off
2043 : OPTION_MASK_ABI_64 if OPTION_MASK_ABI_X32 is turned on by
2044 : -mx32. */
2045 47926496 : if (TARGET_X32_P (opts->x_ix86_isa_flags))
2046 98 : opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_64;
2047 : #else
2048 : /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ABI_X32 is
2049 : on and OPTION_MASK_ABI_64 is off. We turn off
2050 : OPTION_MASK_ABI_X32 if OPTION_MASK_ABI_64 is turned on by
2051 : -m64 or OPTION_MASK_CODE16 is turned on by -m16. */
2052 : if (TARGET_LP64_P (opts->x_ix86_isa_flags)
2053 : || TARGET_16BIT_P (opts->x_ix86_isa_flags))
2054 : opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
2055 : #endif
2056 47926496 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
2057 47926496 : && TARGET_IAMCU_P (opts->x_target_flags))
2058 0 : sorry ("Intel MCU psABI isn%'t supported in %s mode",
2059 : TARGET_X32_P (opts->x_ix86_isa_flags) ? "x32" : "64-bit");
2060 : }
2061 : #endif
2062 :
2063 48538831 : if (TARGET_X32_P (opts->x_ix86_isa_flags))
2064 : {
2065 : /* Always turn on OPTION_MASK_ISA_64BIT and turn off
2066 : OPTION_MASK_ABI_64 for TARGET_X32. */
2067 98 : opts->x_ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
2068 98 : opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_64;
2069 : }
2070 48538733 : else if (TARGET_16BIT_P (opts->x_ix86_isa_flags))
2071 6 : opts->x_ix86_isa_flags &= ~(OPTION_MASK_ISA_64BIT
2072 : | OPTION_MASK_ABI_X32
2073 : | OPTION_MASK_ABI_64);
2074 48538727 : else if (TARGET_LP64_P (opts->x_ix86_isa_flags))
2075 : {
2076 : /* Always turn on OPTION_MASK_ISA_64BIT and turn off
2077 : OPTION_MASK_ABI_X32 for TARGET_LP64. */
2078 47926392 : opts->x_ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
2079 47926392 : opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_X32;
2080 : }
2081 :
2082 : #ifdef SUBTARGET_OVERRIDE_OPTIONS
2083 : SUBTARGET_OVERRIDE_OPTIONS;
2084 : #endif
2085 :
2086 : #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2087 : SUBSUBTARGET_OVERRIDE_OPTIONS;
2088 : #endif
2089 :
2090 : #ifdef HAVE_LD_BROKEN_PE_DWARF5
2091 : /* If the PE linker has broken DWARF 5 support, make
2092 : DWARF 4 the default. */
2093 : if (TARGET_PECOFF)
2094 : SET_OPTION_IF_UNSET (opts, opts_set, dwarf_version, 4);
2095 : #endif
2096 :
2097 : /* -fPIC is the default for x86_64. */
2098 48538831 : if (TARGET_MACHO && TARGET_64BIT_P (opts->x_ix86_isa_flags))
2099 : opts->x_flag_pic = 2;
2100 :
2101 : /* Need to check -mtune=generic first. */
2102 48538831 : if (opts->x_ix86_tune_string)
2103 : {
2104 : /* As special support for cross compilers we read -mtune=native
2105 : as -mtune=generic. With native compilers we won't see the
2106 : -mtune=native, as it was changed by the driver. */
2107 48517478 : if (!strcmp (opts->x_ix86_tune_string, "native"))
2108 0 : opts->x_ix86_tune_string = "generic";
2109 48517478 : else if (!strcmp (opts->x_ix86_tune_string, "x86-64"))
2110 0 : warning (OPT_Wdeprecated,
2111 : main_args_p
2112 : ? G_("%<-mtune=x86-64%> is deprecated; use %<-mtune=k8%> "
2113 : "or %<-mtune=generic%> instead as appropriate")
2114 : : G_("%<target(\"tune=x86-64\")%> is deprecated; use "
2115 : "%<target(\"tune=k8\")%> or %<target(\"tune=generic\")%>"
2116 : " instead as appropriate"));
2117 : }
2118 : else
2119 : {
2120 21353 : if (opts->x_ix86_arch_string)
2121 21353 : opts->x_ix86_tune_string = opts->x_ix86_arch_string;
2122 21353 : if (!opts->x_ix86_tune_string)
2123 : {
2124 0 : opts->x_ix86_tune_string = processor_names[TARGET_CPU_DEFAULT];
2125 0 : ix86_tune_defaulted = 1;
2126 : }
2127 :
2128 : /* opts->x_ix86_tune_string is set to opts->x_ix86_arch_string
2129 : or defaulted. We need to use a sensible tune option. */
2130 21353 : if (startswith (opts->x_ix86_tune_string, "x86-64")
2131 21353 : && (opts->x_ix86_tune_string[6] == '\0'
2132 378 : || (!strcmp (opts->x_ix86_tune_string + 6, "-v2")
2133 338 : || !strcmp (opts->x_ix86_tune_string + 6, "-v3")
2134 132 : || !strcmp (opts->x_ix86_tune_string + 6, "-v4"))))
2135 571 : opts->x_ix86_tune_string = "generic";
2136 : }
2137 :
2138 48538831 : if (opts->x_ix86_stringop_alg == rep_prefix_8_byte
2139 10 : && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
2140 : {
2141 : /* rep; movq isn't available in 32-bit code. */
2142 0 : error ("%<-mstringop-strategy=rep_8byte%> not supported for 32-bit code");
2143 0 : opts->x_ix86_stringop_alg = no_stringop;
2144 : }
2145 :
2146 48538831 : if (TARGET_APX_F_P (opts->x_ix86_isa_flags2)
2147 39654 : && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
2148 0 : error ("%<-mapxf%> is not supported for 32-bit code");
2149 48538831 : else if (opts->x_ix86_apx_features != apx_none
2150 39668 : && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
2151 0 : error ("%<-mapx-features=%> option is not supported for 32-bit code");
2152 :
2153 48538831 : if (TARGET_UINTR_P (opts->x_ix86_isa_flags2)
2154 81847 : && !TARGET_64BIT_P (opts->x_ix86_isa_flags))
2155 0 : error ("%<-muintr%> not supported for 32-bit code");
2156 :
2157 48538831 : if (ix86_lam_type && !TARGET_LP64_P (opts->x_ix86_isa_flags))
2158 0 : error ("%<-mlam=%> option: [u48|u57] not supported for 32-bit code");
2159 :
2160 48538831 : if (!opts->x_ix86_arch_string)
2161 0 : opts->x_ix86_arch_string
2162 0 : = TARGET_64BIT_P (opts->x_ix86_isa_flags)
2163 0 : ? "x86-64" : SUBTARGET32_DEFAULT_CPU;
2164 : else
2165 48538831 : ix86_arch_specified = 1;
2166 :
2167 48538831 : if (opts_set->x_ix86_pmode)
2168 : {
2169 58 : if ((TARGET_LP64_P (opts->x_ix86_isa_flags)
2170 0 : && opts->x_ix86_pmode == PMODE_SI)
2171 58 : || (!TARGET_64BIT_P (opts->x_ix86_isa_flags)
2172 0 : && opts->x_ix86_pmode == PMODE_DI))
2173 0 : error ("address mode %qs not supported in the %s bit mode",
2174 : TARGET_64BIT_P (opts->x_ix86_isa_flags) ? "short" : "long",
2175 : TARGET_64BIT_P (opts->x_ix86_isa_flags) ? "64" : "32");
2176 : }
2177 : else
2178 48538773 : opts->x_ix86_pmode = TARGET_LP64_P (opts->x_ix86_isa_flags)
2179 48538773 : ? PMODE_DI : PMODE_SI;
2180 :
2181 48538831 : SET_OPTION_IF_UNSET (opts, opts_set, ix86_abi, DEFAULT_ABI);
2182 :
2183 48538831 : if (opts->x_ix86_abi == MS_ABI && TARGET_X32_P (opts->x_ix86_isa_flags))
2184 1 : error ("%<-mabi=ms%> not supported with X32 ABI");
2185 48538831 : gcc_assert (opts->x_ix86_abi == SYSV_ABI || opts->x_ix86_abi == MS_ABI);
2186 :
2187 48538831 : const char *abi_name = opts->x_ix86_abi == MS_ABI ? "ms" : "sysv";
2188 48538831 : if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
2189 2881 : && opts->x_ix86_abi != DEFAULT_ABI)
2190 7 : error ("%<-mabi=%s%> not supported with %<-fsanitize=address%>", abi_name);
2191 48538831 : if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2192 144 : && opts->x_ix86_abi != DEFAULT_ABI)
2193 0 : error ("%<-mabi=%s%> not supported with %<-fsanitize=kernel-address%>",
2194 : abi_name);
2195 48538831 : if ((opts->x_flag_sanitize & SANITIZE_THREAD)
2196 293 : && opts->x_ix86_abi != DEFAULT_ABI)
2197 2 : error ("%<-mabi=%s%> not supported with %<-fsanitize=thread%>", abi_name);
2198 :
2199 : /* Hwasan is supported with lam_u57 only. */
2200 48538831 : if (opts->x_flag_sanitize & SANITIZE_HWADDRESS)
2201 : {
2202 400 : if (ix86_lam_type == lam_u48)
2203 0 : warning (0, "%<-mlam=u48%> is not compatible with Hardware-assisted "
2204 : "AddressSanitizer, override to %<-mlam=u57%>");
2205 400 : ix86_lam_type = lam_u57;
2206 : }
2207 :
2208 : /* For targets using ms ABI enable ms-extensions, if not
2209 : explicit turned off. For non-ms ABI we turn off this
2210 : option. */
2211 48538831 : SET_OPTION_IF_UNSET (opts, opts_set, flag_ms_extensions,
2212 : (MS_ABI == DEFAULT_ABI));
2213 :
2214 48538831 : if (opts_set->x_ix86_cmodel)
2215 : {
2216 35555 : switch (opts->x_ix86_cmodel)
2217 : {
2218 1 : case CM_SMALL:
2219 1 : case CM_SMALL_PIC:
2220 1 : if (opts->x_flag_pic)
2221 0 : opts->x_ix86_cmodel = CM_SMALL_PIC;
2222 1 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
2223 0 : error ("code model %qs not supported in the %s bit mode",
2224 : "small", "32");
2225 : break;
2226 :
2227 22443 : case CM_MEDIUM:
2228 22443 : case CM_MEDIUM_PIC:
2229 22443 : if (opts->x_flag_pic)
2230 22431 : opts->x_ix86_cmodel = CM_MEDIUM_PIC;
2231 22443 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
2232 0 : error ("code model %qs not supported in the %s bit mode",
2233 : "medium", "32");
2234 22443 : else if (TARGET_X32_P (opts->x_ix86_isa_flags))
2235 0 : error ("code model %qs not supported in x32 mode",
2236 : "medium");
2237 : break;
2238 :
2239 13110 : case CM_LARGE:
2240 13110 : case CM_LARGE_PIC:
2241 13110 : if (opts->x_flag_pic)
2242 28 : opts->x_ix86_cmodel = CM_LARGE_PIC;
2243 13110 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
2244 0 : error ("code model %qs not supported in the %s bit mode",
2245 : "large", "32");
2246 13110 : else if (TARGET_X32_P (opts->x_ix86_isa_flags))
2247 0 : error ("code model %qs not supported in x32 mode",
2248 : "large");
2249 : break;
2250 :
2251 0 : case CM_32:
2252 0 : if (opts->x_flag_pic)
2253 0 : error ("code model %s does not support PIC mode", "32");
2254 0 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
2255 0 : error ("code model %qs not supported in the %s bit mode",
2256 : "32", "64");
2257 : break;
2258 :
2259 1 : case CM_KERNEL:
2260 1 : if (opts->x_flag_pic)
2261 : {
2262 0 : error ("code model %s does not support PIC mode", "kernel");
2263 0 : opts->x_ix86_cmodel = CM_32;
2264 : }
2265 1 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
2266 0 : error ("code model %qs not supported in the %s bit mode",
2267 : "kernel", "32");
2268 : break;
2269 :
2270 0 : default:
2271 0 : gcc_unreachable ();
2272 : }
2273 : }
2274 : else
2275 : {
2276 : /* For TARGET_64BIT and MS_ABI, force pic on, in order to enable the
2277 : use of rip-relative addressing. This eliminates fixups that
2278 : would otherwise be needed if this object is to be placed in a
2279 : DLL, and is essentially just as efficient as direct addressing. */
2280 48503276 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
2281 : && (TARGET_RDOS || TARGET_PECOFF))
2282 : opts->x_ix86_cmodel = CM_MEDIUM_PIC, opts->x_flag_pic = 1;
2283 48503276 : else if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
2284 95439318 : opts->x_ix86_cmodel = opts->x_flag_pic ? CM_SMALL_PIC : CM_SMALL;
2285 : else
2286 612341 : opts->x_ix86_cmodel = CM_32;
2287 : }
2288 48538831 : if (TARGET_MACHO && opts->x_ix86_asm_dialect == ASM_INTEL)
2289 : {
2290 : error ("%<-masm=intel%> not supported in this configuration");
2291 : opts->x_ix86_asm_dialect = ASM_ATT;
2292 : }
2293 48538831 : if ((TARGET_64BIT_P (opts->x_ix86_isa_flags) != 0)
2294 : != ((opts->x_ix86_isa_flags & OPTION_MASK_ISA_64BIT) != 0))
2295 : sorry ("%i-bit mode not compiled in",
2296 : (opts->x_ix86_isa_flags & OPTION_MASK_ISA_64BIT) ? 64 : 32);
2297 :
2298 : /* Last processor_alias_table must point to "generic" entry. */
2299 48538831 : gcc_checking_assert (strcmp (processor_alias_table[pta_size - 1].name,
2300 : "generic") == 0);
2301 3870672409 : for (i = 0; i < pta_size; i++)
2302 3870672374 : if (! strcmp (opts->x_ix86_arch_string, processor_alias_table[i].name))
2303 : {
2304 48538796 : if (!strcmp (opts->x_ix86_arch_string, "generic"))
2305 : {
2306 2 : error (main_args_p
2307 : ? G_("%<generic%> CPU can be used only for %<-mtune=%> "
2308 : "switch")
2309 : : G_("%<generic%> CPU can be used only for "
2310 : "%<target(\"tune=\")%> attribute"));
2311 2 : return false;
2312 : }
2313 48538794 : else if (!strcmp (opts->x_ix86_arch_string, "intel"))
2314 : {
2315 1 : error (main_args_p
2316 : ? G_("%<intel%> CPU can be used only for %<-mtune=%> "
2317 : "switch")
2318 : : G_("%<intel%> CPU can be used only for "
2319 : "%<target(\"tune=\")%> attribute"));
2320 1 : return false;
2321 : }
2322 :
2323 48538793 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
2324 48538793 : && !((processor_alias_table[i].flags & PTA_64BIT) != 0))
2325 : {
2326 1 : error ("CPU you selected does not support x86-64 "
2327 : "instruction set");
2328 1 : return false;
2329 : }
2330 :
2331 48538792 : ix86_schedule = processor_alias_table[i].schedule;
2332 48538792 : ix86_arch = processor_alias_table[i].processor;
2333 :
2334 : /* Default cpu tuning to the architecture, unless the table
2335 : entry requests not to do this. Used by the x86-64 psABI
2336 : micro-architecture levels. */
2337 48538792 : if ((processor_alias_table[i].flags & PTA_NO_TUNE) == 0)
2338 48207271 : ix86_tune = ix86_arch;
2339 : else
2340 331521 : ix86_tune = PROCESSOR_GENERIC;
2341 :
2342 : /* Enable PTA flags that are enabled by default by a -march option. */
2343 : #define TARGET_EXPLICIT_NO_SAHF_P(opts) (false)
2344 : #define SET_TARGET_NO_SAHF(opts) {}
2345 : #define TARGET_EXPLICIT_PREFETCH_SSE_P(opts) (false)
2346 : #define SET_TARGET_PREFETCH_SSE(opts) {}
2347 : #define TARGET_EXPLICIT_NO_TUNE_P(opts) (false)
2348 : #define SET_TARGET_NO_TUNE(opts) {}
2349 : #define TARGET_EXPLICIT_NO_80387_P(opts) (false)
2350 : #define SET_TARGET_NO_80387(opts) {}
2351 :
2352 : #define DEF_PTA(NAME) \
2353 : if (((processor_alias_table[i].flags & PTA_ ## NAME) != 0) \
2354 : && PTA_ ## NAME != PTA_64BIT \
2355 : && (TARGET_64BIT || (PTA_ ## NAME != PTA_UINTR \
2356 : && PTA_ ## NAME != PTA_APX_F))\
2357 : && !TARGET_EXPLICIT_ ## NAME ## _P (opts)) \
2358 : SET_TARGET_ ## NAME (opts);
2359 : #include "i386-isa.def"
2360 : #undef DEF_PTA
2361 :
2362 :
2363 48538792 : if (!(TARGET_64BIT_P (opts->x_ix86_isa_flags)
2364 47926451 : && ((processor_alias_table[i].flags & PTA_NO_SAHF) != 0))
2365 49233002 : && !TARGET_EXPLICIT_SAHF_P (opts))
2366 1306540 : SET_TARGET_SAHF (opts);
2367 :
2368 48538792 : if (((processor_alias_table[i].flags & PTA_ABM) != 0)
2369 5662 : && !TARGET_EXPLICIT_ABM_P (opts))
2370 : {
2371 5651 : if (!TARGET_EXPLICIT_LZCNT_P (opts))
2372 5650 : SET_TARGET_LZCNT (opts);
2373 5651 : if (!TARGET_EXPLICIT_POPCNT_P (opts))
2374 5218 : SET_TARGET_POPCNT (opts);
2375 : }
2376 :
2377 : /* Enable apx if apxf or apx_features are not
2378 : explicitly set for -march. */
2379 48538792 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags)
2380 47926451 : && ((processor_alias_table[i].flags & PTA_APX_F) != 0)
2381 173 : && !TARGET_EXPLICIT_APX_F_P (opts)
2382 48538965 : && !OPTION_SET_P (ix86_apx_features))
2383 173 : opts->x_ix86_apx_features = apx_all;
2384 :
2385 48538792 : if ((processor_alias_table[i].flags
2386 48538792 : & (PTA_PREFETCH_SSE | PTA_SSE)) != 0)
2387 48538792 : ix86_prefetch_sse = true;
2388 :
2389 : /* Don't enable x87 instructions if only general registers are
2390 : allowed by target("general-regs-only") function attribute or
2391 : -mgeneral-regs-only. */
2392 48538792 : if (!(opts->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
2393 46296147 : && !(opts_set->x_target_flags & MASK_80387))
2394 : {
2395 46296117 : if (((processor_alias_table[i].flags & PTA_NO_80387) != 0))
2396 0 : opts->x_target_flags &= ~MASK_80387;
2397 : else
2398 46296117 : opts->x_target_flags |= MASK_80387;
2399 : }
2400 : break;
2401 : }
2402 :
2403 48538827 : if (i == pta_size)
2404 : {
2405 37 : error (main_args_p
2406 : ? G_("bad value %qs for %<-march=%> switch")
2407 : : G_("bad value %qs for %<target(\"arch=\")%> attribute"),
2408 : opts->x_ix86_arch_string);
2409 :
2410 35 : auto_vec <const char *> candidates;
2411 4095 : for (i = 0; i < pta_size; i++)
2412 4060 : if (strcmp (processor_alias_table[i].name, "generic")
2413 4025 : && strcmp (processor_alias_table[i].name, "intel")
2414 8050 : && (!TARGET_64BIT_P (opts->x_ix86_isa_flags)
2415 6930 : || ((processor_alias_table[i].flags & PTA_64BIT) != 0)))
2416 2870 : candidates.safe_push (processor_alias_table[i].name);
2417 :
2418 : #ifdef HAVE_LOCAL_CPU_DETECT
2419 : /* Add also "native" as possible value. */
2420 35 : candidates.safe_push ("native");
2421 : #endif
2422 :
2423 35 : char *s;
2424 35 : const char *hint
2425 35 : = candidates_list_and_hint (opts->x_ix86_arch_string, s, candidates);
2426 35 : if (hint)
2427 3 : inform (input_location,
2428 : main_args_p
2429 : ? G_("valid arguments to %<-march=%> switch are: "
2430 : "%s; did you mean %qs?")
2431 : : G_("valid arguments to %<target(\"arch=\")%> attribute are: "
2432 : "%s; did you mean %qs?"), s, hint);
2433 : else
2434 34 : inform (input_location,
2435 : main_args_p
2436 : ? G_("valid arguments to %<-march=%> switch are: %s")
2437 : : G_("valid arguments to %<target(\"arch=\")%> attribute "
2438 : "are: %s"), s);
2439 35 : XDELETEVEC (s);
2440 35 : }
2441 :
2442 48538827 : ix86_arch_mask = HOST_WIDE_INT_1U << ix86_arch;
2443 291232962 : for (i = 0; i < X86_ARCH_LAST; ++i)
2444 242694135 : ix86_arch_features[i] = !!(initial_ix86_arch_features[i] & ix86_arch_mask);
2445 :
2446 5578440521 : for (i = 0; i < pta_size; i++)
2447 5578440482 : if (! strcmp (opts->x_ix86_tune_string, processor_alias_table[i].name)
2448 5578440482 : && (processor_alias_table[i].flags & PTA_NO_TUNE) == 0)
2449 : {
2450 48538788 : ix86_schedule = processor_alias_table[i].schedule;
2451 48538788 : ix86_tune = processor_alias_table[i].processor;
2452 48538788 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
2453 : {
2454 47926447 : if (!((processor_alias_table[i].flags & PTA_64BIT) != 0))
2455 : {
2456 0 : if (ix86_tune_defaulted)
2457 : {
2458 0 : opts->x_ix86_tune_string = "x86-64";
2459 0 : for (i = 0; i < pta_size; i++)
2460 0 : if (! strcmp (opts->x_ix86_tune_string,
2461 0 : processor_alias_table[i].name))
2462 : break;
2463 0 : ix86_schedule = processor_alias_table[i].schedule;
2464 0 : ix86_tune = processor_alias_table[i].processor;
2465 : }
2466 : else
2467 0 : error ("CPU you selected does not support x86-64 "
2468 : "instruction set");
2469 : }
2470 : }
2471 : /* Intel CPUs have always interpreted SSE prefetch instructions as
2472 : NOPs; so, we can enable SSE prefetch instructions even when
2473 : -mtune (rather than -march) points us to a processor that has them.
2474 : However, the VIA C3 gives a SIGILL, so we only do that for i686 and
2475 : higher processors. */
2476 48538788 : if (TARGET_CMOV
2477 48538788 : && ((processor_alias_table[i].flags
2478 48538788 : & (PTA_PREFETCH_SSE | PTA_SSE)) != 0))
2479 782503 : ix86_prefetch_sse = true;
2480 : break;
2481 : }
2482 :
2483 48538827 : if (ix86_tune_specified && i == pta_size)
2484 : {
2485 36 : error (main_args_p
2486 : ? G_("bad value %qs for %<-mtune=%> switch")
2487 : : G_("bad value %qs for %<target(\"tune=\")%> attribute"),
2488 : opts->x_ix86_tune_string);
2489 :
2490 34 : auto_vec <const char *> candidates;
2491 3978 : for (i = 0; i < pta_size; i++)
2492 3944 : if ((!TARGET_64BIT_P (opts->x_ix86_isa_flags)
2493 3944 : || ((processor_alias_table[i].flags & PTA_64BIT) != 0))
2494 10642 : && (processor_alias_table[i].flags & PTA_NO_TUNE) == 0)
2495 2754 : candidates.safe_push (processor_alias_table[i].name);
2496 :
2497 : #ifdef HAVE_LOCAL_CPU_DETECT
2498 : /* Add also "native" as possible value. */
2499 34 : candidates.safe_push ("native");
2500 : #endif
2501 :
2502 34 : char *s;
2503 34 : const char *hint
2504 34 : = candidates_list_and_hint (opts->x_ix86_tune_string, s, candidates);
2505 34 : if (hint)
2506 1 : inform (input_location,
2507 : main_args_p
2508 : ? G_("valid arguments to %<-mtune=%> switch are: "
2509 : "%s; did you mean %qs?")
2510 : : G_("valid arguments to %<target(\"tune=\")%> attribute are: "
2511 : "%s; did you mean %qs?"), s, hint);
2512 : else
2513 35 : inform (input_location,
2514 : main_args_p
2515 : ? G_("valid arguments to %<-mtune=%> switch are: %s")
2516 : : G_("valid arguments to %<target(\"tune=\")%> attribute "
2517 : "are: %s"), s);
2518 34 : XDELETEVEC (s);
2519 34 : }
2520 :
2521 48538827 : set_ix86_tune_features (opts, ix86_tune, opts->x_ix86_dump_tunes);
2522 :
2523 48538827 : ix86_recompute_optlev_based_flags (opts, opts_set);
2524 :
2525 48538827 : ix86_override_options_after_change_1 (opts, opts_set);
2526 :
2527 48538827 : ix86_tune_cost = processor_cost_table[ix86_tune];
2528 : /* TODO: ix86_cost should be chosen at instruction or function granuality
2529 : so for cold code we use size_cost even in !optimize_size compilation. */
2530 48538827 : if (opts->x_optimize_size)
2531 694638 : ix86_cost = &ix86_size_cost;
2532 : else
2533 47844189 : ix86_cost = ix86_tune_cost;
2534 :
2535 : /* Arrange to set up i386_stack_locals for all functions. */
2536 48538827 : init_machine_status = ix86_init_machine_status;
2537 :
2538 : /* Override APX flag here if ISA bit is set. */
2539 48538827 : if (TARGET_APX_F_P (opts->x_ix86_isa_flags2)
2540 39827 : && !OPTION_SET_P (ix86_apx_features))
2541 39827 : opts->x_ix86_apx_features = apx_all;
2542 :
2543 : /* Validate -mregparm= value. */
2544 48538827 : if (opts_set->x_ix86_regparm)
2545 : {
2546 0 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
2547 0 : warning (0, "%<-mregparm%> is ignored in 64-bit mode");
2548 0 : else if (TARGET_IAMCU_P (opts->x_target_flags))
2549 0 : warning (0, "%<-mregparm%> is ignored for Intel MCU psABI");
2550 0 : if (opts->x_ix86_regparm > REGPARM_MAX)
2551 : {
2552 0 : error ("%<-mregparm=%d%> is not between 0 and %d",
2553 0 : opts->x_ix86_regparm, REGPARM_MAX);
2554 0 : opts->x_ix86_regparm = 0;
2555 : }
2556 : }
2557 48538827 : if (TARGET_IAMCU_P (opts->x_target_flags)
2558 48538827 : || TARGET_64BIT_P (opts->x_ix86_isa_flags))
2559 95784280 : opts->x_ix86_regparm = REGPARM_MAX;
2560 :
2561 : /* Default align_* from the processor table. */
2562 48538827 : ix86_default_align (&global_options);
2563 :
2564 : /* Provide default for -mbranch-cost= value. */
2565 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, ix86_branch_cost,
2566 : ix86_tune_cost->branch_cost);
2567 :
2568 48538827 : if (TARGET_64BIT_P (opts->x_ix86_isa_flags))
2569 : {
2570 47926486 : opts->x_target_flags
2571 47926486 : |= TARGET_SUBTARGET64_DEFAULT & ~opts_set->x_target_flags;
2572 :
2573 47926486 : if (!ix86_arch_specified)
2574 0 : opts->x_ix86_isa_flags
2575 0 : |= TARGET_SUBTARGET64_ISA_DEFAULT & ~opts->x_ix86_isa_flags_explicit;
2576 :
2577 47926486 : if (!TARGET_128BIT_LONG_DOUBLE_P (opts->x_target_flags))
2578 1 : error ("%<-m96bit-long-double%> is not compatible with this target");
2579 :
2580 47926486 : if (TARGET_RTD_P (opts->x_target_flags))
2581 0 : warning (0,
2582 : main_args_p
2583 : ? G_("%<-mrtd%> is ignored in 64bit mode")
2584 : : G_("%<target(\"rtd\")%> is ignored in 64bit mode"));
2585 : }
2586 : else
2587 : {
2588 612341 : opts->x_target_flags
2589 : |= TARGET_SUBTARGET32_DEFAULT & ~opts_set->x_target_flags;
2590 :
2591 612341 : if (!ix86_arch_specified)
2592 612341 : opts->x_ix86_isa_flags
2593 : |= TARGET_SUBTARGET32_ISA_DEFAULT & ~opts->x_ix86_isa_flags_explicit;
2594 :
2595 : /* i386 ABI does not specify red zone. It still makes sense to use it
2596 : when programmer takes care to stack from being destroyed. */
2597 612341 : if (!(opts_set->x_target_flags & MASK_NO_RED_ZONE))
2598 612341 : opts->x_target_flags |= MASK_NO_RED_ZONE;
2599 : }
2600 :
2601 : /* If we're doing fast math, we don't care about comparison order
2602 : wrt NaNs. This lets us use a shorter comparison sequence. */
2603 48538827 : if (opts->x_flag_finite_math_only)
2604 977482 : opts->x_target_flags &= ~MASK_IEEE_FP;
2605 :
2606 : /* If the architecture always has an FPU, turn off NO_FANCY_MATH_387,
2607 : since the insns won't need emulation. */
2608 48538827 : if (ix86_tune_features [X86_TUNE_ALWAYS_FANCY_MATH_387])
2609 48538827 : opts->x_target_flags &= ~MASK_NO_FANCY_MATH_387;
2610 :
2611 : /* Likewise, if the target doesn't have a 387, or we've specified
2612 : software floating point, don't use 387 inline intrinsics. */
2613 48538827 : if (!TARGET_80387_P (opts->x_target_flags))
2614 2242667 : opts->x_target_flags |= MASK_NO_FANCY_MATH_387;
2615 :
2616 : /* Turn on MMX builtins for -msse. */
2617 48538827 : if (TARGET_SSE_P (opts->x_ix86_isa_flags))
2618 46354454 : opts->x_ix86_isa_flags
2619 46354454 : |= OPTION_MASK_ISA_MMX & ~opts->x_ix86_isa_flags_explicit;
2620 :
2621 : /* Enable SSE prefetch. */
2622 48538827 : if (TARGET_SSE_P (opts->x_ix86_isa_flags)
2623 2184373 : || (TARGET_PRFCHW_P (opts->x_ix86_isa_flags)
2624 18326 : && !TARGET_3DNOW_P (opts->x_ix86_isa_flags)))
2625 46372780 : ix86_prefetch_sse = true;
2626 :
2627 : /* Enable mwait/monitor instructions for -msse3. */
2628 48538827 : if (TARGET_SSE3_P (opts->x_ix86_isa_flags))
2629 46009407 : opts->x_ix86_isa_flags2
2630 46009407 : |= OPTION_MASK_ISA2_MWAIT & ~opts->x_ix86_isa_flags2_explicit;
2631 :
2632 : /* Enable popcnt instruction for -msse4.2 or -mabm. */
2633 48538827 : if (TARGET_SSE4_2_P (opts->x_ix86_isa_flags)
2634 2634055 : || TARGET_ABM_P (opts->x_ix86_isa_flags))
2635 45910855 : opts->x_ix86_isa_flags
2636 45910855 : |= OPTION_MASK_ISA_POPCNT & ~opts->x_ix86_isa_flags_explicit;
2637 :
2638 : /* Enable crc32 instruction for -msse4.2. */
2639 48538827 : if (TARGET_SSE4_2_P (opts->x_ix86_isa_flags))
2640 45904772 : opts->x_ix86_isa_flags
2641 45904772 : |= OPTION_MASK_ISA_CRC32 & ~opts->x_ix86_isa_flags_explicit;
2642 :
2643 : /* Enable lzcnt instruction for -mabm. */
2644 48538827 : if (TARGET_ABM_P(opts->x_ix86_isa_flags))
2645 68348 : opts->x_ix86_isa_flags
2646 68348 : |= OPTION_MASK_ISA_LZCNT & ~opts->x_ix86_isa_flags_explicit;
2647 :
2648 : /* Disable BMI, BMI2 and TBM instructions for -m16. */
2649 48538827 : if (TARGET_16BIT_P(opts->x_ix86_isa_flags))
2650 6 : opts->x_ix86_isa_flags
2651 6 : &= ~((OPTION_MASK_ISA_BMI | OPTION_MASK_ISA_BMI2 | OPTION_MASK_ISA_TBM)
2652 6 : & ~opts->x_ix86_isa_flags_explicit);
2653 :
2654 : /* Validate -mpreferred-stack-boundary= value or default it to
2655 : PREFERRED_STACK_BOUNDARY_DEFAULT. */
2656 48538827 : ix86_preferred_stack_boundary = PREFERRED_STACK_BOUNDARY_DEFAULT;
2657 48538827 : if (opts_set->x_ix86_preferred_stack_boundary_arg)
2658 : {
2659 1616 : int min = TARGET_64BIT_P (opts->x_ix86_isa_flags)? 3 : 2;
2660 1616 : int max = TARGET_SEH ? 4 : 12;
2661 :
2662 1616 : if (opts->x_ix86_preferred_stack_boundary_arg < min
2663 1616 : || opts->x_ix86_preferred_stack_boundary_arg > max)
2664 : {
2665 0 : if (min == max)
2666 : error ("%<-mpreferred-stack-boundary%> is not supported "
2667 : "for this target");
2668 : else
2669 0 : error ("%<-mpreferred-stack-boundary=%d%> is not between %d and %d",
2670 : opts->x_ix86_preferred_stack_boundary_arg, min, max);
2671 : }
2672 : else
2673 1616 : ix86_preferred_stack_boundary
2674 1616 : = (1 << opts->x_ix86_preferred_stack_boundary_arg) * BITS_PER_UNIT;
2675 : }
2676 :
2677 : /* Set the default value for -mstackrealign. */
2678 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, ix86_force_align_arg_pointer,
2679 : STACK_REALIGN_DEFAULT);
2680 :
2681 48538827 : ix86_default_incoming_stack_boundary = PREFERRED_STACK_BOUNDARY;
2682 :
2683 : /* Validate -mincoming-stack-boundary= value or default it to
2684 : MIN_STACK_BOUNDARY/PREFERRED_STACK_BOUNDARY. */
2685 48538827 : ix86_incoming_stack_boundary = ix86_default_incoming_stack_boundary;
2686 48538827 : if (opts_set->x_ix86_incoming_stack_boundary_arg)
2687 : {
2688 15 : int min = TARGET_64BIT_P (opts->x_ix86_isa_flags) ? 3 : 2;
2689 :
2690 15 : if (opts->x_ix86_incoming_stack_boundary_arg < min
2691 15 : || opts->x_ix86_incoming_stack_boundary_arg > 12)
2692 0 : error ("%<-mincoming-stack-boundary=%d%> is not between %d and 12",
2693 : opts->x_ix86_incoming_stack_boundary_arg, min);
2694 : else
2695 : {
2696 15 : ix86_user_incoming_stack_boundary
2697 15 : = (1 << opts->x_ix86_incoming_stack_boundary_arg) * BITS_PER_UNIT;
2698 15 : ix86_incoming_stack_boundary
2699 15 : = ix86_user_incoming_stack_boundary;
2700 : }
2701 : }
2702 :
2703 : #ifndef NO_PROFILE_COUNTERS
2704 : if (flag_nop_mcount)
2705 : error ("%<-mnop-mcount%> is not compatible with this target");
2706 : #endif
2707 48538827 : if (flag_nop_mcount && flag_pic && !flag_plt)
2708 0 : error ("%<-mnop-mcount%> is not implemented for %<-fno-plt%>");
2709 :
2710 : /* Accept -msseregparm only if at least SSE support is enabled. */
2711 48538827 : if (TARGET_SSEREGPARM_P (opts->x_target_flags)
2712 0 : && ! TARGET_SSE_P (opts->x_ix86_isa_flags))
2713 0 : error (main_args_p
2714 : ? G_("%<-msseregparm%> used without SSE enabled")
2715 : : G_("%<target(\"sseregparm\")%> used without SSE enabled"));
2716 :
2717 48538827 : if (opts_set->x_ix86_fpmath)
2718 : {
2719 1303944 : if (opts->x_ix86_fpmath & FPMATH_SSE)
2720 : {
2721 1261336 : if (!TARGET_SSE_P (opts->x_ix86_isa_flags))
2722 : {
2723 45559 : if (TARGET_80387_P (opts->x_target_flags))
2724 : {
2725 0 : warning (0, "SSE instruction set disabled, using 387 arithmetics");
2726 0 : opts->x_ix86_fpmath = FPMATH_387;
2727 : }
2728 : }
2729 1215777 : else if ((opts->x_ix86_fpmath & FPMATH_387)
2730 89 : && !TARGET_80387_P (opts->x_target_flags))
2731 : {
2732 0 : warning (0, "387 instruction set disabled, using SSE arithmetics");
2733 0 : opts->x_ix86_fpmath = FPMATH_SSE;
2734 : }
2735 : }
2736 : }
2737 : /* For all chips supporting SSE2, -mfpmath=sse performs better than
2738 : fpmath=387. The second is however default at many targets since the
2739 : extra 80bit precision of temporaries is considered to be part of ABI.
2740 : Overwrite the default at least for -ffast-math.
2741 : TODO: -mfpmath=both seems to produce same performing code with bit
2742 : smaller binaries. It is however not clear if register allocation is
2743 : ready for this setting.
2744 : Also -mfpmath=387 is overall a lot more compact (bout 4-5%) than SSE
2745 : codegen. We may switch to 387 with -ffast-math for size optimized
2746 : functions. */
2747 47234883 : else if (fast_math_flags_set_p (&global_options)
2748 47234883 : && TARGET_SSE2_P (opts->x_ix86_isa_flags))
2749 901370 : opts->x_ix86_fpmath = FPMATH_SSE;
2750 : else
2751 49069223 : opts->x_ix86_fpmath = TARGET_FPMATH_DEFAULT_P (opts->x_ix86_isa_flags);
2752 :
2753 : /* Use external vectorized library in vectorizing intrinsics. */
2754 48538827 : if (opts_set->x_ix86_veclibabi_type)
2755 6 : switch (opts->x_ix86_veclibabi_type)
2756 : {
2757 3 : case ix86_veclibabi_type_svml:
2758 3 : ix86_veclib_handler = &ix86_veclibabi_svml;
2759 3 : break;
2760 :
2761 2 : case ix86_veclibabi_type_acml:
2762 2 : ix86_veclib_handler = &ix86_veclibabi_acml;
2763 2 : break;
2764 :
2765 1 : case ix86_veclibabi_type_aocl:
2766 1 : ix86_veclib_handler = &ix86_veclibabi_aocl;
2767 1 : break;
2768 :
2769 0 : default:
2770 0 : gcc_unreachable ();
2771 : }
2772 :
2773 48538827 : if (ix86_tune_features [X86_TUNE_ACCUMULATE_OUTGOING_ARGS]
2774 229394 : && !(opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
2775 229394 : opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
2776 :
2777 : /* If stack probes are required, the space used for large function
2778 : arguments on the stack must also be probed, so enable
2779 : -maccumulate-outgoing-args so this happens in the prologue. */
2780 48538827 : if (TARGET_STACK_PROBE_P (opts->x_target_flags)
2781 22 : && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
2782 : {
2783 22 : if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
2784 0 : warning (0,
2785 : main_args_p
2786 : ? G_("stack probing requires %<-maccumulate-outgoing-args%> "
2787 : "for correctness")
2788 : : G_("stack probing requires "
2789 : "%<target(\"accumulate-outgoing-args\")%> for "
2790 : "correctness"));
2791 22 : opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
2792 : }
2793 :
2794 : /* Stack realignment without -maccumulate-outgoing-args requires %ebp,
2795 : so enable -maccumulate-outgoing-args when %ebp is fixed. */
2796 48538827 : if (fixed_regs[BP_REG]
2797 3 : && !(opts->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS))
2798 : {
2799 3 : if (opts_set->x_target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
2800 2 : warning (0,
2801 : main_args_p
2802 : ? G_("fixed ebp register requires "
2803 : "%<-maccumulate-outgoing-args%>")
2804 : : G_("fixed ebp register requires "
2805 : "%<target(\"accumulate-outgoing-args\")%>"));
2806 3 : opts->x_target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
2807 : }
2808 :
2809 : /* Figure out what ASM_GENERATE_INTERNAL_LABEL builds as a prefix. */
2810 48538827 : {
2811 48538827 : char *p;
2812 48538827 : ASM_GENERATE_INTERNAL_LABEL (internal_label_prefix, "LX", 0);
2813 48538827 : p = strchr (internal_label_prefix, 'X');
2814 48538827 : internal_label_prefix_len = p - internal_label_prefix;
2815 48538827 : *p = '\0';
2816 : }
2817 :
2818 : /* When scheduling description is not available, disable scheduler pass
2819 : so it won't slow down the compilation and make x87 code slower. */
2820 48538827 : if (!TARGET_SCHEDULE)
2821 12 : opts->x_flag_schedule_insns_after_reload = opts->x_flag_schedule_insns = 0;
2822 :
2823 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
2824 : ix86_tune_cost->simultaneous_prefetches);
2825 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
2826 : ix86_tune_cost->prefetch_block);
2827 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
2828 : ix86_tune_cost->l1_cache_size);
2829 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
2830 : ix86_tune_cost->l2_cache_size);
2831 :
2832 : /* 64B is the accepted value for these for all x86. */
2833 48538827 : SET_OPTION_IF_UNSET (&global_options, &global_options_set,
2834 : param_destruct_interfere_size, 64);
2835 48538827 : SET_OPTION_IF_UNSET (&global_options, &global_options_set,
2836 : param_construct_interfere_size, 64);
2837 :
2838 : /* Enable sw prefetching at -O3 for CPUS that prefetching is helpful. */
2839 48538827 : if (opts->x_flag_prefetch_loop_arrays < 0
2840 48538768 : && HAVE_prefetch
2841 48538735 : && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
2842 2415586 : && !opts->x_optimize_size
2843 2415582 : && TARGET_SOFTWARE_PREFETCHING_BENEFICIAL)
2844 50 : opts->x_flag_prefetch_loop_arrays = 1;
2845 :
2846 : /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
2847 : can be opts->x_optimized to ap = __builtin_next_arg (0). */
2848 48538827 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) && !opts->x_flag_split_stack)
2849 15447 : targetm.expand_builtin_va_start = NULL;
2850 :
2851 : #ifdef USE_IX86_CLD
2852 : /* Use -mcld by default for 32-bit code if configured with --enable-cld. */
2853 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags))
2854 : opts->x_target_flags |= MASK_CLD & ~opts_set->x_target_flags;
2855 : #endif
2856 :
2857 : /* Set the default value for -mfentry. */
2858 48538827 : if (!opts_set->x_flag_fentry)
2859 48538776 : opts->x_flag_fentry = (TARGET_SEH
2860 48538776 : || (TARGET_64BIT_P (opts->x_ix86_isa_flags)
2861 : && ENABLE_X86_64_MFENTRY));
2862 : else
2863 : {
2864 51 : if (!TARGET_64BIT_P (opts->x_ix86_isa_flags) && opts->x_flag_pic
2865 0 : && opts->x_flag_fentry)
2866 0 : sorry ("%<-mfentry%> isn%'t supported for 32-bit in combination "
2867 : "with %<-fpic%>");
2868 : else if (TARGET_SEH && !opts->x_flag_fentry)
2869 : sorry ("%<-mno-fentry%> isn%'t compatible with SEH");
2870 : }
2871 :
2872 : #ifdef OPTION_GLIBC_P
2873 : /* -mfentry is supported only on glibc targets. */
2874 48538827 : if (!opts->x_flag_fentry
2875 612354 : && OPTION_GLIBC_P (opts)
2876 612354 : && (TARGET_64BIT_P (opts->x_ix86_isa_flags) || !opts->x_flag_pic)
2877 306855 : && opts->x_flag_shrink_wrap
2878 306342 : && opts->x_profile_flag)
2879 2 : warning (0, "%<-pg%> without %<-mfentry%> may be unreliable with "
2880 : "shrink wrapping");
2881 : #endif
2882 :
2883 48538827 : if (TARGET_SEH && TARGET_CALL_MS2SYSV_XLOGUES)
2884 : sorry ("%<-mcall-ms2sysv-xlogues%> isn%'t currently supported with SEH");
2885 :
2886 48538827 : if (!(opts_set->x_target_flags & MASK_VZEROUPPER)
2887 48336397 : && flag_expensive_optimizations
2888 44736220 : && !optimize_size)
2889 44041585 : opts->x_target_flags |= MASK_VZEROUPPER;
2890 48538827 : if (!(opts_set->x_target_flags & MASK_STV))
2891 48533871 : opts->x_target_flags |= MASK_STV;
2892 : /* Disable STV if -mpreferred-stack-boundary={2,3} or
2893 : -mincoming-stack-boundary={2,3} or -mstackrealign - the needed
2894 : stack realignment will be extra cost the pass doesn't take into
2895 : account and the pass can't realign the stack. */
2896 48538827 : if (ix86_preferred_stack_boundary < 128
2897 48538819 : || ix86_incoming_stack_boundary < 128
2898 48538818 : || opts->x_ix86_force_align_arg_pointer)
2899 1617 : opts->x_target_flags &= ~MASK_STV;
2900 48538827 : if (!ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL]
2901 14525 : && !(opts_set->x_target_flags & MASK_AVX256_SPLIT_UNALIGNED_LOAD))
2902 14525 : opts->x_target_flags |= MASK_AVX256_SPLIT_UNALIGNED_LOAD;
2903 48524302 : else if (!main_args_p
2904 48238627 : && ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_LOAD_OPTIMAL])
2905 48238627 : opts->x_target_flags &= ~MASK_AVX256_SPLIT_UNALIGNED_LOAD;
2906 :
2907 48538827 : if (!ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL]
2908 15279 : && !(opts_set->x_target_flags & MASK_AVX256_SPLIT_UNALIGNED_STORE))
2909 15279 : opts->x_target_flags |= MASK_AVX256_SPLIT_UNALIGNED_STORE;
2910 48523548 : else if (!main_args_p
2911 48237920 : && ix86_tune_features[X86_TUNE_AVX256_UNALIGNED_STORE_OPTIMAL])
2912 48237920 : opts->x_target_flags &= ~MASK_AVX256_SPLIT_UNALIGNED_STORE;
2913 :
2914 : /* Enable 128-bit AVX instruction generation
2915 : for the auto-vectorizer. */
2916 48538827 : if (ix86_tune_features[X86_TUNE_AVX128_OPTIMAL]
2917 851 : && (opts_set->x_prefer_vector_width_type == PVW_NONE))
2918 840 : opts->x_prefer_vector_width_type = PVW_AVX128;
2919 :
2920 : /* Use 256-bit AVX instruction generation
2921 : in the auto-vectorizer. */
2922 48538827 : if (ix86_tune_features[X86_TUNE_AVX256_OPTIMAL]
2923 215745 : && (opts_set->x_prefer_vector_width_type == PVW_NONE))
2924 88674 : opts->x_prefer_vector_width_type = PVW_AVX256;
2925 :
2926 48538827 : if (opts_set->x_ix86_move_max == PVW_NONE)
2927 : {
2928 : /* Set the maximum number of bits can be moved from memory to
2929 : memory efficiently. */
2930 48538814 : if (opts_set->x_prefer_vector_width_type != PVW_NONE)
2931 947973 : opts->x_ix86_move_max = opts->x_prefer_vector_width_type;
2932 47590841 : else if (ix86_tune_features[X86_TUNE_AVX512_MOVE_BY_PIECES])
2933 4241 : opts->x_ix86_move_max = PVW_AVX512;
2934 47586600 : else if (ix86_tune_features[X86_TUNE_AVX256_MOVE_BY_PIECES])
2935 405313 : opts->x_ix86_move_max = PVW_AVX256;
2936 : else
2937 : {
2938 47181287 : opts->x_ix86_move_max = opts->x_prefer_vector_width_type;
2939 47181287 : if (opts->x_ix86_move_max == PVW_NONE)
2940 : {
2941 47180511 : if (TARGET_AVX512F_P (opts->x_ix86_isa_flags))
2942 43253286 : opts->x_ix86_move_max = PVW_AVX512;
2943 : /* Align with vectorizer to avoid potential STLF issue. */
2944 3927225 : else if (TARGET_AVX_P (opts->x_ix86_isa_flags))
2945 1341864 : opts->x_ix86_move_max = PVW_AVX256;
2946 : else
2947 2585361 : opts->x_ix86_move_max = PVW_AVX128;
2948 : }
2949 : }
2950 : }
2951 :
2952 48538827 : if (opts->x_ix86_recip_name)
2953 : {
2954 0 : char *p = ASTRDUP (opts->x_ix86_recip_name);
2955 0 : char *q;
2956 0 : unsigned int mask;
2957 0 : bool invert;
2958 :
2959 0 : while ((q = strtok (p, ",")) != NULL)
2960 : {
2961 0 : p = NULL;
2962 0 : if (*q == '!')
2963 : {
2964 0 : invert = true;
2965 0 : q++;
2966 : }
2967 : else
2968 : invert = false;
2969 :
2970 0 : if (!strcmp (q, "default"))
2971 : mask = RECIP_MASK_ALL;
2972 : else
2973 : {
2974 0 : for (i = 0; i < ARRAY_SIZE (recip_options); i++)
2975 0 : if (!strcmp (q, recip_options[i].string))
2976 : {
2977 0 : mask = recip_options[i].mask;
2978 0 : break;
2979 : }
2980 :
2981 0 : if (i == ARRAY_SIZE (recip_options))
2982 : {
2983 0 : error ("unknown option for %<-mrecip=%s%>", q);
2984 0 : invert = false;
2985 0 : mask = RECIP_MASK_NONE;
2986 : }
2987 : }
2988 :
2989 0 : opts->x_recip_mask_explicit |= mask;
2990 0 : if (invert)
2991 0 : opts->x_recip_mask &= ~mask;
2992 : else
2993 0 : opts->x_recip_mask |= mask;
2994 : }
2995 : }
2996 :
2997 48538827 : if (TARGET_RECIP_P (opts->x_target_flags))
2998 13074 : opts->x_recip_mask |= RECIP_MASK_ALL & ~opts->x_recip_mask_explicit;
2999 48525753 : else if (opts_set->x_target_flags & MASK_RECIP)
3000 2 : opts->x_recip_mask &= ~(RECIP_MASK_ALL & ~opts->x_recip_mask_explicit);
3001 :
3002 : /* Default long double to 64-bit for 32-bit Bionic and to __float128
3003 : for 64-bit Bionic. Also default long double to 64-bit for Intel
3004 : MCU psABI. */
3005 48538827 : if ((TARGET_HAS_BIONIC || TARGET_IAMCU)
3006 8 : && !(opts_set->x_target_flags
3007 : & (MASK_LONG_DOUBLE_64 | MASK_LONG_DOUBLE_128)))
3008 2 : opts->x_target_flags |= (TARGET_64BIT
3009 2 : ? MASK_LONG_DOUBLE_128
3010 : : MASK_LONG_DOUBLE_64);
3011 :
3012 : /* Only one of them can be active. */
3013 48538827 : gcc_assert ((opts->x_target_flags & MASK_LONG_DOUBLE_64) == 0
3014 : || (opts->x_target_flags & MASK_LONG_DOUBLE_128) == 0);
3015 :
3016 : /* Handle stack protector */
3017 48538827 : if (!opts_set->x_ix86_stack_protector_guard)
3018 : {
3019 : #ifdef TARGET_THREAD_SSP_OFFSET
3020 48538824 : if (!TARGET_HAS_BIONIC)
3021 48538816 : opts->x_ix86_stack_protector_guard = SSP_TLS;
3022 : else
3023 : #endif
3024 8 : opts->x_ix86_stack_protector_guard = SSP_GLOBAL;
3025 : }
3026 :
3027 48538827 : if (opts_set->x_ix86_stack_protector_guard_offset_str)
3028 : {
3029 1 : char *endp;
3030 1 : const char *str = opts->x_ix86_stack_protector_guard_offset_str;
3031 :
3032 1 : errno = 0;
3033 1 : int64_t offset;
3034 :
3035 : #if defined(INT64_T_IS_LONG)
3036 1 : offset = strtol (str, &endp, 0);
3037 : #else
3038 : offset = strtoll (str, &endp, 0);
3039 : #endif
3040 :
3041 1 : if (!*str || *endp || errno)
3042 0 : error ("%qs is not a valid number "
3043 : "in %<-mstack-protector-guard-offset=%>", str);
3044 :
3045 1 : if (!IN_RANGE (offset, HOST_WIDE_INT_C (-0x80000000),
3046 : HOST_WIDE_INT_C (0x7fffffff)))
3047 0 : error ("%qs is not a valid offset "
3048 : "in %<-mstack-protector-guard-offset=%>", str);
3049 :
3050 1 : opts->x_ix86_stack_protector_guard_offset = offset;
3051 : }
3052 : #ifdef TARGET_THREAD_SSP_OFFSET
3053 : else
3054 96465213 : opts->x_ix86_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET;
3055 : #endif
3056 :
3057 48538827 : if (opts_set->x_ix86_stack_protector_guard_reg_str)
3058 : {
3059 2 : const char *str = opts->x_ix86_stack_protector_guard_reg_str;
3060 2 : addr_space_t seg = ADDR_SPACE_GENERIC;
3061 :
3062 : /* Discard optional register prefix. */
3063 2 : if (str[0] == '%')
3064 0 : str++;
3065 :
3066 2 : if (strlen (str) == 2 && str[1] == 's')
3067 : {
3068 2 : if (str[0] == 'f')
3069 : seg = ADDR_SPACE_SEG_FS;
3070 2 : else if (str[0] == 'g')
3071 : seg = ADDR_SPACE_SEG_GS;
3072 : }
3073 :
3074 : if (seg == ADDR_SPACE_GENERIC)
3075 0 : error ("%qs is not a valid base register "
3076 : "in %<-mstack-protector-guard-reg=%>",
3077 : opts->x_ix86_stack_protector_guard_reg_str);
3078 :
3079 2 : opts->x_ix86_stack_protector_guard_reg = seg;
3080 : }
3081 : else
3082 : {
3083 48538825 : opts->x_ix86_stack_protector_guard_reg = DEFAULT_TLS_SEG_REG;
3084 :
3085 : /* The kernel uses a different segment register for performance
3086 : reasons; a system call would not have to trash the userspace
3087 : segment register, which would be expensive. */
3088 48538825 : if (opts->x_ix86_cmodel == CM_KERNEL)
3089 1 : opts->x_ix86_stack_protector_guard_reg = ADDR_SPACE_SEG_GS;
3090 : }
3091 :
3092 : /* Handle -mmemcpy-strategy= and -mmemset-strategy= */
3093 48538827 : if (opts->x_ix86_tune_memcpy_strategy)
3094 : {
3095 18 : char *str = xstrdup (opts->x_ix86_tune_memcpy_strategy);
3096 18 : ix86_parse_stringop_strategy_string (str, false);
3097 18 : free (str);
3098 : }
3099 :
3100 48538827 : if (opts->x_ix86_tune_memset_strategy)
3101 : {
3102 34 : char *str = xstrdup (opts->x_ix86_tune_memset_strategy);
3103 34 : ix86_parse_stringop_strategy_string (str, true);
3104 34 : free (str);
3105 : }
3106 :
3107 : /* Save the initial options in case the user does function specific
3108 : options. */
3109 48538827 : if (main_args_p)
3110 : {
3111 285716 : opts->x_ix86_excess_precision
3112 285716 : = opts->x_flag_excess_precision;
3113 285716 : opts->x_ix86_unsafe_math_optimizations
3114 285716 : = opts->x_flag_unsafe_math_optimizations;
3115 571432 : target_option_default_node = target_option_current_node
3116 285716 : = build_target_option_node (opts, opts_set);
3117 : }
3118 :
3119 48538827 : const bool cf_okay_p = (TARGET_64BIT || TARGET_CMOV);
3120 : /* When -fhardened, enable -fcf-protection=full, but only when it's
3121 : compatible with this target, and when it wasn't already specified
3122 : on the command line. */
3123 48538827 : if (opts->x_flag_hardened && cf_okay_p)
3124 : {
3125 91 : if (!opts_set->x_flag_cf_protection)
3126 90 : opts->x_flag_cf_protection = CF_FULL;
3127 1 : else if (opts->x_flag_cf_protection != CF_FULL)
3128 1 : warning_at (UNKNOWN_LOCATION, OPT_Whardened,
3129 : "%<-fcf-protection=full%> is not enabled by "
3130 : "%<-fhardened%> because it was specified on the command "
3131 : "line");
3132 : }
3133 :
3134 48538827 : if (opts->x_flag_cf_protection != CF_NONE)
3135 : {
3136 41704 : if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH
3137 41573 : && !cf_okay_p)
3138 0 : error ("%<-fcf-protection%> is not compatible with this target");
3139 :
3140 41704 : opts->x_flag_cf_protection
3141 41704 : = (cf_protection_level) (opts->x_flag_cf_protection | CF_SET);
3142 : }
3143 :
3144 48538827 : if (ix86_tune_features [X86_TUNE_AVOID_512FMA_CHAINS])
3145 112 : SET_OPTION_IF_UNSET (opts, opts_set, param_avoid_fma_max_bits, 512);
3146 48538715 : else if (ix86_tune_features [X86_TUNE_AVOID_256FMA_CHAINS])
3147 47794804 : SET_OPTION_IF_UNSET (opts, opts_set, param_avoid_fma_max_bits, 256);
3148 743911 : else if (ix86_tune_features [X86_TUNE_AVOID_128FMA_CHAINS])
3149 113 : SET_OPTION_IF_UNSET (opts, opts_set, param_avoid_fma_max_bits, 128);
3150 :
3151 : /* PR86952: jump table usage with retpolines is slow.
3152 : The PR provides some numbers about the slowness. */
3153 48538827 : if (ix86_indirect_branch != indirect_branch_keep)
3154 49 : SET_OPTION_IF_UNSET (opts, opts_set, flag_jump_tables, 0);
3155 :
3156 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_ira_consider_dup_in_all_alts, 0);
3157 :
3158 : /* Fully masking the main or the epilogue vectorized loop is not
3159 : profitable generally so leave it disabled until we get more
3160 : fine grained control & costing. */
3161 48538827 : SET_OPTION_IF_UNSET (opts, opts_set, param_vect_partial_vector_usage, 0);
3162 :
3163 : return true;
3164 : }
3165 :
3166 : /* Implement the TARGET_OPTION_OVERRIDE hook. */
3167 :
3168 : void
3169 285717 : ix86_option_override (void)
3170 : {
3171 285717 : ix86_option_override_internal (true, &global_options, &global_options_set);
3172 285717 : }
3173 :
3174 : /* Remember the last target of ix86_set_current_function. */
3175 : static GTY(()) tree ix86_previous_fndecl;
3176 :
3177 : /* Set targets globals to the default (or current #pragma GCC target
3178 : if active). Invalidate ix86_previous_fndecl cache. */
3179 :
3180 : void
3181 2330720 : ix86_reset_previous_fndecl (void)
3182 : {
3183 2330720 : tree new_tree = target_option_current_node;
3184 2330720 : cl_target_option_restore (&global_options, &global_options_set,
3185 2330720 : TREE_TARGET_OPTION (new_tree));
3186 2330720 : if (TREE_TARGET_GLOBALS (new_tree))
3187 582213 : restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
3188 1748507 : else if (new_tree == target_option_default_node)
3189 1266786 : restore_target_globals (&default_target_globals);
3190 : else
3191 481721 : TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
3192 2330720 : ix86_previous_fndecl = NULL_TREE;
3193 2330720 : }
3194 :
3195 : /* Add target attribute to SIMD clone NODE if needed. */
3196 :
3197 : void
3198 7188 : ix86_simd_clone_adjust (struct cgraph_node *node)
3199 : {
3200 7188 : const char *str = NULL;
3201 :
3202 : /* Attributes need to be adjusted for definitions, not declarations. */
3203 7188 : if (!node->definition)
3204 : return;
3205 :
3206 4472 : gcc_assert (node->decl == cfun->decl);
3207 4472 : switch (node->simdclone->vecsize_mangle)
3208 : {
3209 1115 : case 'b':
3210 1115 : if (!TARGET_SSE2)
3211 : str = "sse2";
3212 : break;
3213 1176 : case 'c':
3214 1176 : if (TARGET_PREFER_AVX128)
3215 : {
3216 1 : if (!TARGET_AVX)
3217 : str = "avx,prefer-vector-width=256";
3218 : else
3219 : str = "prefer-vector-width=256";
3220 : }
3221 1175 : else if (!TARGET_AVX)
3222 : str = "avx";
3223 : break;
3224 1091 : case 'd':
3225 1091 : if (TARGET_PREFER_AVX128)
3226 : {
3227 1 : if (!TARGET_AVX2)
3228 : str = "avx2,prefer-vector-width=256";
3229 : else
3230 : str = "prefer-vector-width=256";
3231 : }
3232 1090 : else if (!TARGET_AVX2)
3233 : str = "avx2";
3234 : break;
3235 1090 : case 'e':
3236 1090 : if (TARGET_PREFER_AVX256)
3237 : {
3238 4 : if (!TARGET_AVX512F)
3239 : str = "avx512f,prefer-vector-width=512";
3240 : else
3241 2 : str = "prefer-vector-width=512";
3242 : }
3243 1086 : else if (!TARGET_AVX512F)
3244 : str = "avx512f";
3245 : break;
3246 0 : default:
3247 0 : gcc_unreachable ();
3248 : }
3249 2 : if (str == NULL)
3250 : return;
3251 2862 : push_cfun (NULL);
3252 2862 : tree args = build_tree_list (NULL_TREE, build_string (strlen (str), str));
3253 2862 : bool ok = ix86_valid_target_attribute_p (node->decl, NULL, args, 0);
3254 2862 : gcc_assert (ok);
3255 2862 : pop_cfun ();
3256 2862 : ix86_reset_previous_fndecl ();
3257 2862 : ix86_set_current_function (node->decl);
3258 : }
3259 :
3260 :
3261 :
3262 : /* Set the func_type field from the function FNDECL. */
3263 :
3264 : static void
3265 428327557 : ix86_set_func_type (tree fndecl)
3266 : {
3267 : /* No need to save and restore callee-saved registers for a noreturn
3268 : function with nothrow or compiled with -fno-exceptions unless when
3269 : compiling with -O0 or -Og, except that it interferes with debugging
3270 : of callers. So that backtrace works for those at least
3271 : in most cases, save the bp register if it is used, because it often
3272 : is used in callers to compute CFA.
3273 :
3274 : NB: Can't use just TREE_THIS_VOLATILE to check if this is a noreturn
3275 : function. The local-pure-const pass turns an interrupt function
3276 : into a noreturn function by setting TREE_THIS_VOLATILE. Normally
3277 : the local-pure-const pass is run after ix86_set_func_type is called.
3278 : When the local-pure-const pass is enabled for LTO, the interrupt
3279 : function is marked with TREE_THIS_VOLATILE in the IR output, which
3280 : leads to the incompatible attribute error in LTO1. Ignore the
3281 : interrupt function in this case. */
3282 428327557 : enum call_saved_registers_type no_callee_saved_registers
3283 : = TYPE_DEFAULT_CALL_SAVED_REGISTERS;
3284 428327557 : if (lookup_attribute ("preserve_none",
3285 428327557 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
3286 : no_callee_saved_registers = TYPE_PRESERVE_NONE;
3287 428326648 : else if ((lookup_attribute ("no_callee_saved_registers",
3288 428326648 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
3289 428326648 : || (ix86_noreturn_no_callee_saved_registers
3290 565 : && TREE_THIS_VOLATILE (fndecl)
3291 565 : && optimize
3292 529 : && !optimize_debug
3293 477 : && (TREE_NOTHROW (fndecl) || !flag_exceptions)
3294 477 : && !lookup_attribute ("interrupt",
3295 477 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))
3296 477 : && !lookup_attribute ("no_caller_saved_registers",
3297 477 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))))
3298 : no_callee_saved_registers = TYPE_NO_CALLEE_SAVED_REGISTERS;
3299 :
3300 428327557 : if (cfun->machine->func_type == TYPE_UNKNOWN)
3301 : {
3302 203482147 : if (lookup_attribute ("interrupt",
3303 203482147 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
3304 : {
3305 154 : if (ix86_function_naked (fndecl))
3306 1 : error_at (DECL_SOURCE_LOCATION (fndecl),
3307 : "interrupt and naked attributes are not compatible");
3308 :
3309 154 : if (no_callee_saved_registers)
3310 : {
3311 2 : const char *attr;
3312 2 : if (no_callee_saved_registers == TYPE_PRESERVE_NONE)
3313 : attr = "preserve_none";
3314 : else
3315 1 : attr = "no_callee_saved_registers";
3316 2 : error_at (DECL_SOURCE_LOCATION (fndecl),
3317 : "%qs and %qs attributes are not compatible",
3318 : "interrupt", attr);
3319 : }
3320 :
3321 154 : int nargs = 0;
3322 154 : for (tree arg = DECL_ARGUMENTS (fndecl);
3323 389 : arg;
3324 235 : arg = TREE_CHAIN (arg))
3325 235 : nargs++;
3326 154 : cfun->machine->call_saved_registers
3327 154 : = TYPE_NO_CALLER_SAVED_REGISTERS;
3328 154 : cfun->machine->func_type
3329 154 : = nargs == 2 ? TYPE_EXCEPTION : TYPE_INTERRUPT;
3330 :
3331 154 : ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
3332 :
3333 : /* Only dwarf2out.cc can handle -WORD(AP) as a pointer argument. */
3334 154 : if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
3335 0 : sorry ("only DWARF debug format is supported for interrupt "
3336 : "service routine");
3337 : }
3338 : else
3339 : {
3340 203481993 : cfun->machine->func_type = TYPE_NORMAL;
3341 203481993 : if (no_callee_saved_registers)
3342 82 : cfun->machine->call_saved_registers
3343 82 : = no_callee_saved_registers;
3344 203481911 : else if (lookup_attribute ("no_caller_saved_registers",
3345 203481911 : TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
3346 35 : cfun->machine->call_saved_registers
3347 35 : = TYPE_NO_CALLER_SAVED_REGISTERS;
3348 : }
3349 : }
3350 428327557 : }
3351 :
3352 : /* Set the indirect_branch_type field from the function FNDECL. */
3353 :
3354 : static void
3355 428327557 : ix86_set_indirect_branch_type (tree fndecl)
3356 : {
3357 428327557 : if (cfun->machine->indirect_branch_type == indirect_branch_unset)
3358 : {
3359 203482147 : tree attr = lookup_attribute ("indirect_branch",
3360 203482147 : DECL_ATTRIBUTES (fndecl));
3361 203482147 : if (attr != NULL)
3362 : {
3363 17 : tree args = TREE_VALUE (attr);
3364 17 : if (args == NULL)
3365 0 : gcc_unreachable ();
3366 17 : tree cst = TREE_VALUE (args);
3367 17 : if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)
3368 2 : cfun->machine->indirect_branch_type = indirect_branch_keep;
3369 15 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)
3370 5 : cfun->machine->indirect_branch_type = indirect_branch_thunk;
3371 10 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)
3372 3 : cfun->machine->indirect_branch_type = indirect_branch_thunk_inline;
3373 7 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)
3374 7 : cfun->machine->indirect_branch_type = indirect_branch_thunk_extern;
3375 : else
3376 0 : gcc_unreachable ();
3377 : }
3378 : else
3379 203482130 : cfun->machine->indirect_branch_type = ix86_indirect_branch;
3380 :
3381 : /* -mcmodel=large is not compatible with -mindirect-branch=thunk
3382 : nor -mindirect-branch=thunk-extern. */
3383 203482147 : if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
3384 7464 : && ((cfun->machine->indirect_branch_type
3385 7464 : == indirect_branch_thunk_extern)
3386 7462 : || (cfun->machine->indirect_branch_type
3387 : == indirect_branch_thunk)))
3388 6 : error ("%<-mindirect-branch=%s%> and %<-mcmodel=large%> are not "
3389 : "compatible",
3390 : ((cfun->machine->indirect_branch_type
3391 : == indirect_branch_thunk_extern)
3392 : ? "thunk-extern" : "thunk"));
3393 :
3394 203482147 : if (cfun->machine->indirect_branch_type != indirect_branch_keep
3395 78 : && (cfun->machine->indirect_branch_type
3396 : != indirect_branch_thunk_extern)
3397 52 : && (flag_cf_protection & CF_RETURN))
3398 3 : error ("%<-mindirect-branch%> and %<-fcf-protection%> are not "
3399 : "compatible");
3400 : }
3401 :
3402 428327557 : if (cfun->machine->function_return_type == indirect_branch_unset)
3403 : {
3404 203482147 : tree attr = lookup_attribute ("function_return",
3405 203482147 : DECL_ATTRIBUTES (fndecl));
3406 203482147 : if (attr != NULL)
3407 : {
3408 12 : tree args = TREE_VALUE (attr);
3409 12 : if (args == NULL)
3410 0 : gcc_unreachable ();
3411 12 : tree cst = TREE_VALUE (args);
3412 12 : if (strcmp (TREE_STRING_POINTER (cst), "keep") == 0)
3413 2 : cfun->machine->function_return_type = indirect_branch_keep;
3414 10 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk") == 0)
3415 4 : cfun->machine->function_return_type = indirect_branch_thunk;
3416 6 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk-inline") == 0)
3417 3 : cfun->machine->function_return_type = indirect_branch_thunk_inline;
3418 3 : else if (strcmp (TREE_STRING_POINTER (cst), "thunk-extern") == 0)
3419 3 : cfun->machine->function_return_type = indirect_branch_thunk_extern;
3420 : else
3421 0 : gcc_unreachable ();
3422 : }
3423 : else
3424 203482135 : cfun->machine->function_return_type = ix86_function_return;
3425 :
3426 : /* -mcmodel=large is not compatible with -mfunction-return=thunk
3427 : nor -mfunction-return=thunk-extern. */
3428 203482147 : if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
3429 7464 : && ((cfun->machine->function_return_type
3430 7464 : == indirect_branch_thunk_extern)
3431 7462 : || (cfun->machine->function_return_type
3432 : == indirect_branch_thunk)))
3433 6 : error ("%<-mfunction-return=%s%> and %<-mcmodel=large%> are not "
3434 : "compatible",
3435 : ((cfun->machine->function_return_type
3436 : == indirect_branch_thunk_extern)
3437 : ? "thunk-extern" : "thunk"));
3438 :
3439 203482147 : if (cfun->machine->function_return_type != indirect_branch_keep
3440 32 : && (cfun->machine->function_return_type
3441 : != indirect_branch_thunk_extern)
3442 24 : && (flag_cf_protection & CF_RETURN))
3443 3 : error ("%<-mfunction-return%> and %<-fcf-protection%> are not "
3444 : "compatible");
3445 : }
3446 428327557 : }
3447 :
3448 : /* Establish appropriate back-end context for processing the function
3449 : FNDECL. The argument might be NULL to indicate processing at top
3450 : level, outside of any function scope. */
3451 : void
3452 851380932 : ix86_set_current_function (tree fndecl)
3453 : {
3454 : /* Only change the context if the function changes. This hook is called
3455 : several times in the course of compiling a function, and we don't want to
3456 : slow things down too much or call target_reinit when it isn't safe. */
3457 851380932 : if (fndecl == ix86_previous_fndecl)
3458 : {
3459 : /* There may be 2 function bodies for the same function FNDECL,
3460 : one is extern inline and one isn't. Call ix86_set_func_type
3461 : to set the func_type field. */
3462 118110401 : if (fndecl != NULL_TREE)
3463 : {
3464 118110358 : ix86_set_func_type (fndecl);
3465 118110358 : ix86_set_indirect_branch_type (fndecl);
3466 : }
3467 118110401 : return;
3468 : }
3469 :
3470 733270531 : tree old_tree;
3471 733270531 : if (ix86_previous_fndecl == NULL_TREE)
3472 2007085 : old_tree = target_option_current_node;
3473 731263446 : else if (DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl))
3474 : old_tree = DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl);
3475 : else
3476 672631707 : old_tree = target_option_default_node;
3477 :
3478 733270531 : if (fndecl == NULL_TREE)
3479 : {
3480 423053332 : if (old_tree != target_option_current_node)
3481 1215030 : ix86_reset_previous_fndecl ();
3482 423053332 : return;
3483 : }
3484 :
3485 310217199 : ix86_set_func_type (fndecl);
3486 310217199 : ix86_set_indirect_branch_type (fndecl);
3487 :
3488 310217199 : tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
3489 310217199 : if (new_tree == NULL_TREE)
3490 280273899 : new_tree = target_option_default_node;
3491 :
3492 310217199 : bool fp_flag_change
3493 310217199 : = (flag_unsafe_math_optimizations
3494 310217199 : != TREE_TARGET_OPTION (new_tree)->x_ix86_unsafe_math_optimizations
3495 310217199 : || (flag_excess_precision
3496 310217086 : != TREE_TARGET_OPTION (new_tree)->x_ix86_excess_precision));
3497 310217199 : if (old_tree != new_tree || fp_flag_change)
3498 : {
3499 1215105 : cl_target_option_restore (&global_options, &global_options_set,
3500 1215105 : TREE_TARGET_OPTION (new_tree));
3501 1215105 : if (fp_flag_change)
3502 : {
3503 113 : ix86_excess_precision = flag_excess_precision;
3504 113 : ix86_unsafe_math_optimizations = flag_unsafe_math_optimizations;
3505 113 : DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_tree
3506 113 : = build_target_option_node (&global_options, &global_options_set);
3507 : }
3508 1215105 : if (TREE_TARGET_GLOBALS (new_tree))
3509 1178344 : restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
3510 36761 : else if (new_tree == target_option_default_node)
3511 20542 : restore_target_globals (&default_target_globals);
3512 : else
3513 16219 : TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
3514 : }
3515 310217199 : ix86_previous_fndecl = fndecl;
3516 :
3517 310217199 : static call_saved_registers_type prev_call_saved_registers;
3518 :
3519 : /* 64-bit MS and SYSV ABI have different set of call used registers.
3520 : Avoid expensive re-initialization of init_regs each time we switch
3521 : function context. */
3522 310217199 : if (TARGET_64BIT
3523 310217199 : && (call_used_or_fixed_reg_p (SI_REG)
3524 301746692 : == (cfun->machine->call_abi == MS_ABI)))
3525 36927 : reinit_regs ();
3526 : /* Need to re-initialize init_regs if caller-saved registers are
3527 : changed. */
3528 310180272 : else if (prev_call_saved_registers
3529 310180272 : != cfun->machine->call_saved_registers)
3530 10814 : reinit_regs ();
3531 :
3532 310217199 : if (cfun->machine->func_type != TYPE_NORMAL
3533 310213059 : || (cfun->machine->call_saved_registers
3534 310213059 : == TYPE_NO_CALLER_SAVED_REGISTERS))
3535 : {
3536 : /* Don't allow AVX, AVX512, MMX nor x87 instructions since they
3537 : may change processor state. Don't allow SSE instructions in
3538 : exception/interrupt service routines. */
3539 4953 : const char *isa;
3540 4953 : if (TARGET_SSE)
3541 : {
3542 205 : if (TARGET_AVX512F)
3543 : isa = "AVX512";
3544 205 : else if (TARGET_AVX)
3545 : isa = "AVX";
3546 205 : else if (cfun->machine->func_type != TYPE_NORMAL)
3547 : isa = "SSE";
3548 204 : else if (TARGET_MMX)
3549 : isa = "MMX/3Dnow";
3550 203 : else if (TARGET_80387)
3551 : isa = "80387";
3552 : else
3553 : isa = NULL;
3554 : }
3555 4748 : else if (TARGET_MMX)
3556 : isa = "MMX/3Dnow";
3557 4745 : else if (TARGET_80387)
3558 : isa = "80387";
3559 : else
3560 : isa = NULL;
3561 : if (isa != NULL)
3562 : {
3563 9 : if (cfun->machine->func_type != TYPE_NORMAL)
3564 7 : sorry (cfun->machine->func_type == TYPE_EXCEPTION
3565 : ? G_("%s instructions aren%'t allowed in an"
3566 : " exception service routine")
3567 : : G_("%s instructions aren%'t allowed in an"
3568 : " interrupt service routine"),
3569 : isa);
3570 : else
3571 4 : sorry ("%s instructions aren%'t allowed in a function with "
3572 : "the %<no_caller_saved_registers%> attribute", isa);
3573 : /* Don't issue the same error twice. */
3574 9 : cfun->machine->func_type = TYPE_NORMAL;
3575 9 : cfun->machine->call_saved_registers
3576 9 : = TYPE_DEFAULT_CALL_SAVED_REGISTERS;
3577 : }
3578 : }
3579 :
3580 310217199 : prev_call_saved_registers = cfun->machine->call_saved_registers;
3581 : }
3582 :
3583 : /* Implement the TARGET_OFFLOAD_OPTIONS hook. */
3584 : char *
3585 0 : ix86_offload_options (void)
3586 : {
3587 0 : if (TARGET_LP64)
3588 0 : return xstrdup ("-foffload-abi=lp64 -foffload-abi-host-opts=-m64");
3589 0 : return xstrdup ("-foffload-abi=ilp32 -foffload-abi-host-opts=-m32");
3590 : }
3591 :
3592 : /* Handle "cdecl", "stdcall", "fastcall", "regparm", "thiscall",
3593 : and "sseregparm" calling convention attributes;
3594 : arguments as in struct attribute_spec.handler. */
3595 :
3596 : static tree
3597 11846 : ix86_handle_cconv_attribute (tree *node, tree name, tree args, int,
3598 : bool *no_add_attrs)
3599 : {
3600 11846 : if (TREE_CODE (*node) != FUNCTION_TYPE
3601 11846 : && TREE_CODE (*node) != METHOD_TYPE
3602 : && TREE_CODE (*node) != FIELD_DECL
3603 : && TREE_CODE (*node) != TYPE_DECL)
3604 : {
3605 0 : warning (OPT_Wattributes, "%qE attribute only applies to functions",
3606 : name);
3607 0 : *no_add_attrs = true;
3608 0 : return NULL_TREE;
3609 : }
3610 :
3611 11846 : if (TARGET_64BIT)
3612 : {
3613 : /* Do not warn when emulating the MS ABI. */
3614 791 : if ((TREE_CODE (*node) != FUNCTION_TYPE
3615 : && TREE_CODE (*node) != METHOD_TYPE)
3616 791 : || ix86_function_type_abi (*node) != MS_ABI)
3617 788 : warning (OPT_Wattributes, "%qE attribute ignored",
3618 : name);
3619 791 : *no_add_attrs = true;
3620 791 : return NULL_TREE;
3621 : }
3622 :
3623 : /* Can combine regparm with all attributes but fastcall, and thiscall. */
3624 11055 : if (is_attribute_p ("regparm", name))
3625 : {
3626 11053 : tree cst;
3627 :
3628 11053 : if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
3629 : {
3630 0 : error ("fastcall and regparm attributes are not compatible");
3631 : }
3632 :
3633 11053 : if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
3634 : {
3635 0 : error ("regparm and thiscall attributes are not compatible");
3636 : }
3637 :
3638 11053 : cst = TREE_VALUE (args);
3639 11053 : if (TREE_CODE (cst) != INTEGER_CST)
3640 : {
3641 0 : warning (OPT_Wattributes,
3642 : "%qE attribute requires an integer constant argument",
3643 : name);
3644 0 : *no_add_attrs = true;
3645 : }
3646 11053 : else if (compare_tree_int (cst, REGPARM_MAX) > 0)
3647 : {
3648 0 : warning (OPT_Wattributes, "argument to %qE attribute larger than %d",
3649 0 : name, REGPARM_MAX);
3650 0 : *no_add_attrs = true;
3651 : }
3652 :
3653 11053 : return NULL_TREE;
3654 : }
3655 :
3656 : /* Can combine fastcall with sseregparm. */
3657 2 : if (is_attribute_p ("fastcall", name))
3658 : {
3659 2 : if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
3660 : {
3661 0 : error ("fastcall and cdecl attributes are not compatible");
3662 : }
3663 2 : if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
3664 : {
3665 0 : error ("fastcall and stdcall attributes are not compatible");
3666 : }
3667 2 : if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
3668 : {
3669 0 : error ("fastcall and regparm attributes are not compatible");
3670 : }
3671 2 : if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
3672 : {
3673 0 : error ("fastcall and thiscall attributes are not compatible");
3674 : }
3675 : }
3676 :
3677 : /* Can combine stdcall with regparm and sseregparm. */
3678 0 : else if (is_attribute_p ("stdcall", name))
3679 : {
3680 0 : if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
3681 : {
3682 0 : error ("stdcall and cdecl attributes are not compatible");
3683 : }
3684 0 : if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
3685 : {
3686 0 : error ("stdcall and fastcall attributes are not compatible");
3687 : }
3688 0 : if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
3689 : {
3690 0 : error ("stdcall and thiscall attributes are not compatible");
3691 : }
3692 : }
3693 :
3694 : /* Can combine cdecl with regparm and sseregparm. */
3695 0 : else if (is_attribute_p ("cdecl", name))
3696 : {
3697 0 : if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
3698 : {
3699 0 : error ("stdcall and cdecl attributes are not compatible");
3700 : }
3701 0 : if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
3702 : {
3703 0 : error ("fastcall and cdecl attributes are not compatible");
3704 : }
3705 0 : if (lookup_attribute ("thiscall", TYPE_ATTRIBUTES (*node)))
3706 : {
3707 0 : error ("cdecl and thiscall attributes are not compatible");
3708 : }
3709 : }
3710 0 : else if (is_attribute_p ("thiscall", name))
3711 : {
3712 0 : if (TREE_CODE (*node) != METHOD_TYPE && pedantic)
3713 0 : warning (OPT_Wattributes, "%qE attribute is used for non-class method",
3714 : name);
3715 0 : if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
3716 : {
3717 0 : error ("stdcall and thiscall attributes are not compatible");
3718 : }
3719 0 : if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
3720 : {
3721 0 : error ("fastcall and thiscall attributes are not compatible");
3722 : }
3723 0 : if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
3724 : {
3725 0 : error ("cdecl and thiscall attributes are not compatible");
3726 : }
3727 0 : if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
3728 : {
3729 0 : error ("regparm and thiscall attributes are not compatible");
3730 : }
3731 : }
3732 :
3733 : /* Can combine sseregparm with all attributes. */
3734 :
3735 : return NULL_TREE;
3736 : }
3737 :
3738 : #ifndef CHECK_STACK_LIMIT
3739 : #define CHECK_STACK_LIMIT (-1)
3740 : #endif
3741 :
3742 : /* The transactional memory builtins are implicitly regparm or fastcall
3743 : depending on the ABI. Override the generic do-nothing attribute that
3744 : these builtins were declared with, and replace it with one of the two
3745 : attributes that we expect elsewhere. */
3746 :
3747 : static tree
3748 32568 : ix86_handle_tm_regparm_attribute (tree *node, tree, tree,
3749 : int flags, bool *no_add_attrs)
3750 : {
3751 32568 : tree alt;
3752 :
3753 : /* In no case do we want to add the placeholder attribute. */
3754 32568 : *no_add_attrs = true;
3755 :
3756 : /* The 64-bit ABI is unchanged for transactional memory. */
3757 32568 : if (TARGET_64BIT)
3758 : return NULL_TREE;
3759 :
3760 : /* ??? Is there a better way to validate 32-bit windows? We have
3761 : cfun->machine->call_abi, but that seems to be set only for 64-bit. */
3762 0 : if (CHECK_STACK_LIMIT > 0)
3763 : alt = tree_cons (get_identifier ("fastcall"), NULL, NULL);
3764 : else
3765 : {
3766 0 : alt = tree_cons (NULL, build_int_cst (NULL, 2), NULL);
3767 0 : alt = tree_cons (get_identifier ("regparm"), alt, NULL);
3768 : }
3769 0 : decl_attributes (node, alt, flags);
3770 :
3771 0 : return NULL_TREE;
3772 : }
3773 :
3774 : /* Handle a "force_align_arg_pointer" attribute. */
3775 :
3776 : static tree
3777 5131 : ix86_handle_force_align_arg_pointer_attribute (tree *node, tree name,
3778 : tree, int, bool *no_add_attrs)
3779 : {
3780 5131 : if (TREE_CODE (*node) != FUNCTION_TYPE
3781 5131 : && TREE_CODE (*node) != METHOD_TYPE
3782 : && TREE_CODE (*node) != FIELD_DECL
3783 : && TREE_CODE (*node) != TYPE_DECL)
3784 : {
3785 0 : warning (OPT_Wattributes, "%qE attribute only applies to functions",
3786 : name);
3787 0 : *no_add_attrs = true;
3788 : }
3789 :
3790 5131 : return NULL_TREE;
3791 : }
3792 :
3793 : /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
3794 : struct attribute_spec.handler. */
3795 :
3796 : static tree
3797 74 : ix86_handle_struct_attribute (tree *node, tree name, tree, int,
3798 : bool *no_add_attrs)
3799 : {
3800 74 : tree *type = NULL;
3801 74 : if (DECL_P (*node))
3802 : {
3803 0 : if (TREE_CODE (*node) == TYPE_DECL)
3804 0 : type = &TREE_TYPE (*node);
3805 : }
3806 : else
3807 : type = node;
3808 :
3809 74 : if (!(type && RECORD_OR_UNION_TYPE_P (*type)))
3810 : {
3811 0 : warning (OPT_Wattributes, "%qE attribute ignored",
3812 : name);
3813 0 : *no_add_attrs = true;
3814 : }
3815 :
3816 74 : else if ((is_attribute_p ("ms_struct", name)
3817 62 : && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
3818 136 : || ((is_attribute_p ("gcc_struct", name)
3819 12 : && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
3820 : {
3821 0 : warning (OPT_Wattributes, "%qE incompatible attribute ignored",
3822 : name);
3823 0 : *no_add_attrs = true;
3824 : }
3825 :
3826 74 : return NULL_TREE;
3827 : }
3828 :
3829 : /* Handle a "callee_pop_aggregate_return" attribute; arguments as
3830 : in struct attribute_spec handler. */
3831 :
3832 : static tree
3833 0 : ix86_handle_callee_pop_aggregate_return (tree *node, tree name, tree args, int,
3834 : bool *no_add_attrs)
3835 : {
3836 0 : if (TREE_CODE (*node) != FUNCTION_TYPE
3837 0 : && TREE_CODE (*node) != METHOD_TYPE
3838 : && TREE_CODE (*node) != FIELD_DECL
3839 : && TREE_CODE (*node) != TYPE_DECL)
3840 : {
3841 0 : warning (OPT_Wattributes, "%qE attribute only applies to functions",
3842 : name);
3843 0 : *no_add_attrs = true;
3844 0 : return NULL_TREE;
3845 : }
3846 0 : if (TARGET_64BIT)
3847 : {
3848 0 : warning (OPT_Wattributes, "%qE attribute only available for 32-bit",
3849 : name);
3850 0 : *no_add_attrs = true;
3851 0 : return NULL_TREE;
3852 : }
3853 0 : if (is_attribute_p ("callee_pop_aggregate_return", name))
3854 : {
3855 0 : tree cst;
3856 :
3857 0 : cst = TREE_VALUE (args);
3858 0 : if (TREE_CODE (cst) != INTEGER_CST)
3859 : {
3860 0 : warning (OPT_Wattributes,
3861 : "%qE attribute requires an integer constant argument",
3862 : name);
3863 0 : *no_add_attrs = true;
3864 : }
3865 0 : else if (compare_tree_int (cst, 0) != 0
3866 0 : && compare_tree_int (cst, 1) != 0)
3867 : {
3868 0 : warning (OPT_Wattributes,
3869 : "argument to %qE attribute is neither zero, nor one",
3870 : name);
3871 0 : *no_add_attrs = true;
3872 : }
3873 :
3874 0 : return NULL_TREE;
3875 : }
3876 :
3877 : return NULL_TREE;
3878 : }
3879 :
3880 : /* Handle a "ms_abi" or "sysv" attribute; arguments as in
3881 : struct attribute_spec.handler. */
3882 :
3883 : static tree
3884 1572356 : ix86_handle_abi_attribute (tree *node, tree name, tree, int,
3885 : bool *no_add_attrs)
3886 : {
3887 1572356 : if (TREE_CODE (*node) != FUNCTION_TYPE
3888 1572356 : && TREE_CODE (*node) != METHOD_TYPE
3889 : && TREE_CODE (*node) != FIELD_DECL
3890 : && TREE_CODE (*node) != TYPE_DECL)
3891 : {
3892 0 : warning (OPT_Wattributes, "%qE attribute only applies to functions",
3893 : name);
3894 0 : *no_add_attrs = true;
3895 0 : return NULL_TREE;
3896 : }
3897 :
3898 : /* Can combine regparm with all attributes but fastcall. */
3899 1572356 : if (is_attribute_p ("ms_abi", name))
3900 : {
3901 806411 : if (lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (*node)))
3902 : {
3903 0 : error ("%qs and %qs attributes are not compatible",
3904 : "ms_abi", "sysv_abi");
3905 : }
3906 :
3907 806411 : return NULL_TREE;
3908 : }
3909 765945 : else if (is_attribute_p ("sysv_abi", name))
3910 : {
3911 765945 : if (lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (*node)))
3912 : {
3913 0 : error ("%qs and %qs attributes are not compatible",
3914 : "ms_abi", "sysv_abi");
3915 : }
3916 :
3917 765945 : return NULL_TREE;
3918 : }
3919 :
3920 : return NULL_TREE;
3921 : }
3922 :
3923 : static tree
3924 122 : ix86_handle_fndecl_attribute (tree *node, tree name, tree args, int,
3925 : bool *no_add_attrs)
3926 : {
3927 122 : if (TREE_CODE (*node) != FUNCTION_DECL)
3928 : {
3929 0 : warning (OPT_Wattributes, "%qE attribute only applies to functions",
3930 : name);
3931 0 : *no_add_attrs = true;
3932 : }
3933 :
3934 122 : if (is_attribute_p ("indirect_branch", name))
3935 : {
3936 17 : tree cst = TREE_VALUE (args);
3937 17 : if (TREE_CODE (cst) != STRING_CST)
3938 : {
3939 0 : warning (OPT_Wattributes,
3940 : "%qE attribute requires a string constant argument",
3941 : name);
3942 0 : *no_add_attrs = true;
3943 : }
3944 17 : else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0
3945 15 : && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
3946 10 : && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0
3947 24 : && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
3948 : {
3949 0 : warning (OPT_Wattributes,
3950 : "argument to %qE attribute is not "
3951 : "(keep|thunk|thunk-inline|thunk-extern)", name);
3952 0 : *no_add_attrs = true;
3953 : }
3954 : }
3955 :
3956 122 : if (is_attribute_p ("function_return", name))
3957 : {
3958 12 : tree cst = TREE_VALUE (args);
3959 12 : if (TREE_CODE (cst) != STRING_CST)
3960 : {
3961 0 : warning (OPT_Wattributes,
3962 : "%qE attribute requires a string constant argument",
3963 : name);
3964 0 : *no_add_attrs = true;
3965 : }
3966 12 : else if (strcmp (TREE_STRING_POINTER (cst), "keep") != 0
3967 10 : && strcmp (TREE_STRING_POINTER (cst), "thunk") != 0
3968 6 : && strcmp (TREE_STRING_POINTER (cst), "thunk-inline") != 0
3969 15 : && strcmp (TREE_STRING_POINTER (cst), "thunk-extern") != 0)
3970 : {
3971 0 : warning (OPT_Wattributes,
3972 : "argument to %qE attribute is not "
3973 : "(keep|thunk|thunk-inline|thunk-extern)", name);
3974 0 : *no_add_attrs = true;
3975 : }
3976 : }
3977 :
3978 122 : return NULL_TREE;
3979 : }
3980 :
3981 : static tree
3982 169 : ix86_handle_call_saved_registers_attribute (tree *node, tree name, tree,
3983 : int, bool *)
3984 : {
3985 169 : const char *attr1 = nullptr;
3986 169 : const char *attr2 = nullptr;
3987 :
3988 169 : if (is_attribute_p ("no_callee_saved_registers", name))
3989 : {
3990 : /* Disallow preserve_none and no_caller_saved_registers
3991 : attributes. */
3992 78 : attr1 = "no_callee_saved_registers";
3993 78 : if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node)))
3994 : attr2 = "preserve_none";
3995 77 : else if (lookup_attribute ("no_caller_saved_registers",
3996 77 : TYPE_ATTRIBUTES (*node)))
3997 : attr2 = "no_caller_saved_registers";
3998 : }
3999 91 : else if (is_attribute_p ("no_caller_saved_registers", name))
4000 : {
4001 : /* Disallow preserve_none and no_callee_saved_registers
4002 : attributes. */
4003 52 : attr1 = "no_caller_saved_registers";
4004 52 : if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (*node)))
4005 : attr2 = "preserve_none";
4006 51 : else if (lookup_attribute ("no_callee_saved_registers",
4007 51 : TYPE_ATTRIBUTES (*node)))
4008 : attr2 = "no_callee_saved_registers";
4009 : }
4010 39 : else if (is_attribute_p ("preserve_none", name))
4011 : {
4012 : /* Disallow no_callee_saved_registers and no_caller_saved_registers
4013 : attributes. */
4014 39 : attr1 = "preserve_none";
4015 39 : if (lookup_attribute ("no_callee_saved_registers",
4016 39 : TYPE_ATTRIBUTES (*node)))
4017 : attr2 = "no_caller_saved_registers";
4018 39 : else if (lookup_attribute ("no_callee_saved_registers",
4019 39 : TYPE_ATTRIBUTES (*node)))
4020 : attr2 = "no_callee_saved_registers";
4021 : }
4022 :
4023 : if (attr2)
4024 3 : error ("%qs and %qs attributes are not compatible", attr1, attr2);
4025 :
4026 169 : return NULL_TREE;
4027 : }
4028 :
4029 : static tree
4030 129 : ix86_handle_interrupt_attribute (tree *node, tree, tree, int, bool *)
4031 : {
4032 : /* DECL_RESULT and DECL_ARGUMENTS do not exist there yet,
4033 : but the function type contains args and return type data. */
4034 129 : tree func_type = *node;
4035 129 : tree return_type = TREE_TYPE (func_type);
4036 :
4037 129 : int nargs = 0;
4038 129 : tree current_arg_type = TYPE_ARG_TYPES (func_type);
4039 129 : while (current_arg_type
4040 642 : && ! VOID_TYPE_P (TREE_VALUE (current_arg_type)))
4041 : {
4042 192 : if (nargs == 0)
4043 : {
4044 128 : if (! POINTER_TYPE_P (TREE_VALUE (current_arg_type)))
4045 2 : error ("interrupt service routine should have a pointer "
4046 : "as the first argument");
4047 : }
4048 64 : else if (nargs == 1)
4049 : {
4050 64 : if (TREE_CODE (TREE_VALUE (current_arg_type)) != INTEGER_TYPE
4051 64 : || TYPE_MODE (TREE_VALUE (current_arg_type)) != word_mode)
4052 2 : error ("interrupt service routine should have %qs "
4053 : "as the second argument",
4054 2 : TARGET_64BIT
4055 2 : ? (TARGET_X32 ? "unsigned long long int"
4056 : : "unsigned long int")
4057 : : "unsigned int");
4058 : }
4059 192 : nargs++;
4060 192 : current_arg_type = TREE_CHAIN (current_arg_type);
4061 : }
4062 129 : if (!nargs || nargs > 2)
4063 1 : error ("interrupt service routine can only have a pointer argument "
4064 : "and an optional integer argument");
4065 129 : if (! VOID_TYPE_P (return_type))
4066 1 : error ("interrupt service routine must return %<void%>");
4067 :
4068 129 : return NULL_TREE;
4069 : }
4070 :
4071 : /* Handle fentry_name / fentry_section attribute. */
4072 :
4073 : static tree
4074 4 : ix86_handle_fentry_name (tree *node, tree name, tree args,
4075 : int, bool *no_add_attrs)
4076 : {
4077 4 : if (TREE_CODE (*node) == FUNCTION_DECL
4078 8 : && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
4079 : /* Do nothing else, just set the attribute. We'll get at
4080 : it later with lookup_attribute. */
4081 : ;
4082 : else
4083 : {
4084 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4085 0 : *no_add_attrs = true;
4086 : }
4087 :
4088 4 : return NULL_TREE;
4089 : }
4090 :
4091 : /* Handle a "nodirect_extern_access" attribute; arguments as in
4092 : struct attribute_spec.handler. */
4093 :
4094 : static tree
4095 11 : handle_nodirect_extern_access_attribute (tree *pnode, tree name,
4096 : tree ARG_UNUSED (args),
4097 : int ARG_UNUSED (flags),
4098 : bool *no_add_attrs)
4099 : {
4100 11 : tree node = *pnode;
4101 :
4102 11 : if (VAR_OR_FUNCTION_DECL_P (node))
4103 : {
4104 7 : if ((!TREE_STATIC (node) && TREE_CODE (node) != FUNCTION_DECL
4105 18 : && !DECL_EXTERNAL (node)) || !TREE_PUBLIC (node))
4106 : {
4107 0 : warning (OPT_Wattributes,
4108 : "%qE attribute have effect only on public objects", name);
4109 0 : *no_add_attrs = true;
4110 : }
4111 : }
4112 : else
4113 : {
4114 0 : warning (OPT_Wattributes, "%qE attribute ignored", name);
4115 0 : *no_add_attrs = true;
4116 : }
4117 :
4118 11 : return NULL_TREE;
4119 : }
4120 :
4121 : /* Table of valid machine attributes. */
4122 : static const attribute_spec ix86_gnu_attributes[] =
4123 : {
4124 : /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
4125 : affects_type_identity, handler, exclude } */
4126 : /* Stdcall attribute says callee is responsible for popping arguments
4127 : if they are not variable. */
4128 : { "stdcall", 0, 0, false, true, true, true, ix86_handle_cconv_attribute,
4129 : NULL },
4130 : /* Fastcall attribute says callee is responsible for popping arguments
4131 : if they are not variable. */
4132 : { "fastcall", 0, 0, false, true, true, true, ix86_handle_cconv_attribute,
4133 : NULL },
4134 : /* Thiscall attribute says callee is responsible for popping arguments
4135 : if they are not variable. */
4136 : { "thiscall", 0, 0, false, true, true, true, ix86_handle_cconv_attribute,
4137 : NULL },
4138 : /* Cdecl attribute says the callee is a normal C declaration */
4139 : { "cdecl", 0, 0, false, true, true, true, ix86_handle_cconv_attribute,
4140 : NULL },
4141 : /* Regparm attribute specifies how many integer arguments are to be
4142 : passed in registers. */
4143 : { "regparm", 1, 1, false, true, true, true, ix86_handle_cconv_attribute,
4144 : NULL },
4145 : /* Sseregparm attribute says we are using x86_64 calling conventions
4146 : for FP arguments. */
4147 : { "sseregparm", 0, 0, false, true, true, true, ix86_handle_cconv_attribute,
4148 : NULL },
4149 : /* The transactional memory builtins are implicitly regparm or fastcall
4150 : depending on the ABI. Override the generic do-nothing attribute that
4151 : these builtins were declared with. */
4152 : { "*tm regparm", 0, 0, false, true, true, true,
4153 : ix86_handle_tm_regparm_attribute, NULL },
4154 : /* force_align_arg_pointer says this function realigns the stack at entry. */
4155 : { "force_align_arg_pointer", 0, 0,
4156 : false, true, true, false, ix86_handle_force_align_arg_pointer_attribute,
4157 : NULL },
4158 : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
4159 : { "dllimport", 0, 0, false, false, false, false, handle_dll_attribute,
4160 : NULL },
4161 : { "dllexport", 0, 0, false, false, false, false, handle_dll_attribute,
4162 : NULL },
4163 : { "shared", 0, 0, true, false, false, false,
4164 : ix86_handle_shared_attribute, NULL },
4165 : #endif
4166 : { "ms_struct", 0, 0, false, false, false, false,
4167 : ix86_handle_struct_attribute, NULL },
4168 : { "gcc_struct", 0, 0, false, false, false, false,
4169 : ix86_handle_struct_attribute, NULL },
4170 : #ifdef SUBTARGET_ATTRIBUTE_TABLE
4171 : SUBTARGET_ATTRIBUTE_TABLE,
4172 : #endif
4173 : /* ms_abi and sysv_abi calling convention function attributes. */
4174 : { "ms_abi", 0, 0, false, true, true, true, ix86_handle_abi_attribute, NULL },
4175 : { "sysv_abi", 0, 0, false, true, true, true, ix86_handle_abi_attribute,
4176 : NULL },
4177 : { "ms_abi va_list", 0, 0, false, false, false, false, NULL, NULL },
4178 : { "sysv_abi va_list", 0, 0, false, false, false, false, NULL, NULL },
4179 : { "ms_hook_prologue", 0, 0, true, false, false, false,
4180 : ix86_handle_fndecl_attribute, NULL },
4181 : { "callee_pop_aggregate_return", 1, 1, false, true, true, true,
4182 : ix86_handle_callee_pop_aggregate_return, NULL },
4183 : { "interrupt", 0, 0, false, true, true, false,
4184 : ix86_handle_interrupt_attribute, NULL },
4185 : { "no_caller_saved_registers", 0, 0, false, true, true, false,
4186 : ix86_handle_call_saved_registers_attribute, NULL },
4187 : { "preserve_none", 0, 0, false, true, true, true,
4188 : ix86_handle_call_saved_registers_attribute, NULL },
4189 : { "no_callee_saved_registers", 0, 0, false, true, true, true,
4190 : ix86_handle_call_saved_registers_attribute, NULL },
4191 : { "naked", 0, 0, true, false, false, false,
4192 : ix86_handle_fndecl_attribute, NULL },
4193 : { "indirect_branch", 1, 1, true, false, false, false,
4194 : ix86_handle_fndecl_attribute, NULL },
4195 : { "function_return", 1, 1, true, false, false, false,
4196 : ix86_handle_fndecl_attribute, NULL },
4197 : { "indirect_return", 0, 0, false, true, true, false,
4198 : NULL, NULL },
4199 : { "fentry_name", 1, 1, true, false, false, false,
4200 : ix86_handle_fentry_name, NULL },
4201 : { "fentry_section", 1, 1, true, false, false, false,
4202 : ix86_handle_fentry_name, NULL },
4203 : { "cf_check", 0, 0, true, false, false, false,
4204 : ix86_handle_fndecl_attribute, NULL },
4205 : { "nodirect_extern_access", 0, 0, true, false, false, false,
4206 : handle_nodirect_extern_access_attribute, NULL }
4207 : };
4208 :
4209 : const scoped_attribute_specs ix86_gnu_attribute_table =
4210 : {
4211 : "gnu", { ix86_gnu_attributes }
4212 : };
4213 :
4214 : #include "gt-i386-options.h"
|