/* Convert function calls to rtl insns, for GNU C compiler.
   Copyright (C) 1989-2021 Free Software Foundation, Inc.

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "expmed.h"
#include "optabs.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "internal-fn.h"
#include "dojump.h"
#include "explow.h"
#include "calls.h"
#include "expr.h"
#include "output.h"
#include "langhooks.h"
#include "except.h"
#include "dbgcnt.h"
#include "rtl-iter.h"
#include "tree-vrp.h"
#include "tree-ssanames.h"
#include "intl.h"
#include "stringpool.h"
#include "hash-map.h"
#include "hash-traits.h"
#include "attribs.h"
#include "builtins.h"
#include "gimple-fold.h"
#include "attr-fnspec.h"
#include "value-query.h"
#include "tree-pretty-print.h"

/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits.  */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)

/* Data structure and subroutines used within expand_call.  */

struct arg_data
{
  /* Tree node for this argument.  */
  tree tree_value;
  /* Mode for value; TYPE_MODE unless promoted.  */
  machine_mode mode;
  /* Current RTL value for argument, or 0 if it isn't precomputed.  */
  rtx value;
  /* Initially-compute RTL value for argument; only for const functions.  */
  rtx initial_value;
  /* Register to pass this argument in, 0 if passed on stack, or an
     PARALLEL if the arg is to be copied into multiple non-contiguous
     registers.  */
  rtx reg;
  /* Register to pass this argument in when generating tail call sequence.
     This is not the same register as for normal calls on machines with
     register windows.  */
  rtx tail_call_reg;
  /* If REG is a PARALLEL, this is a copy of VALUE pulled into the correct
     form for emit_group_move.  */
  rtx parallel_value;
  /* If REG was promoted from the actual mode of the argument expression,
     indicates whether the promotion is sign- or zero-extended.  */
  int unsignedp;
  /* Number of bytes to put in registers.  0 means put the whole arg
     in registers.  Also 0 if not passed in registers.  */
  int partial;
  /* Nonzero if argument must be passed on stack.
     Note that some arguments may be passed on the stack
     even though pass_on_stack is zero, just because FUNCTION_ARG says so.
     pass_on_stack identifies arguments that *cannot* go in registers.  */
  int pass_on_stack;
  /* Some fields packaged up for locate_and_pad_parm.  */
  struct locate_and_pad_arg_data locate;
  /* Location on the stack at which parameter should be stored.  The store
     has already been done if STACK == VALUE.  */
  rtx stack;
  /* Location on the stack of the start of this argument slot.  This can
     differ from STACK if this arg pads downward.  This location is known
     to be aligned to TARGET_FUNCTION_ARG_BOUNDARY.  */
  rtx stack_slot;
  /* Place that this stack area has been saved, if needed.  */
  rtx save_area;
  /* If an argument's alignment does not permit direct copying into registers,
     copy in smaller-sized pieces into pseudos.  These are stored in a
     block pointed to by this field.  The next field says how many
     word-sized pseudos we made.  */
  rtx *aligned_regs;
  int n_aligned_regs;
};

/* A vector of one char per byte of stack space.  A byte if nonzero if
   the corresponding stack location has been used.
   This vector is used to prevent a function call within an argument from
   clobbering any stack already set up.  */
static char *stack_usage_map;

/* Size of STACK_USAGE_MAP.  */
static unsigned int highest_outgoing_arg_in_use;

/* Assume that any stack location at this byte index is used,
   without checking the contents of stack_usage_map.  */
static unsigned HOST_WIDE_INT stack_usage_watermark = HOST_WIDE_INT_M1U;

/* A bitmap of virtual-incoming stack space.  Bit is set if the corresponding
   stack location's tail call argument has been already stored into the stack.
   This bitmap is used to prevent sibling call optimization if function tries
   to use parent's incoming argument slots when they have been already
   overwritten with tail call arguments.  */
static sbitmap stored_args_map;

/* Assume that any virtual-incoming location at this byte index has been
   stored, without checking the contents of stored_args_map.  */
static unsigned HOST_WIDE_INT stored_args_watermark;

/* stack_arg_under_construction is nonzero when an argument may be
   initialized with a constructor call (including a C function that
   returns a BLKmode struct) and expand_call must take special action
   to make sure the object being constructed does not overlap the
   argument list for the constructor call.  */
static int stack_arg_under_construction;

static void precompute_register_parameters (int, struct arg_data *, int *);
static int store_one_arg (struct arg_data *, rtx, int, int, int);
static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
static int finalize_must_preallocate (int, int, struct arg_data *,
				      struct args_size *);
static void precompute_arguments (int, struct arg_data *);
static void compute_argument_addresses (struct arg_data *, rtx, int);
static rtx rtx_for_function_call (tree, tree);
static void load_register_parameters (struct arg_data *, int, rtx *, int,
				      int, int *);
static int special_function_p (const_tree, int);
static int check_sibcall_argument_overlap_1 (rtx);
static int check_sibcall_argument_overlap (rtx_insn *, struct arg_data *, int);

static tree split_complex_types (tree);

#ifdef REG_PARM_STACK_SPACE
static rtx save_fixed_argument_area (int, rtx, int *, int *);
static void restore_fixed_argument_area (rtx, rtx, int, int);
#endif

/* Return true if bytes [LOWER_BOUND, UPPER_BOUND) of the outgoing
   stack region might already be in use.  */

static bool
stack_region_maybe_used_p (poly_uint64 lower_bound, poly_uint64 upper_bound,
			   unsigned int reg_parm_stack_space)
{
  unsigned HOST_WIDE_INT const_lower, const_upper;
  const_lower = constant_lower_bound (lower_bound);
  if (!upper_bound.is_constant (&const_upper))
    const_upper = HOST_WIDE_INT_M1U;

  if (const_upper > stack_usage_watermark)
    return true;

  /* Don't worry about things in the fixed argument area;
     it has already been saved.  */
  const_lower = MAX (const_lower, reg_parm_stack_space);
  const_upper = MIN (const_upper, highest_outgoing_arg_in_use);
  for (unsigned HOST_WIDE_INT i = const_lower; i < const_upper; ++i)
    if (stack_usage_map[i])
      return true;
  return false;
}

/* Record that bytes [LOWER_BOUND, UPPER_BOUND) of the outgoing
   stack region are now in use.  */

static void
mark_stack_region_used (poly_uint64 lower_bound, poly_uint64 upper_bound)
{
  unsigned HOST_WIDE_INT const_lower, const_upper;
  const_lower = constant_lower_bound (lower_bound);
  if (upper_bound.is_constant (&const_upper))
    for (unsigned HOST_WIDE_INT i = const_lower; i < const_upper; ++i)
      stack_usage_map[i] = 1;
  else
    stack_usage_watermark = MIN (stack_usage_watermark, const_lower);
}

/* Force FUNEXP into a form suitable for the address of a CALL,
   and return that as an rtx.  Also load the static chain register
   if FNDECL is a nested function.

   CALL_FUSAGE points to a variable holding the prospective
   CALL_INSN_FUNCTION_USAGE information.  */

rtx
prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value,
		      rtx *call_fusage, int reg_parm_seen, int flags)
{
  /* Make a valid memory address and copy constants through pseudo-regs,
     but not for a constant address if -fno-function-cse.  */
  if (GET_CODE (funexp) != SYMBOL_REF)
    {
      /* If it's an indirect call by descriptor, generate code to perform
	 runtime identification of the pointer and load the descriptor.  */
      if ((flags & ECF_BY_DESCRIPTOR) && !flag_trampolines)
	{
	  const int bit_val = targetm.calls.custom_function_descriptors;
	  rtx call_lab = gen_label_rtx ();

	  gcc_assert (fndecl_or_type && TYPE_P (fndecl_or_type));
	  fndecl_or_type
	    = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, NULL_TREE,
			  fndecl_or_type);
	  DECL_STATIC_CHAIN (fndecl_or_type) = 1;
	  rtx chain = targetm.calls.static_chain (fndecl_or_type, false);

	  if (GET_MODE (funexp) != Pmode)
	    funexp = convert_memory_address (Pmode, funexp);

	  /* Avoid long live ranges around function calls.  */
	  funexp = copy_to_mode_reg (Pmode, funexp);

	  if (REG_P (chain))
	    emit_insn (gen_rtx_CLOBBER (VOIDmode, chain));

	  /* Emit the runtime identification pattern.  */
	  rtx mask = gen_rtx_AND (Pmode, funexp, GEN_INT (bit_val));
	  emit_cmp_and_jump_insns (mask, const0_rtx, EQ, NULL_RTX, Pmode, 1,
				   call_lab);

	  /* Statically predict the branch to very likely taken.  */
	  rtx_insn *insn = get_last_insn ();
	  if (JUMP_P (insn))
	    predict_insn_def (insn, PRED_BUILTIN_EXPECT, TAKEN);

	  /* Load the descriptor.  */
	  rtx mem = gen_rtx_MEM (ptr_mode,
				 plus_constant (Pmode, funexp, - bit_val));
	  MEM_NOTRAP_P (mem) = 1;
	  mem = convert_memory_address (Pmode, mem);
	  emit_move_insn (chain, mem);

	  mem = gen_rtx_MEM (ptr_mode,
			     plus_constant (Pmode, funexp,
					    POINTER_SIZE / BITS_PER_UNIT
					      - bit_val));
	  MEM_NOTRAP_P (mem) = 1;
	  mem = convert_memory_address (Pmode, mem);
	  emit_move_insn (funexp, mem);

	  emit_label (call_lab);

	  if (REG_P (chain))
	    {
	      use_reg (call_fusage, chain);
	      STATIC_CHAIN_REG_P (chain) = 1;
	    }

	  /* Make sure we're not going to be overwritten below.  */
	  gcc_assert (!static_chain_value);
	}

      /* If we are using registers for parameters, force the
	 function address into a register now.  */
      funexp = ((reg_parm_seen
		 && targetm.small_register_classes_for_mode_p (FUNCTION_MODE))
		 ? force_not_mem (memory_address (FUNCTION_MODE, funexp))
		 : memory_address (FUNCTION_MODE, funexp));
    }
  else
    {
      /* funexp could be a SYMBOL_REF represents a function pointer which is
	 of ptr_mode.  In this case, it should be converted into address mode
	 to be a valid address for memory rtx pattern.  See PR 64971.  */
      if (GET_MODE (funexp) != Pmode)
	funexp = convert_memory_address (Pmode, funexp);

      if (!(flags & ECF_SIBCALL))
	{
	  if (!NO_FUNCTION_CSE && optimize && ! flag_no_function_cse)
	    funexp = force_reg (Pmode, funexp);
	}
    }

  if (static_chain_value != 0
      && (TREE_CODE (fndecl_or_type) != FUNCTION_DECL
	  || DECL_STATIC_CHAIN (fndecl_or_type)))
    {
      rtx chain;

      chain = targetm.calls.static_chain (fndecl_or_type, false);
      static_chain_value = convert_memory_address (Pmode, static_chain_value);

      emit_move_insn (chain, static_chain_value);
      if (REG_P (chain))
	{
	  use_reg (call_fusage, chain);
	  STATIC_CHAIN_REG_P (chain) = 1;
	}
    }

  return funexp;
}

/* Generate instructions to call function FUNEXP,
   and optionally pop the results.
   The CALL_INSN is the first insn generated.

   FNDECL is the declaration node of the function.  This is given to the
   hook TARGET_RETURN_POPS_ARGS to determine whether this function pops
   its own args.

   FUNTYPE is the data type of the function.  This is given to the hook
   TARGET_RETURN_POPS_ARGS to determine whether this function pops its
   own args.  We used to allow an identifier for library functions, but
   that doesn't work when the return type is an aggregate type and the
   calling convention says that the pointer to this aggregate is to be
   popped by the callee.

   STACK_SIZE is the number of bytes of arguments on the stack,
   ROUNDED_STACK_SIZE is that number rounded up to
   PREFERRED_STACK_BOUNDARY; zero if the size is variable.  This is
   both to put into the call insn and to generate explicit popping
   code if necessary.

   STRUCT_VALUE_SIZE is the number of bytes wanted in a structure value.
   It is zero if this call doesn't want a structure value.

   NEXT_ARG_REG is the rtx that results from executing
     targetm.calls.function_arg (&args_so_far,
				 function_arg_info::end_marker ());
   just after all the args have had their registers assigned.
   This could be whatever you like, but normally it is the first
   arg-register beyond those used for args in this call,
   or 0 if all the arg-registers are used in this call.
   It is passed on to `gen_call' so you can put this info in the call insn.

   VALREG is a hard register in which a value is returned,
   or 0 if the call does not return a value.

   OLD_INHIBIT_DEFER_POP is the value that `inhibit_defer_pop' had before
   the args to this call were processed.
   We restore `inhibit_defer_pop' to that value.

   CALL_FUSAGE is either empty or an EXPR_LIST of USE expressions that
   denote registers used by the called function.  */

static void
emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNUSED,
	     tree funtype ATTRIBUTE_UNUSED,
	     poly_int64 stack_size ATTRIBUTE_UNUSED,
	     poly_int64 rounded_stack_size,
	     poly_int64 struct_value_size ATTRIBUTE_UNUSED,
	     rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg,
	     int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags,
	     cumulative_args_t args_so_far ATTRIBUTE_UNUSED)
{
  rtx rounded_stack_size_rtx = gen_int_mode (rounded_stack_size, Pmode);
  rtx call, funmem, pat;
  int already_popped = 0;
  poly_int64 n_popped = 0;

  /* Sibling call patterns never pop arguments (no sibcall(_value)_pop
     patterns exist).  Any popping that the callee does on return will
     be from our caller's frame rather than ours.  */
  if (!(ecf_flags & ECF_SIBCALL))
    {
      n_popped += targetm.calls.return_pops_args (fndecl, funtype, stack_size);

#ifdef CALL_POPS_ARGS
      n_popped += CALL_POPS_ARGS (*get_cumulative_args (args_so_far));
#endif
    }

  /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
     and we don't want to load it into a register as an optimization,
     because prepare_call_address already did it if it should be done.  */
  if (GET_CODE (funexp) != SYMBOL_REF)
    funexp = memory_address (FUNCTION_MODE, funexp);

  funmem = gen_rtx_MEM (FUNCTION_MODE, funexp);
  if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL)
    {
      tree t = fndecl;

      /* Although a built-in FUNCTION_DECL and its non-__builtin
	 counterpart compare equal and get a shared mem_attrs, they
	 produce different dump output in compare-debug compilations,
	 if an entry gets garbage collected in one compilation, then
	 adds a different (but equivalent) entry, while the other
	 doesn't run the garbage collector at the same spot and then
	 shares the mem_attr with the equivalent entry. */
      if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
	{
	  tree t2 = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
	  if (t2)
	    t = t2;
	}

	set_mem_expr (funmem, t);
    }
  else if (fntree)
    set_mem_expr (funmem, build_simple_mem_ref (CALL_EXPR_FN (fntree)));

  if (ecf_flags & ECF_SIBCALL)
    {
      if (valreg)
	pat = targetm.gen_sibcall_value (valreg, funmem,
					 rounded_stack_size_rtx,
					 next_arg_reg, NULL_RTX);
      else
	pat = targetm.gen_sibcall (funmem, rounded_stack_size_rtx,
				   next_arg_reg,
				   gen_int_mode (struct_value_size, Pmode));
    }
  /* If the target has "call" or "call_value" insns, then prefer them
     if no arguments are actually popped.  If the target does not have
     "call" or "call_value" insns, then we must use the popping versions
     even if the call has no arguments to pop.  */
  else if (maybe_ne (n_popped, 0)
	   || !(valreg
		? targetm.have_call_value ()
		: targetm.have_call ()))
    {
      rtx n_pop = gen_int_mode (n_popped, Pmode);

      /* If this subroutine pops its own args, record that in the call insn
	 if possible, for the sake of frame pointer elimination.  */

      if (valreg)
	pat = targetm.gen_call_value_pop (valreg, funmem,
					  rounded_stack_size_rtx,
					  next_arg_reg, n_pop);
      else
	pat = targetm.gen_call_pop (funmem, rounded_stack_size_rtx,
				    next_arg_reg, n_pop);

      already_popped = 1;
    }
  else
    {
      if (valreg)
	pat = targetm.gen_call_value (valreg, funmem, rounded_stack_size_rtx,
				      next_arg_reg, NULL_RTX);
      else
	pat = targetm.gen_call (funmem, rounded_stack_size_rtx, next_arg_reg,
				gen_int_mode (struct_value_size, Pmode));
    }
  emit_insn (pat);

  /* Find the call we just emitted.  */
  rtx_call_insn *call_insn = last_call_insn ();

  /* Some target create a fresh MEM instead of reusing the one provided
     above.  Set its MEM_EXPR.  */
  call = get_call_rtx_from (call_insn);
  if (call
      && MEM_EXPR (XEXP (call, 0)) == NULL_TREE
      && MEM_EXPR (funmem) != NULL_TREE)
    set_mem_expr (XEXP (call, 0), MEM_EXPR (funmem));

  /* Put the register usage information there.  */
  add_function_usage_to (call_insn, call_fusage);

  /* If this is a const call, then set the insn's unchanging bit.  */
  if (ecf_flags & ECF_CONST)
    RTL_CONST_CALL_P (call_insn) = 1;

  /* If this is a pure call, then set the insn's unchanging bit.  */
  if (ecf_flags & ECF_PURE)
    RTL_PURE_CALL_P (call_insn) = 1;

  /* If this is a const call, then set the insn's unchanging bit.  */
  if (ecf_flags & ECF_LOOPING_CONST_OR_PURE)
    RTL_LOOPING_CONST_OR_PURE_CALL_P (call_insn) = 1;

  /* Create a nothrow REG_EH_REGION note, if needed.  */
  make_reg_eh_region_note (call_insn, ecf_flags, 0);

  if (ecf_flags & ECF_NORETURN)
    add_reg_note (call_insn, REG_NORETURN, const0_rtx);

  if (ecf_flags & ECF_RETURNS_TWICE)
    {
      add_reg_note (call_insn, REG_SETJMP, const0_rtx);
      cfun->calls_setjmp = 1;
    }

  SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);

  /* Restore this now, so that we do defer pops for this call's args
     if the context of the call as a whole permits.  */
  inhibit_defer_pop = old_inhibit_defer_pop;

  if (maybe_ne (n_popped, 0))
    {
      if (!already_popped)
	CALL_INSN_FUNCTION_USAGE (call_insn)
	  = gen_rtx_EXPR_LIST (VOIDmode,
			       gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx),
			       CALL_INSN_FUNCTION_USAGE (call_insn));
      rounded_stack_size -= n_popped;
      rounded_stack_size_rtx = gen_int_mode (rounded_stack_size, Pmode);
      stack_pointer_delta -= n_popped;

      add_args_size_note (call_insn, stack_pointer_delta);

      /* If popup is needed, stack realign must use DRAP  */
      if (SUPPORTS_STACK_ALIGNMENT)
        crtl->need_drap = true;
    }
  /* For noreturn calls when not accumulating outgoing args force
     REG_ARGS_SIZE note to prevent crossjumping of calls with different
     args sizes.  */
  else if (!ACCUMULATE_OUTGOING_ARGS && (ecf_flags & ECF_NORETURN) != 0)
    add_args_size_note (call_insn, stack_pointer_delta);

  if (!ACCUMULATE_OUTGOING_ARGS)
    {
      /* If returning from the subroutine does not automatically pop the args,
	 we need an instruction to pop them sooner or later.
	 Perhaps do it now; perhaps just record how much space to pop later.

	 If returning from the subroutine does pop the args, indicate that the
	 stack pointer will be changed.  */

      if (maybe_ne (rounded_stack_size, 0))
	{
	  if (ecf_flags & ECF_NORETURN)
	    /* Just pretend we did the pop.  */
	    stack_pointer_delta -= rounded_stack_size;
	  else if (flag_defer_pop && inhibit_defer_pop == 0
	      && ! (ecf_flags & (ECF_CONST | ECF_PURE)))
	    pending_stack_adjust += rounded_stack_size;
	  else
	    adjust_stack (rounded_stack_size_rtx);
	}
    }
  /* When we accumulate outgoing args, we must avoid any stack manipulations.
     Restore the stack pointer to its original value now.  Usually
     ACCUMULATE_OUTGOING_ARGS targets don't get here, but there are exceptions.
     On  i386 ACCUMULATE_OUTGOING_ARGS can be enabled on demand, and
     popping variants of functions exist as well.

     ??? We may optimize similar to defer_pop above, but it is
     probably not worthwhile.

     ??? It will be worthwhile to enable combine_stack_adjustments even for
     such machines.  */
  else if (maybe_ne (n_popped, 0))
    anti_adjust_stack (gen_int_mode (n_popped, Pmode));
}

/* Determine if the function identified by FNDECL is one with
   special properties we wish to know about.  Modify FLAGS accordingly.

   For example, if the function might return more than one time (setjmp), then
   set ECF_RETURNS_TWICE.

   Set ECF_MAY_BE_ALLOCA for any memory allocation function that might allocate
   space from the stack such as alloca.  */

static int
special_function_p (const_tree fndecl, int flags)
{
  tree name_decl = DECL_NAME (fndecl);

  if (maybe_special_function_p (fndecl)
      && IDENTIFIER_LENGTH (name_decl) <= 11)
    {
      const char *name = IDENTIFIER_POINTER (name_decl);
      const char *tname = name;

      /* We assume that alloca will always be called by name.  It
	 makes no sense to pass it as a pointer-to-function to
	 anything that does not understand its behavior.  */
      if (IDENTIFIER_LENGTH (name_decl) == 6
	  && name[0] == 'a'
	  && ! strcmp (name, "alloca"))
	flags |= ECF_MAY_BE_ALLOCA;

      /* Disregard prefix _ or __.  */
      if (name[0] == '_')
	{
	  if (name[1] == '_')
	    tname += 2;
	  else
	    tname += 1;
	}

      /* ECF_RETURNS_TWICE is safe even for -ffreestanding.  */
      if (! strcmp (tname, "setjmp")
	  || ! strcmp (tname, "sigsetjmp")
	  || ! strcmp (name, "savectx")
	  || ! strcmp (name, "vfork")
	  || ! strcmp (name, "getcontext"))
	flags |= ECF_RETURNS_TWICE;
    }

  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
      && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (fndecl)))
    flags |= ECF_MAY_BE_ALLOCA;

  return flags;
}

/* Return fnspec for DECL.  */

static attr_fnspec
decl_fnspec (tree fndecl)
{
  tree attr;
  tree type = TREE_TYPE (fndecl);
  if (type)
    {
      attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
      if (attr)
	{
	  return TREE_VALUE (TREE_VALUE (attr));
	}
    }
  if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    return builtin_fnspec (fndecl);
  return "";
}

/* Similar to special_function_p; return a set of ERF_ flags for the
   function FNDECL.  */
static int
decl_return_flags (tree fndecl)
{
  attr_fnspec fnspec = decl_fnspec (fndecl);

  unsigned int arg;
  if (fnspec.returns_arg (&arg))
    return ERF_RETURNS_ARG | arg;

  if (fnspec.returns_noalias_p ())
    return ERF_NOALIAS;
  return 0;
}

/* Return nonzero when FNDECL represents a call to setjmp.  */

int
setjmp_call_p (const_tree fndecl)
{
  if (DECL_IS_RETURNS_TWICE (fndecl))
    return ECF_RETURNS_TWICE;
  return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
}


/* Return true if STMT may be an alloca call.  */

bool
gimple_maybe_alloca_call_p (const gimple *stmt)
{
  tree fndecl;

  if (!is_gimple_call (stmt))
    return false;

  fndecl = gimple_call_fndecl (stmt);
  if (fndecl && (special_function_p (fndecl, 0) & ECF_MAY_BE_ALLOCA))
    return true;

  return false;
}

/* Return true if STMT is a builtin alloca call.  */

bool
gimple_alloca_call_p (const gimple *stmt)
{
  tree fndecl;

  if (!is_gimple_call (stmt))
    return false;

  fndecl = gimple_call_fndecl (stmt);
  if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    switch (DECL_FUNCTION_CODE (fndecl))
      {
      CASE_BUILT_IN_ALLOCA:
	return gimple_call_num_args (stmt) > 0;
      default:
	break;
      }

  return false;
}

/* Return true when exp contains a builtin alloca call.  */

bool
alloca_call_p (const_tree exp)
{
  tree fndecl;
  if (TREE_CODE (exp) == CALL_EXPR
      && (fndecl = get_callee_fndecl (exp))
      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
    switch (DECL_FUNCTION_CODE (fndecl))
      {
      CASE_BUILT_IN_ALLOCA:
        return true;
      default:
	break;
      }

  return false;
}

/* Return TRUE if FNDECL is either a TM builtin or a TM cloned
   function.  Return FALSE otherwise.  */

static bool
is_tm_builtin (const_tree fndecl)
{
  if (fndecl == NULL)
    return false;

  if (decl_is_tm_clone (fndecl))
    return true;

  if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
    {
      switch (DECL_FUNCTION_CODE (fndecl))
	{
	case BUILT_IN_TM_COMMIT:
	case BUILT_IN_TM_COMMIT_EH:
	case BUILT_IN_TM_ABORT:
	case BUILT_IN_TM_IRREVOCABLE:
	case BUILT_IN_TM_GETTMCLONE_IRR:
	case BUILT_IN_TM_MEMCPY:
	case BUILT_IN_TM_MEMMOVE:
	case BUILT_IN_TM_MEMSET:
	CASE_BUILT_IN_TM_STORE (1):
	CASE_BUILT_IN_TM_STORE (2):
	CASE_BUILT_IN_TM_STORE (4):
	CASE_BUILT_IN_TM_STORE (8):
	CASE_BUILT_IN_TM_STORE (FLOAT):
	CASE_BUILT_IN_TM_STORE (DOUBLE):
	CASE_BUILT_IN_TM_STORE (LDOUBLE):
	CASE_BUILT_IN_TM_STORE (M64):
	CASE_BUILT_IN_TM_STORE (M128):
	CASE_BUILT_IN_TM_STORE (M256):
	CASE_BUILT_IN_TM_LOAD (1):
	CASE_BUILT_IN_TM_LOAD (2):
	CASE_BUILT_IN_TM_LOAD (4):
	CASE_BUILT_IN_TM_LOAD (8):
	CASE_BUILT_IN_TM_LOAD (FLOAT):
	CASE_BUILT_IN_TM_LOAD (DOUBLE):
	CASE_BUILT_IN_TM_LOAD (LDOUBLE):
	CASE_BUILT_IN_TM_LOAD (M64):
	CASE_BUILT_IN_TM_LOAD (M128):
	CASE_BUILT_IN_TM_LOAD (M256):
	case BUILT_IN_TM_LOG:
	case BUILT_IN_TM_LOG_1:
	case BUILT_IN_TM_LOG_2:
	case BUILT_IN_TM_LOG_4:
	case BUILT_IN_TM_LOG_8:
	case BUILT_IN_TM_LOG_FLOAT:
	case BUILT_IN_TM_LOG_DOUBLE:
	case BUILT_IN_TM_LOG_LDOUBLE:
	case BUILT_IN_TM_LOG_M64:
	case BUILT_IN_TM_LOG_M128:
	case BUILT_IN_TM_LOG_M256:
	  return true;
	default:
	  break;
	}
    }
  return false;
}

/* Detect flags (function attributes) from the function decl or type node.  */

int
flags_from_decl_or_type (const_tree exp)
{
  int flags = 0;

  if (DECL_P (exp))
    {
      /* The function exp may have the `malloc' attribute.  */
      if (DECL_IS_MALLOC (exp))
	flags |= ECF_MALLOC;

      /* The function exp may have the `returns_twice' attribute.  */
      if (DECL_IS_RETURNS_TWICE (exp))
	flags |= ECF_RETURNS_TWICE;

      /* Process the pure and const attributes.  */
      if (TREE_READONLY (exp))
	flags |= ECF_CONST;
      if (DECL_PURE_P (exp))
	flags |= ECF_PURE;
      if (DECL_LOOPING_CONST_OR_PURE_P (exp))
	flags |= ECF_LOOPING_CONST_OR_PURE;

      if (DECL_IS_NOVOPS (exp))
	flags |= ECF_NOVOPS;
      if (lookup_attribute ("leaf", DECL_ATTRIBUTES (exp)))
	flags |= ECF_LEAF;
      if (lookup_attribute ("cold", DECL_ATTRIBUTES (exp)))
	flags |= ECF_COLD;

      if (TREE_NOTHROW (exp))
	flags |= ECF_NOTHROW;

      if (flag_tm)
	{
	  if (is_tm_builtin (exp))
	    flags |= ECF_TM_BUILTIN;
	  else if ((flags & (ECF_CONST|ECF_NOVOPS)) != 0
		   || lookup_attribute ("transaction_pure",
					TYPE_ATTRIBUTES (TREE_TYPE (exp))))
	    flags |= ECF_TM_PURE;
	}

      flags = special_function_p (exp, flags);
    }
  else if (TYPE_P (exp))
    {
      if (TYPE_READONLY (exp))
	flags |= ECF_CONST;

      if (flag_tm
	  && ((flags & ECF_CONST) != 0
	      || lookup_attribute ("transaction_pure", TYPE_ATTRIBUTES (exp))))
	flags |= ECF_TM_PURE;
    }
  else
    gcc_unreachable ();

  if (TREE_THIS_VOLATILE (exp))
    {
      flags |= ECF_NORETURN;
      if (flags & (ECF_CONST|ECF_PURE))
	flags |= ECF_LOOPING_CONST_OR_PURE;
    }

  return flags;
}

/* Detect flags from a CALL_EXPR.  */

int
call_expr_flags (const_tree t)
{
  int flags;
  tree decl = get_callee_fndecl (t);

  if (decl)
    flags = flags_from_decl_or_type (decl);
  else if (CALL_EXPR_FN (t) == NULL_TREE)
    flags = internal_fn_flags (CALL_EXPR_IFN (t));
  else
    {
      tree type = TREE_TYPE (CALL_EXPR_FN (t));
      if (type && TREE_CODE (type) == POINTER_TYPE)
	flags = flags_from_decl_or_type (TREE_TYPE (type));
      else
	flags = 0;
      if (CALL_EXPR_BY_DESCRIPTOR (t))
	flags |= ECF_BY_DESCRIPTOR;
    }

  return flags;
}

/* Return true if ARG should be passed by invisible reference.  */

bool
pass_by_reference (CUMULATIVE_ARGS *ca, function_arg_info arg)
{
  if (tree type = arg.type)
    {
      /* If this type contains non-trivial constructors, then it is
	 forbidden for the middle-end to create any new copies.  */
      if (TREE_ADDRESSABLE (type))
	return true;

      /* GCC post 3.4 passes *all* variable sized types by reference.  */
      if (!TYPE_SIZE (type) || !poly_int_tree_p (TYPE_SIZE (type)))
	return true;

      /* If a record type should be passed the same as its first (and only)
	 member, use the type and mode of that member.  */
      if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type))
	{
	  arg.type = TREE_TYPE (first_field (type));
	  arg.mode = TYPE_MODE (arg.type);
	}
    }

  return targetm.calls.pass_by_reference (pack_cumulative_args (ca), arg);
}

/* Return true if TYPE should be passed by reference when passed to
   the "..." arguments of a function.  */

bool
pass_va_arg_by_reference (tree type)
{
  return pass_by_reference (NULL, function_arg_info (type, /*named=*/false));
}

/* Decide whether ARG, which occurs in the state described by CA,
   should be passed by reference.  Return true if so and update
   ARG accordingly.  */

bool
apply_pass_by_reference_rules (CUMULATIVE_ARGS *ca, function_arg_info &arg)
{
  if (pass_by_reference (ca, arg))
    {
      arg.type = build_pointer_type (arg.type);
      arg.mode = TYPE_MODE (arg.type);
      arg.pass_by_reference = true;
      return true;
    }
  return false;
}

/* Return true if ARG, which is passed by reference, should be callee
   copied instead of caller copied.  */

bool
reference_callee_copied (CUMULATIVE_ARGS *ca, const function_arg_info &arg)
{
  if (arg.type && TREE_ADDRESSABLE (arg.type))
    return false;
  return targetm.calls.callee_copies (pack_cumulative_args (ca), arg);
}


/* Precompute all register parameters as described by ARGS, storing values
   into fields within the ARGS array.

   NUM_ACTUALS indicates the total number elements in the ARGS array.

   Set REG_PARM_SEEN if we encounter a register parameter.  */

static void
precompute_register_parameters (int num_actuals, struct arg_data *args,
				int *reg_parm_seen)
{
  int i;

  *reg_parm_seen = 0;

  for (i = 0; i < num_actuals; i++)
    if (args[i].reg != 0 && ! args[i].pass_on_stack)
      {
	*reg_parm_seen = 1;

	if (args[i].value == 0)
	  {
	    push_temp_slots ();
	    args[i].value = expand_normal (args[i].tree_value);
	    preserve_temp_slots (args[i].value);
	    pop_temp_slots ();
	  }

	/* If we are to promote the function arg to a wider mode,
	   do it now.  */

	if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value)))
	  args[i].value
	    = convert_modes (args[i].mode,
			     TYPE_MODE (TREE_TYPE (args[i].tree_value)),
			     args[i].value, args[i].unsignedp);

	/* If the value is a non-legitimate constant, force it into a
	   pseudo now.  TLS symbols sometimes need a call to resolve.  */
	if (CONSTANT_P (args[i].value)
	    && (!targetm.legitimate_constant_p (args[i].mode, args[i].value)
		|| targetm.precompute_tls_p (args[i].mode, args[i].value)))
	  args[i].value = force_reg (args[i].mode, args[i].value);

	/* If we're going to have to load the value by parts, pull the
	   parts into pseudos.  The part extraction process can involve
	   non-trivial computation.  */
	if (GET_CODE (args[i].reg) == PARALLEL)
	  {
	    tree type = TREE_TYPE (args[i].tree_value);
	    args[i].parallel_value
	      = emit_group_load_into_temps (args[i].reg, args[i].value,
					    type, int_size_in_bytes (type));
	  }

	/* If the value is expensive, and we are inside an appropriately
	   short loop, put the value into a pseudo and then put the pseudo
	   into the hard reg.

	   For small register classes, also do this if this call uses
	   register parameters.  This is to avoid reload conflicts while
	   loading the parameters registers.  */

	else if ((! (REG_P (args[i].value)
		     || (GET_CODE (args[i].value) == SUBREG
			 && REG_P (SUBREG_REG (args[i].value)))))
		 && args[i].mode != BLKmode
		 && (set_src_cost (args[i].value, args[i].mode,
				   optimize_insn_for_speed_p ())
		     > COSTS_N_INSNS (1))
		 && ((*reg_parm_seen
		      && targetm.small_register_classes_for_mode_p (args[i].mode))
		     || optimize))
	  args[i].value = copy_to_mode_reg (args[i].mode, args[i].value);
      }
}

#ifdef REG_PARM_STACK_SPACE

  /* The argument list is the property of the called routine and it
     may clobber it.  If the fixed area has been used for previous
     parameters, we must save and restore it.  */

static rtx
save_fixed_argument_area (int reg_parm_stack_space, rtx argblock, int *low_to_save, int *high_to_save)
{
  unsigned int low;
  unsigned int high;

  /* Compute the boundary of the area that needs to be saved, if any.  */
  high = reg_parm_stack_space;
  if (ARGS_GROW_DOWNWARD)
    high += 1;

  if (high > highest_outgoing_arg_in_use)
    high = highest_outgoing_arg_in_use;

  for (low = 0; low < high; low++)
    if (stack_usage_map[low] != 0 || low >= stack_usage_watermark)
      {
	int num_to_save;
	machine_mode save_mode;
	int delta;
	rtx addr;
	rtx stack_area;
	rtx save_area;

	while (stack_usage_map[--high] == 0)
	  ;

	*low_to_save = low;
	*high_to_save = high;

	num_to_save = high - low + 1;

	/* If we don't have the required alignment, must do this
	   in BLKmode.  */
	scalar_int_mode imode;
	if (int_mode_for_size (num_to_save * BITS_PER_UNIT, 1).exists (&imode)
	    && (low & (MIN (GET_MODE_SIZE (imode),
			    BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)) == 0)
	  save_mode = imode;
	else
	  save_mode = BLKmode;

	if (ARGS_GROW_DOWNWARD)
	  delta = -high;
	else
	  delta = low;

	addr = plus_constant (Pmode, argblock, delta);
	stack_area = gen_rtx_MEM (save_mode, memory_address (save_mode, addr));

	set_mem_align (stack_area, PARM_BOUNDARY);
	if (save_mode == BLKmode)
	  {
	    save_area = assign_stack_temp (BLKmode, num_to_save);
	    emit_block_move (validize_mem (save_area), stack_area,
			     GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
	  }
	else
	  {
	    save_area = gen_reg_rtx (save_mode);
	    emit_move_insn (save_area, stack_area);
	  }

	return save_area;
      }

  return NULL_RTX;
}

static void
restore_fixed_argument_area (rtx save_area, rtx argblock, int high_to_save, int low_to_save)
{
  machine_mode save_mode = GET_MODE (save_area);
  int delta;
  rtx addr, stack_area;

  if (ARGS_GROW_DOWNWARD)
    delta = -high_to_save;
  else
    delta = low_to_save;

  addr = plus_constant (Pmode, argblock, delta);
  stack_area = gen_rtx_MEM (save_mode, memory_address (save_mode, addr));
  set_mem_align (stack_area, PARM_BOUNDARY);

  if (save_mode != BLKmode)
    emit_move_insn (stack_area, save_area);
  else
    emit_block_move (stack_area, validize_mem (save_area),
		     GEN_INT (high_to_save - low_to_save + 1),
		     BLOCK_OP_CALL_PARM);
}
#endif /* REG_PARM_STACK_SPACE */

/* If any elements in ARGS refer to parameters that are to be passed in
   registers, but not in memory, and whose alignment does not permit a
   direct copy into registers.  Copy the values into a group of pseudos
   which we will later copy into the appropriate hard registers.

   Pseudos for each unaligned argument will be stored into the array
   args[argnum].aligned_regs.  The caller is responsible for deallocating
   the aligned_regs array if it is nonzero.  */

static void
store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
{
  int i, j;

  for (i = 0; i < num_actuals; i++)
    if (args[i].reg != 0 && ! args[i].pass_on_stack
	&& GET_CODE (args[i].reg) != PARALLEL
	&& args[i].mode == BLKmode
	&& MEM_P (args[i].value)
	&& (MEM_ALIGN (args[i].value)
	    < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
      {
	int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
	int endian_correction = 0;

	if (args[i].partial)
	  {
	    gcc_assert (args[i].partial % UNITS_PER_WORD == 0);
	    args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD;
	  }
	else
	  {
	    args[i].n_aligned_regs
	      = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
	  }

	args[i].aligned_regs = XNEWVEC (rtx, args[i].n_aligned_regs);

	/* Structures smaller than a word are normally aligned to the
	   least significant byte.  On a BYTES_BIG_ENDIAN machine,
	   this means we must skip the empty high order bytes when
	   calculating the bit offset.  */
	if (bytes < UNITS_PER_WORD
#ifdef BLOCK_REG_PADDING
	    && (BLOCK_REG_PADDING (args[i].mode,
				   TREE_TYPE (args[i].tree_value), 1)
		== PAD_DOWNWARD)
#else
	    && BYTES_BIG_ENDIAN
#endif
	    )
	  endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;

	for (j = 0; j < args[i].n_aligned_regs; j++)
	  {
	    rtx reg = gen_reg_rtx (word_mode);
	    rtx word = operand_subword_force (args[i].value, j, BLKmode);
	    int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);

	    args[i].aligned_regs[j] = reg;
	    word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
				      word_mode, word_mode, false, NULL);

	    /* There is no need to restrict this code to loading items
	       in TYPE_ALIGN sized hunks.  The bitfield instructions can
	       load up entire word sized registers efficiently.

	       ??? This may not be needed anymore.
	       We use to emit a clobber here but that doesn't let later
	       passes optimize the instructions we emit.  By storing 0 into
	       the register later passes know the first AND to zero out the
	       bitfield being set in the register is unnecessary.  The store
	       of 0 will be deleted as will at least the first AND.  */

	    emit_move_insn (reg, const0_rtx);

	    bytes -= bitsize / BITS_PER_UNIT;
	    store_bit_field (reg, bitsize, endian_correction, 0, 0,
			     word_mode, word, false);
	  }
      }
}

/* Issue an error if CALL_EXPR was flagged as requiring
   tall-call optimization.  */

void
maybe_complain_about_tail_call (tree call_expr, const char *reason)
{
  gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
  if (!CALL_EXPR_MUST_TAIL_CALL (call_expr))
    return;

  error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
}

/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
   CALL_EXPR EXP.

   NUM_ACTUALS is the total number of parameters.

   N_NAMED_ARGS is the total number of named arguments.

   STRUCT_VALUE_ADDR_VALUE is the implicit argument for a struct return
   value, or null.

   FNDECL is the tree code for the target of this call (if known)

   ARGS_SO_FAR holds state needed by the target to know where to place
   the next argument.

   REG_PARM_STACK_SPACE is the number of bytes of stack space reserved
   for arguments which are passed in registers.

   OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level
   and may be modified by this routine.

   OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS are pointers to integer
   flags which may be modified by this routine.

   MAY_TAILCALL is cleared if we encounter an invisible pass-by-reference
   that requires allocation of stack space.

   CALL_FROM_THUNK_P is true if this call is the jump from a thunk to
   the thunked-to function.  */

static void
initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
				 struct arg_data *args,
				 struct args_size *args_size,
				 int n_named_args ATTRIBUTE_UNUSED,
				 tree exp, tree struct_value_addr_value,
				 tree fndecl, tree fntype,
				 cumulative_args_t args_so_far,
				 int reg_parm_stack_space,
				 rtx *old_stack_level,
				 poly_int64_pod *old_pending_adj,
				 int *must_preallocate, int *ecf_flags,
				 bool *may_tailcall, bool call_from_thunk_p)
{
  CUMULATIVE_ARGS *args_so_far_pnt = get_cumulative_args (args_so_far);
  location_t loc = EXPR_LOCATION (exp);

  /* Count arg position in order args appear.  */
  int argpos;

  int i;

  args_size->constant = 0;
  args_size->var = 0;

  bitmap_obstack_initialize (NULL);

  /* In this loop, we consider args in the order they are written.
     We fill up ARGS from the back.  */

  i = num_actuals - 1;
  {
    int j = i;
    call_expr_arg_iterator iter;
    tree arg;
    bitmap slots = NULL;

    if (struct_value_addr_value)
      {
	args[j].tree_value = struct_value_addr_value;
	j--;
      }
    argpos = 0;
    FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
      {
	tree argtype = TREE_TYPE (arg);

	if (targetm.calls.split_complex_arg
	    && argtype
	    && TREE_CODE (argtype) == COMPLEX_TYPE
	    && targetm.calls.split_complex_arg (argtype))
	  {
	    tree subtype = TREE_TYPE (argtype);
	    args[j].tree_value = build1 (REALPART_EXPR, subtype, arg);
	    j--;
	    args[j].tree_value = build1 (IMAGPART_EXPR, subtype, arg);
	  }
	else
	  args[j].tree_value = arg;
	j--;
	argpos++;
      }

    if (slots)
      BITMAP_FREE (slots);
  }

  bitmap_obstack_release (NULL);

  /* I counts args in order (to be) pushed; ARGPOS counts in order written.  */
  for (argpos = 0; argpos < num_actuals; i--, argpos++)
    {
      tree type = TREE_TYPE (args[i].tree_value);
      int unsignedp;

      /* Replace erroneous argument with constant zero.  */
      if (type == error_mark_node || !COMPLETE_TYPE_P (type))
	args[i].tree_value = integer_zero_node, type = integer_type_node;

      /* If TYPE is a transparent union or record, pass things the way
	 we would pass the first field of the union or record.  We have
	 already verified that the modes are the same.  */
      if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
	type = TREE_TYPE (first_field (type));

      /* Decide where to pass this arg.

	 args[i].reg is nonzero if all or part is passed in registers.

	 args[i].partial is nonzero if part but not all is passed in registers,
	 and the exact value says how many bytes are passed in registers.

	 args[i].pass_on_stack is nonzero if the argument must at least be
	 computed on the stack.  It may then be loaded back into registers
	 if args[i].reg is nonzero.

	 These decisions are driven by the FUNCTION_... macros and must agree
	 with those made by function.c.  */

      /* See if this argument should be passed by invisible reference.  */
      function_arg_info arg (type, argpos < n_named_args);
      if (pass_by_reference (args_so_far_pnt, arg))
	{
	  const bool callee_copies
	    = reference_callee_copied (args_so_far_pnt, arg);
	  tree base;

	  /* If we're compiling a thunk, pass directly the address of an object
	     already in memory, instead of making a copy.  Likewise if we want
	     to make the copy in the callee instead of the caller.  */
	  if ((call_from_thunk_p || callee_copies)
	      && TREE_CODE (args[i].tree_value) != WITH_SIZE_EXPR
	      && ((base = get_base_address (args[i].tree_value)), true)
	      && TREE_CODE (base) != SSA_NAME
	      && (!DECL_P (base) || MEM_P (DECL_RTL (base))))
	    {
	      /* We may have turned the parameter value into an SSA name.
		 Go back to the original parameter so we can take the
		 address.  */
	      if (TREE_CODE (args[i].tree_value) == SSA_NAME)
		{
		  gcc_assert (SSA_NAME_IS_DEFAULT_DEF (args[i].tree_value));
		  args[i].tree_value = SSA_NAME_VAR (args[i].tree_value);
		  gcc_assert (TREE_CODE (args[i].tree_value) == PARM_DECL);
		}
	      /* Argument setup code may have copied the value to register.  We
		 revert that optimization now because the tail call code must
		 use the original location.  */
	      if (TREE_CODE (args[i].tree_value) == PARM_DECL
		  && !MEM_P (DECL_RTL (args[i].tree_value))
		  && DECL_INCOMING_RTL (args[i].tree_value)
		  && MEM_P (DECL_INCOMING_RTL (args[i].tree_value)))
		set_decl_rtl (args[i].tree_value,
			      DECL_INCOMING_RTL (args[i].tree_value));

	      mark_addressable (args[i].tree_value);

	      /* We can't use sibcalls if a callee-copied argument is
		 stored in the current function's frame.  */
	      if (!call_from_thunk_p && DECL_P (base) && !TREE_STATIC (base))
		{
		  *may_tailcall = false;
		  maybe_complain_about_tail_call (exp,
						  "a callee-copied argument is"
						  " stored in the current"
						  " function's frame");
		}

	      args[i].tree_value = build_fold_addr_expr_loc (loc,
							 args[i].tree_value);
	      type = TREE_TYPE (args[i].tree_value);

	      if (*ecf_flags & ECF_CONST)
		*ecf_flags &= ~(ECF_CONST | ECF_LOOPING_CONST_OR_PURE);
	    }
	  else
	    {
	      /* We make a copy of the object and pass the address to the
		 function being called.  */
	      rtx copy;

	      if (!COMPLETE_TYPE_P (type)
		  || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
		  || (flag_stack_check == GENERIC_STACK_CHECK
		      && compare_tree_int (TYPE_SIZE_UNIT (type),
					   STACK_CHECK_MAX_VAR_SIZE) > 0))
		{
		  /* This is a variable-sized object.  Make space on the stack
		     for it.  */
		  rtx size_rtx = expr_size (args[i].tree_value);

		  if (*old_stack_level == 0)
		    {
		      emit_stack_save (SAVE_BLOCK, old_stack_level);
		      *old_pending_adj = pending_stack_adjust;
		      pending_stack_adjust = 0;
		    }

		  /* We can pass TRUE as the 4th argument because we just
		     saved the stack pointer and will restore it right after
		     the call.  */
		  copy = allocate_dynamic_stack_space (size_rtx,
						       TYPE_ALIGN (type),
						       TYPE_ALIGN (type),
						       max_int_size_in_bytes
						       (type),
						       true);
		  copy = gen_rtx_MEM (BLKmode, copy);
		  set_mem_attributes (copy, type, 1);
		}
	      else
		copy = assign_temp (type, 1, 0);

	      store_expr (args[i].tree_value, copy, 0, false, false);

	      /* Just change the const function to pure and then let
		 the next test clear the pure based on
		 callee_copies.  */
	      if (*ecf_flags & ECF_CONST)
		{
		  *ecf_flags &= ~ECF_CONST;
		  *ecf_flags |= ECF_PURE;
		}

	      if (!callee_copies && *ecf_flags & ECF_PURE)
		*ecf_flags &= ~(ECF_PURE | ECF_LOOPING_CONST_OR_PURE);

	      args[i].tree_value
		= build_fold_addr_expr_loc (loc, make_tree (type, copy));
	      type = TREE_TYPE (args[i].tree_value);
	      *may_tailcall = false;
	      maybe_complain_about_tail_call (exp,
					      "argument must be passed"
					      " by copying");
	    }
	  arg.pass_by_reference = true;
	}

      unsignedp = TYPE_UNSIGNED (type);
      arg.type = type;
      arg.mode
	= promote_function_mode (type, TYPE_MODE (type), &unsignedp,
				 fndecl ? TREE_TYPE (fndecl) : fntype, 0);

      args[i].unsignedp = unsignedp;
      args[i].mode = arg.mode;

      targetm.calls.warn_parameter_passing_abi (args_so_far, type);

      args[i].reg = targetm.calls.function_arg (args_so_far, arg);

      if (args[i].reg && CONST_INT_P (args[i].reg))
	args[i].reg = NULL;

      /* If this is a sibling call and the machine has register windows, the
	 register window has to be unwinded before calling the routine, so
	 arguments have to go into the incoming registers.  */
      if (targetm.calls.function_incoming_arg != targetm.calls.function_arg)
	args[i].tail_call_reg
	  = targetm.calls.function_incoming_arg (args_so_far, arg);
      else
	args[i].tail_call_reg = args[i].reg;

      if (args[i].reg)
	args[i].partial = targetm.calls.arg_partial_bytes (args_so_far, arg);

      args[i].pass_on_stack = targetm.calls.must_pass_in_stack (arg);

      /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
	 it means that we are to pass this arg in the register(s) designated
	 by the PARALLEL, but also to pass it in the stack.  */
      if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL
	  && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0)
	args[i].pass_on_stack = 1;

      /* If this is an addressable type, we must preallocate the stack
	 since we must evaluate the object into its final location.

	 If this is to be passed in both registers and the stack, it is simpler
	 to preallocate.  */
      if (TREE_ADDRESSABLE (type)
	  || (args[i].pass_on_stack && args[i].reg != 0))
	*must_preallocate = 1;

      /* Compute the stack-size of this argument.  */
      if (args[i].reg == 0 || args[i].partial != 0
	       || reg_parm_stack_space > 0
	       || args[i].pass_on_stack)
	locate_and_pad_parm (arg.mode, type,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
			     1,
#else
			     args[i].reg != 0,
#endif
			     reg_parm_stack_space,
			     args[i].pass_on_stack ? 0 : args[i].partial,
			     fndecl, args_size, &args[i].locate);
#ifdef BLOCK_REG_PADDING
      else
	/* The argument is passed entirely in registers.  See at which
	   end it should be padded.  */
	args[i].locate.where_pad =
	  BLOCK_REG_PADDING (arg.mode, type,
			     int_size_in_bytes (type) <= UNITS_PER_WORD);
#endif

      /* Update ARGS_SIZE, the total stack space for args so far.  */

      args_size->constant += args[i].locate.size.constant;
      if (args[i].locate.size.var)
	ADD_PARM_SIZE (*args_size, args[i].locate.size.var);

      /* Increment ARGS_SO_FAR, which has info about which arg-registers
	 have been used, etc.  */

      /* ??? Traditionally we've passed TYPE_MODE here, instead of the
	 promoted_mode used for function_arg above.  However, the
	 corresponding handling of incoming arguments in function.c
	 does pass the promoted mode.  */
      arg.mode = TYPE_MODE (type);
      targetm.calls.function_arg_advance (args_so_far, arg);
    }
}

/* Update ARGS_SIZE to contain the total size for the argument block.
   Return the original constant component of the argument block's size.

   REG_PARM_STACK_SPACE holds the number of bytes of stack space reserved
   for arguments passed in registers.  */

static poly_int64
compute_argument_block_size (int reg_parm_stack_space,
			     struct args_size *args_size,
			     tree fndecl ATTRIBUTE_UNUSED,
			     tree fntype ATTRIBUTE_UNUSED,
			     int preferred_stack_boundary ATTRIBUTE_UNUSED)
{
  poly_int64 unadjusted_args_size = args_size->constant;

  /* For accumulate outgoing args mode we don't need to align, since the frame
     will be already aligned.  Align to STACK_BOUNDARY in order to prevent
     backends from generating misaligned frame sizes.  */
  if (ACCUMULATE_OUTGOING_ARGS && preferred_stack_boundary > STACK_BOUNDARY)
    preferred_stack_boundary = STACK_BOUNDARY;

  /* Compute the actual size of the argument block required.  The variable
     and constant sizes must be combined, the size may have to be rounded,
     and there may be a minimum required size.  */

  if (args_size->var)
    {
      args_size->var = ARGS_SIZE_TREE (*args_size);
      args_size->constant = 0;

      preferred_stack_boundary /= BITS_PER_UNIT;
      if (preferred_stack_boundary > 1)
	{
	  /* We don't handle this case yet.  To handle it correctly we have
	     to add the delta, round and subtract the delta.
	     Currently no machine description requires this support.  */
	  gcc_assert (multiple_p (stack_pointer_delta,
				  preferred_stack_boundary));
	  args_size->var = round_up (args_size->var, preferred_stack_boundary);
	}

      if (reg_parm_stack_space > 0)
	{
	  args_size->var
	    = size_binop (MAX_EXPR, args_size->var,
			  ssize_int (reg_parm_stack_space));

	  /* The area corresponding to register parameters is not to count in
	     the size of the block we need.  So make the adjustment.  */
	  if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
	    args_size->var
	      = size_binop (MINUS_EXPR, args_size->var,
			    ssize_int (reg_parm_stack_space));
	}
    }
  else
    {
      preferred_stack_boundary /= BITS_PER_UNIT;
      if (preferred_stack_boundary < 1)
	preferred_stack_boundary = 1;
      args_size->constant = (aligned_upper_bound (args_size->constant
						  + stack_pointer_delta,
						  preferred_stack_boundary)
			     - stack_pointer_delta);

      args_size->constant = upper_bound (args_size->constant,
					 reg_parm_stack_space);

      if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
	args_size->constant -= reg_parm_stack_space;
    }
  return unadjusted_args_size;
}

/* Precompute parameters as needed for a function call.

   FLAGS is mask of ECF_* constants.

   NUM_ACTUALS is the number of arguments.

   ARGS is an array containing information for each argument; this
   routine fills in the INITIAL_VALUE and VALUE fields for each
   precomputed argument.  */

static void
precompute_arguments (int num_actuals, struct arg_data *args)
{
  int i;

  /* If this is a libcall, then precompute all arguments so that we do not
     get extraneous instructions emitted as part of the libcall sequence.  */

  /* If we preallocated the stack space, and some arguments must be passed
     on the stack, then we must precompute any parameter which contains a
     function call which will store arguments on the stack.
     Otherwise, evaluating the parameter may clobber previous parameters
     which have already been stored into the stack.  (we have code to avoid
     such case by saving the outgoing stack arguments, but it results in
     worse code)  */
  if (!ACCUMULATE_OUTGOING_ARGS)
    return;

  for (i = 0; i < num_actuals; i++)
    {
      tree type;
      machine_mode mode;

      if (TREE_CODE (args[i].tree_value) != CALL_EXPR)
	continue;

      /* If this is an addressable type, we cannot pre-evaluate it.  */
      type = TREE_TYPE (args[i].tree_value);
      gcc_assert (!TREE_ADDRESSABLE (type));

      args[i].initial_value = args[i].value
	= expand_normal (args[i].tree_value);

      mode = TYPE_MODE (type);
      if (mode != args[i].mode)
	{
	  int unsignedp = args[i].unsignedp;
	  args[i].value
	    = convert_modes (args[i].mode, mode,
			     args[i].value, args[i].unsignedp);

	  /* CSE will replace this only if it contains args[i].value
	     pseudo, so convert it down to the declared mode using
	     a SUBREG.  */
	  if (REG_P (args[i].value)
	      && GET_MODE_CLASS (args[i].mode) == MODE_INT
	      && promote_mode (type, mode, &unsignedp) != args[i].mode)
	    {
	      args[i].initial_value
		= gen_lowpart_SUBREG (mode, args[i].value);
	      SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
	      SUBREG_PROMOTED_SET (args[i].initial_value, args[i].unsignedp);
	    }
	}
    }
}

/* Given the current state of MUST_PREALLOCATE and information about
   arguments to a function call in NUM_ACTUALS, ARGS and ARGS_SIZE,
   compute and return the final value for MUST_PREALLOCATE.  */

static int
finalize_must_preallocate (int must_preallocate, int num_actuals,
			   struct arg_data *args, struct args_size *args_size)
{
  /* See if we have or want to preallocate stack space.

     If we would have to push a partially-in-regs parm
     before other stack parms, preallocate stack space instead.

     If the size of some parm is not a multiple of the required stack
     alignment, we must preallocate.

     If the total size of arguments that would otherwise create a copy in
     a temporary (such as a CALL) is more than half the total argument list
     size, preallocation is faster.

     Another reason to preallocate is if we have a machine (like the m88k)
     where stack alignment is required to be maintained between every
     pair of insns, not just when the call is made.  However, we assume here
     that such machines either do not have push insns (and hence preallocation
     would occur anyway) or the problem is taken care of with
     PUSH_ROUNDING.  */

  if (! must_preallocate)
    {
      int partial_seen = 0;
      poly_int64 copy_to_evaluate_size = 0;
      int i;

      for (i = 0; i < num_actuals && ! must_preallocate; i++)
	{
	  if (args[i].partial > 0 && ! args[i].pass_on_stack)
	    partial_seen = 1;
	  else if (partial_seen && args[i].reg == 0)
	    must_preallocate = 1;

	  if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
	      && (TREE_CODE (args[i].tree_value) == CALL_EXPR
		  || TREE_CODE (args[i].tree_value) == TARGET_EXPR
		  || TREE_CODE (args[i].tree_value) == COND_EXPR
		  || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))))
	    copy_to_evaluate_size
	      += int_size_in_bytes (TREE_TYPE (args[i].tree_value));
	}

      if (maybe_ne (args_size->constant, 0)
	  && maybe_ge (copy_to_evaluate_size * 2, args_size->constant))
	must_preallocate = 1;
    }
  return must_preallocate;
}

/* If we preallocated stack space, compute the address of each argument
   and store it into the ARGS array.

   We need not ensure it is a valid memory address here; it will be
   validized when it is used.

   ARGBLOCK is an rtx for the address of the outgoing arguments.  */

static void
compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals)
{
  if (argblock)
    {
      rtx arg_reg = argblock;
      int i;
      poly_int64 arg_offset = 0;

      if (GET_CODE (argblock) == PLUS)
	{
	  arg_reg = XEXP (argblock, 0);
	  arg_offset = rtx_to_poly_int64 (XEXP (argblock, 1));
	}

      for (i = 0; i < num_actuals; i++)
	{
	  rtx offset = ARGS_SIZE_RTX (args[i].locate.offset);
	  rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
	  rtx addr;
	  unsigned int align, boundary;
	  poly_uint64 units_on_stack = 0;
	  machine_mode partial_mode = VOIDmode;

	  /* Skip this parm if it will not be passed on the stack.  */
	  if (! args[i].pass_on_stack
	      && args[i].reg != 0
	      && args[i].partial == 0)
	    continue;

	  if (TYPE_EMPTY_P (TREE_TYPE (args[i].tree_value)))
	    continue;

	  addr = simplify_gen_binary (PLUS, Pmode, arg_reg, offset);
	  addr = plus_constant (Pmode, addr, arg_offset);

	  if (args[i].partial != 0)
	    {
	      /* Only part of the parameter is being passed on the stack.
		 Generate a simple memory reference of the correct size.  */
	      units_on_stack = args[i].locate.size.constant;
	      poly_uint64 bits_on_stack = units_on_stack * BITS_PER_UNIT;
	      partial_mode = int_mode_for_size (bits_on_stack, 1).else_blk ();
	      args[i].stack = gen_rtx_MEM (partial_mode, addr);
	      set_mem_size (args[i].stack, units_on_stack);
	    }
	  else
	    {
	      args[i].stack = gen_rtx_MEM (args[i].mode, addr);
	      set_mem_attributes (args[i].stack,
				  TREE_TYPE (args[i].tree_value), 1);
	    }
	  align = BITS_PER_UNIT;
	  boundary = args[i].locate.boundary;
	  poly_int64 offset_val;
	  if (args[i].locate.where_pad != PAD_DOWNWARD)
	    align = boundary;
	  else if (poly_int_rtx_p (offset, &offset_val))
	    {
	      align = least_bit_hwi (boundary);
	      unsigned int offset_align
		= known_alignment (offset_val) * BITS_PER_UNIT;
	      if (offset_align != 0)
		align = MIN (align, offset_align);
	    }
	  set_mem_align (args[i].stack, align);

	  addr = simplify_gen_binary (PLUS, Pmode, arg_reg, slot_offset);
	  addr = plus_constant (Pmode, addr, arg_offset);

	  if (args[i].partial != 0)
	    {
	      /* Only part of the parameter is being passed on the stack.
		 Generate a simple memory reference of the correct size.
	       */
	      args[i].stack_slot = gen_rtx_MEM (partial_mode, addr);
	      set_mem_size (args[i].stack_slot, units_on_stack);
	    }
	  else
	    {
	      args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
	      set_mem_attributes (args[i].stack_slot,
				  TREE_TYPE (args[i].tree_value), 1);
	    }
	  set_mem_align (args[i].stack_slot, args[i].locate.boundary);

	  /* Function incoming arguments may overlap with sibling call
	     outgoing arguments and we cannot allow reordering of reads
	     from function arguments with stores to outgoing arguments
	     of sibling calls.  */
	  set_mem_alias_set (args[i].stack, 0);
	  set_mem_alias_set (args[i].stack_slot, 0);
	}
    }
}

/* Given a FNDECL and EXP, return an rtx suitable for use as a target address
   in a call instruction.

   FNDECL is the tree node for the target function.  For an indirect call
   FNDECL will be NULL_TREE.

   ADDR is the operand 0 of CALL_EXPR for this call.  */

static rtx
rtx_for_function_call (tree fndecl, tree addr)
{
  rtx funexp;

  /* Get the function to call, in the form of RTL.  */
  if (fndecl)
    {
      if (!TREE_USED (fndecl) && fndecl != current_function_decl)
	TREE_USED (fndecl) = 1;

      /* Get a SYMBOL_REF rtx for the function address.  */
      funexp = XEXP (DECL_RTL (fndecl), 0);
    }
  else
    /* Generate an rtx (probably a pseudo-register) for the address.  */
    {
      push_temp_slots ();
      funexp = expand_normal (addr);
      pop_temp_slots ();	/* FUNEXP can't be BLKmode.  */
    }
  return funexp;
}

/* Return the static chain for this function, if any.  */

rtx
rtx_for_static_chain (const_tree fndecl_or_type, bool incoming_p)
{
  if (DECL_P (fndecl_or_type) && !DECL_STATIC_CHAIN (fndecl_or_type))
    return NULL;

  return targetm.calls.static_chain (fndecl_or_type, incoming_p);
}

/* Internal state for internal_arg_pointer_based_exp and its helpers.  */
static struct
{
  /* Last insn that has been scanned by internal_arg_pointer_based_exp_scan,
     or NULL_RTX if none has been scanned yet.  */
  rtx_insn *scan_start;
  /* Vector indexed by REGNO - FIRST_PSEUDO_REGISTER, recording if a pseudo is
     based on crtl->args.internal_arg_pointer.  The element is NULL_RTX if the
     pseudo isn't based on it, a CONST_INT offset if the pseudo is based on it
     with fixed offset, or PC if this is with variable or unknown offset.  */
  vec<rtx> cache;
} internal_arg_pointer_exp_state;

static rtx internal_arg_pointer_based_exp (const_rtx, bool);

/* Helper function for internal_arg_pointer_based_exp.  Scan insns in
   the tail call sequence, starting with first insn that hasn't been
   scanned yet, and note for each pseudo on the LHS whether it is based
   on crtl->args.internal_arg_pointer or not, and what offset from that
   that pointer it has.  */

static void
internal_arg_pointer_based_exp_scan (void)
{
  rtx_insn *insn, *scan_start = internal_arg_pointer_exp_state.scan_start;

  if (scan_start == NULL_RTX)
    insn = get_insns ();
  else
    insn = NEXT_INSN (scan_start);

  while (insn)
    {
      rtx set = single_set (insn);
      if (set && REG_P (SET_DEST (set)) && !HARD_REGISTER_P (SET_DEST (set)))
	{
	  rtx val = NULL_RTX;
	  unsigned int idx = REGNO (SET_DEST (set)) - FIRST_PSEUDO_REGISTER;
	  /* Punt on pseudos set multiple times.  */
	  if (idx < internal_arg_pointer_exp_state.cache.length ()
	      && (internal_arg_pointer_exp_state.cache[idx]
		  != NULL_RTX))
	    val = pc_rtx;
	  else
	    val = internal_arg_pointer_based_exp (SET_SRC (set), false);
	  if (val != NULL_RTX)
	    {
	      if (idx >= internal_arg_pointer_exp_state.cache.length ())
		internal_arg_pointer_exp_state.cache
		  .safe_grow_cleared (idx + 1, true);
	      internal_arg_pointer_exp_state.cache[idx] = val;
	    }
	}
      if (NEXT_INSN (insn) == NULL_RTX)
	scan_start = insn;
      insn = NEXT_INSN (insn);
    }

  internal_arg_pointer_exp_state.scan_start = scan_start;
}

/* Compute whether RTL is based on crtl->args.internal_arg_pointer.  Return
   NULL_RTX if RTL isn't based on it, a CONST_INT offset if RTL is based on
   it with fixed offset, or PC if this is with variable or unknown offset.
   TOPLEVEL is true if the function is invoked at the topmost level.  */

static rtx
internal_arg_pointer_based_exp (const_rtx rtl, bool toplevel)
{
  if (CONSTANT_P (rtl))
    return NULL_RTX;

  if (rtl == crtl->args.internal_arg_pointer)
    return const0_rtx;

  if (REG_P (rtl) && HARD_REGISTER_P (rtl))
    return NULL_RTX;

  poly_int64 offset;
  if (GET_CODE (rtl) == PLUS && poly_int_rtx_p (XEXP (rtl, 1), &offset))
    {
      rtx val = internal_arg_pointer_based_exp (XEXP (rtl, 0), toplevel);
      if (val == NULL_RTX || val == pc_rtx)
	return val;
      return plus_constant (Pmode, val, offset);
    }

  /* When called at the topmost level, scan pseudo assignments in between the
     last scanned instruction in the tail call sequence and the latest insn
     in that sequence.  */
  if (toplevel)
    internal_arg_pointer_based_exp_scan ();

  if (REG_P (rtl))
    {
      unsigned int idx = REGNO (rtl) - FIRST_PSEUDO_REGISTER;
      if (idx < internal_arg_pointer_exp_state.cache.length ())
	return internal_arg_pointer_exp_state.cache[idx];

      return NULL_RTX;
    }

  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, rtl, NONCONST)
    {
      const_rtx x = *iter;
      if (REG_P (x) && internal_arg_pointer_based_exp (x, false) != NULL_RTX)
	return pc_rtx;
      if (MEM_P (x))
	iter.skip_subrtxes ();
    }

  return NULL_RTX;
}

/* Return true if SIZE bytes starting from address ADDR might overlap an
   already-clobbered argument area.  This function is used to determine
   if we should give up a sibcall.  */

static bool
mem_might_overlap_already_clobbered_arg_p (rtx addr, poly_uint64 size)
{
  poly_int64 i;
  unsigned HOST_WIDE_INT start, end;
  rtx val;

  if (bitmap_empty_p (stored_args_map)
      && stored_args_watermark == HOST_WIDE_INT_M1U)
    return false;
  val = internal_arg_pointer_based_exp (addr, true);
  if (val == NULL_RTX)
    return false;
  else if (!poly_int_rtx_p (val, &i))
    return true;

  if (known_eq (size, 0U))
    return false;

  if (STACK_GROWS_DOWNWARD)
    i -= crtl->args.pretend_args_size;
  else
    i += crtl->args.pretend_args_size;

  if (ARGS_GROW_DOWNWARD)
    i = -i - size;

  /* We can ignore any references to the function's pretend args,
     which at this point would manifest as negative values of I.  */
  if (known_le (i, 0) && known_le (size, poly_uint64 (-i)))
    return false;

  start = maybe_lt (i, 0) ? 0 : constant_lower_bound (i);
  if (!(i + size).is_constant (&end))
    end = HOST_WIDE_INT_M1U;

  if (end > stored_args_watermark)
    return true;

  end = MIN (end, SBITMAP_SIZE (stored_args_map));
  for (unsigned HOST_WIDE_INT k = start; k < end; ++k)
    if (bitmap_bit_p (stored_args_map, k))
      return true;

  return false;
}

/* Do the register loads required for any wholly-register parms or any
   parms which are passed both on the stack and in a register.  Their
   expressions were already evaluated.

   Mark all register-parms as living through the call, putting these USE
   insns in the CALL_INSN_FUNCTION_USAGE field.

   When IS_SIBCALL, perform the check_sibcall_argument_overlap
   checking, setting *SIBCALL_FAILURE if appropriate.  */

static void
load_register_parameters (struct arg_data *args, int num_actuals,
			  rtx *call_fusage, int flags, int is_sibcall,
			  int *sibcall_failure)
{
  int i, j;

  for (i = 0; i < num_actuals; i++)
    {
      rtx reg = ((flags & ECF_SIBCALL)
		 ? args[i].tail_call_reg : args[i].reg);
      if (reg)
	{
	  int partial = args[i].partial;
	  int nregs;
	  poly_int64 size = 0;
	  HOST_WIDE_INT const_size = 0;
	  rtx_insn *before_arg = get_last_insn ();
	  tree type = TREE_TYPE (args[i].tree_value);
	  if (RECORD_OR_UNION_TYPE_P (type) && TYPE_TRANSPARENT_AGGR (type))
	    type = TREE_TYPE (first_field (type));
	  /* Set non-negative if we must move a word at a time, even if
	     just one word (e.g, partial == 4 && mode == DFmode).  Set
	     to -1 if we just use a normal move insn.  This value can be
	     zero if the argument is a zero size structure.  */
	  nregs = -1;
	  if (GET_CODE (reg) == PARALLEL)
	    ;
	  else if (partial)
	    {
	      gcc_assert (partial % UNITS_PER_WORD == 0);
	      nregs = partial / UNITS_PER_WORD;
	    }
	  else if (TYPE_MODE (type) == BLKmode)
	    {
	      /* Variable-sized parameters should be described by a
		 PARALLEL instead.  */
	      const_size = int_size_in_bytes (type);
	      gcc_assert (const_size >= 0);
	      nregs = (const_size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
	      size = const_size;
	    }
	  else
	    size = GET_MODE_SIZE (args[i].mode);

	  /* Handle calls that pass values in multiple non-contiguous
	     locations.  The Irix 6 ABI has examples of this.  */

	  if (GET_CODE (reg) == PARALLEL)
	    emit_group_move (reg, args[i].parallel_value);

	  /* If simple case, just do move.  If normal partial, store_one_arg
	     has already loaded the register for us.  In all other cases,
	     load the register(s) from memory.  */

	  else if (nregs == -1)
	    {
	      emit_move_insn (reg, args[i].value);
#ifdef BLOCK_REG_PADDING
	      /* Handle case where we have a value that needs shifting
		 up to the msb.  eg. a QImode value and we're padding
		 upward on a BYTES_BIG_ENDIAN machine.  */
	      if (args[i].locate.where_pad
		  == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD))
		{
		  gcc_checking_assert (ordered_p (size, UNITS_PER_WORD));
		  if (maybe_lt (size, UNITS_PER_WORD))
		    {
		      rtx x;
		      poly_int64 shift
			= (UNITS_PER_WORD - size) * BITS_PER_UNIT;

		      /* Assigning REG here rather than a temp makes
			 CALL_FUSAGE report the whole reg as used.
			 Strictly speaking, the call only uses SIZE
			 bytes at the msb end, but it doesn't seem worth
			 generating rtl to say that.  */
		      reg = gen_rtx_REG (word_mode, REGNO (reg));
		      x = expand_shift (LSHIFT_EXPR, word_mode,
					reg, shift, reg, 1);
		      if (x != reg)
			emit_move_insn (reg, x);
		    }
		}
#endif
	    }

	  /* If we have pre-computed the values to put in the registers in
	     the case of non-aligned structures, copy them in now.  */

	  else if (args[i].n_aligned_regs != 0)
	    for (j = 0; j < args[i].n_aligned_regs; j++)
	      emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j),
			      args[i].aligned_regs[j]);

	  else if (partial == 0 || args[i].pass_on_stack)
	    {
	      /* SIZE and CONST_SIZE are 0 for partial arguments and
		 the size of a BLKmode type otherwise.  */
	      gcc_checking_assert (known_eq (size, const_size));
	      rtx mem = validize_mem (copy_rtx (args[i].value));

	      /* Check for overlap with already clobbered argument area,
	         providing that this has non-zero size.  */
	      if (is_sibcall
		  && const_size != 0
		  && (mem_might_overlap_already_clobbered_arg_p
		      (XEXP (args[i].value, 0), const_size)))
		*sibcall_failure = 1;

	      if (const_size % UNITS_PER_WORD == 0
		  || MEM_ALIGN (mem) % BITS_PER_WORD == 0)
		move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
	      else
		{
		  if (nregs > 1)
		    move_block_to_reg (REGNO (reg), mem, nregs - 1,
				       args[i].mode);
		  rtx dest = gen_rtx_REG (word_mode, REGNO (reg) + nregs - 1);
		  unsigned int bitoff = (nregs - 1) * BITS_PER_WORD;
		  unsigned int bitsize = const_size * BITS_PER_UNIT - bitoff;
		  rtx x = extract_bit_field (mem, bitsize, bitoff, 1, dest,
					     word_mode, word_mode, false,
					     NULL);
		  if (BYTES_BIG_ENDIAN)
		    x = expand_shift (LSHIFT_EXPR, word_mode, x,
				      BITS_PER_WORD - bitsize, dest, 1);
		  if (x != dest)
		    emit_move_insn (dest, x);
		}

	      /* Handle a BLKmode that needs shifting.  */
	      if (nregs == 1 && const_size < UNITS_PER_WORD
#ifdef BLOCK_REG_PADDING
		  && args[i].locate.where_pad == PAD_DOWNWARD
#else
		  && BYTES_BIG_ENDIAN
#endif
		  )
		{
		  rtx dest = gen_rtx_REG (word_mode, REGNO (reg));
		  int shift = (UNITS_PER_WORD - const_size) * BITS_PER_UNIT;
		  enum tree_code dir = (BYTES_BIG_ENDIAN
					? RSHIFT_EXPR : LSHIFT_EXPR);
		  rtx x;

		  x = expand_shift (dir, word_mode, dest, shift, dest, 1);
		  if (x != dest)
		    emit_move_insn (dest, x);
		}
	    }

	  /* When a parameter is a block, and perhaps in other cases, it is
	     possible that it did a load from an argument slot that was
	     already clobbered.  */
	  if (is_sibcall
	      && check_sibcall_argument_overlap (before_arg, &args[i], 0))
	    *sibcall_failure = 1;

	  /* Handle calls that pass values in multiple non-contiguous
	     locations.  The Irix 6 ABI has examples of this.  */
	  if (GET_CODE (reg) == PARALLEL)
	    use_group_regs (call_fusage, reg);
	  else if (nregs == -1)
	    use_reg_mode (call_fusage, reg, TYPE_MODE (type));
	  else if (nregs > 0)
	    use_regs (call_fusage, REGNO (reg), nregs);
	}
    }
}

/* We need to pop PENDING_STACK_ADJUST bytes.  But, if the arguments
   wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY
   bytes, then we would need to push some additional bytes to pad the
   arguments.  So, we try to compute an adjust to the stack pointer for an
   amount that will leave the stack under-aligned by UNADJUSTED_ARGS_SIZE
   bytes.  Then, when the arguments are pushed the stack will be perfectly
   aligned.

   Return true if this optimization is possible, storing the adjustment
   in ADJUSTMENT_OUT and setting ARGS_SIZE->CONSTANT to the number of
   bytes that should be popped after the call.  */

static bool
combine_pending_stack_adjustment_and_call (poly_int64_pod *adjustment_out,
					   poly_int64 unadjusted_args_size,
					   struct args_size *args_size,
					   unsigned int preferred_unit_stack_boundary)
{
  /* The number of bytes to pop so that the stack will be
     under-aligned by UNADJUSTED_ARGS_SIZE bytes.  */
  poly_int64 adjustment;
  /* The alignment of the stack after the arguments are pushed, if we
     just pushed the arguments without adjust the stack here.  */
  unsigned HOST_WIDE_INT unadjusted_alignment;

  if (!known_misalignment (stack_pointer_delta + unadjusted_args_size,
			   preferred_unit_stack_boundary,
			   &unadjusted_alignment))
    return false;

  /* We want to get rid of as many of the PENDING_STACK_ADJUST bytes
     as possible -- leaving just enough left to cancel out the
     UNADJUSTED_ALIGNMENT.  In other words, we want to ensure that the
     PENDING_STACK_ADJUST is non-negative, and congruent to
     -UNADJUSTED_ALIGNMENT modulo the PREFERRED_UNIT_STACK_BOUNDARY.  */

  /* Begin by trying to pop all the bytes.  */
  unsigned HOST_WIDE_INT tmp_misalignment;
  if (!known_misalignment (pending_stack_adjust,
			   preferred_unit_stack_boundary,
			   &tmp_misalignment))
    return false;
  unadjusted_alignment -= tmp_misalignment;
  adjustment = pending_stack_adjust;
  /* Push enough additional bytes that the stack will be aligned
     after the arguments are pushed.  */
  if (preferred_unit_stack_boundary > 1 && unadjusted_alignment)
    adjustment -= preferred_unit_stack_boundary - unadjusted_alignment;

  /* We need to know whether the adjusted argument size
     (UNADJUSTED_ARGS_SIZE - ADJUSTMENT) constitutes an allocation
     or a deallocation.  */
  if (!ordered_p (adjustment, unadjusted_args_size))
    return false;

  /* Now, sets ARGS_SIZE->CONSTANT so that we pop the right number of
     bytes after the call.  The right number is the entire
     PENDING_STACK_ADJUST less our ADJUSTMENT plus the amount required
     by the arguments in the first place.  */
  args_size->constant
    = pending_stack_adjust - adjustment + unadjusted_args_size;

  *adjustment_out = adjustment;
  return true;
}

/* Scan X expression if it does not dereference any argument slots
   we already clobbered by tail call arguments (as noted in stored_args_map
   bitmap).
   Return nonzero if X expression dereferences such argument slots,
   zero otherwise.  */

static int
check_sibcall_argument_overlap_1 (rtx x)
{
  RTX_CODE code;
  int i, j;
  const char *fmt;

  if (x == NULL_RTX)
    return 0;

  code = GET_CODE (x);

  /* We need not check the operands of the CALL expression itself.  */
  if (code == CALL)
    return 0;

  if (code == MEM)
    return (mem_might_overlap_already_clobbered_arg_p
	    (XEXP (x, 0), GET_MODE_SIZE (GET_MODE (x))));

  /* Scan all subexpressions.  */
  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
    {
      if (*fmt == 'e')
	{
	  if (check_sibcall_argument_overlap_1 (XEXP (x, i)))
	    return 1;
	}
      else if (*fmt == 'E')
	{
	  for (j = 0; j < XVECLEN (x, i); j++)
	    if (check_sibcall_argument_overlap_1 (XVECEXP (x, i, j)))
	      return 1;
	}
    }
  return 0;
}

/* Scan sequence after INSN if it does not dereference any argument slots
   we already clobbered by tail call arguments (as noted in stored_args_map
   bitmap).  If MARK_STORED_ARGS_MAP, add stack slots for ARG to
   stored_args_map bitmap afterwards (when ARG is a register MARK_STORED_ARGS_MAP
   should be 0).  Return nonzero if sequence after INSN dereferences such argument
   slots, zero otherwise.  */

static int
check_sibcall_argument_overlap (rtx_insn *insn, struct arg_data *arg,
				int mark_stored_args_map)
{
  poly_uint64 low, high;
  unsigned HOST_WIDE_INT const_low, const_high;

  if (insn == NULL_RTX)
    insn = get_insns ();
  else
    insn = NEXT_INSN (insn);

  for (; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn)
	&& check_sibcall_argument_overlap_1 (PATTERN (insn)))
      break;

  if (mark_stored_args_map)
    {
      if (ARGS_GROW_DOWNWARD)
	low = -arg->locate.slot_offset.constant - arg->locate.size.constant;
      else
	low = arg->locate.slot_offset.constant;
      high = low + arg->locate.size.constant;

      const_low = constant_lower_bound (low);
      if (high.is_constant (&const_high))
	for (unsigned HOST_WIDE_INT i = const_low; i < const_high; ++i)
	  bitmap_set_bit (stored_args_map, i);
      else
	stored_args_watermark = MIN (stored_args_watermark, const_low);
    }
  return insn != NULL_RTX;
}

/* Given that a function returns a value of mode MODE at the most
   significant end of hard register VALUE, shift VALUE left or right
   as specified by LEFT_P.  Return true if some action was needed.  */

bool
shift_return_value (machine_mode mode, bool left_p, rtx value)
{
  gcc_assert (REG_P (value) && HARD_REGISTER_P (value));
  machine_mode value_mode = GET_MODE (value);
  poly_int64 shift = GET_MODE_BITSIZE (value_mode) - GET_MODE_BITSIZE (mode);

  if (known_eq (shift, 0))
    return false;

  /* Use ashr rather than lshr for right shifts.  This is for the benefit
     of the MIPS port, which requires SImode values to be sign-extended
     when stored in 64-bit registers.  */
  if (!force_expand_binop (value_mode, left_p ? ashl_optab : ashr_optab,
			   value, gen_int_shift_amount (value_mode, shift),
			   value, 1, OPTAB_WIDEN))
    gcc_unreachable ();
  return true;
}

/* If X is a likely-spilled register value, copy it to a pseudo
   register and return that register.  Return X otherwise.  */

static rtx
avoid_likely_spilled_reg (rtx x)
{
  rtx new_rtx;

  if (REG_P (x)
      && HARD_REGISTER_P (x)
      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (x))))
    {
      /* Make sure that we generate a REG rather than a CONCAT.
	 Moves into CONCATs can need nontrivial instructions,
	 and the whole point of this function is to avoid
	 using the hard register directly in such a situation.  */
      generating_concat_p = 0;
      new_rtx = gen_reg_rtx (GET_MODE (x));
      generating_concat_p = 1;
      emit_move_insn (new_rtx, x);
      return new_rtx;
    }
  return x;
}

/* Helper function for expand_call.
   Return false is EXP is not implementable as a sibling call.  */

static bool
can_implement_as_sibling_call_p (tree exp,
				 rtx structure_value_addr,
				 tree funtype,
				 tree fndecl,
				 int flags,
				 tree addr,
				 const args_size &args_size)
{
  if (!targetm.have_sibcall_epilogue ())
    {
      maybe_complain_about_tail_call
	(exp,
	 "machine description does not have"
	 " a sibcall_epilogue instruction pattern");
      return false;
    }

  /* Doing sibling call optimization needs some work, since
     structure_value_addr can be allocated on the stack.
     It does not seem worth the effort since few optimizable
     sibling calls will return a structure.  */
  if (structure_value_addr != NULL_RTX)
    {
      maybe_complain_about_tail_call (exp, "callee returns a structure");
      return false;
    }

  /* Check whether the target is able to optimize the call
     into a sibcall.  */
  if (!targetm.function_ok_for_sibcall (fndecl, exp))
    {
      maybe_complain_about_tail_call (exp,
				      "target is not able to optimize the"
				      " call into a sibling call");
      return false;
    }

  /* Functions that do not return exactly once may not be sibcall
     optimized.  */
  if (flags & ECF_RETURNS_TWICE)
    {
      maybe_complain_about_tail_call (exp, "callee returns twice");
      return false;
    }
  if (flags & ECF_NORETURN)
    {
      maybe_complain_about_tail_call (exp, "callee does not return");
      return false;
    }

  if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))))
    {
      maybe_complain_about_tail_call (exp, "volatile function type");
      return false;
    }

  /* If the called function is nested in the current one, it might access
     some of the caller's arguments, but could clobber them beforehand if
     the argument areas are shared.  */
  if (fndecl && decl_function_context (fndecl) == current_function_decl)
    {
      maybe_complain_about_tail_call (exp, "nested function");
      return false;
    }

  /* If this function requires more stack slots than the current
     function, we cannot change it into a sibling call.
     crtl->args.pretend_args_size is not part of the
     stack allocated by our caller.  */
  if (maybe_gt (args_size.constant,
		crtl->args.size - crtl->args.pretend_args_size))
    {
      maybe_complain_about_tail_call (exp,
				      "callee required more stack slots"
				      " than the caller");
      return false;
    }

  /* If the callee pops its own arguments, then it must pop exactly
     the same number of arguments as the current function.  */
  if (maybe_ne (targetm.calls.return_pops_args (fndecl, funtype,
						args_size.constant),
		targetm.calls.return_pops_args (current_function_decl,
						TREE_TYPE
						(current_function_decl),
						crtl->args.size)))
    {
      maybe_complain_about_tail_call (exp,
				      "inconsistent number of"
				      " popped arguments");
      return false;
    }

  if (!lang_hooks.decls.ok_for_sibcall (fndecl))
    {
      maybe_complain_about_tail_call (exp, "frontend does not support"
					    " sibling call");
      return false;
    }

  /* All checks passed.  */
  return true;
}

/* Update stack alignment when the parameter is passed in the stack
   since the outgoing parameter requires extra alignment on the calling
   function side. */

static void
update_stack_alignment_for_call (struct locate_and_pad_arg_data *locate)
{
  if (crtl->stack_alignment_needed < locate->boundary)
    crtl->stack_alignment_needed = locate->boundary;
  if (crtl->preferred_stack_boundary < locate->boundary)
    crtl->preferred_stack_boundary = locate->boundary;
}

/* Generate all the code for a CALL_EXPR exp
   and return an rtx for its value.
   Store the value in TARGET (specified as an rtx) if convenient.
   If the value is stored in TARGET then TARGET is returned.
   If IGNORE is nonzero, then we ignore the value of the function call.  */

rtx
expand_call (tree exp, rtx target, int ignore)
{
  /* Nonzero if we are currently expanding a call.  */
  static int currently_expanding_call = 0;

  /* RTX for the function to be called.  */
  rtx funexp;
  /* Sequence of insns to perform a normal "call".  */
  rtx_insn *normal_call_insns = NULL;
  /* Sequence of insns to perform a tail "call".  */
  rtx_insn *tail_call_insns = NULL;
  /* Data type of the function.  */
  tree funtype;
  tree type_arg_types;
  tree rettype;
  /* Declaration of the function being called,
     or 0 if the function is computed (not known by name).  */
  tree fndecl = 0;
  /* The type of the function being called.  */
  tree fntype;
  bool try_tail_call = CALL_EXPR_TAILCALL (exp);
  bool must_tail_call = CALL_EXPR_MUST_TAIL_CALL (exp);
  int pass;

  /* Register in which non-BLKmode value will be returned,
     or 0 if no value or if value is BLKmode.  */
  rtx valreg;
  /* Address where we should return a BLKmode value;
     0 if value not BLKmode.  */
  rtx structure_value_addr = 0;
  /* Nonzero if that address is being passed by treating it as
     an extra, implicit first parameter.  Otherwise,
     it is passed by being copied directly into struct_value_rtx.  */
  int structure_value_addr_parm = 0;
  /* Holds the value of implicit argument for the struct value.  */
  tree structure_value_addr_value = NULL_TREE;
  /* Size of aggregate value wanted, or zero if none wanted
     or if we are using the non-reentrant PCC calling convention
     or expecting the value in registers.  */
  poly_int64 struct_value_size = 0;
  /* Nonzero if called function returns an aggregate in memory PCC style,
     by returning the address of where to find it.  */
  int pcc_struct_value = 0;
  rtx struct_value = 0;

  /* Number of actual parameters in this call, including struct value addr.  */
  int num_actuals;
  /* Number of named args.  Args after this are anonymous ones
     and they must all go on the stack.  */
  int n_named_args;
  /* Number of complex actual arguments that need to be split.  */
  int num_complex_actuals = 0;

  /* Vector of information about each argument.
     Arguments are numbered in the order they will be pushed,
     not the order they are written.  */
  struct arg_data *args;

  /* Total size in bytes of all the stack-parms scanned so far.  */
  struct args_size args_size;
  struct args_size adjusted_args_size;
  /* Size of arguments before any adjustments (such as rounding).  */
  poly_int64 unadjusted_args_size;
  /* Data on reg parms scanned so far.  */
  CUMULATIVE_ARGS args_so_far_v;
  cumulative_args_t args_so_far;
  /* Nonzero if a reg parm has been scanned.  */
  int reg_parm_seen;
  /* Nonzero if this is an indirect function call.  */

  /* Nonzero if we must avoid push-insns in the args for this call.
     If stack space is allocated for register parameters, but not by the
     caller, then it is preallocated in the fixed part of the stack frame.
     So the entire argument block must then be preallocated (i.e., we
     ignore PUSH_ROUNDING in that case).  */

  int must_preallocate = !targetm.calls.push_argument (0);

  /* Size of the stack reserved for parameter registers.  */
  int reg_parm_stack_space = 0;

  /* Address of space preallocated for stack parms
     (on machines that lack push insns), or 0 if space not preallocated.  */
  rtx argblock = 0;

  /* Mask of ECF_ and ERF_ flags.  */
  int flags = 0;
  int return_flags = 0;
#ifdef REG_PARM_STACK_SPACE
  /* Define the boundary of the register parm stack space that needs to be
     saved, if any.  */
  int low_to_save, high_to_save;
  rtx save_area = 0;		/* Place that it is saved */
#endif

  unsigned int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
  char *initial_stack_usage_map = stack_usage_map;
  unsigned HOST_WIDE_INT initial_stack_usage_watermark = stack_usage_watermark;
  char *stack_usage_map_buf = NULL;

  poly_int64 old_stack_allocated;

  /* State variables to track stack modifications.  */
  rtx old_stack_level = 0;
  int old_stack_arg_under_construction = 0;
  poly_int64 old_pending_adj = 0;
  int old_inhibit_defer_pop = inhibit_defer_pop;

  /* Some stack pointer alterations we make are performed via
     allocate_dynamic_stack_space. This modifies the stack_pointer_delta,
     which we then also need to save/restore along the way.  */
  poly_int64 old_stack_pointer_delta = 0;

  rtx call_fusage;
  tree addr = CALL_EXPR_FN (exp);
  int i;
  /* The alignment of the stack, in bits.  */
  unsigned HOST_WIDE_INT preferred_stack_boundary;
  /* The alignment of the stack, in bytes.  */
  unsigned HOST_WIDE_INT preferred_unit_stack_boundary;
  /* The static chain value to use for this call.  */
  rtx static_chain_value;
  /* See if this is "nothrow" function call.  */
  if (TREE_NOTHROW (exp))
    flags |= ECF_NOTHROW;

  /* See if we can find a DECL-node for the actual function, and get the
     function attributes (flags) from the function decl or type node.  */
  fndecl = get_callee_fndecl (exp);
  if (fndecl)
    {
      fntype = TREE_TYPE (fndecl);
      flags |= flags_from_decl_or_type (fndecl);
      return_flags |= decl_return_flags (fndecl);
    }
  else
    {
      fntype = TREE_TYPE (TREE_TYPE (addr));
      flags |= flags_from_decl_or_type (fntype);
      if (CALL_EXPR_BY_DESCRIPTOR (exp))
	flags |= ECF_BY_DESCRIPTOR;
    }
  rettype = TREE_TYPE (exp);

  struct_value = targetm.calls.struct_value_rtx (fntype, 0);

  /* Warn if this value is an aggregate type,
     regardless of which calling convention we are using for it.  */
  if (AGGREGATE_TYPE_P (rettype))
    warning (OPT_Waggregate_return, "function call has aggregate value");

  /* If the result of a non looping pure or const function call is
     ignored (or void), and none of its arguments are volatile, we can
     avoid expanding the call and just evaluate the arguments for
     side-effects.  */
  if ((flags & (ECF_CONST | ECF_PURE))
      && (!(flags & ECF_LOOPING_CONST_OR_PURE))
      && (flags & ECF_NOTHROW)
      && (ignore || target == const0_rtx
	  || TYPE_MODE (rettype) == VOIDmode))
    {
      bool volatilep = false;
      tree arg;
      call_expr_arg_iterator iter;

      FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
	if (TREE_THIS_VOLATILE (arg))
	  {
	    volatilep = true;
	    break;
	  }

      if (! volatilep)
	{
	  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
	    expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
	  return const0_rtx;
	}
    }

#ifdef REG_PARM_STACK_SPACE
  reg_parm_stack_space = REG_PARM_STACK_SPACE (!fndecl ? fntype : fndecl);
#endif

  if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))
      && reg_parm_stack_space > 0 && targetm.calls.push_argument (0))
    must_preallocate = 1;

  /* Set up a place to return a structure.  */

  /* Cater to broken compilers.  */
  if (aggregate_value_p (exp, fntype))
    {
      /* This call returns a big structure.  */
      flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE);

#ifdef PCC_STATIC_STRUCT_RETURN
      {
	pcc_struct_value = 1;
      }
#else /* not PCC_STATIC_STRUCT_RETURN */
      {
	if (!poly_int_tree_p (TYPE_SIZE_UNIT (rettype), &struct_value_size))
	  struct_value_size = -1;

	/* Even if it is semantically safe to use the target as the return
	   slot, it may be not sufficiently aligned for the return type.  */
	if (CALL_EXPR_RETURN_SLOT_OPT (exp)
	    && target
	    && MEM_P (target)
	    /* If rettype is addressable, we may not create a temporary.
	       If target is properly aligned at runtime and the compiler
	       just doesn't know about it, it will work fine, otherwise it
	       will be UB.  */
	    && (TREE_ADDRESSABLE (rettype)
		|| !(MEM_ALIGN (target) < TYPE_ALIGN (rettype)
		     && targetm.slow_unaligned_access (TYPE_MODE (rettype),
						       MEM_ALIGN (target)))))
	  structure_value_addr = XEXP (target, 0);
	else
	  {
	    /* For variable-sized objects, we must be called with a target
	       specified.  If we were to allocate space on the stack here,
	       we would have no way of knowing when to free it.  */
	    rtx d = assign_temp (rettype, 1, 1);
	    structure_value_addr = XEXP (d, 0);
	    target = 0;
	  }
      }
#endif /* not PCC_STATIC_STRUCT_RETURN */
    }

  /* Figure out the amount to which the stack should be aligned.  */
  preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
  if (fndecl)
    {
      struct cgraph_rtl_info *i = cgraph_node::rtl_info (fndecl);
      /* Without automatic stack alignment, we can't increase preferred
	 stack boundary.  With automatic stack alignment, it is
	 unnecessary since unless we can guarantee that all callers will
	 align the outgoing stack properly, callee has to align its
	 stack anyway.  */
      if (i
	  && i->preferred_incoming_stack_boundary
	  && i->preferred_incoming_stack_boundary < preferred_stack_boundary)
	preferred_stack_boundary = i->preferred_incoming_stack_boundary;
    }

  /* Operand 0 is a pointer-to-function; get the type of the function.  */
  funtype = TREE_TYPE (addr);
  gcc_assert (POINTER_TYPE_P (funtype));
  funtype = TREE_TYPE (funtype);

  /* Count whether there are actual complex arguments that need to be split
     into their real and imaginary parts.  Munge the type_arg_types
     appropriately here as well.  */
  if (targetm.calls.split_complex_arg)
    {
      call_expr_arg_iterator iter;
      tree arg;
      FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
	{
	  tree type = TREE_TYPE (arg);
	  if (type && TREE_CODE (type) == COMPLEX_TYPE
	      && targetm.calls.split_complex_arg (type))
	    num_complex_actuals++;
	}
      type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype));
    }
  else
    type_arg_types = TYPE_ARG_TYPES (funtype);

  if (flags & ECF_MAY_BE_ALLOCA)
    cfun->calls_alloca = 1;

  /* If struct_value_rtx is 0, it means pass the address
     as if it were an extra parameter.  Put the argument expression
     in structure_value_addr_value.  */
  if (structure_value_addr && struct_value == 0)
    {
      /* If structure_value_addr is a REG other than
	 virtual_outgoing_args_rtx, we can use always use it.  If it
	 is not a REG, we must always copy it into a register.
	 If it is virtual_outgoing_args_rtx, we must copy it to another
	 register in some cases.  */
      rtx temp = (!REG_P (structure_value_addr)
		  || (ACCUMULATE_OUTGOING_ARGS
		      && stack_arg_under_construction
		      && structure_value_addr == virtual_outgoing_args_rtx)
		  ? copy_addr_to_reg (convert_memory_address
				      (Pmode, structure_value_addr))
		  : structure_value_addr);

      structure_value_addr_value =
	make_tree (build_pointer_type (TREE_TYPE (funtype)), temp);
      structure_value_addr_parm = 1;
    }

  /* Count the arguments and set NUM_ACTUALS.  */
  num_actuals =
    call_expr_nargs (exp) + num_complex_actuals + structure_value_addr_parm;

  /* Compute number of named args.
     First, do a raw count of the args for INIT_CUMULATIVE_ARGS.  */

  if (type_arg_types != 0)
    n_named_args
      = (list_length (type_arg_types)
	 /* Count the struct value address, if it is passed as a parm.  */
	 + structure_value_addr_parm);
  else
    /* If we know nothing, treat all args as named.  */
    n_named_args = num_actuals;

  /* Start updating where the next arg would go.

     On some machines (such as the PA) indirect calls have a different
     calling convention than normal calls.  The fourth argument in
     INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
     or not.  */
  INIT_CUMULATIVE_ARGS (args_so_far_v, funtype, NULL_RTX, fndecl, n_named_args);
  args_so_far = pack_cumulative_args (&args_so_far_v);

  /* Now possibly adjust the number of named args.
     Normally, don't include the last named arg if anonymous args follow.
     We do include the last named arg if
     targetm.calls.strict_argument_naming() returns nonzero.
     (If no anonymous args follow, the result of list_length is actually
     one too large.  This is harmless.)

     If targetm.calls.pretend_outgoing_varargs_named() returns
     nonzero, and targetm.calls.strict_argument_naming() returns zero,
     this machine will be able to place unnamed args that were passed
     in registers into the stack.  So treat all args as named.  This
     allows the insns emitting for a specific argument list to be
     independent of the function declaration.

     If targetm.calls.pretend_outgoing_varargs_named() returns zero,
     we do not have any reliable way to pass unnamed args in
     registers, so we must force them into memory.  */

  if (type_arg_types != 0
      && targetm.calls.strict_argument_naming (args_so_far))
    ;
  else if (type_arg_types != 0
	   && ! targetm.calls.pretend_outgoing_varargs_named (args_so_far))
    /* Don't include the last named arg.  */
    --n_named_args;
  else
    /* Treat all args as named.  */
    n_named_args = num_actuals;

  /* Make a vector to hold all the information about each arg.  */
  args = XCNEWVEC (struct arg_data, num_actuals);

  /* Build up entries in the ARGS array, compute the size of the
     arguments into ARGS_SIZE, etc.  */
  initialize_argument_information (num_actuals, args, &args_size,
				   n_named_args, exp,
				   structure_value_addr_value, fndecl, fntype,
				   args_so_far, reg_parm_stack_space,
				   &old_stack_level, &old_pending_adj,
				   &must_preallocate, &flags,
				   &try_tail_call, CALL_FROM_THUNK_P (exp));

  if (args_size.var)
    must_preallocate = 1;

  /* Now make final decision about preallocating stack space.  */
  must_preallocate = finalize_must_preallocate (must_preallocate,
						num_actuals, args,
						&args_size);

  /* If the structure value address will reference the stack pointer, we
     must stabilize it.  We don't need to do this if we know that we are
     not going to adjust the stack pointer in processing this call.  */

  if (structure_value_addr
      && (reg_mentioned_p (virtual_stack_dynamic_rtx, structure_value_addr)
	  || reg_mentioned_p (virtual_outgoing_args_rtx,
			      structure_value_addr))
      && (args_size.var
	  || (!ACCUMULATE_OUTGOING_ARGS
	      && maybe_ne (args_size.constant, 0))))
    structure_value_addr = copy_to_reg (structure_value_addr);

  /* Tail calls can make things harder to debug, and we've traditionally
     pushed these optimizations into -O2.  Don't try if we're already
     expanding a call, as that means we're an argument.  Don't try if
     there's cleanups, as we know there's code to follow the call.  */
  if (currently_expanding_call++ != 0
      || (!flag_optimize_sibling_calls && !CALL_FROM_THUNK_P (exp))
      || args_size.var
      || dbg_cnt (tail_call) == false)
    try_tail_call = 0;

  /* Workaround buggy C/C++ wrappers around Fortran routines with
     character(len=constant) arguments if the hidden string length arguments
     are passed on the stack; if the callers forget to pass those arguments,
     attempting to tail call in such routines leads to stack corruption.
     Avoid tail calls in functions where at least one such hidden string
     length argument is passed (partially or fully) on the stack in the
     caller and the callee needs to pass any arguments on the stack.
     See PR90329.  */
  if (try_tail_call && maybe_ne (args_size.constant, 0))
    for (tree arg = DECL_ARGUMENTS (current_function_decl);
	 arg; arg = DECL_CHAIN (arg))
      if (DECL_HIDDEN_STRING_LENGTH (arg) && DECL_INCOMING_RTL (arg))
	{
	  subrtx_iterator::array_type array;
	  FOR_EACH_SUBRTX (iter, array, DECL_INCOMING_RTL (arg), NONCONST)
	    if (MEM_P (*iter))
	      {
		try_tail_call = 0;
		break;
	      }
	}

  /* If the user has marked the function as requiring tail-call
     optimization, attempt it.  */
  if (must_tail_call)
    try_tail_call = 1;

  /*  Rest of purposes for tail call optimizations to fail.  */
  if (try_tail_call)
    try_tail_call = can_implement_as_sibling_call_p (exp,
						     structure_value_addr,
						     funtype,
						     fndecl,
						     flags, addr, args_size);

  /* Check if caller and callee disagree in promotion of function
     return value.  */
  if (try_tail_call)
    {
      machine_mode caller_mode, caller_promoted_mode;
      machine_mode callee_mode, callee_promoted_mode;
      int caller_unsignedp, callee_unsignedp;
      tree caller_res = DECL_RESULT (current_function_decl);

      caller_unsignedp = TYPE_UNSIGNED (TREE_TYPE (caller_res));
      caller_mode = DECL_MODE (caller_res);
      callee_unsignedp = TYPE_UNSIGNED (TREE_TYPE (funtype));
      callee_mode = TYPE_MODE (TREE_TYPE (funtype));
      caller_promoted_mode
	= promote_function_mode (TREE_TYPE (caller_res), caller_mode,
				 &caller_unsignedp,
				 TREE_TYPE (current_function_decl), 1);
      callee_promoted_mode
	= promote_function_mode (TREE_TYPE (funtype), callee_mode,
				 &callee_unsignedp,
				 funtype, 1);
      if (caller_mode != VOIDmode
	  && (caller_promoted_mode != callee_promoted_mode
	      || ((caller_mode != caller_promoted_mode
		   || callee_mode != callee_promoted_mode)
		  && (caller_unsignedp != callee_unsignedp
		      || partial_subreg_p (caller_mode, callee_mode)))))
	{
	  try_tail_call = 0;
	  maybe_complain_about_tail_call (exp,
					  "caller and callee disagree in"
					  " promotion of function"
					  " return value");
	}
    }

  /* Ensure current function's preferred stack boundary is at least
     what we need.  Stack alignment may also increase preferred stack
     boundary.  */
  for (i = 0; i < num_actuals; i++)
    if (reg_parm_stack_space > 0
	|| args[i].reg == 0
	|| args[i].partial != 0
	|| args[i].pass_on_stack)
      update_stack_alignment_for_call (&args[i].locate);
  if (crtl->preferred_stack_boundary < preferred_stack_boundary)
    crtl->preferred_stack_boundary = preferred_stack_boundary;
  else
    preferred_stack_boundary = crtl->preferred_stack_boundary;

  preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;

  if (flag_callgraph_info)
    record_final_call (fndecl, EXPR_LOCATION (exp));

  /* We want to make two insn chains; one for a sibling call, the other
     for a normal call.  We will select one of the two chains after
     initial RTL generation is complete.  */
  for (pass = try_tail_call ? 0 : 1; pass < 2; pass++)
    {
      int sibcall_failure = 0;
      /* We want to emit any pending stack adjustments before the tail
	 recursion "call".  That way we know any adjustment after the tail
	 recursion call can be ignored if we indeed use the tail
	 call expansion.  */
      saved_pending_stack_adjust save;
      rtx_insn *insns, *before_call, *after_args;
      rtx next_arg_reg;

      if (pass == 0)
	{
	  /* State variables we need to save and restore between
	     iterations.  */
	  save_pending_stack_adjust (&save);
	}
      if (pass)
	flags &= ~ECF_SIBCALL;
      else
	flags |= ECF_SIBCALL;

      /* Other state variables that we must reinitialize each time
	 through the loop (that are not initialized by the loop itself).  */
      argblock = 0;
      call_fusage = 0;

      /* Start a new sequence for the normal call case.

	 From this point on, if the sibling call fails, we want to set
	 sibcall_failure instead of continuing the loop.  */
      start_sequence ();

      /* Don't let pending stack adjusts add up to too much.
	 Also, do all pending adjustments now if there is any chance
	 this might be a call to alloca or if we are expanding a sibling
	 call sequence.
	 Also do the adjustments before a throwing call, otherwise
	 exception handling can fail; PR 19225. */
      if (maybe_ge (pending_stack_adjust, 32)
	  || (maybe_ne (pending_stack_adjust, 0)
	      && (flags & ECF_MAY_BE_ALLOCA))
	  || (maybe_ne (pending_stack_adjust, 0)
	      && flag_exceptions && !(flags & ECF_NOTHROW))
	  || pass == 0)
	do_pending_stack_adjust ();

      /* Precompute any arguments as needed.  */
      if (pass)
	precompute_arguments (num_actuals, args);

      /* Now we are about to start emitting insns that can be deleted
	 if a libcall is deleted.  */
      if (pass && (flags & ECF_MALLOC))
	start_sequence ();

      if (pass == 0
	  && crtl->stack_protect_guard
	  && targetm.stack_protect_runtime_enabled_p ())
	stack_protect_epilogue ();

      adjusted_args_size = args_size;
      /* Compute the actual size of the argument block required.  The variable
	 and constant sizes must be combined, the size may have to be rounded,
	 and there may be a minimum required size.  When generating a sibcall
	 pattern, do not round up, since we'll be re-using whatever space our
	 caller provided.  */
      unadjusted_args_size
	= compute_argument_block_size (reg_parm_stack_space,
				       &adjusted_args_size,
				       fndecl, fntype,
				       (pass == 0 ? 0
					: preferred_stack_boundary));

      old_stack_allocated = stack_pointer_delta - pending_stack_adjust;

      /* The argument block when performing a sibling call is the
	 incoming argument block.  */
      if (pass == 0)
	{
	  argblock = crtl->args.internal_arg_pointer;
	  if (STACK_GROWS_DOWNWARD)
	    argblock
	      = plus_constant (Pmode, argblock, crtl->args.pretend_args_size);
	  else
	    argblock
	      = plus_constant (Pmode, argblock, -crtl->args.pretend_args_size);

	  HOST_WIDE_INT map_size = constant_lower_bound (args_size.constant);
	  stored_args_map = sbitmap_alloc (map_size);
	  bitmap_clear (stored_args_map);
	  stored_args_watermark = HOST_WIDE_INT_M1U;
	}

      /* If we have no actual push instructions, or shouldn't use them,
	 make space for all args right now.  */
      else if (adjusted_args_size.var != 0)
	{
	  if (old_stack_level == 0)
	    {
	      emit_stack_save (SAVE_BLOCK, &old_stack_level);
	      old_stack_pointer_delta = stack_pointer_delta;
	      old_pending_adj = pending_stack_adjust;
	      pending_stack_adjust = 0;
	      /* stack_arg_under_construction says whether a stack arg is
		 being constructed at the old stack level.  Pushing the stack
		 gets a clean outgoing argument block.  */
	      old_stack_arg_under_construction = stack_arg_under_construction;
	      stack_arg_under_construction = 0;
	    }
	  argblock = push_block (ARGS_SIZE_RTX (adjusted_args_size), 0, 0);
	  if (flag_stack_usage_info)
	    current_function_has_unbounded_dynamic_stack_size = 1;
	}
      else
	{
	  /* Note that we must go through the motions of allocating an argument
	     block even if the size is zero because we may be storing args
	     in the area reserved for register arguments, which may be part of
	     the stack frame.  */

	  poly_int64 needed = adjusted_args_size.constant;

	  /* Store the maximum argument space used.  It will be pushed by
	     the prologue (if ACCUMULATE_OUTGOING_ARGS, or stack overflow
	     checking).  */

	  crtl->outgoing_args_size = upper_bound (crtl->outgoing_args_size,
						  needed);

	  if (must_preallocate)
	    {
	      if (ACCUMULATE_OUTGOING_ARGS)
		{
		  /* Since the stack pointer will never be pushed, it is
		     possible for the evaluation of a parm to clobber
		     something we have already written to the stack.
		     Since most function calls on RISC machines do not use
		     the stack, this is uncommon, but must work correctly.

		     Therefore, we save any area of the stack that was already
		     written and that we are using.  Here we set up to do this
		     by making a new stack usage map from the old one.  The
		     actual save will be done by store_one_arg.

		     Another approach might be to try to reorder the argument
		     evaluations to avoid this conflicting stack usage.  */

		  /* Since we will be writing into the entire argument area,
		     the map must be allocated for its entire size, not just
		     the part that is the responsibility of the caller.  */
		  if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
		    needed += reg_parm_stack_space;

		  poly_int64 limit = needed;
		  if (ARGS_GROW_DOWNWARD)
		    limit += 1;

		  /* For polynomial sizes, this is the maximum possible
		     size needed for arguments with a constant size
		     and offset.  */
		  HOST_WIDE_INT const_limit = constant_lower_bound (limit);
		  highest_outgoing_arg_in_use
		    = MAX (initial_highest_arg_in_use, const_limit);

		  free (stack_usage_map_buf);
		  stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use);
		  stack_usage_map = stack_usage_map_buf;

		  if (initial_highest_arg_in_use)
		    memcpy (stack_usage_map, initial_stack_usage_map,
			    initial_highest_arg_in_use);

		  if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
		    memset (&stack_usage_map[initial_highest_arg_in_use], 0,
			   (highest_outgoing_arg_in_use
			    - initial_highest_arg_in_use));
		  needed = 0;

		  /* The address of the outgoing argument list must not be
		     copied to a register here, because argblock would be left
		     pointing to the wrong place after the call to
		     allocate_dynamic_stack_space below.  */

		  argblock = virtual_outgoing_args_rtx;
		}
	      else
		{
		  /* Try to reuse some or all of the pending_stack_adjust
		     to get this space.  */
		  if (inhibit_defer_pop == 0
		      && (combine_pending_stack_adjustment_and_call
			  (&needed,
			   unadjusted_args_size,
			   &adjusted_args_size,
			   preferred_unit_stack_boundary)))
		    {
		      /* combine_pending_stack_adjustment_and_call computes
			 an adjustment before the arguments are allocated.
			 Account for them and see whether or not the stack
			 needs to go up or down.  */
		      needed = unadjusted_args_size - needed;

		      /* Checked by
			 combine_pending_stack_adjustment_and_call.  */
		      gcc_checking_assert (ordered_p (needed, 0));
		      if (maybe_lt (needed, 0))
			{
			  /* We're releasing stack space.  */
			  /* ??? We can avoid any adjustment at all if we're
			     already aligned.  FIXME.  */
			  pending_stack_adjust = -needed;
			  do_pending_stack_adjust ();
			  needed = 0;
			}
		      else
			/* We need to allocate space.  We'll do that in
			   push_block below.  */
			pending_stack_adjust = 0;
		    }

		  /* Special case this because overhead of `push_block' in
		     this case is non-trivial.  */
		  if (known_eq (needed, 0))
		    argblock = virtual_outgoing_args_rtx;
		  else
		    {
		      rtx needed_rtx = gen_int_mode (needed, Pmode);
		      argblock = push_block (needed_rtx, 0, 0);
		      if (ARGS_GROW_DOWNWARD)
			argblock = plus_constant (Pmode, argblock, needed);
		    }

		  /* We only really need to call `copy_to_reg' in the case
		     where push insns are going to be used to pass ARGBLOCK
		     to a function call in ARGS.  In that case, the stack
		     pointer changes value from the allocation point to the
		     call point, and hence the value of
		     VIRTUAL_OUTGOING_ARGS_RTX changes as well.  But might
		     as well always do it.  */
		  argblock = copy_to_reg (argblock);
		}
	    }
	}

      if (ACCUMULATE_OUTGOING_ARGS)
	{
	  /* The save/restore code in store_one_arg handles all
	     cases except one: a constructor call (including a C
	     function returning a BLKmode struct) to initialize
	     an argument.  */
	  if (stack_arg_under_construction)
	    {
	      rtx push_size
		= (gen_int_mode
		   (adjusted_args_size.constant
		    + (OUTGOING_REG_PARM_STACK_SPACE (!fndecl ? fntype
						      : TREE_TYPE (fndecl))
		       ? 0 : reg_parm_stack_space), Pmode));
	      if (old_stack_level == 0)
		{
		  emit_stack_save (SAVE_BLOCK, &old_stack_level);
		  old_stack_pointer_delta = stack_pointer_delta;
		  old_pending_adj = pending_stack_adjust;
		  pending_stack_adjust = 0;
		  /* stack_arg_under_construction says whether a stack
		     arg is being constructed at the old stack level.
		     Pushing the stack gets a clean outgoing argument
		     block.  */
		  old_stack_arg_under_construction
		    = stack_arg_under_construction;
		  stack_arg_under_construction = 0;
		  /* Make a new map for the new argument list.  */
		  free (stack_usage_map_buf);
		  stack_usage_map_buf = XCNEWVEC (char, highest_outgoing_arg_in_use);
		  stack_usage_map = stack_usage_map_buf;
		  highest_outgoing_arg_in_use = 0;
		  stack_usage_watermark = HOST_WIDE_INT_M1U;
		}
	      /* We can pass TRUE as the 4th argument because we just
		 saved the stack pointer and will restore it right after
		 the call.  */
	      allocate_dynamic_stack_space (push_size, 0, BIGGEST_ALIGNMENT,
					    -1, true);
	    }

	  /* If argument evaluation might modify the stack pointer,
	     copy the address of the argument list to a register.  */
	  for (i = 0; i < num_actuals; i++)
	    if (args[i].pass_on_stack)
	      {
		argblock = copy_addr_to_reg (argblock);
		break;
	      }
	}

      compute_argument_addresses (args, argblock, num_actuals);

      /* Stack is properly aligned, pops can't safely be deferred during
	 the evaluation of the arguments.  */
      NO_DEFER_POP;

      /* Precompute all register parameters.  It isn't safe to compute
	 anything once we have started filling any specific hard regs.
	 TLS symbols sometimes need a call to resolve.  Precompute
	 register parameters before any stack pointer manipulation
	 to avoid unaligned stack in the called function.  */
      precompute_register_parameters (num_actuals, args, &reg_parm_seen);

      OK_DEFER_POP;

      /* Perform stack alignment before the first push (the last arg).  */
      if (argblock == 0
	  && maybe_gt (adjusted_args_size.constant, reg_parm_stack_space)
	  && maybe_ne (adjusted_args_size.constant, unadjusted_args_size))
	{
	  /* When the stack adjustment is pending, we get better code
	     by combining the adjustments.  */
	  if (maybe_ne (pending_stack_adjust, 0)
	      && ! inhibit_defer_pop
	      && (combine_pending_stack_adjustment_and_call
		  (&pending_stack_adjust,
		   unadjusted_args_size,
		   &adjusted_args_size,
		   preferred_unit_stack_boundary)))
	    do_pending_stack_adjust ();
	  else if (argblock == 0)
	    anti_adjust_stack (gen_int_mode (adjusted_args_size.constant
					     - unadjusted_args_size,
					     Pmode));
	}
      /* Now that the stack is properly aligned, pops can't safely
	 be deferred during the evaluation of the arguments.  */
      NO_DEFER_POP;

      /* Record the maximum pushed stack space size.  We need to delay
	 doing it this far to take into account the optimization done
	 by combine_pending_stack_adjustment_and_call.  */
      if (flag_stack_usage_info
	  && !ACCUMULATE_OUTGOING_ARGS
	  && pass
	  && adjusted_args_size.var == 0)
	{
	  poly_int64 pushed = (adjusted_args_size.constant
			       + pending_stack_adjust);
	  current_function_pushed_stack_size
	    = upper_bound (current_function_pushed_stack_size, pushed);
	}

      funexp = rtx_for_function_call (fndecl, addr);

      if (CALL_EXPR_STATIC_CHAIN (exp))
	static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp));
      else
	static_chain_value = 0;

#ifdef REG_PARM_STACK_SPACE
      /* Save the fixed argument area if it's part of the caller's frame and
	 is clobbered by argument setup for this call.  */
      if (ACCUMULATE_OUTGOING_ARGS && pass)
	save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
					      &low_to_save, &high_to_save);
#endif

      /* Now store (and compute if necessary) all non-register parms.
	 These come before register parms, since they can require block-moves,
	 which could clobber the registers used for register parms.
	 Parms which have partial registers are not stored here,
	 but we do preallocate space here if they want that.  */

      for (i = 0; i < num_actuals; i++)
	{
	  if (args[i].reg == 0 || args[i].pass_on_stack)
	    {
	      rtx_insn *before_arg = get_last_insn ();

	      /* We don't allow passing huge (> 2^30 B) arguments
	         by value.  It would cause an overflow later on.  */
	      if (constant_lower_bound (adjusted_args_size.constant)
		  >= (1 << (HOST_BITS_PER_INT - 2)))
	        {
	          sorry ("passing too large argument on stack");
		  continue;
		}

	      if (store_one_arg (&args[i], argblock, flags,
				 adjusted_args_size.var != 0,
				 reg_parm_stack_space)
		  || (pass == 0
		      && check_sibcall_argument_overlap (before_arg,
							 &args[i], 1)))
		sibcall_failure = 1;
	      }

	  if (args[i].stack)
	    call_fusage
	      = gen_rtx_EXPR_LIST (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
				   gen_rtx_USE (VOIDmode, args[i].stack),
				   call_fusage);
	}

      /* If we have a parm that is passed in registers but not in memory
	 and whose alignment does not permit a direct copy into registers,
	 make a group of pseudos that correspond to each register that we
	 will later fill.  */
      if (STRICT_ALIGNMENT)
	store_unaligned_arguments_into_pseudos (args, num_actuals);

      /* Now store any partially-in-registers parm.
	 This is the last place a block-move can happen.  */
      if (reg_parm_seen)
	for (i = 0; i < num_actuals; i++)
	  if (args[i].partial != 0 && ! args[i].pass_on_stack)
	    {
	      rtx_insn *before_arg = get_last_insn ();

	     /* On targets with weird calling conventions (e.g. PA) it's
		hard to ensure that all cases of argument overlap between
		stack and registers work.  Play it safe and bail out.  */
	      if (ARGS_GROW_DOWNWARD && !STACK_GROWS_DOWNWARD)
		{
		  sibcall_failure = 1;
		  break;
		}

	      if (store_one_arg (&args[i], argblock, flags,
				 adjusted_args_size.var != 0,
				 reg_parm_stack_space)
		  || (pass == 0
		      && check_sibcall_argument_overlap (before_arg,
							 &args[i], 1)))
		sibcall_failure = 1;
	    }

      bool any_regs = false;
      for (i = 0; i < num_actuals; i++)
	if (args[i].reg != NULL_RTX)
	  {
	    any_regs = true;
	    targetm.calls.call_args (args[i].reg, funtype);
	  }
      if (!any_regs)
	targetm.calls.call_args (pc_rtx, funtype);

      /* Figure out the register where the value, if any, will come back.  */
      valreg = 0;
      if (TYPE_MODE (rettype) != VOIDmode
	  && ! structure_value_addr)
	{
	  if (pcc_struct_value)
	    valreg = hard_function_value (build_pointer_type (rettype),
					  fndecl, NULL, (pass == 0));
	  else
	    valreg = hard_function_value (rettype, fndecl, fntype,
					  (pass == 0));

	  /* If VALREG is a PARALLEL whose first member has a zero
	     offset, use that.  This is for targets such as m68k that
	     return the same value in multiple places.  */
	  if (GET_CODE (valreg) == PARALLEL)
	    {
	      rtx elem = XVECEXP (valreg, 0, 0);
	      rtx where = XEXP (elem, 0);
	      rtx offset = XEXP (elem, 1);
	      if (offset == const0_rtx
		  && GET_MODE (where) == GET_MODE (valreg))
		valreg = where;
	    }
	}

      /* If register arguments require space on the stack and stack space
	 was not preallocated, allocate stack space here for arguments
	 passed in registers.  */
      if (OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl)))
          && !ACCUMULATE_OUTGOING_ARGS
	  && must_preallocate == 0 && reg_parm_stack_space > 0)
	anti_adjust_stack (GEN_INT (reg_parm_stack_space));

      /* Pass the function the address in which to return a
	 structure value.  */
      if (pass != 0 && structure_value_addr && ! structure_value_addr_parm)
	{
	  structure_value_addr
	    = convert_memory_address (Pmode, structure_value_addr);
	  emit_move_insn (struct_value,
			  force_reg (Pmode,
				     force_operand (structure_value_addr,
						    NULL_RTX)));

	  if (REG_P (struct_value))
	    use_reg (&call_fusage, struct_value);
	}

      after_args = get_last_insn ();
      funexp = prepare_call_address (fndecl ? fndecl : fntype, funexp,
				     static_chain_value, &call_fusage,
				     reg_parm_seen, flags);

      load_register_parameters (args, num_actuals, &call_fusage, flags,
				pass == 0, &sibcall_failure);

      /* Save a pointer to the last insn before the call, so that we can
	 later safely search backwards to find the CALL_INSN.  */
      before_call = get_last_insn ();

      /* Set up next argument register.  For sibling calls on machines
	 with register windows this should be the incoming register.  */
      if (pass == 0)
	next_arg_reg = targetm.calls.function_incoming_arg
	  (args_so_far, function_arg_info::end_marker ());
      else
	next_arg_reg = targetm.calls.function_arg
	  (args_so_far, function_arg_info::end_marker ());

      if (pass == 1 && (return_flags & ERF_RETURNS_ARG))
	{
	  int arg_nr = return_flags & ERF_RETURN_ARG_MASK;
	  arg_nr = num_actuals - arg_nr - 1;
	  if (arg_nr >= 0
	      && arg_nr < num_actuals
	      && args[arg_nr].reg
	      && valreg
	      && REG_P (valreg)
	      && GET_MODE (args[arg_nr].reg) == GET_MODE (valreg))
	  call_fusage
	    = gen_rtx_EXPR_LIST (TYPE_MODE (TREE_TYPE (args[arg_nr].tree_value)),
				 gen_rtx_SET (valreg, args[arg_nr].reg),
				 call_fusage);
	}
      /* All arguments and registers used for the call must be set up by
	 now!  */

      /* Stack must be properly aligned now.  */
      gcc_assert (!pass
		  || multiple_p (stack_pointer_delta,
				 preferred_unit_stack_boundary));

      /* Generate the actual call instruction.  */
      emit_call_1 (funexp, exp, fndecl, funtype, unadjusted_args_size,
		   adjusted_args_size.constant, struct_value_size,
		   next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
		   flags, args_so_far);

      if (flag_ipa_ra)
	{
	  rtx_call_insn *last;
	  rtx datum = NULL_RTX;
	  if (fndecl != NULL_TREE)
	    {
	      datum = XEXP (DECL_RTL (fndecl), 0);
	      gcc_assert (datum != NULL_RTX
			  && GET_CODE (datum) == SYMBOL_REF);
	    }
	  last = last_call_insn ();
	  add_reg_note (last, REG_CALL_DECL, datum);
	}

      /* If the call setup or the call itself overlaps with anything
	 of the argument setup we probably clobbered our call address.
	 In that case we can't do sibcalls.  */
      if (pass == 0
	  && check_sibcall_argument_overlap (after_args, 0, 0))
	sibcall_failure = 1;

      /* If a non-BLKmode value is returned at the most significant end
	 of a register, shift the register right by the appropriate amount
	 and update VALREG accordingly.  BLKmode values are handled by the
	 group load/store machinery below.  */
      if (!structure_value_addr
	  && !pcc_struct_value
	  && TYPE_MODE (rettype) != VOIDmode
	  && TYPE_MODE (rettype) != BLKmode
	  && REG_P (valreg)
	  && targetm.calls.return_in_msb (rettype))
	{
	  if (shift_return_value (TYPE_MODE (rettype), false, valreg))
	    sibcall_failure = 1;
	  valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg));
	}

      if (pass && (flags & ECF_MALLOC))
	{
	  rtx temp = gen_reg_rtx (GET_MODE (valreg));
	  rtx_insn *last, *insns;

	  /* The return value from a malloc-like function is a pointer.  */
	  if (TREE_CODE (rettype) == POINTER_TYPE)
	    mark_reg_pointer (temp, MALLOC_ABI_ALIGNMENT);

	  emit_move_insn (temp, valreg);

	  /* The return value from a malloc-like function cannot alias
	     anything else.  */
	  last = get_last_insn ();
	  add_reg_note (last, REG_NOALIAS, temp);

	  /* Write out the sequence.  */
	  insns = get_insns ();
	  end_sequence ();
	  emit_insn (insns);
	  valreg = temp;
	}

      /* For calls to `setjmp', etc., inform
	 function.c:setjmp_warnings that it should complain if
	 nonvolatile values are live.  For functions that cannot
	 return, inform flow that control does not fall through.  */

      if ((flags & ECF_NORETURN) || pass == 0)
	{
	  /* The barrier must be emitted
	     immediately after the CALL_INSN.  Some ports emit more
	     than just a CALL_INSN above, so we must search for it here.  */

	  rtx_insn *last = get_last_insn ();
	  while (!CALL_P (last))
	    {
	      last = PREV_INSN (last);
	      /* There was no CALL_INSN?  */
	      gcc_assert (last != before_call);
	    }

	  emit_barrier_after (last);

	  /* Stack adjustments after a noreturn call are dead code.
	     However when NO_DEFER_POP is in effect, we must preserve
	     stack_pointer_delta.  */
	  if (inhibit_defer_pop == 0)
	    {
	      stack_pointer_delta = old_stack_allocated;
	      pending_stack_adjust = 0;
	    }
	}

      /* If value type not void, return an rtx for the value.  */

      if (TYPE_MODE (rettype) == VOIDmode
	  || ignore)
	target = const0_rtx;
      else if (structure_value_addr)
	{
	  if (target == 0 || !MEM_P (target))
	    {
	      target
		= gen_rtx_MEM (TYPE_MODE (rettype),
			       memory_address (TYPE_MODE (rettype),
					       structure_value_addr));
	      set_mem_attributes (target, rettype, 1);
	    }
	}
      else if (pcc_struct_value)
	{
	  /* This is the special C++ case where we need to
	     know what the true target was.  We take care to
	     never use this value more than once in one expression.  */
	  target = gen_rtx_MEM (TYPE_MODE (rettype),
				copy_to_reg (valreg));
	  set_mem_attributes (target, rettype, 1);
	}
      /* Handle calls that return values in multiple non-contiguous locations.
	 The Irix 6 ABI has examples of this.  */
      else if (GET_CODE (valreg) == PARALLEL)
	{
	  if (target == 0)
	    target = emit_group_move_into_temps (valreg);
	  else if (rtx_equal_p (target, valreg))
	    ;
	  else if (GET_CODE (target) == PARALLEL)
	    /* Handle the result of a emit_group_move_into_temps
	       call in the previous pass.  */
	    emit_group_move (target, valreg);
	  else
	    emit_group_store (target, valreg, rettype,
			      int_size_in_bytes (rettype));
	}
      else if (target
	       && GET_MODE (target) == TYPE_MODE (rettype)
	       && GET_MODE (target) == GET_MODE (valreg))
	{
	  bool may_overlap = false;

	  /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
	     reg to a plain register.  */
	  if (!REG_P (target) || HARD_REGISTER_P (target))
	    valreg = avoid_likely_spilled_reg (valreg);

	  /* If TARGET is a MEM in the argument area, and we have
	     saved part of the argument area, then we can't store
	     directly into TARGET as it may get overwritten when we
	     restore the argument save area below.  Don't work too
	     hard though and simply force TARGET to a register if it
	     is a MEM; the optimizer is quite likely to sort it out.  */
	  if (ACCUMULATE_OUTGOING_ARGS && pass && MEM_P (target))
	    for (i = 0; i < num_actuals; i++)
	      if (args[i].save_area)
		{
		  may_overlap = true;
		  break;
		}

	  if (may_overlap)
	    target = copy_to_reg (valreg);
	  else
	    {
	      /* TARGET and VALREG cannot be equal at this point
		 because the latter would not have
		 REG_FUNCTION_VALUE_P true, while the former would if
		 it were referring to the same register.

		 If they refer to the same register, this move will be
		 a no-op, except when function inlining is being
		 done.  */
	      emit_move_insn (target, valreg);

	      /* If we are setting a MEM, this code must be executed.
		 Since it is emitted after the call insn, sibcall
		 optimization cannot be performed in that case.  */
	      if (MEM_P (target))
		sibcall_failure = 1;
	    }
	}
      else
	target = copy_to_reg (avoid_likely_spilled_reg (valreg));

      /* If we promoted this return value, make the proper SUBREG.
         TARGET might be const0_rtx here, so be careful.  */
      if (REG_P (target)
	  && TYPE_MODE (rettype) != BLKmode
	  && GET_MODE (target) != TYPE_MODE (rettype))
	{
	  tree type = rettype;
	  int unsignedp = TYPE_UNSIGNED (type);
	  machine_mode pmode;

	  /* Ensure we promote as expected, and get the new unsignedness.  */
	  pmode = promote_function_mode (type, TYPE_MODE (type), &unsignedp,
					 funtype, 1);
	  gcc_assert (GET_MODE (target) == pmode);

	  poly_uint64 offset = subreg_lowpart_offset (TYPE_MODE (type),
						      GET_MODE (target));
	  target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
	  SUBREG_PROMOTED_VAR_P (target) = 1;
	  SUBREG_PROMOTED_SET (target, unsignedp);
	}

      /* If size of args is variable or this was a constructor call for a stack
	 argument, restore saved stack-pointer value.  */

      if (old_stack_level)
	{
	  rtx_insn *prev = get_last_insn ();

	  emit_stack_restore (SAVE_BLOCK, old_stack_level);
	  stack_pointer_delta = old_stack_pointer_delta;

	  fixup_args_size_notes (prev, get_last_insn (), stack_pointer_delta);

	  pending_stack_adjust = old_pending_adj;
	  old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
	  stack_arg_under_construction = old_stack_arg_under_construction;
	  highest_outgoing_arg_in_use = initial_highest_arg_in_use;
	  stack_usage_map = initial_stack_usage_map;
	  stack_usage_watermark = initial_stack_usage_watermark;
	  sibcall_failure = 1;
	}
      else if (ACCUMULATE_OUTGOING_ARGS && pass)
	{
#ifdef REG_PARM_STACK_SPACE
	  if (save_area)
	    restore_fixed_argument_area (save_area, argblock,
					 high_to_save, low_to_save);
#endif

	  /* If we saved any argument areas, restore them.  */
	  for (i = 0; i < num_actuals; i++)
	    if (args[i].save_area)
	      {
		machine_mode save_mode = GET_MODE (args[i].save_area);
		rtx stack_area
		  = gen_rtx_MEM (save_mode,
				 memory_address (save_mode,
						 XEXP (args[i].stack_slot, 0)));

		if (save_mode != BLKmode)
		  emit_move_insn (stack_area, args[i].save_area);
		else
		  emit_block_move (stack_area, args[i].save_area,
				   (gen_int_mode
				    (args[i].locate.size.constant, Pmode)),
				   BLOCK_OP_CALL_PARM);
	      }

	  highest_outgoing_arg_in_use = initial_highest_arg_in_use;
	  stack_usage_map = initial_stack_usage_map;
	  stack_usage_watermark = initial_stack_usage_watermark;
	}

      /* If this was alloca, record the new stack level.  */
      if (flags & ECF_MAY_BE_ALLOCA)
	record_new_stack_level ();

      /* Free up storage we no longer need.  */
      for (i = 0; i < num_actuals; ++i)
	free (args[i].aligned_regs);

      targetm.calls.end_call_args ();

      insns = get_insns ();
      end_sequence ();

      if (pass == 0)
	{
	  tail_call_insns = insns;

	  /* Restore the pending stack adjustment now that we have
	     finished generating the sibling call sequence.  */

	  restore_pending_stack_adjust (&save);

	  /* Prepare arg structure for next iteration.  */
	  for (i = 0; i < num_actuals; i++)
	    {
	      args[i].value = 0;
	      args[i].aligned_regs = 0;
	      args[i].stack = 0;
	    }

	  sbitmap_free (stored_args_map);
	  internal_arg_pointer_exp_state.scan_start = NULL;
	  internal_arg_pointer_exp_state.cache.release ();
	}
      else
	{
	  normal_call_insns = insns;

	  /* Verify that we've deallocated all the stack we used.  */
	  gcc_assert ((flags & ECF_NORETURN)
		      || known_eq (old_stack_allocated,
				   stack_pointer_delta
				   - pending_stack_adjust));
	}

      /* If something prevents making this a sibling call,
	 zero out the sequence.  */
      if (sibcall_failure)
	tail_call_insns = NULL;
      else
	break;
    }

  /* If tail call production succeeded, we need to remove REG_EQUIV notes on
     arguments too, as argument area is now clobbered by the call.  */
  if (tail_call_insns)
    {
      emit_insn (tail_call_insns);
      crtl->tail_call_emit = true;
    }
  else
    {
      emit_insn (normal_call_insns);
      if (try_tail_call)
	/* Ideally we'd emit a message for all of the ways that it could
	   have failed.  */
	maybe_complain_about_tail_call (exp, "tail call production failed");
    }

  currently_expanding_call--;

  free (stack_usage_map_buf);
  free (args);
  return target;
}

/* A sibling call sequence invalidates any REG_EQUIV notes made for
   this function's incoming arguments.

   At the start of RTL generation we know the only REG_EQUIV notes
   in the rtl chain are those for incoming arguments, so we can look
   for REG_EQUIV notes between the start of the function and the
   NOTE_INSN_FUNCTION_BEG.

   This is (slight) overkill.  We could keep track of the highest
   argument we clobber and be more selective in removing notes, but it
   does not seem to be worth the effort.  */

void
fixup_tail_calls (void)
{
  rtx_insn *insn;

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      rtx note;

      /* There are never REG_EQUIV notes for the incoming arguments
	 after the NOTE_INSN_FUNCTION_BEG note, so stop if we see it.  */
      if (NOTE_P (insn)
	  && NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
	break;

      note = find_reg_note (insn, REG_EQUIV, 0);
      if (note)
	remove_note (insn, note);
      note = find_reg_note (insn, REG_EQUIV, 0);
      gcc_assert (!note);
    }
}

/* Traverse a list of TYPES and expand all complex types into their
   components.  */
static tree
split_complex_types (tree types)
{
  tree p;

  /* Before allocating memory, check for the common case of no complex.  */
  for (p = types; p; p = TREE_CHAIN (p))
    {
      tree type = TREE_VALUE (p);
      if (TREE_CODE (type) == COMPLEX_TYPE
	  && targetm.calls.split_complex_arg (type))
	goto found;
    }
  return types;

 found:
  types = copy_list (types);

  for (p = types; p; p = TREE_CHAIN (p))
    {
      tree complex_type = TREE_VALUE (p);

      if (TREE_CODE (complex_type) == COMPLEX_TYPE
	  && targetm.calls.split_complex_arg (complex_type))
	{
	  tree next, imag;

	  /* Rewrite complex type with component type.  */
	  TREE_VALUE (p) = TREE_TYPE (complex_type);
	  next = TREE_CHAIN (p);

	  /* Add another component type for the imaginary part.  */
	  imag = build_tree_list (NULL_TREE, TREE_VALUE (p));
	  TREE_CHAIN (p) = imag;
	  TREE_CHAIN (imag) = next;

	  /* Skip the newly created node.  */
	  p = TREE_CHAIN (p);
	}
    }

  return types;
}

/* Output a library call to function ORGFUN (a SYMBOL_REF rtx)
   for a value of mode OUTMODE,
   with NARGS different arguments, passed as ARGS.
   Store the return value if RETVAL is nonzero: store it in VALUE if
   VALUE is nonnull, otherwise pick a convenient location.  In either
   case return the location of the stored value.

   FN_TYPE should be LCT_NORMAL for `normal' calls, LCT_CONST for
   `const' calls, LCT_PURE for `pure' calls, or another LCT_ value for
   other types of library calls.  */

rtx
emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
			   enum libcall_type fn_type,
			   machine_mode outmode, int nargs, rtx_mode_t *args)
{
  /* Total size in bytes of all the stack-parms scanned so far.  */
  struct args_size args_size;
  /* Size of arguments before any adjustments (such as rounding).  */
  struct args_size original_args_size;
  int argnum;
  rtx fun;
  /* Todo, choose the correct decl type of orgfun. Sadly this information
     isn't present here, so we default to native calling abi here.  */
  tree fndecl ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */
  tree fntype ATTRIBUTE_UNUSED = NULL_TREE; /* library calls default to host calling abi ? */
  int count;
  rtx argblock = 0;
  CUMULATIVE_ARGS args_so_far_v;
  cumulative_args_t args_so_far;
  struct arg
  {
    rtx value;
    machine_mode mode;
    rtx reg;
    int partial;
    struct locate_and_pad_arg_data locate;
    rtx save_area;
  };
  struct arg *argvec;
  int old_inhibit_defer_pop = inhibit_defer_pop;
  rtx call_fusage = 0;
  rtx mem_value = 0;
  rtx valreg;
  int pcc_struct_value = 0;
  poly_int64 struct_value_size = 0;
  int flags;
  int reg_parm_stack_space = 0;
  poly_int64 needed;
  rtx_insn *before_call;
  bool have_push_fusage;
  tree tfom;			/* type_for_mode (outmode, 0) */

#ifdef REG_PARM_STACK_SPACE
  /* Define the boundary of the register parm stack space that needs to be
     save, if any.  */
  int low_to_save = 0, high_to_save = 0;
  rtx save_area = 0;            /* Place that it is saved.  */
#endif

  /* Size of the stack reserved for parameter registers.  */
  unsigned int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
  char *initial_stack_usage_map = stack_usage_map;
  unsigned HOST_WIDE_INT initial_stack_usage_watermark = stack_usage_watermark;
  char *stack_usage_map_buf = NULL;

  rtx struct_value = targetm.calls.struct_value_rtx (0, 0);

#ifdef REG_PARM_STACK_SPACE
  reg_parm_stack_space = REG_PARM_STACK_SPACE ((tree) 0);
#endif

  /* By default, library functions cannot throw.  */
  flags = ECF_NOTHROW;

  switch (fn_type)
    {
    case LCT_NORMAL:
      break;
    case LCT_CONST:
      flags |= ECF_CONST;
      break;
    case LCT_PURE:
      flags |= ECF_PURE;
      break;
    case LCT_NORETURN:
      flags |= ECF_NORETURN;
      break;
    case LCT_THROW:
      flags &= ~ECF_NOTHROW;
      break;
    case LCT_RETURNS_TWICE:
      flags = ECF_RETURNS_TWICE;
      break;
    }
  fun = orgfun;

  /* Ensure current function's preferred stack boundary is at least
     what we need.  */
  if (crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
    crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;

  /* If this kind of value comes back in memory,
     decide where in memory it should come back.  */
  if (outmode != VOIDmode)
    {
      tfom = lang_hooks.types.type_for_mode (outmode, 0);
      if (aggregate_value_p (tfom, 0))
	{
#ifdef PCC_STATIC_STRUCT_RETURN
	  rtx pointer_reg
	    = hard_function_value (build_pointer_type (tfom), 0, 0, 0);
	  mem_value = gen_rtx_MEM (outmode, pointer_reg);
	  pcc_struct_value = 1;
	  if (value == 0)
	    value = gen_reg_rtx (outmode);
#else /* not PCC_STATIC_STRUCT_RETURN */
	  struct_value_size = GET_MODE_SIZE (outmode);
	  if (value != 0 && MEM_P (value))
	    mem_value = value;
	  else
	    mem_value = assign_temp (tfom, 1, 1);
#endif
	  /* This call returns a big structure.  */
	  flags &= ~(ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE);
	}
    }
  else
    tfom = void_type_node;

  /* ??? Unfinished: must pass the memory address as an argument.  */

  /* Copy all the libcall-arguments out of the varargs data
     and into a vector ARGVEC.

     Compute how to pass each argument.  We only support a very small subset
     of the full argument passing conventions to limit complexity here since
     library functions shouldn't have many args.  */

  argvec = XALLOCAVEC (struct arg, nargs + 1);
  memset (argvec, 0, (nargs + 1) * sizeof (struct arg));

#ifdef INIT_CUMULATIVE_LIBCALL_ARGS
  INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far_v, outmode, fun);
#else
  INIT_CUMULATIVE_ARGS (args_so_far_v, NULL_TREE, fun, 0, nargs);
#endif
  args_so_far = pack_cumulative_args (&args_so_far_v);

  args_size.constant = 0;
  args_size.var = 0;

  count = 0;

  push_temp_slots ();

  /* If there's a structure value address to be passed,
     either pass it in the special place, or pass it as an extra argument.  */
  if (mem_value && struct_value == 0 && ! pcc_struct_value)
    {
      rtx addr = XEXP (mem_value, 0);

      nargs++;

      /* Make sure it is a reasonable operand for a move or push insn.  */
      if (!REG_P (addr) && !MEM_P (addr)
	  && !(CONSTANT_P (addr)
	       && targetm.legitimate_constant_p (Pmode, addr)))
	addr = force_operand (addr, NULL_RTX);

      argvec[count].value = addr;
      argvec[count].mode = Pmode;
      argvec[count].partial = 0;

      function_arg_info ptr_arg (Pmode, /*named=*/true);
      argvec[count].reg = targetm.calls.function_arg (args_so_far, ptr_arg);
      gcc_assert (targetm.calls.arg_partial_bytes (args_so_far, ptr_arg) == 0);

      locate_and_pad_parm (Pmode, NULL_TREE,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
			   1,
#else
			   argvec[count].reg != 0,
#endif
			   reg_parm_stack_space, 0,
			   NULL_TREE, &args_size, &argvec[count].locate);

      if (argvec[count].reg == 0 || argvec[count].partial != 0
	  || reg_parm_stack_space > 0)
	args_size.constant += argvec[count].locate.size.constant;

      targetm.calls.function_arg_advance (args_so_far, ptr_arg);

      count++;
    }

  for (unsigned int i = 0; count < nargs; i++, count++)
    {
      rtx val = args[i].first;
      function_arg_info arg (args[i].second, /*named=*/true);
      int unsigned_p = 0;

      /* We cannot convert the arg value to the mode the library wants here;
	 must do it earlier where we know the signedness of the arg.  */
      gcc_assert (arg.mode != BLKmode
		  && (GET_MODE (val) == arg.mode
		      || GET_MODE (val) == VOIDmode));

      /* Make sure it is a reasonable operand for a move or push insn.  */
      if (!REG_P (val) && !MEM_P (val)
	  && !(CONSTANT_P (val)
	       && targetm.legitimate_constant_p (arg.mode, val)))
	val = force_operand (val, NULL_RTX);

      if (pass_by_reference (&args_so_far_v, arg))
	{
	  rtx slot;
	  int must_copy = !reference_callee_copied (&args_so_far_v, arg);

	  /* If this was a CONST function, it is now PURE since it now
	     reads memory.  */
	  if (flags & ECF_CONST)
	    {
	      flags &= ~ECF_CONST;
	      flags |= ECF_PURE;
	    }

	  if (MEM_P (val) && !must_copy)
	    {
	      tree val_expr = MEM_EXPR (val);
	      if (val_expr)
		mark_addressable (val_expr);
	      slot = val;
	    }
	  else
	    {
	      slot = assign_temp (lang_hooks.types.type_for_mode (arg.mode, 0),
				  1, 1);
	      emit_move_insn (slot, val);
	    }

	  call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
					   gen_rtx_USE (VOIDmode, slot),
					   call_fusage);
	  if (must_copy)
	    call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
					     gen_rtx_CLOBBER (VOIDmode,
							      slot),
					     call_fusage);

	  arg.mode = Pmode;
	  arg.pass_by_reference = true;
	  val = force_operand (XEXP (slot, 0), NULL_RTX);
	}

      arg.mode = promote_function_mode (NULL_TREE, arg.mode, &unsigned_p,
					NULL_TREE, 0);
      argvec[count].mode = arg.mode;
      argvec[count].value = convert_modes (arg.mode, GET_MODE (val), val,
					   unsigned_p);
      argvec[count].reg = targetm.calls.function_arg (args_so_far, arg);

      argvec[count].partial
	= targetm.calls.arg_partial_bytes (args_so_far, arg);

      if (argvec[count].reg == 0
	  || argvec[count].partial != 0
	  || reg_parm_stack_space > 0)
	{
	  locate_and_pad_parm (arg.mode, NULL_TREE,
#ifdef STACK_PARMS_IN_REG_PARM_AREA
			       1,
#else
			       argvec[count].reg != 0,
#endif
			       reg_parm_stack_space, argvec[count].partial,
			       NULL_TREE, &args_size, &argvec[count].locate);
	  args_size.constant += argvec[count].locate.size.constant;
	  gcc_assert (!argvec[count].locate.size.var);
	}
#ifdef BLOCK_REG_PADDING
      else
	/* The argument is passed entirely in registers.  See at which
	   end it should be padded.  */
	argvec[count].locate.where_pad =
	  BLOCK_REG_PADDING (arg.mode, NULL_TREE,
			     known_le (GET_MODE_SIZE (arg.mode),
				       UNITS_PER_WORD));
#endif

      targetm.calls.function_arg_advance (args_so_far, arg);
    }

  for (int i = 0; i < nargs; i++)
    if (reg_parm_stack_space > 0
	|| argvec[i].reg == 0
	|| argvec[i].partial != 0)
      update_stack_alignment_for_call (&argvec[i].locate);

  /* If this machine requires an external definition for library
     functions, write one out.  */
  assemble_external_libcall (fun);

  original_args_size = args_size;
  args_size.constant = (aligned_upper_bound (args_size.constant
					     + stack_pointer_delta,
					     STACK_BYTES)
			- stack_pointer_delta);

  args_size.constant = upper_bound (args_size.constant,
				    reg_parm_stack_space);

  if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
    args_size.constant -= reg_parm_stack_space;

  crtl->outgoing_args_size = upper_bound (crtl->outgoing_args_size,
					  args_size.constant);

  if (flag_stack_usage_info && !ACCUMULATE_OUTGOING_ARGS)
    {
      poly_int64 pushed = args_size.constant + pending_stack_adjust;
      current_function_pushed_stack_size
	= upper_bound (current_function_pushed_stack_size, pushed);
    }

  if (ACCUMULATE_OUTGOING_ARGS)
    {
      /* Since the stack pointer will never be pushed, it is possible for
	 the evaluation of a parm to clobber something we have already
	 written to the stack.  Since most function calls on RISC machines
	 do not use the stack, this is uncommon, but must work correctly.

	 Therefore, we save any area of the stack that was already written
	 and that we are using.  Here we set up to do this by making a new
	 stack usage map from the old one.

	 Another approach might be to try to reorder the argument
	 evaluations to avoid this conflicting stack usage.  */

      needed = args_size.constant;

      /* Since we will be writing into the entire argument area, the
	 map must be allocated for its entire size, not just the part that
	 is the responsibility of the caller.  */
      if (! OUTGOING_REG_PARM_STACK_SPACE ((!fndecl ? fntype : TREE_TYPE (fndecl))))
	needed += reg_parm_stack_space;

      poly_int64 limit = needed;
      if (ARGS_GROW_DOWNWARD)
	limit += 1;

      /* For polynomial sizes, this is the maximum possible size needed
	 for arguments with a constant size and offset.  */
      HOST_WIDE_INT const_limit = constant_lower_bound (limit);
      highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
					 const_limit);

      stack_usage_map_buf = XNEWVEC (char, highest_outgoing_arg_in_use);
      stack_usage_map = stack_usage_map_buf;

      if (initial_highest_arg_in_use)
	memcpy (stack_usage_map, initial_stack_usage_map,
		initial_highest_arg_in_use);

      if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
	memset (&stack_usage_map[initial_highest_arg_in_use], 0,
	       highest_outgoing_arg_in_use - initial_highest_arg_in_use);
      needed = 0;

      /* We must be careful to use virtual regs before they're instantiated,
	 and real regs afterwards.  Loop optimization, for example, can create
	 new libcalls after we've instantiated the virtual regs, and if we
	 use virtuals anyway, they won't match the rtl patterns.  */

      if (virtuals_instantiated)
	argblock = plus_constant (Pmode, stack_pointer_rtx,
				  STACK_POINTER_OFFSET);
      else
	argblock = virtual_outgoing_args_rtx;
    }
  else
    {
      if (!targetm.calls.push_argument (0))
	argblock = push_block (gen_int_mode (args_size.constant, Pmode), 0, 0);
    }

  /* We push args individually in reverse order, perform stack alignment
     before the first push (the last arg).  */
  if (argblock == 0)
    anti_adjust_stack (gen_int_mode (args_size.constant
				     - original_args_size.constant,
				     Pmode));

  argnum = nargs - 1;

#ifdef REG_PARM_STACK_SPACE
  if (ACCUMULATE_OUTGOING_ARGS)
    {
      /* The argument list is the property of the called routine and it
	 may clobber it.  If the fixed area has been used for previous
	 parameters, we must save and restore it.  */
      save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
					    &low_to_save, &high_to_save);
    }
#endif

  /* When expanding a normal call, args are stored in push order,
     which is the reverse of what we have here.  */
  bool any_regs = false;
  for (int i = nargs; i-- > 0; )
    if (argvec[i].reg != NULL_RTX)
      {
	targetm.calls.call_args (argvec[i].reg, NULL_TREE);
	any_regs = true;
      }
  if (!any_regs)
    targetm.calls.call_args (pc_rtx, NULL_TREE);

  /* Push the args that need to be pushed.  */

  have_push_fusage = false;

  /* ARGNUM indexes the ARGVEC array in the order in which the arguments
     are to be pushed.  */
  for (count = 0; count < nargs; count++, argnum--)
    {
      machine_mode mode = argvec[argnum].mode;
      rtx val = argvec[argnum].value;
      rtx reg = argvec[argnum].reg;
      int partial = argvec[argnum].partial;
      unsigned int parm_align = argvec[argnum].locate.boundary;
      poly_int64 lower_bound = 0, upper_bound = 0;

      if (! (reg != 0 && partial == 0))
	{
	  rtx use;

	  if (ACCUMULATE_OUTGOING_ARGS)
	    {
	      /* If this is being stored into a pre-allocated, fixed-size,
		 stack area, save any previous data at that location.  */

	      if (ARGS_GROW_DOWNWARD)
		{
		  /* stack_slot is negative, but we want to index stack_usage_map
		     with positive values.  */
		  upper_bound = -argvec[argnum].locate.slot_offset.constant + 1;
		  lower_bound = upper_bound - argvec[argnum].locate.size.constant;
		}
	      else
		{
		  lower_bound = argvec[argnum].locate.slot_offset.constant;
		  upper_bound = lower_bound + argvec[argnum].locate.size.constant;
		}

	      if (stack_region_maybe_used_p (lower_bound, upper_bound,
					     reg_parm_stack_space))
		{
		  /* We need to make a save area.  */
		  poly_uint64 size
		    = argvec[argnum].locate.size.constant * BITS_PER_UNIT;
		  machine_mode save_mode
		    = int_mode_for_size (size, 1).else_blk ();
		  rtx adr
		    = plus_constant (Pmode, argblock,
				     argvec[argnum].locate.offset.constant);
		  rtx stack_area
		    = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));

		  if (save_mode == BLKmode)
		    {
		      argvec[argnum].save_area
			= assign_stack_temp (BLKmode,
					     argvec[argnum].locate.size.constant
					     );

		      emit_block_move (validize_mem
				         (copy_rtx (argvec[argnum].save_area)),
				       stack_area,
				       (gen_int_mode
					(argvec[argnum].locate.size.constant,
					 Pmode)),
				       BLOCK_OP_CALL_PARM);
		    }
		  else
		    {
		      argvec[argnum].save_area = gen_reg_rtx (save_mode);

		      emit_move_insn (argvec[argnum].save_area, stack_area);
		    }
		}
	    }

	  emit_push_insn (val, mode, NULL_TREE, NULL_RTX, parm_align,
			  partial, reg, 0, argblock,
			  (gen_int_mode
			   (argvec[argnum].locate.offset.constant, Pmode)),
			  reg_parm_stack_space,
			  ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad), false);

	  /* Now mark the segment we just used.  */
	  if (ACCUMULATE_OUTGOING_ARGS)
	    mark_stack_region_used (lower_bound, upper_bound);

	  NO_DEFER_POP;

	  /* Indicate argument access so that alias.c knows that these
	     values are live.  */
	  if (argblock)
	    use = plus_constant (Pmode, argblock,
				 argvec[argnum].locate.offset.constant);
	  else if (have_push_fusage)
	    continue;
	  else
	    {
	      /* When arguments are pushed, trying to tell alias.c where
		 exactly this argument is won't work, because the
		 auto-increment causes confusion.  So we merely indicate
		 that we access something with a known mode somewhere on
		 the stack.  */
	      use = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
				  gen_rtx_SCRATCH (Pmode));
	      have_push_fusage = true;
	    }
	  use = gen_rtx_MEM (argvec[argnum].mode, use);
	  use = gen_rtx_USE (VOIDmode, use);
	  call_fusage = gen_rtx_EXPR_LIST (VOIDmode, use, call_fusage);
	}
    }

  argnum = nargs - 1;

  fun = prepare_call_address (NULL, fun, NULL, &call_fusage, 0, 0);

  /* Now load any reg parms into their regs.  */

  /* ARGNUM indexes the ARGVEC array in the order in which the arguments
     are to be pushed.  */
  for (count = 0; count < nargs; count++, argnum--)
    {
      machine_mode mode = argvec[argnum].mode;
      rtx val = argvec[argnum].value;
      rtx reg = argvec[argnum].reg;
      int partial = argvec[argnum].partial;
      
      /* Handle calls that pass values in multiple non-contiguous
	 locations.  The PA64 has examples of this for library calls.  */
      if (reg != 0 && GET_CODE (reg) == PARALLEL)
	emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (mode));
      else if (reg != 0 && partial == 0)
        {
	  emit_move_insn (reg, val);
#ifdef BLOCK_REG_PADDING
	  poly_int64 size = GET_MODE_SIZE (argvec[argnum].mode);

	  /* Copied from load_register_parameters.  */

	  /* Handle case where we have a value that needs shifting
	     up to the msb.  eg. a QImode value and we're padding
	     upward on a BYTES_BIG_ENDIAN machine.  */
	  if (known_lt (size, UNITS_PER_WORD)
	      && (argvec[argnum].locate.where_pad
		  == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
	    {
	      rtx x;
	      poly_int64 shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;

	      /* Assigning REG here rather than a temp makes CALL_FUSAGE
		 report the whole reg as used.  Strictly speaking, the
		 call only uses SIZE bytes at the msb end, but it doesn't
		 seem worth generating rtl to say that.  */
	      reg = gen_rtx_REG (word_mode, REGNO (reg));
	      x = expand_shift (LSHIFT_EXPR, word_mode, reg, shift, reg, 1);
	      if (x != reg)
		emit_move_insn (reg, x);
	    }
#endif
	}

      NO_DEFER_POP;
    }

  /* Any regs containing parms remain in use through the call.  */
  for (count = 0; count < nargs; count++)
    {
      rtx reg = argvec[count].reg;
      if (reg != 0 && GET_CODE (reg) == PARALLEL)
	use_group_regs (&call_fusage, reg);
      else if (reg != 0)
        {
	  int partial = argvec[count].partial;
	  if (partial)
	    {
	      int nregs;
              gcc_assert (partial % UNITS_PER_WORD == 0);
	      nregs = partial / UNITS_PER_WORD;
	      use_regs (&call_fusage, REGNO (reg), nregs);
	    }
	  else
	    use_reg (&call_fusage, reg);
	}
    }

  /* Pass the function the address in which to return a structure value.  */
  if (mem_value != 0 && struct_value != 0 && ! pcc_struct_value)
    {
      emit_move_insn (struct_value,
		      force_reg (Pmode,
				 force_operand (XEXP (mem_value, 0),
						NULL_RTX)));
      if (REG_P (struct_value))
	use_reg (&call_fusage, struct_value);
    }

  /* Don't allow popping to be deferred, since then
     cse'ing of library calls could delete a call and leave the pop.  */
  NO_DEFER_POP;
  valreg = (mem_value == 0 && outmode != VOIDmode
	    ? hard_libcall_value (outmode, orgfun) : NULL_RTX);

  /* Stack must be properly aligned now.  */
  gcc_assert (multiple_p (stack_pointer_delta,
			  PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT));

  before_call = get_last_insn ();

  if (flag_callgraph_info)
    record_final_call (SYMBOL_REF_DECL (orgfun), UNKNOWN_LOCATION);

  /* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
     will set inhibit_defer_pop to that value.  */
  /* The return type is needed to decide how many bytes the function pops.
     Signedness plays no role in that, so for simplicity, we pretend it's
     always signed.  We also assume that the list of arguments passed has
     no impact, so we pretend it is unknown.  */

  emit_call_1 (fun, NULL,
	       get_identifier (XSTR (orgfun, 0)),
	       build_function_type (tfom, NULL_TREE),
	       original_args_size.constant, args_size.constant,
	       struct_value_size,
	       targetm.calls.function_arg (args_so_far,
					   function_arg_info::end_marker ()),
	       valreg,
	       old_inhibit_defer_pop + 1, call_fusage, flags, args_so_far);

  if (flag_ipa_ra)
    {
      rtx datum = orgfun;
      gcc_assert (GET_CODE (datum) == SYMBOL_REF);
      rtx_call_insn *last = last_call_insn ();
      add_reg_note (last, REG_CALL_DECL, datum);
    }

  /* Right-shift returned value if necessary.  */
  if (!pcc_struct_value
      && TYPE_MODE (tfom) != BLKmode
      && targetm.calls.return_in_msb (tfom))
    {
      shift_return_value (TYPE_MODE (tfom), false, valreg);
      valreg = gen_rtx_REG (TYPE_MODE (tfom), REGNO (valreg));
    }

  targetm.calls.end_call_args ();

  /* For calls to `setjmp', etc., inform function.c:setjmp_warnings
     that it should complain if nonvolatile values are live.  For
     functions that cannot return, inform flow that control does not
     fall through.  */
  if (flags & ECF_NORETURN)
    {
      /* The barrier note must be emitted
	 immediately after the CALL_INSN.  Some ports emit more than
	 just a CALL_INSN above, so we must search for it here.  */
      rtx_insn *last = get_last_insn ();
      while (!CALL_P (last))
	{
	  last = PREV_INSN (last);
	  /* There was no CALL_INSN?  */
	  gcc_assert (last != before_call);
	}

      emit_barrier_after (last);
    }

  /* Consider that "regular" libcalls, i.e. all of them except for LCT_THROW
     and LCT_RETURNS_TWICE, cannot perform non-local gotos.  */
  if (flags & ECF_NOTHROW)
    {
      rtx_insn *last = get_last_insn ();
      while (!CALL_P (last))
	{
	  last = PREV_INSN (last);
	  /* There was no CALL_INSN?  */
	  gcc_assert (last != before_call);
	}

      make_reg_eh_region_note_nothrow_nononlocal (last);
    }

  /* Now restore inhibit_defer_pop to its actual original value.  */
  OK_DEFER_POP;

  pop_temp_slots ();

  /* Copy the value to the right place.  */
  if (outmode != VOIDmode && retval)
    {
      if (mem_value)
	{
	  if (value == 0)
	    value = mem_value;
	  if (value != mem_value)
	    emit_move_insn (value, mem_value);
	}
      else if (GET_CODE (valreg) == PARALLEL)
	{
	  if (value == 0)
	    value = gen_reg_rtx (outmode);
	  emit_group_store (value, valreg, NULL_TREE, GET_MODE_SIZE (outmode));
	}
      else
	{
	  /* Convert to the proper mode if a promotion has been active.  */
	  if (GET_MODE (valreg) != outmode)
	    {
	      int unsignedp = TYPE_UNSIGNED (tfom);

	      gcc_assert (promote_function_mode (tfom, outmode, &unsignedp,
						 fndecl ? TREE_TYPE (fndecl) : fntype, 1)
			  == GET_MODE (valreg));
	      valreg = convert_modes (outmode, GET_MODE (valreg), valreg, 0);
	    }

	  if (value != 0)
	    emit_move_insn (value, valreg);
	  else
	    value = valreg;
	}
    }

  if (ACCUMULATE_OUTGOING_ARGS)
    {
#ifdef REG_PARM_STACK_SPACE
      if (save_area)
	restore_fixed_argument_area (save_area, argblock,
				     high_to_save, low_to_save);
#endif

      /* If we saved any argument areas, restore them.  */
      for (count = 0; count < nargs; count++)
	if (argvec[count].save_area)
	  {
	    machine_mode save_mode = GET_MODE (argvec[count].save_area);
	    rtx adr = plus_constant (Pmode, argblock,
				     argvec[count].locate.offset.constant);
	    rtx stack_area = gen_rtx_MEM (save_mode,
					  memory_address (save_mode, adr));

	    if (save_mode == BLKmode)
	      emit_block_move (stack_area,
			       validize_mem
			         (copy_rtx (argvec[count].save_area)),
			       (gen_int_mode
				(argvec[count].locate.size.constant, Pmode)),
			       BLOCK_OP_CALL_PARM);
	    else
	      emit_move_insn (stack_area, argvec[count].save_area);
	  }

      highest_outgoing_arg_in_use = initial_highest_arg_in_use;
      stack_usage_map = initial_stack_usage_map;
      stack_usage_watermark = initial_stack_usage_watermark;
    }

  free (stack_usage_map_buf);

  return value;

}


/* Store a single argument for a function call
   into the register or memory area where it must be passed.
   *ARG describes the argument value and where to pass it.

   ARGBLOCK is the address of the stack-block for all the arguments,
   or 0 on a machine where arguments are pushed individually.

   MAY_BE_ALLOCA nonzero says this could be a call to `alloca'
   so must be careful about how the stack is used.

   VARIABLE_SIZE nonzero says that this was a variable-sized outgoing
   argument stack.  This is used if ACCUMULATE_OUTGOING_ARGS to indicate
   that we need not worry about saving and restoring the stack.

   FNDECL is the declaration of the function we are calling.

   Return nonzero if this arg should cause sibcall failure,
   zero otherwise.  */

static int
store_one_arg (struct arg_data *arg, rtx argblock, int flags,
	       int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space)
{
  tree pval = arg->tree_value;
  rtx reg = 0;
  int partial = 0;
  poly_int64 used = 0;
  poly_int64 lower_bound = 0, upper_bound = 0;
  int sibcall_failure = 0;

  if (TREE_CODE (pval) == ERROR_MARK)
    return 1;

  /* Push a new temporary level for any temporaries we make for
     this argument.  */
  push_temp_slots ();

  if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL))
    {
      /* If this is being stored into a pre-allocated, fixed-size, stack area,
	 save any previous data at that location.  */
      if (argblock && ! variable_size && arg->stack)
	{
	  if (ARGS_GROW_DOWNWARD)
	    {
	      /* stack_slot is negative, but we want to index stack_usage_map
		 with positive values.  */
	      if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
		{
		  rtx offset = XEXP (XEXP (arg->stack_slot, 0), 1);
		  upper_bound = -rtx_to_poly_int64 (offset) + 1;
		}
	      else
		upper_bound = 0;

	      lower_bound = upper_bound - arg->locate.size.constant;
	    }
	  else
	    {
	      if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
		{
		  rtx offset = XEXP (XEXP (arg->stack_slot, 0), 1);
		  lower_bound = rtx_to_poly_int64 (offset);
		}
	      else
		lower_bound = 0;

	      upper_bound = lower_bound + arg->locate.size.constant;
	    }

	  if (stack_region_maybe_used_p (lower_bound, upper_bound,
					 reg_parm_stack_space))
	    {
	      /* We need to make a save area.  */
	      poly_uint64 size = arg->locate.size.constant * BITS_PER_UNIT;
	      machine_mode save_mode
		= int_mode_for_size (size, 1).else_blk ();
	      rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
	      rtx stack_area = gen_rtx_MEM (save_mode, adr);

	      if (save_mode == BLKmode)
		{
		  arg->save_area
		    = assign_temp (TREE_TYPE (arg->tree_value), 1, 1);
		  preserve_temp_slots (arg->save_area);
		  emit_block_move (validize_mem (copy_rtx (arg->save_area)),
				   stack_area,
				   (gen_int_mode
				    (arg->locate.size.constant, Pmode)),
				   BLOCK_OP_CALL_PARM);
		}
	      else
		{
		  arg->save_area = gen_reg_rtx (save_mode);
		  emit_move_insn (arg->save_area, stack_area);
		}
	    }
	}
    }

  /* If this isn't going to be placed on both the stack and in registers,
     set up the register and number of words.  */
  if (! arg->pass_on_stack)
    {
      if (flags & ECF_SIBCALL)
	reg = arg->tail_call_reg;
      else
	reg = arg->reg;
      partial = arg->partial;
    }

  /* Being passed entirely in a register.  We shouldn't be called in
     this case.  */
  gcc_assert (reg == 0 || partial != 0);

  /* If this arg needs special alignment, don't load the registers
     here.  */
  if (arg->n_aligned_regs != 0)
    reg = 0;

  /* If this is being passed partially in a register, we can't evaluate
     it directly into its stack slot.  Otherwise, we can.  */
  if (arg->value == 0)
    {
      /* stack_arg_under_construction is nonzero if a function argument is
	 being evaluated directly into the outgoing argument list and
	 expand_call must take special action to preserve the argument list
	 if it is called recursively.

	 For scalar function arguments stack_usage_map is sufficient to
	 determine which stack slots must be saved and restored.  Scalar
	 arguments in general have pass_on_stack == 0.

	 If this argument is initialized by a function which takes the
	 address of the argument (a C++ constructor or a C function
	 returning a BLKmode structure), then stack_usage_map is
	 insufficient and expand_call must push the stack around the
	 function call.  Such arguments have pass_on_stack == 1.

	 Note that it is always safe to set stack_arg_under_construction,
	 but this generates suboptimal code if set when not needed.  */

      if (arg->pass_on_stack)
	stack_arg_under_construction++;

      arg->value = expand_expr (pval,
				(partial
				 || TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
				? NULL_RTX : arg->stack,
				VOIDmode, EXPAND_STACK_PARM);

      /* If we are promoting object (or for any other reason) the mode
	 doesn't agree, convert the mode.  */

      if (arg->mode != TYPE_MODE (TREE_TYPE (pval)))
	arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)),
				    arg->value, arg->unsignedp);

      if (arg->pass_on_stack)
	stack_arg_under_construction--;
    }

  /* Check for overlap with already clobbered argument area.  */
  if ((flags & ECF_SIBCALL)
      && MEM_P (arg->value)
      && mem_might_overlap_already_clobbered_arg_p (XEXP (arg->value, 0),
						    arg->locate.size.constant))
    sibcall_failure = 1;

  /* Don't allow anything left on stack from computation
     of argument to alloca.  */
  if (flags & ECF_MAY_BE_ALLOCA)
    do_pending_stack_adjust ();

  if (arg->value == arg->stack)
    /* If the value is already in the stack slot, we are done.  */
    ;
  else if (arg->mode != BLKmode)
    {
      unsigned int parm_align;

      /* Argument is a scalar, not entirely passed in registers.
	 (If part is passed in registers, arg->partial says how much
	 and emit_push_insn will take care of putting it there.)

	 Push it, and if its size is less than the
	 amount of space allocated to it,
	 also bump stack pointer by the additional space.
	 Note that in C the default argument promotions
	 will prevent such mismatches.  */

      poly_int64 size = (TYPE_EMPTY_P (TREE_TYPE (pval))
			 ? 0 : GET_MODE_SIZE (arg->mode));

      /* Compute how much space the push instruction will push.
	 On many machines, pushing a byte will advance the stack
	 pointer by a halfword.  */
#ifdef PUSH_ROUNDING
      size = PUSH_ROUNDING (size);
#endif
      used = size;

      /* Compute how much space the argument should get:
	 round up to a multiple of the alignment for arguments.  */
      if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
	  != PAD_NONE)
	/* At the moment we don't (need to) support ABIs for which the
	   padding isn't known at compile time.  In principle it should
	   be easy to add though.  */
	used = force_align_up (size, PARM_BOUNDARY / BITS_PER_UNIT);

      /* Compute the alignment of the pushed argument.  */
      parm_align = arg->locate.boundary;
      if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
	  == PAD_DOWNWARD)
	{
	  poly_int64 pad = used - size;
	  unsigned int pad_align = known_alignment (pad) * BITS_PER_UNIT;
	  if (pad_align != 0)
	    parm_align = MIN (parm_align, pad_align);
	}

      /* This isn't already where we want it on the stack, so put it there.
	 This can either be done with push or copy insns.  */
      if (maybe_ne (used, 0)
	  && !emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval),
			      NULL_RTX, parm_align, partial, reg, used - size,
			      argblock, ARGS_SIZE_RTX (arg->locate.offset),
			      reg_parm_stack_space,
			      ARGS_SIZE_RTX (arg->locate.alignment_pad), true))
	sibcall_failure = 1;

      /* Unless this is a partially-in-register argument, the argument is now
	 in the stack.  */
      if (partial == 0)
	arg->value = arg->stack;
    }
  else
    {
      /* BLKmode, at least partly to be pushed.  */

      unsigned int parm_align;
      poly_int64 excess;
      rtx size_rtx;

      /* Pushing a nonscalar.
	 If part is passed in registers, PARTIAL says how much
	 and emit_push_insn will take care of putting it there.  */

      /* Round its size up to a multiple
	 of the allocation unit for arguments.  */

      if (arg->locate.size.var != 0)
	{
	  excess = 0;
	  size_rtx = ARGS_SIZE_RTX (arg->locate.size);
	}
      else
	{
	  /* PUSH_ROUNDING has no effect on us, because emit_push_insn
	     for BLKmode is careful to avoid it.  */
	  excess = (arg->locate.size.constant
		    - arg_int_size_in_bytes (TREE_TYPE (pval))
		    + partial);
	  size_rtx = expand_expr (arg_size_in_bytes (TREE_TYPE (pval)),
				  NULL_RTX, TYPE_MODE (sizetype),
				  EXPAND_NORMAL);
	}

      parm_align = arg->locate.boundary;

      /* When an argument is padded down, the block is aligned to
	 PARM_BOUNDARY, but the actual argument isn't.  */
      if (targetm.calls.function_arg_padding (arg->mode, TREE_TYPE (pval))
	  == PAD_DOWNWARD)
	{
	  if (arg->locate.size.var)
	    parm_align = BITS_PER_UNIT;
	  else
	    {
	      unsigned int excess_align
		= known_alignment (excess) * BITS_PER_UNIT;
	      if (excess_align != 0)
		parm_align = MIN (parm_align, excess_align);
	    }
	}

      if ((flags & ECF_SIBCALL) && MEM_P (arg->value))
	{
	  /* emit_push_insn might not work properly if arg->value and
	     argblock + arg->locate.offset areas overlap.  */
	  rtx x = arg->value;
	  poly_int64 i = 0;

	  if (strip_offset (XEXP (x, 0), &i)
	      == crtl->args.internal_arg_pointer)
	    {
	      /* arg.locate doesn't contain the pretend_args_size offset,
		 it's part of argblock.  Ensure we don't count it in I.  */
	      if (STACK_GROWS_DOWNWARD)
		i -= crtl->args.pretend_args_size;
	      else
		i += crtl->args.pretend_args_size;

	      /* expand_call should ensure this.  */
	      gcc_assert (!arg->locate.offset.var
			  && arg->locate.size.var == 0);
	      poly_int64 size_val = rtx_to_poly_int64 (size_rtx);

	      if (known_eq (arg->locate.offset.constant, i))
		{
		  /* Even though they appear to be at the same location,
		     if part of the outgoing argument is in registers,
		     they aren't really at the same location.  Check for
		     this by making sure that the incoming size is the
		     same as the outgoing size.  */
		  if (maybe_ne (arg->locate.size.constant, size_val))
		    sibcall_failure = 1;
		}
	      else if (maybe_in_range_p (arg->locate.offset.constant,
					 i, size_val))
		sibcall_failure = 1;
	      /* Use arg->locate.size.constant instead of size_rtx
		 because we only care about the part of the argument
		 on the stack.  */
	      else if (maybe_in_range_p (i, arg->locate.offset.constant,
					 arg->locate.size.constant))
		sibcall_failure = 1;
	    }
	}

      if (!CONST_INT_P (size_rtx) || INTVAL (size_rtx) != 0)
	emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
			parm_align, partial, reg, excess, argblock,
			ARGS_SIZE_RTX (arg->locate.offset),
			reg_parm_stack_space,
			ARGS_SIZE_RTX (arg->locate.alignment_pad), false);

      /* Unless this is a partially-in-register argument, the argument is now
	 in the stack.

	 ??? Unlike the case above, in which we want the actual
	 address of the data, so that we can load it directly into a
	 register, here we want the address of the stack slot, so that
	 it's properly aligned for word-by-word copying or something
	 like that.  It's not clear that this is always correct.  */
      if (partial == 0)
	arg->value = arg->stack_slot;
    }

  if (arg->reg && GET_CODE (arg->reg) == PARALLEL)
    {
      tree type = TREE_TYPE (arg->tree_value);
      arg->parallel_value
	= emit_group_load_into_temps (arg->reg, arg->value, type,
				      int_size_in_bytes (type));
    }

  /* Mark all slots this store used.  */
  if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)
      && argblock && ! variable_size && arg->stack)
    mark_stack_region_used (lower_bound, upper_bound);

  /* Once we have pushed something, pops can't safely
     be deferred during the rest of the arguments.  */
  NO_DEFER_POP;

  /* Free any temporary slots made in processing this argument.  */
  pop_temp_slots ();

  return sibcall_failure;
}

/* Nonzero if we do not know how to pass ARG solely in registers.  */

bool
must_pass_in_stack_var_size (const function_arg_info &arg)
{
  if (!arg.type)
    return false;

  /* If the type has variable size...  */
  if (!poly_int_tree_p (TYPE_SIZE (arg.type)))
    return true;

  /* If the type is marked as addressable (it is required
     to be constructed into the stack)...  */
  if (TREE_ADDRESSABLE (arg.type))
    return true;

  return false;
}

/* Another version of the TARGET_MUST_PASS_IN_STACK hook.  This one
   takes trailing padding of a structure into account.  */
/* ??? Should be able to merge these two by examining BLOCK_REG_PADDING.  */

bool
must_pass_in_stack_var_size_or_pad (const function_arg_info &arg)
{
  if (!arg.type)
    return false;

  /* If the type has variable size...  */
  if (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST)
    return true;

  /* If the type is marked as addressable (it is required
     to be constructed into the stack)...  */
  if (TREE_ADDRESSABLE (arg.type))
    return true;

  if (TYPE_EMPTY_P (arg.type))
    return false;

  /* If the padding and mode of the type is such that a copy into
     a register would put it into the wrong part of the register.  */
  if (arg.mode == BLKmode
      && int_size_in_bytes (arg.type) % (PARM_BOUNDARY / BITS_PER_UNIT)
      && (targetm.calls.function_arg_padding (arg.mode, arg.type)
	  == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
    return true;

  return false;
}

/* Return true if TYPE must be passed on the stack when passed to
   the "..." arguments of a function.  */

bool
must_pass_va_arg_in_stack (tree type)
{
  function_arg_info arg (type, /*named=*/false);
  return targetm.calls.must_pass_in_stack (arg);
}

/* Return true if FIELD is the C++17 empty base field that should
   be ignored for ABI calling convention decisions in order to
   maintain ABI compatibility between C++14 and earlier, which doesn't
   add this FIELD to classes with empty bases, and C++17 and later
   which does.  */

bool
cxx17_empty_base_field_p (const_tree field)
{
  return (DECL_FIELD_ABI_IGNORED (field)
	  && DECL_ARTIFICIAL (field)
	  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
	  && !lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (field)));
}
