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

source code of gcc/config/i386/i386-options.cc