/* Language specific subroutines used for code generation on IBM S/390
   and zSeries
   Copyright (C) 2015-2022 Free Software Foundation, Inc.

   Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com).

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.

   Based on gcc/config/rs6000/rs6000-c.cc.

   In GCC terms this file belongs to the frontend.  It will be
   compiled with -DIN_GCC_FRONTEND.  With that rtl.h cannot be
   included anymore - a mechanism supposed to avoid adding frontend -
   backend dependencies.  */

#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tree.h"
#include "c-family/c-common.h"
#include "c/c-tree.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "c-family/c-pragma.h"
#include "langhooks.h"
#include "tree-pretty-print.h"

#include "s390-builtins.h"

static GTY(()) tree __vector_keyword;
static GTY(()) tree vector_keyword;
static GTY(()) tree __bool_keyword;
static GTY(()) tree bool_keyword;
static GTY(()) tree _Bool_keyword;


/* Generate an array holding all the descriptions of variants of
   overloaded builtins defined with OB_DEF_VAR in
   s390-builtins.def.  */
static enum s390_builtin_ov_type_index
type_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX + 1] =
  {
#undef B_DEF
#undef OB_DEF
#undef OB_DEF_VAR
#define B_DEF(...)
#define OB_DEF(...)
#define OB_DEF_VAR(NAME, PATTERN, FLAGS, OPFLAGS, FNTYPE) FNTYPE,
#include "s390-builtins.def"
    BT_OV_MAX
  };


/* Generate an array indexed by an overloaded builtin index returning
   the first index in desc_for_overloaded_builtin_var where the
   variants for the builtin can be found.  */
static enum s390_overloaded_builtin_vars
desc_start_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
  {
#undef B_DEF
#undef OB_DEF
#undef OB_DEF_VAR
#define B_DEF(...)
#define OB_DEF(NAME, FIRST_VAR_NAME,...)	\
    S390_OVERLOADED_BUILTIN_VAR_##FIRST_VAR_NAME,
#define OB_DEF_VAR(...)
    #include "s390-builtins.def"
    S390_OVERLOADED_BUILTIN_VAR_MAX
  };

/* Generate an array indexed by an overloaded builtin index returning
   the last index in desc_for_overloaded_builtin_var where the
   variants for the builtin can be found.  */
static enum s390_overloaded_builtin_vars
desc_end_for_overloaded_builtin[S390_OVERLOADED_BUILTIN_MAX + 1] =
  {
#undef B_DEF
#undef OB_DEF
#undef OB_DEF_VAR
#define B_DEF(...)
#define OB_DEF(NAME, FIRST_VAR_NAME, LAST_VAR_NAME,...)	\
    S390_OVERLOADED_BUILTIN_VAR_##LAST_VAR_NAME,
#define OB_DEF_VAR(...)
    #include "s390-builtins.def"
    S390_OVERLOADED_BUILTIN_VAR_MAX
  };

static enum s390_builtin_type_index
s390_builtin_ov_types[BT_OV_MAX][MAX_OV_OPERANDS] =
  {
#undef DEF_TYPE
#undef DEF_POINTER_TYPE
#undef DEF_DISTINCT_TYPE
#undef DEF_VECTOR_TYPE
#undef DEF_OPAQUE_VECTOR_TYPE
#undef DEF_FN_TYPE
#undef DEF_OV_TYPE
#define DEF_TYPE(...)
#define DEF_POINTER_TYPE(...)
#define DEF_DISTINCT_TYPE(...)
#define DEF_VECTOR_TYPE(...)
#define DEF_OPAQUE_VECTOR_TYPE(...)
#define DEF_FN_TYPE(...)
#define DEF_OV_TYPE(INDEX, args...) { args },
#include "s390-builtin-types.def"
  };

static const enum s390_builtins
bt_for_overloaded_builtin_var[S390_OVERLOADED_BUILTIN_VAR_MAX] = {
#undef B_DEF
#undef OB_DEF
#undef OB_DEF_VAR
#define B_DEF(...)
#define OB_DEF(...)
#define OB_DEF_VAR(NAME, BT, ...) S390_BUILTIN_##BT,

#include "s390-builtins.def"
  };

/* In addition to calling fold_convert for EXPR of type TYPE, also
   call c_fully_fold to remove any C_MAYBE_CONST_EXPRs that could be
   hiding there (PR47197).  */
tree
fully_fold_convert (tree type, tree expr)
{
  tree result = fold_convert (type, expr);
  bool maybe_const = true;

  if (!c_dialect_cxx ())
    result = c_fully_fold (result, false, &maybe_const);

  return result;
}

/* Unify the different variants to the same nodes in order to keep the
   code working with it simple.  */
static cpp_hashnode *
s390_categorize_keyword (const cpp_token *tok)
{
  if (tok->type == CPP_NAME)
    {
      cpp_hashnode *ident = tok->val.node.node;

      if (ident == C_CPP_HASHNODE (vector_keyword))
	return C_CPP_HASHNODE (__vector_keyword);

      if (ident == C_CPP_HASHNODE (bool_keyword))
	return C_CPP_HASHNODE (__bool_keyword);

      if (ident == C_CPP_HASHNODE (_Bool_keyword))
	return C_CPP_HASHNODE (__bool_keyword);
      return ident;
    }

  return 0;
}


/* Called to decide whether a conditional macro should be expanded.
   Since we have exactly one such macro (i.e, 'vector'), we do not
   need to examine the 'tok' parameter.  */

static cpp_hashnode *
s390_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
{
  cpp_hashnode *expand_this = tok->val.node.node;
  cpp_hashnode *ident;
  static bool expand_bool_p = false;
  int idx = 0;
  enum rid rid_code;

  /* The vector keyword is only expanded if the machine actually
     provides hardware support.  */
  if (!TARGET_ZVECTOR)
    return NULL;

  ident = s390_categorize_keyword (tok);

  /* Triggered when we picked a different variant in
     s390_categorize_keyword.  */
  if (ident != expand_this)
    expand_this = NULL;

  /* The vector keyword has been found already and we remembered to
     expand the next bool.  */
  if (expand_bool_p && ident == C_CPP_HASHNODE (__bool_keyword))
    {
      expand_bool_p = false;
      return ident;
    }

  if (ident != C_CPP_HASHNODE (__vector_keyword))
    return expand_this;

  do
    tok = cpp_peek_token (pfile, idx++);
  while (tok->type == CPP_PADDING);
  ident = s390_categorize_keyword (tok);

  if (!ident)
    return expand_this;

  /* vector bool - remember to expand the next bool. */
  if (ident == C_CPP_HASHNODE (__bool_keyword))
    {
      expand_bool_p = true;
      return C_CPP_HASHNODE (__vector_keyword);
    }

  /* The boost libraries have code with Iterator::vector vector in it.
     If we allow the normal handling, this module will be called
     recursively, and the vector will be skipped.; */
  if (ident == C_CPP_HASHNODE (__vector_keyword))
    return expand_this;

  rid_code = (enum rid)(ident->rid_code);

  if (cpp_macro_p (ident))
    {
      /* Now actually fetch the tokens we "peeked" before and do a
	 lookahead for the next.  */
      do
	(void) cpp_get_token (pfile);
      while (--idx > 0);
      do
	tok = cpp_peek_token (pfile, idx++);
      while (tok->type == CPP_PADDING);
      ident = s390_categorize_keyword (tok);

      if (ident == C_CPP_HASHNODE (__bool_keyword))
	{
	  expand_bool_p = true;
	  return C_CPP_HASHNODE (__vector_keyword);
	}
      else if (ident)
	rid_code = (enum rid)(ident->rid_code);
    }

  /* vector keyword followed by type identifier: vector unsigned,
     vector long, ...
     Types consisting of more than one identifier are not supported by
     zvector e.g. long long, long double, unsigned long int.  */
  if (rid_code == RID_UNSIGNED || rid_code == RID_LONG
      || rid_code == RID_SHORT || rid_code == RID_SIGNED
      || rid_code == RID_INT || rid_code == RID_CHAR
      || (rid_code == RID_FLOAT && TARGET_VXE)
      || rid_code == RID_DOUBLE)
    {
      expand_this = C_CPP_HASHNODE (__vector_keyword);
      /* If the next keyword is bool, it will need to be expanded as
	 well.  */
      do
	tok = cpp_peek_token (pfile, idx++);
      while (tok->type == CPP_PADDING);
      ident = s390_categorize_keyword (tok);

      /* __vector long __bool a; */
      if (ident == C_CPP_HASHNODE (__bool_keyword))
	expand_bool_p = true;
      else
	{
	  /* Triggered with: __vector long long __bool a; */
	  do
	    tok = cpp_peek_token (pfile, idx++);
	  while (tok->type == CPP_PADDING);
	  ident = s390_categorize_keyword (tok);

	  if (ident == C_CPP_HASHNODE (__bool_keyword))
	    expand_bool_p = true;
	}
    }

  return expand_this;
}

/* Helper function that defines or undefines macros.  If SET is true, the macro
   MACRO_DEF is defined.  If SET is false, the macro MACRO_UNDEF is undefined.
   Nothing is done if SET and WAS_SET have the same value.  */
template <typename F>
static void
s390_def_or_undef_macro (cpp_reader *pfile, F is_set,
			 const struct cl_target_option *old_opts,
			 const struct cl_target_option *new_opts,
			 const char *macro_def, const char *macro_undef)
{
  bool was_set;
  bool set;

  was_set = (!old_opts) ? false : is_set (old_opts);
  set = is_set (new_opts);
  if (was_set == set)
    return;
  if (set)
    cpp_define (pfile, macro_def);
  else
    cpp_undef (pfile, macro_undef);
}

struct target_flag_set_p
{
  target_flag_set_p (unsigned int mask) : m_mask (mask) {}

  bool
  operator() (const struct cl_target_option *opts) const
  {
    return opts->x_target_flags & m_mask;
  }

  unsigned int m_mask;
};

/* Internal function to either define or undef the appropriate system
   macros.  */
static void
s390_cpu_cpp_builtins_internal (cpp_reader *pfile,
				struct cl_target_option *opts,
				const struct cl_target_option *old_opts)
{
  s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_OPT_HTM), old_opts,
			   opts, "__HTM__", "__HTM__");
  s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_OPT_VX), old_opts,
			   opts, "__VX__", "__VX__");
  s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR), old_opts,
			   opts, "__VEC__=10304", "__VEC__");
  s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR), old_opts,
			   opts, "__vector=__attribute__((vector_size(16)))",
			   "__vector__");
  s390_def_or_undef_macro (
      pfile, target_flag_set_p (MASK_ZVECTOR), old_opts, opts,
      "__bool=__attribute__((s390_vector_bool)) unsigned", "__bool");
  {
    char macro_def[64];
    gcc_assert (s390_arch != PROCESSOR_NATIVE);
    sprintf (macro_def, "__ARCH__=%d", processor_table[s390_arch].arch_level);
    cpp_undef (pfile, "__ARCH__");
    cpp_define (pfile, macro_def);
  }
  s390_def_or_undef_macro (
      pfile,
      [] (const struct cl_target_option *opts) { return TARGET_VXE_P (opts); },
      old_opts, opts, "__LONG_DOUBLE_VX__", "__LONG_DOUBLE_VX__");

  if (!flag_iso)
    {
      s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR),
			       old_opts, opts, "__VECTOR_KEYWORD_SUPPORTED__",
			       "__VECTOR_KEYWORD_SUPPORTED__");
      s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR),
			       old_opts, opts, "vector=vector", "vector");
      s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR),
			       old_opts, opts, "bool=bool", "bool");
      s390_def_or_undef_macro (pfile, target_flag_set_p (MASK_ZVECTOR),
			       old_opts, opts, "_Bool=_Bool", "_Bool");
      if (TARGET_ZVECTOR_P (opts->x_target_flags) && __vector_keyword == NULL)
	{
	  __vector_keyword = get_identifier ("__vector");
	  C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;

	  vector_keyword = get_identifier ("vector");
	  C_CPP_HASHNODE (vector_keyword)->flags |= NODE_CONDITIONAL;

	  __bool_keyword = get_identifier ("__bool");
	  C_CPP_HASHNODE (__bool_keyword)->flags |= NODE_CONDITIONAL;

	  bool_keyword = get_identifier ("bool");
	  C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;

	  _Bool_keyword = get_identifier ("_Bool");
	  C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;

	  /* Enable context-sensitive macros.  */
	  cpp_get_callbacks (pfile)->macro_to_expand = s390_macro_to_expand;
	}
    }
}

/* Define platform dependent macros.  */
void
s390_cpu_cpp_builtins (cpp_reader *pfile)
{
  struct cl_target_option opts;

  cpp_assert (pfile, "cpu=s390");
  cpp_assert (pfile, "machine=s390");
  cpp_define (pfile, "__s390__");
  if (TARGET_ZARCH)
    cpp_define (pfile, "__zarch__");
  if (TARGET_64BIT)
    cpp_define (pfile, "__s390x__");
  if (TARGET_LONG_DOUBLE_128)
    cpp_define (pfile, "__LONG_DOUBLE_128__");
  cl_target_option_save (&opts, &global_options, &global_options_set);
  s390_cpu_cpp_builtins_internal (pfile, &opts, NULL);
}

#if S390_USE_TARGET_ATTRIBUTE
/* Hook to validate the current #pragma GCC target and set the state, and
   update the macros based on what was changed.  If ARGS is NULL, then
   POP_TARGET is used to reset the options.  */

static bool
s390_pragma_target_parse (tree args, tree pop_target)
{
  tree prev_tree = build_target_option_node (&global_options,
					     &global_options_set);
  tree cur_tree;

  if (! args)
    cur_tree = pop_target;
  else
    {
      cur_tree = s390_valid_target_attribute_tree (args, &global_options,
						   &global_options_set, true);
      if (!cur_tree || cur_tree == error_mark_node)
	{
	  cl_target_option_restore (&global_options, &global_options_set,
				    TREE_TARGET_OPTION (prev_tree));
	  return false;
	}
    }

  target_option_current_node = cur_tree;
  s390_activate_target_options (target_option_current_node);

  {
    struct cl_target_option *prev_opt;
    struct cl_target_option *cur_opt;

    /* Figure out the previous/current differences.  */
    prev_opt = TREE_TARGET_OPTION (prev_tree);
    cur_opt = TREE_TARGET_OPTION (cur_tree);

    /* For the definitions, ensure all newly defined macros are considered
       as used for -Wunused-macros.  There is no point warning about the
       compiler predefined macros.  */
    cpp_options *cpp_opts = cpp_get_options (parse_in);
    unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;

    cpp_opts->warn_unused_macros = 0;

    /* Define all of the macros for new options that were just turned on.  */
    cpp_force_token_locations (parse_in, BUILTINS_LOCATION);
    s390_cpu_cpp_builtins_internal (parse_in, cur_opt, prev_opt);
    cpp_stop_forcing_token_locations (parse_in);

    cpp_opts->warn_unused_macros = saved_warn_unused_macros;
  }

  return true;
}
#endif

/* Expand builtins which can directly be mapped to tree expressions.
   LOC - location information
   FCODE - function code of the builtin
   ARGLIST - value supposed to be passed as arguments
   RETURN-TYPE - expected return type of the builtin */
static tree
s390_expand_overloaded_builtin (location_t loc,
				unsigned fcode,
				vec<tree, va_gc> *arglist,
				tree return_type)
{
  switch (fcode)
    {
    case S390_OVERLOADED_BUILTIN_s390_vec_step:
      if (TREE_CODE (TREE_TYPE ((*arglist)[0])) != VECTOR_TYPE)
	{
	  error_at (loc, "builtin %qs can only be used on vector types",
		    "vec_step");
	  return error_mark_node;
	}
      return build_int_cst (NULL_TREE,
			    TYPE_VECTOR_SUBPARTS (TREE_TYPE ((*arglist)[0])));
    case S390_OVERLOADED_BUILTIN_s390_vec_xl:
    case S390_OVERLOADED_BUILTIN_s390_vec_xld2:
    case S390_OVERLOADED_BUILTIN_s390_vec_xlw4:
      {
	/* Build a vector type with the alignment of the source
	   location in order to enable correct alignment hints to be
	   generated for vl.  */
	tree mem_type = build_aligned_type (return_type,
					    TYPE_ALIGN (TREE_TYPE (TREE_TYPE ((*arglist)[1]))));
	return build2 (MEM_REF, mem_type,
		       fold_build_pointer_plus ((*arglist)[1], (*arglist)[0]),
		       build_int_cst (TREE_TYPE ((*arglist)[1]), 0));
      }
    case S390_OVERLOADED_BUILTIN_s390_vec_xst:
    case S390_OVERLOADED_BUILTIN_s390_vec_xstd2:
    case S390_OVERLOADED_BUILTIN_s390_vec_xstw4:
      {
	/* Build a vector type with the alignment of the target
	   location in order to enable correct alignment hints to be
	   generated for vst.  */
	tree mem_type = build_aligned_type (TREE_TYPE((*arglist)[0]),
					    TYPE_ALIGN (TREE_TYPE (TREE_TYPE ((*arglist)[2]))));
	return build2 (MODIFY_EXPR, mem_type,
		       build1 (INDIRECT_REF, mem_type,
			       fold_build_pointer_plus ((*arglist)[2], (*arglist)[1])),
		       (*arglist)[0]);
      }
    case S390_OVERLOADED_BUILTIN_s390_vec_load_pair:
      return build_constructor_va (return_type, 2,
				   NULL_TREE, (*arglist)[0],
				   NULL_TREE, (*arglist)[1]);
    default:
      gcc_unreachable ();
    }
}

/* invert result */
#define __VSTRING_FLAG_IN         8
/* result type */
#define __VSTRING_FLAG_RT         4
/* zero search */
#define __VSTRING_FLAG_ZS         2
/* set condition code */
#define __VSTRING_FLAG_CS         1

/* Return the flags value to be used for string low-level builtins
   when expanded from overloaded builtin OB_FCODE.  */
static unsigned int
s390_get_vstring_flags (int ob_fcode)
{
  unsigned int flags = 0;

  switch (ob_fcode)
    {
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
      flags |= __VSTRING_FLAG_IN;
      break;
    default:
      break;
    }
  switch (ob_fcode)
    {

    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
      flags |= __VSTRING_FLAG_RT;
      break;
    default:
      break;
    }
  switch (ob_fcode)
    {

    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
      flags |= __VSTRING_FLAG_ZS;
      break;
    default:
      break;
    }
  switch (ob_fcode)
    {
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
    case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
      flags |= __VSTRING_FLAG_CS;
      break;
    default:
      break;
    }
  return flags;
}
#undef __VSTRING_FLAG_IN
#undef __VSTRING_FLAG_RT
#undef __VSTRING_FLAG_ZS
#undef __VSTRING_FLAG_CS

/* For several overloaded builtins the argument lists do not match
   exactly the signature of a low-level builtin.  This function
   adjusts the argument list ARGLIST for the overloaded builtin
   OB_FCODE to the signature of the low-level builtin given by
   DECL.  */
static void
s390_adjust_builtin_arglist (unsigned int ob_fcode, tree decl,
			     vec<tree, va_gc> **arglist)
{
  tree arg_chain;
  int src_arg_index, dest_arg_index;
  vec<tree, va_gc> *folded_args = NULL;

  /* We at most add one more operand to the list.  */
  vec_alloc (folded_args, (*arglist)->allocated () + 1);
  for (arg_chain = TYPE_ARG_TYPES (TREE_TYPE (decl)),
	 src_arg_index = 0, dest_arg_index = 0;
       !VOID_TYPE_P (TREE_VALUE (arg_chain));
       arg_chain = TREE_CHAIN (arg_chain), dest_arg_index++)
    {
      bool arg_assigned_p = false;
      switch (ob_fcode)
	{
	  /* For all these the low level builtin needs an additional flags parameter.  */
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_or_0_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_or_0_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_eq_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_find_any_ne_cc:
	  if (dest_arg_index == 2)
	    {
	      folded_args->quick_push (build_int_cst (integer_type_node,
				       s390_get_vstring_flags (ob_fcode)));
	      arg_assigned_p = true;
	    }
	  break;
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_or_0_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_or_0_idx_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmprg_cc:
	case S390_OVERLOADED_BUILTIN_s390_vec_cmpnrg_cc:
	  if (dest_arg_index == 3)
	    {
	      folded_args->quick_push (build_int_cst (integer_type_node,
				       s390_get_vstring_flags (ob_fcode)));
	      arg_assigned_p = true;
	    }
	  break;
	case S390_OVERLOADED_BUILTIN_s390_vec_sel:
	case S390_OVERLOADED_BUILTIN_s390_vec_insert:
	case S390_OVERLOADED_BUILTIN_s390_vec_load_len:
	  /* Swap the first to arguments. It is better to do it here
	     instead of the header file to avoid operand checking
	     throwing error messages for a weird operand index.  */
	  if (dest_arg_index < 2)
	    {
	      folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
					 (**arglist)[1 - dest_arg_index]));
	      src_arg_index++;
	      arg_assigned_p = true;
	    }
	  break;
	case S390_OVERLOADED_BUILTIN_s390_vec_store_len:
	  if (dest_arg_index == 1 || dest_arg_index == 2)
	    {
	      folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
					 (**arglist)[3 - dest_arg_index]));
	      src_arg_index++;
	      arg_assigned_p = true;
	    }
	  break;

	case S390_OVERLOADED_BUILTIN_s390_vec_load_bndry:
	  {
	    int code;
	    if (dest_arg_index == 1)
	      {
		tree arg = (**arglist)[src_arg_index];

		if (TREE_CODE (arg) != INTEGER_CST)
		  {
		    error ("constant value required for builtin %qF argument %d",
			   decl, src_arg_index + 1);
		    return;
		  }

		switch (tree_to_uhwi (arg))
		  {
		  case 64: code = 0; break;
		  case 128: code = 1; break;
		  case 256: code = 2; break;
		  case 512: code = 3; break;
		  case 1024: code = 4; break;
		  case 2048: code = 5; break;
		  case 4096: code = 6; break;
		  default:
		    error ("valid values for builtin %qF argument %d are 64, "
			   "128, 256, 512, 1024, 2048, and 4096", decl,
			   src_arg_index + 1);
		    return;
		  }
		folded_args->quick_push (build_int_cst (integer_type_node,
							code));
		src_arg_index++;
		arg_assigned_p = true;
	      }
	  }
	  break;
	case S390_OVERLOADED_BUILTIN_s390_vec_rl_mask:
	  /* Duplicate the first src arg.  */
	  if (dest_arg_index == 0)
	    {
	      folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
					   (**arglist)[src_arg_index]));
	      arg_assigned_p = true;
	    }
	  break;
	default:
	  break;
	}
      if (!arg_assigned_p)
	{
	  folded_args->quick_push (fully_fold_convert (TREE_VALUE (arg_chain),
						 (**arglist)[src_arg_index]));
	  src_arg_index++;
	}
    }
  *arglist = folded_args;
}

/* Check whether the arguments in ARGLIST match the function type
   DEF_TYPE. Return the number of argument types which required
   conversion/promotion in order to make it match.
   0 stands for a perfect match - all operand types match without changes
   INT_MAX stands for a mismatch.  */
static int
s390_fn_types_compatible (enum s390_builtin_ov_type_index typeindex,
			  vec<tree, va_gc> *arglist)
{
  unsigned int i;
  int match_type = 0;

  for (i = 0; i < vec_safe_length (arglist); i++)
    {
      tree b_arg_type = s390_builtin_types[s390_builtin_ov_types[typeindex][i + 1]];
      tree in_arg = (*arglist)[i];
      tree in_type = TREE_TYPE (in_arg);

      if (TREE_CODE (b_arg_type) == VECTOR_TYPE)
	{
	  /* Vector types have to match precisely.  */
	  if (b_arg_type != in_type
	      && TYPE_MAIN_VARIANT (b_arg_type) != TYPE_MAIN_VARIANT (in_type))
	    goto mismatch;
	}

      if (lang_hooks.types_compatible_p (in_type, b_arg_type))
	continue;

      if (lang_hooks.types_compatible_p (
	    lang_hooks.types.type_promotes_to (in_type),
	    lang_hooks.types.type_promotes_to (b_arg_type)))
	{
	  match_type++;
	  continue;
	}

      /* In this stage the C++ frontend would go ahead trying to find
	 implicit conversion chains for the argument to match the
	 target type.  We will mimic this here only for our limited
	 subset of argument types.  */
      if (TREE_CODE (b_arg_type) == INTEGER_TYPE
	  && TREE_CODE (in_type) == INTEGER_TYPE)
	{
	  match_type++;
	  continue;
	}

      /* If the incoming pointer argument has more qualifiers than the
	 argument type it can still be an imperfect match.  */
      if (POINTER_TYPE_P (b_arg_type) && POINTER_TYPE_P (in_type)
	  && !(TYPE_QUALS (TREE_TYPE (in_type))
	       & ~TYPE_QUALS (TREE_TYPE (b_arg_type)))
	  && (TYPE_QUALS (TREE_TYPE (b_arg_type))
	      & ~TYPE_QUALS (TREE_TYPE (in_type))))
	{
	  tree qual_in_type =
	    build_qualified_type (TREE_TYPE (in_type),
				  TYPE_QUALS (TREE_TYPE (b_arg_type)));

	  if (lang_hooks.types_compatible_p (qual_in_type,
					     TREE_TYPE (b_arg_type)))
	    {
	      match_type++;
	      continue;
	    }
	}

    mismatch:
      if (TARGET_DEBUG_ARG)
	{
	  fprintf (stderr, " mismatch in operand: %d incoming: ", i + 1);
	  print_generic_expr (stderr, in_type, TDF_VOPS|TDF_MEMSYMS);
	  fprintf (stderr, " expected: ");
	  print_generic_expr (stderr, b_arg_type, TDF_VOPS|TDF_MEMSYMS);
	  fprintf (stderr, "\n");
	}
      return INT_MAX;
    }

  return match_type;
}

/* Return the number of elements in the vector arguments of FNDECL in
   case all it matches for all vector arguments, -1 otherwise.  */
static int
s390_vec_n_elem (tree fndecl)
{
  tree b_arg_chain;
  int n_elem = -1;

  if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) == VECTOR_TYPE)
    n_elem = TYPE_VECTOR_SUBPARTS (TREE_TYPE (TREE_TYPE ((fndecl))));

  for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
       !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
       b_arg_chain = TREE_CHAIN (b_arg_chain))
    {
      int tmp_n_elem;
      if (TREE_CODE (TREE_VALUE (b_arg_chain)) != VECTOR_TYPE)
	continue;
      tmp_n_elem = TYPE_VECTOR_SUBPARTS (TREE_VALUE (b_arg_chain));
      if (n_elem != -1 && n_elem != tmp_n_elem)
	return -1;
      n_elem = tmp_n_elem;
    }
  return n_elem;
}


/* Return a tree expression for a call to the overloaded builtin
   function OB_FNDECL at LOC with arguments PASSED_ARGLIST.  */
tree
s390_resolve_overloaded_builtin (location_t loc,
				 tree ob_fndecl,
				 void *passed_arglist)
{
  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
  unsigned int in_args_num = vec_safe_length (arglist);
  unsigned int ob_args_num = 0;
  unsigned int ob_fcode = DECL_MD_FUNCTION_CODE (ob_fndecl);
  enum s390_overloaded_builtin_vars bindex;
  unsigned int i;
  int last_match_type = INT_MAX;
  int last_match_index = -1;
  unsigned int all_op_flags;
  const unsigned int ob_flags = bflags_for_builtin(ob_fcode);
  int num_matches = 0;
  tree target_builtin_decl, b_arg_chain, return_type;
  enum s390_builtin_ov_type_index last_match_fntype_index = BT_OV_MAX;

  if (TARGET_DEBUG_ARG)
    fprintf (stderr,
      "s390_resolve_overloaded_builtin, code = %4d, %s - %s overloaded\n",
      (int)ob_fcode, IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)),
     ob_fcode < S390_BUILTIN_MAX ? "not" : "");

  /* 0...S390_BUILTIN_MAX-1 is for non-overloaded builtins.  */
  if (ob_fcode < S390_BUILTIN_MAX)
    {
      if (ob_flags & B_INT)
	{
	  error_at (loc,
		    "builtin %qF is for GCC internal use only",
		    ob_fndecl);
	  return error_mark_node;
	}
      return NULL_TREE;
    }

  if (ob_flags & B_DEP)
    warning_at (loc, 0, "builtin %qF is deprecated", ob_fndecl);

  if (!TARGET_VX && (ob_flags & B_VX))
    {
      error_at (loc, "%qF requires %<-mvx%>", ob_fndecl);
      return error_mark_node;
    }

  if (!TARGET_VXE && (ob_flags & B_VXE))
    {
      error_at (loc, "%qF requires z14 or higher", ob_fndecl);
      return error_mark_node;
    }

  if (!TARGET_VXE2 && (ob_flags & B_VXE2))
    {
      error_at (loc, "%qF requires z15 or higher", ob_fndecl);
      return error_mark_node;
    }

  ob_fcode -= S390_BUILTIN_MAX;

  for (b_arg_chain = TYPE_ARG_TYPES (TREE_TYPE (ob_fndecl));
       !VOID_TYPE_P (TREE_VALUE (b_arg_chain));
       b_arg_chain = TREE_CHAIN (b_arg_chain))
    ob_args_num++;

  if (ob_args_num != in_args_num)
    {
      error_at (loc,
		"mismatch in number of arguments for builtin %qF. "
		"Expected: %d got %d", ob_fndecl,
		ob_args_num, in_args_num);
      return error_mark_node;
    }

  for (i = 0; i < in_args_num; i++)
    if ((*arglist)[i] == error_mark_node)
      return error_mark_node;

  /* Overloaded builtins without any variants are directly expanded here.  */
  if (desc_start_for_overloaded_builtin[ob_fcode] ==
      S390_OVERLOADED_BUILTIN_VAR_MAX)
    return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, NULL_TREE);

  for (bindex = desc_start_for_overloaded_builtin[ob_fcode];
       bindex <= desc_end_for_overloaded_builtin[ob_fcode];
       bindex = (enum s390_overloaded_builtin_vars)((int)bindex + 1))
  {
    int match_type;
    enum s390_builtin_ov_type_index type_index =
      type_for_overloaded_builtin_var[bindex];

    if (TARGET_DEBUG_ARG)
      fprintf (stderr, "checking variant number: %d", (int)bindex);

    match_type = s390_fn_types_compatible (type_index, arglist);

    if (match_type == INT_MAX)
      continue;

    if (TARGET_DEBUG_ARG)
      fprintf (stderr,
	       " %s match score: %d\n", match_type == 0 ? "perfect" : "imperfect",
	       match_type);

    if (match_type < last_match_type)
      {
	num_matches = 1;
	last_match_type = match_type;
	last_match_fntype_index = type_index;
	last_match_index = bindex;
      }
    else if (match_type == last_match_type)
      num_matches++;
  }

  if (last_match_type == INT_MAX)
    {
      error_at (loc, "invalid parameter combination for intrinsic %qs",
		IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
      return error_mark_node;
    }
  else if (num_matches > 1)
    {
      error_at (loc, "ambiguous overload for intrinsic %qs",
		IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
      return error_mark_node;
    }

  if (!TARGET_VXE
      && bflags_overloaded_builtin_var[last_match_index] & B_VXE)
    {
      error_at (loc, "%qs matching variant requires z14 or higher",
		IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
      return error_mark_node;
    }


  if (!TARGET_VXE2
      && bflags_overloaded_builtin_var[last_match_index] & B_VXE2)
    {
      error_at (loc, "%qs matching variant requires z15 or higher",
		IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));
      return error_mark_node;
    }

  if (bflags_overloaded_builtin_var[last_match_index] & B_DEP)
    warning_at (loc, 0, "%qs matching variant is deprecated",
		IDENTIFIER_POINTER (DECL_NAME (ob_fndecl)));

  /* Overloaded variants which have MAX set as low level builtin are
     supposed to be replaced during expansion with something else.  */
  if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
    target_builtin_decl = ob_fndecl;
  else
    target_builtin_decl = s390_builtin_decls[bt_for_overloaded_builtin_var[last_match_index]];

  all_op_flags = opflags_overloaded_builtin_var[last_match_index];
  return_type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][0]];

  /* Check for the operand flags in the overloaded builtin variant.  */
  for (i = 0; i < ob_args_num; i++)
    {
      unsigned int op_flags = all_op_flags & ((1 << O_SHIFT) - 1);
      tree arg = (*arglist)[i];
      tree type = s390_builtin_types[s390_builtin_ov_types[last_match_fntype_index][i + 1]];

      all_op_flags = all_op_flags >> O_SHIFT;

      if (op_flags == O_ELEM)
	{
	  int n_elem = s390_vec_n_elem (target_builtin_decl);
	  gcc_assert (n_elem > 0);
	  gcc_assert (type == integer_type_node);
	  (*arglist)[i] = build2 (BIT_AND_EXPR, integer_type_node,
				  fold_convert (integer_type_node, arg),
				  build_int_cst (NULL_TREE, n_elem - 1));
	}

      if (TREE_CODE (arg) != INTEGER_CST || !O_IMM_P (op_flags))
	continue;

      if ((TYPE_UNSIGNED (type)
	   && !int_fits_type_p (arg, c_common_unsigned_type (type)))
	  || (!TYPE_UNSIGNED (type)
	      && !int_fits_type_p (arg, c_common_signed_type (type))))
	{
	  error("constant argument %d for builtin %qF is out "
		"of range for target type",
		i + 1, target_builtin_decl);
	  return error_mark_node;
	}

      if (TREE_CODE (arg) == INTEGER_CST
	  && !s390_const_operand_ok (arg, i + 1, op_flags, target_builtin_decl))
	return error_mark_node;
    }

  /* Handle builtins we expand directly - without mapping it to a low
     level builtin.  */
  if (bt_for_overloaded_builtin_var[last_match_index] == S390_BUILTIN_MAX)
    return s390_expand_overloaded_builtin (loc, ob_fcode, arglist, return_type);

  s390_adjust_builtin_arglist (ob_fcode, target_builtin_decl, &arglist);

  if (VOID_TYPE_P (return_type))
    return build_function_call_vec (loc, vNULL, target_builtin_decl,
				    arglist, NULL);
  else
    return fully_fold_convert (return_type,
			       build_function_call_vec (loc, vNULL, target_builtin_decl,
							arglist, NULL));
}

/* This is used to define the REGISTER_TARGET_PRAGMAS macro in s390.h.  */
void
s390_register_target_pragmas (void)
{
  targetm.resolve_overloaded_builtin = s390_resolve_overloaded_builtin;
#if S390_USE_TARGET_ATTRIBUTE
  /* Update pragma hook to allow parsing #pragma GCC target.  */
  targetm.target_option.pragma_parse = s390_pragma_target_parse;
#endif
}
