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