* hooks.h (hook_uint_uintp_false): Rename to...
[official-gcc.git] / gcc / config / s390 / s390-c.c
blobcd3584bfdda20c477a0d29a73ac041d6a8eb9340
1 /* Language specific subroutines used for code generation on IBM S/390
2 and zSeries
3 Copyright (C) 2015-2016 Free Software Foundation, Inc.
5 Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
7 This file is part of GCC.
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 by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
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.
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/>.
23 Based on gcc/config/rs6000/rs6000-c.c.
25 In GCC terms this file belongs to the frontend. It will be
26 compiled with -DIN_GCC_FRONTEND. With that rtl.h cannot be
27 included anymore - a mechanism supposed to avoid adding frontend -
28 backend dependencies. */
30 #include "config.h"
31 #include "system.h"
32 #include "coretypes.h"
33 #include "target.h"
34 #include "tree.h"
35 #include "c-family/c-common.h"
36 #include "c/c-tree.h"
37 #include "tm_p.h"
38 #include "stringpool.h"
39 #include "c-family/c-pragma.h"
40 #include "langhooks.h"
41 #include "tree-pretty-print.h"
43 #include "s390-builtins.h"
45 static GTY(()) tree __vector_keyword;
46 static GTY(()) tree vector_keyword;
47 static GTY(()) tree __bool_keyword;
48 static GTY(()) tree bool_keyword;
49 static GTY(()) tree _Bool_keyword;
52 /* Generate an array holding all the descriptions of variants of
53 overloaded builtins defined with OB_DEF_VAR in
54 s390-builtins.def. */
55 static enum s390_builtin_ov_type_index
56 type_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
58 #undef B_DEF
59 #undef OB_DEF
60 #undef OB_DEF_VAR
61 #define B_DEF(...)
62 #define OB_DEF(...)
63 #define OB_DEF_VAR(NAME, PATTERN, FLAGS, FNTYPE) FNTYPE,
64 #include "s390-builtins.def"
65 BT_OV_MAX
69 /* Generate an array indexed by an overloaded builtin index returning
70 the first index in desc_for_overloaded_builtin_var where the
71 variants for the builtin can be found. */
72 static enum s390_overloaded_builtin_vars
73 desc_start_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
75 #undef B_DEF
76 #undef OB_DEF
77 #undef OB_DEF_VAR
78 #define B_DEF(...)
79 #define OB_DEF(NAME, FIRST_VAR_NAME,...) \
80 S390_OVERLOADED_BUILTIN_VAR_##FIRST_VAR_NAME,
81 #define OB_DEF_VAR(...)
82 #include "s390-builtins.def"
83 S390_OVERLOADED_BUILTIN_VAR_MAX
86 /* Generate an array indexed by an overloaded builtin index returning
87 the last index in desc_for_overloaded_builtin_var where the
88 variants for the builtin can be found. */
89 static enum s390_overloaded_builtin_vars
90 desc_end_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
92 #undef B_DEF
93 #undef OB_DEF
94 #undef OB_DEF_VAR
95 #define B_DEF(...)
96 #define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME,...) \
97 S390_OVERLOADED_BUILTIN_VAR_##LAST_VAR_NAME,
98 #define OB_DEF_VAR(...)
99 #include "s390-builtins.def"
100 S390_OVERLOADED_BUILTIN_VAR_MAX
103 static enum s390_builtin_type_index
104 s390_builtin_ov_types[BT_OV_MAX][MAX_OV_OPERANDS] =
106 #undef DEF_TYPE
107 #undef DEF_POINTER_TYPE
108 #undef DEF_DISTINCT_TYPE
109 #undef DEF_VECTOR_TYPE
110 #undef DEF_OPAQUE_VECTOR_TYPE
111 #undef DEF_FN_TYPE
112 #undef DEF_OV_TYPE
113 #define DEF_TYPE(...)
114 #define DEF_POINTER_TYPE(...)
115 #define DEF_DISTINCT_TYPE(...)
116 #define DEF_VECTOR_TYPE(...)
117 #define DEF_OPAQUE_VECTOR_TYPE(...)
118 #define DEF_FN_TYPE(...)
119 #define DEF_OV_TYPE(INDEX, args...) { args },
120 #include "s390-builtin-types.def"
123 static const enum s390_builtins
124 bt_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX] = {
125 #undef B_DEF
126 #undef OB_DEF
127 #undef OB_DEF_VAR
128 #define B_DEF(...)
129 #define OB_DEF(...)
130 #define OB_DEF_VAR(NAME, BT, ...) S390_BUILTIN_##BT,
132 #include "s390-builtins.def"
135 /* In addition to calling fold_convert for EXPR of type TYPE, also
136 call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be
137 hiding there (PR47197). */
138 tree
139 fully_fold_convert (tree type, tree expr)
141 tree result = fold_convert (type, expr);
142 bool maybe_const = true;
144 if (!c_dialect_cxx ())
145 result = c_fully_fold (result, false, &maybe_const);
147 return result;
150 /* Unify the different variants to the same nodes in order to keep the
151 code working with it simple. */
152 static cpp_hashnode *
153 s390_categorize_keyword (const cpp_token *tok)
155 if (tok->type == CPP_NAME)
157 cpp_hashnode *ident = tok->val.node.node;
159 if (ident == C_CPP_HASHNODE (vector_keyword))
160 return C_CPP_HASHNODE (__vector_keyword);
162 if (ident == C_CPP_HASHNODE (bool_keyword))
163 return C_CPP_HASHNODE (__bool_keyword);
165 if (ident == C_CPP_HASHNODE (_Bool_keyword))
166 return C_CPP_HASHNODE (__bool_keyword);
167 return ident;
170 return 0;
174 /* Called to decide whether a conditional macro should be expanded.
175 Since we have exactly one such macro (i.e, 'vector'), we do not
176 need to examine the 'tok' parameter. */
178 static cpp_hashnode *
179 s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
181 cpp_hashnode *expand_this = tok->val.node.node;
182 cpp_hashnode *ident;
183 static bool expand_bool_p = false;
184 int idx = 0;
185 enum rid rid_code;
187 /* The vector keyword is only expanded if the machine actually
188 provides hardware support. */
189 if (!TARGET_ZVECTOR)
190 return NULL;
192 ident = s390_categorize_keyword (tok);
194 /* Triggered when we picked a different variant in
195 s390_categorize_keyword. */
196 if (ident != expand_this)
197 expand_this = NULL;
199 /* The vector keyword has been found already and we remembered to
200 expand the next bool. */
201 if (expand_bool_p && ident == C_CPP_HASHNODE (__bool_keyword))
203 expand_bool_p = false;
204 return ident;
207 if (ident != C_CPP_HASHNODE (__vector_keyword))
208 return expand_this;
211 tok = cpp_peek_token (pfile, idx++);
212 while (tok->type == CPP_PADDING);
213 ident = s390_categorize_keyword (tok);
215 if (!ident)
216 return expand_this;
218 /* vector bool - remember to expand the next bool. */
219 if (ident == C_CPP_HASHNODE (__bool_keyword))
221 expand_bool_p = true;
222 return C_CPP_HASHNODE (__vector_keyword);
225 /* The boost libraries have code with Iterator::vector vector in it.
226 If we allow the normal handling, this module will be called
227 recursively, and the vector will be skipped.; */
228 if (ident == C_CPP_HASHNODE (__vector_keyword))
229 return expand_this;
231 rid_code = (enum rid)(ident->rid_code);
233 if (ident->type == NT_MACRO)
235 /* Now actually fetch the tokens we "peeked" before and do a
236 lookahead for the next. */
238 (void) cpp_get_token (pfile);
239 while (--idx > 0);
241 tok = cpp_peek_token (pfile, idx++);
242 while (tok->type == CPP_PADDING);
243 ident = s390_categorize_keyword (tok);
245 if (ident == C_CPP_HASHNODE (__bool_keyword))
247 expand_bool_p = true;
248 return C_CPP_HASHNODE (__vector_keyword);
250 else if (ident)
251 rid_code = (enum rid)(ident->rid_code);
254 /* vector keyword followed by type identifier: vector unsigned,
255 vector long, ...
256 Types consisting of more than one identifier are not supported by
257 zvector e.g. long long, long double, unsigned long int. */
258 if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
259 || rid_code == RID_SHORT || rid_code == RID_SIGNED
260 || rid_code == RID_INT || rid_code == RID_CHAR
261 || rid_code == RID_DOUBLE)
263 expand_this = C_CPP_HASHNODE (__vector_keyword);
264 /* If the next keyword is bool, it will need to be expanded as
265 well. */
267 tok = cpp_peek_token (pfile, idx++);
268 while (tok->type == CPP_PADDING);
269 ident = s390_categorize_keyword (tok);
271 /* __vector long __bool a; */
272 if (ident == C_CPP_HASHNODE (__bool_keyword))
273 expand_bool_p = true;
274 else
276 /* Triggered with: __vector long long __bool a; */
278 tok = cpp_peek_token (pfile, idx++);
279 while (tok->type == CPP_PADDING);
280 ident = s390_categorize_keyword (tok);
282 if (ident == C_CPP_HASHNODE (__bool_keyword))
283 expand_bool_p = true;
287 return expand_this;
290 /* Helper function that defines or undefines macros. If SET is true, the macro
291 MACRO_DEF is defined. If SET is false, the macro MACRO_UNDEF is undefined.
292 Nothing is done if SET and WAS_SET have the same value. */
293 static void
294 s390_def_or_undef_macro (cpp_reader *pfile,
295 unsigned int mask,
296 const struct cl_target_option *old_opts,
297 const struct cl_target_option *new_opts,
298 const char *macro_def, const char *macro_undef)
300 bool was_set;
301 bool set;
303 was_set = (!old_opts) ? false : old_opts->x_target_flags & mask;
304 set = new_opts->x_target_flags & mask;
305 if (was_set == set)
306 return;
307 if (set)
308 cpp_define (pfile, macro_def);
309 else
310 cpp_undef (pfile, macro_undef);
313 /* Internal function to either define or undef the appropriate system
314 macros. */
315 static void
316 s390_cpu_cpp_builtins_internal (cpp_reader *pfile,
317 struct cl_target_option *opts,
318 const struct cl_target_option *old_opts)
320 s390_def_or_undef_macro (pfile, MASK_OPT_HTM, old_opts, opts,
321 "__HTM__", "__HTM__");
322 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
323 "__VEC__=10301", "__VEC__");
324 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
325 "__vector=__attribute__((vector_size(16)))",
326 "__vector__");
327 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
328 "__bool=__attribute__((s390_vector_bool)) unsigned",
329 "__bool");
330 if (!flag_iso)
332 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
333 "__VECTOR_KEYWORD_SUPPORTED__",
334 "__VECTOR_KEYWORD_SUPPORTED__");
335 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
336 "vector=vector", "vector");
337 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
338 "bool=bool", "bool");
339 if (TARGET_ZVECTOR_P (opts->x_target_flags) && __vector_keyword == NULL)
341 __vector_keyword = get_identifier ("__vector");
342 C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
344 vector_keyword = get_identifier ("vector");
345 C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
347 __bool_keyword = get_identifier ("__bool");
348 C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
350 bool_keyword = get_identifier ("bool");
351 C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
353 _Bool_keyword = get_identifier ("_Bool");
354 C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
356 /* Enable context-sensitive macros. */
357 cpp_get_callbacks (pfile)->macro_to_expand = s390_macro_to_expand;
362 /* Define platform dependent macros. */
363 void
364 s390_cpu_cpp_builtins (cpp_reader *pfile)
366 struct cl_target_option opts;
368 cpp_assert (pfile, "cpu=s390");
369 cpp_assert (pfile, "machine=s390");
370 cpp_define (pfile, "__s390__");
371 if (TARGET_ZARCH)
372 cpp_define (pfile, "__zarch__");
373 if (TARGET_64BIT)
374 cpp_define (pfile, "__s390x__");
375 if (TARGET_LONG_DOUBLE_128)
376 cpp_define (pfile, "__LONG_DOUBLE_128__");
377 cl_target_option_save (&opts, &global_options);
378 s390_cpu_cpp_builtins_internal (pfile, &opts, NULL);
381 #if S390_USE_TARGET_ATTRIBUTE
382 /* Hook to validate the current #pragma GCC target and set the state, and
383 update the macros based on what was changed. If ARGS is NULL, then
384 POP_TARGET is used to reset the options. */
386 static bool
387 s390_pragma_target_parse (tree args, tree pop_target)
389 tree prev_tree = build_target_option_node (&global_options);
390 tree cur_tree;
392 if (! args)
393 cur_tree = pop_target;
394 else
396 cur_tree = s390_valid_target_attribute_tree (args, &global_options,
397 &global_options_set, true);
398 if (!cur_tree || cur_tree == error_mark_node)
400 cl_target_option_restore (&global_options,
401 TREE_TARGET_OPTION (prev_tree));
402 return false;
406 target_option_current_node = cur_tree;
407 s390_activate_target_options (target_option_current_node);
410 struct cl_target_option *prev_opt;
411 struct cl_target_option *cur_opt;
413 /* Figure out the previous/current differences. */
414 prev_opt = TREE_TARGET_OPTION (prev_tree);
415 cur_opt = TREE_TARGET_OPTION (cur_tree);
417 /* For the definitions, ensure all newly defined macros are considered
418 as used for -Wunused-macros. There is no point warning about the
419 compiler predefined macros. */
420 cpp_options *cpp_opts = cpp_get_options (parse_in);
421 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
423 cpp_opts->warn_unused_macros = 0;
425 /* Define all of the macros for new options that were just turned on. */
426 s390_cpu_cpp_builtins_internal (parse_in, cur_opt, prev_opt);
428 cpp_opts->warn_unused_macros = saved_warn_unused_macros;
431 return true;
433 #endif
435 /* Expand builtins which can directly be mapped to tree expressions.
436 LOC - location information
437 FCODE - function code of the builtin
438 ARGLIST - value supposed to be passed as arguments
439 RETURN-TYPE - expected return type of the builtin */
440 static tree
441 s390_expand_overloaded_builtin (location_t loc,
442 unsigned fcode,
443 vec<tree, va_gc> *arglist,
444 tree return_type)
446 switch (fcode)
448 case S390_OVERLOADED_BUILTIN_s390_vec_step:
449 if (TREE_CODE (TREE_TYPE ((*arglist)[0])) != VECTOR_TYPE)
451 error_at (loc, "Builtin vec_step can only be used on vector types.");
452 return error_mark_node;
454 return build_int_cst (NULL_TREE,
455 TYPE_VECTOR_SUBPARTS (TREE_TYPE ((*arglist)[0])));
456 case S390_OVERLOADED_BUILTIN_s390_vec_xld2:
457 case S390_OVERLOADED_BUILTIN_s390_vec_xlw4:
458 return build2 (MEM_REF, return_type,
459 fold_build_pointer_plus ((*arglist)[1], (*arglist)[0]),
460 build_int_cst (TREE_TYPE ((*arglist)[1]), 0));
461 case S390_OVERLOADED_BUILTIN_s390_vec_xstd2:
462 case S390_OVERLOADED_BUILTIN_s390_vec_xstw4:
463 return build2 (MODIFY_EXPR, TREE_TYPE((*arglist)[0]),
464 build1 (INDIRECT_REF, TREE_TYPE((*arglist)[0]),
465 fold_build_pointer_plus ((*arglist)[2], (*arglist)[1])),
466 (*arglist)[0]);
467 case S390_OVERLOADED_BUILTIN_s390_vec_load_pair:
468 return build_constructor_va (return_type, 2,
469 NULL_TREE, (*arglist)[0],
470 NULL_TREE, (*arglist)[1]);
471 default:
472 gcc_unreachable ();
476 /* invert result */
477 #define __VSTRING_FLAG_IN 8
478 /* result type */
479 #define __VSTRING_FLAG_RT 4
480 /* zero search */
481 #define __VSTRING_FLAG_ZS 2
482 /* set condition code */
483 #define __VSTRING_FLAG_CS 1
485 /* Return the flags value to be used for string low-level builtins
486 when expanded from overloaded builtin OB_FCODE. */
487 static unsigned int
488 s390_get_vstring_flags (int ob_fcode)
490 unsigned int flags = 0;
492 switch (ob_fcode)
494 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
495 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
496 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
497 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
498 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
499 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
500 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
501 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
502 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
503 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
504 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
505 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
506 flags |= __VSTRING_FLAG_IN;
507 break;
508 default:
509 break;
511 switch (ob_fcode)
514 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
515 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
516 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
517 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
518 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
519 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
520 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
521 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
522 flags |= __VSTRING_FLAG_RT;
523 break;
524 default:
525 break;
527 switch (ob_fcode)
530 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
531 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
532 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
533 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
534 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
535 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
536 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
537 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
538 flags |= __VSTRING_FLAG_ZS;
539 break;
540 default:
541 break;
543 switch (ob_fcode)
545 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
546 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
547 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
548 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
549 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
550 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
551 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
552 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
553 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
554 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
555 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
556 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
557 flags |= __VSTRING_FLAG_CS;
558 break;
559 default:
560 break;
562 return flags;
564 #undef __VSTRING_FLAG_IN
565 #undef __VSTRING_FLAG_RT
566 #undef __VSTRING_FLAG_ZS
567 #undef __VSTRING_FLAG_CS
569 /* For several overloaded builtins the argument lists do not match
570 exactly the signature of a low-level builtin. This function
571 adjusts the argument list ARGLIST for the overloaded builtin
572 OB_FCODE to the signature of the low-level builtin given by
573 DECL. */
574 static void
575 s390_adjust_builtin_arglist (unsigned int ob_fcode, tree decl,
576 vec<tree, va_gc> **arglist)
578 tree arg_chain;
579 int src_arg_index, dest_arg_index;
580 vec<tree, va_gc> *folded_args = NULL;
582 /* We at most add one more operand to the list. */
583 vec_alloc (folded_args, (*arglist)->allocated () + 1);
584 for (arg_chain = TYPE_ARG_TYPES (TREE_TYPE (decl)),
585 src_arg_index = 0, dest_arg_index = 0;
586 !VOID_TYPE_P (TREE_VALUE (arg_chain));
587 arg_chain = TREE_CHAIN (arg_chain), dest_arg_index++)
589 bool arg_assigned_p = false;
590 switch (ob_fcode)
592 /* For all these the low level builtin needs an additional flags parameter. */
593 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx:
594 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
595 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
596 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
597 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
598 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
599 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
600 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
601 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
602 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
603 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
604 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
605 if (dest_arg_index == 2)
607 folded_args->quick_push (build_int_cst (integer_type_node,
608 s390_get_vstring_flags (ob_fcode)));
609 arg_assigned_p = true;
611 break;
612 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx:
613 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
614 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
615 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
616 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
617 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
618 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
619 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
620 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
621 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
622 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
623 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
624 if (dest_arg_index == 3)
626 folded_args->quick_push (build_int_cst (integer_type_node,
627 s390_get_vstring_flags (ob_fcode)));
628 arg_assigned_p = true;
630 break;
631 case S390_OVERLOADED_BUILTIN_s390_vec_sel:
632 case S390_OVERLOADED_BUILTIN_s390_vec_insert:
633 case S390_OVERLOADED_BUILTIN_s390_vec_load_len:
634 /* Swap the first to arguments. It is better to do it here
635 instead of the header file to avoid operand checking
636 throwing error messages for a weird operand index. */
637 if (dest_arg_index < 2)
639 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
640 (**arglist)[1 - dest_arg_index]));
641 src_arg_index++;
642 arg_assigned_p = true;
644 break;
645 case S390_OVERLOADED_BUILTIN_s390_vec_store_len:
646 if (dest_arg_index == 1 || dest_arg_index == 2)
648 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
649 (**arglist)[3 - dest_arg_index]));
650 src_arg_index++;
651 arg_assigned_p = true;
653 break;
655 case S390_OVERLOADED_BUILTIN_s390_vec_load_bndry:
657 int code;
659 if (dest_arg_index == 1)
661 switch (tree_to_uhwi ((**arglist)[src_arg_index]))
663 case 64: code = 0; break;
664 case 128: code = 1; break;
665 case 256: code = 2; break;
666 case 512: code = 3; break;
667 case 1024: code = 4; break;
668 case 2048: code = 5; break;
669 case 4096: code = 6; break;
670 default:
671 error ("valid values for builtin %qF argument %d are 64, "
672 "128, 256, 512, 1024, 2048, and 4096", decl,
673 src_arg_index + 1);
674 return;
676 folded_args->quick_push (build_int_cst (integer_type_node,
677 code));
678 src_arg_index++;
679 arg_assigned_p = true;
682 break;
683 case S390_OVERLOADED_BUILTIN_s390_vec_rl_mask:
684 /* Duplicate the first src arg. */
685 if (dest_arg_index == 0)
687 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
688 (**arglist)[src_arg_index]));
689 arg_assigned_p = true;
691 break;
692 default:
693 break;
695 if (!arg_assigned_p)
697 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
698 (**arglist)[src_arg_index]));
699 src_arg_index++;
702 *arglist = folded_args;
705 /* Check whether the arguments in ARGLIST match the function type
706 DEF_TYPE. Return the number of argument types which required
707 conversion/promotion in order to make it match.
708 0 stands for a perfect match - all operand types match without changes
709 INT_MAX stands for a mismatch. */
710 static int
711 s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex,
712 vec<tree, va_gc> *arglist)
714 unsigned int i;
715 int match_type = 0;
717 for (i = 0; i < vec_safe_length (arglist); i++)
719 tree b_arg_type = s390_builtin_types[s390_builtin_ov_types[typeindex][i + 1]];
720 tree in_arg = (*arglist)[i];
721 tree in_type = TREE_TYPE (in_arg);
723 if (TREE_CODE (b_arg_type) == VECTOR_TYPE)
725 /* Vector types have to match precisely. */
726 if (b_arg_type != in_type
727 && TYPE_MAIN_VARIANT (b_arg_type) != TYPE_MAIN_VARIANT (in_type))
728 goto mismatch;
731 if (lang_hooks.types_compatible_p (in_type, b_arg_type))
732 continue;
734 if (lang_hooks.types_compatible_p (
735 lang_hooks.types.type_promotes_to (in_type),
736 lang_hooks.types.type_promotes_to (b_arg_type)))
738 match_type++;
739 continue;
742 /* In this stage the C++ frontend would go ahead trying to find
743 implicit conversion chains for the argument to match the
744 target type. We will mimic this here only for our limited
745 subset of argument types. */
746 if (TREE_CODE (b_arg_type) == INTEGER_TYPE
747 && TREE_CODE (in_type) == INTEGER_TYPE)
749 match_type++;
750 continue;
753 /* If the incoming pointer argument has more qualifiers than the
754 argument type it can still be an imperfect match. */
755 if (POINTER_TYPE_P (b_arg_type) && POINTER_TYPE_P (in_type)
756 && !(TYPE_QUALS (TREE_TYPE (in_type))
757 & ~TYPE_QUALS (TREE_TYPE (b_arg_type)))
758 && (TYPE_QUALS (TREE_TYPE (b_arg_type))
759 & ~TYPE_QUALS (TREE_TYPE (in_type))))
761 tree qual_in_type =
762 build_qualified_type (TREE_TYPE (in_type),
763 TYPE_QUALS (TREE_TYPE (b_arg_type)));
765 if (lang_hooks.types_compatible_p (qual_in_type,
766 TREE_TYPE (b_arg_type)))
768 match_type++;
769 continue;
773 mismatch:
774 if (TARGET_DEBUG_ARG)
775 fprintf (stderr, " mismatch in operand: %d\n", i + 1);
776 return INT_MAX;
779 return match_type;
782 /* Return the number of elements in the vector arguments of FNDECL in
783 case all it matches for all vector arguments, -1 otherwise. */
784 static int
785 s390_vec_n_elem (tree fndecl)
787 tree b_arg_chain;
788 int n_elem = -1;
790 if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) == VECTOR_TYPE)
791 n_elem = TYPE_VECTOR_SUBPARTS (TREE_TYPE (TREE_TYPE ((fndecl))));
793 for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
794 !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
795 b_arg_chain = TREE_CHAIN (b_arg_chain))
797 int tmp_n_elem;
798 if (TREE_CODE (TREE_VALUE (b_arg_chain)) != VECTOR_TYPE)
799 continue;
800 tmp_n_elem = TYPE_VECTOR_SUBPARTS (TREE_VALUE (b_arg_chain));
801 if (n_elem != -1 && n_elem != tmp_n_elem)
802 return -1;
803 n_elem = tmp_n_elem;
805 return n_elem;
809 /* Return a tree expression for a call to the overloaded builtin
810 function OB_FNDECL at LOC with arguments PASSED_ARGLIST. */
811 tree
812 s390_resolve_overloaded_builtin (location_t loc,
813 tree ob_fndecl,
814 void *passed_arglist)
816 vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
817 unsigned int in_args_num = vec_safe_length (arglist);
818 unsigned int ob_args_num = 0;
819 unsigned int ob_fcode = DECL_FUNCTION_CODE (ob_fndecl);
820 enum s390_overloaded_builtin_vars bindex;
821 unsigned int i;
822 int last_match_type = INT_MAX;
823 int last_match_index = -1;
824 unsigned int all_op_flags;
825 int num_matches = 0;
826 tree target_builtin_decl, b_arg_chain, return_type;
827 enum s390_builtin_ov_type_index last_match_fntype_index;
829 if (TARGET_DEBUG_ARG)
830 fprintf (stderr,
831 "s390_resolve_overloaded_builtin, code = %4d, %s - %s overloaded\n",
832 (int)ob_fcode, IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)),
833 ob_fcode < S390_BUILTIN_MAX ? "not" : "");
835 /* 0...S390_BUILTIN_MAX-1 is for non-overloaded builtins. */
836 if (ob_fcode < S390_BUILTIN_MAX)
838 if (bflags_for_builtin(ob_fcode) & B_INT)
840 error_at (loc,
841 "Builtin %qF is for GCC internal use only.",
842 ob_fndecl);
843 return error_mark_node;
845 return NULL_TREE;
848 ob_fcode -= S390_BUILTIN_MAX;
850 for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (ob_fndecl));
851 !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
852 b_arg_chain = TREE_CHAIN (b_arg_chain))
853 ob_args_num++;
855 if (ob_args_num != in_args_num)
857 error_at (loc,
858 "Mismatch in number of arguments for builtin %qF. "
859 "Expected: %d got %d", ob_fndecl,
860 ob_args_num, in_args_num);
861 return error_mark_node;
864 for (i = 0; i < in_args_num; i++)
865 if ((*arglist)[i] == error_mark_node)
866 return error_mark_node;
868 /* Overloaded builtins without any variants are directly expanded here. */
869 if (desc_start_for_overloaded_builtin[ob_fcode] ==
870 S390_OVERLOADED_BUILTIN_VAR_MAX)
871 return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, NULL_TREE);
873 for (bindex = desc_start_for_overloaded_builtin[ob_fcode];
874 bindex <= desc_end_for_overloaded_builtin[ob_fcode];
875 bindex = (enum s390_overloaded_builtin_vars)((int)bindex + 1))
877 int match_type;
878 enum s390_builtin_ov_type_index type_index =
879 type_for_overloaded_builtin_var[bindex];
881 if (TARGET_DEBUG_ARG)
882 fprintf (stderr, "checking variant number: %d", (int)bindex);
884 match_type = s390_fn_types_compatible (type_index, arglist);
886 if (match_type == INT_MAX)
887 continue;
889 if (TARGET_DEBUG_ARG)
890 fprintf (stderr,
891 " %s match score: %d\n", match_type == 0 ? "perfect" : "imperfect",
892 match_type);
894 if (match_type < last_match_type)
896 num_matches = 1;
897 last_match_type = match_type;
898 last_match_fntype_index = type_index;
899 last_match_index = bindex;
901 else if (match_type == last_match_type)
902 num_matches++;
905 if (last_match_type == INT_MAX)
907 error_at (loc, "invalid parameter combination for intrinsic %qs",
908 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
909 return error_mark_node;
911 else if (num_matches > 1)
913 error_at (loc, "ambiguous overload for intrinsic %qs",
914 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
915 return error_mark_node;
918 if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
919 target_builtin_decl = ob_fndecl;
920 else
921 target_builtin_decl = s390_builtin_decls[bt_for_overloaded_builtin_var[last_match_index]];
923 all_op_flags = opflags_overloaded_builtin_var[last_match_index];
924 return_type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][0]];
926 /* Check for the operand flags in the overloaded builtin variant. */
927 for (i = 0; i < ob_args_num; i++)
929 unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
930 tree arg = (*arglist)[i];
931 tree type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][i + 1]];
933 all_op_flags = all_op_flags >> O_SHIFT;
935 if (op_flags == O_ELEM)
937 int n_elem = s390_vec_n_elem (target_builtin_decl);
938 gcc_assert (n_elem > 0);
939 gcc_assert (type == integer_type_node);
940 (*arglist)[i] = build2 (BIT_AND_EXPR, integer_type_node,
941 fold_convert (integer_type_node, arg),
942 build_int_cst (NULL_TREE, n_elem - 1));
945 if (TREE_CODE (arg) != INTEGER_CST || !O_IMM_P (op_flags))
946 continue;
948 if ((TYPE_UNSIGNED (type)
949 && !int_fits_type_p (arg, c_common_unsigned_type (type)))
950 || (!TYPE_UNSIGNED (type)
951 && !int_fits_type_p (arg, c_common_signed_type (type))))
953 error("constant argument %d for builtin %qF is out "
954 "of range for target type",
955 i + 1, target_builtin_decl);
956 return error_mark_node;
959 if (TREE_CODE (arg) == INTEGER_CST
960 && !s390_const_operand_ok (arg, i + 1, op_flags, target_builtin_decl))
961 return error_mark_node;
964 /* Handle builtins we expand directly - without mapping it to a low
965 level builtin. */
966 if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
967 return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, return_type);
969 s390_adjust_builtin_arglist (ob_fcode, target_builtin_decl, &arglist);
971 if (VOID_TYPE_P (return_type))
972 return build_function_call_vec (loc, vNULL, target_builtin_decl,
973 arglist, NULL);
974 else
975 return fully_fold_convert (return_type,
976 build_function_call_vec (loc, vNULL, target_builtin_decl,
977 arglist, NULL));
980 /* This is used to define the REGISTER_TARGET_PRAGMAS macro in s390.h. */
981 void
982 s390_register_target_pragmas (void)
984 targetm.resolve_overloaded_builtin = s390_resolve_overloaded_builtin;
985 #if S390_USE_TARGET_ATTRIBUTE
986 /* Update pragma hook to allow parsing #pragma GCC target. */
987 targetm.target_option.pragma_parse = s390_pragma_target_parse;
988 #endif