1 /* Subroutines for the C front end on the PowerPC architecture.
2 Copyright (C) 2002-2022 Free Software Foundation, Inc.
3
4 Contributed by Zack Weinberg <zack@codesourcery.com>
5 and Paolo Bonzini <bonzini@gnu.org>
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 #define IN_TARGET_CODE 1
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "target.h"
29 #include "c-family/c-common.h"
30 #include "memmodel.h"
31 #include "tm_p.h"
32 #include "stringpool.h"
33 #include "stor-layout.h"
34 #include "c-family/c-pragma.h"
35 #include "langhooks.h"
36 #include "c/c-tree.h"
37
38 #include "rs6000-internal.h"
39
40 /* Handle the machine specific pragma longcall. Its syntax is
41
42 # pragma longcall ( TOGGLE )
43
44 where TOGGLE is either 0 or 1.
45
46 rs6000_default_long_calls is set to the value of TOGGLE, changing
47 whether or not new function declarations receive a longcall
48 attribute by default. */
49
50 void
rs6000_pragma_longcall(cpp_reader * pfile ATTRIBUTE_UNUSED)51 rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
52 {
53 #define SYNTAX_ERROR(gmsgid) do { \
54 warning (OPT_Wpragmas, gmsgid); \
55 warning (OPT_Wpragmas, "ignoring malformed %<#pragma longcall%>"); \
56 return; \
57 } while (0)
58
59
60
61 tree x, n;
62
63 /* If we get here, generic code has already scanned the directive
64 leader and the word "longcall". */
65
66 if (pragma_lex (&x) != CPP_OPEN_PAREN)
67 SYNTAX_ERROR ("missing open paren");
68 if (pragma_lex (&n) != CPP_NUMBER)
69 SYNTAX_ERROR ("missing number");
70 if (pragma_lex (&x) != CPP_CLOSE_PAREN)
71 SYNTAX_ERROR ("missing close paren");
72
73 if (n != integer_zero_node && n != integer_one_node)
74 SYNTAX_ERROR ("number must be 0 or 1");
75
76 if (pragma_lex (&x) != CPP_EOF)
77 warning (OPT_Wpragmas, "junk at end of %<#pragma longcall%>");
78
79 rs6000_default_long_calls = (n == integer_one_node);
80 }
81
82 /* Handle defining many CPP flags based on TARGET_xxx. As a general
83 policy, rather than trying to guess what flags a user might want a
84 #define for, it's better to define a flag for everything. */
85
86 #define builtin_define(TXT) cpp_define (pfile, TXT)
87 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
88
89 /* Keep the AltiVec keywords handy for fast comparisons. */
90 static GTY(()) tree __vector_keyword;
91 static GTY(()) tree vector_keyword;
92 static GTY(()) tree __pixel_keyword;
93 static GTY(()) tree pixel_keyword;
94 static GTY(()) tree __bool_keyword;
95 static GTY(()) tree bool_keyword;
96 static GTY(()) tree _Bool_keyword;
97 static GTY(()) tree __int128_type;
98 static GTY(()) tree __uint128_type;
99
100 /* Preserved across calls. */
101 static tree expand_bool_pixel;
102
103 static cpp_hashnode *
altivec_categorize_keyword(const cpp_token * tok)104 altivec_categorize_keyword (const cpp_token *tok)
105 {
106 if (tok->type == CPP_NAME)
107 {
108 cpp_hashnode *ident = tok->val.node.node;
109
110 if (ident == C_CPP_HASHNODE (vector_keyword))
111 return C_CPP_HASHNODE (__vector_keyword);
112
113 if (ident == C_CPP_HASHNODE (pixel_keyword))
114 return C_CPP_HASHNODE (__pixel_keyword);
115
116 if (ident == C_CPP_HASHNODE (bool_keyword))
117 return C_CPP_HASHNODE (__bool_keyword);
118
119 if (ident == C_CPP_HASHNODE (_Bool_keyword))
120 return C_CPP_HASHNODE (__bool_keyword);
121
122 return ident;
123 }
124
125 return 0;
126 }
127
128 static void
init_vector_keywords(void)129 init_vector_keywords (void)
130 {
131 /* Keywords without two leading underscores are context-sensitive, and hence
132 implemented as conditional macros, controlled by the
133 rs6000_macro_to_expand() function below. If we have ISA 2.07 64-bit
134 support, record the __int128_t and __uint128_t types. */
135
136 __vector_keyword = get_identifier ("__vector");
137 C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
138
139 __pixel_keyword = get_identifier ("__pixel");
140 C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL;
141
142 __bool_keyword = get_identifier ("__bool");
143 C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
144
145 vector_keyword = get_identifier ("vector");
146 C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
147
148 pixel_keyword = get_identifier ("pixel");
149 C_CPP_HASHNODE (pixel_keyword)->flags |= NODE_CONDITIONAL;
150
151 bool_keyword = get_identifier ("bool");
152 C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
153
154 _Bool_keyword = get_identifier ("_Bool");
155 C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
156
157 if (TARGET_VADDUQM)
158 {
159 __int128_type = get_identifier ("__int128_t");
160 __uint128_type = get_identifier ("__uint128_t");
161 }
162 }
163
164 /* Helper function to find out which RID_INT_N_* code is the one for
165 __int128, if any. Returns RID_MAX+1 if none apply, which is safe
166 (for our purposes, since we always expect to have __int128) to
167 compare against. */
168 static int
rid_int128(void)169 rid_int128(void)
170 {
171 int i;
172
173 for (i = 0; i < NUM_INT_N_ENTS; i ++)
174 if (int_n_enabled_p[i]
175 && int_n_data[i].bitsize == 128)
176 return RID_INT_N_0 + i;
177
178 return RID_MAX + 1;
179 }
180
181 /* Called to decide whether a conditional macro should be expanded.
182 Since we have exactly one such macro (i.e, 'vector'), we do not
183 need to examine the 'tok' parameter. */
184
185 static cpp_hashnode *
rs6000_macro_to_expand(cpp_reader * pfile,const cpp_token * tok)186 rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
187 {
188 cpp_hashnode *expand_this = tok->val.node.node;
189 cpp_hashnode *ident;
190
191 /* If the current machine does not have altivec, don't look for the
192 keywords. */
193 if (!TARGET_ALTIVEC)
194 return NULL;
195
196 ident = altivec_categorize_keyword (tok);
197
198 if (ident != expand_this)
199 expand_this = NULL;
200
201 if (ident == C_CPP_HASHNODE (__vector_keyword))
202 {
203 int idx = 0;
204 do
205 tok = cpp_peek_token (pfile, idx++);
206 while (tok->type == CPP_PADDING);
207 ident = altivec_categorize_keyword (tok);
208
209 if (ident == C_CPP_HASHNODE (__pixel_keyword))
210 {
211 expand_this = C_CPP_HASHNODE (__vector_keyword);
212 expand_bool_pixel = __pixel_keyword;
213 }
214 else if (ident == C_CPP_HASHNODE (__bool_keyword))
215 {
216 expand_this = C_CPP_HASHNODE (__vector_keyword);
217 expand_bool_pixel = __bool_keyword;
218 }
219 /* The boost libraries have code with Iterator::vector vector in it. If
220 we allow the normal handling, this module will be called recursively,
221 and the vector will be skipped.; */
222 else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
223 {
224 enum rid rid_code = (enum rid)(ident->rid_code);
225 bool is_macro = cpp_macro_p (ident);
226
227 /* If there is a function-like macro, check if it is going to be
228 invoked with or without arguments. Without following ( treat
229 it like non-macro, otherwise the following cpp_get_token eats
230 what should be preserved. */
231 if (is_macro && cpp_fun_like_macro_p (ident))
232 {
233 int idx2 = idx;
234 do
235 tok = cpp_peek_token (pfile, idx2++);
236 while (tok->type == CPP_PADDING);
237 if (tok->type != CPP_OPEN_PAREN)
238 is_macro = false;
239 }
240
241 if (is_macro)
242 {
243 do
244 (void) cpp_get_token (pfile);
245 while (--idx > 0);
246 do
247 tok = cpp_peek_token (pfile, idx++);
248 while (tok->type == CPP_PADDING);
249 ident = altivec_categorize_keyword (tok);
250 if (ident == C_CPP_HASHNODE (__pixel_keyword))
251 {
252 expand_this = C_CPP_HASHNODE (__vector_keyword);
253 expand_bool_pixel = __pixel_keyword;
254 rid_code = RID_MAX;
255 }
256 else if (ident == C_CPP_HASHNODE (__bool_keyword))
257 {
258 expand_this = C_CPP_HASHNODE (__vector_keyword);
259 expand_bool_pixel = __bool_keyword;
260 rid_code = RID_MAX;
261 }
262 else if (ident)
263 rid_code = (enum rid)(ident->rid_code);
264 }
265
266 if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
267 || rid_code == RID_SHORT || rid_code == RID_SIGNED
268 || rid_code == RID_INT || rid_code == RID_CHAR
269 || rid_code == RID_FLOAT
270 || (rid_code == RID_DOUBLE && TARGET_VSX)
271 || (rid_code == rid_int128 () && TARGET_VADDUQM))
272 {
273 expand_this = C_CPP_HASHNODE (__vector_keyword);
274 /* If the next keyword is bool or pixel, it
275 will need to be expanded as well. */
276 do
277 tok = cpp_peek_token (pfile, idx++);
278 while (tok->type == CPP_PADDING);
279 ident = altivec_categorize_keyword (tok);
280
281 if (ident == C_CPP_HASHNODE (__pixel_keyword))
282 expand_bool_pixel = __pixel_keyword;
283 else if (ident == C_CPP_HASHNODE (__bool_keyword))
284 expand_bool_pixel = __bool_keyword;
285 else
286 {
287 /* Try two tokens down, too. */
288 do
289 tok = cpp_peek_token (pfile, idx++);
290 while (tok->type == CPP_PADDING);
291 ident = altivec_categorize_keyword (tok);
292 if (ident == C_CPP_HASHNODE (__pixel_keyword))
293 expand_bool_pixel = __pixel_keyword;
294 else if (ident == C_CPP_HASHNODE (__bool_keyword))
295 expand_bool_pixel = __bool_keyword;
296 }
297 }
298
299 /* Support vector __int128_t, but we don't need to worry about bool
300 or pixel on this type. */
301 else if (TARGET_VADDUQM
302 && (ident == C_CPP_HASHNODE (__int128_type)
303 || ident == C_CPP_HASHNODE (__uint128_type)))
304 expand_this = C_CPP_HASHNODE (__vector_keyword);
305 }
306 }
307 else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__pixel_keyword))
308 {
309 expand_this = C_CPP_HASHNODE (__pixel_keyword);
310 expand_bool_pixel = 0;
311 }
312 else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__bool_keyword))
313 {
314 expand_this = C_CPP_HASHNODE (__bool_keyword);
315 expand_bool_pixel = 0;
316 }
317
318 return expand_this;
319 }
320
321
322 /* Define or undefine a single macro. */
323
324 static void
rs6000_define_or_undefine_macro(bool define_p,const char * name)325 rs6000_define_or_undefine_macro (bool define_p, const char *name)
326 {
327 if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
328 fprintf (stderr, "#%s %s\n", (define_p) ? "define" : "undef", name);
329
330 if (define_p)
331 cpp_define (parse_in, name);
332 else
333 cpp_undef (parse_in, name);
334 }
335
336 /* Define or undefine macros based on the current target. If the user does
337 #pragma GCC target, we need to adjust the macros dynamically. Note, some of
338 the options needed for builtins have been moved to separate variables, so
339 have both the target flags and the builtin flags as arguments. */
340
341 void
rs6000_target_modify_macros(bool define_p,HOST_WIDE_INT flags,HOST_WIDE_INT bu_mask)342 rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
343 HOST_WIDE_INT bu_mask)
344 {
345 if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
346 fprintf (stderr,
347 "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX
348 ", " HOST_WIDE_INT_PRINT_HEX ")\n",
349 (define_p) ? "define" : "undef",
350 flags, bu_mask);
351
352 /* Each of the flags mentioned below controls whether certain
353 preprocessor macros will be automatically defined when
354 preprocessing source files for compilation by this compiler.
355 While most of these flags can be enabled or disabled
356 explicitly by specifying certain command-line options when
357 invoking the compiler, there are also many ways in which these
358 flags are enabled or disabled implicitly, based on compiler
359 defaults, configuration choices, and on the presence of certain
360 related command-line options. Many, but not all, of these
361 implicit behaviors can be found in file "rs6000.cc", the
362 rs6000_option_override_internal() function.
363
364 In general, each of the flags may be automatically enabled in
365 any of the following conditions:
366
367 1. If no -mcpu target is specified on the command line and no
368 --with-cpu target is specified to the configure command line
369 and the TARGET_DEFAULT macro for this default cpu host
370 includes the flag, and the flag has not been explicitly disabled
371 by command-line options.
372
373 2. If the target specified with -mcpu=target on the command line, or
374 in the absence of a -mcpu=target command-line option, if the
375 target specified using --with-cpu=target on the configure
376 command line, is disqualified because the associated binary
377 tools (e.g. the assembler) lack support for the requested cpu,
378 and the TARGET_DEFAULT macro for this default cpu host
379 includes the flag, and the flag has not been explicitly disabled
380 by command-line options.
381
382 3. If either of the above two conditions apply except that the
383 TARGET_DEFAULT macro is defined to equal zero, and
384 TARGET_POWERPC64 and
385 a) BYTES_BIG_ENDIAN and the flag to be enabled is either
386 MASK_PPC_GFXOPT or MASK_POWERPC64 (flags for "powerpc64"
387 target), or
388 b) !BYTES_BIG_ENDIAN and the flag to be enabled is either
389 MASK_POWERPC64 or it is one of the flags included in
390 ISA_2_7_MASKS_SERVER (flags for "powerpc64le" target).
391
392 4. If a cpu has been requested with a -mcpu=target command-line option
393 and this cpu has not been disqualified due to shortcomings of the
394 binary tools, and the set of flags associated with the requested cpu
395 include the flag to be enabled. See rs6000-cpus.def for macro
396 definitions that represent various ABI standards
397 (e.g. ISA_2_1_MASKS, ISA_3_0_MASKS_SERVER) and for a list of
398 the specific flags that are associated with each of the cpu
399 choices that can be specified as the target of a -mcpu=target
400 compile option, or as the target of a --with-cpu=target
401 configure option. Target flags that are specified in either
402 of these two ways are considered "implicit" since the flags
403 are not mentioned specifically by name.
404
405 Additional documentation describing behavior specific to
406 particular flags is provided below, immediately preceding the
407 use of each relevant flag.
408
409 5. If there is no -mcpu=target command-line option, and the cpu
410 requested by a --with-cpu=target command-line option has not
411 been disqualified due to shortcomings of the binary tools, and
412 the set of flags associated with the specified target include
413 the flag to be enabled. See the notes immediately above for a
414 summary of the flags associated with particular cpu
415 definitions. */
416
417 /* rs6000_isa_flags based options. */
418 rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC");
419 if ((flags & OPTION_MASK_PPC_GPOPT) != 0)
420 rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCSQ");
421 if ((flags & OPTION_MASK_PPC_GFXOPT) != 0)
422 rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR");
423 if ((flags & OPTION_MASK_POWERPC64) != 0)
424 rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64");
425 if ((flags & OPTION_MASK_MFCRF) != 0)
426 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4");
427 if ((flags & OPTION_MASK_POPCNTB) != 0)
428 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5");
429 if ((flags & OPTION_MASK_FPRND) != 0)
430 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X");
431 if ((flags & OPTION_MASK_CMPB) != 0)
432 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6");
433 if ((flags & OPTION_MASK_POPCNTD) != 0)
434 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7");
435 /* Note that the OPTION_MASK_DIRECT_MOVE flag is automatically
436 turned on in the following condition:
437 1. TARGET_P8_VECTOR is enabled and OPTION_MASK_DIRECT_MOVE is not
438 explicitly disabled.
439 Hereafter, the OPTION_MASK_DIRECT_MOVE flag is considered to
440 have been turned on explicitly.
441 Note that the OPTION_MASK_DIRECT_MOVE flag is automatically
442 turned off in any of the following conditions:
443 1. TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX is explicitly
444 disabled and OPTION_MASK_DIRECT_MOVE was not explicitly
445 enabled.
446 2. TARGET_VSX is off. */
447 if ((flags & OPTION_MASK_DIRECT_MOVE) != 0)
448 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR8");
449 if ((flags & OPTION_MASK_MODULO) != 0)
450 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR9");
451 if ((flags & OPTION_MASK_POWER10) != 0)
452 rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR10");
453 if ((flags & OPTION_MASK_SOFT_FLOAT) != 0)
454 rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT");
455 if ((flags & OPTION_MASK_RECIP_PRECISION) != 0)
456 rs6000_define_or_undefine_macro (define_p, "__RECIP_PRECISION__");
457 /* Note that the OPTION_MASK_ALTIVEC flag is automatically turned on
458 in any of the following conditions:
459 1. The operating system is Darwin and it is configured for 64
460 bit. (See darwin_rs6000_override_options.)
461 2. The operating system is Darwin and the operating system
462 version is 10.5 or higher and the user has not explicitly
463 disabled ALTIVEC by specifying -mcpu=G3 or -mno-altivec and
464 the compiler is not producing code for integration within the
465 kernel. (See darwin_rs6000_override_options.)
466 Note that the OPTION_MASK_ALTIVEC flag is automatically turned
467 off in any of the following conditions:
468 1. The operating system does not support saving of AltiVec
469 registers (OS_MISSING_ALTIVEC).
470 2. If an inner context (as introduced by
471 __attribute__((__target__())) or #pragma GCC target()
472 requests a target that normally enables the
473 OPTION_MASK_ALTIVEC flag but the outer-most "main target"
474 does not support the rs6000_altivec_abi, this flag is
475 turned off for the inner context unless OPTION_MASK_ALTIVEC
476 was explicitly enabled for the inner context. */
477 if ((flags & OPTION_MASK_ALTIVEC) != 0)
478 {
479 const char *vec_str = (define_p) ? "__VEC__=10206" : "__VEC__";
480 rs6000_define_or_undefine_macro (define_p, "__ALTIVEC__");
481 rs6000_define_or_undefine_macro (define_p, vec_str);
482
483 /* Define this when supporting context-sensitive keywords. */
484 if (!flag_iso)
485 rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__");
486 if (rs6000_aix_extabi)
487 rs6000_define_or_undefine_macro (define_p, "__EXTABI__");
488 }
489 /* Note that the OPTION_MASK_VSX flag is automatically turned on in
490 the following conditions:
491 1. TARGET_P8_VECTOR is explicitly turned on and the OPTION_MASK_VSX
492 was not explicitly turned off. Hereafter, the OPTION_MASK_VSX
493 flag is considered to have been explicitly turned on.
494 Note that the OPTION_MASK_VSX flag is automatically turned off in
495 the following conditions:
496 1. The operating system does not support saving of AltiVec
497 registers (OS_MISSING_ALTIVEC).
498 2. If the option TARGET_HARD_FLOAT is turned off. Hereafter, the
499 OPTION_MASK_VSX flag is considered to have been turned off
500 explicitly.
501 3. If TARGET_AVOID_XFORM is turned on explicitly at the outermost
502 compilation context, or if it is turned on by any means in an
503 inner compilation context. Hereafter, the OPTION_MASK_VSX
504 flag is considered to have been turned off explicitly.
505 4. If TARGET_ALTIVEC was explicitly disabled. Hereafter, the
506 OPTION_MASK_VSX flag is considered to have been turned off
507 explicitly.
508 5. If an inner context (as introduced by
509 __attribute__((__target__())) or #pragma GCC target()
510 requests a target that normally enables the
511 OPTION_MASK_VSX flag but the outer-most "main target"
512 does not support the rs6000_altivec_abi, this flag is
513 turned off for the inner context unless OPTION_MASK_VSX
514 was explicitly enabled for the inner context. */
515 if ((flags & OPTION_MASK_VSX) != 0)
516 rs6000_define_or_undefine_macro (define_p, "__VSX__");
517 if ((flags & OPTION_MASK_HTM) != 0)
518 {
519 rs6000_define_or_undefine_macro (define_p, "__HTM__");
520 /* Tell the user that our HTM insn patterns act as memory barriers. */
521 rs6000_define_or_undefine_macro (define_p, "__TM_FENCE__");
522 }
523 /* Note that the OPTION_MASK_P8_VECTOR flag is automatically turned
524 on in the following conditions:
525 1. TARGET_P9_VECTOR is explicitly turned on and
526 OPTION_MASK_P8_VECTOR is not explicitly turned off.
527 Hereafter, the OPTION_MASK_P8_VECTOR flag is considered to
528 have been turned off explicitly.
529 Note that the OPTION_MASK_P8_VECTOR flag is automatically turned
530 off in the following conditions:
531 1. If any of TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX
532 were turned off explicitly and OPTION_MASK_P8_VECTOR flag was
533 not turned on explicitly.
534 2. If TARGET_ALTIVEC is turned off. Hereafter, the
535 OPTION_MASK_P8_VECTOR flag is considered to have been turned off
536 explicitly.
537 3. If TARGET_VSX is turned off and OPTION_MASK_P8_VECTOR was not
538 explicitly enabled. If TARGET_VSX is explicitly enabled, the
539 OPTION_MASK_P8_VECTOR flag is hereafter also considered to
540 have been turned off explicitly. */
541 if ((flags & OPTION_MASK_P8_VECTOR) != 0)
542 rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__");
543 /* Note that the OPTION_MASK_P9_VECTOR flag is automatically turned
544 off in the following conditions:
545 1. If TARGET_P8_VECTOR is turned off and OPTION_MASK_P9_VECTOR is
546 not turned on explicitly. Hereafter, if OPTION_MASK_P8_VECTOR
547 was turned on explicitly, the OPTION_MASK_P9_VECTOR flag is
548 also considered to have been turned off explicitly.
549 Note that the OPTION_MASK_P9_VECTOR is automatically turned on
550 in the following conditions:
551 1. If TARGET_P9_MINMAX was turned on explicitly.
552 Hereafter, THE OPTION_MASK_P9_VECTOR flag is considered to
553 have been turned on explicitly. */
554 if ((flags & OPTION_MASK_P9_VECTOR) != 0)
555 rs6000_define_or_undefine_macro (define_p, "__POWER9_VECTOR__");
556 /* Note that the OPTION_MASK_QUAD_MEMORY flag is automatically
557 turned off in the following conditions:
558 1. If TARGET_POWERPC64 is turned off.
559 2. If WORDS_BIG_ENDIAN is false (non-atomic quad memory
560 load/store are disabled on little endian). */
561 if ((flags & OPTION_MASK_QUAD_MEMORY) != 0)
562 rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY__");
563 /* Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is automatically
564 turned off in the following conditions:
565 1. If TARGET_POWERPC64 is turned off.
566 Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is
567 automatically turned on in the following conditions:
568 1. If TARGET_QUAD_MEMORY and this flag was not explicitly
569 disabled. */
570 if ((flags & OPTION_MASK_QUAD_MEMORY_ATOMIC) != 0)
571 rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY_ATOMIC__");
572 /* Note that the OPTION_MASK_CRYPTO flag is automatically turned off
573 in the following conditions:
574 1. If any of TARGET_HARD_FLOAT or TARGET_ALTIVEC or TARGET_VSX
575 are turned off explicitly and OPTION_MASK_CRYPTO is not turned
576 on explicitly.
577 2. If TARGET_ALTIVEC is turned off. */
578 if ((flags & OPTION_MASK_CRYPTO) != 0)
579 rs6000_define_or_undefine_macro (define_p, "__CRYPTO__");
580 if ((flags & OPTION_MASK_FLOAT128_KEYWORD) != 0)
581 {
582 rs6000_define_or_undefine_macro (define_p, "__FLOAT128__");
583 if (define_p)
584 rs6000_define_or_undefine_macro (true, "__float128=__ieee128");
585 else
586 rs6000_define_or_undefine_macro (false, "__float128");
587 if (ieee128_float_type_node && define_p)
588 rs6000_define_or_undefine_macro (true, "__SIZEOF_FLOAT128__=16");
589 else
590 rs6000_define_or_undefine_macro (false, "__SIZEOF_FLOAT128__");
591 }
592 /* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or
593 via the target attribute/pragma. */
594 if ((flags & OPTION_MASK_FLOAT128_HW) != 0)
595 rs6000_define_or_undefine_macro (define_p, "__FLOAT128_HARDWARE__");
596
597 /* options from the builtin masks. */
598 /* Note that RS6000_BTM_CELL is enabled only if (rs6000_cpu ==
599 PROCESSOR_CELL) (e.g. -mcpu=cell). */
600 if ((bu_mask & RS6000_BTM_CELL) != 0)
601 rs6000_define_or_undefine_macro (define_p, "__PPU__");
602
603 /* Tell the user if we support the MMA instructions. */
604 if ((flags & OPTION_MASK_MMA) != 0)
605 rs6000_define_or_undefine_macro (define_p, "__MMA__");
606 /* Whether pc-relative code is being generated. */
607 if ((flags & OPTION_MASK_PCREL) != 0)
608 rs6000_define_or_undefine_macro (define_p, "__PCREL__");
609 /* Tell the user -mrop-protect is in play. */
610 if (rs6000_rop_protect)
611 rs6000_define_or_undefine_macro (define_p, "__ROP_PROTECT__");
612 }
613
614 void
rs6000_cpu_cpp_builtins(cpp_reader * pfile)615 rs6000_cpu_cpp_builtins (cpp_reader *pfile)
616 {
617 /* Define all of the common macros. */
618 rs6000_target_modify_macros (true, rs6000_isa_flags,
619 rs6000_builtin_mask_calculate ());
620
621 if (TARGET_FRE)
622 builtin_define ("__RECIP__");
623 if (TARGET_FRES)
624 builtin_define ("__RECIPF__");
625 if (TARGET_FRSQRTE)
626 builtin_define ("__RSQRTE__");
627 if (TARGET_FRSQRTES)
628 builtin_define ("__RSQRTEF__");
629 if (TARGET_FLOAT128_TYPE)
630 builtin_define ("__FLOAT128_TYPE__");
631 if (ibm128_float_type_node)
632 builtin_define ("__SIZEOF_IBM128__=16");
633 if (ieee128_float_type_node)
634 builtin_define ("__SIZEOF_IEEE128__=16");
635 #ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
636 builtin_define ("__BUILTIN_CPU_SUPPORTS__");
637 #endif
638
639 if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM)
640 {
641 /* Define the AltiVec syntactic elements. */
642 builtin_define ("__vector=__attribute__((altivec(vector__)))");
643 builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
644 builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");
645
646 if (!flag_iso)
647 {
648 builtin_define ("vector=vector");
649 builtin_define ("pixel=pixel");
650 builtin_define ("bool=bool");
651 builtin_define ("_Bool=_Bool");
652 init_vector_keywords ();
653
654 /* Enable context-sensitive macros. */
655 cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand;
656 }
657 }
658 if (!TARGET_HARD_FLOAT)
659 builtin_define ("_SOFT_DOUBLE");
660 /* Used by lwarx/stwcx. errata work-around. */
661 if (rs6000_cpu == PROCESSOR_PPC405)
662 builtin_define ("__PPC405__");
663 /* Used by libstdc++. */
664 if (TARGET_NO_LWSYNC)
665 builtin_define ("__NO_LWSYNC__");
666
667 if (TARGET_EXTRA_BUILTINS)
668 {
669 /* For the VSX builtin functions identical to Altivec functions, just map
670 the altivec builtin into the vsx version (the altivec functions
671 generate VSX code if -mvsx). */
672 builtin_define ("__builtin_vsx_xxland=__builtin_vec_and");
673 builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc");
674 builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor");
675 builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or");
676 builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor");
677 builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel");
678 builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm");
679
680 /* Also map the a and m versions of the multiply/add instructions to the
681 builtin for people blindly going off the instruction manual. */
682 builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp");
683 builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp");
684 builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp");
685 builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp");
686 builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp");
687 builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp");
688 builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp");
689 builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp");
690 builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp");
691 builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp");
692 builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp");
693 builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp");
694 builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp");
695 builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp");
696 builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp");
697 builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp");
698 }
699
700 /* Map the old _Float128 'q' builtins into the new 'f128' builtins. */
701 if (TARGET_FLOAT128_TYPE)
702 {
703 builtin_define ("__builtin_fabsq=__builtin_fabsf128");
704 builtin_define ("__builtin_copysignq=__builtin_copysignf128");
705 builtin_define ("__builtin_nanq=__builtin_nanf128");
706 builtin_define ("__builtin_nansq=__builtin_nansf128");
707 builtin_define ("__builtin_infq=__builtin_inff128");
708 builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
709 }
710
711 /* Tell users they can use __builtin_bswap{16,64}. */
712 builtin_define ("__HAVE_BSWAP__");
713
714 /* May be overridden by target configuration. */
715 RS6000_CPU_CPP_ENDIAN_BUILTINS();
716
717 if (TARGET_LONG_DOUBLE_128)
718 {
719 builtin_define ("__LONG_DOUBLE_128__");
720 builtin_define ("__LONGDOUBLE128");
721
722 if (TARGET_IEEEQUAD)
723 {
724 /* Older versions of GLIBC used __attribute__((__KC__)) to create the
725 IEEE 128-bit floating point complex type for C++ (which does not
726 support _Float128 _Complex). If the default for long double is
727 IEEE 128-bit mode, the library would need to use
728 __attribute__((__TC__)) instead. Defining __KF__ and __KC__
729 is a stop-gap to build with the older libraries, until we
730 get an updated library. */
731 builtin_define ("__LONG_DOUBLE_IEEE128__");
732 builtin_define ("__KF__=__TF__");
733 builtin_define ("__KC__=__TC__");
734 }
735 else
736 builtin_define ("__LONG_DOUBLE_IBM128__");
737 }
738
739 switch (TARGET_CMODEL)
740 {
741 /* Deliberately omit __CMODEL_SMALL__ since that was the default
742 before --mcmodel support was added. */
743 case CMODEL_MEDIUM:
744 builtin_define ("__CMODEL_MEDIUM__");
745 break;
746 case CMODEL_LARGE:
747 builtin_define ("__CMODEL_LARGE__");
748 break;
749 default:
750 break;
751 }
752
753 switch (rs6000_current_abi)
754 {
755 case ABI_V4:
756 builtin_define ("_CALL_SYSV");
757 break;
758 case ABI_AIX:
759 builtin_define ("_CALL_AIXDESC");
760 builtin_define ("_CALL_AIX");
761 builtin_define ("_CALL_ELF=1");
762 break;
763 case ABI_ELFv2:
764 builtin_define ("_CALL_ELF=2");
765 break;
766 case ABI_DARWIN:
767 builtin_define ("_CALL_DARWIN");
768 break;
769 default:
770 break;
771 }
772
773 /* Vector element order. */
774 if (BYTES_BIG_ENDIAN)
775 builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_BIG_ENDIAN__");
776 else
777 builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_LITTLE_ENDIAN__");
778
779 /* Let the compiled code know if 'f' class registers will not be available. */
780 if (TARGET_SOFT_FLOAT)
781 builtin_define ("__NO_FPRS__");
782
783 /* Whether aggregates passed by value are aligned to a 16 byte boundary
784 if their alignment is 16 bytes or larger. */
785 if ((TARGET_MACHO && rs6000_darwin64_abi)
786 || DEFAULT_ABI == ABI_ELFv2
787 || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
788 builtin_define ("__STRUCT_PARM_ALIGN__=16");
789 }
790
791
792
793 /* Convert a type stored into a struct altivec_builtin_types as ID,
794 into a tree. The types are in rs6000_builtin_types: negative values
795 create a pointer type for the type associated to ~ID. Note it is
796 a logical NOT, rather than a negation, otherwise you cannot represent
797 a pointer type for ID 0. */
798
799 static inline tree
rs6000_builtin_type(int id)800 rs6000_builtin_type (int id)
801 {
802 tree t;
803 t = rs6000_builtin_types[id < 0 ? ~id : id];
804 return id < 0 ? build_pointer_type (t) : t;
805 }
806
807 /* Check whether the type of an argument, T, is compatible with a type ID
808 stored into a struct altivec_builtin_types. Integer types are considered
809 compatible; otherwise, the language hook lang_hooks.types_compatible_p makes
810 the decision. Also allow long double and _Float128 to be compatible if
811 -mabi=ieeelongdouble. */
812
813 static inline bool
is_float128_p(tree t)814 is_float128_p (tree t)
815 {
816 return (t == float128_type_node
817 || (TARGET_IEEEQUAD
818 && TARGET_LONG_DOUBLE_128
819 && t == long_double_type_node));
820 }
821
822
823 /* Return true iff ARGTYPE can be compatibly passed as PARMTYPE. */
824 static bool
rs6000_builtin_type_compatible(tree parmtype,tree argtype)825 rs6000_builtin_type_compatible (tree parmtype, tree argtype)
826 {
827 if (parmtype == error_mark_node)
828 return false;
829
830 if (INTEGRAL_TYPE_P (parmtype) && INTEGRAL_TYPE_P (argtype))
831 return true;
832
833 if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
834 && is_float128_p (parmtype) && is_float128_p (argtype))
835 return true;
836
837 if (POINTER_TYPE_P (parmtype) && POINTER_TYPE_P (argtype))
838 {
839 parmtype = TREE_TYPE (parmtype);
840 argtype = TREE_TYPE (argtype);
841 if (TYPE_READONLY (argtype))
842 parmtype = build_qualified_type (parmtype, TYPE_QUAL_CONST);
843 }
844
845 return lang_hooks.types_compatible_p (parmtype, argtype);
846 }
847
848 /* In addition to calling fold_convert for EXPR of type TYPE, also
849 call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be
850 hiding there (PR47197). */
851
852 static tree
fully_fold_convert(tree type,tree expr)853 fully_fold_convert (tree type, tree expr)
854 {
855 tree result = fold_convert (type, expr);
856 bool maybe_const = true;
857
858 if (!c_dialect_cxx ())
859 result = c_fully_fold (result, false, &maybe_const);
860
861 return result;
862 }
863
864 /* Build a tree for a function call to an Altivec non-overloaded builtin.
865 The overloaded builtin that matched the types and args is described
866 by DESC. The N arguments are given in ARGS, respectively.
867
868 Actually the only thing it does is calling fold_convert on ARGS, with
869 a small exception for vec_{all,any}_{ge,le} predicates. */
870
871 static tree
altivec_build_resolved_builtin(tree * args,int n,tree fntype,tree ret_type,rs6000_gen_builtins bif_id,rs6000_gen_builtins ovld_id)872 altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type,
873 rs6000_gen_builtins bif_id,
874 rs6000_gen_builtins ovld_id)
875 {
876 tree argtypes = TYPE_ARG_TYPES (fntype);
877 tree arg_type[MAX_OVLD_ARGS];
878 tree fndecl = rs6000_builtin_decls[bif_id];
879
880 for (int i = 0; i < n; i++)
881 {
882 arg_type[i] = TREE_VALUE (argtypes);
883 argtypes = TREE_CHAIN (argtypes);
884 }
885
886 /* The AltiVec overloading implementation is overall gross, but this
887 is particularly disgusting. The vec_{all,any}_{ge,le} builtins
888 are completely different for floating-point vs. integer vector
889 types, because the former has vcmpgefp, but the latter should use
890 vcmpgtXX.
891
892 In practice, the second and third arguments are swapped, and the
893 condition (LT vs. EQ, which is recognizable by bit 1 of the first
894 argument) is reversed. Patch the arguments here before building
895 the resolved CALL_EXPR. */
896 if (n == 3
897 && ovld_id == RS6000_OVLD_VEC_CMPGE_P
898 && bif_id != RS6000_BIF_VCMPGEFP_P
899 && bif_id != RS6000_BIF_XVCMPGEDP_P)
900 {
901 std::swap (args[1], args[2]);
902 std::swap (arg_type[1], arg_type[2]);
903
904 args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0],
905 build_int_cst (NULL_TREE, 2));
906 }
907
908 for (int j = 0; j < n; j++)
909 args[j] = fully_fold_convert (arg_type[j], args[j]);
910
911 /* If the number of arguments to an overloaded function increases,
912 we must expand this switch. */
913 gcc_assert (MAX_OVLD_ARGS <= 4);
914
915 tree call;
916 switch (n)
917 {
918 case 0:
919 call = build_call_expr (fndecl, 0);
920 break;
921 case 1:
922 call = build_call_expr (fndecl, 1, args[0]);
923 break;
924 case 2:
925 call = build_call_expr (fndecl, 2, args[0], args[1]);
926 break;
927 case 3:
928 call = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
929 break;
930 case 4:
931 call = build_call_expr (fndecl, 4, args[0], args[1], args[2], args[3]);
932 break;
933 default:
934 gcc_unreachable ();
935 }
936 return fold_convert (ret_type, call);
937 }
938
939 /* Enumeration of possible results from attempted overload resolution.
940 This is used by special-case helper functions to tell their caller
941 whether they succeeded and what still needs to be done.
942
943 unresolved = Still needs processing
944 resolved = Resolved (but may be an error_mark_node)
945 resolved_bad = An error that needs handling by the caller. */
946
947 enum resolution { unresolved, resolved, resolved_bad };
948
949 /* Resolve an overloaded vec_mul call and return a tree expression for the
950 resolved call if successful. ARGS contains the arguments to the call.
951 TYPES contains their types. RES must be set to indicate the status of
952 the resolution attempt. LOC contains statement location information. */
953
954 static tree
resolve_vec_mul(resolution * res,tree * args,tree * types,location_t loc)955 resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc)
956 {
957 /* vec_mul needs to be special cased because there are no instructions for it
958 for the {un}signed char, {un}signed short, and {un}signed int types. */
959
960 /* Both arguments must be vectors and the types must be compatible. */
961 if (TREE_CODE (types[0]) != VECTOR_TYPE
962 || !lang_hooks.types_compatible_p (types[0], types[1]))
963 {
964 *res = resolved_bad;
965 return error_mark_node;
966 }
967
968 switch (TYPE_MODE (TREE_TYPE (types[0])))
969 {
970 case E_QImode:
971 case E_HImode:
972 case E_SImode:
973 case E_DImode:
974 case E_TImode:
975 /* For scalar types just use a multiply expression. */
976 *res = resolved;
977 return fold_build2_loc (loc, MULT_EXPR, types[0], args[0],
978 fold_convert (types[0], args[1]));
979 case E_SFmode:
980 {
981 /* For floats use the xvmulsp instruction directly. */
982 *res = resolved;
983 tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP];
984 return build_call_expr (call, 2, args[0], args[1]);
985 }
986 case E_DFmode:
987 {
988 /* For doubles use the xvmuldp instruction directly. */
989 *res = resolved;
990 tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP];
991 return build_call_expr (call, 2, args[0], args[1]);
992 }
993 /* Other types are errors. */
994 default:
995 *res = resolved_bad;
996 return error_mark_node;
997 }
998 }
999
1000 /* Resolve an overloaded vec_cmpne call and return a tree expression for the
1001 resolved call if successful. ARGS contains the arguments to the call.
1002 TYPES contains their types. RES must be set to indicate the status of
1003 the resolution attempt. LOC contains statement location information. */
1004
1005 static tree
resolve_vec_cmpne(resolution * res,tree * args,tree * types,location_t loc)1006 resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc)
1007 {
1008 /* vec_cmpne needs to be special cased because there are no instructions
1009 for it (prior to power 9). */
1010
1011 /* Both arguments must be vectors and the types must be compatible. */
1012 if (TREE_CODE (types[0]) != VECTOR_TYPE
1013 || !lang_hooks.types_compatible_p (types[0], types[1]))
1014 {
1015 *res = resolved_bad;
1016 return error_mark_node;
1017 }
1018
1019 machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0]));
1020
1021 /* Power9 instructions provide the most efficient implementation of
1022 ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode
1023 or SFmode or DFmode. */
1024 if (!TARGET_P9_VECTOR
1025 || arg0_elt_mode == DImode
1026 || arg0_elt_mode == TImode
1027 || arg0_elt_mode == SFmode
1028 || arg0_elt_mode == DFmode)
1029 {
1030 switch (arg0_elt_mode)
1031 {
1032 /* vec_cmpneq (va, vb) == vec_nor (vec_cmpeq (va, vb),
1033 vec_cmpeq (va, vb)). */
1034 /* Note: vec_nand also works but opt changes vec_nand's
1035 to vec_nor's anyway. */
1036 case E_QImode:
1037 case E_HImode:
1038 case E_SImode:
1039 case E_DImode:
1040 case E_TImode:
1041 case E_SFmode:
1042 case E_DFmode:
1043 {
1044 /* call = vec_cmpeq (va, vb)
1045 result = vec_nor (call, call). */
1046 vec<tree, va_gc> *params = make_tree_vector ();
1047 vec_safe_push (params, args[0]);
1048 vec_safe_push (params, args[1]);
1049 tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ];
1050 tree call = altivec_resolve_overloaded_builtin (loc, decl, params);
1051 /* Use save_expr to ensure that operands used more than once
1052 that may have side effects (like calls) are only evaluated
1053 once. */
1054 call = save_expr (call);
1055 params = make_tree_vector ();
1056 vec_safe_push (params, call);
1057 vec_safe_push (params, call);
1058 decl = rs6000_builtin_decls[RS6000_OVLD_VEC_NOR];
1059 *res = resolved;
1060 return altivec_resolve_overloaded_builtin (loc, decl, params);
1061 }
1062 /* Other types are errors. */
1063 default:
1064 *res = resolved_bad;
1065 return error_mark_node;
1066 }
1067 }
1068
1069 /* Otherwise this call is unresolved, and altivec_resolve_overloaded_builtin
1070 will later process the Power9 alternative. */
1071 *res = unresolved;
1072 return error_mark_node;
1073 }
1074
1075 /* Resolve an overloaded vec_adde or vec_sube call and return a tree expression
1076 for the resolved call if successful. ARGS contains the arguments to the
1077 call. TYPES contains their arguments. RES must be set to indicate the
1078 status of the resolution attempt. LOC contains statement location
1079 information. */
1080
1081 static tree
resolve_vec_adde_sube(resolution * res,rs6000_gen_builtins fcode,tree * args,tree * types,location_t loc)1082 resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
1083 tree *args, tree *types, location_t loc)
1084 {
1085 /* vec_adde needs to be special cased because there is no instruction
1086 for the {un}signed int version. */
1087
1088 /* All 3 arguments must be vectors of (signed or unsigned) (int or
1089 __int128) and the types must be compatible. */
1090 if (TREE_CODE (types[0]) != VECTOR_TYPE
1091 || !lang_hooks.types_compatible_p (types[0], types[1])
1092 || !lang_hooks.types_compatible_p (types[1], types[2]))
1093 {
1094 *res = resolved_bad;
1095 return error_mark_node;
1096 }
1097
1098 switch (TYPE_MODE (TREE_TYPE (types[0])))
1099 {
1100 /* For {un}signed ints,
1101 vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
1102 vec_and (carryv, 1)).
1103 vec_sube (va, vb, carryv) == vec_sub (vec_sub (va, vb),
1104 vec_and (carryv, 1)). */
1105 case E_SImode:
1106 {
1107 vec<tree, va_gc> *params = make_tree_vector ();
1108 vec_safe_push (params, args[0]);
1109 vec_safe_push (params, args[1]);
1110
1111 tree add_sub_builtin;
1112 if (fcode == RS6000_OVLD_VEC_ADDE)
1113 add_sub_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADD];
1114 else
1115 add_sub_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUB];
1116
1117 tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
1118 params);
1119 tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
1120 tree ones_vector = build_vector_from_val (types[0], const1);
1121 tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
1122 args[2], ones_vector);
1123 params = make_tree_vector ();
1124 vec_safe_push (params, call);
1125 vec_safe_push (params, and_expr);
1126 *res = resolved;
1127 return altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
1128 params);
1129 }
1130 /* For {un}signed __int128s use the vaddeuqm/vsubeuqm instruction
1131 directly using the standard machinery. */
1132 case E_TImode:
1133 *res = unresolved;
1134 break;
1135
1136 /* Types other than {un}signed int and {un}signed __int128
1137 are errors. */
1138 default:
1139 *res = resolved_bad;
1140 }
1141
1142 return error_mark_node;
1143 }
1144
1145 /* Resolve an overloaded vec_addec or vec_subec call and return a tree
1146 expression for the resolved call if successful. ARGS contains the arguments
1147 to the call. TYPES contains their types. RES must be set to indicate the
1148 status of the resolution attempt. LOC contains statement location
1149 information. */
1150
1151 static tree
resolve_vec_addec_subec(resolution * res,rs6000_gen_builtins fcode,tree * args,tree * types,location_t loc)1152 resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
1153 tree *args, tree *types, location_t loc)
1154 {
1155 /* vec_addec and vec_subec needs to be special cased because there is
1156 no instruction for the (un)signed int version. */
1157
1158 /* All 3 arguments must be vectors of (signed or unsigned) (int or
1159 __int128) and the types must be compatible. */
1160 if (TREE_CODE (types[0]) != VECTOR_TYPE
1161 || !lang_hooks.types_compatible_p (types[0], types[1])
1162 || !lang_hooks.types_compatible_p (types[1], types[2]))
1163 {
1164 *res = resolved_bad;
1165 return error_mark_node;
1166 }
1167
1168 switch (TYPE_MODE (TREE_TYPE (types[0])))
1169 {
1170 /* For {un}signed ints,
1171 vec_addec (va, vb, carryv) ==
1172 vec_or (vec_addc (va, vb),
1173 vec_addc (vec_add (va, vb),
1174 vec_and (carryv, 0x1))). */
1175 case E_SImode:
1176 {
1177 /* Use save_expr to ensure that operands used more than once that may
1178 have side effects (like calls) are only evaluated once. */
1179 args[0] = save_expr (args[0]);
1180 args[1] = save_expr (args[1]);
1181 vec<tree, va_gc> *params = make_tree_vector ();
1182 vec_safe_push (params, args[0]);
1183 vec_safe_push (params, args[1]);
1184
1185 tree as_c_builtin;
1186 if (fcode == RS6000_OVLD_VEC_ADDEC)
1187 as_c_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADDC];
1188 else
1189 as_c_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUBC];
1190
1191 tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
1192 params);
1193 params = make_tree_vector ();
1194 vec_safe_push (params, args[0]);
1195 vec_safe_push (params, args[1]);
1196
1197 tree as_builtin;
1198 if (fcode == RS6000_OVLD_VEC_ADDEC)
1199 as_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADD];
1200 else
1201 as_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUB];
1202
1203 tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
1204 params);
1205 tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
1206 tree ones_vector = build_vector_from_val (types[0], const1);
1207 tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
1208 args[2], ones_vector);
1209 params = make_tree_vector ();
1210 vec_safe_push (params, call2);
1211 vec_safe_push (params, and_expr);
1212 call2 = altivec_resolve_overloaded_builtin (loc, as_c_builtin, params);
1213 params = make_tree_vector ();
1214 vec_safe_push (params, call1);
1215 vec_safe_push (params, call2);
1216 tree or_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_OR];
1217 *res = resolved;
1218 return altivec_resolve_overloaded_builtin (loc, or_builtin, params);
1219 }
1220 /* For {un}signed __int128s use the vaddecuq/vsubbecuq
1221 instructions. This occurs through normal processing. */
1222 case E_TImode:
1223 *res = unresolved;
1224 break;
1225
1226 /* Types other than {un}signed int and {un}signed __int128
1227 are errors. */
1228 default:
1229 *res = resolved_bad;
1230 }
1231
1232 return error_mark_node;
1233 }
1234
1235 /* Resolve an overloaded vec_splats or vec_promote call and return a tree
1236 expression for the resolved call if successful. NARGS is the number of
1237 arguments to the call. ARGLIST contains the arguments. RES must be set
1238 to indicate the status of the resolution attempt. */
1239
1240 static tree
resolve_vec_splats(resolution * res,rs6000_gen_builtins fcode,vec<tree,va_gc> * arglist,unsigned nargs)1241 resolve_vec_splats (resolution *res, rs6000_gen_builtins fcode,
1242 vec<tree, va_gc> *arglist, unsigned nargs)
1243 {
1244 const char *name;
1245 name = fcode == RS6000_OVLD_VEC_SPLATS ? "vec_splats" : "vec_promote";
1246
1247 if (fcode == RS6000_OVLD_VEC_SPLATS && nargs != 1)
1248 {
1249 error ("builtin %qs only accepts 1 argument", name);
1250 *res = resolved;
1251 return error_mark_node;
1252 }
1253
1254 if (fcode == RS6000_OVLD_VEC_PROMOTE && nargs != 2)
1255 {
1256 error ("builtin %qs only accepts 2 arguments", name);
1257 *res = resolved;
1258 return error_mark_node;
1259 }
1260
1261 /* Ignore promote's element argument. */
1262 if (fcode == RS6000_OVLD_VEC_PROMOTE
1263 && !INTEGRAL_TYPE_P (TREE_TYPE ((*arglist)[1])))
1264 {
1265 *res = resolved_bad;
1266 return error_mark_node;
1267 }
1268
1269 tree arg = (*arglist)[0];
1270 tree type = TREE_TYPE (arg);
1271
1272 if (!SCALAR_FLOAT_TYPE_P (type) && !INTEGRAL_TYPE_P (type))
1273 {
1274 *res = resolved_bad;
1275 return error_mark_node;
1276 }
1277
1278 bool unsigned_p = TYPE_UNSIGNED (type);
1279 int size;
1280
1281 switch (TYPE_MODE (type))
1282 {
1283 case E_TImode:
1284 type = unsigned_p ? unsigned_V1TI_type_node : V1TI_type_node;
1285 size = 1;
1286 break;
1287 case E_DImode:
1288 type = unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node;
1289 size = 2;
1290 break;
1291 case E_SImode:
1292 type = unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node;
1293 size = 4;
1294 break;
1295 case E_HImode:
1296 type = unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node;
1297 size = 8;
1298 break;
1299 case E_QImode:
1300 type = unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node;
1301 size = 16;
1302 break;
1303 case E_SFmode:
1304 type = V4SF_type_node;
1305 size = 4;
1306 break;
1307 case E_DFmode:
1308 type = V2DF_type_node;
1309 size = 2;
1310 break;
1311 default:
1312 *res = resolved_bad;
1313 return error_mark_node;
1314 }
1315
1316 arg = save_expr (fold_convert (TREE_TYPE (type), arg));
1317 vec<constructor_elt, va_gc> *vec;
1318 vec_alloc (vec, size);
1319
1320 for (int i = 0; i < size; i++)
1321 {
1322 constructor_elt elt = {NULL_TREE, arg};
1323 vec->quick_push (elt);
1324 }
1325
1326 *res = resolved;
1327 return build_constructor (type, vec);
1328 }
1329
1330 /* Resolve an overloaded vec_extract call and return a tree expression for
1331 the resolved call if successful. NARGS is the number of arguments to
1332 the call. ARGLIST contains the arguments. RES must be set to indicate
1333 the status of the resolution attempt. LOC contains statement location
1334 information. */
1335
1336 static tree
resolve_vec_extract(resolution * res,vec<tree,va_gc> * arglist,unsigned nargs,location_t loc)1337 resolve_vec_extract (resolution *res, vec<tree, va_gc> *arglist,
1338 unsigned nargs, location_t loc)
1339 {
1340 if (nargs != 2)
1341 {
1342 error ("builtin %qs only accepts 2 arguments", "vec_extract");
1343 *res = resolved;
1344 return error_mark_node;
1345 }
1346
1347 tree arg1 = (*arglist)[0];
1348 tree arg1_type = TREE_TYPE (arg1);
1349 tree arg2 = (*arglist)[1];
1350
1351 if (TREE_CODE (arg1_type) != VECTOR_TYPE
1352 || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
1353 {
1354 *res = resolved_bad;
1355 return error_mark_node;
1356 }
1357
1358 /* See if we can optimize vec_extract with the current VSX instruction
1359 set. */
1360 machine_mode mode = TYPE_MODE (arg1_type);
1361 tree arg1_inner_type;
1362
1363 if (VECTOR_MEM_VSX_P (mode))
1364 {
1365 tree call = NULL_TREE;
1366 int nunits = GET_MODE_NUNITS (mode);
1367 arg2 = fold_for_warn (arg2);
1368
1369 /* If the second argument is an integer constant, generate
1370 the built-in code if we can. We need 64-bit and direct
1371 move to extract the small integer vectors. */
1372 if (TREE_CODE (arg2) == INTEGER_CST)
1373 {
1374 wide_int selector = wi::to_wide (arg2);
1375 selector = wi::umod_trunc (selector, nunits);
1376 arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
1377 switch (mode)
1378 {
1379 case E_V1TImode:
1380 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V1TI];
1381 break;
1382
1383 case E_V2DFmode:
1384 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DF];
1385 break;
1386
1387 case E_V2DImode:
1388 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DI];
1389 break;
1390
1391 case E_V4SFmode:
1392 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SF];
1393 break;
1394
1395 case E_V4SImode:
1396 if (TARGET_DIRECT_MOVE_64BIT)
1397 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SI];
1398 break;
1399
1400 case E_V8HImode:
1401 if (TARGET_DIRECT_MOVE_64BIT)
1402 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V8HI];
1403 break;
1404
1405 case E_V16QImode:
1406 if (TARGET_DIRECT_MOVE_64BIT)
1407 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V16QI];
1408 break;
1409
1410 default:
1411 break;
1412 }
1413 }
1414
1415 /* If the second argument is variable, we can optimize it if we are
1416 generating 64-bit code on a machine with direct move. */
1417 else if (TREE_CODE (arg2) != INTEGER_CST && TARGET_DIRECT_MOVE_64BIT)
1418 {
1419 switch (mode)
1420 {
1421 case E_V2DFmode:
1422 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DF];
1423 break;
1424
1425 case E_V2DImode:
1426 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DI];
1427 break;
1428
1429 case E_V4SFmode:
1430 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SF];
1431 break;
1432
1433 case E_V4SImode:
1434 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SI];
1435 break;
1436
1437 case E_V8HImode:
1438 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V8HI];
1439 break;
1440
1441 case E_V16QImode:
1442 call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V16QI];
1443 break;
1444
1445 default:
1446 break;
1447 }
1448 }
1449
1450 if (call)
1451 {
1452 tree result = build_call_expr (call, 2, arg1, arg2);
1453 /* Coerce the result to vector element type. May be no-op. */
1454 arg1_inner_type = TREE_TYPE (arg1_type);
1455 result = fold_convert (arg1_inner_type, result);
1456 *res = resolved;
1457 return result;
1458 }
1459 }
1460
1461 /* Build *(((arg1_inner_type*) & (vector type){arg1}) + arg2). */
1462 arg1_inner_type = TREE_TYPE (arg1_type);
1463 tree subp = build_int_cst (TREE_TYPE (arg2),
1464 TYPE_VECTOR_SUBPARTS (arg1_type) - 1);
1465 arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, subp, 0);
1466
1467 tree decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
1468 DECL_EXTERNAL (decl) = 0;
1469 TREE_PUBLIC (decl) = 0;
1470 DECL_CONTEXT (decl) = current_function_decl;
1471 TREE_USED (decl) = 1;
1472 TREE_TYPE (decl) = arg1_type;
1473 TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
1474
1475 tree stmt;
1476 if (c_dialect_cxx ())
1477 {
1478 stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, NULL_TREE, NULL_TREE);
1479 SET_EXPR_LOCATION (stmt, loc);
1480 }
1481 else
1482 {
1483 DECL_INITIAL (decl) = arg1;
1484 stmt = build1 (DECL_EXPR, arg1_type, decl);
1485 TREE_ADDRESSABLE (decl) = 1;
1486 SET_EXPR_LOCATION (stmt, loc);
1487 stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
1488 }
1489
1490 tree innerptrtype = build_pointer_type (arg1_inner_type);
1491 stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
1492 stmt = convert (innerptrtype, stmt);
1493 stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
1494 stmt = build_indirect_ref (loc, stmt, RO_NULL);
1495
1496 /* PR83660: We mark this as having side effects so that downstream in
1497 fold_build_cleanup_point_expr () it will get a CLEANUP_POINT_EXPR. If it
1498 does not we can run into an ICE later in gimplify_cleanup_point_expr ().
1499 Potentially this causes missed optimization because there actually is no
1500 side effect. */
1501 if (c_dialect_cxx ())
1502 TREE_SIDE_EFFECTS (stmt) = 1;
1503
1504 *res = resolved;
1505 return stmt;
1506 }
1507
1508 /* Resolve an overloaded vec_insert call and return a tree expression for
1509 the resolved call if successful. NARGS is the number of arguments to
1510 the call. ARGLIST contains the arguments. RES must be set to indicate
1511 the status of the resolution attempt. LOC contains statement location
1512 information. */
1513
1514 static tree
resolve_vec_insert(resolution * res,vec<tree,va_gc> * arglist,unsigned nargs,location_t loc)1515 resolve_vec_insert (resolution *res, vec<tree, va_gc> *arglist,
1516 unsigned nargs, location_t loc)
1517 {
1518 if (nargs != 3)
1519 {
1520 error ("builtin %qs only accepts 3 arguments", "vec_insert");
1521 *res = resolved;
1522 return error_mark_node;
1523 }
1524
1525 tree arg0 = (*arglist)[0];
1526 tree arg1 = (*arglist)[1];
1527 tree arg1_type = TREE_TYPE (arg1);
1528 tree arg2 = fold_for_warn ((*arglist)[2]);
1529
1530 if (TREE_CODE (arg1_type) != VECTOR_TYPE
1531 || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
1532 {
1533 *res = resolved_bad;
1534 return error_mark_node;
1535 }
1536
1537 /* If we can use the VSX xxpermdi instruction, use that for insert. */
1538 machine_mode mode = TYPE_MODE (arg1_type);
1539
1540 if ((mode == V2DFmode || mode == V2DImode)
1541 && VECTOR_UNIT_VSX_P (mode)
1542 && TREE_CODE (arg2) == INTEGER_CST)
1543 {
1544 wide_int selector = wi::to_wide (arg2);
1545 selector = wi::umod_trunc (selector, 2);
1546 arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
1547
1548 tree call = NULL_TREE;
1549 if (mode == V2DFmode)
1550 call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V2DF];
1551 else if (mode == V2DImode)
1552 call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V2DI];
1553
1554 /* Note, __builtin_vec_insert_<xxx> has vector and scalar types
1555 reversed. */
1556 if (call)
1557 {
1558 *res = resolved;
1559 return build_call_expr (call, 3, arg1, arg0, arg2);
1560 }
1561 }
1562
1563 else if (mode == V1TImode
1564 && VECTOR_UNIT_VSX_P (mode)
1565 && TREE_CODE (arg2) == INTEGER_CST)
1566 {
1567 tree call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V1TI];
1568 wide_int selector = wi::zero(32);
1569 arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
1570
1571 /* Note, __builtin_vec_insert_<xxx> has vector and scalar types
1572 reversed. */
1573 *res = resolved;
1574 return build_call_expr (call, 3, arg1, arg0, arg2);
1575 }
1576
1577 /* Build *(((arg1_inner_type*) & (vector type){arg1}) + arg2) = arg0 with
1578 VIEW_CONVERT_EXPR. i.e.:
1579 D.3192 = v1;
1580 _1 = n & 3;
1581 VIEW_CONVERT_EXPR<int[4]>(D.3192)[_1] = i;
1582 v1 = D.3192;
1583 D.3194 = v1; */
1584 if (TYPE_VECTOR_SUBPARTS (arg1_type) == 1)
1585 arg2 = build_int_cst (TREE_TYPE (arg2), 0);
1586 else
1587 {
1588 tree c = build_int_cst (TREE_TYPE (arg2),
1589 TYPE_VECTOR_SUBPARTS (arg1_type) - 1);
1590 arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, c, 0);
1591 }
1592
1593 tree decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
1594 DECL_EXTERNAL (decl) = 0;
1595 TREE_PUBLIC (decl) = 0;
1596 DECL_CONTEXT (decl) = current_function_decl;
1597 TREE_USED (decl) = 1;
1598 TREE_TYPE (decl) = arg1_type;
1599 TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
1600 TREE_ADDRESSABLE (decl) = 1;
1601
1602 tree stmt;
1603 if (c_dialect_cxx ())
1604 {
1605 stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, NULL_TREE, NULL_TREE);
1606 SET_EXPR_LOCATION (stmt, loc);
1607 }
1608 else
1609 {
1610 DECL_INITIAL (decl) = arg1;
1611 stmt = build1 (DECL_EXPR, arg1_type, decl);
1612 SET_EXPR_LOCATION (stmt, loc);
1613 stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
1614 }
1615
1616 if (TARGET_VSX)
1617 {
1618 stmt = build_array_ref (loc, stmt, arg2);
1619 stmt = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg0), stmt,
1620 convert (TREE_TYPE (stmt), arg0));
1621 stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
1622 }
1623 else
1624 {
1625 tree arg1_inner_type = TREE_TYPE (arg1_type);
1626 tree innerptrtype = build_pointer_type (arg1_inner_type);
1627 stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
1628 stmt = convert (innerptrtype, stmt);
1629 stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
1630 stmt = build_indirect_ref (loc, stmt, RO_NULL);
1631 stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
1632 convert (TREE_TYPE (stmt), arg0));
1633 stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
1634 }
1635
1636 *res = resolved;
1637 return stmt;
1638 }
1639
1640 /* Resolve an overloaded vec_step call and return a tree expression for
1641 the resolved call if successful. NARGS is the number of arguments to
1642 the call. ARGLIST contains the arguments. RES must be set to indicate
1643 the status of the resolution attempt. */
1644
1645 static tree
resolve_vec_step(resolution * res,vec<tree,va_gc> * arglist,unsigned nargs)1646 resolve_vec_step (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs)
1647 {
1648 if (nargs != 1)
1649 {
1650 error ("builtin %qs only accepts 1 argument", "vec_step");
1651 *res = resolved;
1652 return error_mark_node;
1653 }
1654
1655 tree arg0 = (*arglist)[0];
1656 tree arg0_type = TREE_TYPE (arg0);
1657
1658 if (TREE_CODE (arg0_type) != VECTOR_TYPE)
1659 {
1660 *res = resolved_bad;
1661 return error_mark_node;
1662 }
1663
1664 *res = resolved;
1665 return build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (arg0_type));
1666 }
1667
1668 /* Look for a matching instance in a chain of instances. INSTANCE points to
1669 the chain of instances; INSTANCE_CODE is the code identifying the specific
1670 built-in being searched for; FCODE is the overloaded function code; TYPES
1671 contains an array of two types that must match the types of the instance's
1672 parameters; and ARGS contains an array of two arguments to be passed to
1673 the instance. If found, resolve the built-in and return it, unless the
1674 built-in is not supported in context. In that case, set
1675 UNSUPPORTED_BUILTIN to true. If we don't match, return error_mark_node
1676 and leave UNSUPPORTED_BUILTIN alone. */
1677
1678 tree
find_instance(bool * unsupported_builtin,ovlddata ** instance,rs6000_gen_builtins instance_code,rs6000_gen_builtins fcode,tree * types,tree * args)1679 find_instance (bool *unsupported_builtin, ovlddata **instance,
1680 rs6000_gen_builtins instance_code,
1681 rs6000_gen_builtins fcode,
1682 tree *types, tree *args)
1683 {
1684 while (*instance && (*instance)->bifid != instance_code)
1685 *instance = (*instance)->next;
1686
1687 ovlddata *inst = *instance;
1688 gcc_assert (inst != NULL);
1689 /* It is possible for an instance to require a data type that isn't
1690 defined on this target, in which case inst->fntype will be NULL. */
1691 if (!inst->fntype)
1692 return error_mark_node;
1693 tree fntype = rs6000_builtin_info[inst->bifid].fntype;
1694 tree parmtype0 = TREE_VALUE (TYPE_ARG_TYPES (fntype));
1695 tree parmtype1 = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (fntype)));
1696
1697 if (rs6000_builtin_type_compatible (types[0], parmtype0)
1698 && rs6000_builtin_type_compatible (types[1], parmtype1))
1699 {
1700 if (rs6000_builtin_decl (inst->bifid, false) != error_mark_node
1701 && rs6000_builtin_is_supported (inst->bifid))
1702 {
1703 tree ret_type = TREE_TYPE (inst->fntype);
1704 return altivec_build_resolved_builtin (args, 2, fntype, ret_type,
1705 inst->bifid, fcode);
1706 }
1707 else
1708 *unsupported_builtin = true;
1709 }
1710
1711 return error_mark_node;
1712 }
1713
1714 /* Implementation of the resolve_overloaded_builtin target hook, to
1715 support Altivec's overloaded builtins. */
1716
1717 tree
altivec_resolve_overloaded_builtin(location_t loc,tree fndecl,void * passed_arglist)1718 altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
1719 void *passed_arglist)
1720 {
1721 rs6000_gen_builtins fcode
1722 = (rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
1723
1724 /* Return immediately if this isn't an overload. */
1725 if (fcode <= RS6000_OVLD_NONE)
1726 return NULL_TREE;
1727
1728 if (TARGET_DEBUG_BUILTIN)
1729 fprintf (stderr, "altivec_resolve_overloaded_builtin, code = %4d, %s\n",
1730 (int) fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)));
1731
1732 /* vec_lvsl and vec_lvsr are deprecated for use with LE element order. */
1733 if (fcode == RS6000_OVLD_VEC_LVSL && !BYTES_BIG_ENDIAN)
1734 warning (OPT_Wdeprecated,
1735 "%<vec_lvsl%> is deprecated for little endian; use "
1736 "assignment for unaligned loads and stores");
1737 else if (fcode == RS6000_OVLD_VEC_LVSR && !BYTES_BIG_ENDIAN)
1738 warning (OPT_Wdeprecated,
1739 "%<vec_lvsr%> is deprecated for little endian; use "
1740 "assignment for unaligned loads and stores");
1741
1742 /* Gather the arguments and their types into arrays for easier handling. */
1743 tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
1744 tree types[MAX_OVLD_ARGS];
1745 tree args[MAX_OVLD_ARGS];
1746 unsigned int n;
1747
1748 /* Count the number of expected arguments. */
1749 unsigned expected_args = 0;
1750 for (tree chain = fnargs;
1751 chain && !VOID_TYPE_P (TREE_VALUE (chain));
1752 chain = TREE_CHAIN (chain))
1753 expected_args++;
1754
1755 vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
1756 unsigned int nargs = vec_safe_length (arglist);
1757
1758 /* If the number of arguments did not match the prototype, return NULL
1759 and the generic code will issue the appropriate error message. Skip
1760 this test for functions where we don't fully describe all the possible
1761 overload signatures in rs6000-overload.def (because they aren't relevant
1762 to the expansion here). If we don't, we get confusing error messages. */
1763 /* As an example, for vec_splats we have:
1764
1765 ; There are no actual builtins for vec_splats. There is special handling for
1766 ; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
1767 ; is replaced by a constructor. The single overload here causes
1768 ; __builtin_vec_splats to be registered with the front end so that can happen.
1769 [VEC_SPLATS, vec_splats, __builtin_vec_splats]
1770 vsi __builtin_vec_splats (vsi);
1771 ABS_V4SI SPLATS_FAKERY
1772
1773 So even though __builtin_vec_splats accepts all vector types, the
1774 infrastructure cheats and just records one prototype. We end up getting
1775 an error message that refers to this specific prototype even when we
1776 are handling a different argument type. That is completely confusing
1777 to the user, so it's best to let these cases be handled individually
1778 in the resolve_vec_splats, etc., helper functions. */
1779
1780 if (expected_args != nargs
1781 && !(fcode == RS6000_OVLD_VEC_PROMOTE
1782 || fcode == RS6000_OVLD_VEC_SPLATS
1783 || fcode == RS6000_OVLD_VEC_EXTRACT
1784 || fcode == RS6000_OVLD_VEC_INSERT
1785 || fcode == RS6000_OVLD_VEC_STEP))
1786 return NULL;
1787
1788 for (n = 0;
1789 !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs;
1790 fnargs = TREE_CHAIN (fnargs), n++)
1791 {
1792 tree decl_type = TREE_VALUE (fnargs);
1793 tree arg = (*arglist)[n];
1794
1795 if (arg == error_mark_node)
1796 return error_mark_node;
1797
1798 if (n >= MAX_OVLD_ARGS)
1799 abort ();
1800
1801 arg = default_conversion (arg);
1802 tree type = TREE_TYPE (arg);
1803
1804 /* The C++ front-end converts float * to const void * using
1805 NOP_EXPR<const void *> (NOP_EXPR<void *> (x)). */
1806 if (POINTER_TYPE_P (type)
1807 && TREE_CODE (arg) == NOP_EXPR
1808 && lang_hooks.types_compatible_p (TREE_TYPE (arg),
1809 const_ptr_type_node)
1810 && lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (arg, 0)),
1811 ptr_type_node))
1812 {
1813 arg = TREE_OPERAND (arg, 0);
1814 type = TREE_TYPE (arg);
1815 }
1816
1817 /* Remove the const from the pointers to simplify the overload
1818 matching further down. */
1819 if (POINTER_TYPE_P (decl_type)
1820 && POINTER_TYPE_P (type)
1821 && TYPE_QUALS (TREE_TYPE (type)) != 0)
1822 {
1823 if (TYPE_READONLY (TREE_TYPE (type))
1824 && !TYPE_READONLY (TREE_TYPE (decl_type)))
1825 warning (0, "passing argument %d of %qE discards %qs "
1826 "qualifier from pointer target type", n + 1, fndecl,
1827 "const");
1828 type = build_qualified_type (TREE_TYPE (type), 0);
1829 type = build_pointer_type (type);
1830 arg = fold_convert (type, arg);
1831 }
1832
1833 /* For RS6000_OVLD_VEC_LXVL, convert any const * to its non constant
1834 equivalent to simplify the overload matching below. */
1835 if (fcode == RS6000_OVLD_VEC_LXVL
1836 && POINTER_TYPE_P (type)
1837 && TYPE_READONLY (TREE_TYPE (type)))
1838 {
1839 type = build_qualified_type (TREE_TYPE (type), 0);
1840 type = build_pointer_type (type);
1841 arg = fold_convert (type, arg);
1842 }
1843
1844 args[n] = arg;
1845 types[n] = type;
1846 }
1847
1848 /* Some overloads require special handling. */
1849 tree returned_expr = NULL;
1850 resolution res = unresolved;
1851
1852 if (fcode == RS6000_OVLD_VEC_MUL)
1853 returned_expr = resolve_vec_mul (&res, args, types, loc);
1854 else if (fcode == RS6000_OVLD_VEC_CMPNE)
1855 returned_expr = resolve_vec_cmpne (&res, args, types, loc);
1856 else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
1857 returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
1858 else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
1859 returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
1860 else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
1861 returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
1862 else if (fcode == RS6000_OVLD_VEC_EXTRACT)
1863 returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
1864 else if (fcode == RS6000_OVLD_VEC_INSERT)
1865 returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
1866 else if (fcode == RS6000_OVLD_VEC_STEP)
1867 returned_expr = resolve_vec_step (&res, arglist, nargs);
1868
1869 if (res == resolved)
1870 return returned_expr;
1871
1872 /* "Regular" built-in functions and overloaded functions share a namespace
1873 for some arrays, like rs6000_builtin_decls. But rs6000_overload_info
1874 only has information for the overloaded functions, so we need an
1875 adjusted index for that. */
1876 unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
1877
1878 if (res == resolved_bad)
1879 {
1880 const char *name = rs6000_overload_info[adj_fcode].ovld_name;
1881 error ("invalid parameter combination for AltiVec intrinsic %qs", name);
1882 return error_mark_node;
1883 }
1884
1885 bool unsupported_builtin = false;
1886 rs6000_gen_builtins instance_code;
1887 bool supported = false;
1888 ovlddata *instance = rs6000_overload_info[adj_fcode].first_instance;
1889 gcc_assert (instance != NULL);
1890
1891 /* Functions with no arguments can have only one overloaded instance. */
1892 gcc_assert (nargs > 0 || !instance->next);
1893
1894 /* Standard overload processing involves determining whether an instance
1895 exists that is type-compatible with the overloaded function call. In
1896 a couple of cases, we need to do some extra processing to disambiguate
1897 between multiple compatible instances. */
1898 switch (fcode)
1899 {
1900 /* Need to special case __builtin_cmpb because the overloaded forms
1901 of this function take (unsigned int, unsigned int) or (unsigned
1902 long long int, unsigned long long int). Since C conventions
1903 allow the respective argument types to be implicitly coerced into
1904 each other, the default handling does not provide adequate
1905 discrimination between the desired forms of the function. */
1906 case RS6000_OVLD_SCAL_CMPB:
1907 {
1908 machine_mode arg1_mode = TYPE_MODE (types[0]);
1909 machine_mode arg2_mode = TYPE_MODE (types[1]);
1910
1911 /* If any supplied arguments are wider than 32 bits, resolve to
1912 64-bit variant of built-in function. */
1913 if (GET_MODE_PRECISION (arg1_mode) > 32
1914 || GET_MODE_PRECISION (arg2_mode) > 32)
1915 /* Assure all argument and result types are compatible with
1916 the built-in function represented by RS6000_BIF_CMPB. */
1917 instance_code = RS6000_BIF_CMPB;
1918 else
1919 /* Assure all argument and result types are compatible with
1920 the built-in function represented by RS6000_BIF_CMPB_32. */
1921 instance_code = RS6000_BIF_CMPB_32;
1922
1923 tree call = find_instance (&unsupported_builtin, &instance,
1924 instance_code, fcode, types, args);
1925 if (call != error_mark_node)
1926 return call;
1927 break;
1928 }
1929 case RS6000_OVLD_VEC_VSIE:
1930 {
1931 machine_mode arg1_mode = TYPE_MODE (types[0]);
1932
1933 /* If supplied first argument is wider than 64 bits, resolve to
1934 128-bit variant of built-in function. */
1935 if (GET_MODE_PRECISION (arg1_mode) > 64)
1936 {
1937 /* If first argument is of float variety, choose variant
1938 that expects __ieee128 argument. Otherwise, expect
1939 __int128 argument. */
1940 if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
1941 instance_code = RS6000_BIF_VSIEQPF;
1942 else
1943 instance_code = RS6000_BIF_VSIEQP;
1944 }
1945 else
1946 {
1947 /* If first argument is of float variety, choose variant
1948 that expects double argument. Otherwise, expect
1949 long long int argument. */
1950 if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
1951 instance_code = RS6000_BIF_VSIEDPF;
1952 else
1953 instance_code = RS6000_BIF_VSIEDP;
1954 }
1955
1956 tree call = find_instance (&unsupported_builtin, &instance,
1957 instance_code, fcode, types, args);
1958 if (call != error_mark_node)
1959 return call;
1960 break;
1961 }
1962 default:
1963 /* Standard overload processing. Look for an instance with compatible
1964 parameter types. If it is supported in the current context, resolve
1965 the overloaded call to that instance. */
1966 for (; instance != NULL; instance = instance->next)
1967 {
1968 /* It is possible for an instance to require a data type that isn't
1969 defined on this target, in which case instance->fntype will be
1970 NULL. */
1971 if (!instance->fntype)
1972 continue;
1973
1974 bool mismatch = false;
1975 tree nextparm = TYPE_ARG_TYPES (instance->fntype);
1976
1977 for (unsigned int arg_i = 0;
1978 arg_i < nargs && nextparm != NULL;
1979 arg_i++)
1980 {
1981 tree parmtype = TREE_VALUE (nextparm);
1982 if (!rs6000_builtin_type_compatible (types[arg_i], parmtype))
1983 {
1984 mismatch = true;
1985 break;
1986 }
1987 nextparm = TREE_CHAIN (nextparm);
1988 }
1989
1990 if (mismatch)
1991 continue;
1992
1993 supported = rs6000_builtin_is_supported (instance->bifid);
1994 if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
1995 && supported)
1996 {
1997 tree fntype = rs6000_builtin_info[instance->bifid].fntype;
1998 tree ret_type = TREE_TYPE (instance->fntype);
1999 return altivec_build_resolved_builtin (args, nargs, fntype,
2000 ret_type, instance->bifid,
2001 fcode);
2002 }
2003 else
2004 {
2005 unsupported_builtin = true;
2006 break;
2007 }
2008 }
2009 }
2010
2011 if (unsupported_builtin)
2012 {
2013 const char *name = rs6000_overload_info[adj_fcode].ovld_name;
2014 if (!supported)
2015 {
2016 /* Indicate that the instantiation of the overloaded builtin
2017 name is not available with the target flags in effect. */
2018 rs6000_gen_builtins fcode = (rs6000_gen_builtins) instance->bifid;
2019 rs6000_invalid_builtin (fcode);
2020 /* Provide clarity of the relationship between the overload
2021 and the instantiation. */
2022 const char *internal_name
2023 = rs6000_builtin_info[instance->bifid].bifname;
2024 rich_location richloc (line_table, input_location);
2025 inform (&richloc,
2026 "overloaded builtin %qs is implemented by builtin %qs",
2027 name, internal_name);
2028 }
2029 else
2030 error ("%qs is not supported in this compiler configuration", name);
2031
2032 return error_mark_node;
2033 }
2034
2035 /* If we fall through to here, there were no compatible instances. */
2036 const char *name = rs6000_overload_info[adj_fcode].ovld_name;
2037 error ("invalid parameter combination for AltiVec intrinsic %qs", name);
2038 return error_mark_node;
2039 }
2040