Add GCC support to ENQCMD.
[official-gcc.git] / gcc / config / i386 / i386-builtins.c
blob9484b3d2daf9f0cdc8df196198a755e800277bfd
1 /* Copyright (C) 1988-2019 Free Software Foundation, Inc.
3 This file is part of GCC.
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.
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.
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/>. */
19 #define IN_TARGET_CODE 1
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 "params.h"
62 #include "cselib.h"
63 #include "sched-int.h"
64 #include "opts.h"
65 #include "tree-pass.h"
66 #include "context.h"
67 #include "pass_manager.h"
68 #include "target-globals.h"
69 #include "gimple-iterator.h"
70 #include "tree-vectorizer.h"
71 #include "shrink-wrap.h"
72 #include "builtins.h"
73 #include "rtl-iter.h"
74 #include "tree-iterator.h"
75 #include "dbgcnt.h"
76 #include "case-cfn-macros.h"
77 #include "dojump.h"
78 #include "fold-const-call.h"
79 #include "tree-vrp.h"
80 #include "tree-ssanames.h"
81 #include "selftest.h"
82 #include "selftest-rtl.h"
83 #include "print-rtl.h"
84 #include "intl.h"
85 #include "ifcvt.h"
86 #include "symbol-summary.h"
87 #include "ipa-prop.h"
88 #include "ipa-fnsummary.h"
89 #include "wide-int-bitmask.h"
90 #include "tree-vector-builder.h"
91 #include "debug.h"
92 #include "dwarf2out.h"
93 #include "i386-builtins.h"
95 #undef BDESC
96 #undef BDESC_FIRST
97 #undef BDESC_END
99 /* Macros for verification of enum ix86_builtins order. */
100 #define BDESC_VERIFY(x, y, z) \
101 gcc_checking_assert ((x) == (enum ix86_builtins) ((y) + (z)))
102 #define BDESC_VERIFYS(x, y, z) \
103 STATIC_ASSERT ((x) == (enum ix86_builtins) ((y) + (z)))
105 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPESTR_FIRST,
106 IX86_BUILTIN__BDESC_COMI_LAST, 1);
107 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPISTR_FIRST,
108 IX86_BUILTIN__BDESC_PCMPESTR_LAST, 1);
109 BDESC_VERIFYS (IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST,
110 IX86_BUILTIN__BDESC_PCMPISTR_LAST, 1);
111 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ARGS_FIRST,
112 IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST, 1);
113 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST,
114 IX86_BUILTIN__BDESC_ARGS_LAST, 1);
115 BDESC_VERIFYS (IX86_BUILTIN__BDESC_MULTI_ARG_FIRST,
116 IX86_BUILTIN__BDESC_ROUND_ARGS_LAST, 1);
117 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_FIRST,
118 IX86_BUILTIN__BDESC_MULTI_ARG_LAST, 1);
119 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_NORMAL_FIRST,
120 IX86_BUILTIN__BDESC_CET_LAST, 1);
121 BDESC_VERIFYS (IX86_BUILTIN_MAX,
122 IX86_BUILTIN__BDESC_CET_NORMAL_LAST, 1);
125 /* Table for the ix86 builtin non-function types. */
126 static GTY(()) tree ix86_builtin_type_tab[(int) IX86_BT_LAST_CPTR + 1];
128 /* Retrieve an element from the above table, building some of
129 the types lazily. */
131 static tree
132 ix86_get_builtin_type (enum ix86_builtin_type tcode)
134 unsigned int index;
135 tree type, itype;
137 gcc_assert ((unsigned)tcode < ARRAY_SIZE(ix86_builtin_type_tab));
139 type = ix86_builtin_type_tab[(int) tcode];
140 if (type != NULL)
141 return type;
143 gcc_assert (tcode > IX86_BT_LAST_PRIM);
144 if (tcode <= IX86_BT_LAST_VECT)
146 machine_mode mode;
148 index = tcode - IX86_BT_LAST_PRIM - 1;
149 itype = ix86_get_builtin_type (ix86_builtin_type_vect_base[index]);
150 mode = ix86_builtin_type_vect_mode[index];
152 type = build_vector_type_for_mode (itype, mode);
154 else
156 int quals;
158 index = tcode - IX86_BT_LAST_VECT - 1;
159 if (tcode <= IX86_BT_LAST_PTR)
160 quals = TYPE_UNQUALIFIED;
161 else
162 quals = TYPE_QUAL_CONST;
164 itype = ix86_get_builtin_type (ix86_builtin_type_ptr_base[index]);
165 if (quals != TYPE_UNQUALIFIED)
166 itype = build_qualified_type (itype, quals);
168 type = build_pointer_type (itype);
171 ix86_builtin_type_tab[(int) tcode] = type;
172 return type;
175 /* Table for the ix86 builtin function types. */
176 static GTY(()) tree ix86_builtin_func_type_tab[(int) IX86_BT_LAST_ALIAS + 1];
178 /* Retrieve an element from the above table, building some of
179 the types lazily. */
181 static tree
182 ix86_get_builtin_func_type (enum ix86_builtin_func_type tcode)
184 tree type;
186 gcc_assert ((unsigned)tcode < ARRAY_SIZE (ix86_builtin_func_type_tab));
188 type = ix86_builtin_func_type_tab[(int) tcode];
189 if (type != NULL)
190 return type;
192 if (tcode <= IX86_BT_LAST_FUNC)
194 unsigned start = ix86_builtin_func_start[(int) tcode];
195 unsigned after = ix86_builtin_func_start[(int) tcode + 1];
196 tree rtype, atype, args = void_list_node;
197 unsigned i;
199 rtype = ix86_get_builtin_type (ix86_builtin_func_args[start]);
200 for (i = after - 1; i > start; --i)
202 atype = ix86_get_builtin_type (ix86_builtin_func_args[i]);
203 args = tree_cons (NULL, atype, args);
206 type = build_function_type (rtype, args);
208 else
210 unsigned index = tcode - IX86_BT_LAST_FUNC - 1;
211 enum ix86_builtin_func_type icode;
213 icode = ix86_builtin_func_alias_base[index];
214 type = ix86_get_builtin_func_type (icode);
217 ix86_builtin_func_type_tab[(int) tcode] = type;
218 return type;
221 /* Table for the ix86 builtin decls. */
222 static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
224 struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
226 tree get_ix86_builtin (enum ix86_builtins c)
228 return ix86_builtins[c];
231 /* Bits that can still enable any inclusion of a builtin. */
232 HOST_WIDE_INT deferred_isa_values = 0;
233 HOST_WIDE_INT deferred_isa_values2 = 0;
235 /* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the
236 MASK and MASK2 of which isa_flags and ix86_isa_flags2 to use in the
237 ix86_builtins_isa array. Stores the function decl in the ix86_builtins
238 array. Returns the function decl or NULL_TREE, if the builtin was not
239 added.
241 If the front end has a special hook for builtin functions, delay adding
242 builtin functions that aren't in the current ISA until the ISA is changed
243 with function specific optimization. Doing so, can save about 300K for the
244 default compiler. When the builtin is expanded, check at that time whether
245 it is valid.
247 If the front end doesn't have a special hook, record all builtins, even if
248 it isn't an instruction set in the current ISA in case the user uses
249 function specific options for a different ISA, so that we don't get scope
250 errors if a builtin is added in the middle of a function scope. */
252 static inline tree
253 def_builtin (HOST_WIDE_INT mask, HOST_WIDE_INT mask2,
254 const char *name,
255 enum ix86_builtin_func_type tcode,
256 enum ix86_builtins code)
258 tree decl = NULL_TREE;
260 /* An instruction may be 64bit only regardless of ISAs. */
261 if (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT)
263 ix86_builtins_isa[(int) code].isa = mask;
264 ix86_builtins_isa[(int) code].isa2 = mask2;
266 mask &= ~OPTION_MASK_ISA_64BIT;
268 /* Filter out the masks most often ored together with others. */
269 if ((mask & ix86_isa_flags & OPTION_MASK_ISA_AVX512VL)
270 && mask != OPTION_MASK_ISA_AVX512VL)
271 mask &= ~OPTION_MASK_ISA_AVX512VL;
272 if ((mask & ix86_isa_flags & OPTION_MASK_ISA_AVX512BW)
273 && mask != OPTION_MASK_ISA_AVX512BW)
274 mask &= ~OPTION_MASK_ISA_AVX512BW;
276 if (((mask2 == 0 || (mask2 & ix86_isa_flags2) != 0)
277 && (mask == 0 || (mask & ix86_isa_flags) != 0))
278 || (lang_hooks.builtin_function
279 == lang_hooks.builtin_function_ext_scope))
281 tree type = ix86_get_builtin_func_type (tcode);
282 decl = add_builtin_function (name, type, code, BUILT_IN_MD,
283 NULL, NULL_TREE);
284 ix86_builtins[(int) code] = decl;
285 ix86_builtins_isa[(int) code].set_and_not_built_p = false;
287 else
289 /* Just MASK and MASK2 where set_and_not_built_p == true can potentially
290 include a builtin. */
291 deferred_isa_values |= mask;
292 deferred_isa_values2 |= mask2;
293 ix86_builtins[(int) code] = NULL_TREE;
294 ix86_builtins_isa[(int) code].tcode = tcode;
295 ix86_builtins_isa[(int) code].name = name;
296 ix86_builtins_isa[(int) code].const_p = false;
297 ix86_builtins_isa[(int) code].pure_p = false;
298 ix86_builtins_isa[(int) code].set_and_not_built_p = true;
302 return decl;
305 /* Like def_builtin, but also marks the function decl "const". */
307 static inline tree
308 def_builtin_const (HOST_WIDE_INT mask, HOST_WIDE_INT mask2, const char *name,
309 enum ix86_builtin_func_type tcode, enum ix86_builtins code)
311 tree decl = def_builtin (mask, mask2, name, tcode, code);
312 if (decl)
313 TREE_READONLY (decl) = 1;
314 else
315 ix86_builtins_isa[(int) code].const_p = true;
317 return decl;
320 /* Like def_builtin, but also marks the function decl "pure". */
322 static inline tree
323 def_builtin_pure (HOST_WIDE_INT mask, HOST_WIDE_INT mask2, const char *name,
324 enum ix86_builtin_func_type tcode, enum ix86_builtins code)
326 tree decl = def_builtin (mask, mask2, name, tcode, code);
327 if (decl)
328 DECL_PURE_P (decl) = 1;
329 else
330 ix86_builtins_isa[(int) code].pure_p = true;
332 return decl;
335 /* Add any new builtin functions for a given ISA that may not have been
336 declared. This saves a bit of space compared to adding all of the
337 declarations to the tree, even if we didn't use them. */
339 void
340 ix86_add_new_builtins (HOST_WIDE_INT isa, HOST_WIDE_INT isa2)
342 isa &= ~OPTION_MASK_ISA_64BIT;
344 if ((isa & deferred_isa_values) == 0
345 && (isa2 & deferred_isa_values2) == 0)
346 return;
348 /* Bits in ISA value can be removed from potential isa values. */
349 deferred_isa_values &= ~isa;
350 deferred_isa_values2 &= ~isa2;
352 int i;
353 tree saved_current_target_pragma = current_target_pragma;
354 current_target_pragma = NULL_TREE;
356 for (i = 0; i < (int)IX86_BUILTIN_MAX; i++)
358 if (((ix86_builtins_isa[i].isa & isa) != 0
359 || (ix86_builtins_isa[i].isa2 & isa2) != 0)
360 && ix86_builtins_isa[i].set_and_not_built_p)
362 tree decl, type;
364 /* Don't define the builtin again. */
365 ix86_builtins_isa[i].set_and_not_built_p = false;
367 type = ix86_get_builtin_func_type (ix86_builtins_isa[i].tcode);
368 decl = add_builtin_function_ext_scope (ix86_builtins_isa[i].name,
369 type, i, BUILT_IN_MD, NULL,
370 NULL_TREE);
372 ix86_builtins[i] = decl;
373 if (ix86_builtins_isa[i].const_p)
374 TREE_READONLY (decl) = 1;
378 current_target_pragma = saved_current_target_pragma;
381 /* TM vector builtins. */
383 /* Reuse the existing x86-specific `struct builtin_description' cause
384 we're lazy. Add casts to make them fit. */
385 static const struct builtin_description bdesc_tm[] =
387 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_WM64", (enum ix86_builtins) BUILT_IN_TM_STORE_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
388 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_WaRM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
389 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_WaWM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
390 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_RM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
391 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
392 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
393 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
395 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_WM128", (enum ix86_builtins) BUILT_IN_TM_STORE_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
396 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_WaRM128", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
397 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_WaWM128", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
398 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
399 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
400 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
401 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
403 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_WM256", (enum ix86_builtins) BUILT_IN_TM_STORE_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
404 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_WaRM256", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
405 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_WaWM256", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
406 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
407 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
408 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
409 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
411 { OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0, CODE_FOR_nothing, "__builtin__ITM_LM64", (enum ix86_builtins) BUILT_IN_TM_LOG_M64, UNKNOWN, VOID_FTYPE_PCVOID },
412 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_LM128", (enum ix86_builtins) BUILT_IN_TM_LOG_M128, UNKNOWN, VOID_FTYPE_PCVOID },
413 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_LM256", (enum ix86_builtins) BUILT_IN_TM_LOG_M256, UNKNOWN, VOID_FTYPE_PCVOID },
416 /* Initialize the transactional memory vector load/store builtins. */
418 static void
419 ix86_init_tm_builtins (void)
421 enum ix86_builtin_func_type ftype;
422 const struct builtin_description *d;
423 size_t i;
424 tree decl;
425 tree attrs_load, attrs_type_load, attrs_store, attrs_type_store;
426 tree attrs_log, attrs_type_log;
428 if (!flag_tm)
429 return;
431 /* If there are no builtins defined, we must be compiling in a
432 language without trans-mem support. */
433 if (!builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
434 return;
436 /* Use whatever attributes a normal TM load has. */
437 decl = builtin_decl_explicit (BUILT_IN_TM_LOAD_1);
438 attrs_load = DECL_ATTRIBUTES (decl);
439 attrs_type_load = TYPE_ATTRIBUTES (TREE_TYPE (decl));
440 /* Use whatever attributes a normal TM store has. */
441 decl = builtin_decl_explicit (BUILT_IN_TM_STORE_1);
442 attrs_store = DECL_ATTRIBUTES (decl);
443 attrs_type_store = TYPE_ATTRIBUTES (TREE_TYPE (decl));
444 /* Use whatever attributes a normal TM log has. */
445 decl = builtin_decl_explicit (BUILT_IN_TM_LOG);
446 attrs_log = DECL_ATTRIBUTES (decl);
447 attrs_type_log = TYPE_ATTRIBUTES (TREE_TYPE (decl));
449 for (i = 0, d = bdesc_tm;
450 i < ARRAY_SIZE (bdesc_tm);
451 i++, d++)
453 if ((d->mask & ix86_isa_flags) != 0
454 || (lang_hooks.builtin_function
455 == lang_hooks.builtin_function_ext_scope))
457 tree type, attrs, attrs_type;
458 enum built_in_function code = (enum built_in_function) d->code;
460 ftype = (enum ix86_builtin_func_type) d->flag;
461 type = ix86_get_builtin_func_type (ftype);
463 if (BUILTIN_TM_LOAD_P (code))
465 attrs = attrs_load;
466 attrs_type = attrs_type_load;
468 else if (BUILTIN_TM_STORE_P (code))
470 attrs = attrs_store;
471 attrs_type = attrs_type_store;
473 else
475 attrs = attrs_log;
476 attrs_type = attrs_type_log;
478 decl = add_builtin_function (d->name, type, code, BUILT_IN_NORMAL,
479 /* The builtin without the prefix for
480 calling it directly. */
481 d->name + strlen ("__builtin_"),
482 attrs);
483 /* add_builtin_function() will set the DECL_ATTRIBUTES, now
484 set the TYPE_ATTRIBUTES. */
485 decl_attributes (&TREE_TYPE (decl), attrs_type, ATTR_FLAG_BUILT_IN);
487 set_builtin_decl (code, decl, false);
492 /* Set up all the MMX/SSE builtins, even builtins for instructions that are not
493 in the current target ISA to allow the user to compile particular modules
494 with different target specific options that differ from the command line
495 options. */
496 static void
497 ix86_init_mmx_sse_builtins (void)
499 const struct builtin_description * d;
500 enum ix86_builtin_func_type ftype;
501 size_t i;
503 /* Add all special builtins with variable number of operands. */
504 for (i = 0, d = bdesc_special_args;
505 i < ARRAY_SIZE (bdesc_special_args);
506 i++, d++)
508 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST, i);
509 if (d->name == 0)
510 continue;
512 ftype = (enum ix86_builtin_func_type) d->flag;
513 def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
515 BDESC_VERIFYS (IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST,
516 IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST,
517 ARRAY_SIZE (bdesc_special_args) - 1);
519 /* Add all builtins with variable number of operands. */
520 for (i = 0, d = bdesc_args;
521 i < ARRAY_SIZE (bdesc_args);
522 i++, d++)
524 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_ARGS_FIRST, i);
525 if (d->name == 0)
526 continue;
528 ftype = (enum ix86_builtin_func_type) d->flag;
529 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
531 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ARGS_LAST,
532 IX86_BUILTIN__BDESC_ARGS_FIRST,
533 ARRAY_SIZE (bdesc_args) - 1);
535 /* Add all builtins with rounding. */
536 for (i = 0, d = bdesc_round_args;
537 i < ARRAY_SIZE (bdesc_round_args);
538 i++, d++)
540 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST, i);
541 if (d->name == 0)
542 continue;
544 ftype = (enum ix86_builtin_func_type) d->flag;
545 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
547 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ROUND_ARGS_LAST,
548 IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST,
549 ARRAY_SIZE (bdesc_round_args) - 1);
551 /* pcmpestr[im] insns. */
552 for (i = 0, d = bdesc_pcmpestr;
553 i < ARRAY_SIZE (bdesc_pcmpestr);
554 i++, d++)
556 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_PCMPESTR_FIRST, i);
557 if (d->code == IX86_BUILTIN_PCMPESTRM128)
558 ftype = V16QI_FTYPE_V16QI_INT_V16QI_INT_INT;
559 else
560 ftype = INT_FTYPE_V16QI_INT_V16QI_INT_INT;
561 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
563 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPESTR_LAST,
564 IX86_BUILTIN__BDESC_PCMPESTR_FIRST,
565 ARRAY_SIZE (bdesc_pcmpestr) - 1);
567 /* pcmpistr[im] insns. */
568 for (i = 0, d = bdesc_pcmpistr;
569 i < ARRAY_SIZE (bdesc_pcmpistr);
570 i++, d++)
572 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_PCMPISTR_FIRST, i);
573 if (d->code == IX86_BUILTIN_PCMPISTRM128)
574 ftype = V16QI_FTYPE_V16QI_V16QI_INT;
575 else
576 ftype = INT_FTYPE_V16QI_V16QI_INT;
577 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
579 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPISTR_LAST,
580 IX86_BUILTIN__BDESC_PCMPISTR_FIRST,
581 ARRAY_SIZE (bdesc_pcmpistr) - 1);
583 /* comi/ucomi insns. */
584 for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
586 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_COMI_FIRST, i);
587 if (d->mask == OPTION_MASK_ISA_SSE2)
588 ftype = INT_FTYPE_V2DF_V2DF;
589 else
590 ftype = INT_FTYPE_V4SF_V4SF;
591 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
593 BDESC_VERIFYS (IX86_BUILTIN__BDESC_COMI_LAST,
594 IX86_BUILTIN__BDESC_COMI_FIRST,
595 ARRAY_SIZE (bdesc_comi) - 1);
597 /* SSE */
598 def_builtin (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_ldmxcsr",
599 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
600 def_builtin_pure (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_stmxcsr",
601 UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
603 /* SSE or 3DNow!A */
604 def_builtin (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
605 /* As it uses V4HImode, we have to require -mmmx too. */
606 | OPTION_MASK_ISA_MMX, 0,
607 "__builtin_ia32_maskmovq", VOID_FTYPE_V8QI_V8QI_PCHAR,
608 IX86_BUILTIN_MASKMOVQ);
610 /* SSE2 */
611 def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_maskmovdqu",
612 VOID_FTYPE_V16QI_V16QI_PCHAR, IX86_BUILTIN_MASKMOVDQU);
614 def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_clflush",
615 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSH);
616 x86_mfence = def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_mfence",
617 VOID_FTYPE_VOID, IX86_BUILTIN_MFENCE);
619 /* SSE3. */
620 def_builtin (OPTION_MASK_ISA_SSE3, 0, "__builtin_ia32_monitor",
621 VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITOR);
622 def_builtin (OPTION_MASK_ISA_SSE3, 0, "__builtin_ia32_mwait",
623 VOID_FTYPE_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAIT);
625 /* AES */
626 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
627 "__builtin_ia32_aesenc128",
628 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENC128);
629 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
630 "__builtin_ia32_aesenclast128",
631 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENCLAST128);
632 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
633 "__builtin_ia32_aesdec128",
634 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDEC128);
635 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
636 "__builtin_ia32_aesdeclast128",
637 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDECLAST128);
638 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
639 "__builtin_ia32_aesimc128",
640 V2DI_FTYPE_V2DI, IX86_BUILTIN_AESIMC128);
641 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
642 "__builtin_ia32_aeskeygenassist128",
643 V2DI_FTYPE_V2DI_INT, IX86_BUILTIN_AESKEYGENASSIST128);
645 /* PCLMUL */
646 def_builtin_const (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2, 0,
647 "__builtin_ia32_pclmulqdq128",
648 V2DI_FTYPE_V2DI_V2DI_INT, IX86_BUILTIN_PCLMULQDQ128);
650 /* RDRND */
651 def_builtin (OPTION_MASK_ISA_RDRND, 0, "__builtin_ia32_rdrand16_step",
652 INT_FTYPE_PUSHORT, IX86_BUILTIN_RDRAND16_STEP);
653 def_builtin (OPTION_MASK_ISA_RDRND, 0, "__builtin_ia32_rdrand32_step",
654 INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDRAND32_STEP);
655 def_builtin (OPTION_MASK_ISA_RDRND | OPTION_MASK_ISA_64BIT, 0,
656 "__builtin_ia32_rdrand64_step", INT_FTYPE_PULONGLONG,
657 IX86_BUILTIN_RDRAND64_STEP);
659 /* AVX2 */
660 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv2df",
661 V2DF_FTYPE_V2DF_PCDOUBLE_V4SI_V2DF_INT,
662 IX86_BUILTIN_GATHERSIV2DF);
664 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4df",
665 V4DF_FTYPE_V4DF_PCDOUBLE_V4SI_V4DF_INT,
666 IX86_BUILTIN_GATHERSIV4DF);
668 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv2df",
669 V2DF_FTYPE_V2DF_PCDOUBLE_V2DI_V2DF_INT,
670 IX86_BUILTIN_GATHERDIV2DF);
672 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4df",
673 V4DF_FTYPE_V4DF_PCDOUBLE_V4DI_V4DF_INT,
674 IX86_BUILTIN_GATHERDIV4DF);
676 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4sf",
677 V4SF_FTYPE_V4SF_PCFLOAT_V4SI_V4SF_INT,
678 IX86_BUILTIN_GATHERSIV4SF);
680 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv8sf",
681 V8SF_FTYPE_V8SF_PCFLOAT_V8SI_V8SF_INT,
682 IX86_BUILTIN_GATHERSIV8SF);
684 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4sf",
685 V4SF_FTYPE_V4SF_PCFLOAT_V2DI_V4SF_INT,
686 IX86_BUILTIN_GATHERDIV4SF);
688 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4sf256",
689 V4SF_FTYPE_V4SF_PCFLOAT_V4DI_V4SF_INT,
690 IX86_BUILTIN_GATHERDIV8SF);
692 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv2di",
693 V2DI_FTYPE_V2DI_PCINT64_V4SI_V2DI_INT,
694 IX86_BUILTIN_GATHERSIV2DI);
696 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4di",
697 V4DI_FTYPE_V4DI_PCINT64_V4SI_V4DI_INT,
698 IX86_BUILTIN_GATHERSIV4DI);
700 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv2di",
701 V2DI_FTYPE_V2DI_PCINT64_V2DI_V2DI_INT,
702 IX86_BUILTIN_GATHERDIV2DI);
704 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4di",
705 V4DI_FTYPE_V4DI_PCINT64_V4DI_V4DI_INT,
706 IX86_BUILTIN_GATHERDIV4DI);
708 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4si",
709 V4SI_FTYPE_V4SI_PCINT_V4SI_V4SI_INT,
710 IX86_BUILTIN_GATHERSIV4SI);
712 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv8si",
713 V8SI_FTYPE_V8SI_PCINT_V8SI_V8SI_INT,
714 IX86_BUILTIN_GATHERSIV8SI);
716 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4si",
717 V4SI_FTYPE_V4SI_PCINT_V2DI_V4SI_INT,
718 IX86_BUILTIN_GATHERDIV4SI);
720 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4si256",
721 V4SI_FTYPE_V4SI_PCINT_V4DI_V4SI_INT,
722 IX86_BUILTIN_GATHERDIV8SI);
724 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltsiv4df ",
725 V4DF_FTYPE_V4DF_PCDOUBLE_V8SI_V4DF_INT,
726 IX86_BUILTIN_GATHERALTSIV4DF);
728 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltdiv8sf ",
729 V8SF_FTYPE_V8SF_PCFLOAT_V4DI_V8SF_INT,
730 IX86_BUILTIN_GATHERALTDIV8SF);
732 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltsiv4di ",
733 V4DI_FTYPE_V4DI_PCINT64_V8SI_V4DI_INT,
734 IX86_BUILTIN_GATHERALTSIV4DI);
736 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltdiv8si ",
737 V8SI_FTYPE_V8SI_PCINT_V4DI_V8SI_INT,
738 IX86_BUILTIN_GATHERALTDIV8SI);
740 /* AVX512F */
741 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gathersiv16sf",
742 V16SF_FTYPE_V16SF_PCVOID_V16SI_HI_INT,
743 IX86_BUILTIN_GATHER3SIV16SF);
745 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gathersiv8df",
746 V8DF_FTYPE_V8DF_PCVOID_V8SI_QI_INT,
747 IX86_BUILTIN_GATHER3SIV8DF);
749 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gatherdiv16sf",
750 V8SF_FTYPE_V8SF_PCVOID_V8DI_QI_INT,
751 IX86_BUILTIN_GATHER3DIV16SF);
753 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gatherdiv8df",
754 V8DF_FTYPE_V8DF_PCVOID_V8DI_QI_INT,
755 IX86_BUILTIN_GATHER3DIV8DF);
757 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gathersiv16si",
758 V16SI_FTYPE_V16SI_PCVOID_V16SI_HI_INT,
759 IX86_BUILTIN_GATHER3SIV16SI);
761 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gathersiv8di",
762 V8DI_FTYPE_V8DI_PCVOID_V8SI_QI_INT,
763 IX86_BUILTIN_GATHER3SIV8DI);
765 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gatherdiv16si",
766 V8SI_FTYPE_V8SI_PCVOID_V8DI_QI_INT,
767 IX86_BUILTIN_GATHER3DIV16SI);
769 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gatherdiv8di",
770 V8DI_FTYPE_V8DI_PCVOID_V8DI_QI_INT,
771 IX86_BUILTIN_GATHER3DIV8DI);
773 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gather3altsiv8df ",
774 V8DF_FTYPE_V8DF_PCDOUBLE_V16SI_QI_INT,
775 IX86_BUILTIN_GATHER3ALTSIV8DF);
777 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gather3altdiv16sf ",
778 V16SF_FTYPE_V16SF_PCFLOAT_V8DI_HI_INT,
779 IX86_BUILTIN_GATHER3ALTDIV16SF);
781 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gather3altsiv8di ",
782 V8DI_FTYPE_V8DI_PCINT64_V16SI_QI_INT,
783 IX86_BUILTIN_GATHER3ALTSIV8DI);
785 def_builtin_pure (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_gather3altdiv16si ",
786 V16SI_FTYPE_V16SI_PCINT_V8DI_HI_INT,
787 IX86_BUILTIN_GATHER3ALTDIV16SI);
789 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scattersiv16sf",
790 VOID_FTYPE_PVOID_HI_V16SI_V16SF_INT,
791 IX86_BUILTIN_SCATTERSIV16SF);
793 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scattersiv8df",
794 VOID_FTYPE_PVOID_QI_V8SI_V8DF_INT,
795 IX86_BUILTIN_SCATTERSIV8DF);
797 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatterdiv16sf",
798 VOID_FTYPE_PVOID_QI_V8DI_V8SF_INT,
799 IX86_BUILTIN_SCATTERDIV16SF);
801 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatterdiv8df",
802 VOID_FTYPE_PVOID_QI_V8DI_V8DF_INT,
803 IX86_BUILTIN_SCATTERDIV8DF);
805 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scattersiv16si",
806 VOID_FTYPE_PVOID_HI_V16SI_V16SI_INT,
807 IX86_BUILTIN_SCATTERSIV16SI);
809 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scattersiv8di",
810 VOID_FTYPE_PVOID_QI_V8SI_V8DI_INT,
811 IX86_BUILTIN_SCATTERSIV8DI);
813 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatterdiv16si",
814 VOID_FTYPE_PVOID_QI_V8DI_V8SI_INT,
815 IX86_BUILTIN_SCATTERDIV16SI);
817 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatterdiv8di",
818 VOID_FTYPE_PVOID_QI_V8DI_V8DI_INT,
819 IX86_BUILTIN_SCATTERDIV8DI);
821 /* AVX512VL */
822 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv2df",
823 V2DF_FTYPE_V2DF_PCVOID_V4SI_QI_INT,
824 IX86_BUILTIN_GATHER3SIV2DF);
826 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4df",
827 V4DF_FTYPE_V4DF_PCVOID_V4SI_QI_INT,
828 IX86_BUILTIN_GATHER3SIV4DF);
830 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div2df",
831 V2DF_FTYPE_V2DF_PCVOID_V2DI_QI_INT,
832 IX86_BUILTIN_GATHER3DIV2DF);
834 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4df",
835 V4DF_FTYPE_V4DF_PCVOID_V4DI_QI_INT,
836 IX86_BUILTIN_GATHER3DIV4DF);
838 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4sf",
839 V4SF_FTYPE_V4SF_PCVOID_V4SI_QI_INT,
840 IX86_BUILTIN_GATHER3SIV4SF);
842 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv8sf",
843 V8SF_FTYPE_V8SF_PCVOID_V8SI_QI_INT,
844 IX86_BUILTIN_GATHER3SIV8SF);
846 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4sf",
847 V4SF_FTYPE_V4SF_PCVOID_V2DI_QI_INT,
848 IX86_BUILTIN_GATHER3DIV4SF);
850 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div8sf",
851 V4SF_FTYPE_V4SF_PCVOID_V4DI_QI_INT,
852 IX86_BUILTIN_GATHER3DIV8SF);
854 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv2di",
855 V2DI_FTYPE_V2DI_PCVOID_V4SI_QI_INT,
856 IX86_BUILTIN_GATHER3SIV2DI);
858 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4di",
859 V4DI_FTYPE_V4DI_PCVOID_V4SI_QI_INT,
860 IX86_BUILTIN_GATHER3SIV4DI);
862 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div2di",
863 V2DI_FTYPE_V2DI_PCVOID_V2DI_QI_INT,
864 IX86_BUILTIN_GATHER3DIV2DI);
866 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4di",
867 V4DI_FTYPE_V4DI_PCVOID_V4DI_QI_INT,
868 IX86_BUILTIN_GATHER3DIV4DI);
870 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4si",
871 V4SI_FTYPE_V4SI_PCVOID_V4SI_QI_INT,
872 IX86_BUILTIN_GATHER3SIV4SI);
874 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv8si",
875 V8SI_FTYPE_V8SI_PCVOID_V8SI_QI_INT,
876 IX86_BUILTIN_GATHER3SIV8SI);
878 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4si",
879 V4SI_FTYPE_V4SI_PCVOID_V2DI_QI_INT,
880 IX86_BUILTIN_GATHER3DIV4SI);
882 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div8si",
883 V4SI_FTYPE_V4SI_PCVOID_V4DI_QI_INT,
884 IX86_BUILTIN_GATHER3DIV8SI);
886 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altsiv4df ",
887 V4DF_FTYPE_V4DF_PCDOUBLE_V8SI_QI_INT,
888 IX86_BUILTIN_GATHER3ALTSIV4DF);
890 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altdiv8sf ",
891 V8SF_FTYPE_V8SF_PCFLOAT_V4DI_QI_INT,
892 IX86_BUILTIN_GATHER3ALTDIV8SF);
894 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altsiv4di ",
895 V4DI_FTYPE_V4DI_PCINT64_V8SI_QI_INT,
896 IX86_BUILTIN_GATHER3ALTSIV4DI);
898 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altdiv8si ",
899 V8SI_FTYPE_V8SI_PCINT_V4DI_QI_INT,
900 IX86_BUILTIN_GATHER3ALTDIV8SI);
902 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv8sf",
903 VOID_FTYPE_PVOID_QI_V8SI_V8SF_INT,
904 IX86_BUILTIN_SCATTERSIV8SF);
906 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4sf",
907 VOID_FTYPE_PVOID_QI_V4SI_V4SF_INT,
908 IX86_BUILTIN_SCATTERSIV4SF);
910 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4df",
911 VOID_FTYPE_PVOID_QI_V4SI_V4DF_INT,
912 IX86_BUILTIN_SCATTERSIV4DF);
914 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv2df",
915 VOID_FTYPE_PVOID_QI_V4SI_V2DF_INT,
916 IX86_BUILTIN_SCATTERSIV2DF);
918 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv8sf",
919 VOID_FTYPE_PVOID_QI_V4DI_V4SF_INT,
920 IX86_BUILTIN_SCATTERDIV8SF);
922 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4sf",
923 VOID_FTYPE_PVOID_QI_V2DI_V4SF_INT,
924 IX86_BUILTIN_SCATTERDIV4SF);
926 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4df",
927 VOID_FTYPE_PVOID_QI_V4DI_V4DF_INT,
928 IX86_BUILTIN_SCATTERDIV4DF);
930 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv2df",
931 VOID_FTYPE_PVOID_QI_V2DI_V2DF_INT,
932 IX86_BUILTIN_SCATTERDIV2DF);
934 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv8si",
935 VOID_FTYPE_PVOID_QI_V8SI_V8SI_INT,
936 IX86_BUILTIN_SCATTERSIV8SI);
938 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4si",
939 VOID_FTYPE_PVOID_QI_V4SI_V4SI_INT,
940 IX86_BUILTIN_SCATTERSIV4SI);
942 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4di",
943 VOID_FTYPE_PVOID_QI_V4SI_V4DI_INT,
944 IX86_BUILTIN_SCATTERSIV4DI);
946 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv2di",
947 VOID_FTYPE_PVOID_QI_V4SI_V2DI_INT,
948 IX86_BUILTIN_SCATTERSIV2DI);
950 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv8si",
951 VOID_FTYPE_PVOID_QI_V4DI_V4SI_INT,
952 IX86_BUILTIN_SCATTERDIV8SI);
954 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4si",
955 VOID_FTYPE_PVOID_QI_V2DI_V4SI_INT,
956 IX86_BUILTIN_SCATTERDIV4SI);
958 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4di",
959 VOID_FTYPE_PVOID_QI_V4DI_V4DI_INT,
960 IX86_BUILTIN_SCATTERDIV4DI);
962 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv2di",
963 VOID_FTYPE_PVOID_QI_V2DI_V2DI_INT,
964 IX86_BUILTIN_SCATTERDIV2DI);
966 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatteraltsiv8df ",
967 VOID_FTYPE_PDOUBLE_QI_V16SI_V8DF_INT,
968 IX86_BUILTIN_SCATTERALTSIV8DF);
970 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatteraltdiv16sf ",
971 VOID_FTYPE_PFLOAT_HI_V8DI_V16SF_INT,
972 IX86_BUILTIN_SCATTERALTDIV16SF);
974 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatteraltsiv8di ",
975 VOID_FTYPE_PLONGLONG_QI_V16SI_V8DI_INT,
976 IX86_BUILTIN_SCATTERALTSIV8DI);
978 def_builtin (OPTION_MASK_ISA_AVX512F, 0, "__builtin_ia32_scatteraltdiv16si ",
979 VOID_FTYPE_PINT_HI_V8DI_V16SI_INT,
980 IX86_BUILTIN_SCATTERALTDIV16SI);
982 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv4df ",
983 VOID_FTYPE_PDOUBLE_QI_V8SI_V4DF_INT,
984 IX86_BUILTIN_SCATTERALTSIV4DF);
986 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv8sf ",
987 VOID_FTYPE_PFLOAT_QI_V4DI_V8SF_INT,
988 IX86_BUILTIN_SCATTERALTDIV8SF);
990 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv4di ",
991 VOID_FTYPE_PLONGLONG_QI_V8SI_V4DI_INT,
992 IX86_BUILTIN_SCATTERALTSIV4DI);
994 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv8si ",
995 VOID_FTYPE_PINT_QI_V4DI_V8SI_INT,
996 IX86_BUILTIN_SCATTERALTDIV8SI);
998 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv2df ",
999 VOID_FTYPE_PDOUBLE_QI_V4SI_V2DF_INT,
1000 IX86_BUILTIN_SCATTERALTSIV2DF);
1002 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv4sf ",
1003 VOID_FTYPE_PFLOAT_QI_V2DI_V4SF_INT,
1004 IX86_BUILTIN_SCATTERALTDIV4SF);
1006 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv2di ",
1007 VOID_FTYPE_PLONGLONG_QI_V4SI_V2DI_INT,
1008 IX86_BUILTIN_SCATTERALTSIV2DI);
1010 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv4si ",
1011 VOID_FTYPE_PINT_QI_V2DI_V4SI_INT,
1012 IX86_BUILTIN_SCATTERALTDIV4SI);
1014 /* AVX512PF */
1015 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_gatherpfdpd",
1016 VOID_FTYPE_QI_V8SI_PCVOID_INT_INT,
1017 IX86_BUILTIN_GATHERPFDPD);
1018 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_gatherpfdps",
1019 VOID_FTYPE_HI_V16SI_PCVOID_INT_INT,
1020 IX86_BUILTIN_GATHERPFDPS);
1021 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_gatherpfqpd",
1022 VOID_FTYPE_QI_V8DI_PCVOID_INT_INT,
1023 IX86_BUILTIN_GATHERPFQPD);
1024 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_gatherpfqps",
1025 VOID_FTYPE_QI_V8DI_PCVOID_INT_INT,
1026 IX86_BUILTIN_GATHERPFQPS);
1027 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_scatterpfdpd",
1028 VOID_FTYPE_QI_V8SI_PCVOID_INT_INT,
1029 IX86_BUILTIN_SCATTERPFDPD);
1030 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_scatterpfdps",
1031 VOID_FTYPE_HI_V16SI_PCVOID_INT_INT,
1032 IX86_BUILTIN_SCATTERPFDPS);
1033 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_scatterpfqpd",
1034 VOID_FTYPE_QI_V8DI_PCVOID_INT_INT,
1035 IX86_BUILTIN_SCATTERPFQPD);
1036 def_builtin (OPTION_MASK_ISA_AVX512PF, 0, "__builtin_ia32_scatterpfqps",
1037 VOID_FTYPE_QI_V8DI_PCVOID_INT_INT,
1038 IX86_BUILTIN_SCATTERPFQPS);
1040 /* SHA */
1041 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1msg1",
1042 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1MSG1);
1043 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1msg2",
1044 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1MSG2);
1045 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1nexte",
1046 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1NEXTE);
1047 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1rnds4",
1048 V4SI_FTYPE_V4SI_V4SI_INT, IX86_BUILTIN_SHA1RNDS4);
1049 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256msg1",
1050 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA256MSG1);
1051 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256msg2",
1052 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA256MSG2);
1053 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256rnds2",
1054 V4SI_FTYPE_V4SI_V4SI_V4SI, IX86_BUILTIN_SHA256RNDS2);
1056 /* RTM. */
1057 def_builtin (OPTION_MASK_ISA_RTM, 0, "__builtin_ia32_xabort",
1058 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_XABORT);
1060 /* MMX access to the vec_init patterns. */
1061 def_builtin_const (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0,
1062 "__builtin_ia32_vec_init_v2si",
1063 V2SI_FTYPE_INT_INT, IX86_BUILTIN_VEC_INIT_V2SI);
1065 def_builtin_const (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0,
1066 "__builtin_ia32_vec_init_v4hi",
1067 V4HI_FTYPE_HI_HI_HI_HI,
1068 IX86_BUILTIN_VEC_INIT_V4HI);
1070 def_builtin_const (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0,
1071 "__builtin_ia32_vec_init_v8qi",
1072 V8QI_FTYPE_QI_QI_QI_QI_QI_QI_QI_QI,
1073 IX86_BUILTIN_VEC_INIT_V8QI);
1075 /* Access to the vec_extract patterns. */
1076 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v2df",
1077 DOUBLE_FTYPE_V2DF_INT, IX86_BUILTIN_VEC_EXT_V2DF);
1078 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v2di",
1079 DI_FTYPE_V2DI_INT, IX86_BUILTIN_VEC_EXT_V2DI);
1080 def_builtin_const (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_vec_ext_v4sf",
1081 FLOAT_FTYPE_V4SF_INT, IX86_BUILTIN_VEC_EXT_V4SF);
1082 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v4si",
1083 SI_FTYPE_V4SI_INT, IX86_BUILTIN_VEC_EXT_V4SI);
1084 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v8hi",
1085 HI_FTYPE_V8HI_INT, IX86_BUILTIN_VEC_EXT_V8HI);
1087 def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
1088 /* As it uses V4HImode, we have to require -mmmx too. */
1089 | OPTION_MASK_ISA_MMX, 0,
1090 "__builtin_ia32_vec_ext_v4hi",
1091 HI_FTYPE_V4HI_INT, IX86_BUILTIN_VEC_EXT_V4HI);
1093 def_builtin_const (OPTION_MASK_ISA_MMX | OPTION_MASK_ISA_SSE2, 0,
1094 "__builtin_ia32_vec_ext_v2si",
1095 SI_FTYPE_V2SI_INT, IX86_BUILTIN_VEC_EXT_V2SI);
1097 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v16qi",
1098 QI_FTYPE_V16QI_INT, IX86_BUILTIN_VEC_EXT_V16QI);
1100 /* Access to the vec_set patterns. */
1101 def_builtin_const (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_64BIT, 0,
1102 "__builtin_ia32_vec_set_v2di",
1103 V2DI_FTYPE_V2DI_DI_INT, IX86_BUILTIN_VEC_SET_V2DI);
1105 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v4sf",
1106 V4SF_FTYPE_V4SF_FLOAT_INT, IX86_BUILTIN_VEC_SET_V4SF);
1108 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v4si",
1109 V4SI_FTYPE_V4SI_SI_INT, IX86_BUILTIN_VEC_SET_V4SI);
1111 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_set_v8hi",
1112 V8HI_FTYPE_V8HI_HI_INT, IX86_BUILTIN_VEC_SET_V8HI);
1114 def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
1115 /* As it uses V4HImode, we have to require -mmmx too. */
1116 | OPTION_MASK_ISA_MMX, 0,
1117 "__builtin_ia32_vec_set_v4hi",
1118 V4HI_FTYPE_V4HI_HI_INT, IX86_BUILTIN_VEC_SET_V4HI);
1120 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v16qi",
1121 V16QI_FTYPE_V16QI_QI_INT, IX86_BUILTIN_VEC_SET_V16QI);
1123 /* RDSEED */
1124 def_builtin (OPTION_MASK_ISA_RDSEED, 0, "__builtin_ia32_rdseed_hi_step",
1125 INT_FTYPE_PUSHORT, IX86_BUILTIN_RDSEED16_STEP);
1126 def_builtin (OPTION_MASK_ISA_RDSEED, 0, "__builtin_ia32_rdseed_si_step",
1127 INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDSEED32_STEP);
1128 def_builtin (OPTION_MASK_ISA_RDSEED | OPTION_MASK_ISA_64BIT, 0,
1129 "__builtin_ia32_rdseed_di_step",
1130 INT_FTYPE_PULONGLONG, IX86_BUILTIN_RDSEED64_STEP);
1132 /* ADCX */
1133 def_builtin (0, 0, "__builtin_ia32_addcarryx_u32",
1134 UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_ADDCARRYX32);
1135 def_builtin (OPTION_MASK_ISA_64BIT, 0,
1136 "__builtin_ia32_addcarryx_u64",
1137 UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
1138 IX86_BUILTIN_ADDCARRYX64);
1140 /* SBB */
1141 def_builtin (0, 0, "__builtin_ia32_sbb_u32",
1142 UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_SBB32);
1143 def_builtin (OPTION_MASK_ISA_64BIT, 0,
1144 "__builtin_ia32_sbb_u64",
1145 UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
1146 IX86_BUILTIN_SBB64);
1148 /* Read/write FLAGS. */
1149 if (TARGET_64BIT)
1151 def_builtin (OPTION_MASK_ISA_64BIT, 0, "__builtin_ia32_readeflags_u64",
1152 UINT64_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
1153 def_builtin (OPTION_MASK_ISA_64BIT, 0, "__builtin_ia32_writeeflags_u64",
1154 VOID_FTYPE_UINT64, IX86_BUILTIN_WRITE_FLAGS);
1156 else
1158 def_builtin (0, 0, "__builtin_ia32_readeflags_u32",
1159 UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
1160 def_builtin (0, 0, "__builtin_ia32_writeeflags_u32",
1161 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_WRITE_FLAGS);
1164 /* CLFLUSHOPT. */
1165 def_builtin (OPTION_MASK_ISA_CLFLUSHOPT, 0, "__builtin_ia32_clflushopt",
1166 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSHOPT);
1168 /* CLWB. */
1169 def_builtin (OPTION_MASK_ISA_CLWB, 0, "__builtin_ia32_clwb",
1170 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLWB);
1172 /* MONITORX and MWAITX. */
1173 def_builtin (0, OPTION_MASK_ISA_MWAITX, "__builtin_ia32_monitorx",
1174 VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITORX);
1175 def_builtin (0, OPTION_MASK_ISA_MWAITX, "__builtin_ia32_mwaitx",
1176 VOID_FTYPE_UNSIGNED_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAITX);
1178 /* CLZERO. */
1179 def_builtin (0, OPTION_MASK_ISA_CLZERO, "__builtin_ia32_clzero",
1180 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLZERO);
1182 /* WAITPKG. */
1183 def_builtin (0, OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_umonitor",
1184 VOID_FTYPE_PVOID, IX86_BUILTIN_UMONITOR);
1185 def_builtin (0, OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_umwait",
1186 UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_UMWAIT);
1187 def_builtin (0, OPTION_MASK_ISA_WAITPKG, "__builtin_ia32_tpause",
1188 UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_TPAUSE);
1190 /* CLDEMOTE. */
1191 def_builtin (0, OPTION_MASK_ISA_CLDEMOTE, "__builtin_ia32_cldemote",
1192 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLDEMOTE);
1194 /* Add FMA4 multi-arg argument instructions */
1195 for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
1197 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_MULTI_ARG_FIRST, i);
1198 if (d->name == 0)
1199 continue;
1201 ftype = (enum ix86_builtin_func_type) d->flag;
1202 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
1204 BDESC_VERIFYS (IX86_BUILTIN__BDESC_MULTI_ARG_LAST,
1205 IX86_BUILTIN__BDESC_MULTI_ARG_FIRST,
1206 ARRAY_SIZE (bdesc_multi_arg) - 1);
1208 /* Add CET inrinsics. */
1209 for (i = 0, d = bdesc_cet; i < ARRAY_SIZE (bdesc_cet); i++, d++)
1211 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_CET_FIRST, i);
1212 if (d->name == 0)
1213 continue;
1215 ftype = (enum ix86_builtin_func_type) d->flag;
1216 def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
1218 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_LAST,
1219 IX86_BUILTIN__BDESC_CET_FIRST,
1220 ARRAY_SIZE (bdesc_cet) - 1);
1222 for (i = 0, d = bdesc_cet_rdssp;
1223 i < ARRAY_SIZE (bdesc_cet_rdssp);
1224 i++, d++)
1226 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_CET_NORMAL_FIRST, i);
1227 if (d->name == 0)
1228 continue;
1230 ftype = (enum ix86_builtin_func_type) d->flag;
1231 def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
1233 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_NORMAL_LAST,
1234 IX86_BUILTIN__BDESC_CET_NORMAL_FIRST,
1235 ARRAY_SIZE (bdesc_cet_rdssp) - 1);
1238 #undef BDESC_VERIFY
1239 #undef BDESC_VERIFYS
1241 /* Make builtins to detect cpu type and features supported. NAME is
1242 the builtin name, CODE is the builtin code, and FTYPE is the function
1243 type of the builtin. */
1245 static void
1246 make_cpu_type_builtin (const char* name, int code,
1247 enum ix86_builtin_func_type ftype, bool is_const)
1249 tree decl;
1250 tree type;
1252 type = ix86_get_builtin_func_type (ftype);
1253 decl = add_builtin_function (name, type, code, BUILT_IN_MD,
1254 NULL, NULL_TREE);
1255 gcc_assert (decl != NULL_TREE);
1256 ix86_builtins[(int) code] = decl;
1257 TREE_READONLY (decl) = is_const;
1260 /* Make builtins to get CPU type and features supported. The created
1261 builtins are :
1263 __builtin_cpu_init (), to detect cpu type and features,
1264 __builtin_cpu_is ("<CPUNAME>"), to check if cpu is of type <CPUNAME>,
1265 __builtin_cpu_supports ("<FEATURE>"), to check if cpu supports <FEATURE>
1268 static void
1269 ix86_init_platform_type_builtins (void)
1271 make_cpu_type_builtin ("__builtin_cpu_init", IX86_BUILTIN_CPU_INIT,
1272 INT_FTYPE_VOID, false);
1273 make_cpu_type_builtin ("__builtin_cpu_is", IX86_BUILTIN_CPU_IS,
1274 INT_FTYPE_PCCHAR, true);
1275 make_cpu_type_builtin ("__builtin_cpu_supports", IX86_BUILTIN_CPU_SUPPORTS,
1276 INT_FTYPE_PCCHAR, true);
1279 /* Internal method for ix86_init_builtins. */
1281 static void
1282 ix86_init_builtins_va_builtins_abi (void)
1284 tree ms_va_ref, sysv_va_ref;
1285 tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
1286 tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
1287 tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
1288 tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
1290 if (!TARGET_64BIT)
1291 return;
1292 fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
1293 fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
1294 ms_va_ref = build_reference_type (ms_va_list_type_node);
1295 sysv_va_ref = build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
1297 fnvoid_va_end_ms = build_function_type_list (void_type_node, ms_va_ref,
1298 NULL_TREE);
1299 fnvoid_va_start_ms
1300 = build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
1301 fnvoid_va_end_sysv
1302 = build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
1303 fnvoid_va_start_sysv
1304 = build_varargs_function_type_list (void_type_node, sysv_va_ref,
1305 NULL_TREE);
1306 fnvoid_va_copy_ms
1307 = build_function_type_list (void_type_node, ms_va_ref,
1308 ms_va_list_type_node, NULL_TREE);
1309 fnvoid_va_copy_sysv
1310 = build_function_type_list (void_type_node, sysv_va_ref,
1311 sysv_va_ref, NULL_TREE);
1313 add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
1314 BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
1315 add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
1316 BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
1317 add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
1318 BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
1319 add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
1320 BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1321 add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
1322 BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1323 add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
1324 BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1327 static void
1328 ix86_init_builtin_types (void)
1330 tree float80_type_node, const_string_type_node;
1332 /* The __float80 type. */
1333 float80_type_node = long_double_type_node;
1334 if (TYPE_MODE (float80_type_node) != XFmode)
1336 if (float64x_type_node != NULL_TREE
1337 && TYPE_MODE (float64x_type_node) == XFmode)
1338 float80_type_node = float64x_type_node;
1339 else
1341 /* The __float80 type. */
1342 float80_type_node = make_node (REAL_TYPE);
1344 TYPE_PRECISION (float80_type_node) = 80;
1345 layout_type (float80_type_node);
1348 lang_hooks.types.register_builtin_type (float80_type_node, "__float80");
1350 /* The __float128 type. The node has already been created as
1351 _Float128, so we only need to register the __float128 name for
1352 it. */
1353 lang_hooks.types.register_builtin_type (float128_type_node, "__float128");
1355 const_string_type_node
1356 = build_pointer_type (build_qualified_type
1357 (char_type_node, TYPE_QUAL_CONST));
1359 /* This macro is built by i386-builtin-types.awk. */
1360 DEFINE_BUILTIN_PRIMITIVE_TYPES;
1363 void
1364 ix86_init_builtins (void)
1366 tree ftype, decl;
1368 ix86_init_builtin_types ();
1370 /* Builtins to get CPU type and features. */
1371 ix86_init_platform_type_builtins ();
1373 /* TFmode support builtins. */
1374 def_builtin_const (0, 0, "__builtin_infq",
1375 FLOAT128_FTYPE_VOID, IX86_BUILTIN_INFQ);
1376 def_builtin_const (0, 0, "__builtin_huge_valq",
1377 FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ);
1379 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING);
1380 decl = add_builtin_function ("__builtin_nanq", ftype, IX86_BUILTIN_NANQ,
1381 BUILT_IN_MD, "nanq", NULL_TREE);
1382 TREE_READONLY (decl) = 1;
1383 ix86_builtins[(int) IX86_BUILTIN_NANQ] = decl;
1385 decl = add_builtin_function ("__builtin_nansq", ftype, IX86_BUILTIN_NANSQ,
1386 BUILT_IN_MD, "nansq", NULL_TREE);
1387 TREE_READONLY (decl) = 1;
1388 ix86_builtins[(int) IX86_BUILTIN_NANSQ] = decl;
1390 /* We will expand them to normal call if SSE isn't available since
1391 they are used by libgcc. */
1392 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128);
1393 decl = add_builtin_function ("__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ,
1394 BUILT_IN_MD, "__fabstf2", NULL_TREE);
1395 TREE_READONLY (decl) = 1;
1396 ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
1398 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128_FLOAT128);
1399 decl = add_builtin_function ("__builtin_copysignq", ftype,
1400 IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
1401 "__copysigntf3", NULL_TREE);
1402 TREE_READONLY (decl) = 1;
1403 ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
1405 ix86_init_tm_builtins ();
1406 ix86_init_mmx_sse_builtins ();
1408 if (TARGET_LP64)
1409 ix86_init_builtins_va_builtins_abi ();
1411 #ifdef SUBTARGET_INIT_BUILTINS
1412 SUBTARGET_INIT_BUILTINS;
1413 #endif
1416 /* Return the ix86 builtin for CODE. */
1418 tree
1419 ix86_builtin_decl (unsigned code, bool)
1421 if (code >= IX86_BUILTIN_MAX)
1422 return error_mark_node;
1424 return ix86_builtins[code];
1427 /* This returns the target-specific builtin with code CODE if
1428 current_function_decl has visibility on this builtin, which is checked
1429 using isa flags. Returns NULL_TREE otherwise. */
1431 static tree ix86_get_builtin (enum ix86_builtins code)
1433 struct cl_target_option *opts;
1434 tree target_tree = NULL_TREE;
1436 /* Determine the isa flags of current_function_decl. */
1438 if (current_function_decl)
1439 target_tree = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl);
1441 if (target_tree == NULL)
1442 target_tree = target_option_default_node;
1444 opts = TREE_TARGET_OPTION (target_tree);
1446 if ((ix86_builtins_isa[(int) code].isa & opts->x_ix86_isa_flags)
1447 || (ix86_builtins_isa[(int) code].isa2 & opts->x_ix86_isa_flags2))
1448 return ix86_builtin_decl (code, true);
1449 else
1450 return NULL_TREE;
1453 /* Vectorization library interface and handlers. */
1454 tree (*ix86_veclib_handler) (combined_fn, tree, tree);
1456 /* Returns a function decl for a vectorized version of the combined function
1457 with combined_fn code FN and the result vector type TYPE, or NULL_TREE
1458 if it is not available. */
1460 tree
1461 ix86_builtin_vectorized_function (unsigned int fn, tree type_out,
1462 tree type_in)
1464 machine_mode in_mode, out_mode;
1465 int in_n, out_n;
1467 if (TREE_CODE (type_out) != VECTOR_TYPE
1468 || TREE_CODE (type_in) != VECTOR_TYPE)
1469 return NULL_TREE;
1471 out_mode = TYPE_MODE (TREE_TYPE (type_out));
1472 out_n = TYPE_VECTOR_SUBPARTS (type_out);
1473 in_mode = TYPE_MODE (TREE_TYPE (type_in));
1474 in_n = TYPE_VECTOR_SUBPARTS (type_in);
1476 switch (fn)
1478 CASE_CFN_EXP2:
1479 if (out_mode == SFmode && in_mode == SFmode)
1481 if (out_n == 16 && in_n == 16)
1482 return ix86_get_builtin (IX86_BUILTIN_EXP2PS);
1484 break;
1486 CASE_CFN_IFLOOR:
1487 CASE_CFN_LFLOOR:
1488 CASE_CFN_LLFLOOR:
1489 /* The round insn does not trap on denormals. */
1490 if (flag_trapping_math || !TARGET_SSE4_1)
1491 break;
1493 if (out_mode == SImode && in_mode == DFmode)
1495 if (out_n == 4 && in_n == 2)
1496 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX);
1497 else if (out_n == 8 && in_n == 4)
1498 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX256);
1499 else if (out_n == 16 && in_n == 8)
1500 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512);
1502 if (out_mode == SImode && in_mode == SFmode)
1504 if (out_n == 4 && in_n == 4)
1505 return ix86_get_builtin (IX86_BUILTIN_FLOORPS_SFIX);
1506 else if (out_n == 8 && in_n == 8)
1507 return ix86_get_builtin (IX86_BUILTIN_FLOORPS_SFIX256);
1508 else if (out_n == 16 && in_n == 16)
1509 return ix86_get_builtin (IX86_BUILTIN_FLOORPS_SFIX512);
1511 break;
1513 CASE_CFN_ICEIL:
1514 CASE_CFN_LCEIL:
1515 CASE_CFN_LLCEIL:
1516 /* The round insn does not trap on denormals. */
1517 if (flag_trapping_math || !TARGET_SSE4_1)
1518 break;
1520 if (out_mode == SImode && in_mode == DFmode)
1522 if (out_n == 4 && in_n == 2)
1523 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX);
1524 else if (out_n == 8 && in_n == 4)
1525 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX256);
1526 else if (out_n == 16 && in_n == 8)
1527 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512);
1529 if (out_mode == SImode && in_mode == SFmode)
1531 if (out_n == 4 && in_n == 4)
1532 return ix86_get_builtin (IX86_BUILTIN_CEILPS_SFIX);
1533 else if (out_n == 8 && in_n == 8)
1534 return ix86_get_builtin (IX86_BUILTIN_CEILPS_SFIX256);
1535 else if (out_n == 16 && in_n == 16)
1536 return ix86_get_builtin (IX86_BUILTIN_CEILPS_SFIX512);
1538 break;
1540 CASE_CFN_IRINT:
1541 CASE_CFN_LRINT:
1542 CASE_CFN_LLRINT:
1543 if (out_mode == SImode && in_mode == DFmode)
1545 if (out_n == 4 && in_n == 2)
1546 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX);
1547 else if (out_n == 8 && in_n == 4)
1548 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX256);
1549 else if (out_n == 16 && in_n == 8)
1550 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX512);
1552 if (out_mode == SImode && in_mode == SFmode)
1554 if (out_n == 4 && in_n == 4)
1555 return ix86_get_builtin (IX86_BUILTIN_CVTPS2DQ);
1556 else if (out_n == 8 && in_n == 8)
1557 return ix86_get_builtin (IX86_BUILTIN_CVTPS2DQ256);
1558 else if (out_n == 16 && in_n == 16)
1559 return ix86_get_builtin (IX86_BUILTIN_CVTPS2DQ512);
1561 break;
1563 CASE_CFN_IROUND:
1564 CASE_CFN_LROUND:
1565 CASE_CFN_LLROUND:
1566 /* The round insn does not trap on denormals. */
1567 if (flag_trapping_math || !TARGET_SSE4_1)
1568 break;
1570 if (out_mode == SImode && in_mode == DFmode)
1572 if (out_n == 4 && in_n == 2)
1573 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX);
1574 else if (out_n == 8 && in_n == 4)
1575 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX256);
1576 else if (out_n == 16 && in_n == 8)
1577 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX512);
1579 if (out_mode == SImode && in_mode == SFmode)
1581 if (out_n == 4 && in_n == 4)
1582 return ix86_get_builtin (IX86_BUILTIN_ROUNDPS_AZ_SFIX);
1583 else if (out_n == 8 && in_n == 8)
1584 return ix86_get_builtin (IX86_BUILTIN_ROUNDPS_AZ_SFIX256);
1585 else if (out_n == 16 && in_n == 16)
1586 return ix86_get_builtin (IX86_BUILTIN_ROUNDPS_AZ_SFIX512);
1588 break;
1590 CASE_CFN_FLOOR:
1591 /* The round insn does not trap on denormals. */
1592 if (flag_trapping_math || !TARGET_SSE4_1)
1593 break;
1595 if (out_mode == DFmode && in_mode == DFmode)
1597 if (out_n == 2 && in_n == 2)
1598 return ix86_get_builtin (IX86_BUILTIN_FLOORPD);
1599 else if (out_n == 4 && in_n == 4)
1600 return ix86_get_builtin (IX86_BUILTIN_FLOORPD256);
1601 else if (out_n == 8 && in_n == 8)
1602 return ix86_get_builtin (IX86_BUILTIN_FLOORPD512);
1604 if (out_mode == SFmode && in_mode == SFmode)
1606 if (out_n == 4 && in_n == 4)
1607 return ix86_get_builtin (IX86_BUILTIN_FLOORPS);
1608 else if (out_n == 8 && in_n == 8)
1609 return ix86_get_builtin (IX86_BUILTIN_FLOORPS256);
1610 else if (out_n == 16 && in_n == 16)
1611 return ix86_get_builtin (IX86_BUILTIN_FLOORPS512);
1613 break;
1615 CASE_CFN_CEIL:
1616 /* The round insn does not trap on denormals. */
1617 if (flag_trapping_math || !TARGET_SSE4_1)
1618 break;
1620 if (out_mode == DFmode && in_mode == DFmode)
1622 if (out_n == 2 && in_n == 2)
1623 return ix86_get_builtin (IX86_BUILTIN_CEILPD);
1624 else if (out_n == 4 && in_n == 4)
1625 return ix86_get_builtin (IX86_BUILTIN_CEILPD256);
1626 else if (out_n == 8 && in_n == 8)
1627 return ix86_get_builtin (IX86_BUILTIN_CEILPD512);
1629 if (out_mode == SFmode && in_mode == SFmode)
1631 if (out_n == 4 && in_n == 4)
1632 return ix86_get_builtin (IX86_BUILTIN_CEILPS);
1633 else if (out_n == 8 && in_n == 8)
1634 return ix86_get_builtin (IX86_BUILTIN_CEILPS256);
1635 else if (out_n == 16 && in_n == 16)
1636 return ix86_get_builtin (IX86_BUILTIN_CEILPS512);
1638 break;
1640 CASE_CFN_TRUNC:
1641 /* The round insn does not trap on denormals. */
1642 if (flag_trapping_math || !TARGET_SSE4_1)
1643 break;
1645 if (out_mode == DFmode && in_mode == DFmode)
1647 if (out_n == 2 && in_n == 2)
1648 return ix86_get_builtin (IX86_BUILTIN_TRUNCPD);
1649 else if (out_n == 4 && in_n == 4)
1650 return ix86_get_builtin (IX86_BUILTIN_TRUNCPD256);
1651 else if (out_n == 8 && in_n == 8)
1652 return ix86_get_builtin (IX86_BUILTIN_TRUNCPD512);
1654 if (out_mode == SFmode && in_mode == SFmode)
1656 if (out_n == 4 && in_n == 4)
1657 return ix86_get_builtin (IX86_BUILTIN_TRUNCPS);
1658 else if (out_n == 8 && in_n == 8)
1659 return ix86_get_builtin (IX86_BUILTIN_TRUNCPS256);
1660 else if (out_n == 16 && in_n == 16)
1661 return ix86_get_builtin (IX86_BUILTIN_TRUNCPS512);
1663 break;
1665 CASE_CFN_RINT:
1666 /* The round insn does not trap on denormals. */
1667 if (flag_trapping_math || !TARGET_SSE4_1)
1668 break;
1670 if (out_mode == DFmode && in_mode == DFmode)
1672 if (out_n == 2 && in_n == 2)
1673 return ix86_get_builtin (IX86_BUILTIN_RINTPD);
1674 else if (out_n == 4 && in_n == 4)
1675 return ix86_get_builtin (IX86_BUILTIN_RINTPD256);
1677 if (out_mode == SFmode && in_mode == SFmode)
1679 if (out_n == 4 && in_n == 4)
1680 return ix86_get_builtin (IX86_BUILTIN_RINTPS);
1681 else if (out_n == 8 && in_n == 8)
1682 return ix86_get_builtin (IX86_BUILTIN_RINTPS256);
1684 break;
1686 CASE_CFN_FMA:
1687 if (out_mode == DFmode && in_mode == DFmode)
1689 if (out_n == 2 && in_n == 2)
1690 return ix86_get_builtin (IX86_BUILTIN_VFMADDPD);
1691 if (out_n == 4 && in_n == 4)
1692 return ix86_get_builtin (IX86_BUILTIN_VFMADDPD256);
1694 if (out_mode == SFmode && in_mode == SFmode)
1696 if (out_n == 4 && in_n == 4)
1697 return ix86_get_builtin (IX86_BUILTIN_VFMADDPS);
1698 if (out_n == 8 && in_n == 8)
1699 return ix86_get_builtin (IX86_BUILTIN_VFMADDPS256);
1701 break;
1703 default:
1704 break;
1707 /* Dispatch to a handler for a vectorization library. */
1708 if (ix86_veclib_handler)
1709 return ix86_veclib_handler (combined_fn (fn), type_out, type_in);
1711 return NULL_TREE;
1714 /* Returns a decl of a function that implements gather load with
1715 memory type MEM_VECTYPE and index type INDEX_VECTYPE and SCALE.
1716 Return NULL_TREE if it is not available. */
1718 tree
1719 ix86_vectorize_builtin_gather (const_tree mem_vectype,
1720 const_tree index_type, int scale)
1722 bool si;
1723 enum ix86_builtins code;
1725 if (! TARGET_AVX2 || !TARGET_USE_GATHER)
1726 return NULL_TREE;
1728 if ((TREE_CODE (index_type) != INTEGER_TYPE
1729 && !POINTER_TYPE_P (index_type))
1730 || (TYPE_MODE (index_type) != SImode
1731 && TYPE_MODE (index_type) != DImode))
1732 return NULL_TREE;
1734 if (TYPE_PRECISION (index_type) > POINTER_SIZE)
1735 return NULL_TREE;
1737 /* v*gather* insn sign extends index to pointer mode. */
1738 if (TYPE_PRECISION (index_type) < POINTER_SIZE
1739 && TYPE_UNSIGNED (index_type))
1740 return NULL_TREE;
1742 if (scale <= 0
1743 || scale > 8
1744 || (scale & (scale - 1)) != 0)
1745 return NULL_TREE;
1747 si = TYPE_MODE (index_type) == SImode;
1748 switch (TYPE_MODE (mem_vectype))
1750 case E_V2DFmode:
1751 if (TARGET_AVX512VL)
1752 code = si ? IX86_BUILTIN_GATHER3SIV2DF : IX86_BUILTIN_GATHER3DIV2DF;
1753 else
1754 code = si ? IX86_BUILTIN_GATHERSIV2DF : IX86_BUILTIN_GATHERDIV2DF;
1755 break;
1756 case E_V4DFmode:
1757 if (TARGET_AVX512VL)
1758 code = si ? IX86_BUILTIN_GATHER3ALTSIV4DF : IX86_BUILTIN_GATHER3DIV4DF;
1759 else
1760 code = si ? IX86_BUILTIN_GATHERALTSIV4DF : IX86_BUILTIN_GATHERDIV4DF;
1761 break;
1762 case E_V2DImode:
1763 if (TARGET_AVX512VL)
1764 code = si ? IX86_BUILTIN_GATHER3SIV2DI : IX86_BUILTIN_GATHER3DIV2DI;
1765 else
1766 code = si ? IX86_BUILTIN_GATHERSIV2DI : IX86_BUILTIN_GATHERDIV2DI;
1767 break;
1768 case E_V4DImode:
1769 if (TARGET_AVX512VL)
1770 code = si ? IX86_BUILTIN_GATHER3ALTSIV4DI : IX86_BUILTIN_GATHER3DIV4DI;
1771 else
1772 code = si ? IX86_BUILTIN_GATHERALTSIV4DI : IX86_BUILTIN_GATHERDIV4DI;
1773 break;
1774 case E_V4SFmode:
1775 if (TARGET_AVX512VL)
1776 code = si ? IX86_BUILTIN_GATHER3SIV4SF : IX86_BUILTIN_GATHER3DIV4SF;
1777 else
1778 code = si ? IX86_BUILTIN_GATHERSIV4SF : IX86_BUILTIN_GATHERDIV4SF;
1779 break;
1780 case E_V8SFmode:
1781 if (TARGET_AVX512VL)
1782 code = si ? IX86_BUILTIN_GATHER3SIV8SF : IX86_BUILTIN_GATHER3ALTDIV8SF;
1783 else
1784 code = si ? IX86_BUILTIN_GATHERSIV8SF : IX86_BUILTIN_GATHERALTDIV8SF;
1785 break;
1786 case E_V4SImode:
1787 if (TARGET_AVX512VL)
1788 code = si ? IX86_BUILTIN_GATHER3SIV4SI : IX86_BUILTIN_GATHER3DIV4SI;
1789 else
1790 code = si ? IX86_BUILTIN_GATHERSIV4SI : IX86_BUILTIN_GATHERDIV4SI;
1791 break;
1792 case E_V8SImode:
1793 if (TARGET_AVX512VL)
1794 code = si ? IX86_BUILTIN_GATHER3SIV8SI : IX86_BUILTIN_GATHER3ALTDIV8SI;
1795 else
1796 code = si ? IX86_BUILTIN_GATHERSIV8SI : IX86_BUILTIN_GATHERALTDIV8SI;
1797 break;
1798 case E_V8DFmode:
1799 if (TARGET_AVX512F)
1800 code = si ? IX86_BUILTIN_GATHER3ALTSIV8DF : IX86_BUILTIN_GATHER3DIV8DF;
1801 else
1802 return NULL_TREE;
1803 break;
1804 case E_V8DImode:
1805 if (TARGET_AVX512F)
1806 code = si ? IX86_BUILTIN_GATHER3ALTSIV8DI : IX86_BUILTIN_GATHER3DIV8DI;
1807 else
1808 return NULL_TREE;
1809 break;
1810 case E_V16SFmode:
1811 if (TARGET_AVX512F)
1812 code = si ? IX86_BUILTIN_GATHER3SIV16SF : IX86_BUILTIN_GATHER3ALTDIV16SF;
1813 else
1814 return NULL_TREE;
1815 break;
1816 case E_V16SImode:
1817 if (TARGET_AVX512F)
1818 code = si ? IX86_BUILTIN_GATHER3SIV16SI : IX86_BUILTIN_GATHER3ALTDIV16SI;
1819 else
1820 return NULL_TREE;
1821 break;
1822 default:
1823 return NULL_TREE;
1826 return ix86_get_builtin (code);
1829 /* Returns a code for a target-specific builtin that implements
1830 reciprocal of the function, or NULL_TREE if not available. */
1832 tree
1833 ix86_builtin_reciprocal (tree fndecl)
1835 enum ix86_builtins fn_code
1836 = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
1837 switch (fn_code)
1839 /* Vectorized version of sqrt to rsqrt conversion. */
1840 case IX86_BUILTIN_SQRTPS_NR:
1841 return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR);
1843 case IX86_BUILTIN_SQRTPS_NR256:
1844 return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR256);
1846 default:
1847 return NULL_TREE;
1851 /* Priority of i386 features, greater value is higher priority. This is
1852 used to decide the order in which function dispatch must happen. For
1853 instance, a version specialized for SSE4.2 should be checked for dispatch
1854 before a version for SSE3, as SSE4.2 implies SSE3. */
1855 enum feature_priority
1857 P_ZERO = 0,
1858 P_MMX,
1859 P_SSE,
1860 P_SSE2,
1861 P_SSE3,
1862 P_SSSE3,
1863 P_PROC_SSSE3,
1864 P_SSE4_A,
1865 P_PROC_SSE4_A,
1866 P_SSE4_1,
1867 P_SSE4_2,
1868 P_PROC_SSE4_2,
1869 P_POPCNT,
1870 P_AES,
1871 P_PCLMUL,
1872 P_AVX,
1873 P_PROC_AVX,
1874 P_BMI,
1875 P_PROC_BMI,
1876 P_FMA4,
1877 P_XOP,
1878 P_PROC_XOP,
1879 P_FMA,
1880 P_PROC_FMA,
1881 P_BMI2,
1882 P_AVX2,
1883 P_PROC_AVX2,
1884 P_AVX512F,
1885 P_PROC_AVX512F
1888 /* This is the order of bit-fields in __processor_features in cpuinfo.c */
1889 enum processor_features
1891 F_CMOV = 0,
1892 F_MMX,
1893 F_POPCNT,
1894 F_SSE,
1895 F_SSE2,
1896 F_SSE3,
1897 F_SSSE3,
1898 F_SSE4_1,
1899 F_SSE4_2,
1900 F_AVX,
1901 F_AVX2,
1902 F_SSE4_A,
1903 F_FMA4,
1904 F_XOP,
1905 F_FMA,
1906 F_AVX512F,
1907 F_BMI,
1908 F_BMI2,
1909 F_AES,
1910 F_PCLMUL,
1911 F_AVX512VL,
1912 F_AVX512BW,
1913 F_AVX512DQ,
1914 F_AVX512CD,
1915 F_AVX512ER,
1916 F_AVX512PF,
1917 F_AVX512VBMI,
1918 F_AVX512IFMA,
1919 F_AVX5124VNNIW,
1920 F_AVX5124FMAPS,
1921 F_AVX512VPOPCNTDQ,
1922 F_AVX512VBMI2,
1923 F_GFNI,
1924 F_VPCLMULQDQ,
1925 F_AVX512VNNI,
1926 F_AVX512BITALG,
1927 F_AVX512BF16,
1928 F_MAX
1931 /* These are the values for vendor types and cpu types and subtypes
1932 in cpuinfo.c. Cpu types and subtypes should be subtracted by
1933 the corresponding start value. */
1934 enum processor_model
1936 M_INTEL = 1,
1937 M_AMD,
1938 M_CPU_TYPE_START,
1939 M_INTEL_BONNELL,
1940 M_INTEL_CORE2,
1941 M_INTEL_COREI7,
1942 M_AMDFAM10H,
1943 M_AMDFAM15H,
1944 M_INTEL_SILVERMONT,
1945 M_INTEL_KNL,
1946 M_AMD_BTVER1,
1947 M_AMD_BTVER2,
1948 M_AMDFAM17H,
1949 M_INTEL_KNM,
1950 M_INTEL_GOLDMONT,
1951 M_INTEL_GOLDMONT_PLUS,
1952 M_INTEL_TREMONT,
1953 M_CPU_SUBTYPE_START,
1954 M_INTEL_COREI7_NEHALEM,
1955 M_INTEL_COREI7_WESTMERE,
1956 M_INTEL_COREI7_SANDYBRIDGE,
1957 M_AMDFAM10H_BARCELONA,
1958 M_AMDFAM10H_SHANGHAI,
1959 M_AMDFAM10H_ISTANBUL,
1960 M_AMDFAM15H_BDVER1,
1961 M_AMDFAM15H_BDVER2,
1962 M_AMDFAM15H_BDVER3,
1963 M_AMDFAM15H_BDVER4,
1964 M_AMDFAM17H_ZNVER1,
1965 M_INTEL_COREI7_IVYBRIDGE,
1966 M_INTEL_COREI7_HASWELL,
1967 M_INTEL_COREI7_BROADWELL,
1968 M_INTEL_COREI7_SKYLAKE,
1969 M_INTEL_COREI7_SKYLAKE_AVX512,
1970 M_INTEL_COREI7_CANNONLAKE,
1971 M_INTEL_COREI7_ICELAKE_CLIENT,
1972 M_INTEL_COREI7_ICELAKE_SERVER,
1973 M_AMDFAM17H_ZNVER2,
1974 M_INTEL_COREI7_CASCADELAKE
1977 struct _arch_names_table
1979 const char *const name;
1980 const enum processor_model model;
1983 static const _arch_names_table arch_names_table[] =
1985 {"amd", M_AMD},
1986 {"intel", M_INTEL},
1987 {"atom", M_INTEL_BONNELL},
1988 {"slm", M_INTEL_SILVERMONT},
1989 {"core2", M_INTEL_CORE2},
1990 {"corei7", M_INTEL_COREI7},
1991 {"nehalem", M_INTEL_COREI7_NEHALEM},
1992 {"westmere", M_INTEL_COREI7_WESTMERE},
1993 {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
1994 {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
1995 {"haswell", M_INTEL_COREI7_HASWELL},
1996 {"broadwell", M_INTEL_COREI7_BROADWELL},
1997 {"skylake", M_INTEL_COREI7_SKYLAKE},
1998 {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
1999 {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
2000 {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
2001 {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
2002 {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
2003 {"bonnell", M_INTEL_BONNELL},
2004 {"silvermont", M_INTEL_SILVERMONT},
2005 {"goldmont", M_INTEL_GOLDMONT},
2006 {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
2007 {"tremont", M_INTEL_TREMONT},
2008 {"knl", M_INTEL_KNL},
2009 {"knm", M_INTEL_KNM},
2010 {"amdfam10h", M_AMDFAM10H},
2011 {"barcelona", M_AMDFAM10H_BARCELONA},
2012 {"shanghai", M_AMDFAM10H_SHANGHAI},
2013 {"istanbul", M_AMDFAM10H_ISTANBUL},
2014 {"btver1", M_AMD_BTVER1},
2015 {"amdfam15h", M_AMDFAM15H},
2016 {"bdver1", M_AMDFAM15H_BDVER1},
2017 {"bdver2", M_AMDFAM15H_BDVER2},
2018 {"bdver3", M_AMDFAM15H_BDVER3},
2019 {"bdver4", M_AMDFAM15H_BDVER4},
2020 {"btver2", M_AMD_BTVER2},
2021 {"amdfam17h", M_AMDFAM17H},
2022 {"znver1", M_AMDFAM17H_ZNVER1},
2023 {"znver2", M_AMDFAM17H_ZNVER2},
2026 /* These are the target attribute strings for which a dispatcher is
2027 available, from fold_builtin_cpu. */
2028 struct _isa_names_table
2030 const char *const name;
2031 const enum processor_features feature;
2032 const enum feature_priority priority;
2035 static const _isa_names_table isa_names_table[] =
2037 {"cmov", F_CMOV, P_ZERO},
2038 {"mmx", F_MMX, P_MMX},
2039 {"popcnt", F_POPCNT, P_POPCNT},
2040 {"sse", F_SSE, P_SSE},
2041 {"sse2", F_SSE2, P_SSE2},
2042 {"sse3", F_SSE3, P_SSE3},
2043 {"ssse3", F_SSSE3, P_SSSE3},
2044 {"sse4a", F_SSE4_A, P_SSE4_A},
2045 {"sse4.1", F_SSE4_1, P_SSE4_1},
2046 {"sse4.2", F_SSE4_2, P_SSE4_2},
2047 {"avx", F_AVX, P_AVX},
2048 {"fma4", F_FMA4, P_FMA4},
2049 {"xop", F_XOP, P_XOP},
2050 {"fma", F_FMA, P_FMA},
2051 {"avx2", F_AVX2, P_AVX2},
2052 {"avx512f", F_AVX512F, P_AVX512F},
2053 {"bmi", F_BMI, P_BMI},
2054 {"bmi2", F_BMI2, P_BMI2},
2055 {"aes", F_AES, P_AES},
2056 {"pclmul", F_PCLMUL, P_PCLMUL},
2057 {"avx512vl",F_AVX512VL, P_ZERO},
2058 {"avx512bw",F_AVX512BW, P_ZERO},
2059 {"avx512dq",F_AVX512DQ, P_ZERO},
2060 {"avx512cd",F_AVX512CD, P_ZERO},
2061 {"avx512er",F_AVX512ER, P_ZERO},
2062 {"avx512pf",F_AVX512PF, P_ZERO},
2063 {"avx512vbmi",F_AVX512VBMI, P_ZERO},
2064 {"avx512ifma",F_AVX512IFMA, P_ZERO},
2065 {"avx5124vnniw",F_AVX5124VNNIW, P_ZERO},
2066 {"avx5124fmaps",F_AVX5124FMAPS, P_ZERO},
2067 {"avx512vpopcntdq",F_AVX512VPOPCNTDQ, P_ZERO},
2068 {"avx512vbmi2", F_AVX512VBMI2, P_ZERO},
2069 {"gfni", F_GFNI, P_ZERO},
2070 {"vpclmulqdq", F_VPCLMULQDQ, P_ZERO},
2071 {"avx512vnni", F_AVX512VNNI, P_ZERO},
2072 {"avx512bitalg", F_AVX512BITALG, P_ZERO},
2073 {"avx512bf16", F_AVX512BF16, P_ZERO}
2076 /* This parses the attribute arguments to target in DECL and determines
2077 the right builtin to use to match the platform specification.
2078 It returns the priority value for this version decl. If PREDICATE_LIST
2079 is not NULL, it stores the list of cpu features that need to be checked
2080 before dispatching this function. */
2082 unsigned int
2083 get_builtin_code_for_version (tree decl, tree *predicate_list)
2085 tree attrs;
2086 struct cl_target_option cur_target;
2087 tree target_node;
2088 struct cl_target_option *new_target;
2089 const char *arg_str = NULL;
2090 const char *attrs_str = NULL;
2091 char *tok_str = NULL;
2092 char *token;
2094 enum feature_priority priority = P_ZERO;
2096 static unsigned int NUM_FEATURES
2097 = sizeof (isa_names_table) / sizeof (_isa_names_table);
2099 unsigned int i;
2101 tree predicate_chain = NULL_TREE;
2102 tree predicate_decl, predicate_arg;
2104 attrs = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
2105 gcc_assert (attrs != NULL);
2107 attrs = TREE_VALUE (TREE_VALUE (attrs));
2109 gcc_assert (TREE_CODE (attrs) == STRING_CST);
2110 attrs_str = TREE_STRING_POINTER (attrs);
2112 /* Return priority zero for default function. */
2113 if (strcmp (attrs_str, "default") == 0)
2114 return 0;
2116 /* Handle arch= if specified. For priority, set it to be 1 more than
2117 the best instruction set the processor can handle. For instance, if
2118 there is a version for atom and a version for ssse3 (the highest ISA
2119 priority for atom), the atom version must be checked for dispatch
2120 before the ssse3 version. */
2121 if (strstr (attrs_str, "arch=") != NULL)
2123 cl_target_option_save (&cur_target, &global_options);
2124 target_node
2125 = ix86_valid_target_attribute_tree (decl, attrs, &global_options,
2126 &global_options_set, 0);
2128 gcc_assert (target_node);
2129 if (target_node == error_mark_node)
2130 return 0;
2131 new_target = TREE_TARGET_OPTION (target_node);
2132 gcc_assert (new_target);
2134 if (new_target->arch_specified && new_target->arch > 0)
2136 switch (new_target->arch)
2138 case PROCESSOR_CORE2:
2139 arg_str = "core2";
2140 priority = P_PROC_SSSE3;
2141 break;
2142 case PROCESSOR_NEHALEM:
2143 if (new_target->x_ix86_isa_flags & OPTION_MASK_ISA_PCLMUL)
2145 arg_str = "westmere";
2146 priority = P_PCLMUL;
2148 else
2150 /* We translate "arch=corei7" and "arch=nehalem" to
2151 "corei7" so that it will be mapped to M_INTEL_COREI7
2152 as cpu type to cover all M_INTEL_COREI7_XXXs. */
2153 arg_str = "corei7";
2154 priority = P_PROC_SSE4_2;
2156 break;
2157 case PROCESSOR_SANDYBRIDGE:
2158 if (new_target->x_ix86_isa_flags & OPTION_MASK_ISA_F16C)
2159 arg_str = "ivybridge";
2160 else
2161 arg_str = "sandybridge";
2162 priority = P_PROC_AVX;
2163 break;
2164 case PROCESSOR_HASWELL:
2165 if (new_target->x_ix86_isa_flags & OPTION_MASK_ISA_ADX)
2166 arg_str = "broadwell";
2167 else
2168 arg_str = "haswell";
2169 priority = P_PROC_AVX2;
2170 break;
2171 case PROCESSOR_SKYLAKE:
2172 arg_str = "skylake";
2173 priority = P_PROC_AVX2;
2174 break;
2175 case PROCESSOR_SKYLAKE_AVX512:
2176 arg_str = "skylake-avx512";
2177 priority = P_PROC_AVX512F;
2178 break;
2179 case PROCESSOR_CANNONLAKE:
2180 arg_str = "cannonlake";
2181 priority = P_PROC_AVX512F;
2182 break;
2183 case PROCESSOR_ICELAKE_CLIENT:
2184 arg_str = "icelake-client";
2185 priority = P_PROC_AVX512F;
2186 break;
2187 case PROCESSOR_ICELAKE_SERVER:
2188 arg_str = "icelake-server";
2189 priority = P_PROC_AVX512F;
2190 break;
2191 case PROCESSOR_CASCADELAKE:
2192 arg_str = "cascadelake";
2193 priority = P_PROC_AVX512F;
2194 break;
2195 case PROCESSOR_BONNELL:
2196 arg_str = "bonnell";
2197 priority = P_PROC_SSSE3;
2198 break;
2199 case PROCESSOR_KNL:
2200 arg_str = "knl";
2201 priority = P_PROC_AVX512F;
2202 break;
2203 case PROCESSOR_KNM:
2204 arg_str = "knm";
2205 priority = P_PROC_AVX512F;
2206 break;
2207 case PROCESSOR_SILVERMONT:
2208 arg_str = "silvermont";
2209 priority = P_PROC_SSE4_2;
2210 break;
2211 case PROCESSOR_GOLDMONT:
2212 arg_str = "goldmont";
2213 priority = P_PROC_SSE4_2;
2214 break;
2215 case PROCESSOR_GOLDMONT_PLUS:
2216 arg_str = "goldmont-plus";
2217 priority = P_PROC_SSE4_2;
2218 break;
2219 case PROCESSOR_TREMONT:
2220 arg_str = "tremont";
2221 priority = P_PROC_SSE4_2;
2222 break;
2223 case PROCESSOR_AMDFAM10:
2224 arg_str = "amdfam10h";
2225 priority = P_PROC_SSE4_A;
2226 break;
2227 case PROCESSOR_BTVER1:
2228 arg_str = "btver1";
2229 priority = P_PROC_SSE4_A;
2230 break;
2231 case PROCESSOR_BTVER2:
2232 arg_str = "btver2";
2233 priority = P_PROC_BMI;
2234 break;
2235 case PROCESSOR_BDVER1:
2236 arg_str = "bdver1";
2237 priority = P_PROC_XOP;
2238 break;
2239 case PROCESSOR_BDVER2:
2240 arg_str = "bdver2";
2241 priority = P_PROC_FMA;
2242 break;
2243 case PROCESSOR_BDVER3:
2244 arg_str = "bdver3";
2245 priority = P_PROC_FMA;
2246 break;
2247 case PROCESSOR_BDVER4:
2248 arg_str = "bdver4";
2249 priority = P_PROC_AVX2;
2250 break;
2251 case PROCESSOR_ZNVER1:
2252 arg_str = "znver1";
2253 priority = P_PROC_AVX2;
2254 break;
2255 case PROCESSOR_ZNVER2:
2256 arg_str = "znver2";
2257 priority = P_PROC_AVX2;
2258 break;
2262 cl_target_option_restore (&global_options, &cur_target);
2264 if (predicate_list && arg_str == NULL)
2266 error_at (DECL_SOURCE_LOCATION (decl),
2267 "no dispatcher found for the versioning attributes");
2268 return 0;
2271 if (predicate_list)
2273 predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
2274 /* For a C string literal the length includes the trailing NULL. */
2275 predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str);
2276 predicate_chain = tree_cons (predicate_decl, predicate_arg,
2277 predicate_chain);
2281 /* Process feature name. */
2282 tok_str = (char *) xmalloc (strlen (attrs_str) + 1);
2283 strcpy (tok_str, attrs_str);
2284 token = strtok (tok_str, ",");
2285 predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_SUPPORTS];
2287 while (token != NULL)
2289 /* Do not process "arch=" */
2290 if (strncmp (token, "arch=", 5) == 0)
2292 token = strtok (NULL, ",");
2293 continue;
2295 for (i = 0; i < NUM_FEATURES; ++i)
2297 if (strcmp (token, isa_names_table[i].name) == 0)
2299 if (predicate_list)
2301 predicate_arg = build_string_literal (
2302 strlen (isa_names_table[i].name) + 1,
2303 isa_names_table[i].name);
2304 predicate_chain = tree_cons (predicate_decl, predicate_arg,
2305 predicate_chain);
2307 /* Find the maximum priority feature. */
2308 if (isa_names_table[i].priority > priority)
2309 priority = isa_names_table[i].priority;
2311 break;
2314 if (predicate_list && priority == P_ZERO)
2316 error_at (DECL_SOURCE_LOCATION (decl),
2317 "ISA %qs is not supported in %<target%> attribute, "
2318 "use %<arch=%> syntax", token);
2319 return 0;
2321 token = strtok (NULL, ",");
2323 free (tok_str);
2325 if (predicate_list && predicate_chain == NULL_TREE)
2327 error_at (DECL_SOURCE_LOCATION (decl),
2328 "no dispatcher found for the versioning attributes: %s",
2329 attrs_str);
2330 return 0;
2332 else if (predicate_list)
2334 predicate_chain = nreverse (predicate_chain);
2335 *predicate_list = predicate_chain;
2338 return priority;
2341 /* This builds the processor_model struct type defined in
2342 libgcc/config/i386/cpuinfo.c */
2344 static tree
2345 build_processor_model_struct (void)
2347 const char *field_name[] = {"__cpu_vendor", "__cpu_type", "__cpu_subtype",
2348 "__cpu_features"};
2349 tree field = NULL_TREE, field_chain = NULL_TREE;
2350 int i;
2351 tree type = make_node (RECORD_TYPE);
2353 /* The first 3 fields are unsigned int. */
2354 for (i = 0; i < 3; ++i)
2356 field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
2357 get_identifier (field_name[i]), unsigned_type_node);
2358 if (field_chain != NULL_TREE)
2359 DECL_CHAIN (field) = field_chain;
2360 field_chain = field;
2363 /* The last field is an array of unsigned integers of size one. */
2364 field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
2365 get_identifier (field_name[3]),
2366 build_array_type (unsigned_type_node,
2367 build_index_type (size_one_node)));
2368 if (field_chain != NULL_TREE)
2369 DECL_CHAIN (field) = field_chain;
2370 field_chain = field;
2372 finish_builtin_struct (type, "__processor_model", field_chain, NULL_TREE);
2373 return type;
2376 /* Returns a extern, comdat VAR_DECL of type TYPE and name NAME. */
2378 static tree
2379 make_var_decl (tree type, const char *name)
2381 tree new_decl;
2383 new_decl = build_decl (UNKNOWN_LOCATION,
2384 VAR_DECL,
2385 get_identifier(name),
2386 type);
2388 DECL_EXTERNAL (new_decl) = 1;
2389 TREE_STATIC (new_decl) = 1;
2390 TREE_PUBLIC (new_decl) = 1;
2391 DECL_INITIAL (new_decl) = 0;
2392 DECL_ARTIFICIAL (new_decl) = 0;
2393 DECL_PRESERVE_P (new_decl) = 1;
2395 make_decl_one_only (new_decl, DECL_ASSEMBLER_NAME (new_decl));
2396 assemble_variable (new_decl, 0, 0, 0);
2398 return new_decl;
2401 /* FNDECL is a __builtin_cpu_is or a __builtin_cpu_supports call that is folded
2402 into an integer defined in libgcc/config/i386/cpuinfo.c */
2404 tree
2405 fold_builtin_cpu (tree fndecl, tree *args)
2407 unsigned int i;
2408 enum ix86_builtins fn_code = (enum ix86_builtins)
2409 DECL_FUNCTION_CODE (fndecl);
2410 tree param_string_cst = NULL;
2412 tree __processor_model_type = build_processor_model_struct ();
2413 tree __cpu_model_var = make_var_decl (__processor_model_type,
2414 "__cpu_model");
2417 varpool_node::add (__cpu_model_var);
2419 gcc_assert ((args != NULL) && (*args != NULL));
2421 param_string_cst = *args;
2422 while (param_string_cst
2423 && TREE_CODE (param_string_cst) != STRING_CST)
2425 /* *args must be a expr that can contain other EXPRS leading to a
2426 STRING_CST. */
2427 if (!EXPR_P (param_string_cst))
2429 error ("parameter to builtin must be a string constant or literal");
2430 return integer_zero_node;
2432 param_string_cst = TREE_OPERAND (EXPR_CHECK (param_string_cst), 0);
2435 gcc_assert (param_string_cst);
2437 if (fn_code == IX86_BUILTIN_CPU_IS)
2439 tree ref;
2440 tree field;
2441 tree final;
2443 unsigned int field_val = 0;
2444 unsigned int NUM_ARCH_NAMES
2445 = sizeof (arch_names_table) / sizeof (struct _arch_names_table);
2447 for (i = 0; i < NUM_ARCH_NAMES; i++)
2448 if (strcmp (arch_names_table[i].name,
2449 TREE_STRING_POINTER (param_string_cst)) == 0)
2450 break;
2452 if (i == NUM_ARCH_NAMES)
2454 error ("parameter to builtin not valid: %s",
2455 TREE_STRING_POINTER (param_string_cst));
2456 return integer_zero_node;
2459 field = TYPE_FIELDS (__processor_model_type);
2460 field_val = arch_names_table[i].model;
2462 /* CPU types are stored in the next field. */
2463 if (field_val > M_CPU_TYPE_START
2464 && field_val < M_CPU_SUBTYPE_START)
2466 field = DECL_CHAIN (field);
2467 field_val -= M_CPU_TYPE_START;
2470 /* CPU subtypes are stored in the next field. */
2471 if (field_val > M_CPU_SUBTYPE_START)
2473 field = DECL_CHAIN ( DECL_CHAIN (field));
2474 field_val -= M_CPU_SUBTYPE_START;
2477 /* Get the appropriate field in __cpu_model. */
2478 ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
2479 field, NULL_TREE);
2481 /* Check the value. */
2482 final = build2 (EQ_EXPR, unsigned_type_node, ref,
2483 build_int_cstu (unsigned_type_node, field_val));
2484 return build1 (CONVERT_EXPR, integer_type_node, final);
2486 else if (fn_code == IX86_BUILTIN_CPU_SUPPORTS)
2488 tree ref;
2489 tree array_elt;
2490 tree field;
2491 tree final;
2493 unsigned int field_val = 0;
2494 unsigned int NUM_ISA_NAMES
2495 = sizeof (isa_names_table) / sizeof (struct _isa_names_table);
2497 for (i = 0; i < NUM_ISA_NAMES; i++)
2498 if (strcmp (isa_names_table[i].name,
2499 TREE_STRING_POINTER (param_string_cst)) == 0)
2500 break;
2502 if (i == NUM_ISA_NAMES)
2504 error ("parameter to builtin not valid: %s",
2505 TREE_STRING_POINTER (param_string_cst));
2506 return integer_zero_node;
2509 if (isa_names_table[i].feature >= 32)
2511 tree __cpu_features2_var = make_var_decl (unsigned_type_node,
2512 "__cpu_features2");
2514 varpool_node::add (__cpu_features2_var);
2515 field_val = (1U << (isa_names_table[i].feature - 32));
2516 /* Return __cpu_features2 & field_val */
2517 final = build2 (BIT_AND_EXPR, unsigned_type_node,
2518 __cpu_features2_var,
2519 build_int_cstu (unsigned_type_node, field_val));
2520 return build1 (CONVERT_EXPR, integer_type_node, final);
2523 field = TYPE_FIELDS (__processor_model_type);
2524 /* Get the last field, which is __cpu_features. */
2525 while (DECL_CHAIN (field))
2526 field = DECL_CHAIN (field);
2528 /* Get the appropriate field: __cpu_model.__cpu_features */
2529 ref = build3 (COMPONENT_REF, TREE_TYPE (field), __cpu_model_var,
2530 field, NULL_TREE);
2532 /* Access the 0th element of __cpu_features array. */
2533 array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
2534 integer_zero_node, NULL_TREE, NULL_TREE);
2536 field_val = (1U << isa_names_table[i].feature);
2537 /* Return __cpu_model.__cpu_features[0] & field_val */
2538 final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
2539 build_int_cstu (unsigned_type_node, field_val));
2540 return build1 (CONVERT_EXPR, integer_type_node, final);
2542 gcc_unreachable ();
2545 #include "gt-i386-builtins.h"