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, OPFLAGS, 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_FLOAT
&& TARGET_VXE
)
263 || rid_code
== RID_DOUBLE
)
265 expand_this
= C_CPP_HASHNODE (__vector_keyword
);
266 /* If the next keyword is bool, it will need to be expanded as
269 tok
= cpp_peek_token (pfile
, idx
++);
270 while (tok
->type
== CPP_PADDING
);
271 ident
= s390_categorize_keyword (tok
);
273 /* __vector long __bool a; */
274 if (ident
== C_CPP_HASHNODE (__bool_keyword
))
275 expand_bool_p
= true;
278 /* Triggered with: __vector long long __bool a; */
280 tok
= cpp_peek_token (pfile
, idx
++);
281 while (tok
->type
== CPP_PADDING
);
282 ident
= s390_categorize_keyword (tok
);
284 if (ident
== C_CPP_HASHNODE (__bool_keyword
))
285 expand_bool_p
= true;
292 /* Helper function that defines or undefines macros. If SET is true, the macro
293 MACRO_DEF is defined. If SET is false, the macro MACRO_UNDEF is undefined.
294 Nothing is done if SET and WAS_SET have the same value. */
296 s390_def_or_undef_macro (cpp_reader
*pfile
,
298 const struct cl_target_option
*old_opts
,
299 const struct cl_target_option
*new_opts
,
300 const char *macro_def
, const char *macro_undef
)
305 was_set
= (!old_opts
) ? false : old_opts
->x_target_flags
& mask
;
306 set
= new_opts
->x_target_flags
& mask
;
310 cpp_define (pfile
, macro_def
);
312 cpp_undef (pfile
, macro_undef
);
315 /* Internal function to either define or undef the appropriate system
318 s390_cpu_cpp_builtins_internal (cpp_reader
*pfile
,
319 struct cl_target_option
*opts
,
320 const struct cl_target_option
*old_opts
)
322 s390_def_or_undef_macro (pfile
, MASK_OPT_HTM
, old_opts
, opts
,
323 "__HTM__", "__HTM__");
324 s390_def_or_undef_macro (pfile
, MASK_OPT_VX
, old_opts
, opts
,
326 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
327 "__VEC__=10302", "__VEC__");
328 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
329 "__vector=__attribute__((vector_size(16)))",
331 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
332 "__bool=__attribute__((s390_vector_bool)) unsigned",
337 gcc_assert (s390_arch
!= PROCESSOR_NATIVE
);
338 arch_level
= (int)s390_arch
+ 3;
339 if (s390_arch
>= PROCESSOR_2094_Z9_EC
)
340 /* Z9_EC has the same level as Z9_109. */
342 /* Review when a new arch is added and increase the value. */
343 char dummy
[(PROCESSOR_max
> 12) ? -1 : 1] __attribute__((unused
));
344 sprintf (macro_def
, "__ARCH__=%d", arch_level
);
345 cpp_undef (pfile
, "__ARCH__");
346 cpp_define (pfile
, macro_def
);
351 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
352 "__VECTOR_KEYWORD_SUPPORTED__",
353 "__VECTOR_KEYWORD_SUPPORTED__");
354 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
355 "vector=vector", "vector");
356 s390_def_or_undef_macro (pfile
, MASK_ZVECTOR
, old_opts
, opts
,
357 "bool=bool", "bool");
358 if (TARGET_ZVECTOR_P (opts
->x_target_flags
) && __vector_keyword
== NULL
)
360 __vector_keyword
= get_identifier ("__vector");
361 C_CPP_HASHNODE (__vector_keyword
)->flags
|= NODE_CONDITIONAL
;
363 vector_keyword
= get_identifier ("vector");
364 C_CPP_HASHNODE (vector_keyword
)->flags
|= NODE_CONDITIONAL
;
366 __bool_keyword
= get_identifier ("__bool");
367 C_CPP_HASHNODE (__bool_keyword
)->flags
|= NODE_CONDITIONAL
;
369 bool_keyword
= get_identifier ("bool");
370 C_CPP_HASHNODE (bool_keyword
)->flags
|= NODE_CONDITIONAL
;
372 _Bool_keyword
= get_identifier ("_Bool");
373 C_CPP_HASHNODE (_Bool_keyword
)->flags
|= NODE_CONDITIONAL
;
375 /* Enable context-sensitive macros. */
376 cpp_get_callbacks (pfile
)->macro_to_expand
= s390_macro_to_expand
;
381 /* Define platform dependent macros. */
383 s390_cpu_cpp_builtins (cpp_reader
*pfile
)
385 struct cl_target_option opts
;
387 cpp_assert (pfile
, "cpu=s390");
388 cpp_assert (pfile
, "machine=s390");
389 cpp_define (pfile
, "__s390__");
391 cpp_define (pfile
, "__zarch__");
393 cpp_define (pfile
, "__s390x__");
394 if (TARGET_LONG_DOUBLE_128
)
395 cpp_define (pfile
, "__LONG_DOUBLE_128__");
396 cl_target_option_save (&opts
, &global_options
);
397 s390_cpu_cpp_builtins_internal (pfile
, &opts
, NULL
);
400 #if S390_USE_TARGET_ATTRIBUTE
401 /* Hook to validate the current #pragma GCC target and set the state, and
402 update the macros based on what was changed. If ARGS is NULL, then
403 POP_TARGET is used to reset the options. */
406 s390_pragma_target_parse (tree args
, tree pop_target
)
408 tree prev_tree
= build_target_option_node (&global_options
);
412 cur_tree
= pop_target
;
415 cur_tree
= s390_valid_target_attribute_tree (args
, &global_options
,
416 &global_options_set
, true);
417 if (!cur_tree
|| cur_tree
== error_mark_node
)
419 cl_target_option_restore (&global_options
,
420 TREE_TARGET_OPTION (prev_tree
));
425 target_option_current_node
= cur_tree
;
426 s390_activate_target_options (target_option_current_node
);
429 struct cl_target_option
*prev_opt
;
430 struct cl_target_option
*cur_opt
;
432 /* Figure out the previous/current differences. */
433 prev_opt
= TREE_TARGET_OPTION (prev_tree
);
434 cur_opt
= TREE_TARGET_OPTION (cur_tree
);
436 /* For the definitions, ensure all newly defined macros are considered
437 as used for -Wunused-macros. There is no point warning about the
438 compiler predefined macros. */
439 cpp_options
*cpp_opts
= cpp_get_options (parse_in
);
440 unsigned char saved_warn_unused_macros
= cpp_opts
->warn_unused_macros
;
442 cpp_opts
->warn_unused_macros
= 0;
444 /* Define all of the macros for new options that were just turned on. */
445 s390_cpu_cpp_builtins_internal (parse_in
, cur_opt
, prev_opt
);
447 cpp_opts
->warn_unused_macros
= saved_warn_unused_macros
;
454 /* Expand builtins which can directly be mapped to tree expressions.
455 LOC - location information
456 FCODE - function code of the builtin
457 ARGLIST - value supposed to be passed as arguments
458 RETURN-TYPE - expected return type of the builtin */
460 s390_expand_overloaded_builtin (location_t loc
,
462 vec
<tree
, va_gc
> *arglist
,
467 case S390_OVERLOADED_BUILTIN_s390_vec_step
:
468 if (TREE_CODE (TREE_TYPE ((*arglist
)[0])) != VECTOR_TYPE
)
470 error_at (loc
, "builtin vec_step can only be used on vector types.");
471 return error_mark_node
;
473 return build_int_cst (NULL_TREE
,
474 TYPE_VECTOR_SUBPARTS (TREE_TYPE ((*arglist
)[0])));
475 case S390_OVERLOADED_BUILTIN_s390_vec_xl
:
476 case S390_OVERLOADED_BUILTIN_s390_vec_xld2
:
477 case S390_OVERLOADED_BUILTIN_s390_vec_xlw4
:
478 return build2 (MEM_REF
, return_type
,
479 fold_build_pointer_plus ((*arglist
)[1], (*arglist
)[0]),
480 build_int_cst (TREE_TYPE ((*arglist
)[1]), 0));
481 case S390_OVERLOADED_BUILTIN_s390_vec_xst
:
482 case S390_OVERLOADED_BUILTIN_s390_vec_xstd2
:
483 case S390_OVERLOADED_BUILTIN_s390_vec_xstw4
:
484 return build2 (MODIFY_EXPR
, TREE_TYPE((*arglist
)[0]),
485 build1 (INDIRECT_REF
, TREE_TYPE((*arglist
)[0]),
486 fold_build_pointer_plus ((*arglist
)[2], (*arglist
)[1])),
488 case S390_OVERLOADED_BUILTIN_s390_vec_load_pair
:
489 return build_constructor_va (return_type
, 2,
490 NULL_TREE
, (*arglist
)[0],
491 NULL_TREE
, (*arglist
)[1]);
498 #define __VSTRING_FLAG_IN 8
500 #define __VSTRING_FLAG_RT 4
502 #define __VSTRING_FLAG_ZS 2
503 /* set condition code */
504 #define __VSTRING_FLAG_CS 1
506 /* Return the flags value to be used for string low-level builtins
507 when expanded from overloaded builtin OB_FCODE. */
509 s390_get_vstring_flags (int ob_fcode
)
511 unsigned int flags
= 0;
515 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx
:
516 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx
:
517 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne
:
518 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc
:
519 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc
:
520 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc
:
521 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx
:
522 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx
:
523 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg
:
524 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc
:
525 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc
:
526 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc
:
527 flags
|= __VSTRING_FLAG_IN
;
535 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq
:
536 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne
:
537 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc
:
538 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc
:
539 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg
:
540 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg
:
541 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc
:
542 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc
:
543 flags
|= __VSTRING_FLAG_RT
;
551 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx
:
552 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx
:
553 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc
:
554 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc
:
555 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx
:
556 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx
:
557 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc
:
558 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc
:
559 flags
|= __VSTRING_FLAG_ZS
;
566 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc
:
567 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc
:
568 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc
:
569 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc
:
570 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc
:
571 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc
:
572 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc
:
573 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc
:
574 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc
:
575 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc
:
576 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc
:
577 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc
:
578 flags
|= __VSTRING_FLAG_CS
;
585 #undef __VSTRING_FLAG_IN
586 #undef __VSTRING_FLAG_RT
587 #undef __VSTRING_FLAG_ZS
588 #undef __VSTRING_FLAG_CS
590 /* For several overloaded builtins the argument lists do not match
591 exactly the signature of a low-level builtin. This function
592 adjusts the argument list ARGLIST for the overloaded builtin
593 OB_FCODE to the signature of the low-level builtin given by
596 s390_adjust_builtin_arglist (unsigned int ob_fcode
, tree decl
,
597 vec
<tree
, va_gc
> **arglist
)
600 int src_arg_index
, dest_arg_index
;
601 vec
<tree
, va_gc
> *folded_args
= NULL
;
603 /* We at most add one more operand to the list. */
604 vec_alloc (folded_args
, (*arglist
)->allocated () + 1);
605 for (arg_chain
= TYPE_ARG_TYPES (TREE_TYPE (decl
)),
606 src_arg_index
= 0, dest_arg_index
= 0;
607 !VOID_TYPE_P (TREE_VALUE (arg_chain
));
608 arg_chain
= TREE_CHAIN (arg_chain
), dest_arg_index
++)
610 bool arg_assigned_p
= false;
613 /* For all these the low level builtin needs an additional flags parameter. */
614 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx
:
615 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx
:
616 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx
:
617 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx
:
618 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq
:
619 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne
:
620 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc
:
621 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc
:
622 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc
:
623 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc
:
624 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc
:
625 case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc
:
626 if (dest_arg_index
== 2)
628 folded_args
->quick_push (build_int_cst (integer_type_node
,
629 s390_get_vstring_flags (ob_fcode
)));
630 arg_assigned_p
= true;
633 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx
:
634 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx
:
635 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx
:
636 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx
:
637 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg
:
638 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg
:
639 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc
:
640 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc
:
641 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc
:
642 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc
:
643 case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc
:
644 case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc
:
645 if (dest_arg_index
== 3)
647 folded_args
->quick_push (build_int_cst (integer_type_node
,
648 s390_get_vstring_flags (ob_fcode
)));
649 arg_assigned_p
= true;
652 case S390_OVERLOADED_BUILTIN_s390_vec_sel
:
653 case S390_OVERLOADED_BUILTIN_s390_vec_insert
:
654 case S390_OVERLOADED_BUILTIN_s390_vec_load_len
:
655 /* Swap the first to arguments. It is better to do it here
656 instead of the header file to avoid operand checking
657 throwing error messages for a weird operand index. */
658 if (dest_arg_index
< 2)
660 folded_args
->quick_push (fully_fold_convert (TREE_VALUE (arg_chain
),
661 (**arglist
)[1 - dest_arg_index
]));
663 arg_assigned_p
= true;
666 case S390_OVERLOADED_BUILTIN_s390_vec_store_len
:
667 if (dest_arg_index
== 1 || dest_arg_index
== 2)
669 folded_args
->quick_push (fully_fold_convert (TREE_VALUE (arg_chain
),
670 (**arglist
)[3 - dest_arg_index
]));
672 arg_assigned_p
= true;
676 case S390_OVERLOADED_BUILTIN_s390_vec_load_bndry
:
679 if (dest_arg_index
== 1)
681 tree arg
= (**arglist
)[src_arg_index
];
683 if (TREE_CODE (arg
) != INTEGER_CST
)
685 error ("constant value required for builtin %qF argument %d",
686 decl
, src_arg_index
+ 1);
690 switch (tree_to_uhwi (arg
))
692 case 64: code
= 0; break;
693 case 128: code
= 1; break;
694 case 256: code
= 2; break;
695 case 512: code
= 3; break;
696 case 1024: code
= 4; break;
697 case 2048: code
= 5; break;
698 case 4096: code
= 6; break;
700 error ("valid values for builtin %qF argument %d are 64, "
701 "128, 256, 512, 1024, 2048, and 4096", decl
,
705 folded_args
->quick_push (build_int_cst (integer_type_node
,
708 arg_assigned_p
= true;
712 case S390_OVERLOADED_BUILTIN_s390_vec_rl_mask
:
713 /* Duplicate the first src arg. */
714 if (dest_arg_index
== 0)
716 folded_args
->quick_push (fully_fold_convert (TREE_VALUE (arg_chain
),
717 (**arglist
)[src_arg_index
]));
718 arg_assigned_p
= true;
726 folded_args
->quick_push (fully_fold_convert (TREE_VALUE (arg_chain
),
727 (**arglist
)[src_arg_index
]));
731 *arglist
= folded_args
;
734 /* Check whether the arguments in ARGLIST match the function type
735 DEF_TYPE. Return the number of argument types which required
736 conversion/promotion in order to make it match.
737 0 stands for a perfect match - all operand types match without changes
738 INT_MAX stands for a mismatch. */
740 s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex
,
741 vec
<tree
, va_gc
> *arglist
)
746 for (i
= 0; i
< vec_safe_length (arglist
); i
++)
748 tree b_arg_type
= s390_builtin_types
[s390_builtin_ov_types
[typeindex
][i
+ 1]];
749 tree in_arg
= (*arglist
)[i
];
750 tree in_type
= TREE_TYPE (in_arg
);
752 if (TREE_CODE (b_arg_type
) == VECTOR_TYPE
)
754 /* Vector types have to match precisely. */
755 if (b_arg_type
!= in_type
756 && TYPE_MAIN_VARIANT (b_arg_type
) != TYPE_MAIN_VARIANT (in_type
))
760 if (lang_hooks
.types_compatible_p (in_type
, b_arg_type
))
763 if (lang_hooks
.types_compatible_p (
764 lang_hooks
.types
.type_promotes_to (in_type
),
765 lang_hooks
.types
.type_promotes_to (b_arg_type
)))
771 /* In this stage the C++ frontend would go ahead trying to find
772 implicit conversion chains for the argument to match the
773 target type. We will mimic this here only for our limited
774 subset of argument types. */
775 if (TREE_CODE (b_arg_type
) == INTEGER_TYPE
776 && TREE_CODE (in_type
) == INTEGER_TYPE
)
782 /* If the incoming pointer argument has more qualifiers than the
783 argument type it can still be an imperfect match. */
784 if (POINTER_TYPE_P (b_arg_type
) && POINTER_TYPE_P (in_type
)
785 && !(TYPE_QUALS (TREE_TYPE (in_type
))
786 & ~TYPE_QUALS (TREE_TYPE (b_arg_type
)))
787 && (TYPE_QUALS (TREE_TYPE (b_arg_type
))
788 & ~TYPE_QUALS (TREE_TYPE (in_type
))))
791 build_qualified_type (TREE_TYPE (in_type
),
792 TYPE_QUALS (TREE_TYPE (b_arg_type
)));
794 if (lang_hooks
.types_compatible_p (qual_in_type
,
795 TREE_TYPE (b_arg_type
)))
803 if (TARGET_DEBUG_ARG
)
804 fprintf (stderr
, " mismatch in operand: %d\n", i
+ 1);
811 /* Return the number of elements in the vector arguments of FNDECL in
812 case all it matches for all vector arguments, -1 otherwise. */
814 s390_vec_n_elem (tree fndecl
)
819 if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl
))) == VECTOR_TYPE
)
820 n_elem
= TYPE_VECTOR_SUBPARTS (TREE_TYPE (TREE_TYPE ((fndecl
))));
822 for (b_arg_chain
= TYPE_ARG_TYPES (TREE_TYPE (fndecl
));
823 !VOID_TYPE_P (TREE_VALUE (b_arg_chain
));
824 b_arg_chain
= TREE_CHAIN (b_arg_chain
))
827 if (TREE_CODE (TREE_VALUE (b_arg_chain
)) != VECTOR_TYPE
)
829 tmp_n_elem
= TYPE_VECTOR_SUBPARTS (TREE_VALUE (b_arg_chain
));
830 if (n_elem
!= -1 && n_elem
!= tmp_n_elem
)
838 /* Return a tree expression for a call to the overloaded builtin
839 function OB_FNDECL at LOC with arguments PASSED_ARGLIST. */
841 s390_resolve_overloaded_builtin (location_t loc
,
843 void *passed_arglist
)
845 vec
<tree
, va_gc
> *arglist
= static_cast<vec
<tree
, va_gc
> *> (passed_arglist
);
846 unsigned int in_args_num
= vec_safe_length (arglist
);
847 unsigned int ob_args_num
= 0;
848 unsigned int ob_fcode
= DECL_FUNCTION_CODE (ob_fndecl
);
849 enum s390_overloaded_builtin_vars bindex
;
851 int last_match_type
= INT_MAX
;
852 int last_match_index
= -1;
853 unsigned int all_op_flags
;
854 const unsigned int ob_flags
= bflags_for_builtin(ob_fcode
);
856 tree target_builtin_decl
, b_arg_chain
, return_type
;
857 enum s390_builtin_ov_type_index last_match_fntype_index
= BT_OV_MAX
;
859 if (TARGET_DEBUG_ARG
)
861 "s390_resolve_overloaded_builtin, code = %4d, %s - %s overloaded\n",
862 (int)ob_fcode
, IDENTIFIER_POINTER (DECL_NAME (ob_fndecl
)),
863 ob_fcode
< S390_BUILTIN_MAX
? "not" : "");
865 /* 0...S390_BUILTIN_MAX-1 is for non-overloaded builtins. */
866 if (ob_fcode
< S390_BUILTIN_MAX
)
868 if (ob_flags
& B_INT
)
871 "builtin %qF is for GCC internal use only.",
873 return error_mark_node
;
878 if (ob_flags
& B_DEP
)
879 warning_at (loc
, 0, "builtin %qF is deprecated.", ob_fndecl
);
881 if (!TARGET_VX
&& (ob_flags
& B_VX
))
883 error_at (loc
, "%qF requires -mvx", ob_fndecl
);
884 return error_mark_node
;
887 if (!TARGET_VXE
&& (ob_flags
& B_VXE
))
889 error_at (loc
, "%qF requires z14 or higher", ob_fndecl
);
890 return error_mark_node
;
893 ob_fcode
-= S390_BUILTIN_MAX
;
895 for (b_arg_chain
= TYPE_ARG_TYPES (TREE_TYPE (ob_fndecl
));
896 !VOID_TYPE_P (TREE_VALUE (b_arg_chain
));
897 b_arg_chain
= TREE_CHAIN (b_arg_chain
))
900 if (ob_args_num
!= in_args_num
)
903 "mismatch in number of arguments for builtin %qF. "
904 "Expected: %d got %d", ob_fndecl
,
905 ob_args_num
, in_args_num
);
906 return error_mark_node
;
909 for (i
= 0; i
< in_args_num
; i
++)
910 if ((*arglist
)[i
] == error_mark_node
)
911 return error_mark_node
;
913 /* Overloaded builtins without any variants are directly expanded here. */
914 if (desc_start_for_overloaded_builtin
[ob_fcode
] ==
915 S390_OVERLOADED_BUILTIN_VAR_MAX
)
916 return s390_expand_overloaded_builtin (loc
, ob_fcode
, arglist
, NULL_TREE
);
918 for (bindex
= desc_start_for_overloaded_builtin
[ob_fcode
];
919 bindex
<= desc_end_for_overloaded_builtin
[ob_fcode
];
920 bindex
= (enum s390_overloaded_builtin_vars
)((int)bindex
+ 1))
923 enum s390_builtin_ov_type_index type_index
=
924 type_for_overloaded_builtin_var
[bindex
];
926 if (TARGET_DEBUG_ARG
)
927 fprintf (stderr
, "checking variant number: %d", (int)bindex
);
929 match_type
= s390_fn_types_compatible (type_index
, arglist
);
931 if (match_type
== INT_MAX
)
934 if (TARGET_DEBUG_ARG
)
936 " %s match score: %d\n", match_type
== 0 ? "perfect" : "imperfect",
939 if (match_type
< last_match_type
)
942 last_match_type
= match_type
;
943 last_match_fntype_index
= type_index
;
944 last_match_index
= bindex
;
946 else if (match_type
== last_match_type
)
950 if (last_match_type
== INT_MAX
)
952 error_at (loc
, "invalid parameter combination for intrinsic %qs",
953 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl
)));
954 return error_mark_node
;
956 else if (num_matches
> 1)
958 error_at (loc
, "ambiguous overload for intrinsic %qs",
959 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl
)));
960 return error_mark_node
;
964 && bflags_overloaded_builtin_var
[last_match_index
] & B_VXE
)
966 error_at (loc
, "%qs matching variant requires z14 or higher",
967 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl
)));
968 return error_mark_node
;
971 if (bflags_overloaded_builtin_var
[last_match_index
] & B_DEP
)
972 warning_at (loc
, 0, "%qs matching variant is deprecated.",
973 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl
)));
975 /* Overloaded variants which have MAX set as low level builtin are
976 supposed to be replaced during expansion with something else. */
977 if (bt_for_overloaded_builtin_var
[last_match_index
] == S390_BUILTIN_MAX
)
978 target_builtin_decl
= ob_fndecl
;
980 target_builtin_decl
= s390_builtin_decls
[bt_for_overloaded_builtin_var
[last_match_index
]];
982 all_op_flags
= opflags_overloaded_builtin_var
[last_match_index
];
983 return_type
= s390_builtin_types
[s390_builtin_ov_types
[last_match_fntype_index
][0]];
985 /* Check for the operand flags in the overloaded builtin variant. */
986 for (i
= 0; i
< ob_args_num
; i
++)
988 unsigned int op_flags
= all_op_flags
& ((1 << O_SHIFT
) - 1);
989 tree arg
= (*arglist
)[i
];
990 tree type
= s390_builtin_types
[s390_builtin_ov_types
[last_match_fntype_index
][i
+ 1]];
992 all_op_flags
= all_op_flags
>> O_SHIFT
;
994 if (op_flags
== O_ELEM
)
996 int n_elem
= s390_vec_n_elem (target_builtin_decl
);
997 gcc_assert (n_elem
> 0);
998 gcc_assert (type
== integer_type_node
);
999 (*arglist
)[i
] = build2 (BIT_AND_EXPR
, integer_type_node
,
1000 fold_convert (integer_type_node
, arg
),
1001 build_int_cst (NULL_TREE
, n_elem
- 1));
1004 if (TREE_CODE (arg
) != INTEGER_CST
|| !O_IMM_P (op_flags
))
1007 if ((TYPE_UNSIGNED (type
)
1008 && !int_fits_type_p (arg
, c_common_unsigned_type (type
)))
1009 || (!TYPE_UNSIGNED (type
)
1010 && !int_fits_type_p (arg
, c_common_signed_type (type
))))
1012 error("constant argument %d for builtin %qF is out "
1013 "of range for target type",
1014 i
+ 1, target_builtin_decl
);
1015 return error_mark_node
;
1018 if (TREE_CODE (arg
) == INTEGER_CST
1019 && !s390_const_operand_ok (arg
, i
+ 1, op_flags
, target_builtin_decl
))
1020 return error_mark_node
;
1023 /* Handle builtins we expand directly - without mapping it to a low
1025 if (bt_for_overloaded_builtin_var
[last_match_index
] == S390_BUILTIN_MAX
)
1026 return s390_expand_overloaded_builtin (loc
, ob_fcode
, arglist
, return_type
);
1028 s390_adjust_builtin_arglist (ob_fcode
, target_builtin_decl
, &arglist
);
1030 if (VOID_TYPE_P (return_type
))
1031 return build_function_call_vec (loc
, vNULL
, target_builtin_decl
,
1034 return fully_fold_convert (return_type
,
1035 build_function_call_vec (loc
, vNULL
, target_builtin_decl
,
1039 /* This is used to define the REGISTER_TARGET_PRAGMAS macro in s390.h. */
1041 s390_register_target_pragmas (void)
1043 targetm
.resolve_overloaded_builtin
= s390_resolve_overloaded_builtin
;
1044 #if S390_USE_TARGET_ATTRIBUTE
1045 /* Update pragma hook to allow parsing #pragma GCC target. */
1046 targetm
.target_option
.pragma_parse
= s390_pragma_target_parse
;