1 /* Language specific subroutines used for code generation on IBM S/390
3 Copyright (C) 2015-2017 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)
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. */
32 #include "coretypes.h"
35 #include "c-family/c-common.h"
39 #include "stringpool.h"
40 #include "c-family/c-pragma.h"
41 #include "langhooks.h"
42 #include "tree-pretty-print.h"
44 #include "s390-builtins.h"
46 static GTY(()) tree __vector_keyword;
47 static GTY(()) tree vector_keyword;
48 static GTY(()) tree __bool_keyword;
49 static GTY(()) tree bool_keyword;
50 static GTY(()) tree _Bool_keyword;
53 /* Generate an array holding all the descriptions of variants of
54 overloaded builtins defined with OB_DEF_VAR in
56 static enum s390_builtin_ov_type_index
57 type_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
64 #define OB_DEF_VAR(NAME, PATTERN, FLAGS, FNTYPE) FNTYPE,
65 #include "s390-builtins.def"
70 /* Generate an array indexed by an overloaded builtin index returning
71 the first index in desc_for_overloaded_builtin_var where the
72 variants for the builtin can be found. */
73 static enum s390_overloaded_builtin_vars
74 desc_start_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
80 #define OB_DEF(NAME, FIRST_VAR_NAME,...) \
81 S390_OVERLOADED_BUILTIN_VAR_##FIRST_VAR_NAME,
82 #define OB_DEF_VAR(...)
83 #include "s390-builtins.def"
84 S390_OVERLOADED_BUILTIN_VAR_MAX
87 /* Generate an array indexed by an overloaded builtin index returning
88 the last index in desc_for_overloaded_builtin_var where the
89 variants for the builtin can be found. */
90 static enum s390_overloaded_builtin_vars
91 desc_end_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
97 #define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME,...) \
98 S390_OVERLOADED_BUILTIN_VAR_##LAST_VAR_NAME,
99 #define OB_DEF_VAR(...)
100 #include "s390-builtins.def"
101 S390_OVERLOADED_BUILTIN_VAR_MAX
104 static enum s390_builtin_type_index
105 s390_builtin_ov_types[BT_OV_MAX][MAX_OV_OPERANDS] =
108 #undef DEF_POINTER_TYPE
109 #undef DEF_DISTINCT_TYPE
110 #undef DEF_VECTOR_TYPE
111 #undef DEF_OPAQUE_VECTOR_TYPE
114 #define DEF_TYPE(...)
115 #define DEF_POINTER_TYPE(...)
116 #define DEF_DISTINCT_TYPE(...)
117 #define DEF_VECTOR_TYPE(...)
118 #define DEF_OPAQUE_VECTOR_TYPE(...)
119 #define DEF_FN_TYPE(...)
120 #define DEF_OV_TYPE(INDEX, args...) { args },
121 #include "s390-builtin-types.def"
124 static const enum s390_builtins
125 bt_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX] = {
131 #define OB_DEF_VAR(NAME, BT, ...) S390_BUILTIN_##BT,
133 #include "s390-builtins.def"
136 /* In addition to calling fold_convert for EXPR of type TYPE, also
137 call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be
138 hiding there (PR47197). */
140 fully_fold_convert (tree type, tree expr)
142 tree result = fold_convert (type, expr);
143 bool maybe_const = true;
145 if (!c_dialect_cxx ())
146 result = c_fully_fold (result, false, &maybe_const);
151 /* Unify the different variants to the same nodes in order to keep the
152 code working with it simple. */
153 static cpp_hashnode *
154 s390_categorize_keyword (const cpp_token *tok)
156 if (tok->type == CPP_NAME)
158 cpp_hashnode *ident = tok->val.node.node;
160 if (ident == C_CPP_HASHNODE (vector_keyword))
161 return C_CPP_HASHNODE (__vector_keyword);
163 if (ident == C_CPP_HASHNODE (bool_keyword))
164 return C_CPP_HASHNODE (__bool_keyword);
166 if (ident == C_CPP_HASHNODE (_Bool_keyword))
167 return C_CPP_HASHNODE (__bool_keyword);
175 /* Called to decide whether a conditional macro should be expanded.
176 Since we have exactly one such macro (i.e, 'vector'), we do not
177 need to examine the 'tok' parameter. */
179 static cpp_hashnode *
180 s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
182 cpp_hashnode *expand_this = tok->val.node.node;
184 static bool expand_bool_p = false;
188 /* The vector keyword is only expanded if the machine actually
189 provides hardware support. */
193 ident = s390_categorize_keyword (tok);
195 /* Triggered when we picked a different variant in
196 s390_categorize_keyword. */
197 if (ident != expand_this)
200 /* The vector keyword has been found already and we remembered to
201 expand the next bool. */
202 if (expand_bool_p && ident == C_CPP_HASHNODE (__bool_keyword))
204 expand_bool_p = false;
208 if (ident != C_CPP_HASHNODE (__vector_keyword))
212 tok = cpp_peek_token (pfile, idx++);
213 while (tok->type == CPP_PADDING);
214 ident = s390_categorize_keyword (tok);
219 /* vector bool - remember to expand the next bool. */
220 if (ident == C_CPP_HASHNODE (__bool_keyword))
222 expand_bool_p = true;
223 return C_CPP_HASHNODE (__vector_keyword);
226 /* The boost libraries have code with Iterator::vector vector in it.
227 If we allow the normal handling, this module will be called
228 recursively, and the vector will be skipped.; */
229 if (ident == C_CPP_HASHNODE (__vector_keyword))
232 rid_code = (enum rid)(ident->rid_code);
234 if (ident->type == NT_MACRO)
236 /* Now actually fetch the tokens we "peeked" before and do a
237 lookahead for the next. */
239 (void) cpp_get_token (pfile);
242 tok = cpp_peek_token (pfile, idx++);
243 while (tok->type == CPP_PADDING);
244 ident = s390_categorize_keyword (tok);
246 if (ident == C_CPP_HASHNODE (__bool_keyword))
248 expand_bool_p = true;
249 return C_CPP_HASHNODE (__vector_keyword);
252 rid_code = (enum rid)(ident->rid_code);
255 /* vector keyword followed by type identifier: vector unsigned,
257 Types consisting of more than one identifier are not supported by
258 zvector e.g. long long, long double, unsigned long int. */
259 if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
260 || rid_code == RID_SHORT || rid_code == RID_SIGNED
261 || rid_code == RID_INT || rid_code == RID_CHAR
262 || rid_code == RID_DOUBLE)
264 expand_this = C_CPP_HASHNODE (__vector_keyword);
265 /* If the next keyword is bool, it will need to be expanded as
268 tok = cpp_peek_token (pfile, idx++);
269 while (tok->type == CPP_PADDING);
270 ident = s390_categorize_keyword (tok);
272 /* __vector long __bool a; */
273 if (ident == C_CPP_HASHNODE (__bool_keyword))
274 expand_bool_p = true;
277 /* Triggered with: __vector long long __bool a; */
279 tok = cpp_peek_token (pfile, idx++);
280 while (tok->type == CPP_PADDING);
281 ident = s390_categorize_keyword (tok);
283 if (ident == C_CPP_HASHNODE (__bool_keyword))
284 expand_bool_p = true;
291 /* Helper function that defines or undefines macros. If SET is true, the macro
292 MACRO_DEF is defined. If SET is false, the macro MACRO_UNDEF is undefined.
293 Nothing is done if SET and WAS_SET have the same value. */
295 s390_def_or_undef_macro (cpp_reader *pfile,
297 const struct cl_target_option *old_opts,
298 const struct cl_target_option *new_opts,
299 const char *macro_def, const char *macro_undef)
304 was_set = (!old_opts) ? false : old_opts->x_target_flags & mask;
305 set = new_opts->x_target_flags & mask;
309 cpp_define (pfile, macro_def);
311 cpp_undef (pfile, macro_undef);
314 /* Internal function to either define or undef the appropriate system
317 s390_cpu_cpp_builtins_internal (cpp_reader *pfile,
318 struct cl_target_option *opts,
319 const struct cl_target_option *old_opts)
321 s390_def_or_undef_macro (pfile, MASK_OPT_HTM, old_opts, opts,
322 "__HTM__", "__HTM__");
323 s390_def_or_undef_macro (pfile, MASK_OPT_VX, old_opts, opts,
325 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
326 "__VEC__=10301", "__VEC__");
327 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
328 "__vector=__attribute__((vector_size(16)))",
330 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
331 "__bool=__attribute__((s390_vector_bool)) unsigned",
336 gcc_assert (s390_arch != PROCESSOR_NATIVE);
337 arch_level = (int)s390_arch + 3;
338 if (s390_arch >= PROCESSOR_2094_Z9_EC)
339 /* Z9_EC has the same level as Z9_109. */
341 /* Review when a new arch is added and increase the value. */
342 char dummy[(PROCESSOR_max > 12) ? -1 : 1] __attribute__((unused));
343 sprintf (macro_def, "__ARCH__=%d", arch_level);
344 cpp_undef (pfile, "__ARCH__");
345 cpp_define (pfile, macro_def);
350 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
351 "__VECTOR_KEYWORD_SUPPORTED__",
352 "__VECTOR_KEYWORD_SUPPORTED__");
353 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
354 "vector=vector", "vector");
355 s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
356 "bool=bool", "bool");
357 if (TARGET_ZVECTOR_P (opts->x_target_flags) && __vector_keyword == NULL)
359 __vector_keyword = get_identifier ("__vector");
360 C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
362 vector_keyword = get_identifier ("vector");
363 C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
365 __bool_keyword = get_identifier ("__bool");
366 C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
368 bool_keyword = get_identifier ("bool");
369 C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
371 _Bool_keyword = get_identifier ("_Bool");
372 C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
374 /* Enable context-sensitive macros. */
375 cpp_get_callbacks (pfile)->macro_to_expand = s390_macro_to_expand;
380 /* Define platform dependent macros. */
382 s390_cpu_cpp_builtins (cpp_reader *pfile)
384 struct cl_target_option opts;
386 cpp_assert (pfile, "cpu=s390");
387 cpp_assert (pfile, "machine=s390");
388 cpp_define (pfile, "__s390__");
390 cpp_define (pfile, "__zarch__");
392 cpp_define (pfile, "__s390x__");
393 if (TARGET_LONG_DOUBLE_128)
394 cpp_define (pfile, "__LONG_DOUBLE_128__");
395 cl_target_option_save (&opts, &global_options);
396 s390_cpu_cpp_builtins_internal (pfile, &opts, NULL);
399 #if S390_USE_TARGET_ATTRIBUTE
400 /* Hook to validate the current #pragma GCC target and set the state, and
401 update the macros based on what was changed. If ARGS is NULL, then
402 POP_TARGET is used to reset the options. */
405 s390_pragma_target_parse (tree args, tree pop_target)
407 tree prev_tree = build_target_option_node (&global_options);
411 cur_tree = pop_target;
414 cur_tree = s390_valid_target_attribute_tree (args, &global_options,
415 &global_options_set, true);
416 if (!cur_tree || cur_tree == error_mark_node)
418 cl_target_option_restore (&global_options,
419 TREE_TARGET_OPTION (prev_tree));
424 target_option_current_node = cur_tree;
425 s390_activate_target_options (target_option_current_node);
428 struct cl_target_option *prev_opt;
429 struct cl_target_option *cur_opt;
431 /* Figure out the previous/current differences. */
432 prev_opt = TREE_TARGET_OPTION (prev_tree);
433 cur_opt = TREE_TARGET_OPTION (cur_tree);
435 /* For the definitions, ensure all newly defined macros are considered
436 as used for -Wunused-macros. There is no point warning about the
437 compiler predefined macros. */
438 cpp_options *cpp_opts = cpp_get_options (parse_in);
439 unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
441 cpp_opts->warn_unused_macros = 0;
443 /* Define all of the macros for new options that were just turned on. */
444 s390_cpu_cpp_builtins_internal (parse_in, cur_opt, prev_opt);
446 cpp_opts->warn_unused_macros = saved_warn_unused_macros;
453 /* Expand builtins which can directly be mapped to tree expressions.
454 LOC - location information
455 FCODE - function code of the builtin
456 ARGLIST - value supposed to be passed as arguments
457 RETURN-TYPE - expected return type of the builtin */
459 s390_expand_overloaded_builtin (location_t loc,
461 vec<tree, va_gc> *arglist,
466 case S390_OVERLOADED_BUILTIN_s390_vec_step:
467 if (TREE_CODE (TREE_TYPE ((*arglist)[0])) != VECTOR_TYPE)
469 error_at (loc, "builtin vec_step can only be used on vector types.");
470 return error_mark_node;
472 return build_int_cst (NULL_TREE,
473 TYPE_VECTOR_SUBPARTS (TREE_TYPE ((*arglist)[0])));
474 case S390_OVERLOADED_BUILTIN_s390_vec_xld2:
475 case S390_OVERLOADED_BUILTIN_s390_vec_xlw4:
476 return build2 (MEM_REF, return_type,
477 fold_build_pointer_plus ((*arglist)[1], (*arglist)[0]),
478 build_int_cst (TREE_TYPE ((*arglist)[1]), 0));
479 case S390_OVERLOADED_BUILTIN_s390_vec_xstd2:
480 case S390_OVERLOADED_BUILTIN_s390_vec_xstw4:
481 return build2 (MODIFY_EXPR, TREE_TYPE((*arglist)[0]),
482 build1 (INDIRECT_REF, TREE_TYPE((*arglist)[0]),
483 fold_build_pointer_plus ((*arglist)[2], (*arglist)[1])),
485 case S390_OVERLOADED_BUILTIN_s390_vec_load_pair:
486 return build_constructor_va (return_type, 2,
487 NULL_TREE, (*arglist)[0],
488 NULL_TREE, (*arglist)[1]);
495 #define __VSTRING_FLAG_IN 8
497 #define __VSTRING_FLAG_RT 4
499 #define __VSTRING_FLAG_ZS 2
500 /* set condition code */
501 #define __VSTRING_FLAG_CS 1
503 /* Return the flags value to be used for string low-level builtins
504 when expanded from overloaded builtin OB_FCODE. */
506 s390_get_vstring_flags (int ob_fcode)
508 unsigned int flags = 0;
512 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
513 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
514 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
515 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
516 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
517 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
518 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
519 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
520 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
521 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
522 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
523 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
524 flags |= __VSTRING_FLAG_IN;
532 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
533 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
534 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
535 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
536 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
537 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
538 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
539 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
540 flags |= __VSTRING_FLAG_RT;
548 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
549 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
550 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
551 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
552 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
553 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
554 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
555 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
556 flags |= __VSTRING_FLAG_ZS;
563 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
564 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
565 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
566 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
567 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
568 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
569 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
570 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
571 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
572 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
573 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
574 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
575 flags |= __VSTRING_FLAG_CS;
582 #undef __VSTRING_FLAG_IN
583 #undef __VSTRING_FLAG_RT
584 #undef __VSTRING_FLAG_ZS
585 #undef __VSTRING_FLAG_CS
587 /* For several overloaded builtins the argument lists do not match
588 exactly the signature of a low-level builtin. This function
589 adjusts the argument list ARGLIST for the overloaded builtin
590 OB_FCODE to the signature of the low-level builtin given by
593 s390_adjust_builtin_arglist (unsigned int ob_fcode, tree decl,
594 vec<tree, va_gc> **arglist)
597 int src_arg_index, dest_arg_index;
598 vec<tree, va_gc> *folded_args = NULL;
600 /* We at most add one more operand to the list. */
601 vec_alloc (folded_args, (*arglist)->allocated () + 1);
602 for (arg_chain = TYPE_ARG_TYPES (TREE_TYPE (decl)),
603 src_arg_index = 0, dest_arg_index = 0;
604 !VOID_TYPE_P (TREE_VALUE (arg_chain));
605 arg_chain = TREE_CHAIN (arg_chain), dest_arg_index++)
607 bool arg_assigned_p = false;
610 /* For all these the low level builtin needs an additional flags parameter. */
611 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx:
612 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
613 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
614 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
615 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
616 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
617 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
618 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
619 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
620 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
621 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
622 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
623 if (dest_arg_index == 2)
625 folded_args->quick_push (build_int_cst (integer_type_node,
626 s390_get_vstring_flags (ob_fcode)));
627 arg_assigned_p = true;
630 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx:
631 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
632 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
633 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
634 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
635 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
636 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
637 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
638 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
639 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
640 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
641 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
642 if (dest_arg_index == 3)
644 folded_args->quick_push (build_int_cst (integer_type_node,
645 s390_get_vstring_flags (ob_fcode)));
646 arg_assigned_p = true;
649 case S390_OVERLOADED_BUILTIN_s390_vec_sel:
650 case S390_OVERLOADED_BUILTIN_s390_vec_insert:
651 case S390_OVERLOADED_BUILTIN_s390_vec_load_len:
652 /* Swap the first to arguments. It is better to do it here
653 instead of the header file to avoid operand checking
654 throwing error messages for a weird operand index. */
655 if (dest_arg_index < 2)
657 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
658 (**arglist)[1 - dest_arg_index]));
660 arg_assigned_p = true;
663 case S390_OVERLOADED_BUILTIN_s390_vec_store_len:
664 if (dest_arg_index == 1 || dest_arg_index == 2)
666 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
667 (**arglist)[3 - dest_arg_index]));
669 arg_assigned_p = true;
673 case S390_OVERLOADED_BUILTIN_s390_vec_load_bndry:
676 if (dest_arg_index == 1)
678 tree arg = (**arglist)[src_arg_index];
680 if (TREE_CODE (arg) != INTEGER_CST)
682 error ("constant value required for builtin %qF argument %d",
683 decl, src_arg_index + 1);
687 switch (tree_to_uhwi (arg))
689 case 64: code = 0; break;
690 case 128: code = 1; break;
691 case 256: code = 2; break;
692 case 512: code = 3; break;
693 case 1024: code = 4; break;
694 case 2048: code = 5; break;
695 case 4096: code = 6; break;
697 error ("valid values for builtin %qF argument %d are 64, "
698 "128, 256, 512, 1024, 2048, and 4096", decl,
702 folded_args->quick_push (build_int_cst (integer_type_node,
705 arg_assigned_p = true;
709 case S390_OVERLOADED_BUILTIN_s390_vec_rl_mask:
710 /* Duplicate the first src arg. */
711 if (dest_arg_index == 0)
713 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
714 (**arglist)[src_arg_index]));
715 arg_assigned_p = true;
723 folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
724 (**arglist)[src_arg_index]));
728 *arglist = folded_args;
731 /* Check whether the arguments in ARGLIST match the function type
732 DEF_TYPE. Return the number of argument types which required
733 conversion/promotion in order to make it match.
734 0 stands for a perfect match - all operand types match without changes
735 INT_MAX stands for a mismatch. */
737 s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex,
738 vec<tree, va_gc> *arglist)
743 for (i = 0; i < vec_safe_length (arglist); i++)
745 tree b_arg_type = s390_builtin_types[s390_builtin_ov_types[typeindex][i + 1]];
746 tree in_arg = (*arglist)[i];
747 tree in_type = TREE_TYPE (in_arg);
749 if (TREE_CODE (b_arg_type) == VECTOR_TYPE)
751 /* Vector types have to match precisely. */
752 if (b_arg_type != in_type
753 && TYPE_MAIN_VARIANT (b_arg_type) != TYPE_MAIN_VARIANT (in_type))
757 if (lang_hooks.types_compatible_p (in_type, b_arg_type))
760 if (lang_hooks.types_compatible_p (
761 lang_hooks.types.type_promotes_to (in_type),
762 lang_hooks.types.type_promotes_to (b_arg_type)))
768 /* In this stage the C++ frontend would go ahead trying to find
769 implicit conversion chains for the argument to match the
770 target type. We will mimic this here only for our limited
771 subset of argument types. */
772 if (TREE_CODE (b_arg_type) == INTEGER_TYPE
773 && TREE_CODE (in_type) == INTEGER_TYPE)
779 /* If the incoming pointer argument has more qualifiers than the
780 argument type it can still be an imperfect match. */
781 if (POINTER_TYPE_P (b_arg_type) && POINTER_TYPE_P (in_type)
782 && !(TYPE_QUALS (TREE_TYPE (in_type))
783 & ~TYPE_QUALS (TREE_TYPE (b_arg_type)))
784 && (TYPE_QUALS (TREE_TYPE (b_arg_type))
785 & ~TYPE_QUALS (TREE_TYPE (in_type))))
788 build_qualified_type (TREE_TYPE (in_type),
789 TYPE_QUALS (TREE_TYPE (b_arg_type)));
791 if (lang_hooks.types_compatible_p (qual_in_type,
792 TREE_TYPE (b_arg_type)))
800 if (TARGET_DEBUG_ARG)
801 fprintf (stderr, " mismatch in operand: %d\n", i + 1);
808 /* Return the number of elements in the vector arguments of FNDECL in
809 case all it matches for all vector arguments, -1 otherwise. */
811 s390_vec_n_elem (tree fndecl)
816 if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) == VECTOR_TYPE)
817 n_elem = TYPE_VECTOR_SUBPARTS (TREE_TYPE (TREE_TYPE ((fndecl))));
819 for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
820 !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
821 b_arg_chain = TREE_CHAIN (b_arg_chain))
824 if (TREE_CODE (TREE_VALUE (b_arg_chain)) != VECTOR_TYPE)
826 tmp_n_elem = TYPE_VECTOR_SUBPARTS (TREE_VALUE (b_arg_chain));
827 if (n_elem != -1 && n_elem != tmp_n_elem)
835 /* Return a tree expression for a call to the overloaded builtin
836 function OB_FNDECL at LOC with arguments PASSED_ARGLIST. */
838 s390_resolve_overloaded_builtin (location_t loc,
840 void *passed_arglist)
842 vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
843 unsigned int in_args_num = vec_safe_length (arglist);
844 unsigned int ob_args_num = 0;
845 unsigned int ob_fcode = DECL_FUNCTION_CODE (ob_fndecl);
846 enum s390_overloaded_builtin_vars bindex;
848 int last_match_type = INT_MAX;
849 int last_match_index = -1;
850 unsigned int all_op_flags;
852 tree target_builtin_decl, b_arg_chain, return_type;
853 enum s390_builtin_ov_type_index last_match_fntype_index;
855 if (TARGET_DEBUG_ARG)
857 "s390_resolve_overloaded_builtin, code = %4d, %s - %s overloaded\n",
858 (int)ob_fcode, IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)),
859 ob_fcode < S390_BUILTIN_MAX ? "not" : "");
861 /* 0...S390_BUILTIN_MAX-1 is for non-overloaded builtins. */
862 if (ob_fcode < S390_BUILTIN_MAX)
864 if (bflags_for_builtin(ob_fcode) & B_INT)
867 "builtin %qF is for GCC internal use only.",
869 return error_mark_node;
874 ob_fcode -= S390_BUILTIN_MAX;
876 for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (ob_fndecl));
877 !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
878 b_arg_chain = TREE_CHAIN (b_arg_chain))
881 if (ob_args_num != in_args_num)
884 "mismatch in number of arguments for builtin %qF. "
885 "Expected: %d got %d", ob_fndecl,
886 ob_args_num, in_args_num);
887 return error_mark_node;
890 for (i = 0; i < in_args_num; i++)
891 if ((*arglist)[i] == error_mark_node)
892 return error_mark_node;
894 /* Overloaded builtins without any variants are directly expanded here. */
895 if (desc_start_for_overloaded_builtin[ob_fcode] ==
896 S390_OVERLOADED_BUILTIN_VAR_MAX)
897 return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, NULL_TREE);
899 for (bindex = desc_start_for_overloaded_builtin[ob_fcode];
900 bindex <= desc_end_for_overloaded_builtin[ob_fcode];
901 bindex = (enum s390_overloaded_builtin_vars)((int)bindex + 1))
904 enum s390_builtin_ov_type_index type_index =
905 type_for_overloaded_builtin_var[bindex];
907 if (TARGET_DEBUG_ARG)
908 fprintf (stderr, "checking variant number: %d", (int)bindex);
910 match_type = s390_fn_types_compatible (type_index, arglist);
912 if (match_type == INT_MAX)
915 if (TARGET_DEBUG_ARG)
917 " %s match score: %d\n", match_type == 0 ? "perfect" : "imperfect",
920 if (match_type < last_match_type)
923 last_match_type = match_type;
924 last_match_fntype_index = type_index;
925 last_match_index = bindex;
927 else if (match_type == last_match_type)
931 if (last_match_type == INT_MAX)
933 error_at (loc, "invalid parameter combination for intrinsic %qs",
934 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
935 return error_mark_node;
937 else if (num_matches > 1)
939 error_at (loc, "ambiguous overload for intrinsic %qs",
940 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
941 return error_mark_node;
944 if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
945 target_builtin_decl = ob_fndecl;
947 target_builtin_decl = s390_builtin_decls[bt_for_overloaded_builtin_var[last_match_index]];
949 all_op_flags = opflags_overloaded_builtin_var[last_match_index];
950 return_type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][0]];
952 /* Check for the operand flags in the overloaded builtin variant. */
953 for (i = 0; i < ob_args_num; i++)
955 unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
956 tree arg = (*arglist)[i];
957 tree type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][i + 1]];
959 all_op_flags = all_op_flags >> O_SHIFT;
961 if (op_flags == O_ELEM)
963 int n_elem = s390_vec_n_elem (target_builtin_decl);
964 gcc_assert (n_elem > 0);
965 gcc_assert (type == integer_type_node);
966 (*arglist)[i] = build2 (BIT_AND_EXPR, integer_type_node,
967 fold_convert (integer_type_node, arg),
968 build_int_cst (NULL_TREE, n_elem - 1));
971 if (TREE_CODE (arg) != INTEGER_CST || !O_IMM_P (op_flags))
974 if ((TYPE_UNSIGNED (type)
975 && !int_fits_type_p (arg, c_common_unsigned_type (type)))
976 || (!TYPE_UNSIGNED (type)
977 && !int_fits_type_p (arg, c_common_signed_type (type))))
979 error("constant argument %d for builtin %qF is out "
980 "of range for target type",
981 i + 1, target_builtin_decl);
982 return error_mark_node;
985 if (TREE_CODE (arg) == INTEGER_CST
986 && !s390_const_operand_ok (arg, i + 1, op_flags, target_builtin_decl))
987 return error_mark_node;
990 /* Handle builtins we expand directly - without mapping it to a low
992 if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
993 return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, return_type);
995 s390_adjust_builtin_arglist (ob_fcode, target_builtin_decl, &arglist);
997 if (VOID_TYPE_P (return_type))
998 return build_function_call_vec (loc, vNULL, target_builtin_decl,
1001 return fully_fold_convert (return_type,
1002 build_function_call_vec (loc, vNULL, target_builtin_decl,
1006 /* This is used to define the REGISTER_TARGET_PRAGMAS macro in s390.h. */
1008 s390_register_target_pragmas (void)
1010 targetm.resolve_overloaded_builtin = s390_resolve_overloaded_builtin;
1011 #if S390_USE_TARGET_ATTRIBUTE
1012 /* Update pragma hook to allow parsing #pragma GCC target. */
1013 targetm.target_option.pragma_parse = s390_pragma_target_parse;