/* Subroutines for the C front end on the PowerPC architecture.
   Copyright (C) 2002-2022 Free Software Foundation, Inc.

   Contributed by Zack Weinberg <zack@codesourcery.com>
   and Paolo Bonzini <bonzini@gnu.org>

   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/>.  */

#define IN_TARGET_CODE 1

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

#include "rs6000-internal.h"

/* Handle the machine specific pragma longcall.  Its syntax is

   # pragma longcall ( TOGGLE )

   where TOGGLE is either 0 or 1.

   rs6000_default_long_calls is set to the value of TOGGLE, changing
   whether or not new function declarations receive a longcall
   attribute by default.  */

void
rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
#define SYNTAX_ERROR(gmsgid) do {					\
  warning (OPT_Wpragmas, gmsgid);					\
  warning (OPT_Wpragmas, "ignoring malformed %<#pragma longcall%>");	\
  return;								\
} while (0)



  tree x, n;

  /* If we get here, generic code has already scanned the directive
     leader and the word "longcall".  */

  if (pragma_lex (&x) != CPP_OPEN_PAREN)
    SYNTAX_ERROR ("missing open paren");
  if (pragma_lex (&n) != CPP_NUMBER)
    SYNTAX_ERROR ("missing number");
  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
    SYNTAX_ERROR ("missing close paren");

  if (n != integer_zero_node && n != integer_one_node)
    SYNTAX_ERROR ("number must be 0 or 1");

  if (pragma_lex (&x) != CPP_EOF)
    warning (OPT_Wpragmas, "junk at end of %<#pragma longcall%>");

  rs6000_default_long_calls = (n == integer_one_node);
}

/* Handle defining many CPP flags based on TARGET_xxx.  As a general
   policy, rather than trying to guess what flags a user might want a
   #define for, it's better to define a flag for everything.  */

#define builtin_define(TXT) cpp_define (pfile, TXT)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)

/* Keep the AltiVec keywords handy for fast comparisons.  */
static GTY(()) tree __vector_keyword;
static GTY(()) tree vector_keyword;
static GTY(()) tree __pixel_keyword;
static GTY(()) tree pixel_keyword;
static GTY(()) tree __bool_keyword;
static GTY(()) tree bool_keyword;
static GTY(()) tree _Bool_keyword;
static GTY(()) tree __int128_type;
static GTY(()) tree __uint128_type;

/* Preserved across calls.  */
static tree expand_bool_pixel;

static cpp_hashnode *
altivec_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 (pixel_keyword))
	return C_CPP_HASHNODE (__pixel_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;
}

static void
init_vector_keywords (void)
{
  /* Keywords without two leading underscores are context-sensitive, and hence
     implemented as conditional macros, controlled by the
     rs6000_macro_to_expand() function below.  If we have ISA 2.07 64-bit
     support, record the __int128_t and __uint128_t types.  */

  __vector_keyword = get_identifier ("__vector");
  C_CPP_HASHNODE (__vector_keyword)->flags |= NODE_CONDITIONAL;

  __pixel_keyword = get_identifier ("__pixel");
  C_CPP_HASHNODE (__pixel_keyword)->flags |= NODE_CONDITIONAL;

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

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

  pixel_keyword = get_identifier ("pixel");
  C_CPP_HASHNODE (pixel_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;

  if (TARGET_VADDUQM)
    {
      __int128_type = get_identifier ("__int128_t");
      __uint128_type = get_identifier ("__uint128_t");
    }
}

/* Helper function to find out which RID_INT_N_* code is the one for
   __int128, if any.  Returns RID_MAX+1 if none apply, which is safe
   (for our purposes, since we always expect to have __int128) to
   compare against.  */
static int
rid_int128(void)
{
  int i;

  for (i = 0; i < NUM_INT_N_ENTS; i ++)
    if (int_n_enabled_p[i]
	&& int_n_data[i].bitsize == 128)
      return RID_INT_N_0 + i;

  return RID_MAX + 1;
}

/* 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 *
rs6000_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
{
  cpp_hashnode *expand_this = tok->val.node.node;
  cpp_hashnode *ident;

  /* If the current machine does not have altivec, don't look for the
     keywords.  */
  if (!TARGET_ALTIVEC)
    return NULL;

  ident = altivec_categorize_keyword (tok);

  if (ident != expand_this)
    expand_this = NULL;

  if (ident == C_CPP_HASHNODE (__vector_keyword))
    {
      int idx = 0;
      do
	tok = cpp_peek_token (pfile, idx++);
      while (tok->type == CPP_PADDING);
      ident = altivec_categorize_keyword (tok);

      if (ident == C_CPP_HASHNODE (__pixel_keyword))
	{
	  expand_this = C_CPP_HASHNODE (__vector_keyword);
	  expand_bool_pixel = __pixel_keyword;
	}
      else if (ident == C_CPP_HASHNODE (__bool_keyword))
	{
	  expand_this = C_CPP_HASHNODE (__vector_keyword);
	  expand_bool_pixel = __bool_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.; */
      else if (ident && (ident != C_CPP_HASHNODE (__vector_keyword)))
	{
	  enum rid rid_code = (enum rid)(ident->rid_code);
	  bool is_macro = cpp_macro_p (ident);

	  /* If there is a function-like macro, check if it is going to be
	     invoked with or without arguments.  Without following ( treat
	     it like non-macro, otherwise the following cpp_get_token eats
	     what should be preserved.  */
	  if (is_macro && cpp_fun_like_macro_p (ident))
	    {
	      int idx2 = idx;
	      do
		tok = cpp_peek_token (pfile, idx2++);
	      while (tok->type == CPP_PADDING);
	      if (tok->type != CPP_OPEN_PAREN)
		is_macro = false;
	    }

	  if (is_macro)
	    {
	      do
		(void) cpp_get_token (pfile);
	      while (--idx > 0);
	      do
		tok = cpp_peek_token (pfile, idx++);
	      while (tok->type == CPP_PADDING);
	      ident = altivec_categorize_keyword (tok);
	      if (ident == C_CPP_HASHNODE (__pixel_keyword))
		{
		  expand_this = C_CPP_HASHNODE (__vector_keyword);
		  expand_bool_pixel = __pixel_keyword;
		  rid_code = RID_MAX;
		}
	      else if (ident == C_CPP_HASHNODE (__bool_keyword))
		{
		  expand_this = C_CPP_HASHNODE (__vector_keyword);
		  expand_bool_pixel = __bool_keyword;
		  rid_code = RID_MAX;
		}
	      else if (ident)
		rid_code = (enum rid)(ident->rid_code);
	    }

	  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
	      || (rid_code == RID_DOUBLE && TARGET_VSX)
	      || (rid_code == rid_int128 () && TARGET_VADDUQM))
	    {
	      expand_this = C_CPP_HASHNODE (__vector_keyword);
	      /* If the next keyword is bool or pixel, it
		 will need to be expanded as well.  */
	      do
		tok = cpp_peek_token (pfile, idx++);
	      while (tok->type == CPP_PADDING);
	      ident = altivec_categorize_keyword (tok);

	      if (ident == C_CPP_HASHNODE (__pixel_keyword))
		expand_bool_pixel = __pixel_keyword;
	      else if (ident == C_CPP_HASHNODE (__bool_keyword))
		expand_bool_pixel = __bool_keyword;
	      else
		{
		  /* Try two tokens down, too.  */
		  do
		    tok = cpp_peek_token (pfile, idx++);
		  while (tok->type == CPP_PADDING);
		  ident = altivec_categorize_keyword (tok);
		  if (ident == C_CPP_HASHNODE (__pixel_keyword))
		    expand_bool_pixel = __pixel_keyword;
		  else if (ident == C_CPP_HASHNODE (__bool_keyword))
		    expand_bool_pixel = __bool_keyword;
		}
	    }

	  /* Support vector __int128_t, but we don't need to worry about bool
	     or pixel on this type.  */
	  else if (TARGET_VADDUQM
		   && (ident == C_CPP_HASHNODE (__int128_type)
		       || ident == C_CPP_HASHNODE (__uint128_type)))
	    expand_this = C_CPP_HASHNODE (__vector_keyword);
	}
    }
  else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__pixel_keyword))
    {
      expand_this = C_CPP_HASHNODE (__pixel_keyword);
      expand_bool_pixel = 0;
    }
  else if (expand_bool_pixel && ident == C_CPP_HASHNODE (__bool_keyword))
    {
      expand_this = C_CPP_HASHNODE (__bool_keyword);
      expand_bool_pixel = 0;
    }

  return expand_this;
}


/* Define or undefine a single macro.  */

static void
rs6000_define_or_undefine_macro (bool define_p, const char *name)
{
  if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
    fprintf (stderr, "#%s %s\n", (define_p) ? "define" : "undef", name);

  if (define_p)
    cpp_define (parse_in, name);
  else
    cpp_undef (parse_in, name);
}

/* Define or undefine macros based on the current target.  If the user does
   #pragma GCC target, we need to adjust the macros dynamically.  Note, some of
   the options needed for builtins have been moved to separate variables, so
   have both the target flags and the builtin flags as arguments.  */

void
rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
			     HOST_WIDE_INT bu_mask)
{
  if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
    fprintf (stderr,
	     "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX
	     ", " HOST_WIDE_INT_PRINT_HEX ")\n",
	     (define_p) ? "define" : "undef",
	     flags, bu_mask);

  /* Each of the flags mentioned below controls whether certain
     preprocessor macros will be automatically defined when
     preprocessing source files for compilation by this compiler.
     While most of these flags can be enabled or disabled
     explicitly by specifying certain command-line options when
     invoking the compiler, there are also many ways in which these
     flags are enabled or disabled implicitly, based on compiler
     defaults, configuration choices, and on the presence of certain
     related command-line options.  Many, but not all, of these
     implicit behaviors can be found in file "rs6000.cc", the
     rs6000_option_override_internal() function.

     In general, each of the flags may be automatically enabled in
     any of the following conditions:

     1. If no -mcpu target is specified on the command line and no
	--with-cpu target is specified to the configure command line
	and the TARGET_DEFAULT macro for this default cpu host
	includes the flag, and the flag has not been explicitly disabled
	by command-line options.

     2. If the target specified with -mcpu=target on the command line, or
	in the absence of a -mcpu=target command-line option, if the
	target specified using --with-cpu=target on the configure
	command line, is disqualified because the associated binary
	tools (e.g. the assembler) lack support for the requested cpu,
	and the TARGET_DEFAULT macro for this default cpu host
	includes the flag, and the flag has not been explicitly disabled
	by command-line options.

     3. If either of the above two conditions apply except that the
	TARGET_DEFAULT macro is defined to equal zero, and
	TARGET_POWERPC64 and
	a) BYTES_BIG_ENDIAN and the flag to be enabled is either
	   MASK_PPC_GFXOPT or MASK_POWERPC64 (flags for "powerpc64"
	   target), or
	b) !BYTES_BIG_ENDIAN and the flag to be enabled is either
	   MASK_POWERPC64 or it is one of the flags included in
	   ISA_2_7_MASKS_SERVER (flags for "powerpc64le" target).

     4. If a cpu has been requested with a -mcpu=target command-line option
	and this cpu has not been disqualified due to shortcomings of the
	binary tools, and the set of flags associated with the requested cpu
	include the flag to be enabled.  See rs6000-cpus.def for macro
	definitions that represent various ABI standards
	(e.g. ISA_2_1_MASKS, ISA_3_0_MASKS_SERVER) and for a list of
	the specific flags that are associated with each of the cpu
	choices that can be specified as the target of a -mcpu=target
	compile option, or as the target of a --with-cpu=target
	configure option.  Target flags that are specified in either
	of these two ways are considered "implicit" since the flags
	are not mentioned specifically by name.

	Additional documentation describing behavior specific to
	particular flags is provided below, immediately preceding the
	use of each relevant flag.

     5. If there is no -mcpu=target command-line option, and the cpu
	requested by a --with-cpu=target command-line option has not
	been disqualified due to shortcomings of the binary tools, and
	the set of flags associated with the specified target include
	the flag to be enabled.  See the notes immediately above for a
	summary of the flags associated with particular cpu
	definitions.  */

  /* rs6000_isa_flags based options.  */
  rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC");
  if ((flags & OPTION_MASK_PPC_GPOPT) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCSQ");
  if ((flags & OPTION_MASK_PPC_GFXOPT) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PPCGR");
  if ((flags & OPTION_MASK_POWERPC64) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC64");
  if ((flags & OPTION_MASK_MFCRF) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR4");
  if ((flags & OPTION_MASK_POPCNTB) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5");
  if ((flags & OPTION_MASK_FPRND) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR5X");
  if ((flags & OPTION_MASK_CMPB) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR6");
  if ((flags & OPTION_MASK_POPCNTD) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR7");
  /* Note that the OPTION_MASK_DIRECT_MOVE flag is automatically
     turned on in the following condition:
     1. TARGET_P8_VECTOR is enabled and OPTION_MASK_DIRECT_MOVE is not
        explicitly disabled.
        Hereafter, the OPTION_MASK_DIRECT_MOVE flag is considered to
        have been turned on explicitly.
     Note that the OPTION_MASK_DIRECT_MOVE flag is automatically
     turned off in any of the following conditions:
     1. TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX is explicitly
	disabled and OPTION_MASK_DIRECT_MOVE was not explicitly
	enabled.
     2. TARGET_VSX is off.  */
  if ((flags & OPTION_MASK_DIRECT_MOVE) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR8");
  if ((flags & OPTION_MASK_MODULO) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR9");
  if ((flags & OPTION_MASK_POWER10) != 0)
    rs6000_define_or_undefine_macro (define_p, "_ARCH_PWR10");
  if ((flags & OPTION_MASK_SOFT_FLOAT) != 0)
    rs6000_define_or_undefine_macro (define_p, "_SOFT_FLOAT");
  if ((flags & OPTION_MASK_RECIP_PRECISION) != 0)
    rs6000_define_or_undefine_macro (define_p, "__RECIP_PRECISION__");
  /* Note that the OPTION_MASK_ALTIVEC flag is automatically turned on
     in any of the following conditions:
     1. The operating system is Darwin and it is configured for 64
	bit.  (See darwin_rs6000_override_options.)
     2. The operating system is Darwin and the operating system
	version is 10.5 or higher and the user has not explicitly
	disabled ALTIVEC by specifying -mcpu=G3 or -mno-altivec and
	the compiler is not producing code for integration within the
	kernel.  (See darwin_rs6000_override_options.)
     Note that the OPTION_MASK_ALTIVEC flag is automatically turned
     off in any of the following conditions:
     1. The operating system does not support saving of AltiVec
	registers (OS_MISSING_ALTIVEC).
     2. If an inner context (as introduced by
	__attribute__((__target__())) or #pragma GCC target()
	requests a target that normally enables the
	OPTION_MASK_ALTIVEC flag but the outer-most "main target"
	does not support the rs6000_altivec_abi, this flag is
	turned off for the inner context unless OPTION_MASK_ALTIVEC
	was explicitly enabled for the inner context.  */
  if ((flags & OPTION_MASK_ALTIVEC) != 0)
    {
      const char *vec_str = (define_p) ? "__VEC__=10206" : "__VEC__";
      rs6000_define_or_undefine_macro (define_p, "__ALTIVEC__");
      rs6000_define_or_undefine_macro (define_p, vec_str);

	  /* Define this when supporting context-sensitive keywords.  */
      if (!flag_iso)
	rs6000_define_or_undefine_macro (define_p, "__APPLE_ALTIVEC__");
      if (rs6000_aix_extabi)
	rs6000_define_or_undefine_macro (define_p, "__EXTABI__");
    }
  /* Note that the OPTION_MASK_VSX flag is automatically turned on in
     the following conditions:
     1. TARGET_P8_VECTOR is explicitly turned on and the OPTION_MASK_VSX
        was not explicitly turned off.  Hereafter, the OPTION_MASK_VSX
        flag is considered to have been explicitly turned on.
     Note that the OPTION_MASK_VSX flag is automatically turned off in
     the following conditions:
     1. The operating system does not support saving of AltiVec
	registers (OS_MISSING_ALTIVEC).
     2. If the option TARGET_HARD_FLOAT is turned off.  Hereafter, the
	OPTION_MASK_VSX flag is considered to have been turned off
	explicitly.
     3. If TARGET_AVOID_XFORM is turned on explicitly at the outermost
	compilation context, or if it is turned on by any means in an
	inner compilation context.  Hereafter, the OPTION_MASK_VSX
	flag is considered to have been turned off explicitly.
     4. If TARGET_ALTIVEC was explicitly disabled.  Hereafter, the
	OPTION_MASK_VSX flag is considered to have been turned off
	explicitly.
     5. If an inner context (as introduced by
	__attribute__((__target__())) or #pragma GCC target()
	requests a target that normally enables the
	OPTION_MASK_VSX flag but the outer-most "main target"
	does not support the rs6000_altivec_abi, this flag is
	turned off for the inner context unless OPTION_MASK_VSX
	was explicitly enabled for the inner context.  */
  if ((flags & OPTION_MASK_VSX) != 0)
    rs6000_define_or_undefine_macro (define_p, "__VSX__");
  if ((flags & OPTION_MASK_HTM) != 0)
    {
      rs6000_define_or_undefine_macro (define_p, "__HTM__");
      /* Tell the user that our HTM insn patterns act as memory barriers.  */
      rs6000_define_or_undefine_macro (define_p, "__TM_FENCE__");
    }
  /* Note that the OPTION_MASK_P8_VECTOR flag is automatically turned
     on in the following conditions:
     1. TARGET_P9_VECTOR is explicitly turned on and
        OPTION_MASK_P8_VECTOR is not explicitly turned off.
        Hereafter, the OPTION_MASK_P8_VECTOR flag is considered to
        have been turned off explicitly.
     Note that the OPTION_MASK_P8_VECTOR flag is automatically turned
     off in the following conditions:
     1. If any of TARGET_HARD_FLOAT, TARGET_ALTIVEC, or TARGET_VSX
	were turned off explicitly and OPTION_MASK_P8_VECTOR flag was
	not turned on explicitly.
     2. If TARGET_ALTIVEC is turned off.  Hereafter, the
	OPTION_MASK_P8_VECTOR flag is considered to have been turned off
	explicitly.
     3. If TARGET_VSX is turned off and OPTION_MASK_P8_VECTOR was not
        explicitly enabled.  If TARGET_VSX is explicitly enabled, the
        OPTION_MASK_P8_VECTOR flag is hereafter also considered to
	have been turned off explicitly.  */
  if ((flags & OPTION_MASK_P8_VECTOR) != 0)
    rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__");
  /* Note that the OPTION_MASK_P9_VECTOR flag is automatically turned
     off in the following conditions:
     1. If TARGET_P8_VECTOR is turned off and OPTION_MASK_P9_VECTOR is
        not turned on explicitly. Hereafter, if OPTION_MASK_P8_VECTOR
        was turned on explicitly, the OPTION_MASK_P9_VECTOR flag is
        also considered to have been turned off explicitly.
     Note that the OPTION_MASK_P9_VECTOR is automatically turned on
     in the following conditions:
     1. If TARGET_P9_MINMAX was turned on explicitly.
        Hereafter, THE OPTION_MASK_P9_VECTOR flag is considered to
        have been turned on explicitly.  */
  if ((flags & OPTION_MASK_P9_VECTOR) != 0)
    rs6000_define_or_undefine_macro (define_p, "__POWER9_VECTOR__");
  /* Note that the OPTION_MASK_QUAD_MEMORY flag is automatically
     turned off in the following conditions:
     1. If TARGET_POWERPC64 is turned off.
     2. If WORDS_BIG_ENDIAN is false (non-atomic quad memory
	load/store are disabled on little endian).  */
  if ((flags & OPTION_MASK_QUAD_MEMORY) != 0)
    rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY__");
  /* Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is automatically
     turned off in the following conditions:
     1. If TARGET_POWERPC64 is turned off.
     Note that the OPTION_MASK_QUAD_MEMORY_ATOMIC flag is
     automatically turned on in the following conditions:
     1. If TARGET_QUAD_MEMORY and this flag was not explicitly
	disabled.  */
  if ((flags & OPTION_MASK_QUAD_MEMORY_ATOMIC) != 0)
    rs6000_define_or_undefine_macro (define_p, "__QUAD_MEMORY_ATOMIC__");
  /* Note that the OPTION_MASK_CRYPTO flag is automatically turned off
     in the following conditions:
     1. If any of TARGET_HARD_FLOAT or TARGET_ALTIVEC or TARGET_VSX
	are turned off explicitly and OPTION_MASK_CRYPTO is not turned
	on explicitly.
     2. If TARGET_ALTIVEC is turned off.  */
  if ((flags & OPTION_MASK_CRYPTO) != 0)
    rs6000_define_or_undefine_macro (define_p, "__CRYPTO__");
  if ((flags & OPTION_MASK_FLOAT128_KEYWORD) != 0)
    {
      rs6000_define_or_undefine_macro (define_p, "__FLOAT128__");
      if (define_p)
	rs6000_define_or_undefine_macro (true, "__float128=__ieee128");
      else
	rs6000_define_or_undefine_macro (false, "__float128");
    }
  /* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or
     via the target attribute/pragma.  */
  if ((flags & OPTION_MASK_FLOAT128_HW) != 0)
    rs6000_define_or_undefine_macro (define_p, "__FLOAT128_HARDWARE__");

  /* options from the builtin masks.  */
  /* Note that RS6000_BTM_CELL is enabled only if (rs6000_cpu ==
     PROCESSOR_CELL) (e.g. -mcpu=cell).  */
  if ((bu_mask & RS6000_BTM_CELL) != 0)
    rs6000_define_or_undefine_macro (define_p, "__PPU__");

  /* Tell the user if we support the MMA instructions.  */
  if ((flags & OPTION_MASK_MMA) != 0)
    rs6000_define_or_undefine_macro (define_p, "__MMA__");
  /* Whether pc-relative code is being generated.  */
  if ((flags & OPTION_MASK_PCREL) != 0)
    rs6000_define_or_undefine_macro (define_p, "__PCREL__");
  /* Tell the user -mrop-protect is in play.  */
  if (rs6000_rop_protect)
    rs6000_define_or_undefine_macro (define_p, "__ROP_PROTECT__");
}

void
rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
  /* Define all of the common macros.  */
  rs6000_target_modify_macros (true, rs6000_isa_flags,
			       rs6000_builtin_mask_calculate ());

  if (TARGET_FRE)
    builtin_define ("__RECIP__");
  if (TARGET_FRES)
    builtin_define ("__RECIPF__");
  if (TARGET_FRSQRTE)
    builtin_define ("__RSQRTE__");
  if (TARGET_FRSQRTES)
    builtin_define ("__RSQRTEF__");
  if (TARGET_FLOAT128_TYPE)
    builtin_define ("__FLOAT128_TYPE__");
#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
  builtin_define ("__BUILTIN_CPU_SUPPORTS__");
#endif

  if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM)
    {
      /* Define the AltiVec syntactic elements.  */
      builtin_define ("__vector=__attribute__((altivec(vector__)))");
      builtin_define ("__pixel=__attribute__((altivec(pixel__))) unsigned short");
      builtin_define ("__bool=__attribute__((altivec(bool__))) unsigned");

      if (!flag_iso)
	{
	  builtin_define ("vector=vector");
	  builtin_define ("pixel=pixel");
	  builtin_define ("bool=bool");
	  builtin_define ("_Bool=_Bool");
	  init_vector_keywords ();

	  /* Enable context-sensitive macros.  */
	  cpp_get_callbacks (pfile)->macro_to_expand = rs6000_macro_to_expand;
	}
    }
  if (!TARGET_HARD_FLOAT)
    builtin_define ("_SOFT_DOUBLE");
  /* Used by lwarx/stwcx. errata work-around.  */
  if (rs6000_cpu == PROCESSOR_PPC405)
    builtin_define ("__PPC405__");
  /* Used by libstdc++.  */
  if (TARGET_NO_LWSYNC)
    builtin_define ("__NO_LWSYNC__");

  if (TARGET_EXTRA_BUILTINS)
    {
      /* For the VSX builtin functions identical to Altivec functions, just map
	 the altivec builtin into the vsx version (the altivec functions
	 generate VSX code if -mvsx).  */
      builtin_define ("__builtin_vsx_xxland=__builtin_vec_and");
      builtin_define ("__builtin_vsx_xxlandc=__builtin_vec_andc");
      builtin_define ("__builtin_vsx_xxlnor=__builtin_vec_nor");
      builtin_define ("__builtin_vsx_xxlor=__builtin_vec_or");
      builtin_define ("__builtin_vsx_xxlxor=__builtin_vec_xor");
      builtin_define ("__builtin_vsx_xxsel=__builtin_vec_sel");
      builtin_define ("__builtin_vsx_vperm=__builtin_vec_perm");

      /* Also map the a and m versions of the multiply/add instructions to the
	 builtin for people blindly going off the instruction manual.  */
      builtin_define ("__builtin_vsx_xvmaddadp=__builtin_vsx_xvmadddp");
      builtin_define ("__builtin_vsx_xvmaddmdp=__builtin_vsx_xvmadddp");
      builtin_define ("__builtin_vsx_xvmaddasp=__builtin_vsx_xvmaddsp");
      builtin_define ("__builtin_vsx_xvmaddmsp=__builtin_vsx_xvmaddsp");
      builtin_define ("__builtin_vsx_xvmsubadp=__builtin_vsx_xvmsubdp");
      builtin_define ("__builtin_vsx_xvmsubmdp=__builtin_vsx_xvmsubdp");
      builtin_define ("__builtin_vsx_xvmsubasp=__builtin_vsx_xvmsubsp");
      builtin_define ("__builtin_vsx_xvmsubmsp=__builtin_vsx_xvmsubsp");
      builtin_define ("__builtin_vsx_xvnmaddadp=__builtin_vsx_xvnmadddp");
      builtin_define ("__builtin_vsx_xvnmaddmdp=__builtin_vsx_xvnmadddp");
      builtin_define ("__builtin_vsx_xvnmaddasp=__builtin_vsx_xvnmaddsp");
      builtin_define ("__builtin_vsx_xvnmaddmsp=__builtin_vsx_xvnmaddsp");
      builtin_define ("__builtin_vsx_xvnmsubadp=__builtin_vsx_xvnmsubdp");
      builtin_define ("__builtin_vsx_xvnmsubmdp=__builtin_vsx_xvnmsubdp");
      builtin_define ("__builtin_vsx_xvnmsubasp=__builtin_vsx_xvnmsubsp");
      builtin_define ("__builtin_vsx_xvnmsubmsp=__builtin_vsx_xvnmsubsp");
    }

  /* Map the old _Float128 'q' builtins into the new 'f128' builtins.  */
  if (TARGET_FLOAT128_TYPE)
    {
      builtin_define ("__builtin_fabsq=__builtin_fabsf128");
      builtin_define ("__builtin_copysignq=__builtin_copysignf128");
      builtin_define ("__builtin_nanq=__builtin_nanf128");
      builtin_define ("__builtin_nansq=__builtin_nansf128");
      builtin_define ("__builtin_infq=__builtin_inff128");
      builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
    }

  /* Tell users they can use __builtin_bswap{16,64}.  */
  builtin_define ("__HAVE_BSWAP__");

  /* May be overridden by target configuration.  */
  RS6000_CPU_CPP_ENDIAN_BUILTINS();

  if (TARGET_LONG_DOUBLE_128)
    {
      builtin_define ("__LONG_DOUBLE_128__");
      builtin_define ("__LONGDOUBLE128");

      if (TARGET_IEEEQUAD)
	{
	  /* Older versions of GLIBC used __attribute__((__KC__)) to create the
	     IEEE 128-bit floating point complex type for C++ (which does not
	     support _Float128 _Complex).  If the default for long double is
	     IEEE 128-bit mode, the library would need to use
	     __attribute__((__TC__)) instead.  Defining __KF__ and __KC__
	     is a stop-gap to build with the older libraries, until we
	     get an updated library.  */
	  builtin_define ("__LONG_DOUBLE_IEEE128__");
	  builtin_define ("__KF__=__TF__");
	  builtin_define ("__KC__=__TC__");
	}
      else
	builtin_define ("__LONG_DOUBLE_IBM128__");
    }

  switch (TARGET_CMODEL)
    {
      /* Deliberately omit __CMODEL_SMALL__ since that was the default
	 before --mcmodel support was added.  */
    case CMODEL_MEDIUM:
      builtin_define ("__CMODEL_MEDIUM__");
      break;
    case CMODEL_LARGE:
      builtin_define ("__CMODEL_LARGE__");
      break;
    default:
      break;
    }

  switch (rs6000_current_abi)
    {
    case ABI_V4:
      builtin_define ("_CALL_SYSV");
      break;
    case ABI_AIX:
      builtin_define ("_CALL_AIXDESC");
      builtin_define ("_CALL_AIX");
      builtin_define ("_CALL_ELF=1");
      break;
    case ABI_ELFv2:
      builtin_define ("_CALL_ELF=2");
      break;
    case ABI_DARWIN:
      builtin_define ("_CALL_DARWIN");
      break;
    default:
      break;
    }

  /* Vector element order.  */
  if (BYTES_BIG_ENDIAN)
    builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_BIG_ENDIAN__");
  else
    builtin_define ("__VEC_ELEMENT_REG_ORDER__=__ORDER_LITTLE_ENDIAN__");

  /* Let the compiled code know if 'f' class registers will not be available.  */
  if (TARGET_SOFT_FLOAT)
    builtin_define ("__NO_FPRS__");

  /* Whether aggregates passed by value are aligned to a 16 byte boundary
     if their alignment is 16 bytes or larger.  */
  if ((TARGET_MACHO && rs6000_darwin64_abi)
      || DEFAULT_ABI == ABI_ELFv2
      || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
    builtin_define ("__STRUCT_PARM_ALIGN__=16");
}



/* Convert a type stored into a struct altivec_builtin_types as ID,
   into a tree.  The types are in rs6000_builtin_types: negative values
   create a pointer type for the type associated to ~ID.  Note it is
   a logical NOT, rather than a negation, otherwise you cannot represent
   a pointer type for ID 0.  */

static inline tree
rs6000_builtin_type (int id)
{
  tree t;
  t = rs6000_builtin_types[id < 0 ? ~id : id];
  return id < 0 ? build_pointer_type (t) : t;
}

/* Check whether the type of an argument, T, is compatible with a type ID
   stored into a struct altivec_builtin_types.  Integer types are considered
   compatible; otherwise, the language hook lang_hooks.types_compatible_p makes
   the decision.  Also allow long double and _Float128 to be compatible if
   -mabi=ieeelongdouble.  */

static inline bool
is_float128_p (tree t)
{
  return (t == float128_type_node
	  || (TARGET_IEEEQUAD
	      && TARGET_LONG_DOUBLE_128
	      && t == long_double_type_node));
}
  

/* Return true iff ARGTYPE can be compatibly passed as PARMTYPE.  */
static bool
rs6000_builtin_type_compatible (tree parmtype, tree argtype)
{
  if (parmtype == error_mark_node)
    return false;

  if (INTEGRAL_TYPE_P (parmtype) && INTEGRAL_TYPE_P (argtype))
    return true;

  if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
      && is_float128_p (parmtype) && is_float128_p (argtype))
    return true;

  if (POINTER_TYPE_P (parmtype) && POINTER_TYPE_P (argtype))
    {
      parmtype = TREE_TYPE (parmtype);
      argtype = TREE_TYPE (argtype);
      if (TYPE_READONLY (argtype))
	parmtype = build_qualified_type (parmtype, TYPE_QUAL_CONST);
    }

  return lang_hooks.types_compatible_p (parmtype, argtype);
}

/* 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).  */

static 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;
}

/* Build a tree for a function call to an Altivec non-overloaded builtin.
   The overloaded builtin that matched the types and args is described
   by DESC.  The N arguments are given in ARGS, respectively.

   Actually the only thing it does is calling fold_convert on ARGS, with
   a small exception for vec_{all,any}_{ge,le} predicates. */

static tree
altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type,
				rs6000_gen_builtins bif_id,
				rs6000_gen_builtins ovld_id)
{
  tree argtypes = TYPE_ARG_TYPES (fntype);
  tree arg_type[MAX_OVLD_ARGS];
  tree fndecl = rs6000_builtin_decls[bif_id];

  for (int i = 0; i < n; i++)
    {
      arg_type[i] = TREE_VALUE (argtypes);
      argtypes = TREE_CHAIN (argtypes);
    }

  /* The AltiVec overloading implementation is overall gross, but this
     is particularly disgusting.  The vec_{all,any}_{ge,le} builtins
     are completely different for floating-point vs. integer vector
     types, because the former has vcmpgefp, but the latter should use
     vcmpgtXX.

     In practice, the second and third arguments are swapped, and the
     condition (LT vs. EQ, which is recognizable by bit 1 of the first
     argument) is reversed.  Patch the arguments here before building
     the resolved CALL_EXPR.  */
  if (n == 3
      && ovld_id == RS6000_OVLD_VEC_CMPGE_P
      && bif_id != RS6000_BIF_VCMPGEFP_P
      && bif_id != RS6000_BIF_XVCMPGEDP_P)
    {
      std::swap (args[1], args[2]);
      std::swap (arg_type[1], arg_type[2]);

      args[0] = fold_build2 (BIT_XOR_EXPR, TREE_TYPE (args[0]), args[0],
			     build_int_cst (NULL_TREE, 2));
    }

  for (int j = 0; j < n; j++)
    args[j] = fully_fold_convert (arg_type[j], args[j]);

  /* If the number of arguments to an overloaded function increases,
     we must expand this switch.  */
  gcc_assert (MAX_OVLD_ARGS <= 4);

  tree call;
  switch (n)
    {
    case 0:
      call = build_call_expr (fndecl, 0);
      break;
    case 1:
      call = build_call_expr (fndecl, 1, args[0]);
      break;
    case 2:
      call = build_call_expr (fndecl, 2, args[0], args[1]);
      break;
    case 3:
      call = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
      break;
    case 4:
      call = build_call_expr (fndecl, 4, args[0], args[1], args[2], args[3]);
      break;
    default:
      gcc_unreachable ();
    }
  return fold_convert (ret_type, call);
}

/* Enumeration of possible results from attempted overload resolution.
   This is used by special-case helper functions to tell their caller
   whether they succeeded and what still needs to be done.

	unresolved = Still needs processing
	  resolved = Resolved (but may be an error_mark_node)
      resolved_bad = An error that needs handling by the caller.  */

enum resolution { unresolved, resolved, resolved_bad };

/* Resolve an overloaded vec_mul call and return a tree expression for the
   resolved call if successful.  ARGS contains the arguments to the call.
   TYPES contains their types.  RES must be set to indicate the status of
   the resolution attempt.  LOC contains statement location information.  */

static tree
resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc)
{
  /* vec_mul needs to be special cased because there are no instructions for it
     for the {un}signed char, {un}signed short, and {un}signed int types.  */

  /* Both arguments must be vectors and the types must be compatible.  */
  if (TREE_CODE (types[0]) != VECTOR_TYPE
      || !lang_hooks.types_compatible_p (types[0], types[1]))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  switch (TYPE_MODE (TREE_TYPE (types[0])))
    {
    case E_QImode:
    case E_HImode:
    case E_SImode:
    case E_DImode:
    case E_TImode:
      /* For scalar types just use a multiply expression.  */
      *res = resolved;
      return fold_build2_loc (loc, MULT_EXPR, types[0], args[0],
			      fold_convert (types[0], args[1]));
    case E_SFmode:
      {
	/* For floats use the xvmulsp instruction directly.  */
	*res = resolved;
	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP];
	return build_call_expr (call, 2, args[0], args[1]);
      }
    case E_DFmode:
      {
	/* For doubles use the xvmuldp instruction directly.  */
	*res = resolved;
	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP];
	return build_call_expr (call, 2, args[0], args[1]);
      }
    /* Other types are errors.  */
    default:
      *res = resolved_bad;
      return error_mark_node;
    }
}

/* Resolve an overloaded vec_cmpne call and return a tree expression for the
   resolved call if successful.  ARGS contains the arguments to the call.
   TYPES contains their types.  RES must be set to indicate the status of
   the resolution attempt.  LOC contains statement location information.  */

static tree
resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc)
{
  /* vec_cmpne needs to be special cased because there are no instructions
     for it (prior to power 9).  */

  /* Both arguments must be vectors and the types must be compatible.  */
  if (TREE_CODE (types[0]) != VECTOR_TYPE
      || !lang_hooks.types_compatible_p (types[0], types[1]))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0]));

  /* Power9 instructions provide the most efficient implementation of
     ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode
     or SFmode or DFmode.  */
  if (!TARGET_P9_VECTOR
      || arg0_elt_mode == DImode
      || arg0_elt_mode == TImode
      || arg0_elt_mode == SFmode
      || arg0_elt_mode == DFmode)
    {
      switch (arg0_elt_mode)
	{
	  /* vec_cmpneq (va, vb) == vec_nor (vec_cmpeq (va, vb),
					     vec_cmpeq (va, vb)).  */
	  /* Note:  vec_nand also works but opt changes vec_nand's
	     to vec_nor's anyway.  */
	case E_QImode:
	case E_HImode:
	case E_SImode:
	case E_DImode:
	case E_TImode:
	case E_SFmode:
	case E_DFmode:
	  {
	    /* call = vec_cmpeq (va, vb)
	       result = vec_nor (call, call).  */
	    vec<tree, va_gc> *params = make_tree_vector ();
	    vec_safe_push (params, args[0]);
	    vec_safe_push (params, args[1]);
	    tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ];
	    tree call = altivec_resolve_overloaded_builtin (loc, decl, params);
	    /* Use save_expr to ensure that operands used more than once
	       that may have side effects (like calls) are only evaluated
	       once.  */
	    call = save_expr (call);
	    params = make_tree_vector ();
	    vec_safe_push (params, call);
	    vec_safe_push (params, call);
	    decl = rs6000_builtin_decls[RS6000_OVLD_VEC_NOR];
	    *res = resolved;
	    return altivec_resolve_overloaded_builtin (loc, decl, params);
	  }
	  /* Other types are errors.  */
	default:
	  *res = resolved_bad;
	  return error_mark_node;
	}
    }

  /* Otherwise this call is unresolved, and altivec_resolve_overloaded_builtin
     will later process the Power9 alternative.  */
  *res = unresolved;
  return error_mark_node;
}

/* Resolve an overloaded vec_adde or vec_sube call and return a tree expression
   for the resolved call if successful.  ARGS contains the arguments to the
   call.  TYPES contains their arguments.  RES must be set to indicate the
   status of the resolution attempt.  LOC contains statement location
   information.  */

static tree
resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
		       tree *args, tree *types, location_t loc)
{
  /* vec_adde needs to be special cased because there is no instruction
     for the {un}signed int version.  */

  /* All 3 arguments must be vectors of (signed or unsigned) (int or
     __int128) and the types must be compatible.  */
  if (TREE_CODE (types[0]) != VECTOR_TYPE
      || !lang_hooks.types_compatible_p (types[0], types[1])
      || !lang_hooks.types_compatible_p (types[1], types[2]))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  switch (TYPE_MODE (TREE_TYPE (types[0])))
    {
      /* For {un}signed ints,
	 vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
					       vec_and (carryv, 1)).
	 vec_sube (va, vb, carryv) == vec_sub (vec_sub (va, vb),
					       vec_and (carryv, 1)).  */
    case E_SImode:
      {
	vec<tree, va_gc> *params = make_tree_vector ();
	vec_safe_push (params, args[0]);
	vec_safe_push (params, args[1]);

	tree add_sub_builtin;
	if (fcode == RS6000_OVLD_VEC_ADDE)
	  add_sub_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADD];
	else
	  add_sub_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUB];

	tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
							params);
	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
	tree ones_vector = build_vector_from_val (types[0], const1);
	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
					 args[2], ones_vector);
	params = make_tree_vector ();
	vec_safe_push (params, call);
	vec_safe_push (params, and_expr);
	*res = resolved;
	return altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
						   params);
      }
      /* For {un}signed __int128s use the vaddeuqm/vsubeuqm instruction
	 directly using the standard machinery.  */
    case E_TImode:
      *res = unresolved;
      break;

      /* Types other than {un}signed int and {un}signed __int128
	 are errors.  */
    default:
      *res = resolved_bad;
    }

  return error_mark_node;
}

/* Resolve an overloaded vec_addec or vec_subec call and return a tree
   expression for the resolved call if successful.  ARGS contains the arguments
   to the call.  TYPES contains their types.  RES must be set to indicate the
   status of the resolution attempt.  LOC contains statement location
   information.  */

static tree
resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
			 tree *args, tree *types, location_t loc)
{
  /* vec_addec and vec_subec needs to be special cased because there is
     no instruction for the (un)signed int version.  */

  /* All 3 arguments must be vectors of (signed or unsigned) (int or
     __int128) and the types must be compatible.  */
  if (TREE_CODE (types[0]) != VECTOR_TYPE
      || !lang_hooks.types_compatible_p (types[0], types[1])
      || !lang_hooks.types_compatible_p (types[1], types[2]))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  switch (TYPE_MODE (TREE_TYPE (types[0])))
    {
      /* For {un}signed ints,
	   vec_addec (va, vb, carryv) ==
	     vec_or (vec_addc (va, vb),
		     vec_addc (vec_add (va, vb),
			       vec_and (carryv, 0x1))).  */
    case E_SImode:
      {
	/* Use save_expr to ensure that operands used more than once that may
	   have side effects (like calls) are only evaluated once.  */
	args[0] = save_expr (args[0]);
	args[1] = save_expr (args[1]);
	vec<tree, va_gc> *params = make_tree_vector ();
	vec_safe_push (params, args[0]);
	vec_safe_push (params, args[1]);

	tree as_c_builtin;
	if (fcode == RS6000_OVLD_VEC_ADDEC)
	  as_c_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADDC];
	else
	  as_c_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUBC];

	tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
							 params);
	params = make_tree_vector ();
	vec_safe_push (params, args[0]);
	vec_safe_push (params, args[1]);

	tree as_builtin;
	if (fcode == RS6000_OVLD_VEC_ADDEC)
	  as_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_ADD];
	else
	  as_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_SUB];

	tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
							 params);
	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
	tree ones_vector = build_vector_from_val (types[0], const1);
	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
					 args[2], ones_vector);
	params = make_tree_vector ();
	vec_safe_push (params, call2);
	vec_safe_push (params, and_expr);
	call2 = altivec_resolve_overloaded_builtin (loc, as_c_builtin, params);
	params = make_tree_vector ();
	vec_safe_push (params, call1);
	vec_safe_push (params, call2);
	tree or_builtin = rs6000_builtin_decls[RS6000_OVLD_VEC_OR];
	*res = resolved;
	return altivec_resolve_overloaded_builtin (loc, or_builtin, params);
      }
      /* For {un}signed __int128s use the vaddecuq/vsubbecuq
	 instructions.  This occurs through normal processing.  */
    case E_TImode:
      *res = unresolved;
      break;

      /* Types other than {un}signed int and {un}signed __int128
	 are errors.  */
    default:
      *res = resolved_bad;
    }

  return error_mark_node;
}

/* Resolve an overloaded vec_splats or vec_promote call and return a tree
   expression for the resolved call if successful.  NARGS is the number of
   arguments to the call.  ARGLIST contains the arguments.  RES must be set
   to indicate the status of the resolution attempt.  */

static tree
resolve_vec_splats (resolution *res, rs6000_gen_builtins fcode,
		    vec<tree, va_gc> *arglist, unsigned nargs)
{
  const char *name;
  name = fcode == RS6000_OVLD_VEC_SPLATS ? "vec_splats" : "vec_promote";

  if (fcode == RS6000_OVLD_VEC_SPLATS && nargs != 1)
    {
      error ("builtin %qs only accepts 1 argument", name);
      *res = resolved;
      return error_mark_node;
    }

  if (fcode == RS6000_OVLD_VEC_PROMOTE && nargs != 2)
    {
      error ("builtin %qs only accepts 2 arguments", name);
      *res = resolved;
      return error_mark_node;
    }

  /* Ignore promote's element argument.  */
  if (fcode == RS6000_OVLD_VEC_PROMOTE
      && !INTEGRAL_TYPE_P (TREE_TYPE ((*arglist)[1])))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  tree arg = (*arglist)[0];
  tree type = TREE_TYPE (arg);

  if (!SCALAR_FLOAT_TYPE_P (type) && !INTEGRAL_TYPE_P (type))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  bool unsigned_p = TYPE_UNSIGNED (type);
  int size;

  switch (TYPE_MODE (type))
    {
    case E_TImode:
      type = unsigned_p ? unsigned_V1TI_type_node : V1TI_type_node;
      size = 1;
      break;
    case E_DImode:
      type = unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node;
      size = 2;
      break;
    case E_SImode:
      type = unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node;
      size = 4;
      break;
    case E_HImode:
      type = unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node;
      size = 8;
      break;
    case E_QImode:
      type = unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node;
      size = 16;
      break;
    case E_SFmode:
      type = V4SF_type_node;
      size = 4;
      break;
    case E_DFmode:
      type = V2DF_type_node;
      size = 2;
      break;
    default:
      *res = resolved_bad;
      return error_mark_node;
    }

  arg = save_expr (fold_convert (TREE_TYPE (type), arg));
  vec<constructor_elt, va_gc> *vec;
  vec_alloc (vec, size);

  for (int i = 0; i < size; i++)
    {
      constructor_elt elt = {NULL_TREE, arg};
      vec->quick_push (elt);
    }

  *res = resolved;
  return build_constructor (type, vec);
}

/* Resolve an overloaded vec_extract call and return a tree expression for
   the resolved call if successful.  NARGS is the number of arguments to
   the call.  ARGLIST contains the arguments.  RES must be set to indicate
   the status of the resolution attempt.  LOC contains statement location
   information.  */

static tree
resolve_vec_extract (resolution *res, vec<tree, va_gc> *arglist,
		     unsigned nargs, location_t loc)
{
  if (nargs != 2)
    {
      error ("builtin %qs only accepts 2 arguments", "vec_extract");
      *res = resolved;
      return error_mark_node;
    }

  tree arg1 = (*arglist)[0];
  tree arg1_type = TREE_TYPE (arg1);
  tree arg2 = (*arglist)[1];

  if (TREE_CODE (arg1_type) != VECTOR_TYPE
      || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  /* See if we can optimize vec_extract with the current VSX instruction
     set.  */
  machine_mode mode = TYPE_MODE (arg1_type);
  tree arg1_inner_type;

  if (VECTOR_MEM_VSX_P (mode))
    {
      tree call = NULL_TREE;
      int nunits = GET_MODE_NUNITS (mode);
      arg2 = fold_for_warn (arg2);

      /* If the second argument is an integer constant, generate
	 the built-in code if we can.  We need 64-bit and direct
	 move to extract the small integer vectors.  */
      if (TREE_CODE (arg2) == INTEGER_CST)
	{
	  wide_int selector = wi::to_wide (arg2);
	  selector = wi::umod_trunc (selector, nunits);
	  arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
	  switch (mode)
	    {
	    case E_V1TImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V1TI];
	      break;

	    case E_V2DFmode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DF];
	      break;

	    case E_V2DImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DI];
	      break;

	    case E_V4SFmode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SF];
	      break;

	    case E_V4SImode:
	      if (TARGET_DIRECT_MOVE_64BIT)
		call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SI];
	      break;

	    case E_V8HImode:
	      if (TARGET_DIRECT_MOVE_64BIT)
		call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V8HI];
	      break;

	    case E_V16QImode:
	      if (TARGET_DIRECT_MOVE_64BIT)
		call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V16QI];
	      break;

	    default:
	      break;
	    }
	}

      /* If the second argument is variable, we can optimize it if we are
	 generating 64-bit code on a machine with direct move.  */
      else if (TREE_CODE (arg2) != INTEGER_CST && TARGET_DIRECT_MOVE_64BIT)
	{
	  switch (mode)
	    {
	    case E_V2DFmode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DF];
	      break;

	    case E_V2DImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V2DI];
	      break;

	    case E_V4SFmode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SF];
	      break;

	    case E_V4SImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V4SI];
	      break;

	    case E_V8HImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V8HI];
	      break;

	    case E_V16QImode:
	      call = rs6000_builtin_decls[RS6000_BIF_VEC_EXT_V16QI];
	      break;

	    default:
	      break;
	    }
	}

      if (call)
	{
	  tree result = build_call_expr (call, 2, arg1, arg2);
	  /* Coerce the result to vector element type.  May be no-op.  */
	  arg1_inner_type = TREE_TYPE (arg1_type);
	  result = fold_convert (arg1_inner_type, result);
	  *res = resolved;
	  return result;
	}
    }

  /* Build *(((arg1_inner_type*) & (vector type){arg1}) + arg2). */
  arg1_inner_type = TREE_TYPE (arg1_type);
  tree subp = build_int_cst (TREE_TYPE (arg2),
			     TYPE_VECTOR_SUBPARTS (arg1_type) - 1);
  arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, subp, 0);

  tree decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
  DECL_EXTERNAL (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  DECL_CONTEXT (decl) = current_function_decl;
  TREE_USED (decl) = 1;
  TREE_TYPE (decl) = arg1_type;
  TREE_READONLY (decl) = TYPE_READONLY (arg1_type);

  tree stmt;
  if (c_dialect_cxx ())
    {
      stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, NULL_TREE, NULL_TREE);
      SET_EXPR_LOCATION (stmt, loc);
    }
  else
    {
      DECL_INITIAL (decl) = arg1;
      stmt = build1 (DECL_EXPR, arg1_type, decl);
      TREE_ADDRESSABLE (decl) = 1;
      SET_EXPR_LOCATION (stmt, loc);
      stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
    }

  tree innerptrtype = build_pointer_type (arg1_inner_type);
  stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
  stmt = convert (innerptrtype, stmt);
  stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
  stmt = build_indirect_ref (loc, stmt, RO_NULL);

  /* PR83660: We mark this as having side effects so that downstream in
     fold_build_cleanup_point_expr () it will get a CLEANUP_POINT_EXPR.  If it
     does not we can run into an ICE later in gimplify_cleanup_point_expr ().
     Potentially this causes missed optimization because there actually is no
     side effect.  */
  if (c_dialect_cxx ())
    TREE_SIDE_EFFECTS (stmt) = 1;

  *res = resolved;
  return stmt;
}

/* Resolve an overloaded vec_insert call and return a tree expression for
   the resolved call if successful.  NARGS is the number of arguments to
   the call.  ARGLIST contains the arguments.  RES must be set to indicate
   the status of the resolution attempt.  LOC contains statement location
   information.  */

static tree
resolve_vec_insert (resolution *res, vec<tree, va_gc> *arglist,
		    unsigned nargs, location_t loc)
{
  if (nargs != 3)
    {
      error ("builtin %qs only accepts 3 arguments", "vec_insert");
      *res = resolved;
      return error_mark_node;
    }

  tree arg0 = (*arglist)[0];
  tree arg1 = (*arglist)[1];
  tree arg1_type = TREE_TYPE (arg1);
  tree arg2 = fold_for_warn ((*arglist)[2]);

  if (TREE_CODE (arg1_type) != VECTOR_TYPE
      || !INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  /* If we can use the VSX xxpermdi instruction, use that for insert.  */
  machine_mode mode = TYPE_MODE (arg1_type);

  if ((mode == V2DFmode || mode == V2DImode)
      && VECTOR_UNIT_VSX_P (mode)
      && TREE_CODE (arg2) == INTEGER_CST)
    {
      wide_int selector = wi::to_wide (arg2);
      selector = wi::umod_trunc (selector, 2);
      arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);

      tree call = NULL_TREE;
      if (mode == V2DFmode)
	call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V2DF];
      else if (mode == V2DImode)
	call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V2DI];

      /* Note, __builtin_vec_insert_<xxx> has vector and scalar types
	 reversed.  */
      if (call)
	{
	  *res = resolved;
	  return build_call_expr (call, 3, arg1, arg0, arg2);
	}
    }

  else if (mode == V1TImode
	   && VECTOR_UNIT_VSX_P (mode)
	   && TREE_CODE (arg2) == INTEGER_CST)
    {
      tree call = rs6000_builtin_decls[RS6000_BIF_VEC_SET_V1TI];
      wide_int selector = wi::zero(32);
      arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);

      /* Note, __builtin_vec_insert_<xxx> has vector and scalar types
	 reversed.  */
      *res = resolved;
      return build_call_expr (call, 3, arg1, arg0, arg2);
    }

  /* Build *(((arg1_inner_type*) & (vector type){arg1}) + arg2) = arg0 with
     VIEW_CONVERT_EXPR.  i.e.:
       D.3192 = v1;
       _1 = n & 3;
       VIEW_CONVERT_EXPR<int[4]>(D.3192)[_1] = i;
       v1 = D.3192;
       D.3194 = v1;  */
  if (TYPE_VECTOR_SUBPARTS (arg1_type) == 1)
    arg2 = build_int_cst (TREE_TYPE (arg2), 0);
  else
    {
      tree c = build_int_cst (TREE_TYPE (arg2),
			      TYPE_VECTOR_SUBPARTS (arg1_type) - 1);
      arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2, c, 0);
    }

  tree decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
  DECL_EXTERNAL (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  DECL_CONTEXT (decl) = current_function_decl;
  TREE_USED (decl) = 1;
  TREE_TYPE (decl) = arg1_type;
  TREE_READONLY (decl) = TYPE_READONLY (arg1_type);
  TREE_ADDRESSABLE (decl) = 1;

  tree stmt;
  if (c_dialect_cxx ())
    {
      stmt = build4 (TARGET_EXPR, arg1_type, decl, arg1, NULL_TREE, NULL_TREE);
      SET_EXPR_LOCATION (stmt, loc);
    }
  else
    {
      DECL_INITIAL (decl) = arg1;
      stmt = build1 (DECL_EXPR, arg1_type, decl);
      SET_EXPR_LOCATION (stmt, loc);
      stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
    }

  if (TARGET_VSX)
    {
      stmt = build_array_ref (loc, stmt, arg2);
      stmt = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg0), stmt,
			  convert (TREE_TYPE (stmt), arg0));
      stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
    }
  else
    {
      tree arg1_inner_type = TREE_TYPE (arg1_type);
      tree innerptrtype = build_pointer_type (arg1_inner_type);
      stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
      stmt = convert (innerptrtype, stmt);
      stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
      stmt = build_indirect_ref (loc, stmt, RO_NULL);
      stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
		     convert (TREE_TYPE (stmt), arg0));
      stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
    }

  *res = resolved;
  return stmt;
}

/* Resolve an overloaded vec_step call and return a tree expression for
   the resolved call if successful.  NARGS is the number of arguments to
   the call.  ARGLIST contains the arguments.  RES must be set to indicate
   the status of the resolution attempt.  */

static tree
resolve_vec_step (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs)
{
  if (nargs != 1)
    {
      error ("builtin %qs only accepts 1 argument", "vec_step");
      *res = resolved;
      return error_mark_node;
    }

  tree arg0 = (*arglist)[0];
  tree arg0_type = TREE_TYPE (arg0);

  if (TREE_CODE (arg0_type) != VECTOR_TYPE)
    {
      *res = resolved_bad;
      return error_mark_node;
    }

  *res = resolved;
  return build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (arg0_type));
}

/* Look for a matching instance in a chain of instances.  INSTANCE points to
   the chain of instances; INSTANCE_CODE is the code identifying the specific
   built-in being searched for; FCODE is the overloaded function code; TYPES
   contains an array of two types that must match the types of the instance's
   parameters; and ARGS contains an array of two arguments to be passed to
   the instance.  If found, resolve the built-in and return it, unless the
   built-in is not supported in context.  In that case, set
   UNSUPPORTED_BUILTIN to true.  If we don't match, return error_mark_node
   and leave UNSUPPORTED_BUILTIN alone.  */

tree
find_instance (bool *unsupported_builtin, ovlddata **instance,
	       rs6000_gen_builtins instance_code,
	       rs6000_gen_builtins fcode,
	       tree *types, tree *args)
{
  while (*instance && (*instance)->bifid != instance_code)
    *instance = (*instance)->next;

  ovlddata *inst = *instance;
  gcc_assert (inst != NULL);
  tree fntype = rs6000_builtin_info[inst->bifid].fntype;
  tree parmtype0 = TREE_VALUE (TYPE_ARG_TYPES (fntype));
  tree parmtype1 = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (fntype)));

  if (rs6000_builtin_type_compatible (types[0], parmtype0)
      && rs6000_builtin_type_compatible (types[1], parmtype1))
    {
      if (rs6000_builtin_decl (inst->bifid, false) != error_mark_node
	  && rs6000_builtin_is_supported (inst->bifid))
	{
	  tree ret_type = TREE_TYPE (inst->fntype);
	  return altivec_build_resolved_builtin (args, 2, fntype, ret_type,
						 inst->bifid, fcode);
	}
      else
	*unsupported_builtin = true;
    }

  return error_mark_node;
}

/* Implementation of the resolve_overloaded_builtin target hook, to
   support Altivec's overloaded builtins.  */

tree
altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
				    void *passed_arglist)
{
  rs6000_gen_builtins fcode
    = (rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);

  /* Return immediately if this isn't an overload.  */
  if (fcode <= RS6000_OVLD_NONE)
    return NULL_TREE;

  if (TARGET_DEBUG_BUILTIN)
    fprintf (stderr, "altivec_resolve_overloaded_builtin, code = %4d, %s\n",
	     (int) fcode, IDENTIFIER_POINTER (DECL_NAME (fndecl)));

  /* vec_lvsl and vec_lvsr are deprecated for use with LE element order.  */
  if (fcode == RS6000_OVLD_VEC_LVSL && !BYTES_BIG_ENDIAN)
    warning (OPT_Wdeprecated,
	     "%<vec_lvsl%> is deprecated for little endian; use "
	     "assignment for unaligned loads and stores");
  else if (fcode == RS6000_OVLD_VEC_LVSR && !BYTES_BIG_ENDIAN)
    warning (OPT_Wdeprecated,
	     "%<vec_lvsr%> is deprecated for little endian; use "
	     "assignment for unaligned loads and stores");

  /* Gather the arguments and their types into arrays for easier handling.  */
  tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
  tree types[MAX_OVLD_ARGS];
  tree args[MAX_OVLD_ARGS];
  unsigned int n;

  /* Count the number of expected arguments.  */
  unsigned expected_args = 0;
  for (tree chain = fnargs;
       chain && !VOID_TYPE_P (TREE_VALUE (chain));
       chain = TREE_CHAIN (chain))
    expected_args++;

  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
  unsigned int nargs = vec_safe_length (arglist);

  for (n = 0;
       !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs;
       fnargs = TREE_CHAIN (fnargs), n++)
    {
      tree decl_type = TREE_VALUE (fnargs);
      tree arg = (*arglist)[n];

      if (arg == error_mark_node)
	return error_mark_node;

      if (n >= MAX_OVLD_ARGS)
	abort ();

      arg = default_conversion (arg);
      tree type = TREE_TYPE (arg);

      /* The C++ front-end converts float * to const void * using
	 NOP_EXPR<const void *> (NOP_EXPR<void *> (x)).  */
      if (POINTER_TYPE_P (type)
	  && TREE_CODE (arg) == NOP_EXPR
	  && lang_hooks.types_compatible_p (TREE_TYPE (arg),
					    const_ptr_type_node)
	  && lang_hooks.types_compatible_p (TREE_TYPE (TREE_OPERAND (arg, 0)),
					    ptr_type_node))
	{
	  arg = TREE_OPERAND (arg, 0);
	  type = TREE_TYPE (arg);
	}

      /* Remove the const from the pointers to simplify the overload
	 matching further down.  */
      if (POINTER_TYPE_P (decl_type)
	  && POINTER_TYPE_P (type)
	  && TYPE_QUALS (TREE_TYPE (type)) != 0)
	{
	  if (TYPE_READONLY (TREE_TYPE (type))
	      && !TYPE_READONLY (TREE_TYPE (decl_type)))
	    warning (0, "passing argument %d of %qE discards const qualifier "
		     "from pointer target type", n + 1, fndecl);
	  type = build_qualified_type (TREE_TYPE (type), 0);
	  type = build_pointer_type (type);
	  arg = fold_convert (type, arg);
	}

      /* For RS6000_OVLD_VEC_LXVL, convert any const * to its non constant
	 equivalent to simplify the overload matching below.  */
      if (fcode == RS6000_OVLD_VEC_LXVL
	  && POINTER_TYPE_P (type)
	  && TYPE_READONLY (TREE_TYPE (type)))
	{
	  type = build_qualified_type (TREE_TYPE (type), 0);
	  type = build_pointer_type (type);
	  arg = fold_convert (type, arg);
	}

      args[n] = arg;
      types[n] = type;
    }

  /* If the number of arguments did not match the prototype, return NULL
     and the generic code will issue the appropriate error message.  Skip
     this test for functions where we don't fully describe all the possible
     overload signatures in rs6000-overload.def (because they aren't relevant
     to the expansion here).  If we don't, we get confusing error messages.  */
  /* As an example, for vec_splats we have:

; There are no actual builtins for vec_splats.  There is special handling for
; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
; is replaced by a constructor.  The single overload here causes
; __builtin_vec_splats to be registered with the front end so that can happen.
[VEC_SPLATS, vec_splats, __builtin_vec_splats]
  vsi __builtin_vec_splats (vsi);
    ABS_V4SI SPLATS_FAKERY

    So even though __builtin_vec_splats accepts all vector types, the
    infrastructure cheats and just records one prototype.  We end up getting
    an error message that refers to this specific prototype even when we
    are handling a different argument type.  That is completely confusing
    to the user, so it's best to let these cases be handled individually
    in the resolve_vec_splats, etc., helper functions.  */

  if (n != expected_args
      && !(fcode == RS6000_OVLD_VEC_PROMOTE
	   || fcode == RS6000_OVLD_VEC_SPLATS
	   || fcode == RS6000_OVLD_VEC_EXTRACT
	   || fcode == RS6000_OVLD_VEC_INSERT
	   || fcode == RS6000_OVLD_VEC_STEP))
    return NULL;

  /* Some overloads require special handling.  */
  tree returned_expr = NULL;
  resolution res = unresolved;

  if (fcode == RS6000_OVLD_VEC_MUL)
    returned_expr = resolve_vec_mul (&res, args, types, loc);
  else if (fcode == RS6000_OVLD_VEC_CMPNE)
    returned_expr = resolve_vec_cmpne (&res, args, types, loc);
  else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
    returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
  else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
    returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
  else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
    returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
  else if (fcode == RS6000_OVLD_VEC_EXTRACT)
    returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
  else if (fcode == RS6000_OVLD_VEC_INSERT)
    returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
  else if (fcode == RS6000_OVLD_VEC_STEP)
    returned_expr = resolve_vec_step (&res, arglist, nargs);

  if (res == resolved)
    return returned_expr;

  /* "Regular" built-in functions and overloaded functions share a namespace
     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
     only has information for the overloaded functions, so we need an
     adjusted index for that.  */
  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;

  if (res == resolved_bad)
    {
      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
      return error_mark_node;
    }

  bool unsupported_builtin = false;
  rs6000_gen_builtins instance_code;
  bool supported = false;
  ovlddata *instance = rs6000_overload_info[adj_fcode].first_instance;
  gcc_assert (instance != NULL);

  /* Functions with no arguments can have only one overloaded instance.  */
  gcc_assert (nargs > 0 || !instance->next);

  /* Standard overload processing involves determining whether an instance
     exists that is type-compatible with the overloaded function call.  In
     a couple of cases, we need to do some extra processing to disambiguate
     between multiple compatible instances.  */
  switch (fcode)
    {
      /* Need to special case __builtin_cmpb because the overloaded forms
	 of this function take (unsigned int, unsigned int) or (unsigned
	 long long int, unsigned long long int).  Since C conventions
	 allow the respective argument types to be implicitly coerced into
	 each other, the default handling does not provide adequate
	 discrimination between the desired forms of the function.  */
    case RS6000_OVLD_SCAL_CMPB:
      {
	machine_mode arg1_mode = TYPE_MODE (types[0]);
	machine_mode arg2_mode = TYPE_MODE (types[1]);

	/* If any supplied arguments are wider than 32 bits, resolve to
	   64-bit variant of built-in function.  */
	if (GET_MODE_PRECISION (arg1_mode) > 32
	    || GET_MODE_PRECISION (arg2_mode) > 32)
	  /* Assure all argument and result types are compatible with
	     the built-in function represented by RS6000_BIF_CMPB.  */
	  instance_code = RS6000_BIF_CMPB;
	else
	  /* Assure all argument and result types are compatible with
	     the built-in function represented by RS6000_BIF_CMPB_32.  */
	  instance_code = RS6000_BIF_CMPB_32;

	tree call = find_instance (&unsupported_builtin, &instance,
				   instance_code, fcode, types, args);
	if (call != error_mark_node)
	  return call;
	break;
      }
    case RS6000_OVLD_VEC_VSIE:
      {
	machine_mode arg1_mode = TYPE_MODE (types[0]);

	/* If supplied first argument is wider than 64 bits, resolve to
	   128-bit variant of built-in function.  */
	if (GET_MODE_PRECISION (arg1_mode) > 64)
	  {
	    /* If first argument is of float variety, choose variant
	       that expects __ieee128 argument.  Otherwise, expect
	       __int128 argument.  */
	    if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
	      instance_code = RS6000_BIF_VSIEQPF;
	    else
	      instance_code = RS6000_BIF_VSIEQP;
	  }
	else
	  {
	    /* If first argument is of float variety, choose variant
	       that expects double argument.  Otherwise, expect
	       long long int argument.  */
	    if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT)
	      instance_code = RS6000_BIF_VSIEDPF;
	    else
	      instance_code = RS6000_BIF_VSIEDP;
	  }

	tree call = find_instance (&unsupported_builtin, &instance,
				   instance_code, fcode, types, args);
	if (call != error_mark_node)
	  return call;
	break;
      }
    default:
      /* Standard overload processing.  Look for an instance with compatible
	 parameter types.  If it is supported in the current context, resolve
	 the overloaded call to that instance.  */
      for (; instance != NULL; instance = instance->next)
	{
	  /* It is possible for an instance to require a data type that isn't
	     defined on this target, in which case instance->fntype will be
	     NULL.  */
	  if (!instance->fntype)
	    continue;

	  bool mismatch = false;
	  tree nextparm = TYPE_ARG_TYPES (instance->fntype);

	  for (unsigned int arg_i = 0;
	       arg_i < nargs && nextparm != NULL;
	       arg_i++)
	    {
	      tree parmtype = TREE_VALUE (nextparm);
	      if (!rs6000_builtin_type_compatible (types[arg_i], parmtype))
		{
		  mismatch = true;
		  break;
		}
	      nextparm = TREE_CHAIN (nextparm);
	    }

	  if (mismatch)
	    continue;

	  supported = rs6000_builtin_is_supported (instance->bifid);
	  if (rs6000_builtin_decl (instance->bifid, false) != error_mark_node
	      && supported)
	    {
	      tree fntype = rs6000_builtin_info[instance->bifid].fntype;
	      tree ret_type = TREE_TYPE (instance->fntype);
	      return altivec_build_resolved_builtin (args, nargs, fntype,
						     ret_type, instance->bifid,
						     fcode);
	    }
	  else
	    {
	      unsupported_builtin = true;
	      break;
	    }
	}
    }

  if (unsupported_builtin)
    {
      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
      if (!supported)
	{
	  /* Indicate that the instantiation of the overloaded builtin
	     name is not available with the target flags in effect.  */
	  rs6000_gen_builtins fcode = (rs6000_gen_builtins) instance->bifid;
	  rs6000_invalid_builtin (fcode);
	  /* Provide clarity of the relationship between the overload
	     and the instantiation.  */
	  const char *internal_name
	    = rs6000_builtin_info[instance->bifid].bifname;
	  rich_location richloc (line_table, input_location);
	  inform (&richloc,
		  "overloaded builtin %qs is implemented by builtin %qs",
		  name, internal_name);
	}
      else
	error ("%qs is not supported in this compiler configuration", name);

      return error_mark_node;
    }

  /* If we fall through to here, there were no compatible instances.  */
  const char *name = rs6000_overload_info[adj_fcode].ovld_name;
  error ("invalid parameter combination for AltiVec intrinsic %qs", name);
  return error_mark_node;
}
