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