0521e1eeb55ede4099f2c8d36299b3da8aeab447
[platform/upstream/gcc.git] / gcc / config / s390 / s390-c.c
1 /* Language specific subroutines used for code generation on IBM S/390
2    and zSeries
3    Copyright (C) 2015-2017 Free Software Foundation, Inc.
4
5    Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com).
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 by
11    the Free Software Foundation; either version 3, or (at your option)
12    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    Based on gcc/config/rs6000/rs6000-c.c.
24
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.  */
29
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 "memmodel.h"
38 #include "tm_p.h"
39 #include "stringpool.h"
40 #include "c-family/c-pragma.h"
41 #include "langhooks.h"
42 #include "tree-pretty-print.h"
43
44 #include "s390-builtins.h"
45
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;
51
52
53 /* Generate an array holding all the descriptions of variants of
54    overloaded builtins defined with OB_DEF_VAR in
55    s390-builtins.def.  */
56 static enum s390_builtin_ov_type_index
57 type_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
58   {
59 #undef B_DEF
60 #undef OB_DEF
61 #undef OB_DEF_VAR
62 #define B_DEF(...)
63 #define OB_DEF(...)
64 #define OB_DEF_VAR(NAME, PATTERN, FLAGS, FNTYPE) FNTYPE,
65 #include "s390-builtins.def"
66     BT_OV_MAX
67   };
68
69
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] =
75   {
76 #undef B_DEF
77 #undef OB_DEF
78 #undef OB_DEF_VAR
79 #define B_DEF(...)
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
85   };
86
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] =
92   {
93 #undef B_DEF
94 #undef OB_DEF
95 #undef OB_DEF_VAR
96 #define B_DEF(...)
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
102   };
103
104 static enum s390_builtin_type_index
105 s390_builtin_ov_types[BT_OV_MAX][MAX_OV_OPERANDS] =
106   {
107 #undef DEF_TYPE
108 #undef DEF_POINTER_TYPE
109 #undef DEF_DISTINCT_TYPE
110 #undef DEF_VECTOR_TYPE
111 #undef DEF_OPAQUE_VECTOR_TYPE
112 #undef DEF_FN_TYPE
113 #undef DEF_OV_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"
122   };
123
124 static const enum s390_builtins
125 bt_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX] = {
126 #undef B_DEF
127 #undef OB_DEF
128 #undef OB_DEF_VAR
129 #define B_DEF(...)
130 #define OB_DEF(...)
131 #define OB_DEF_VAR(NAME, BT, ...) S390_BUILTIN_##BT,
132
133 #include "s390-builtins.def"
134   };
135
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).  */
139 tree
140 fully_fold_convert (tree type, tree expr)
141 {
142   tree result = fold_convert (type, expr);
143   bool maybe_const = true;
144
145   if (!c_dialect_cxx ())
146     result = c_fully_fold (result, false, &maybe_const);
147
148   return result;
149 }
150
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)
155 {
156   if (tok->type == CPP_NAME)
157     {
158       cpp_hashnode *ident = tok->val.node.node;
159
160       if (ident == C_CPP_HASHNODE (vector_keyword))
161         return C_CPP_HASHNODE (__vector_keyword);
162
163       if (ident == C_CPP_HASHNODE (bool_keyword))
164         return C_CPP_HASHNODE (__bool_keyword);
165
166       if (ident == C_CPP_HASHNODE (_Bool_keyword))
167         return C_CPP_HASHNODE (__bool_keyword);
168       return ident;
169     }
170
171   return 0;
172 }
173
174
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.  */
178
179 static cpp_hashnode *
180 s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
181 {
182   cpp_hashnode *expand_this = tok->val.node.node;
183   cpp_hashnode *ident;
184   static bool expand_bool_p = false;
185   int idx = 0;
186   enum rid rid_code;
187
188   /* The vector keyword is only expanded if the machine actually
189      provides hardware support.  */
190   if (!TARGET_ZVECTOR)
191     return NULL;
192
193   ident = s390_categorize_keyword (tok);
194
195   /* Triggered when we picked a different variant in
196      s390_categorize_keyword.  */
197   if (ident != expand_this)
198     expand_this = NULL;
199
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))
203     {
204       expand_bool_p = false;
205       return ident;
206     }
207
208   if (ident != C_CPP_HASHNODE (__vector_keyword))
209     return expand_this;
210
211   do
212     tok = cpp_peek_token (pfile, idx++);
213   while (tok->type == CPP_PADDING);
214   ident = s390_categorize_keyword (tok);
215
216   if (!ident)
217     return expand_this;
218
219   /* vector bool - remember to expand the next bool. */
220   if (ident == C_CPP_HASHNODE (__bool_keyword))
221     {
222       expand_bool_p = true;
223       return C_CPP_HASHNODE (__vector_keyword);
224     }
225
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))
230     return expand_this;
231
232   rid_code = (enum rid)(ident->rid_code);
233
234   if (ident->type == NT_MACRO)
235     {
236       /* Now actually fetch the tokens we "peeked" before and do a
237          lookahead for the next.  */
238       do
239         (void) cpp_get_token (pfile);
240       while (--idx > 0);
241       do
242         tok = cpp_peek_token (pfile, idx++);
243       while (tok->type == CPP_PADDING);
244       ident = s390_categorize_keyword (tok);
245
246       if (ident == C_CPP_HASHNODE (__bool_keyword))
247         {
248           expand_bool_p = true;
249           return C_CPP_HASHNODE (__vector_keyword);
250         }
251       else if (ident)
252         rid_code = (enum rid)(ident->rid_code);
253     }
254
255   /* vector keyword followed by type identifier: vector unsigned,
256      vector long, ...
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)
263     {
264       expand_this = C_CPP_HASHNODE (__vector_keyword);
265       /* If the next keyword is bool, it will need to be expanded as
266          well.  */
267       do
268         tok = cpp_peek_token (pfile, idx++);
269       while (tok->type == CPP_PADDING);
270       ident = s390_categorize_keyword (tok);
271
272       /* __vector long __bool a; */
273       if (ident == C_CPP_HASHNODE (__bool_keyword))
274         expand_bool_p = true;
275       else
276         {
277           /* Triggered with: __vector long long __bool a; */
278           do
279             tok = cpp_peek_token (pfile, idx++);
280           while (tok->type == CPP_PADDING);
281           ident = s390_categorize_keyword (tok);
282
283           if (ident == C_CPP_HASHNODE (__bool_keyword))
284             expand_bool_p = true;
285         }
286     }
287
288   return expand_this;
289 }
290
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.  */
294 static void
295 s390_def_or_undef_macro (cpp_reader *pfile,
296                          unsigned int mask,
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)
300 {
301   bool was_set;
302   bool set;
303
304   was_set = (!old_opts) ? false : old_opts->x_target_flags & mask;
305   set = new_opts->x_target_flags & mask;
306   if (was_set == set)
307     return;
308   if (set)
309     cpp_define (pfile, macro_def);
310   else
311     cpp_undef (pfile, macro_undef);
312 }
313
314 /* Internal function to either define or undef the appropriate system
315    macros.  */
316 static void
317 s390_cpu_cpp_builtins_internal (cpp_reader *pfile,
318                                 struct cl_target_option *opts,
319                                 const struct cl_target_option *old_opts)
320 {
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,
324                            "__VX__", "__VX__");
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)))",
329                            "__vector__");
330   s390_def_or_undef_macro (pfile, MASK_ZVECTOR, old_opts, opts,
331                            "__bool=__attribute__((s390_vector_bool)) unsigned",
332                            "__bool");
333   {
334     char macro_def[64];
335     int arch_level;
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.  */
340       arch_level--;
341     /* Review when a new arch is added and increase the value.  */
342     char dummy[23 - 2 * PROCESSOR_max] __attribute__((unused));
343     sprintf (macro_def, "__ARCH__=%d", arch_level);
344     cpp_undef (pfile, "__ARCH__");
345     cpp_define (pfile, macro_def);
346   }
347
348   if (!flag_iso)
349     {
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)
358         {
359           __vector_keyword = get_identifier ("__vector");
360           C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;
361
362           vector_keyword = get_identifier ("vector");
363           C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;
364
365           __bool_keyword = get_identifier ("__bool");
366           C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;
367
368           bool_keyword = get_identifier ("bool");
369           C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
370
371           _Bool_keyword = get_identifier ("_Bool");
372           C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
373
374           /* Enable context-sensitive macros.  */
375           cpp_get_callbacks (pfile)->macro_to_expand = s390_macro_to_expand;
376         }
377     }
378 }
379
380 /* Define platform dependent macros.  */
381 void
382 s390_cpu_cpp_builtins (cpp_reader *pfile)
383 {
384   struct cl_target_option opts;
385
386   cpp_assert (pfile, "cpu=s390");
387   cpp_assert (pfile, "machine=s390");
388   cpp_define (pfile, "__s390__");
389   if (TARGET_ZARCH)
390     cpp_define (pfile, "__zarch__");
391   if (TARGET_64BIT)
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);
397 }
398
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.  */
403
404 static bool
405 s390_pragma_target_parse (tree args, tree pop_target)
406 {
407   tree prev_tree = build_target_option_node (&global_options);
408   tree cur_tree;
409
410   if (! args)
411     cur_tree = pop_target;
412   else
413     {
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)
417         {
418           cl_target_option_restore (&global_options,
419                                     TREE_TARGET_OPTION (prev_tree));
420           return false;
421         }
422     }
423
424   target_option_current_node = cur_tree;
425   s390_activate_target_options (target_option_current_node);
426
427   {
428     struct cl_target_option *prev_opt;
429     struct cl_target_option *cur_opt;
430
431     /* Figure out the previous/current differences.  */
432     prev_opt = TREE_TARGET_OPTION (prev_tree);
433     cur_opt = TREE_TARGET_OPTION (cur_tree);
434
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;
440
441     cpp_opts->warn_unused_macros = 0;
442
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);
445
446     cpp_opts->warn_unused_macros = saved_warn_unused_macros;
447   }
448
449   return true;
450 }
451 #endif
452
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 */
458 static tree
459 s390_expand_overloaded_builtin (location_t loc,
460                                 unsigned fcode,
461                                 vec<tree, va_gc> *arglist,
462                                 tree return_type)
463 {
464   switch (fcode)
465     {
466     case S390_OVERLOADED_BUILTIN_s390_vec_step:
467       if (TREE_CODE (TREE_TYPE ((*arglist)[0])) != VECTOR_TYPE)
468         {
469           error_at (loc, "builtin vec_step can only be used on vector types.");
470           return error_mark_node;
471         }
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])),
484                      (*arglist)[0]);
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]);
489     default:
490       gcc_unreachable ();
491     }
492 }
493
494 /* invert result */
495 #define __VSTRING_FLAG_IN         8
496 /* result type */
497 #define __VSTRING_FLAG_RT         4
498 /* zero search */
499 #define __VSTRING_FLAG_ZS         2
500 /* set condition code */
501 #define __VSTRING_FLAG_CS         1
502
503 /* Return the flags value to be used for string low-level builtins
504    when expanded from overloaded builtin OB_FCODE.  */
505 static unsigned int
506 s390_get_vstring_flags (int ob_fcode)
507 {
508   unsigned int flags = 0;
509
510   switch (ob_fcode)
511     {
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;
525       break;
526     default:
527       break;
528     }
529   switch (ob_fcode)
530     {
531
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;
541       break;
542     default:
543       break;
544     }
545   switch (ob_fcode)
546     {
547
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;
557       break;
558     default:
559       break;
560     }
561   switch (ob_fcode)
562     {
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;
576       break;
577     default:
578       break;
579     }
580   return flags;
581 }
582 #undef __VSTRING_FLAG_IN
583 #undef __VSTRING_FLAG_RT
584 #undef __VSTRING_FLAG_ZS
585 #undef __VSTRING_FLAG_CS
586
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
591    DECL.  */
592 static void
593 s390_adjust_builtin_arglist (unsigned int ob_fcode, tree decl,
594                              vec<tree, va_gc> **arglist)
595 {
596   tree arg_chain;
597   int src_arg_index, dest_arg_index;
598   vec<tree, va_gc> *folded_args = NULL;
599
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++)
606     {
607       bool arg_assigned_p = false;
608       switch (ob_fcode)
609         {
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)
624             {
625               folded_args->quick_push (build_int_cst (integer_type_node,
626                                        s390_get_vstring_flags (ob_fcode)));
627               arg_assigned_p = true;
628             }
629           break;
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)
643             {
644               folded_args->quick_push (build_int_cst (integer_type_node,
645                                        s390_get_vstring_flags (ob_fcode)));
646               arg_assigned_p = true;
647             }
648           break;
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)
656             {
657               folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
658                                          (**arglist)[1 - dest_arg_index]));
659               src_arg_index++;
660               arg_assigned_p = true;
661             }
662           break;
663         case S390_OVERLOADED_BUILTIN_s390_vec_store_len:
664           if (dest_arg_index == 1 || dest_arg_index == 2)
665             {
666               folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
667                                          (**arglist)[3 - dest_arg_index]));
668               src_arg_index++;
669               arg_assigned_p = true;
670             }
671           break;
672
673         case S390_OVERLOADED_BUILTIN_s390_vec_load_bndry:
674           {
675             int code;
676             if (dest_arg_index == 1)
677               {
678                 tree arg = (**arglist)[src_arg_index];
679
680                 if (TREE_CODE (arg) != INTEGER_CST)
681                   {
682                     error ("constant value required for builtin %qF argument %d",
683                            decl, src_arg_index + 1);
684                     return;
685                   }
686
687                 switch (tree_to_uhwi (arg))
688                   {
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;
696                   default:
697                     error ("valid values for builtin %qF argument %d are 64, "
698                            "128, 256, 512, 1024, 2048, and 4096", decl,
699                            src_arg_index + 1);
700                     return;
701                   }
702                 folded_args->quick_push (build_int_cst (integer_type_node,
703                                                         code));
704                 src_arg_index++;
705                 arg_assigned_p = true;
706               }
707           }
708           break;
709         case S390_OVERLOADED_BUILTIN_s390_vec_rl_mask:
710           /* Duplicate the first src arg.  */
711           if (dest_arg_index == 0)
712             {
713               folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
714                                            (**arglist)[src_arg_index]));
715               arg_assigned_p = true;
716             }
717           break;
718         default:
719           break;
720         }
721       if (!arg_assigned_p)
722         {
723           folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
724                                                  (**arglist)[src_arg_index]));
725           src_arg_index++;
726         }
727     }
728   *arglist = folded_args;
729 }
730
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.  */
736 static int
737 s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex,
738                           vec<tree, va_gc> *arglist)
739 {
740   unsigned int i;
741   int match_type = 0;
742
743   for (i = 0; i < vec_safe_length (arglist); i++)
744     {
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);
748
749       if (TREE_CODE (b_arg_type) == VECTOR_TYPE)
750         {
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))
754             goto mismatch;
755         }
756
757       if (lang_hooks.types_compatible_p (in_type, b_arg_type))
758         continue;
759
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)))
763         {
764           match_type++;
765           continue;
766         }
767
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)
774         {
775           match_type++;
776           continue;
777         }
778
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))))
786         {
787           tree qual_in_type =
788             build_qualified_type (TREE_TYPE (in_type),
789                                   TYPE_QUALS (TREE_TYPE (b_arg_type)));
790
791           if (lang_hooks.types_compatible_p (qual_in_type,
792                                              TREE_TYPE (b_arg_type)))
793             {
794               match_type++;
795               continue;
796             }
797         }
798
799     mismatch:
800       if (TARGET_DEBUG_ARG)
801         fprintf (stderr, " mismatch in operand: %d\n", i + 1);
802       return INT_MAX;
803     }
804
805   return match_type;
806 }
807
808 /* Return the number of elements in the vector arguments of FNDECL in
809    case all it matches for all vector arguments, -1 otherwise.  */
810 static int
811 s390_vec_n_elem (tree fndecl)
812 {
813   tree b_arg_chain;
814   int n_elem = -1;
815
816   if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) == VECTOR_TYPE)
817     n_elem = TYPE_VECTOR_SUBPARTS (TREE_TYPE (TREE_TYPE ((fndecl))));
818
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))
822     {
823       int tmp_n_elem;
824       if (TREE_CODE (TREE_VALUE (b_arg_chain)) != VECTOR_TYPE)
825         continue;
826       tmp_n_elem = TYPE_VECTOR_SUBPARTS (TREE_VALUE (b_arg_chain));
827       if (n_elem != -1 && n_elem != tmp_n_elem)
828         return -1;
829       n_elem = tmp_n_elem;
830     }
831   return n_elem;
832 }
833
834
835 /* Return a tree expression for a call to the overloaded builtin
836    function OB_FNDECL at LOC with arguments PASSED_ARGLIST.  */
837 tree
838 s390_resolve_overloaded_builtin (location_t loc,
839                                  tree ob_fndecl,
840                                  void *passed_arglist)
841 {
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;
847   unsigned int i;
848   int last_match_type = INT_MAX;
849   int last_match_index = -1;
850   unsigned int all_op_flags;
851   int num_matches = 0;
852   tree target_builtin_decl, b_arg_chain, return_type;
853   enum s390_builtin_ov_type_index last_match_fntype_index;
854
855   if (TARGET_DEBUG_ARG)
856     fprintf (stderr,
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" : "");
860
861   /* 0...S390_BUILTIN_MAX-1 is for non-overloaded builtins.  */
862   if (ob_fcode < S390_BUILTIN_MAX)
863     {
864       if (bflags_for_builtin(ob_fcode) & B_INT)
865         {
866           error_at (loc,
867                     "builtin %qF is for GCC internal use only.",
868                     ob_fndecl);
869           return error_mark_node;
870         }
871       return NULL_TREE;
872     }
873
874   ob_fcode -= S390_BUILTIN_MAX;
875
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))
879     ob_args_num++;
880
881   if (ob_args_num != in_args_num)
882     {
883       error_at (loc,
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;
888     }
889
890   for (i = 0; i < in_args_num; i++)
891     if ((*arglist)[i] == error_mark_node)
892       return error_mark_node;
893
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);
898
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))
902   {
903     int match_type;
904     enum s390_builtin_ov_type_index type_index =
905       type_for_overloaded_builtin_var[bindex];
906
907     if (TARGET_DEBUG_ARG)
908       fprintf (stderr, "checking variant number: %d", (int)bindex);
909
910     match_type = s390_fn_types_compatible (type_index, arglist);
911
912     if (match_type == INT_MAX)
913       continue;
914
915     if (TARGET_DEBUG_ARG)
916       fprintf (stderr,
917                " %s match score: %d\n", match_type == 0 ? "perfect" : "imperfect",
918                match_type);
919
920     if (match_type < last_match_type)
921       {
922         num_matches = 1;
923         last_match_type = match_type;
924         last_match_fntype_index = type_index;
925         last_match_index = bindex;
926       }
927     else if (match_type == last_match_type)
928       num_matches++;
929   }
930
931   if (last_match_type == INT_MAX)
932     {
933       error_at (loc, "invalid parameter combination for intrinsic %qs",
934                 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
935       return error_mark_node;
936     }
937   else if (num_matches > 1)
938     {
939       error_at (loc, "ambiguous overload for intrinsic %qs",
940                 IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
941       return error_mark_node;
942     }
943
944   if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
945     target_builtin_decl = ob_fndecl;
946   else
947     target_builtin_decl = s390_builtin_decls[bt_for_overloaded_builtin_var[last_match_index]];
948
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]];
951
952   /* Check for the operand flags in the overloaded builtin variant.  */
953   for (i = 0; i < ob_args_num; i++)
954     {
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]];
958
959       all_op_flags = all_op_flags >> O_SHIFT;
960
961       if (op_flags == O_ELEM)
962         {
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));
969         }
970
971       if (TREE_CODE (arg) != INTEGER_CST || !O_IMM_P (op_flags))
972         continue;
973
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))))
978         {
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;
983         }
984
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;
988     }
989
990   /* Handle builtins we expand directly - without mapping it to a low
991      level builtin.  */
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);
994
995   s390_adjust_builtin_arglist (ob_fcode, target_builtin_decl, &arglist);
996
997   if (VOID_TYPE_P (return_type))
998     return build_function_call_vec (loc, vNULL, target_builtin_decl,
999                                     arglist, NULL);
1000   else
1001     return fully_fold_convert (return_type,
1002                                build_function_call_vec (loc, vNULL, target_builtin_decl,
1003                                                         arglist, NULL));
1004 }
1005
1006 /* This is used to define the REGISTER_TARGET_PRAGMAS macro in s390.h.  */
1007 void
1008 s390_register_target_pragmas (void)
1009 {
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;
1014 #endif
1015 }