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