libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / config / i386 / i386-builtins.cc
blob4286eeb80e636c08532ec8cfb8cd6c357b92f438
1 /* Copyright (C) 1988-2024 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 "cselib.h"
62 #include "sched-int.h"
63 #include "opts.h"
64 #include "tree-pass.h"
65 #include "context.h"
66 #include "pass_manager.h"
67 #include "target-globals.h"
68 #include "gimple-iterator.h"
69 #include "shrink-wrap.h"
70 #include "builtins.h"
71 #include "rtl-iter.h"
72 #include "tree-iterator.h"
73 #include "dbgcnt.h"
74 #include "case-cfn-macros.h"
75 #include "dojump.h"
76 #include "fold-const-call.h"
77 #include "tree-vrp.h"
78 #include "tree-ssanames.h"
79 #include "selftest.h"
80 #include "selftest-rtl.h"
81 #include "print-rtl.h"
82 #include "intl.h"
83 #include "ifcvt.h"
84 #include "symbol-summary.h"
85 #include "sreal.h"
86 #include "ipa-cp.h"
87 #include "ipa-prop.h"
88 #include "ipa-fnsummary.h"
89 #include "wide-int-bitmask.h"
90 #include "tree-vector-builder.h"
91 #include "debug.h"
92 #include "dwarf2out.h"
93 #include "i386-builtins.h"
94 #include "common/config/i386/i386-isas.h"
96 #undef BDESC
97 #undef BDESC_FIRST
98 #undef BDESC_END
100 /* Macros for verification of enum ix86_builtins order. */
101 #define BDESC_VERIFY(x, y, z) \
102 gcc_checking_assert ((x) == (enum ix86_builtins) ((y) + (z)))
103 #define BDESC_VERIFYS(x, y, z) \
104 STATIC_ASSERT ((x) == (enum ix86_builtins) ((y) + (z)))
106 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPESTR_FIRST,
107 IX86_BUILTIN__BDESC_COMI_LAST, 1);
108 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPISTR_FIRST,
109 IX86_BUILTIN__BDESC_PCMPESTR_LAST, 1);
110 BDESC_VERIFYS (IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST,
111 IX86_BUILTIN__BDESC_PCMPISTR_LAST, 1);
112 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PURE_ARGS_FIRST,
113 IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST, 1);
114 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ARGS_FIRST,
115 IX86_BUILTIN__BDESC_PURE_ARGS_LAST, 1);
116 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST,
117 IX86_BUILTIN__BDESC_ARGS_LAST, 1);
118 BDESC_VERIFYS (IX86_BUILTIN__BDESC_MULTI_ARG_FIRST,
119 IX86_BUILTIN__BDESC_ROUND_ARGS_LAST, 1);
120 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_FIRST,
121 IX86_BUILTIN__BDESC_MULTI_ARG_LAST, 1);
122 BDESC_VERIFYS (IX86_BUILTIN_MAX,
123 IX86_BUILTIN__BDESC_CET_LAST, 1);
126 /* Table for the ix86 builtin non-function types. */
127 static GTY(()) tree ix86_builtin_type_tab[(int) IX86_BT_LAST_CPTR + 1];
129 tree ix86_float16_type_node = NULL_TREE;
130 tree ix86_bf16_type_node = NULL_TREE;
132 /* Retrieve an element from the above table, building some of
133 the types lazily. */
135 static tree
136 ix86_get_builtin_type (enum ix86_builtin_type tcode)
138 unsigned int index;
139 tree type, itype;
141 gcc_assert ((unsigned)tcode < ARRAY_SIZE(ix86_builtin_type_tab));
143 type = ix86_builtin_type_tab[(int) tcode];
144 if (type != NULL)
145 return type;
147 gcc_assert (tcode > IX86_BT_LAST_PRIM);
148 if (tcode <= IX86_BT_LAST_VECT)
150 machine_mode mode;
152 index = tcode - IX86_BT_LAST_PRIM - 1;
153 itype = ix86_get_builtin_type (ix86_builtin_type_vect_base[index]);
154 mode = ix86_builtin_type_vect_mode[index];
156 type = build_vector_type_for_mode (itype, mode);
158 else
160 int quals;
162 index = tcode - IX86_BT_LAST_VECT - 1;
163 if (tcode <= IX86_BT_LAST_PTR)
164 quals = TYPE_UNQUALIFIED;
165 else
166 quals = TYPE_QUAL_CONST;
168 itype = ix86_get_builtin_type (ix86_builtin_type_ptr_base[index]);
169 if (quals != TYPE_UNQUALIFIED)
170 itype = build_qualified_type (itype, quals);
172 type = build_pointer_type (itype);
175 ix86_builtin_type_tab[(int) tcode] = type;
176 return type;
179 /* Table for the ix86 builtin function types. */
180 static GTY(()) tree ix86_builtin_func_type_tab[(int) IX86_BT_LAST_ALIAS + 1];
182 /* Retrieve an element from the above table, building some of
183 the types lazily. */
185 static tree
186 ix86_get_builtin_func_type (enum ix86_builtin_func_type tcode)
188 tree type;
190 gcc_assert ((unsigned)tcode < ARRAY_SIZE (ix86_builtin_func_type_tab));
192 type = ix86_builtin_func_type_tab[(int) tcode];
193 if (type != NULL)
194 return type;
196 if (tcode <= IX86_BT_LAST_FUNC)
198 unsigned start = ix86_builtin_func_start[(int) tcode];
199 unsigned after = ix86_builtin_func_start[(int) tcode + 1];
200 tree rtype, atype, args = void_list_node;
201 unsigned i;
203 rtype = ix86_get_builtin_type (ix86_builtin_func_args[start]);
204 for (i = after - 1; i > start; --i)
206 atype = ix86_get_builtin_type (ix86_builtin_func_args[i]);
207 args = tree_cons (NULL, atype, args);
210 type = build_function_type (rtype, args);
212 else
214 unsigned index = tcode - IX86_BT_LAST_FUNC - 1;
215 enum ix86_builtin_func_type icode;
217 icode = ix86_builtin_func_alias_base[index];
218 type = ix86_get_builtin_func_type (icode);
221 ix86_builtin_func_type_tab[(int) tcode] = type;
222 return type;
225 /* Table for the ix86 builtin decls. */
226 static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX + 1];
228 struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
230 tree get_ix86_builtin (enum ix86_builtins c)
232 return ix86_builtins[c];
235 /* Bits that can still enable any inclusion of a builtin. */
236 HOST_WIDE_INT deferred_isa_values = 0;
237 HOST_WIDE_INT deferred_isa_values2 = 0;
239 /* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the
240 MASK and MASK2 of which isa_flags and ix86_isa_flags2 to use in the
241 ix86_builtins_isa array. Stores the function decl in the ix86_builtins
242 array. Returns the function decl or NULL_TREE, if the builtin was not
243 added.
245 If the front end has a special hook for builtin functions, delay adding
246 builtin functions that aren't in the current ISA until the ISA is changed
247 with function specific optimization. Doing so, can save about 300K for the
248 default compiler. When the builtin is expanded, check at that time whether
249 it is valid.
251 If the front end doesn't have a special hook, record all builtins, even if
252 it isn't an instruction set in the current ISA in case the user uses
253 function specific options for a different ISA, so that we don't get scope
254 errors if a builtin is added in the middle of a function scope. */
256 static inline tree
257 def_builtin (HOST_WIDE_INT mask, HOST_WIDE_INT mask2,
258 const char *name,
259 enum ix86_builtin_func_type tcode,
260 enum ix86_builtins code)
262 tree decl = NULL_TREE;
264 /* An instruction may be 64bit only regardless of ISAs. */
265 if (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT)
267 ix86_builtins_isa[(int) code].isa = mask;
268 ix86_builtins_isa[(int) code].isa2 = mask2;
270 mask &= ~OPTION_MASK_ISA_64BIT;
272 /* Filter out the masks most often ored together with others. */
273 if ((mask & ix86_isa_flags & OPTION_MASK_ISA_AVX512VL)
274 && mask != OPTION_MASK_ISA_AVX512VL)
275 mask &= ~OPTION_MASK_ISA_AVX512VL;
276 if ((mask & ix86_isa_flags & OPTION_MASK_ISA_AVX512BW)
277 && mask != OPTION_MASK_ISA_AVX512BW)
278 mask &= ~OPTION_MASK_ISA_AVX512BW;
280 if (((mask2 == 0 || (mask2 & ix86_isa_flags2) != 0)
281 && (mask == 0 || (mask & ix86_isa_flags) != 0))
282 || ((mask & OPTION_MASK_ISA_MMX) != 0 && TARGET_MMX_WITH_SSE)
283 /* "Unified" builtin used by either AVXVNNI/AVXIFMA/AES/
284 AVXVNNIINT{8,16} intrinsics or AVX512VNNIVL/AVX512IFMAVL/VAESVL/
285 AVX10.2 non-mask intrinsics should be defined whenever avxvnni/
286 avxifma/aes/avxvnniint{8,16} or avx512vnni && avx512vl/avx512ifma
287 && avx512vl/vaes && avx512vl/avx10.2 exist. */
288 || (mask2 == OPTION_MASK_ISA2_AVXVNNI)
289 || (mask2 == OPTION_MASK_ISA2_AVXIFMA)
290 || (mask2 == (OPTION_MASK_ISA2_AVXNECONVERT
291 | OPTION_MASK_ISA2_AVX512BF16))
292 || ((mask2 & OPTION_MASK_ISA2_VAES) != 0)
293 || ((mask2 & OPTION_MASK_ISA2_AVXVNNIINT8) != 0)
294 || ((mask2 & OPTION_MASK_ISA2_AVXVNNIINT16) != 0)
295 || (lang_hooks.builtin_function
296 == lang_hooks.builtin_function_ext_scope))
298 tree type = ix86_get_builtin_func_type (tcode);
299 decl = add_builtin_function (name, type, code, BUILT_IN_MD,
300 NULL, NULL_TREE);
301 ix86_builtins[(int) code] = decl;
302 ix86_builtins_isa[(int) code].set_and_not_built_p = false;
303 if (!flag_non_call_exceptions)
304 TREE_NOTHROW (decl) = 1;
305 if (ix86_builtins[(int) IX86_BUILTIN_MAX] == NULL_TREE)
306 ix86_builtins[(int) IX86_BUILTIN_MAX]
307 = build_tree_list (get_identifier ("leaf"), NULL_TREE);
308 DECL_ATTRIBUTES (decl) = ix86_builtins[(int) IX86_BUILTIN_MAX];
310 else
312 /* Just MASK and MASK2 where set_and_not_built_p == true can potentially
313 include a builtin. */
314 deferred_isa_values |= mask;
315 deferred_isa_values2 |= mask2;
316 ix86_builtins[(int) code] = NULL_TREE;
317 ix86_builtins_isa[(int) code].tcode = tcode;
318 ix86_builtins_isa[(int) code].name = name;
319 ix86_builtins_isa[(int) code].const_p = false;
320 ix86_builtins_isa[(int) code].pure_p = false;
321 ix86_builtins_isa[(int) code].set_and_not_built_p = true;
325 return decl;
328 /* Like def_builtin, but also marks the function decl "const". */
330 static inline tree
331 def_builtin_const (HOST_WIDE_INT mask, HOST_WIDE_INT mask2, const char *name,
332 enum ix86_builtin_func_type tcode, enum ix86_builtins code)
334 tree decl = def_builtin (mask, mask2, name, tcode, code);
335 if (decl)
336 TREE_READONLY (decl) = 1;
337 else
338 ix86_builtins_isa[(int) code].const_p = true;
340 return decl;
343 /* Like def_builtin, but also marks the function decl "pure". */
345 static inline tree
346 def_builtin_pure (HOST_WIDE_INT mask, HOST_WIDE_INT mask2, const char *name,
347 enum ix86_builtin_func_type tcode, enum ix86_builtins code)
349 tree decl = def_builtin (mask, mask2, name, tcode, code);
350 if (decl)
351 DECL_PURE_P (decl) = 1;
352 else
353 ix86_builtins_isa[(int) code].pure_p = true;
355 return decl;
358 /* Add any new builtin functions for a given ISA that may not have been
359 declared. This saves a bit of space compared to adding all of the
360 declarations to the tree, even if we didn't use them. */
362 void
363 ix86_add_new_builtins (HOST_WIDE_INT isa, HOST_WIDE_INT isa2)
365 isa &= ~OPTION_MASK_ISA_64BIT;
367 if ((isa & deferred_isa_values) == 0
368 && (isa2 & deferred_isa_values2) == 0
369 && ((deferred_isa_values & OPTION_MASK_ISA_MMX) == 0
370 || !(TARGET_64BIT && (isa & OPTION_MASK_ISA_SSE2) != 0)))
371 return;
373 /* Bits in ISA value can be removed from potential isa values. */
374 deferred_isa_values &= ~isa;
375 deferred_isa_values2 &= ~isa2;
376 if (TARGET_64BIT && (isa & OPTION_MASK_ISA_SSE2) != 0)
377 deferred_isa_values &= ~OPTION_MASK_ISA_MMX;
379 int i;
380 tree saved_current_target_pragma = current_target_pragma;
381 current_target_pragma = NULL_TREE;
383 for (i = 0; i < (int)IX86_BUILTIN_MAX; i++)
385 if (((ix86_builtins_isa[i].isa & isa) != 0
386 || (ix86_builtins_isa[i].isa2 & isa2) != 0
387 || ((ix86_builtins_isa[i].isa & OPTION_MASK_ISA_MMX) != 0
388 && TARGET_64BIT
389 && (isa & OPTION_MASK_ISA_SSE2) != 0))
390 && ix86_builtins_isa[i].set_and_not_built_p)
392 tree decl, type;
394 /* Don't define the builtin again. */
395 ix86_builtins_isa[i].set_and_not_built_p = false;
397 type = ix86_get_builtin_func_type (ix86_builtins_isa[i].tcode);
398 decl = add_builtin_function_ext_scope (ix86_builtins_isa[i].name,
399 type, i, BUILT_IN_MD, NULL,
400 NULL_TREE);
402 ix86_builtins[i] = decl;
403 if (ix86_builtins_isa[i].const_p)
404 TREE_READONLY (decl) = 1;
405 if (ix86_builtins_isa[i].pure_p)
406 DECL_PURE_P (decl) = 1;
407 if (!flag_non_call_exceptions)
408 TREE_NOTHROW (decl) = 1;
409 if (ix86_builtins[(int) IX86_BUILTIN_MAX] == NULL_TREE)
410 ix86_builtins[(int) IX86_BUILTIN_MAX]
411 = build_tree_list (get_identifier ("leaf"), NULL_TREE);
412 DECL_ATTRIBUTES (decl) = ix86_builtins[(int) IX86_BUILTIN_MAX];
416 current_target_pragma = saved_current_target_pragma;
419 /* TM vector builtins. */
421 /* Reuse the existing x86-specific `struct builtin_description' cause
422 we're lazy. Add casts to make them fit. */
423 static const struct builtin_description bdesc_tm[] =
425 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_WM64", (enum ix86_builtins) BUILT_IN_TM_STORE_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
426 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_WaRM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAR_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
427 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_WaWM64", (enum ix86_builtins) BUILT_IN_TM_STORE_WAW_M64, UNKNOWN, VOID_FTYPE_PV2SI_V2SI },
428 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_RM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
429 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
430 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
431 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM64", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M64, UNKNOWN, V2SI_FTYPE_PCV2SI },
433 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_WM128", (enum ix86_builtins) BUILT_IN_TM_STORE_M128, UNKNOWN, VOID_FTYPE_PV4SF_V4SF },
434 { 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 },
435 { 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 },
436 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
437 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
438 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
439 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM128", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M128, UNKNOWN, V4SF_FTYPE_PCV4SF },
441 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_WM256", (enum ix86_builtins) BUILT_IN_TM_STORE_M256, UNKNOWN, VOID_FTYPE_PV8SF_V8SF },
442 { 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 },
443 { 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 },
444 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
445 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RaRM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAR_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
446 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RaWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RAW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
447 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_RfWM256", (enum ix86_builtins) BUILT_IN_TM_LOAD_RFW_M256, UNKNOWN, V8SF_FTYPE_PCV8SF },
449 { OPTION_MASK_ISA_MMX, 0, CODE_FOR_nothing, "__builtin__ITM_LM64", (enum ix86_builtins) BUILT_IN_TM_LOG_M64, UNKNOWN, VOID_FTYPE_PCVOID },
450 { OPTION_MASK_ISA_SSE, 0, CODE_FOR_nothing, "__builtin__ITM_LM128", (enum ix86_builtins) BUILT_IN_TM_LOG_M128, UNKNOWN, VOID_FTYPE_PCVOID },
451 { OPTION_MASK_ISA_AVX, 0, CODE_FOR_nothing, "__builtin__ITM_LM256", (enum ix86_builtins) BUILT_IN_TM_LOG_M256, UNKNOWN, VOID_FTYPE_PCVOID },
454 /* Initialize the transactional memory vector load/store builtins. */
456 static void
457 ix86_init_tm_builtins (void)
459 enum ix86_builtin_func_type ftype;
460 const struct builtin_description *d;
461 size_t i;
462 tree decl;
463 tree attrs_load, attrs_type_load, attrs_store, attrs_type_store;
464 tree attrs_log, attrs_type_log;
466 if (!flag_tm)
467 return;
469 /* If there are no builtins defined, we must be compiling in a
470 language without trans-mem support. */
471 if (!builtin_decl_explicit_p (BUILT_IN_TM_LOAD_1))
472 return;
474 /* Use whatever attributes a normal TM load has. */
475 decl = builtin_decl_explicit (BUILT_IN_TM_LOAD_1);
476 attrs_load = DECL_ATTRIBUTES (decl);
477 attrs_type_load = TYPE_ATTRIBUTES (TREE_TYPE (decl));
478 /* Use whatever attributes a normal TM store has. */
479 decl = builtin_decl_explicit (BUILT_IN_TM_STORE_1);
480 attrs_store = DECL_ATTRIBUTES (decl);
481 attrs_type_store = TYPE_ATTRIBUTES (TREE_TYPE (decl));
482 /* Use whatever attributes a normal TM log has. */
483 decl = builtin_decl_explicit (BUILT_IN_TM_LOG);
484 attrs_log = DECL_ATTRIBUTES (decl);
485 attrs_type_log = TYPE_ATTRIBUTES (TREE_TYPE (decl));
487 for (i = 0, d = bdesc_tm;
488 i < ARRAY_SIZE (bdesc_tm);
489 i++, d++)
491 if ((d->mask & ix86_isa_flags) != 0
492 || ((d->mask & OPTION_MASK_ISA_MMX) != 0 && TARGET_MMX_WITH_SSE)
493 || (lang_hooks.builtin_function
494 == lang_hooks.builtin_function_ext_scope))
496 tree type, attrs, attrs_type;
497 enum built_in_function code = (enum built_in_function) d->code;
499 ftype = (enum ix86_builtin_func_type) d->flag;
500 type = ix86_get_builtin_func_type (ftype);
502 if (BUILTIN_TM_LOAD_P (code))
504 attrs = attrs_load;
505 attrs_type = attrs_type_load;
507 else if (BUILTIN_TM_STORE_P (code))
509 attrs = attrs_store;
510 attrs_type = attrs_type_store;
512 else
514 attrs = attrs_log;
515 attrs_type = attrs_type_log;
517 decl = add_builtin_function (d->name, type, code, BUILT_IN_NORMAL,
518 /* The builtin without the prefix for
519 calling it directly. */
520 d->name + strlen ("__builtin_"),
521 attrs);
522 /* add_builtin_function() will set the DECL_ATTRIBUTES, now
523 set the TYPE_ATTRIBUTES. */
524 decl_attributes (&TREE_TYPE (decl), attrs_type, ATTR_FLAG_BUILT_IN);
526 set_builtin_decl (code, decl, false);
531 /* Set up all the MMX/SSE builtins, even builtins for instructions that are not
532 in the current target ISA to allow the user to compile particular modules
533 with different target specific options that differ from the command line
534 options. */
535 static void
536 ix86_init_mmx_sse_builtins (void)
538 const struct builtin_description * d;
539 enum ix86_builtin_func_type ftype;
540 size_t i;
542 /* Add all special builtins with variable number of operands. */
543 for (i = 0, d = bdesc_special_args;
544 i < ARRAY_SIZE (bdesc_special_args);
545 i++, d++)
547 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST, i);
548 if (d->name == 0)
549 continue;
551 ftype = (enum ix86_builtin_func_type) d->flag;
552 def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
554 BDESC_VERIFYS (IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST,
555 IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST,
556 ARRAY_SIZE (bdesc_special_args) - 1);
558 /* Add all pure builtins with variable number of operands. */
559 for (i = 0, d = bdesc_pure_args;
560 i < ARRAY_SIZE (bdesc_pure_args);
561 i++, d++)
563 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_PURE_ARGS_FIRST, i);
564 if (d->name == 0)
565 continue;
567 ftype = (enum ix86_builtin_func_type) d->flag;
568 def_builtin_pure (d->mask, d->mask2, d->name, ftype, d->code);
570 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PURE_ARGS_LAST,
571 IX86_BUILTIN__BDESC_PURE_ARGS_FIRST,
572 ARRAY_SIZE (bdesc_pure_args) - 1);
574 /* Add all const builtins with variable number of operands. */
575 for (i = 0, d = bdesc_args;
576 i < ARRAY_SIZE (bdesc_args);
577 i++, d++)
579 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_ARGS_FIRST, i);
580 if (d->name == 0)
581 continue;
583 ftype = (enum ix86_builtin_func_type) d->flag;
584 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
586 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ARGS_LAST,
587 IX86_BUILTIN__BDESC_ARGS_FIRST,
588 ARRAY_SIZE (bdesc_args) - 1);
590 /* Add all builtins with rounding. */
591 for (i = 0, d = bdesc_round_args;
592 i < ARRAY_SIZE (bdesc_round_args);
593 i++, d++)
595 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST, i);
596 if (d->name == 0)
597 continue;
599 ftype = (enum ix86_builtin_func_type) d->flag;
600 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
602 BDESC_VERIFYS (IX86_BUILTIN__BDESC_ROUND_ARGS_LAST,
603 IX86_BUILTIN__BDESC_ROUND_ARGS_FIRST,
604 ARRAY_SIZE (bdesc_round_args) - 1);
606 /* pcmpestr[im] insns. */
607 for (i = 0, d = bdesc_pcmpestr;
608 i < ARRAY_SIZE (bdesc_pcmpestr);
609 i++, d++)
611 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_PCMPESTR_FIRST, i);
612 if (d->code == IX86_BUILTIN_PCMPESTRM128)
613 ftype = V16QI_FTYPE_V16QI_INT_V16QI_INT_INT;
614 else
615 ftype = INT_FTYPE_V16QI_INT_V16QI_INT_INT;
616 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
618 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPESTR_LAST,
619 IX86_BUILTIN__BDESC_PCMPESTR_FIRST,
620 ARRAY_SIZE (bdesc_pcmpestr) - 1);
622 /* pcmpistr[im] insns. */
623 for (i = 0, d = bdesc_pcmpistr;
624 i < ARRAY_SIZE (bdesc_pcmpistr);
625 i++, d++)
627 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_PCMPISTR_FIRST, i);
628 if (d->code == IX86_BUILTIN_PCMPISTRM128)
629 ftype = V16QI_FTYPE_V16QI_V16QI_INT;
630 else
631 ftype = INT_FTYPE_V16QI_V16QI_INT;
632 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
634 BDESC_VERIFYS (IX86_BUILTIN__BDESC_PCMPISTR_LAST,
635 IX86_BUILTIN__BDESC_PCMPISTR_FIRST,
636 ARRAY_SIZE (bdesc_pcmpistr) - 1);
638 /* comi/ucomi insns. */
639 for (i = 0, d = bdesc_comi; i < ARRAY_SIZE (bdesc_comi); i++, d++)
641 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_COMI_FIRST, i);
642 if (d->mask == OPTION_MASK_ISA_SSE2)
643 ftype = INT_FTYPE_V2DF_V2DF;
644 else
645 ftype = INT_FTYPE_V4SF_V4SF;
646 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
648 BDESC_VERIFYS (IX86_BUILTIN__BDESC_COMI_LAST,
649 IX86_BUILTIN__BDESC_COMI_FIRST,
650 ARRAY_SIZE (bdesc_comi) - 1);
652 /* SSE */
653 def_builtin (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_ldmxcsr",
654 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_LDMXCSR);
655 def_builtin_pure (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_stmxcsr",
656 UNSIGNED_FTYPE_VOID, IX86_BUILTIN_STMXCSR);
658 /* SSE or 3DNow!A */
659 def_builtin (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
660 /* As it uses V4HImode, we have to require -mmmx too. */
661 | OPTION_MASK_ISA_MMX, 0,
662 "__builtin_ia32_maskmovq", VOID_FTYPE_V8QI_V8QI_PCHAR,
663 IX86_BUILTIN_MASKMOVQ);
665 /* SSE2 */
666 def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_maskmovdqu",
667 VOID_FTYPE_V16QI_V16QI_PCHAR, IX86_BUILTIN_MASKMOVDQU);
669 def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_clflush",
670 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSH);
671 x86_mfence = def_builtin (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_mfence",
672 VOID_FTYPE_VOID, IX86_BUILTIN_MFENCE);
674 /* SSE3. */
675 def_builtin (0, OPTION_MASK_ISA2_MWAIT, "__builtin_ia32_monitor",
676 VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITOR);
677 def_builtin (0, OPTION_MASK_ISA2_MWAIT, "__builtin_ia32_mwait",
678 VOID_FTYPE_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAIT);
680 /* AES */
681 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2
682 | OPTION_MASK_ISA_AVX512VL,
683 OPTION_MASK_ISA2_VAES,
684 "__builtin_ia32_aesenc128",
685 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENC128);
686 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2
687 | OPTION_MASK_ISA_AVX512VL,
688 OPTION_MASK_ISA2_VAES,
689 "__builtin_ia32_aesenclast128",
690 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENCLAST128);
691 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2
692 | OPTION_MASK_ISA_AVX512VL,
693 OPTION_MASK_ISA2_VAES,
694 "__builtin_ia32_aesdec128",
695 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDEC128);
696 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2
697 | OPTION_MASK_ISA_AVX512VL,
698 OPTION_MASK_ISA2_VAES,
699 "__builtin_ia32_aesdeclast128",
700 V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDECLAST128);
701 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
702 "__builtin_ia32_aesimc128",
703 V2DI_FTYPE_V2DI, IX86_BUILTIN_AESIMC128);
704 def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, 0,
705 "__builtin_ia32_aeskeygenassist128",
706 V2DI_FTYPE_V2DI_INT, IX86_BUILTIN_AESKEYGENASSIST128);
708 /* PCLMUL */
709 def_builtin_const (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2, 0,
710 "__builtin_ia32_pclmulqdq128",
711 V2DI_FTYPE_V2DI_V2DI_INT, IX86_BUILTIN_PCLMULQDQ128);
713 /* RDRND */
714 def_builtin (OPTION_MASK_ISA_RDRND, 0, "__builtin_ia32_rdrand16_step",
715 INT_FTYPE_PUSHORT, IX86_BUILTIN_RDRAND16_STEP);
716 def_builtin (OPTION_MASK_ISA_RDRND, 0, "__builtin_ia32_rdrand32_step",
717 INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDRAND32_STEP);
718 def_builtin (OPTION_MASK_ISA_RDRND | OPTION_MASK_ISA_64BIT, 0,
719 "__builtin_ia32_rdrand64_step", INT_FTYPE_PULONGLONG,
720 IX86_BUILTIN_RDRAND64_STEP);
722 /* AVX2 */
723 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv2df",
724 V2DF_FTYPE_V2DF_PCDOUBLE_V4SI_V2DF_INT,
725 IX86_BUILTIN_GATHERSIV2DF);
727 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4df",
728 V4DF_FTYPE_V4DF_PCDOUBLE_V4SI_V4DF_INT,
729 IX86_BUILTIN_GATHERSIV4DF);
731 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv2df",
732 V2DF_FTYPE_V2DF_PCDOUBLE_V2DI_V2DF_INT,
733 IX86_BUILTIN_GATHERDIV2DF);
735 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4df",
736 V4DF_FTYPE_V4DF_PCDOUBLE_V4DI_V4DF_INT,
737 IX86_BUILTIN_GATHERDIV4DF);
739 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4sf",
740 V4SF_FTYPE_V4SF_PCFLOAT_V4SI_V4SF_INT,
741 IX86_BUILTIN_GATHERSIV4SF);
743 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv8sf",
744 V8SF_FTYPE_V8SF_PCFLOAT_V8SI_V8SF_INT,
745 IX86_BUILTIN_GATHERSIV8SF);
747 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4sf",
748 V4SF_FTYPE_V4SF_PCFLOAT_V2DI_V4SF_INT,
749 IX86_BUILTIN_GATHERDIV4SF);
751 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4sf256",
752 V4SF_FTYPE_V4SF_PCFLOAT_V4DI_V4SF_INT,
753 IX86_BUILTIN_GATHERDIV8SF);
755 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv2di",
756 V2DI_FTYPE_V2DI_PCINT64_V4SI_V2DI_INT,
757 IX86_BUILTIN_GATHERSIV2DI);
759 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4di",
760 V4DI_FTYPE_V4DI_PCINT64_V4SI_V4DI_INT,
761 IX86_BUILTIN_GATHERSIV4DI);
763 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv2di",
764 V2DI_FTYPE_V2DI_PCINT64_V2DI_V2DI_INT,
765 IX86_BUILTIN_GATHERDIV2DI);
767 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4di",
768 V4DI_FTYPE_V4DI_PCINT64_V4DI_V4DI_INT,
769 IX86_BUILTIN_GATHERDIV4DI);
771 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv4si",
772 V4SI_FTYPE_V4SI_PCINT_V4SI_V4SI_INT,
773 IX86_BUILTIN_GATHERSIV4SI);
775 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gathersiv8si",
776 V8SI_FTYPE_V8SI_PCINT_V8SI_V8SI_INT,
777 IX86_BUILTIN_GATHERSIV8SI);
779 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4si",
780 V4SI_FTYPE_V4SI_PCINT_V2DI_V4SI_INT,
781 IX86_BUILTIN_GATHERDIV4SI);
783 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatherdiv4si256",
784 V4SI_FTYPE_V4SI_PCINT_V4DI_V4SI_INT,
785 IX86_BUILTIN_GATHERDIV8SI);
787 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltsiv4df ",
788 V4DF_FTYPE_V4DF_PCDOUBLE_V8SI_V4DF_INT,
789 IX86_BUILTIN_GATHERALTSIV4DF);
791 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltdiv8sf ",
792 V8SF_FTYPE_V8SF_PCFLOAT_V4DI_V8SF_INT,
793 IX86_BUILTIN_GATHERALTDIV8SF);
795 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltsiv4di ",
796 V4DI_FTYPE_V4DI_PCINT64_V8SI_V4DI_INT,
797 IX86_BUILTIN_GATHERALTSIV4DI);
799 def_builtin_pure (OPTION_MASK_ISA_AVX2, 0, "__builtin_ia32_gatheraltdiv8si ",
800 V8SI_FTYPE_V8SI_PCINT_V4DI_V8SI_INT,
801 IX86_BUILTIN_GATHERALTDIV8SI);
803 /* AVX512F */
804 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
805 "__builtin_ia32_gathersiv16sf",
806 V16SF_FTYPE_V16SF_PCVOID_V16SI_HI_INT,
807 IX86_BUILTIN_GATHER3SIV16SF);
809 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
810 "__builtin_ia32_gathersiv8df",
811 V8DF_FTYPE_V8DF_PCVOID_V8SI_QI_INT,
812 IX86_BUILTIN_GATHER3SIV8DF);
814 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
815 "__builtin_ia32_gatherdiv16sf",
816 V8SF_FTYPE_V8SF_PCVOID_V8DI_QI_INT,
817 IX86_BUILTIN_GATHER3DIV16SF);
819 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
820 "__builtin_ia32_gatherdiv8df",
821 V8DF_FTYPE_V8DF_PCVOID_V8DI_QI_INT,
822 IX86_BUILTIN_GATHER3DIV8DF);
824 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
825 "__builtin_ia32_gathersiv16si",
826 V16SI_FTYPE_V16SI_PCVOID_V16SI_HI_INT,
827 IX86_BUILTIN_GATHER3SIV16SI);
829 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
830 "__builtin_ia32_gathersiv8di",
831 V8DI_FTYPE_V8DI_PCVOID_V8SI_QI_INT,
832 IX86_BUILTIN_GATHER3SIV8DI);
834 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
835 "__builtin_ia32_gatherdiv16si",
836 V8SI_FTYPE_V8SI_PCVOID_V8DI_QI_INT,
837 IX86_BUILTIN_GATHER3DIV16SI);
839 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
840 "__builtin_ia32_gatherdiv8di",
841 V8DI_FTYPE_V8DI_PCVOID_V8DI_QI_INT,
842 IX86_BUILTIN_GATHER3DIV8DI);
844 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
845 "__builtin_ia32_gather3altsiv8df ",
846 V8DF_FTYPE_V8DF_PCDOUBLE_V16SI_QI_INT,
847 IX86_BUILTIN_GATHER3ALTSIV8DF);
849 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
850 "__builtin_ia32_gather3altdiv16sf ",
851 V16SF_FTYPE_V16SF_PCFLOAT_V8DI_HI_INT,
852 IX86_BUILTIN_GATHER3ALTDIV16SF);
854 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
855 "__builtin_ia32_gather3altsiv8di ",
856 V8DI_FTYPE_V8DI_PCINT64_V16SI_QI_INT,
857 IX86_BUILTIN_GATHER3ALTSIV8DI);
859 def_builtin_pure (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
860 "__builtin_ia32_gather3altdiv16si ",
861 V16SI_FTYPE_V16SI_PCINT_V8DI_HI_INT,
862 IX86_BUILTIN_GATHER3ALTDIV16SI);
864 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
865 "__builtin_ia32_scattersiv16sf",
866 VOID_FTYPE_PVOID_HI_V16SI_V16SF_INT,
867 IX86_BUILTIN_SCATTERSIV16SF);
869 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
870 "__builtin_ia32_scattersiv8df",
871 VOID_FTYPE_PVOID_QI_V8SI_V8DF_INT,
872 IX86_BUILTIN_SCATTERSIV8DF);
874 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
875 "__builtin_ia32_scatterdiv16sf",
876 VOID_FTYPE_PVOID_QI_V8DI_V8SF_INT,
877 IX86_BUILTIN_SCATTERDIV16SF);
879 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
880 "__builtin_ia32_scatterdiv8df",
881 VOID_FTYPE_PVOID_QI_V8DI_V8DF_INT,
882 IX86_BUILTIN_SCATTERDIV8DF);
884 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
885 "__builtin_ia32_scattersiv16si",
886 VOID_FTYPE_PVOID_HI_V16SI_V16SI_INT,
887 IX86_BUILTIN_SCATTERSIV16SI);
889 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
890 "__builtin_ia32_scattersiv8di",
891 VOID_FTYPE_PVOID_QI_V8SI_V8DI_INT,
892 IX86_BUILTIN_SCATTERSIV8DI);
894 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
895 "__builtin_ia32_scatterdiv16si",
896 VOID_FTYPE_PVOID_QI_V8DI_V8SI_INT,
897 IX86_BUILTIN_SCATTERDIV16SI);
899 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
900 "__builtin_ia32_scatterdiv8di",
901 VOID_FTYPE_PVOID_QI_V8DI_V8DI_INT,
902 IX86_BUILTIN_SCATTERDIV8DI);
904 /* AVX512VL */
905 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv2df",
906 V2DF_FTYPE_V2DF_PCVOID_V4SI_QI_INT,
907 IX86_BUILTIN_GATHER3SIV2DF);
909 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4df",
910 V4DF_FTYPE_V4DF_PCVOID_V4SI_QI_INT,
911 IX86_BUILTIN_GATHER3SIV4DF);
913 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div2df",
914 V2DF_FTYPE_V2DF_PCVOID_V2DI_QI_INT,
915 IX86_BUILTIN_GATHER3DIV2DF);
917 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4df",
918 V4DF_FTYPE_V4DF_PCVOID_V4DI_QI_INT,
919 IX86_BUILTIN_GATHER3DIV4DF);
921 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4sf",
922 V4SF_FTYPE_V4SF_PCVOID_V4SI_QI_INT,
923 IX86_BUILTIN_GATHER3SIV4SF);
925 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv8sf",
926 V8SF_FTYPE_V8SF_PCVOID_V8SI_QI_INT,
927 IX86_BUILTIN_GATHER3SIV8SF);
929 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4sf",
930 V4SF_FTYPE_V4SF_PCVOID_V2DI_QI_INT,
931 IX86_BUILTIN_GATHER3DIV4SF);
933 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div8sf",
934 V4SF_FTYPE_V4SF_PCVOID_V4DI_QI_INT,
935 IX86_BUILTIN_GATHER3DIV8SF);
937 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv2di",
938 V2DI_FTYPE_V2DI_PCVOID_V4SI_QI_INT,
939 IX86_BUILTIN_GATHER3SIV2DI);
941 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4di",
942 V4DI_FTYPE_V4DI_PCVOID_V4SI_QI_INT,
943 IX86_BUILTIN_GATHER3SIV4DI);
945 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div2di",
946 V2DI_FTYPE_V2DI_PCVOID_V2DI_QI_INT,
947 IX86_BUILTIN_GATHER3DIV2DI);
949 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4di",
950 V4DI_FTYPE_V4DI_PCVOID_V4DI_QI_INT,
951 IX86_BUILTIN_GATHER3DIV4DI);
953 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv4si",
954 V4SI_FTYPE_V4SI_PCVOID_V4SI_QI_INT,
955 IX86_BUILTIN_GATHER3SIV4SI);
957 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3siv8si",
958 V8SI_FTYPE_V8SI_PCVOID_V8SI_QI_INT,
959 IX86_BUILTIN_GATHER3SIV8SI);
961 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div4si",
962 V4SI_FTYPE_V4SI_PCVOID_V2DI_QI_INT,
963 IX86_BUILTIN_GATHER3DIV4SI);
965 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3div8si",
966 V4SI_FTYPE_V4SI_PCVOID_V4DI_QI_INT,
967 IX86_BUILTIN_GATHER3DIV8SI);
969 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altsiv4df ",
970 V4DF_FTYPE_V4DF_PCDOUBLE_V8SI_QI_INT,
971 IX86_BUILTIN_GATHER3ALTSIV4DF);
973 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altdiv8sf ",
974 V8SF_FTYPE_V8SF_PCFLOAT_V4DI_QI_INT,
975 IX86_BUILTIN_GATHER3ALTDIV8SF);
977 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altsiv4di ",
978 V4DI_FTYPE_V4DI_PCINT64_V8SI_QI_INT,
979 IX86_BUILTIN_GATHER3ALTSIV4DI);
981 def_builtin_pure (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_gather3altdiv8si ",
982 V8SI_FTYPE_V8SI_PCINT_V4DI_QI_INT,
983 IX86_BUILTIN_GATHER3ALTDIV8SI);
985 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv8sf",
986 VOID_FTYPE_PVOID_QI_V8SI_V8SF_INT,
987 IX86_BUILTIN_SCATTERSIV8SF);
989 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4sf",
990 VOID_FTYPE_PVOID_QI_V4SI_V4SF_INT,
991 IX86_BUILTIN_SCATTERSIV4SF);
993 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4df",
994 VOID_FTYPE_PVOID_QI_V4SI_V4DF_INT,
995 IX86_BUILTIN_SCATTERSIV4DF);
997 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv2df",
998 VOID_FTYPE_PVOID_QI_V4SI_V2DF_INT,
999 IX86_BUILTIN_SCATTERSIV2DF);
1001 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv8sf",
1002 VOID_FTYPE_PVOID_QI_V4DI_V4SF_INT,
1003 IX86_BUILTIN_SCATTERDIV8SF);
1005 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4sf",
1006 VOID_FTYPE_PVOID_QI_V2DI_V4SF_INT,
1007 IX86_BUILTIN_SCATTERDIV4SF);
1009 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4df",
1010 VOID_FTYPE_PVOID_QI_V4DI_V4DF_INT,
1011 IX86_BUILTIN_SCATTERDIV4DF);
1013 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv2df",
1014 VOID_FTYPE_PVOID_QI_V2DI_V2DF_INT,
1015 IX86_BUILTIN_SCATTERDIV2DF);
1017 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv8si",
1018 VOID_FTYPE_PVOID_QI_V8SI_V8SI_INT,
1019 IX86_BUILTIN_SCATTERSIV8SI);
1021 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4si",
1022 VOID_FTYPE_PVOID_QI_V4SI_V4SI_INT,
1023 IX86_BUILTIN_SCATTERSIV4SI);
1025 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv4di",
1026 VOID_FTYPE_PVOID_QI_V4SI_V4DI_INT,
1027 IX86_BUILTIN_SCATTERSIV4DI);
1029 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scattersiv2di",
1030 VOID_FTYPE_PVOID_QI_V4SI_V2DI_INT,
1031 IX86_BUILTIN_SCATTERSIV2DI);
1033 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv8si",
1034 VOID_FTYPE_PVOID_QI_V4DI_V4SI_INT,
1035 IX86_BUILTIN_SCATTERDIV8SI);
1037 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4si",
1038 VOID_FTYPE_PVOID_QI_V2DI_V4SI_INT,
1039 IX86_BUILTIN_SCATTERDIV4SI);
1041 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv4di",
1042 VOID_FTYPE_PVOID_QI_V4DI_V4DI_INT,
1043 IX86_BUILTIN_SCATTERDIV4DI);
1045 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatterdiv2di",
1046 VOID_FTYPE_PVOID_QI_V2DI_V2DI_INT,
1047 IX86_BUILTIN_SCATTERDIV2DI);
1049 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
1050 "__builtin_ia32_scatteraltsiv8df ",
1051 VOID_FTYPE_PDOUBLE_QI_V16SI_V8DF_INT,
1052 IX86_BUILTIN_SCATTERALTSIV8DF);
1054 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
1055 "__builtin_ia32_scatteraltdiv16sf ",
1056 VOID_FTYPE_PFLOAT_HI_V8DI_V16SF_INT,
1057 IX86_BUILTIN_SCATTERALTDIV16SF);
1059 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
1060 "__builtin_ia32_scatteraltsiv8di ",
1061 VOID_FTYPE_PLONGLONG_QI_V16SI_V8DI_INT,
1062 IX86_BUILTIN_SCATTERALTSIV8DI);
1064 def_builtin (OPTION_MASK_ISA_AVX512F, OPTION_MASK_ISA2_EVEX512,
1065 "__builtin_ia32_scatteraltdiv16si ",
1066 VOID_FTYPE_PINT_HI_V8DI_V16SI_INT,
1067 IX86_BUILTIN_SCATTERALTDIV16SI);
1069 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv4df ",
1070 VOID_FTYPE_PDOUBLE_QI_V8SI_V4DF_INT,
1071 IX86_BUILTIN_SCATTERALTSIV4DF);
1073 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv8sf ",
1074 VOID_FTYPE_PFLOAT_QI_V4DI_V8SF_INT,
1075 IX86_BUILTIN_SCATTERALTDIV8SF);
1077 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv4di ",
1078 VOID_FTYPE_PLONGLONG_QI_V8SI_V4DI_INT,
1079 IX86_BUILTIN_SCATTERALTSIV4DI);
1081 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv8si ",
1082 VOID_FTYPE_PINT_QI_V4DI_V8SI_INT,
1083 IX86_BUILTIN_SCATTERALTDIV8SI);
1085 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv2df ",
1086 VOID_FTYPE_PDOUBLE_QI_V4SI_V2DF_INT,
1087 IX86_BUILTIN_SCATTERALTSIV2DF);
1089 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv4sf ",
1090 VOID_FTYPE_PFLOAT_QI_V2DI_V4SF_INT,
1091 IX86_BUILTIN_SCATTERALTDIV4SF);
1093 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltsiv2di ",
1094 VOID_FTYPE_PLONGLONG_QI_V4SI_V2DI_INT,
1095 IX86_BUILTIN_SCATTERALTSIV2DI);
1097 def_builtin (OPTION_MASK_ISA_AVX512VL, 0, "__builtin_ia32_scatteraltdiv4si ",
1098 VOID_FTYPE_PINT_QI_V2DI_V4SI_INT,
1099 IX86_BUILTIN_SCATTERALTDIV4SI);
1101 /* SHA */
1102 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1msg1",
1103 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1MSG1);
1104 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1msg2",
1105 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1MSG2);
1106 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1nexte",
1107 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA1NEXTE);
1108 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha1rnds4",
1109 V4SI_FTYPE_V4SI_V4SI_INT, IX86_BUILTIN_SHA1RNDS4);
1110 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256msg1",
1111 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA256MSG1);
1112 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256msg2",
1113 V4SI_FTYPE_V4SI_V4SI, IX86_BUILTIN_SHA256MSG2);
1114 def_builtin_const (OPTION_MASK_ISA_SHA, 0, "__builtin_ia32_sha256rnds2",
1115 V4SI_FTYPE_V4SI_V4SI_V4SI, IX86_BUILTIN_SHA256RNDS2);
1117 /* RTM. */
1118 def_builtin (OPTION_MASK_ISA_RTM, 0, "__builtin_ia32_xabort",
1119 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_XABORT);
1121 /* MMX access to the vec_init patterns. */
1122 def_builtin_const (OPTION_MASK_ISA_MMX, 0,
1123 "__builtin_ia32_vec_init_v2si",
1124 V2SI_FTYPE_INT_INT, IX86_BUILTIN_VEC_INIT_V2SI);
1126 def_builtin_const (OPTION_MASK_ISA_MMX, 0,
1127 "__builtin_ia32_vec_init_v4hi",
1128 V4HI_FTYPE_HI_HI_HI_HI,
1129 IX86_BUILTIN_VEC_INIT_V4HI);
1131 def_builtin_const (OPTION_MASK_ISA_MMX, 0,
1132 "__builtin_ia32_vec_init_v8qi",
1133 V8QI_FTYPE_QI_QI_QI_QI_QI_QI_QI_QI,
1134 IX86_BUILTIN_VEC_INIT_V8QI);
1136 /* Access to the vec_extract patterns. */
1137 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v2df",
1138 DOUBLE_FTYPE_V2DF_INT, IX86_BUILTIN_VEC_EXT_V2DF);
1139 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v2di",
1140 DI_FTYPE_V2DI_INT, IX86_BUILTIN_VEC_EXT_V2DI);
1141 def_builtin_const (OPTION_MASK_ISA_SSE, 0, "__builtin_ia32_vec_ext_v4sf",
1142 FLOAT_FTYPE_V4SF_INT, IX86_BUILTIN_VEC_EXT_V4SF);
1143 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v4si",
1144 SI_FTYPE_V4SI_INT, IX86_BUILTIN_VEC_EXT_V4SI);
1145 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v8hi",
1146 HI_FTYPE_V8HI_INT, IX86_BUILTIN_VEC_EXT_V8HI);
1148 def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
1149 /* As it uses V4HImode, we have to require -mmmx too. */
1150 | OPTION_MASK_ISA_MMX, 0,
1151 "__builtin_ia32_vec_ext_v4hi",
1152 HI_FTYPE_V4HI_INT, IX86_BUILTIN_VEC_EXT_V4HI);
1154 def_builtin_const (OPTION_MASK_ISA_MMX, 0,
1155 "__builtin_ia32_vec_ext_v2si",
1156 SI_FTYPE_V2SI_INT, IX86_BUILTIN_VEC_EXT_V2SI);
1158 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_ext_v16qi",
1159 QI_FTYPE_V16QI_INT, IX86_BUILTIN_VEC_EXT_V16QI);
1161 /* Access to the vec_set patterns. */
1162 def_builtin_const (OPTION_MASK_ISA_SSE4_1 | OPTION_MASK_ISA_64BIT, 0,
1163 "__builtin_ia32_vec_set_v2di",
1164 V2DI_FTYPE_V2DI_DI_INT, IX86_BUILTIN_VEC_SET_V2DI);
1166 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v4sf",
1167 V4SF_FTYPE_V4SF_FLOAT_INT, IX86_BUILTIN_VEC_SET_V4SF);
1169 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v4si",
1170 V4SI_FTYPE_V4SI_SI_INT, IX86_BUILTIN_VEC_SET_V4SI);
1172 def_builtin_const (OPTION_MASK_ISA_SSE2, 0, "__builtin_ia32_vec_set_v8hi",
1173 V8HI_FTYPE_V8HI_HI_INT, IX86_BUILTIN_VEC_SET_V8HI);
1175 def_builtin_const (OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
1176 /* As it uses V4HImode, we have to require -mmmx too. */
1177 | OPTION_MASK_ISA_MMX, 0,
1178 "__builtin_ia32_vec_set_v4hi",
1179 V4HI_FTYPE_V4HI_HI_INT, IX86_BUILTIN_VEC_SET_V4HI);
1181 def_builtin_const (OPTION_MASK_ISA_SSE4_1, 0, "__builtin_ia32_vec_set_v16qi",
1182 V16QI_FTYPE_V16QI_QI_INT, IX86_BUILTIN_VEC_SET_V16QI);
1184 /* RDSEED */
1185 def_builtin (OPTION_MASK_ISA_RDSEED, 0, "__builtin_ia32_rdseed_hi_step",
1186 INT_FTYPE_PUSHORT, IX86_BUILTIN_RDSEED16_STEP);
1187 def_builtin (OPTION_MASK_ISA_RDSEED, 0, "__builtin_ia32_rdseed_si_step",
1188 INT_FTYPE_PUNSIGNED, IX86_BUILTIN_RDSEED32_STEP);
1189 def_builtin (OPTION_MASK_ISA_RDSEED | OPTION_MASK_ISA_64BIT, 0,
1190 "__builtin_ia32_rdseed_di_step",
1191 INT_FTYPE_PULONGLONG, IX86_BUILTIN_RDSEED64_STEP);
1193 /* ADCX */
1194 def_builtin (0, 0, "__builtin_ia32_addcarryx_u32",
1195 UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_ADDCARRYX32);
1196 def_builtin (OPTION_MASK_ISA_64BIT, 0,
1197 "__builtin_ia32_addcarryx_u64",
1198 UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
1199 IX86_BUILTIN_ADDCARRYX64);
1201 /* SBB */
1202 def_builtin (0, 0, "__builtin_ia32_sbb_u32",
1203 UCHAR_FTYPE_UCHAR_UINT_UINT_PUNSIGNED, IX86_BUILTIN_SBB32);
1204 def_builtin (OPTION_MASK_ISA_64BIT, 0,
1205 "__builtin_ia32_sbb_u64",
1206 UCHAR_FTYPE_UCHAR_ULONGLONG_ULONGLONG_PULONGLONG,
1207 IX86_BUILTIN_SBB64);
1209 /* Read/write FLAGS. */
1210 if (TARGET_64BIT)
1212 def_builtin (OPTION_MASK_ISA_64BIT, 0, "__builtin_ia32_readeflags_u64",
1213 UINT64_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
1214 def_builtin (OPTION_MASK_ISA_64BIT, 0, "__builtin_ia32_writeeflags_u64",
1215 VOID_FTYPE_UINT64, IX86_BUILTIN_WRITE_FLAGS);
1217 else
1219 def_builtin (0, 0, "__builtin_ia32_readeflags_u32",
1220 UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
1221 def_builtin (0, 0, "__builtin_ia32_writeeflags_u32",
1222 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_WRITE_FLAGS);
1225 /* CLFLUSHOPT. */
1226 def_builtin (OPTION_MASK_ISA_CLFLUSHOPT, 0, "__builtin_ia32_clflushopt",
1227 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLFLUSHOPT);
1229 /* CLWB. */
1230 def_builtin (OPTION_MASK_ISA_CLWB, 0, "__builtin_ia32_clwb",
1231 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLWB);
1233 /* MONITORX and MWAITX. */
1234 def_builtin (0, OPTION_MASK_ISA2_MWAITX, "__builtin_ia32_monitorx",
1235 VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITORX);
1236 def_builtin (0, OPTION_MASK_ISA2_MWAITX, "__builtin_ia32_mwaitx",
1237 VOID_FTYPE_UNSIGNED_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAITX);
1239 /* CLZERO. */
1240 def_builtin (0, OPTION_MASK_ISA2_CLZERO, "__builtin_ia32_clzero",
1241 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLZERO);
1243 /* WAITPKG. */
1244 def_builtin (0, OPTION_MASK_ISA2_WAITPKG, "__builtin_ia32_umonitor",
1245 VOID_FTYPE_PVOID, IX86_BUILTIN_UMONITOR);
1246 def_builtin (0, OPTION_MASK_ISA2_WAITPKG, "__builtin_ia32_umwait",
1247 UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_UMWAIT);
1248 def_builtin (0, OPTION_MASK_ISA2_WAITPKG, "__builtin_ia32_tpause",
1249 UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_TPAUSE);
1251 /* UINTR. */
1252 def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR,
1253 "__builtin_ia32_testui",
1254 UINT8_FTYPE_VOID, IX86_BUILTIN_TESTUI);
1256 /* USER_MSR. */
1257 def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_USER_MSR,
1258 "__builtin_ia32_urdmsr", UINT64_FTYPE_UINT64,
1259 IX86_BUILTIN_URDMSR);
1260 def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_USER_MSR,
1261 "__builtin_ia32_uwrmsr", VOID_FTYPE_UINT64_UINT64,
1262 IX86_BUILTIN_UWRMSR);
1264 /* CLDEMOTE. */
1265 def_builtin (0, OPTION_MASK_ISA2_CLDEMOTE, "__builtin_ia32_cldemote",
1266 VOID_FTYPE_PCVOID, IX86_BUILTIN_CLDEMOTE);
1268 /* Add FMA4 multi-arg argument instructions */
1269 for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++)
1271 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_MULTI_ARG_FIRST, i);
1272 if (d->name == 0)
1273 continue;
1275 ftype = (enum ix86_builtin_func_type) d->flag;
1276 def_builtin_const (d->mask, d->mask2, d->name, ftype, d->code);
1278 BDESC_VERIFYS (IX86_BUILTIN__BDESC_MULTI_ARG_LAST,
1279 IX86_BUILTIN__BDESC_MULTI_ARG_FIRST,
1280 ARRAY_SIZE (bdesc_multi_arg) - 1);
1282 /* Add CET inrinsics. */
1283 for (i = 0, d = bdesc_cet; i < ARRAY_SIZE (bdesc_cet); i++, d++)
1285 BDESC_VERIFY (d->code, IX86_BUILTIN__BDESC_CET_FIRST, i);
1286 if (d->name == 0)
1287 continue;
1289 ftype = (enum ix86_builtin_func_type) d->flag;
1290 def_builtin (d->mask, d->mask2, d->name, ftype, d->code);
1292 BDESC_VERIFYS (IX86_BUILTIN__BDESC_CET_LAST,
1293 IX86_BUILTIN__BDESC_CET_FIRST,
1294 ARRAY_SIZE (bdesc_cet) - 1);
1297 #undef BDESC_VERIFY
1298 #undef BDESC_VERIFYS
1300 /* Make builtins to detect cpu type and features supported. NAME is
1301 the builtin name, CODE is the builtin code, and FTYPE is the function
1302 type of the builtin. */
1304 static void
1305 make_cpu_type_builtin (const char* name, int code,
1306 enum ix86_builtin_func_type ftype, bool is_const)
1308 tree decl;
1309 tree type;
1311 type = ix86_get_builtin_func_type (ftype);
1312 decl = add_builtin_function (name, type, code, BUILT_IN_MD,
1313 NULL, NULL_TREE);
1314 gcc_assert (decl != NULL_TREE);
1315 ix86_builtins[(int) code] = decl;
1316 TREE_READONLY (decl) = is_const;
1319 /* Make builtins to get CPU type and features supported. The created
1320 builtins are :
1322 __builtin_cpu_init (), to detect cpu type and features,
1323 __builtin_cpu_is ("<CPUNAME>"), to check if cpu is of type <CPUNAME>,
1324 __builtin_cpu_supports ("<FEATURE>"), to check if cpu supports <FEATURE>
1327 static void
1328 ix86_init_platform_type_builtins (void)
1330 make_cpu_type_builtin ("__builtin_cpu_init", IX86_BUILTIN_CPU_INIT,
1331 INT_FTYPE_VOID, false);
1332 make_cpu_type_builtin ("__builtin_cpu_is", IX86_BUILTIN_CPU_IS,
1333 INT_FTYPE_PCCHAR, true);
1334 make_cpu_type_builtin ("__builtin_cpu_supports", IX86_BUILTIN_CPU_SUPPORTS,
1335 INT_FTYPE_PCCHAR, true);
1338 /* Internal method for ix86_init_builtins. */
1340 static void
1341 ix86_init_builtins_va_builtins_abi (void)
1343 tree ms_va_ref, sysv_va_ref;
1344 tree fnvoid_va_end_ms, fnvoid_va_end_sysv;
1345 tree fnvoid_va_start_ms, fnvoid_va_start_sysv;
1346 tree fnvoid_va_copy_ms, fnvoid_va_copy_sysv;
1347 tree fnattr_ms = NULL_TREE, fnattr_sysv = NULL_TREE;
1349 if (!TARGET_64BIT)
1350 return;
1351 fnattr_ms = build_tree_list (get_identifier ("ms_abi"), NULL_TREE);
1352 fnattr_sysv = build_tree_list (get_identifier ("sysv_abi"), NULL_TREE);
1353 ms_va_ref = build_reference_type (ms_va_list_type_node);
1354 sysv_va_ref = build_pointer_type (TREE_TYPE (sysv_va_list_type_node));
1356 fnvoid_va_end_ms = build_function_type_list (void_type_node, ms_va_ref,
1357 NULL_TREE);
1358 fnvoid_va_start_ms
1359 = build_varargs_function_type_list (void_type_node, ms_va_ref, NULL_TREE);
1360 fnvoid_va_end_sysv
1361 = build_function_type_list (void_type_node, sysv_va_ref, NULL_TREE);
1362 fnvoid_va_start_sysv
1363 = build_varargs_function_type_list (void_type_node, sysv_va_ref,
1364 NULL_TREE);
1365 fnvoid_va_copy_ms
1366 = build_function_type_list (void_type_node, ms_va_ref,
1367 ms_va_list_type_node, NULL_TREE);
1368 fnvoid_va_copy_sysv
1369 = build_function_type_list (void_type_node, sysv_va_ref,
1370 sysv_va_ref, NULL_TREE);
1372 add_builtin_function ("__builtin_ms_va_start", fnvoid_va_start_ms,
1373 BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_ms);
1374 add_builtin_function ("__builtin_ms_va_end", fnvoid_va_end_ms,
1375 BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_ms);
1376 add_builtin_function ("__builtin_ms_va_copy", fnvoid_va_copy_ms,
1377 BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_ms);
1378 add_builtin_function ("__builtin_sysv_va_start", fnvoid_va_start_sysv,
1379 BUILT_IN_VA_START, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1380 add_builtin_function ("__builtin_sysv_va_end", fnvoid_va_end_sysv,
1381 BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1382 add_builtin_function ("__builtin_sysv_va_copy", fnvoid_va_copy_sysv,
1383 BUILT_IN_VA_COPY, BUILT_IN_NORMAL, NULL, fnattr_sysv);
1386 static void
1387 ix86_register_float16_builtin_type (void)
1389 /* Provide the _Float16 type and float16_type_node if needed so that
1390 it can be used in AVX512FP16 intrinsics and builtins. */
1391 if (!float16_type_node)
1393 ix86_float16_type_node = make_node (REAL_TYPE);
1394 TYPE_PRECISION (ix86_float16_type_node) = 16;
1395 SET_TYPE_MODE (ix86_float16_type_node, HFmode);
1396 layout_type (ix86_float16_type_node);
1398 else
1399 ix86_float16_type_node = float16_type_node;
1401 if (!maybe_get_identifier ("_Float16"))
1402 lang_hooks.types.register_builtin_type (ix86_float16_type_node,
1403 "_Float16");
1406 static void
1407 ix86_register_bf16_builtin_type (void)
1409 if (bfloat16_type_node == NULL_TREE)
1411 ix86_bf16_type_node = make_node (REAL_TYPE);
1412 TYPE_PRECISION (ix86_bf16_type_node) = 16;
1413 SET_TYPE_MODE (ix86_bf16_type_node, BFmode);
1414 layout_type (ix86_bf16_type_node);
1416 else
1417 ix86_bf16_type_node = bfloat16_type_node;
1419 if (!maybe_get_identifier ("__bf16"))
1420 lang_hooks.types.register_builtin_type (ix86_bf16_type_node, "__bf16");
1423 static void
1424 ix86_init_builtin_types (void)
1426 tree float80_type_node, const_string_type_node;
1428 /* The __float80 type. */
1429 float80_type_node = long_double_type_node;
1430 if (TYPE_MODE (float80_type_node) != XFmode)
1432 if (float64x_type_node != NULL_TREE
1433 && TYPE_MODE (float64x_type_node) == XFmode)
1434 float80_type_node = float64x_type_node;
1435 else
1437 /* The __float80 type. */
1438 float80_type_node = make_node (REAL_TYPE);
1440 TYPE_PRECISION (float80_type_node) = 80;
1441 layout_type (float80_type_node);
1444 lang_hooks.types.register_builtin_type (float80_type_node, "__float80");
1446 /* The __float128 type. The node has already been created as
1447 _Float128, so for C we only need to register the __float128 name for
1448 it. For C++, we create a distinct type which will mangle differently
1449 (g) vs. _Float128 (DF128_) and behave backwards compatibly. */
1450 if (float128t_type_node == NULL_TREE)
1452 float128t_type_node = make_node (REAL_TYPE);
1453 TYPE_PRECISION (float128t_type_node)
1454 = TYPE_PRECISION (float128_type_node);
1455 SET_TYPE_MODE (float128t_type_node, TYPE_MODE (float128_type_node));
1456 layout_type (float128t_type_node);
1458 lang_hooks.types.register_builtin_type (float128t_type_node, "__float128");
1460 ix86_register_float16_builtin_type ();
1462 ix86_register_bf16_builtin_type ();
1464 const_string_type_node
1465 = build_pointer_type (build_qualified_type
1466 (char_type_node, TYPE_QUAL_CONST));
1468 /* This macro is built by i386-builtin-types.awk. */
1469 DEFINE_BUILTIN_PRIMITIVE_TYPES;
1472 void
1473 ix86_init_builtins (void)
1475 tree ftype, decl;
1477 ix86_init_builtin_types ();
1479 /* Builtins to get CPU type and features. */
1480 ix86_init_platform_type_builtins ();
1482 /* TFmode support builtins. */
1483 def_builtin_const (0, 0, "__builtin_infq",
1484 FLOAT128_FTYPE_VOID, IX86_BUILTIN_INFQ);
1485 def_builtin_const (0, 0, "__builtin_huge_valq",
1486 FLOAT128_FTYPE_VOID, IX86_BUILTIN_HUGE_VALQ);
1488 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_CONST_STRING);
1489 decl = add_builtin_function ("__builtin_nanq", ftype, IX86_BUILTIN_NANQ,
1490 BUILT_IN_MD, "nanq", NULL_TREE);
1491 TREE_READONLY (decl) = 1;
1492 ix86_builtins[(int) IX86_BUILTIN_NANQ] = decl;
1494 decl = add_builtin_function ("__builtin_nansq", ftype, IX86_BUILTIN_NANSQ,
1495 BUILT_IN_MD, "nansq", NULL_TREE);
1496 TREE_READONLY (decl) = 1;
1497 ix86_builtins[(int) IX86_BUILTIN_NANSQ] = decl;
1499 /* We will expand them to normal call if SSE isn't available since
1500 they are used by libgcc. */
1501 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128);
1502 decl = add_builtin_function ("__builtin_fabsq", ftype, IX86_BUILTIN_FABSQ,
1503 BUILT_IN_MD, "__fabstf2", NULL_TREE);
1504 TREE_READONLY (decl) = 1;
1505 ix86_builtins[(int) IX86_BUILTIN_FABSQ] = decl;
1507 ftype = ix86_get_builtin_func_type (FLOAT128_FTYPE_FLOAT128_FLOAT128);
1508 decl = add_builtin_function ("__builtin_copysignq", ftype,
1509 IX86_BUILTIN_COPYSIGNQ, BUILT_IN_MD,
1510 "__copysigntf3", NULL_TREE);
1511 TREE_READONLY (decl) = 1;
1512 ix86_builtins[(int) IX86_BUILTIN_COPYSIGNQ] = decl;
1514 ix86_init_tm_builtins ();
1515 ix86_init_mmx_sse_builtins ();
1517 if (TARGET_LP64)
1518 ix86_init_builtins_va_builtins_abi ();
1520 #ifdef SUBTARGET_INIT_BUILTINS
1521 SUBTARGET_INIT_BUILTINS;
1522 #endif
1525 /* Return the ix86 builtin for CODE. */
1527 tree
1528 ix86_builtin_decl (unsigned code, bool)
1530 if (code >= IX86_BUILTIN_MAX)
1531 return error_mark_node;
1533 return ix86_builtins[code];
1536 /* This returns the target-specific builtin with code CODE if
1537 current_function_decl has visibility on this builtin, which is checked
1538 using isa flags. Returns NULL_TREE otherwise. */
1540 static tree ix86_get_builtin (enum ix86_builtins code)
1542 struct cl_target_option *opts;
1543 tree target_tree = NULL_TREE;
1545 /* Determine the isa flags of current_function_decl. */
1547 if (current_function_decl)
1548 target_tree = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl);
1550 if (target_tree == NULL)
1551 target_tree = target_option_default_node;
1553 opts = TREE_TARGET_OPTION (target_tree);
1555 if ((ix86_builtins_isa[(int) code].isa & opts->x_ix86_isa_flags)
1556 || (ix86_builtins_isa[(int) code].isa2 & opts->x_ix86_isa_flags2))
1557 return ix86_builtin_decl (code, true);
1558 else
1559 return NULL_TREE;
1562 /* Vectorization library interface and handlers. */
1563 tree (*ix86_veclib_handler) (combined_fn, tree, tree);
1565 /* Returns a function decl for a vectorized version of the combined function
1566 with combined_fn code FN and the result vector type TYPE, or NULL_TREE
1567 if it is not available. */
1569 tree
1570 ix86_builtin_vectorized_function (unsigned int fn, tree type_out,
1571 tree type_in)
1573 machine_mode in_mode, out_mode;
1574 int in_n, out_n;
1576 if (TREE_CODE (type_out) != VECTOR_TYPE
1577 || TREE_CODE (type_in) != VECTOR_TYPE)
1578 return NULL_TREE;
1580 out_mode = TYPE_MODE (TREE_TYPE (type_out));
1581 out_n = TYPE_VECTOR_SUBPARTS (type_out);
1582 in_mode = TYPE_MODE (TREE_TYPE (type_in));
1583 in_n = TYPE_VECTOR_SUBPARTS (type_in);
1585 switch (fn)
1587 CASE_CFN_IFLOOR:
1588 CASE_CFN_LFLOOR:
1589 /* The round insn does not trap on denormals. */
1590 if (flag_trapping_math || !TARGET_SSE4_1)
1591 break;
1593 /* PR106910, currently vectorizer doesn't go direct internal fn way
1594 when out_n != in_n, so let's still keep this.
1595 Otherwise, it relies on expander of
1596 lceilmn2/lfloormn2/lroundmn2/lrintmn2. */
1597 if (out_mode == SImode && in_mode == DFmode)
1599 if (out_n == 4 && in_n == 2)
1600 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX);
1601 else if (out_n == 8 && in_n == 4)
1602 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX256);
1603 else if (out_n == 16 && in_n == 8)
1604 return ix86_get_builtin (IX86_BUILTIN_FLOORPD_VEC_PACK_SFIX512);
1606 break;
1608 CASE_CFN_ICEIL:
1609 CASE_CFN_LCEIL:
1610 /* The round insn does not trap on denormals. */
1611 if (flag_trapping_math || !TARGET_SSE4_1)
1612 break;
1614 if (out_mode == SImode && in_mode == DFmode)
1616 if (out_n == 4 && in_n == 2)
1617 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX);
1618 else if (out_n == 8 && in_n == 4)
1619 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX256);
1620 else if (out_n == 16 && in_n == 8)
1621 return ix86_get_builtin (IX86_BUILTIN_CEILPD_VEC_PACK_SFIX512);
1623 break;
1625 CASE_CFN_IRINT:
1626 CASE_CFN_LRINT:
1627 if (out_mode == SImode && in_mode == DFmode)
1629 if (out_n == 4 && in_n == 2)
1630 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX);
1631 else if (out_n == 8 && in_n == 4)
1632 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX256);
1633 else if (out_n == 16 && in_n == 8)
1634 return ix86_get_builtin (IX86_BUILTIN_VEC_PACK_SFIX512);
1636 break;
1638 CASE_CFN_IROUND:
1639 CASE_CFN_LROUND:
1640 /* The round insn does not trap on denormals. */
1641 if (flag_trapping_math || !TARGET_SSE4_1)
1642 break;
1644 if (out_mode == SImode && in_mode == DFmode)
1646 if (out_n == 4 && in_n == 2)
1647 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX);
1648 else if (out_n == 8 && in_n == 4)
1649 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX256);
1650 else if (out_n == 16 && in_n == 8)
1651 return ix86_get_builtin (IX86_BUILTIN_ROUNDPD_AZ_VEC_PACK_SFIX512);
1653 break;
1656 default:
1657 break;
1660 /* Dispatch to a handler for a vectorization library. */
1661 if (ix86_veclib_handler)
1662 return ix86_veclib_handler (combined_fn (fn), type_out, type_in);
1664 return NULL_TREE;
1667 /* Returns a decl of a function that implements gather load with
1668 memory type MEM_VECTYPE and index type INDEX_VECTYPE and SCALE.
1669 Return NULL_TREE if it is not available. */
1671 tree
1672 ix86_vectorize_builtin_gather (const_tree mem_vectype,
1673 const_tree index_type, int scale)
1675 bool si;
1676 enum ix86_builtins code;
1677 const machine_mode mode = TYPE_MODE (TREE_TYPE (mem_vectype));
1679 if ((!TARGET_AVX512F || !TARGET_EVEX512) && GET_MODE_SIZE (mode) == 64)
1680 return NULL_TREE;
1682 if (! TARGET_AVX2
1683 || (known_eq (TYPE_VECTOR_SUBPARTS (mem_vectype), 2u)
1684 ? !TARGET_USE_GATHER_2PARTS
1685 : (known_eq (TYPE_VECTOR_SUBPARTS (mem_vectype), 4u)
1686 ? !TARGET_USE_GATHER_4PARTS
1687 : !TARGET_USE_GATHER_8PARTS)))
1688 return NULL_TREE;
1690 if ((TREE_CODE (index_type) != INTEGER_TYPE
1691 && !POINTER_TYPE_P (index_type))
1692 || (TYPE_MODE (index_type) != SImode
1693 && TYPE_MODE (index_type) != DImode))
1694 return NULL_TREE;
1696 if (TYPE_PRECISION (index_type) > POINTER_SIZE)
1697 return NULL_TREE;
1699 /* v*gather* insn sign extends index to pointer mode. */
1700 if (TYPE_PRECISION (index_type) < POINTER_SIZE
1701 && TYPE_UNSIGNED (index_type))
1702 return NULL_TREE;
1704 if (scale <= 0
1705 || scale > 8
1706 || (scale & (scale - 1)) != 0)
1707 return NULL_TREE;
1709 si = TYPE_MODE (index_type) == SImode;
1710 switch (TYPE_MODE (mem_vectype))
1712 case E_V2DFmode:
1713 if (TARGET_AVX512VL)
1714 code = si ? IX86_BUILTIN_GATHER3SIV2DF : IX86_BUILTIN_GATHER3DIV2DF;
1715 else
1716 code = si ? IX86_BUILTIN_GATHERSIV2DF : IX86_BUILTIN_GATHERDIV2DF;
1717 break;
1718 case E_V4DFmode:
1719 if (TARGET_AVX512VL)
1720 code = si ? IX86_BUILTIN_GATHER3ALTSIV4DF : IX86_BUILTIN_GATHER3DIV4DF;
1721 else
1722 code = si ? IX86_BUILTIN_GATHERALTSIV4DF : IX86_BUILTIN_GATHERDIV4DF;
1723 break;
1724 case E_V2DImode:
1725 if (TARGET_AVX512VL)
1726 code = si ? IX86_BUILTIN_GATHER3SIV2DI : IX86_BUILTIN_GATHER3DIV2DI;
1727 else
1728 code = si ? IX86_BUILTIN_GATHERSIV2DI : IX86_BUILTIN_GATHERDIV2DI;
1729 break;
1730 case E_V4DImode:
1731 if (TARGET_AVX512VL)
1732 code = si ? IX86_BUILTIN_GATHER3ALTSIV4DI : IX86_BUILTIN_GATHER3DIV4DI;
1733 else
1734 code = si ? IX86_BUILTIN_GATHERALTSIV4DI : IX86_BUILTIN_GATHERDIV4DI;
1735 break;
1736 case E_V4SFmode:
1737 if (TARGET_AVX512VL)
1738 code = si ? IX86_BUILTIN_GATHER3SIV4SF : IX86_BUILTIN_GATHER3DIV4SF;
1739 else
1740 code = si ? IX86_BUILTIN_GATHERSIV4SF : IX86_BUILTIN_GATHERDIV4SF;
1741 break;
1742 case E_V8SFmode:
1743 if (TARGET_AVX512VL)
1744 code = si ? IX86_BUILTIN_GATHER3SIV8SF : IX86_BUILTIN_GATHER3ALTDIV8SF;
1745 else
1746 code = si ? IX86_BUILTIN_GATHERSIV8SF : IX86_BUILTIN_GATHERALTDIV8SF;
1747 break;
1748 case E_V4SImode:
1749 if (TARGET_AVX512VL)
1750 code = si ? IX86_BUILTIN_GATHER3SIV4SI : IX86_BUILTIN_GATHER3DIV4SI;
1751 else
1752 code = si ? IX86_BUILTIN_GATHERSIV4SI : IX86_BUILTIN_GATHERDIV4SI;
1753 break;
1754 case E_V8SImode:
1755 if (TARGET_AVX512VL)
1756 code = si ? IX86_BUILTIN_GATHER3SIV8SI : IX86_BUILTIN_GATHER3ALTDIV8SI;
1757 else
1758 code = si ? IX86_BUILTIN_GATHERSIV8SI : IX86_BUILTIN_GATHERALTDIV8SI;
1759 break;
1760 case E_V8DFmode:
1761 code = si ? IX86_BUILTIN_GATHER3ALTSIV8DF : IX86_BUILTIN_GATHER3DIV8DF;
1762 break;
1763 case E_V8DImode:
1764 code = si ? IX86_BUILTIN_GATHER3ALTSIV8DI : IX86_BUILTIN_GATHER3DIV8DI;
1765 break;
1766 case E_V16SFmode:
1767 code = si ? IX86_BUILTIN_GATHER3SIV16SF : IX86_BUILTIN_GATHER3ALTDIV16SF;
1768 break;
1769 case E_V16SImode:
1770 code = si ? IX86_BUILTIN_GATHER3SIV16SI : IX86_BUILTIN_GATHER3ALTDIV16SI;
1771 break;
1772 default:
1773 return NULL_TREE;
1776 return ix86_get_builtin (code);
1779 /* Returns a code for a target-specific builtin that implements
1780 reciprocal of the function, or NULL_TREE if not available. */
1782 tree
1783 ix86_builtin_reciprocal (tree fndecl)
1785 enum ix86_builtins fn_code
1786 = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
1787 switch (fn_code)
1789 /* Vectorized version of sqrt to rsqrt conversion. */
1790 case IX86_BUILTIN_SQRTPS_NR:
1791 return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR);
1793 case IX86_BUILTIN_SQRTPS_NR256:
1794 return ix86_get_builtin (IX86_BUILTIN_RSQRTPS_NR256);
1796 default:
1797 return NULL_TREE;
1801 /* This parses the attribute arguments to target in DECL and determines
1802 the right builtin to use to match the platform specification.
1803 It returns the priority value for this version decl. If PREDICATE_LIST
1804 is not NULL, it stores the list of cpu features that need to be checked
1805 before dispatching this function. */
1807 unsigned int
1808 get_builtin_code_for_version (tree decl, tree *predicate_list)
1810 tree attrs;
1811 struct cl_target_option cur_target;
1812 tree target_node;
1813 struct cl_target_option *new_target;
1814 const char *arg_str = NULL;
1815 const char *attrs_str = NULL;
1816 char *tok_str = NULL;
1817 char *token;
1819 enum feature_priority priority = P_NONE;
1821 static unsigned int NUM_FEATURES = ARRAY_SIZE (isa_names_table);
1823 unsigned int i;
1825 tree predicate_chain = NULL_TREE;
1826 tree predicate_decl, predicate_arg;
1828 attrs = lookup_attribute ("target", DECL_ATTRIBUTES (decl));
1829 gcc_assert (attrs != NULL);
1831 attrs = TREE_VALUE (TREE_VALUE (attrs));
1833 gcc_assert (TREE_CODE (attrs) == STRING_CST);
1834 attrs_str = TREE_STRING_POINTER (attrs);
1836 /* Return priority zero for default function. */
1837 if (strcmp (attrs_str, "default") == 0)
1838 return 0;
1840 /* Handle arch= if specified. For priority, set it to be 1 more than
1841 the best instruction set the processor can handle. For instance, if
1842 there is a version for atom and a version for ssse3 (the highest ISA
1843 priority for atom), the atom version must be checked for dispatch
1844 before the ssse3 version. */
1845 if (strstr (attrs_str, "arch=") != NULL)
1847 cl_target_option_save (&cur_target, &global_options,
1848 &global_options_set);
1849 target_node
1850 = ix86_valid_target_attribute_tree (decl, attrs, &global_options,
1851 &global_options_set, 0);
1853 gcc_assert (target_node);
1854 if (target_node == error_mark_node)
1855 return 0;
1856 new_target = TREE_TARGET_OPTION (target_node);
1857 gcc_assert (new_target);
1858 enum ix86_builtins builtin_fn = IX86_BUILTIN_CPU_IS;
1860 /* Special case x86-64 micro-level architectures. */
1861 const char *arch_name = attrs_str + strlen ("arch=");
1862 if (startswith (arch_name, "x86-64"))
1864 arg_str = arch_name;
1865 builtin_fn = IX86_BUILTIN_CPU_SUPPORTS;
1866 if (strcmp (arch_name, "x86-64") == 0)
1867 priority = P_X86_64_BASELINE;
1868 else if (strcmp (arch_name, "x86-64-v2") == 0)
1869 priority = P_X86_64_V2;
1870 else if (strcmp (arch_name, "x86-64-v3") == 0)
1871 priority = P_X86_64_V3;
1872 else if (strcmp (arch_name, "x86-64-v4") == 0)
1873 priority = P_X86_64_V4;
1875 else if (new_target->arch_specified && new_target->arch > 0)
1876 for (i = 0; i < pta_size; i++)
1877 if (processor_alias_table[i].processor == new_target->arch)
1879 const pta *arch_info = &processor_alias_table[i];
1880 switch (arch_info->priority)
1882 default:
1883 arg_str = arch_info->name;
1884 priority = arch_info->priority;
1885 break;
1886 case P_PROC_DYNAMIC:
1887 switch (new_target->arch)
1889 case PROCESSOR_NEHALEM:
1890 if (TARGET_PCLMUL_P (new_target->x_ix86_isa_flags))
1892 arg_str = "westmere";
1893 priority = P_PCLMUL;
1895 else
1897 /* We translate "arch=corei7" and "arch=nehalem"
1898 to "corei7" so that it will be mapped to
1899 M_INTEL_COREI7 as cpu type to cover all
1900 M_INTEL_COREI7_XXXs. */
1901 arg_str = "corei7";
1902 priority = P_PROC_SSE4_2;
1904 break;
1905 case PROCESSOR_SANDYBRIDGE:
1906 if (TARGET_F16C_P (new_target->x_ix86_isa_flags))
1907 arg_str = "ivybridge";
1908 else
1909 arg_str = "sandybridge";
1910 priority = P_PROC_AVX;
1911 break;
1912 case PROCESSOR_HASWELL:
1913 if (TARGET_ADX_P (new_target->x_ix86_isa_flags))
1914 arg_str = "broadwell";
1915 else
1916 arg_str = "haswell";
1917 priority = P_PROC_AVX2;
1918 break;
1919 case PROCESSOR_AMDFAM10:
1920 arg_str = "amdfam10h";
1921 priority = P_PROC_SSE4_A;
1922 break;
1923 default:
1924 gcc_unreachable ();
1926 break;
1927 case P_NONE:
1928 break;
1930 break;
1933 cl_target_option_restore (&global_options, &global_options_set,
1934 &cur_target);
1936 if (predicate_list && arg_str == NULL)
1938 error_at (DECL_SOURCE_LOCATION (decl),
1939 "no dispatcher found for the versioning attributes");
1940 return 0;
1943 if (predicate_list)
1945 predicate_decl = ix86_builtins [(int) builtin_fn];
1946 /* For a C string literal the length includes the trailing NULL. */
1947 predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str);
1948 predicate_chain = tree_cons (predicate_decl, predicate_arg,
1949 predicate_chain);
1953 /* Process feature name. */
1954 tok_str = (char *) xmalloc (strlen (attrs_str) + 1);
1955 strcpy (tok_str, attrs_str);
1956 token = strtok (tok_str, ",");
1957 predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_SUPPORTS];
1959 while (token != NULL)
1961 /* Do not process "arch=" */
1962 if (startswith (token, "arch="))
1964 token = strtok (NULL, ",");
1965 continue;
1967 for (i = 0; i < NUM_FEATURES; ++i)
1969 if (strcmp (token, isa_names_table[i].name) == 0)
1971 if (predicate_list)
1973 predicate_arg = build_string_literal (
1974 strlen (isa_names_table[i].name) + 1,
1975 isa_names_table[i].name);
1976 predicate_chain = tree_cons (predicate_decl, predicate_arg,
1977 predicate_chain);
1979 /* Find the maximum priority feature. */
1980 if (isa_names_table[i].priority > priority)
1981 priority = isa_names_table[i].priority;
1983 break;
1986 if (predicate_list && priority == P_NONE)
1988 error_at (DECL_SOURCE_LOCATION (decl),
1989 "ISA %qs is not supported in %<target%> attribute, "
1990 "use %<arch=%> syntax", token);
1991 return 0;
1993 token = strtok (NULL, ",");
1995 free (tok_str);
1997 if (predicate_list && predicate_chain == NULL_TREE)
1999 error_at (DECL_SOURCE_LOCATION (decl),
2000 "no dispatcher found for the versioning attributes: %s",
2001 attrs_str);
2002 return 0;
2004 else if (predicate_list)
2006 predicate_chain = nreverse (predicate_chain);
2007 *predicate_list = predicate_chain;
2010 return priority;
2013 /* This builds the processor_model struct type defined in
2014 libgcc/config/i386/cpuinfo.c */
2016 static tree
2017 build_processor_model_struct (void)
2019 const char *field_name[] = {"__cpu_vendor", "__cpu_type", "__cpu_subtype",
2020 "__cpu_features"};
2021 tree field = NULL_TREE, field_chain = NULL_TREE;
2022 int i;
2023 tree type = make_node (RECORD_TYPE);
2025 /* The first 3 fields are unsigned int. */
2026 for (i = 0; i < 3; ++i)
2028 field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
2029 get_identifier (field_name[i]), unsigned_type_node);
2030 if (field_chain != NULL_TREE)
2031 DECL_CHAIN (field) = field_chain;
2032 field_chain = field;
2035 /* The last field is an array of unsigned integers of size one. */
2036 field = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
2037 get_identifier (field_name[3]),
2038 build_array_type (unsigned_type_node,
2039 build_index_type (size_one_node)));
2040 if (field_chain != NULL_TREE)
2041 DECL_CHAIN (field) = field_chain;
2042 field_chain = field;
2044 finish_builtin_struct (type, "__processor_model", field_chain, NULL_TREE);
2045 return type;
2048 /* Returns a extern, comdat VAR_DECL of type TYPE and name NAME. */
2050 static tree
2051 make_var_decl (tree type, const char *name)
2053 tree new_decl;
2055 new_decl = build_decl (UNKNOWN_LOCATION,
2056 VAR_DECL,
2057 get_identifier(name),
2058 type);
2060 DECL_EXTERNAL (new_decl) = 1;
2061 TREE_STATIC (new_decl) = 1;
2062 TREE_PUBLIC (new_decl) = 1;
2063 DECL_INITIAL (new_decl) = 0;
2064 DECL_ARTIFICIAL (new_decl) = 0;
2065 DECL_PRESERVE_P (new_decl) = 1;
2067 make_decl_one_only (new_decl, DECL_ASSEMBLER_NAME (new_decl));
2068 assemble_variable (new_decl, 0, 0, 0);
2070 return new_decl;
2073 static GTY(()) tree ix86_cpu_model_type_node;
2074 static GTY(()) tree ix86_cpu_model_var;
2075 static GTY(()) tree ix86_cpu_features2_type_node;
2076 static GTY(()) tree ix86_cpu_features2_var;
2078 /* FNDECL is a __builtin_cpu_is or a __builtin_cpu_supports call that is folded
2079 into an integer defined in libgcc/config/i386/cpuinfo.c */
2081 tree
2082 fold_builtin_cpu (tree fndecl, tree *args)
2084 unsigned int i;
2085 enum ix86_builtins fn_code
2086 = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
2087 tree param_string_cst = NULL;
2089 if (ix86_cpu_model_var == nullptr)
2091 /* Build a single __cpu_model variable for all references to
2092 __cpu_model so that GIMPLE level optimizers can CSE the loads
2093 of __cpu_model and optimize bit-operations properly. */
2094 ix86_cpu_model_type_node = build_processor_model_struct ();
2095 ix86_cpu_model_var = make_var_decl (ix86_cpu_model_type_node,
2096 "__cpu_model");
2097 varpool_node::add (ix86_cpu_model_var);
2100 gcc_assert ((args != NULL) && (*args != NULL));
2102 param_string_cst = *args;
2103 while (param_string_cst
2104 && TREE_CODE (param_string_cst) != STRING_CST)
2106 /* *args must be a expr that can contain other EXPRS leading to a
2107 STRING_CST. */
2108 if (!EXPR_P (param_string_cst))
2110 error ("parameter to builtin must be a string constant or literal");
2111 return integer_zero_node;
2113 param_string_cst = TREE_OPERAND (EXPR_CHECK (param_string_cst), 0);
2116 gcc_assert (param_string_cst);
2118 if (fn_code == IX86_BUILTIN_CPU_IS)
2120 tree ref;
2121 tree field;
2122 tree final;
2124 unsigned int field_val = 0;
2126 for (i = 0; i < num_arch_names; i++)
2127 if (processor_alias_table[i].model != 0
2128 && strcmp (processor_alias_table[i].name,
2129 TREE_STRING_POINTER (param_string_cst)) == 0)
2130 break;
2132 if (i == num_arch_names)
2134 error ("parameter to builtin not valid: %s",
2135 TREE_STRING_POINTER (param_string_cst));
2136 return integer_zero_node;
2139 field = TYPE_FIELDS (ix86_cpu_model_type_node);
2140 field_val = processor_alias_table[i].model;
2142 /* CPU types are stored in the next field. */
2143 if (field_val > M_CPU_TYPE_START
2144 && field_val < M_CPU_SUBTYPE_START)
2146 field = DECL_CHAIN (field);
2147 field_val -= M_CPU_TYPE_START;
2150 /* CPU subtypes are stored in the next field. */
2151 if (field_val > M_CPU_SUBTYPE_START)
2153 field = DECL_CHAIN ( DECL_CHAIN (field));
2154 field_val -= M_CPU_SUBTYPE_START;
2157 /* Get the appropriate field in __cpu_model. */
2158 ref = build3 (COMPONENT_REF, TREE_TYPE (field), ix86_cpu_model_var,
2159 field, NULL_TREE);
2161 /* Check the value. */
2162 final = build2 (EQ_EXPR, unsigned_type_node, ref,
2163 build_int_cstu (unsigned_type_node, field_val));
2164 return build1 (NOP_EXPR, integer_type_node, final);
2166 else if (fn_code == IX86_BUILTIN_CPU_SUPPORTS)
2168 tree ref;
2169 tree array_elt;
2170 tree field;
2171 tree final;
2173 unsigned int field_val = 0;
2174 unsigned int NUM_ISA_NAMES = ARRAY_SIZE (isa_names_table);
2176 for (i = 0; i < NUM_ISA_NAMES; i++)
2177 if (strcmp (isa_names_table[i].name,
2178 TREE_STRING_POINTER (param_string_cst)) == 0)
2179 break;
2181 if (i == NUM_ISA_NAMES)
2183 error ("parameter to builtin not valid: %s",
2184 TREE_STRING_POINTER (param_string_cst));
2185 return integer_zero_node;
2188 unsigned feature = isa_names_table[i].feature;
2189 if (feature >= INT_TYPE_SIZE)
2191 if (ix86_cpu_features2_var == nullptr)
2193 /* Build a single __cpu_features2 variable for all
2194 references to __cpu_features2 so that GIMPLE level
2195 optimizers can CSE the loads of __cpu_features2 and
2196 optimize bit-operations properly. */
2197 tree index_type
2198 = build_index_type (size_int (SIZE_OF_CPU_FEATURES));
2199 ix86_cpu_features2_type_node
2200 = build_array_type (unsigned_type_node, index_type);
2201 ix86_cpu_features2_var
2202 = make_var_decl (ix86_cpu_features2_type_node,
2203 "__cpu_features2");
2204 varpool_node::add (ix86_cpu_features2_var);
2207 /* Skip __cpu_features[0]. */
2208 feature -= INT_TYPE_SIZE;
2209 tree index = size_int (feature / INT_TYPE_SIZE);
2210 feature = feature % INT_TYPE_SIZE;
2211 array_elt = build4 (ARRAY_REF, unsigned_type_node,
2212 ix86_cpu_features2_var,
2213 index, NULL_TREE, NULL_TREE);
2214 /* Return __cpu_features2[index] & field_val */
2216 else
2218 field = TYPE_FIELDS (ix86_cpu_model_type_node);
2219 /* Get the last field, which is __cpu_features. */
2220 while (DECL_CHAIN (field))
2221 field = DECL_CHAIN (field);
2223 /* Get the appropriate field: __cpu_model.__cpu_features */
2224 ref = build3 (COMPONENT_REF, TREE_TYPE (field), ix86_cpu_model_var,
2225 field, NULL_TREE);
2227 /* Access the 0th element of __cpu_features array. */
2228 array_elt = build4 (ARRAY_REF, unsigned_type_node, ref,
2229 integer_zero_node, NULL_TREE, NULL_TREE);
2231 /* Return __cpu_model.__cpu_features[0] & field_val */
2234 field_val = 1U << feature;
2235 final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt,
2236 build_int_cstu (unsigned_type_node, field_val));
2237 if (feature == INT_TYPE_SIZE - 1)
2238 return build2 (NE_EXPR, integer_type_node, final,
2239 build_int_cst (unsigned_type_node, 0));
2240 else
2241 return build1 (NOP_EXPR, integer_type_node, final);
2243 gcc_unreachable ();
2246 #include "gt-i386-builtins.h"