1132732Skan/* Expands front end tree to back end RTL for GCC.
272564Sobrien   Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3169702Skan   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169702Skan   Free Software Foundation, Inc.
518334Speter
690091SobrienThis file is part of GCC.
718334Speter
890091SobrienGCC is free software; you can redistribute it and/or modify it under
990091Sobrienthe terms of the GNU General Public License as published by the Free
1090091SobrienSoftware Foundation; either version 2, or (at your option) any later
1190091Sobrienversion.
1218334Speter
1390091SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490091SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590091SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690091Sobrienfor more details.
1718334Speter
1818334SpeterYou should have received a copy of the GNU General Public License
1990091Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169702SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169702Skan02110-1301, USA.  */
2218334Speter
23124160Skan/* $FreeBSD$ */
24124160Skan
2518334Speter/* This file handles the generation of rtl code from tree structure
2618334Speter   at the level of the function as a whole.
2718334Speter   It creates the rtl expressions for parameters and auto variables
2818334Speter   and has full responsibility for allocating stack slots.
2918334Speter
3018334Speter   `expand_function_start' is called at the beginning of a function,
3118334Speter   before the function body is parsed, and `expand_function_end' is
3218334Speter   called after parsing the body.
3318334Speter
3418334Speter   Call `assign_stack_local' to allocate a stack slot for a local variable.
3518334Speter   This is usually done during the RTL generation for the function body,
3618334Speter   but it can also be done in the reload pass when a pseudo-register does
37169702Skan   not get a hard register.  */
3818334Speter
3918334Speter#include "config.h"
4052268Sobrien#include "system.h"
41132732Skan#include "coretypes.h"
42132732Skan#include "tm.h"
4318334Speter#include "rtl.h"
4418334Speter#include "tree.h"
4518334Speter#include "flags.h"
4652268Sobrien#include "except.h"
4718334Speter#include "function.h"
4818334Speter#include "expr.h"
49132732Skan#include "optabs.h"
5090091Sobrien#include "libfuncs.h"
5118334Speter#include "regs.h"
5218334Speter#include "hard-reg-set.h"
5318334Speter#include "insn-config.h"
5418334Speter#include "recog.h"
5518334Speter#include "output.h"
5618334Speter#include "basic-block.h"
5752268Sobrien#include "toplev.h"
58117404Skan#include "hashtab.h"
5990091Sobrien#include "ggc.h"
6090091Sobrien#include "tm_p.h"
6190091Sobrien#include "integrate.h"
62107605Sobrien#include "langhooks.h"
63132732Skan#include "target.h"
64169702Skan#include "cfglayout.h"
65169702Skan#include "tree-gimple.h"
66169702Skan#include "tree-pass.h"
67169702Skan#include "predict.h"
68169702Skan#include "vecprim.h"
6918334Speter
7052518Sobrien#ifndef LOCAL_ALIGNMENT
7152518Sobrien#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
7252518Sobrien#endif
7352518Sobrien
74132732Skan#ifndef STACK_ALIGNMENT_NEEDED
75132732Skan#define STACK_ALIGNMENT_NEEDED 1
76132732Skan#endif
77132732Skan
78132732Skan#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
79132732Skan
8018334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these
8118334Speter   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
8218334Speter   give the same symbol without quotes for an alternative entry point.  You
8352268Sobrien   must define both, or neither.  */
8418334Speter#ifndef NAME__MAIN
8518334Speter#define NAME__MAIN "__main"
8618334Speter#endif
8718334Speter
8818334Speter/* Round a value to the lowest integer less than it that is a multiple of
8918334Speter   the required alignment.  Avoid using division in case the value is
9018334Speter   negative.  Assume the alignment is a power of two.  */
9118334Speter#define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))
9218334Speter
9318334Speter/* Similar, but round to the next highest integer that meets the
9418334Speter   alignment.  */
9518334Speter#define CEIL_ROUND(VALUE,ALIGN)	(((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
9618334Speter
9752518Sobrien/* Nonzero if function being compiled doesn't contain any calls
9852518Sobrien   (ignoring the prologue and epilogue).  This is set prior to
9952518Sobrien   local register allocation and is valid for the remaining
10090091Sobrien   compiler passes.  */
10152518Sobrienint current_function_is_leaf;
10218334Speter
10352518Sobrien/* Nonzero if function being compiled doesn't modify the stack pointer
10452518Sobrien   (ignoring the prologue and epilogue).  This is only valid after
10590091Sobrien   life_analysis has run.  */
10652518Sobrienint current_function_sp_is_unchanging;
10752518Sobrien
10852518Sobrien/* Nonzero if the function being compiled is a leaf function which only
10952518Sobrien   uses leaf registers.  This is valid after reload (specifically after
11052518Sobrien   sched2) and is useful only if the port defines LEAF_REGISTERS.  */
11152518Sobrienint current_function_uses_only_leaf_regs;
11252518Sobrien
11390091Sobrien/* Nonzero once virtual register instantiation has been done.
11490091Sobrien   assign_stack_local uses frame_pointer_rtx when this is nonzero.
11590091Sobrien   calls.c:emit_library_call_value_1 uses it to set up
11690091Sobrien   post-instantiation libcalls.  */
11790091Sobrienint virtuals_instantiated;
11852518Sobrien
119261188Spfg/* APPLE LOCAL begin radar 5732232 - blocks */
120261188Spfgstruct block_sema_info *cur_block;
121261188Spfg/* APPLE LOCAL end radar 5732232 - blocks */
122261188Spfg
123117404Skan/* Assign unique numbers to labels generated for profiling, debugging, etc.  */
124132732Skanstatic GTY(()) int funcdef_no;
12596283Sobrien
12690091Sobrien/* These variables hold pointers to functions to create and destroy
12790091Sobrien   target specific, per-function data structures.  */
128132732Skanstruct machine_function * (*init_machine_status) (void);
12952518Sobrien
13090091Sobrien/* The currently compiled function.  */
13190091Sobrienstruct function *cfun = 0;
13218334Speter
13390091Sobrien/* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
134169702Skanstatic VEC(int,heap) *prologue;
135169702Skanstatic VEC(int,heap) *epilogue;
13618334Speter
13790091Sobrien/* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
13818334Speter   in this function.  */
139169702Skanstatic VEC(int,heap) *sibcall_epilogue;
14018334Speter
14118334Speter/* In order to evaluate some expressions, such as function calls returning
14218334Speter   structures in memory, we need to temporarily allocate stack locations.
14318334Speter   We record each allocated temporary in the following structure.
14418334Speter
14518334Speter   Associated with each temporary slot is a nesting level.  When we pop up
14618334Speter   one level, all temporaries associated with the previous level are freed.
14718334Speter   Normally, all temporaries are freed after the execution of the statement
14818334Speter   in which they were created.  However, if we are inside a ({...}) grouping,
14918334Speter   the result may be in a temporary and hence must be preserved.  If the
15018334Speter   result could be in a temporary, we preserve it if we can determine which
15118334Speter   one it is in.  If we cannot determine which temporary may contain the
15218334Speter   result, all temporaries are preserved.  A temporary is preserved by
15318334Speter   pretending it was allocated at the previous nesting level.
15418334Speter
15518334Speter   Automatic variables are also assigned temporary slots, at the nesting
15618334Speter   level where they are defined.  They are marked a "kept" so that
15718334Speter   free_temp_slots will not free them.  */
15818334Speter
159117404Skanstruct temp_slot GTY(())
16018334Speter{
16118334Speter  /* Points to next temporary slot.  */
16218334Speter  struct temp_slot *next;
163169702Skan  /* Points to previous temporary slot.  */
164169702Skan  struct temp_slot *prev;
165169702Skan
16652268Sobrien  /* The rtx to used to reference the slot.  */
16718334Speter  rtx slot;
16818334Speter  /* The rtx used to represent the address if not the address of the
16918334Speter     slot above.  May be an EXPR_LIST if multiple addresses exist.  */
17018334Speter  rtx address;
17190091Sobrien  /* The alignment (in bits) of the slot.  */
17290091Sobrien  unsigned int align;
17318334Speter  /* The size, in units, of the slot.  */
17452268Sobrien  HOST_WIDE_INT size;
17590091Sobrien  /* The type of the object in the slot, or zero if it doesn't correspond
17690091Sobrien     to a type.  We use this to determine whether a slot can be reused.
17790091Sobrien     It can be reused if objects of the type of the new slot will always
17890091Sobrien     conflict with objects of the type of the old slot.  */
17990091Sobrien  tree type;
180117404Skan  /* Nonzero if this temporary is currently in use.  */
18118334Speter  char in_use;
182117404Skan  /* Nonzero if this temporary has its address taken.  */
18318334Speter  char addr_taken;
18418334Speter  /* Nesting level at which this slot is being used.  */
18518334Speter  int level;
186117404Skan  /* Nonzero if this should survive a call to free_temp_slots.  */
18718334Speter  int keep;
18818334Speter  /* The offset of the slot from the frame_pointer, including extra space
18918334Speter     for alignment.  This info is for combine_temp_slots.  */
19052268Sobrien  HOST_WIDE_INT base_offset;
19118334Speter  /* The size of the slot, including extra space for alignment.  This
19218334Speter     info is for combine_temp_slots.  */
19352268Sobrien  HOST_WIDE_INT full_size;
19418334Speter};
19552268Sobrien
19618334Speter/* Forward declarations.  */
19718334Speter
198132732Skanstatic rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
199132732Skan				 struct function *);
200132732Skanstatic struct temp_slot *find_temp_slot_from_address (rtx);
201132732Skanstatic void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
202132732Skanstatic void pad_below (struct args_size *, enum machine_mode, tree);
203169702Skanstatic void reorder_blocks_1 (rtx, tree, VEC(tree,heap) **);
204132732Skanstatic int all_blocks (tree, tree *);
205132732Skanstatic tree *get_block_vector (tree, int *);
206132732Skanextern tree debug_find_var_in_block_tree (tree, tree);
207169702Skan/* We always define `record_insns' even if it's not used so that we
20890091Sobrien   can always export `prologue_epilogue_contains'.  */
209169702Skanstatic void record_insns (rtx, VEC(int,heap) **) ATTRIBUTE_UNUSED;
210169702Skanstatic int contains (rtx, VEC(int,heap) **);
21190091Sobrien#ifdef HAVE_return
212132732Skanstatic void emit_return_into_block (basic_block, rtx);
21352268Sobrien#endif
21490091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
215132732Skanstatic rtx keep_stack_depressed (rtx);
21690091Sobrien#endif
217132732Skanstatic void prepare_function_start (tree);
218132732Skanstatic void do_clobber_return_reg (rtx, void *);
219132732Skanstatic void do_use_return_reg (rtx, void *);
220132732Skanstatic void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
221261188Spfg/* APPLE LOCAL radar 6163705, Blocks prologues  */
222261188Spfgstatic rtx find_block_prologue_insns (void);
22318334Speter
22418334Speter/* Pointer to chain of `struct function' for containing functions.  */
225132732Skanstruct function *outer_function_chain;
22618334Speter
22718334Speter/* Given a function decl for a containing function,
22818334Speter   return the `struct function' for it.  */
22918334Speter
23018334Speterstruct function *
231132732Skanfind_function_data (tree decl)
23218334Speter{
23318334Speter  struct function *p;
23452268Sobrien
23590091Sobrien  for (p = outer_function_chain; p; p = p->outer)
23618334Speter    if (p->decl == decl)
23718334Speter      return p;
23852268Sobrien
239169702Skan  gcc_unreachable ();
24018334Speter}
24118334Speter
24218334Speter/* Save the current context for compilation of a nested function.
24390091Sobrien   This is called from language-specific code.  The caller should use
244117404Skan   the enter_nested langhook to save any language-specific state,
24590091Sobrien   since this function knows only about language-independent
24690091Sobrien   variables.  */
24718334Speter
24818334Spetervoid
249169702Skanpush_function_context_to (tree context ATTRIBUTE_UNUSED)
25018334Speter{
25190091Sobrien  struct function *p;
25218334Speter
25390091Sobrien  if (cfun == 0)
25490091Sobrien    init_dummy_function_start ();
25590091Sobrien  p = cfun;
25690091Sobrien
25790091Sobrien  p->outer = outer_function_chain;
25818334Speter  outer_function_chain = p;
25918334Speter
260169702Skan  lang_hooks.function.enter_nested (p);
26190091Sobrien
26290091Sobrien  cfun = 0;
26318334Speter}
26418334Speter
26518334Spetervoid
266132732Skanpush_function_context (void)
26718334Speter{
26818334Speter  push_function_context_to (current_function_decl);
26918334Speter}
27018334Speter
27118334Speter/* Restore the last saved context, at the end of a nested function.
27218334Speter   This function is called from language-specific code.  */
27318334Speter
27418334Spetervoid
275132732Skanpop_function_context_from (tree context ATTRIBUTE_UNUSED)
27618334Speter{
27718334Speter  struct function *p = outer_function_chain;
27818334Speter
27990091Sobrien  cfun = p;
28090091Sobrien  outer_function_chain = p->outer;
28118334Speter
28218334Speter  current_function_decl = p->decl;
28318334Speter
284169702Skan  lang_hooks.function.leave_nested (p);
28518334Speter
28618334Speter  /* Reset variables that have known state during rtx generation.  */
28718334Speter  virtuals_instantiated = 0;
28890091Sobrien  generating_concat_p = 1;
28918334Speter}
29018334Speter
29190091Sobrienvoid
292132732Skanpop_function_context (void)
29318334Speter{
29418334Speter  pop_function_context_from (current_function_decl);
29518334Speter}
29690091Sobrien
29790091Sobrien/* Clear out all parts of the state in F that can safely be discarded
29890091Sobrien   after the function has been parsed, but not compiled, to let
29990091Sobrien   garbage collection reclaim the memory.  */
30090091Sobrien
30190091Sobrienvoid
302132732Skanfree_after_parsing (struct function *f)
30390091Sobrien{
30490091Sobrien  /* f->expr->forced_labels is used by code generation.  */
30590091Sobrien  /* f->emit->regno_reg_rtx is used by code generation.  */
30690091Sobrien  /* f->varasm is used by code generation.  */
30790091Sobrien  /* f->eh->eh_return_stub_label is used by code generation.  */
30890091Sobrien
309169702Skan  lang_hooks.function.final (f);
31090091Sobrien}
31190091Sobrien
31290091Sobrien/* Clear out all parts of the state in F that can safely be discarded
31390091Sobrien   after the function has been compiled, to let garbage collection
31490091Sobrien   reclaim the memory.  */
31590091Sobrien
31690091Sobrienvoid
317132732Skanfree_after_compilation (struct function *f)
31890091Sobrien{
319169702Skan  VEC_free (int, heap, prologue);
320169702Skan  VEC_free (int, heap, epilogue);
321169702Skan  VEC_free (int, heap, sibcall_epilogue);
322169702Skan
323117404Skan  f->eh = NULL;
324117404Skan  f->expr = NULL;
325117404Skan  f->emit = NULL;
326117404Skan  f->varasm = NULL;
327117404Skan  f->machine = NULL;
328169702Skan  f->cfg = NULL;
32990091Sobrien
330169702Skan  f->x_avail_temp_slots = NULL;
331169702Skan  f->x_used_temp_slots = NULL;
33290091Sobrien  f->arg_offset_rtx = NULL;
33390091Sobrien  f->return_rtx = NULL;
33490091Sobrien  f->internal_arg_pointer = NULL;
33590091Sobrien  f->x_nonlocal_goto_handler_labels = NULL;
33690091Sobrien  f->x_return_label = NULL;
337132732Skan  f->x_naked_return_label = NULL;
33890091Sobrien  f->x_stack_slot_list = NULL;
339169702Skan  f->x_stack_check_probe_note = NULL;
34090091Sobrien  f->x_arg_pointer_save_area = NULL;
34190091Sobrien  f->x_parm_birth_insn = NULL;
34290091Sobrien  f->epilogue_delay_list = NULL;
34390091Sobrien}
34418334Speter
34518334Speter/* Allocate fixed slots in the stack frame of the current function.  */
34618334Speter
34790091Sobrien/* Return size needed for stack frame based on slots so far allocated in
34890091Sobrien   function F.
34952518Sobrien   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
35018334Speter   the caller may have to do that.  */
35118334Speter
352169702Skanstatic HOST_WIDE_INT
353132732Skanget_func_frame_size (struct function *f)
35418334Speter{
355169702Skan  if (FRAME_GROWS_DOWNWARD)
356169702Skan    return -f->x_frame_offset;
357169702Skan  else
358169702Skan    return f->x_frame_offset;
35918334Speter}
36018334Speter
36190091Sobrien/* Return size needed for stack frame based on slots so far allocated.
36290091Sobrien   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
36390091Sobrien   the caller may have to do that.  */
364169702Skan
36590091SobrienHOST_WIDE_INT
366132732Skanget_frame_size (void)
36790091Sobrien{
36890091Sobrien  return get_func_frame_size (cfun);
36990091Sobrien}
37090091Sobrien
371169702Skan/* Issue an error message and return TRUE if frame OFFSET overflows in
372169702Skan   the signed target pointer arithmetics for function FUNC.  Otherwise
373169702Skan   return FALSE.  */
374169702Skan
375169702Skanbool
376169702Skanframe_offset_overflow (HOST_WIDE_INT offset, tree func)
377169702Skan{
378169702Skan  unsigned HOST_WIDE_INT size = FRAME_GROWS_DOWNWARD ? -offset : offset;
379169702Skan
380169702Skan  if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1))
381169702Skan	       /* Leave room for the fixed part of the frame.  */
382169702Skan	       - 64 * UNITS_PER_WORD)
383169702Skan    {
384169702Skan      error ("%Jtotal size of local objects too large", func);
385169702Skan      return TRUE;
386169702Skan    }
387169702Skan
388169702Skan  return FALSE;
389169702Skan}
390169702Skan
39118334Speter/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
39218334Speter   with machine mode MODE.
39390091Sobrien
39418334Speter   ALIGN controls the amount of alignment for the address of the slot:
39518334Speter   0 means according to MODE,
39618334Speter   -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
397146908Skan   -2 means use BITS_PER_UNIT,
39818334Speter   positive specifies alignment boundary in bits.
39918334Speter
40090091Sobrien   We do not round to stack_boundary here.
40118334Speter
40290091Sobrien   FUNCTION specifies the function to allocate in.  */
40390091Sobrien
40490091Sobrienstatic rtx
405132732Skanassign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
406132732Skan		      struct function *function)
40718334Speter{
40890091Sobrien  rtx x, addr;
40918334Speter  int bigend_correction = 0;
410169702Skan  unsigned int alignment;
41190091Sobrien  int frame_off, frame_alignment, frame_phase;
41218334Speter
41318334Speter  if (align == 0)
41418334Speter    {
41552518Sobrien      tree type;
41652518Sobrien
41718334Speter      if (mode == BLKmode)
41852518Sobrien	alignment = BIGGEST_ALIGNMENT;
41990091Sobrien      else
42090091Sobrien	alignment = GET_MODE_ALIGNMENT (mode);
42152518Sobrien
42252518Sobrien      /* Allow the target to (possibly) increase the alignment of this
42352518Sobrien	 stack slot.  */
424169702Skan      type = lang_hooks.types.type_for_mode (mode, 0);
42552518Sobrien      if (type)
42652518Sobrien	alignment = LOCAL_ALIGNMENT (type, alignment);
42752518Sobrien
42852518Sobrien      alignment /= BITS_PER_UNIT;
42918334Speter    }
43018334Speter  else if (align == -1)
43118334Speter    {
43218334Speter      alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
43318334Speter      size = CEIL_ROUND (size, alignment);
43418334Speter    }
435146908Skan  else if (align == -2)
436146908Skan    alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
43718334Speter  else
43818334Speter    alignment = align / BITS_PER_UNIT;
43918334Speter
440169702Skan  if (FRAME_GROWS_DOWNWARD)
441169702Skan    function->x_frame_offset -= size;
44252518Sobrien
44390091Sobrien  /* Ignore alignment we can't do with expected alignment of the boundary.  */
44490091Sobrien  if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
44590091Sobrien    alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
44690091Sobrien
44790091Sobrien  if (function->stack_alignment_needed < alignment * BITS_PER_UNIT)
44890091Sobrien    function->stack_alignment_needed = alignment * BITS_PER_UNIT;
44990091Sobrien
45090091Sobrien  /* Calculate how many bytes the start of local variables is off from
45190091Sobrien     stack alignment.  */
45290091Sobrien  frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
45390091Sobrien  frame_off = STARTING_FRAME_OFFSET % frame_alignment;
45490091Sobrien  frame_phase = frame_off ? frame_alignment - frame_off : 0;
45590091Sobrien
456132732Skan  /* Round the frame offset to the specified alignment.  The default is
457132732Skan     to always honor requests to align the stack but a port may choose to
458132732Skan     do its own stack alignment by defining STACK_ALIGNMENT_NEEDED.  */
459132732Skan  if (STACK_ALIGNMENT_NEEDED
460132732Skan      || mode != BLKmode
461132732Skan      || size != 0)
462132732Skan    {
463132732Skan      /*  We must be careful here, since FRAME_OFFSET might be negative and
464132732Skan	  division with a negative dividend isn't as well defined as we might
465132732Skan	  like.  So we instead assume that ALIGNMENT is a power of two and
466132732Skan	  use logical operations which are unambiguous.  */
467169702Skan      if (FRAME_GROWS_DOWNWARD)
468169702Skan	function->x_frame_offset
469169702Skan	  = (FLOOR_ROUND (function->x_frame_offset - frame_phase,
470169702Skan			  (unsigned HOST_WIDE_INT) alignment)
471169702Skan	     + frame_phase);
472169702Skan      else
473169702Skan	function->x_frame_offset
474169702Skan	  = (CEIL_ROUND (function->x_frame_offset - frame_phase,
475169702Skan			 (unsigned HOST_WIDE_INT) alignment)
476169702Skan	     + frame_phase);
477132732Skan    }
47818334Speter
47918334Speter  /* On a big-endian machine, if we are allocating more space than we will use,
48018334Speter     use the least significant bytes of those that are allocated.  */
481169702Skan  if (BYTES_BIG_ENDIAN && mode != BLKmode && GET_MODE_SIZE (mode) < size)
48218334Speter    bigend_correction = size - GET_MODE_SIZE (mode);
48318334Speter
48418334Speter  /* If we have already instantiated virtual registers, return the actual
48518334Speter     address relative to the frame pointer.  */
48690091Sobrien  if (function == cfun && virtuals_instantiated)
48718334Speter    addr = plus_constant (frame_pointer_rtx,
488132732Skan			  trunc_int_for_mode
48918334Speter			  (frame_offset + bigend_correction
490132732Skan			   + STARTING_FRAME_OFFSET, Pmode));
49118334Speter  else
49218334Speter    addr = plus_constant (virtual_stack_vars_rtx,
493132732Skan			  trunc_int_for_mode
494132732Skan			  (function->x_frame_offset + bigend_correction,
495132732Skan			   Pmode));
49618334Speter
497169702Skan  if (!FRAME_GROWS_DOWNWARD)
498169702Skan    function->x_frame_offset += size;
49918334Speter
50052268Sobrien  x = gen_rtx_MEM (mode, addr);
501169702Skan  MEM_NOTRAP_P (x) = 1;
50218334Speter
50390091Sobrien  function->x_stack_slot_list
50490091Sobrien    = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
50518334Speter
506169702Skan  if (frame_offset_overflow (function->x_frame_offset, function->decl))
507169702Skan    function->x_frame_offset = 0;
508169702Skan
50918334Speter  return x;
51018334Speter}
51118334Speter
51290091Sobrien/* Wrapper around assign_stack_local_1;  assign a local stack slot for the
51390091Sobrien   current function.  */
51418334Speter
51590091Sobrienrtx
516132732Skanassign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
51718334Speter{
51890091Sobrien  return assign_stack_local_1 (mode, size, align, cfun);
51918334Speter}
520169702Skan
52118334Speter
522169702Skan/* Removes temporary slot TEMP from LIST.  */
523169702Skan
524169702Skanstatic void
525169702Skancut_slot_from_list (struct temp_slot *temp, struct temp_slot **list)
526169702Skan{
527169702Skan  if (temp->next)
528169702Skan    temp->next->prev = temp->prev;
529169702Skan  if (temp->prev)
530169702Skan    temp->prev->next = temp->next;
531169702Skan  else
532169702Skan    *list = temp->next;
533169702Skan
534169702Skan  temp->prev = temp->next = NULL;
535169702Skan}
536169702Skan
537169702Skan/* Inserts temporary slot TEMP to LIST.  */
538169702Skan
539169702Skanstatic void
540169702Skaninsert_slot_to_list (struct temp_slot *temp, struct temp_slot **list)
541169702Skan{
542169702Skan  temp->next = *list;
543169702Skan  if (*list)
544169702Skan    (*list)->prev = temp;
545169702Skan  temp->prev = NULL;
546169702Skan  *list = temp;
547169702Skan}
548169702Skan
549169702Skan/* Returns the list of used temp slots at LEVEL.  */
550169702Skan
551169702Skanstatic struct temp_slot **
552169702Skantemp_slots_at_level (int level)
553169702Skan{
554169702Skan  if (level >= (int) VEC_length (temp_slot_p, used_temp_slots))
555169702Skan    {
556169702Skan      size_t old_length = VEC_length (temp_slot_p, used_temp_slots);
557169702Skan      temp_slot_p *p;
558169702Skan
559169702Skan      VEC_safe_grow (temp_slot_p, gc, used_temp_slots, level + 1);
560169702Skan      p = VEC_address (temp_slot_p, used_temp_slots);
561169702Skan      memset (&p[old_length], 0,
562169702Skan	      sizeof (temp_slot_p) * (level + 1 - old_length));
563169702Skan    }
564169702Skan
565169702Skan  return &(VEC_address (temp_slot_p, used_temp_slots)[level]);
566169702Skan}
567169702Skan
568169702Skan/* Returns the maximal temporary slot level.  */
569169702Skan
570169702Skanstatic int
571169702Skanmax_slot_level (void)
572169702Skan{
573169702Skan  if (!used_temp_slots)
574169702Skan    return -1;
575169702Skan
576169702Skan  return VEC_length (temp_slot_p, used_temp_slots) - 1;
577169702Skan}
578169702Skan
579169702Skan/* Moves temporary slot TEMP to LEVEL.  */
580169702Skan
581169702Skanstatic void
582169702Skanmove_slot_to_level (struct temp_slot *temp, int level)
583169702Skan{
584169702Skan  cut_slot_from_list (temp, temp_slots_at_level (temp->level));
585169702Skan  insert_slot_to_list (temp, temp_slots_at_level (level));
586169702Skan  temp->level = level;
587169702Skan}
588169702Skan
589169702Skan/* Make temporary slot TEMP available.  */
590169702Skan
591169702Skanstatic void
592169702Skanmake_slot_available (struct temp_slot *temp)
593169702Skan{
594169702Skan  cut_slot_from_list (temp, temp_slots_at_level (temp->level));
595169702Skan  insert_slot_to_list (temp, &avail_temp_slots);
596169702Skan  temp->in_use = 0;
597169702Skan  temp->level = -1;
598169702Skan}
599169702Skan
60018334Speter/* Allocate a temporary stack slot and record it for possible later
60118334Speter   reuse.
60218334Speter
60318334Speter   MODE is the machine mode to be given to the returned rtx.
60418334Speter
60518334Speter   SIZE is the size in units of the space required.  We do no rounding here
60618334Speter   since assign_stack_local will do any required rounding.
60718334Speter
60818334Speter   KEEP is 1 if this slot is to be retained after a call to
60918334Speter   free_temp_slots.  Automatic variables for a block are allocated
610169702Skan   with this flag.  KEEP values of 2 or 3 were needed respectively
611169702Skan   for variables whose lifetime is controlled by CLEANUP_POINT_EXPRs
612169702Skan   or for SAVE_EXPRs, but they are now unused.
61318334Speter
61452518Sobrien   TYPE is the type that will be used for the stack slot.  */
61552518Sobrien
61690091Sobrienrtx
617169702Skanassign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size,
618169702Skan			    int keep, tree type)
61918334Speter{
62090091Sobrien  unsigned int align;
621169702Skan  struct temp_slot *p, *best_p = 0, *selected = NULL, **pp;
622102794Skan  rtx slot;
62318334Speter
62418334Speter  /* If SIZE is -1 it means that somebody tried to allocate a temporary
62518334Speter     of a variable size.  */
626169702Skan  gcc_assert (size != -1);
62718334Speter
628169702Skan  /* These are now unused.  */
629169702Skan  gcc_assert (keep <= 1);
630169702Skan
63152518Sobrien  if (mode == BLKmode)
63252518Sobrien    align = BIGGEST_ALIGNMENT;
63390091Sobrien  else
63490091Sobrien    align = GET_MODE_ALIGNMENT (mode);
63552518Sobrien
63652518Sobrien  if (! type)
637169702Skan    type = lang_hooks.types.type_for_mode (mode, 0);
63890091Sobrien
63952518Sobrien  if (type)
64052518Sobrien    align = LOCAL_ALIGNMENT (type, align);
64152518Sobrien
64252518Sobrien  /* Try to find an available, already-allocated temporary of the proper
64352518Sobrien     mode which meets the size and alignment requirements.  Choose the
644169702Skan     smallest one with the closest alignment.
645169702Skan
646169702Skan     If assign_stack_temp is called outside of the tree->rtl expansion,
647169702Skan     we cannot reuse the stack slots (that may still refer to
648169702Skan     VIRTUAL_STACK_VARS_REGNUM).  */
649169702Skan  if (!virtuals_instantiated)
650169702Skan    {
651169702Skan      for (p = avail_temp_slots; p; p = p->next)
652169702Skan	{
653169702Skan	  if (p->align >= align && p->size >= size
654169702Skan	      && GET_MODE (p->slot) == mode
655169702Skan	      && objects_must_conflict_p (p->type, type)
656169702Skan	      && (best_p == 0 || best_p->size > p->size
657169702Skan		  || (best_p->size == p->size && best_p->align > p->align)))
658169702Skan	    {
659169702Skan	      if (p->align == align && p->size == size)
660169702Skan		{
661169702Skan		  selected = p;
662169702Skan		  cut_slot_from_list (selected, &avail_temp_slots);
663169702Skan		  best_p = 0;
664169702Skan		  break;
665169702Skan		}
666169702Skan	      best_p = p;
667169702Skan	    }
668169702Skan	}
669169702Skan    }
67018334Speter
67118334Speter  /* Make our best, if any, the one to use.  */
67218334Speter  if (best_p)
67318334Speter    {
674169702Skan      selected = best_p;
675169702Skan      cut_slot_from_list (selected, &avail_temp_slots);
676169702Skan
67718334Speter      /* If there are enough aligned bytes left over, make them into a new
67818334Speter	 temp_slot so that the extra bytes don't get wasted.  Do this only
67918334Speter	 for BLKmode slots, so that we can be sure of the alignment.  */
68090091Sobrien      if (GET_MODE (best_p->slot) == BLKmode)
68118334Speter	{
68252518Sobrien	  int alignment = best_p->align / BITS_PER_UNIT;
68352268Sobrien	  HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
68418334Speter
68518334Speter	  if (best_p->size - rounded_size >= alignment)
68618334Speter	    {
687132732Skan	      p = ggc_alloc (sizeof (struct temp_slot));
68818334Speter	      p->in_use = p->addr_taken = 0;
68918334Speter	      p->size = best_p->size - rounded_size;
69018334Speter	      p->base_offset = best_p->base_offset + rounded_size;
69118334Speter	      p->full_size = best_p->full_size - rounded_size;
692169702Skan	      p->slot = adjust_address_nv (best_p->slot, BLKmode, rounded_size);
69352518Sobrien	      p->align = best_p->align;
69418334Speter	      p->address = 0;
69590091Sobrien	      p->type = best_p->type;
696169702Skan	      insert_slot_to_list (p, &avail_temp_slots);
69718334Speter
69852268Sobrien	      stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, p->slot,
69952268Sobrien						   stack_slot_list);
70018334Speter
70118334Speter	      best_p->size = rounded_size;
70218334Speter	      best_p->full_size = rounded_size;
70318334Speter	    }
70418334Speter	}
70518334Speter    }
70690091Sobrien
70718334Speter  /* If we still didn't find one, make a new temporary.  */
708169702Skan  if (selected == 0)
70918334Speter    {
71052268Sobrien      HOST_WIDE_INT frame_offset_old = frame_offset;
71152268Sobrien
712132732Skan      p = ggc_alloc (sizeof (struct temp_slot));
71352268Sobrien
71452518Sobrien      /* We are passing an explicit alignment request to assign_stack_local.
71552518Sobrien	 One side effect of that is assign_stack_local will not round SIZE
71652518Sobrien	 to ensure the frame offset remains suitably aligned.
71752268Sobrien
71852518Sobrien	 So for requests which depended on the rounding of SIZE, we go ahead
71952518Sobrien	 and round it now.  We also make sure ALIGNMENT is at least
72052518Sobrien	 BIGGEST_ALIGNMENT.  */
721169702Skan      gcc_assert (mode != BLKmode || align == BIGGEST_ALIGNMENT);
72252518Sobrien      p->slot = assign_stack_local (mode,
72352763Sobrien				    (mode == BLKmode
724132732Skan				     ? CEIL_ROUND (size, (int) align / BITS_PER_UNIT)
72552763Sobrien				     : size),
72652518Sobrien				    align);
72752518Sobrien
72852518Sobrien      p->align = align;
72952518Sobrien
73018334Speter      /* The following slot size computation is necessary because we don't
73118334Speter	 know the actual size of the temporary slot until assign_stack_local
73218334Speter	 has performed all the frame alignment and size rounding for the
73318334Speter	 requested temporary.  Note that extra space added for alignment
73418334Speter	 can be either above or below this stack slot depending on which
73518334Speter	 way the frame grows.  We include the extra space if and only if it
73618334Speter	 is above this slot.  */
737169702Skan      if (FRAME_GROWS_DOWNWARD)
738169702Skan	p->size = frame_offset_old - frame_offset;
739169702Skan      else
740169702Skan	p->size = size;
74152268Sobrien
74218334Speter      /* Now define the fields used by combine_temp_slots.  */
743169702Skan      if (FRAME_GROWS_DOWNWARD)
744169702Skan	{
745169702Skan	  p->base_offset = frame_offset;
746169702Skan	  p->full_size = frame_offset_old - frame_offset;
747169702Skan	}
748169702Skan      else
749169702Skan	{
750169702Skan	  p->base_offset = frame_offset_old;
751169702Skan	  p->full_size = frame_offset - frame_offset_old;
752169702Skan	}
75318334Speter      p->address = 0;
754169702Skan
755169702Skan      selected = p;
75618334Speter    }
75718334Speter
758169702Skan  p = selected;
75918334Speter  p->in_use = 1;
76018334Speter  p->addr_taken = 0;
76190091Sobrien  p->type = type;
762169702Skan  p->level = temp_slot_level;
763169702Skan  p->keep = keep;
76418334Speter
765169702Skan  pp = temp_slots_at_level (p->level);
766169702Skan  insert_slot_to_list (p, pp);
76752268Sobrien
768102794Skan  /* Create a new MEM rtx to avoid clobbering MEM flags of old slots.  */
769102794Skan  slot = gen_rtx_MEM (mode, XEXP (p->slot, 0));
770102794Skan  stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, slot, stack_slot_list);
771102794Skan
77290091Sobrien  /* If we know the alias set for the memory that will be used, use
77390091Sobrien     it.  If there's no TYPE, then we don't know anything about the
77490091Sobrien     alias set for the memory.  */
775102794Skan  set_mem_alias_set (slot, type ? get_alias_set (type) : 0);
776102794Skan  set_mem_align (slot, align);
77790091Sobrien
77890091Sobrien  /* If a type is specified, set the relevant flags.  */
77990091Sobrien  if (type != 0)
78090091Sobrien    {
781102794Skan      MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type);
782102794Skan      MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type));
78390091Sobrien    }
784169702Skan  MEM_NOTRAP_P (slot) = 1;
78590091Sobrien
786102794Skan  return slot;
78718334Speter}
78852518Sobrien
78952518Sobrien/* Allocate a temporary stack slot and record it for possible later
79052518Sobrien   reuse.  First three arguments are same as in preceding function.  */
79152518Sobrien
79252518Sobrienrtx
793132732Skanassign_stack_temp (enum machine_mode mode, HOST_WIDE_INT size, int keep)
79452518Sobrien{
79552518Sobrien  return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
79652518Sobrien}
79752268Sobrien
79896283Sobrien/* Assign a temporary.
79996283Sobrien   If TYPE_OR_DECL is a decl, then we are doing it on behalf of the decl
80096283Sobrien   and so that should be used in error messages.  In either case, we
80196283Sobrien   allocate of the given type.
80252268Sobrien   KEEP is as for assign_stack_temp.
80352268Sobrien   MEMORY_REQUIRED is 1 if the result must be addressable stack memory;
80452268Sobrien   it is 0 if a register is OK.
80552268Sobrien   DONT_PROMOTE is 1 if we should not promote values in register
80652268Sobrien   to wider modes.  */
80718334Speter
80852268Sobrienrtx
809132732Skanassign_temp (tree type_or_decl, int keep, int memory_required,
810132732Skan	     int dont_promote ATTRIBUTE_UNUSED)
81152268Sobrien{
81296283Sobrien  tree type, decl;
81396283Sobrien  enum machine_mode mode;
814169702Skan#ifdef PROMOTE_MODE
81596283Sobrien  int unsignedp;
81690091Sobrien#endif
81752268Sobrien
81896283Sobrien  if (DECL_P (type_or_decl))
81996283Sobrien    decl = type_or_decl, type = TREE_TYPE (decl);
82096283Sobrien  else
82196283Sobrien    decl = NULL, type = type_or_decl;
82296283Sobrien
82396283Sobrien  mode = TYPE_MODE (type);
824169702Skan#ifdef PROMOTE_MODE
825169702Skan  unsignedp = TYPE_UNSIGNED (type);
82696283Sobrien#endif
82796283Sobrien
82852268Sobrien  if (mode == BLKmode || memory_required)
82952268Sobrien    {
83052268Sobrien      HOST_WIDE_INT size = int_size_in_bytes (type);
83152268Sobrien      rtx tmp;
83252268Sobrien
83390091Sobrien      /* Zero sized arrays are GNU C extension.  Set size to 1 to avoid
83490091Sobrien	 problems with allocating the stack space.  */
83590091Sobrien      if (size == 0)
83690091Sobrien	size = 1;
83790091Sobrien
83852268Sobrien      /* Unfortunately, we don't yet know how to allocate variable-sized
839169702Skan	 temporaries.  However, sometimes we can find a fixed upper limit on
840169702Skan	 the size, so try that instead.  */
841169702Skan      else if (size == -1)
842169702Skan	size = max_int_size_in_bytes (type);
84352268Sobrien
84496283Sobrien      /* The size of the temporary may be too large to fit into an integer.  */
84596283Sobrien      /* ??? Not sure this should happen except for user silliness, so limit
846117404Skan	 this to things that aren't compiler-generated temporaries.  The
847169702Skan	 rest of the time we'll die in assign_stack_temp_for_type.  */
84896283Sobrien      if (decl && size == -1
84996283Sobrien	  && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
85096283Sobrien	{
851169702Skan	  error ("size of variable %q+D is too large", decl);
85296283Sobrien	  size = 1;
85396283Sobrien	}
85496283Sobrien
85552518Sobrien      tmp = assign_stack_temp_for_type (mode, size, keep, type);
85652268Sobrien      return tmp;
85752268Sobrien    }
85852268Sobrien
859169702Skan#ifdef PROMOTE_MODE
86052268Sobrien  if (! dont_promote)
86152268Sobrien    mode = promote_mode (type, mode, &unsignedp, 0);
86252268Sobrien#endif
86352268Sobrien
86452268Sobrien  return gen_reg_rtx (mode);
86552268Sobrien}
86652268Sobrien
86718334Speter/* Combine temporary stack slots which are adjacent on the stack.
86818334Speter
86918334Speter   This allows for better use of already allocated stack space.  This is only
87018334Speter   done for BLKmode slots because we can be sure that we won't have alignment
87118334Speter   problems in this case.  */
87218334Speter
873169702Skanstatic void
874132732Skancombine_temp_slots (void)
87518334Speter{
876169702Skan  struct temp_slot *p, *q, *next, *next_q;
87752268Sobrien  int num_slots;
87818334Speter
87952518Sobrien  /* We can't combine slots, because the information about which slot
88052518Sobrien     is in which alias set will be lost.  */
88152518Sobrien  if (flag_strict_aliasing)
88252518Sobrien    return;
88352518Sobrien
88490091Sobrien  /* If there are a lot of temp slots, don't do anything unless
88590091Sobrien     high levels of optimization.  */
88652268Sobrien  if (! flag_expensive_optimizations)
887169702Skan    for (p = avail_temp_slots, num_slots = 0; p; p = p->next, num_slots++)
88852268Sobrien      if (num_slots > 100 || (num_slots > 10 && optimize == 0))
88952268Sobrien	return;
89052268Sobrien
891169702Skan  for (p = avail_temp_slots; p; p = next)
89218334Speter    {
89318334Speter      int delete_p = 0;
89452268Sobrien
895169702Skan      next = p->next;
896169702Skan
897169702Skan      if (GET_MODE (p->slot) != BLKmode)
898169702Skan	continue;
899169702Skan
900169702Skan      for (q = p->next; q; q = next_q)
901169702Skan	{
902169702Skan       	  int delete_q = 0;
903169702Skan
904169702Skan	  next_q = q->next;
905169702Skan
906169702Skan	  if (GET_MODE (q->slot) != BLKmode)
907169702Skan	    continue;
908169702Skan
909169702Skan	  if (p->base_offset + p->full_size == q->base_offset)
910169702Skan	    {
911169702Skan	      /* Q comes after P; combine Q into P.  */
912169702Skan	      p->size += q->size;
913169702Skan	      p->full_size += q->full_size;
914169702Skan	      delete_q = 1;
915169702Skan	    }
916169702Skan	  else if (q->base_offset + q->full_size == p->base_offset)
917169702Skan	    {
918169702Skan	      /* P comes after Q; combine P into Q.  */
919169702Skan	      q->size += p->size;
920169702Skan	      q->full_size += p->full_size;
921169702Skan	      delete_p = 1;
922169702Skan	      break;
923169702Skan	    }
924169702Skan	  if (delete_q)
925169702Skan	    cut_slot_from_list (q, &avail_temp_slots);
926169702Skan	}
927169702Skan
92818334Speter      /* Either delete P or advance past it.  */
92918334Speter      if (delete_p)
930169702Skan	cut_slot_from_list (p, &avail_temp_slots);
93118334Speter    }
93218334Speter}
93318334Speter
93418334Speter/* Find the temp slot corresponding to the object at address X.  */
93518334Speter
93618334Speterstatic struct temp_slot *
937132732Skanfind_temp_slot_from_address (rtx x)
93818334Speter{
93918334Speter  struct temp_slot *p;
94018334Speter  rtx next;
941169702Skan  int i;
94218334Speter
943169702Skan  for (i = max_slot_level (); i >= 0; i--)
944169702Skan    for (p = *temp_slots_at_level (i); p; p = p->next)
945169702Skan      {
946169702Skan	if (XEXP (p->slot, 0) == x
947169702Skan	    || p->address == x
948169702Skan	    || (GET_CODE (x) == PLUS
949169702Skan		&& XEXP (x, 0) == virtual_stack_vars_rtx
950169702Skan		&& GET_CODE (XEXP (x, 1)) == CONST_INT
951169702Skan		&& INTVAL (XEXP (x, 1)) >= p->base_offset
952169702Skan		&& INTVAL (XEXP (x, 1)) < p->base_offset + p->full_size))
953169702Skan	  return p;
95452268Sobrien
955169702Skan	else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST)
956169702Skan	  for (next = p->address; next; next = XEXP (next, 1))
957169702Skan	    if (XEXP (next, 0) == x)
958169702Skan	      return p;
959169702Skan      }
96018334Speter
96190091Sobrien  /* If we have a sum involving a register, see if it points to a temp
96290091Sobrien     slot.  */
963169702Skan  if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))
96490091Sobrien      && (p = find_temp_slot_from_address (XEXP (x, 0))) != 0)
96590091Sobrien    return p;
966169702Skan  else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 1))
96790091Sobrien	   && (p = find_temp_slot_from_address (XEXP (x, 1))) != 0)
96890091Sobrien    return p;
96990091Sobrien
97018334Speter  return 0;
97118334Speter}
97290091Sobrien
97318334Speter/* Indicate that NEW is an alternate way of referring to the temp slot
97452268Sobrien   that previously was known by OLD.  */
97518334Speter
97618334Spetervoid
977132732Skanupdate_temp_slot_address (rtx old, rtx new)
97818334Speter{
97990091Sobrien  struct temp_slot *p;
98018334Speter
98190091Sobrien  if (rtx_equal_p (old, new))
98290091Sobrien    return;
98390091Sobrien
98490091Sobrien  p = find_temp_slot_from_address (old);
98590091Sobrien
98690091Sobrien  /* If we didn't find one, see if both OLD is a PLUS.  If so, and NEW
98790091Sobrien     is a register, see if one operand of the PLUS is a temporary
98890091Sobrien     location.  If so, NEW points into it.  Otherwise, if both OLD and
98990091Sobrien     NEW are a PLUS and if there is a register in common between them.
99090091Sobrien     If so, try a recursive call on those values.  */
99118334Speter  if (p == 0)
99290091Sobrien    {
99390091Sobrien      if (GET_CODE (old) != PLUS)
99490091Sobrien	return;
99590091Sobrien
996169702Skan      if (REG_P (new))
99790091Sobrien	{
99890091Sobrien	  update_temp_slot_address (XEXP (old, 0), new);
99990091Sobrien	  update_temp_slot_address (XEXP (old, 1), new);
100090091Sobrien	  return;
100190091Sobrien	}
100290091Sobrien      else if (GET_CODE (new) != PLUS)
100390091Sobrien	return;
100490091Sobrien
100590091Sobrien      if (rtx_equal_p (XEXP (old, 0), XEXP (new, 0)))
100690091Sobrien	update_temp_slot_address (XEXP (old, 1), XEXP (new, 1));
100790091Sobrien      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 0)))
100890091Sobrien	update_temp_slot_address (XEXP (old, 0), XEXP (new, 1));
100990091Sobrien      else if (rtx_equal_p (XEXP (old, 0), XEXP (new, 1)))
101090091Sobrien	update_temp_slot_address (XEXP (old, 1), XEXP (new, 0));
101190091Sobrien      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 1)))
101290091Sobrien	update_temp_slot_address (XEXP (old, 0), XEXP (new, 0));
101390091Sobrien
101490091Sobrien      return;
101590091Sobrien    }
101690091Sobrien
101790091Sobrien  /* Otherwise add an alias for the temp's address.  */
101818334Speter  else if (p->address == 0)
101918334Speter    p->address = new;
102018334Speter  else
102118334Speter    {
102218334Speter      if (GET_CODE (p->address) != EXPR_LIST)
102352268Sobrien	p->address = gen_rtx_EXPR_LIST (VOIDmode, p->address, NULL_RTX);
102418334Speter
102552268Sobrien      p->address = gen_rtx_EXPR_LIST (VOIDmode, new, p->address);
102618334Speter    }
102718334Speter}
102818334Speter
102918334Speter/* If X could be a reference to a temporary slot, mark the fact that its
103018334Speter   address was taken.  */
103118334Speter
103218334Spetervoid
1033132732Skanmark_temp_addr_taken (rtx x)
103418334Speter{
103518334Speter  struct temp_slot *p;
103618334Speter
103718334Speter  if (x == 0)
103818334Speter    return;
103918334Speter
104018334Speter  /* If X is not in memory or is at a constant address, it cannot be in
104118334Speter     a temporary slot.  */
1042169702Skan  if (!MEM_P (x) || CONSTANT_P (XEXP (x, 0)))
104318334Speter    return;
104418334Speter
104518334Speter  p = find_temp_slot_from_address (XEXP (x, 0));
104618334Speter  if (p != 0)
104718334Speter    p->addr_taken = 1;
104818334Speter}
104918334Speter
105052268Sobrien/* If X could be a reference to a temporary slot, mark that slot as
105152268Sobrien   belonging to the to one level higher than the current level.  If X
105252268Sobrien   matched one of our slots, just mark that one.  Otherwise, we can't
105352268Sobrien   easily predict which it is, so upgrade all of them.  Kept slots
105452268Sobrien   need not be touched.
105518334Speter
105618334Speter   This is called when an ({...}) construct occurs and a statement
105718334Speter   returns a value in memory.  */
105818334Speter
105918334Spetervoid
1060132732Skanpreserve_temp_slots (rtx x)
106118334Speter{
1062169702Skan  struct temp_slot *p = 0, *next;
106318334Speter
106418334Speter  /* If there is no result, we still might have some objects whose address
106518334Speter     were taken, so we need to make sure they stay around.  */
106618334Speter  if (x == 0)
106718334Speter    {
1068169702Skan      for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1069169702Skan	{
1070169702Skan	  next = p->next;
107118334Speter
1072169702Skan	  if (p->addr_taken)
1073169702Skan	    move_slot_to_level (p, temp_slot_level - 1);
1074169702Skan	}
1075169702Skan
107618334Speter      return;
107718334Speter    }
107818334Speter
107918334Speter  /* If X is a register that is being used as a pointer, see if we have
108018334Speter     a temporary slot we know it points to.  To be consistent with
108118334Speter     the code below, we really should preserve all non-kept slots
108218334Speter     if we can't find a match, but that seems to be much too costly.  */
1083169702Skan  if (REG_P (x) && REG_POINTER (x))
108418334Speter    p = find_temp_slot_from_address (x);
108518334Speter
108618334Speter  /* If X is not in memory or is at a constant address, it cannot be in
108718334Speter     a temporary slot, but it can contain something whose address was
108818334Speter     taken.  */
1089169702Skan  if (p == 0 && (!MEM_P (x) || CONSTANT_P (XEXP (x, 0))))
109018334Speter    {
1091169702Skan      for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1092169702Skan	{
1093169702Skan	  next = p->next;
109418334Speter
1095169702Skan	  if (p->addr_taken)
1096169702Skan	    move_slot_to_level (p, temp_slot_level - 1);
1097169702Skan	}
1098169702Skan
109918334Speter      return;
110018334Speter    }
110118334Speter
110218334Speter  /* First see if we can find a match.  */
110318334Speter  if (p == 0)
110418334Speter    p = find_temp_slot_from_address (XEXP (x, 0));
110518334Speter
110618334Speter  if (p != 0)
110718334Speter    {
110818334Speter      /* Move everything at our level whose address was taken to our new
110918334Speter	 level in case we used its address.  */
111018334Speter      struct temp_slot *q;
111118334Speter
111252268Sobrien      if (p->level == temp_slot_level)
111352268Sobrien	{
1114169702Skan	  for (q = *temp_slots_at_level (temp_slot_level); q; q = next)
1115169702Skan	    {
1116169702Skan	      next = q->next;
111718334Speter
1118169702Skan	      if (p != q && q->addr_taken)
1119169702Skan		move_slot_to_level (q, temp_slot_level - 1);
1120169702Skan	    }
1121169702Skan
1122169702Skan	  move_slot_to_level (p, temp_slot_level - 1);
112352268Sobrien	  p->addr_taken = 0;
112452268Sobrien	}
112518334Speter      return;
112618334Speter    }
112718334Speter
112818334Speter  /* Otherwise, preserve all non-kept slots at this level.  */
1129169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1130169702Skan    {
1131169702Skan      next = p->next;
113218334Speter
1133169702Skan      if (!p->keep)
1134169702Skan	move_slot_to_level (p, temp_slot_level - 1);
113518334Speter    }
113618334Speter}
113718334Speter
1138169702Skan/* Free all temporaries used so far.  This is normally called at the
1139169702Skan   end of generating code for a statement.  */
114018334Speter
114118334Spetervoid
1142132732Skanfree_temp_slots (void)
114318334Speter{
1144169702Skan  struct temp_slot *p, *next;
114518334Speter
1146169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1147169702Skan    {
1148169702Skan      next = p->next;
114918334Speter
1150169702Skan      if (!p->keep)
1151169702Skan	make_slot_available (p);
1152169702Skan    }
115318334Speter
115418334Speter  combine_temp_slots ();
115518334Speter}
115618334Speter
115718334Speter/* Push deeper into the nesting level for stack temporaries.  */
115818334Speter
115918334Spetervoid
1160132732Skanpush_temp_slots (void)
116118334Speter{
116218334Speter  temp_slot_level++;
116318334Speter}
116418334Speter
116518334Speter/* Pop a temporary nesting level.  All slots in use in the current level
116618334Speter   are freed.  */
116718334Speter
116818334Spetervoid
1169132732Skanpop_temp_slots (void)
117018334Speter{
1171169702Skan  struct temp_slot *p, *next;
117218334Speter
1173169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1174169702Skan    {
1175169702Skan      next = p->next;
1176169702Skan      make_slot_available (p);
1177169702Skan    }
117818334Speter
117918334Speter  combine_temp_slots ();
118018334Speter
118118334Speter  temp_slot_level--;
118218334Speter}
118352268Sobrien
118452268Sobrien/* Initialize temporary slots.  */
118552268Sobrien
118652268Sobrienvoid
1187132732Skaninit_temp_slots (void)
118852268Sobrien{
118952268Sobrien  /* We have not allocated any temporaries yet.  */
1190169702Skan  avail_temp_slots = 0;
1191169702Skan  used_temp_slots = 0;
119252268Sobrien  temp_slot_level = 0;
119352268Sobrien}
119418334Speter
1195169702Skan/* These routines are responsible for converting virtual register references
1196169702Skan   to the actual hard register references once RTL generation is complete.
119718334Speter
1198169702Skan   The following four variables are used for communication between the
1199169702Skan   routines.  They contain the offsets of the virtual registers from their
1200169702Skan   respective hard registers.  */
120118334Speter
1202169702Skanstatic int in_arg_offset;
1203169702Skanstatic int var_offset;
1204169702Skanstatic int dynamic_offset;
1205169702Skanstatic int out_arg_offset;
1206169702Skanstatic int cfa_offset;
120718334Speter
1208169702Skan/* In most machines, the stack pointer register is equivalent to the bottom
1209169702Skan   of the stack.  */
121018334Speter
1211169702Skan#ifndef STACK_POINTER_OFFSET
1212169702Skan#define STACK_POINTER_OFFSET	0
1213169702Skan#endif
121418334Speter
1215169702Skan/* If not defined, pick an appropriate default for the offset of dynamically
1216169702Skan   allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
1217169702Skan   REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE.  */
121818334Speter
1219169702Skan#ifndef STACK_DYNAMIC_OFFSET
122018334Speter
1221169702Skan/* The bottom of the stack points to the actual arguments.  If
1222169702Skan   REG_PARM_STACK_SPACE is defined, this includes the space for the register
1223169702Skan   parameters.  However, if OUTGOING_REG_PARM_STACK space is not defined,
1224169702Skan   stack space for register parameters is not pushed by the caller, but
1225169702Skan   rather part of the fixed stack areas and hence not included in
1226169702Skan   `current_function_outgoing_args_size'.  Nevertheless, we must allow
1227169702Skan   for it when allocating stack dynamic objects.  */
122818334Speter
1229169702Skan#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
1230169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL)	\
1231169702Skan((ACCUMULATE_OUTGOING_ARGS						      \
1232169702Skan  ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\
1233169702Skan + (STACK_POINTER_OFFSET))						      \
1234169702Skan
1235169702Skan#else
1236169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL)	\
1237169702Skan((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0)	      \
1238169702Skan + (STACK_POINTER_OFFSET))
123952268Sobrien#endif
1240169702Skan#endif
124152268Sobrien
1242169702Skan
1243169702Skan/* Given a piece of RTX and a pointer to a HOST_WIDE_INT, if the RTX
1244169702Skan   is a virtual register, return the equivalent hard register and set the
1245169702Skan   offset indirectly through the pointer.  Otherwise, return 0.  */
124652268Sobrien
1247169702Skanstatic rtx
1248169702Skaninstantiate_new_reg (rtx x, HOST_WIDE_INT *poffset)
1249169702Skan{
1250169702Skan  rtx new;
1251169702Skan  HOST_WIDE_INT offset;
125218334Speter
1253169702Skan  if (x == virtual_incoming_args_rtx)
1254169702Skan    new = arg_pointer_rtx, offset = in_arg_offset;
1255169702Skan  else if (x == virtual_stack_vars_rtx)
1256169702Skan    new = frame_pointer_rtx, offset = var_offset;
1257169702Skan  else if (x == virtual_stack_dynamic_rtx)
1258169702Skan    new = stack_pointer_rtx, offset = dynamic_offset;
1259169702Skan  else if (x == virtual_outgoing_args_rtx)
1260169702Skan    new = stack_pointer_rtx, offset = out_arg_offset;
1261169702Skan  else if (x == virtual_cfa_rtx)
126252268Sobrien    {
1263169702Skan#ifdef FRAME_POINTER_CFA_OFFSET
1264169702Skan      new = frame_pointer_rtx;
126518334Speter#else
1266169702Skan      new = arg_pointer_rtx;
126718334Speter#endif
1268169702Skan      offset = cfa_offset;
126918334Speter    }
127052268Sobrien  else
1271169702Skan    return NULL_RTX;
127218334Speter
1273169702Skan  *poffset = offset;
1274169702Skan  return new;
127590091Sobrien}
127652268Sobrien
1277169702Skan/* A subroutine of instantiate_virtual_regs, called via for_each_rtx.
1278169702Skan   Instantiate any virtual registers present inside of *LOC.  The expression
1279169702Skan   is simplified, as much as possible, but is not to be considered "valid"
1280169702Skan   in any sense implied by the target.  If any change is made, set CHANGED
1281169702Skan   to true.  */
128290091Sobrien
1283169702Skanstatic int
1284169702Skaninstantiate_virtual_regs_in_rtx (rtx *loc, void *data)
128590091Sobrien{
1286169702Skan  HOST_WIDE_INT offset;
1287169702Skan  bool *changed = (bool *) data;
1288169702Skan  rtx x, new;
128990091Sobrien
1290169702Skan  x = *loc;
1291169702Skan  if (x == 0)
1292169702Skan    return 0;
129318334Speter
1294169702Skan  switch (GET_CODE (x))
129590091Sobrien    {
1296169702Skan    case REG:
1297169702Skan      new = instantiate_new_reg (x, &offset);
1298169702Skan      if (new)
1299169702Skan	{
1300169702Skan	  *loc = plus_constant (new, offset);
1301169702Skan	  if (changed)
1302169702Skan	    *changed = true;
1303169702Skan	}
1304169702Skan      return -1;
130518334Speter
1306169702Skan    case PLUS:
1307169702Skan      new = instantiate_new_reg (XEXP (x, 0), &offset);
1308169702Skan      if (new)
130918334Speter	{
1310169702Skan	  new = plus_constant (new, offset);
1311169702Skan	  *loc = simplify_gen_binary (PLUS, GET_MODE (x), new, XEXP (x, 1));
1312169702Skan	  if (changed)
1313169702Skan	    *changed = true;
1314169702Skan	  return -1;
131518334Speter	}
131618334Speter
1317169702Skan      /* FIXME -- from old code */
1318169702Skan	  /* If we have (plus (subreg (virtual-reg)) (const_int)), we know
1319169702Skan	     we can commute the PLUS and SUBREG because pointers into the
1320169702Skan	     frame are well-behaved.  */
1321169702Skan      break;
132218334Speter
1323169702Skan    default:
1324169702Skan      break;
132518334Speter    }
132618334Speter
1327169702Skan  return 0;
132818334Speter}
132918334Speter
1330169702Skan/* A subroutine of instantiate_virtual_regs_in_insn.  Return true if X
1331169702Skan   matches the predicate for insn CODE operand OPERAND.  */
133218334Speter
1333169702Skanstatic int
1334169702Skansafe_insn_predicate (int code, int operand, rtx x)
133518334Speter{
1336169702Skan  const struct insn_operand_data *op_data;
133752268Sobrien
1338169702Skan  if (code < 0)
1339169702Skan    return true;
134090091Sobrien
1341169702Skan  op_data = &insn_data[code].operand[operand];
1342169702Skan  if (op_data->predicate == NULL)
1343169702Skan    return true;
134418334Speter
1345169702Skan  return op_data->predicate (x, op_data->mode);
134690091Sobrien}
134718334Speter
1348169702Skan/* A subroutine of instantiate_virtual_regs.  Instantiate any virtual
1349169702Skan   registers present inside of insn.  The result will be a valid insn.  */
135018334Speter
135190091Sobrienstatic void
1352169702Skaninstantiate_virtual_regs_in_insn (rtx insn)
135390091Sobrien{
1354169702Skan  HOST_WIDE_INT offset;
1355169702Skan  int insn_code, i;
1356169702Skan  bool any_change = false;
1357169702Skan  rtx set, new, x, seq;
135818334Speter
1359169702Skan  /* There are some special cases to be handled first.  */
1360169702Skan  set = single_set (insn);
1361169702Skan  if (set)
136290091Sobrien    {
1363169702Skan      /* We're allowed to assign to a virtual register.  This is interpreted
1364169702Skan	 to mean that the underlying register gets assigned the inverse
1365169702Skan	 transformation.  This is used, for example, in the handling of
1366169702Skan	 non-local gotos.  */
1367169702Skan      new = instantiate_new_reg (SET_DEST (set), &offset);
1368169702Skan      if (new)
136990091Sobrien	{
1370169702Skan	  start_sequence ();
137118334Speter
1372169702Skan	  for_each_rtx (&SET_SRC (set), instantiate_virtual_regs_in_rtx, NULL);
1373169702Skan	  x = simplify_gen_binary (PLUS, GET_MODE (new), SET_SRC (set),
1374169702Skan				   GEN_INT (-offset));
1375169702Skan	  x = force_operand (x, new);
1376169702Skan	  if (x != new)
1377169702Skan	    emit_move_insn (new, x);
137890091Sobrien
1379169702Skan	  seq = get_insns ();
1380169702Skan	  end_sequence ();
138190091Sobrien
1382169702Skan	  emit_insn_before (seq, insn);
1383169702Skan	  delete_insn (insn);
1384169702Skan	  return;
138518334Speter	}
138652518Sobrien
1387169702Skan      /* Handle a straight copy from a virtual register by generating a
1388169702Skan	 new add insn.  The difference between this and falling through
1389169702Skan	 to the generic case is avoiding a new pseudo and eliminating a
1390169702Skan	 move insn in the initial rtl stream.  */
1391169702Skan      new = instantiate_new_reg (SET_SRC (set), &offset);
1392169702Skan      if (new && offset != 0
1393169702Skan	  && REG_P (SET_DEST (set))
1394169702Skan	  && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
139552518Sobrien	{
1396169702Skan	  start_sequence ();
139790091Sobrien
1398169702Skan	  x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS,
1399169702Skan				   new, GEN_INT (offset), SET_DEST (set),
1400169702Skan				   1, OPTAB_LIB_WIDEN);
1401169702Skan	  if (x != SET_DEST (set))
1402169702Skan	    emit_move_insn (SET_DEST (set), x);
140390091Sobrien
1404169702Skan	  seq = get_insns ();
1405169702Skan	  end_sequence ();
140690091Sobrien
1407169702Skan	  emit_insn_before (seq, insn);
1408169702Skan	  delete_insn (insn);
1409169702Skan	  return;
141052518Sobrien	}
141190091Sobrien
1412169702Skan      extract_insn (insn);
1413169702Skan      insn_code = INSN_CODE (insn);
141418334Speter
1415169702Skan      /* Handle a plus involving a virtual register by determining if the
1416169702Skan	 operands remain valid if they're modified in place.  */
1417169702Skan      if (GET_CODE (SET_SRC (set)) == PLUS
1418169702Skan	  && recog_data.n_operands >= 3
1419169702Skan	  && recog_data.operand_loc[1] == &XEXP (SET_SRC (set), 0)
1420169702Skan	  && recog_data.operand_loc[2] == &XEXP (SET_SRC (set), 1)
1421169702Skan	  && GET_CODE (recog_data.operand[2]) == CONST_INT
1422169702Skan	  && (new = instantiate_new_reg (recog_data.operand[1], &offset)))
142352268Sobrien	{
1424169702Skan	  offset += INTVAL (recog_data.operand[2]);
142552268Sobrien
1426169702Skan	  /* If the sum is zero, then replace with a plain move.  */
1427169702Skan	  if (offset == 0
1428169702Skan	      && REG_P (SET_DEST (set))
1429169702Skan	      && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
143052268Sobrien	    {
143152518Sobrien	      start_sequence ();
1432169702Skan	      emit_move_insn (SET_DEST (set), new);
1433117404Skan	      seq = get_insns ();
143452518Sobrien	      end_sequence ();
143552518Sobrien
143652518Sobrien	      emit_insn_before (seq, insn);
1437169702Skan	      delete_insn (insn);
1438169702Skan	      return;
143952268Sobrien	    }
144052268Sobrien
1441169702Skan	  x = gen_int_mode (offset, recog_data.operand_mode[2]);
144218334Speter
1443169702Skan	  /* Using validate_change and apply_change_group here leaves
1444169702Skan	     recog_data in an invalid state.  Since we know exactly what
1445169702Skan	     we want to check, do those two by hand.  */
1446169702Skan	  if (safe_insn_predicate (insn_code, 1, new)
1447169702Skan	      && safe_insn_predicate (insn_code, 2, x))
144818334Speter	    {
1449169702Skan	      *recog_data.operand_loc[1] = recog_data.operand[1] = new;
1450169702Skan	      *recog_data.operand_loc[2] = recog_data.operand[2] = x;
1451169702Skan	      any_change = true;
1452169702Skan
1453169702Skan	      /* Fall through into the regular operand fixup loop in
1454169702Skan		 order to take care of operands other than 1 and 2.  */
145518334Speter	    }
145618334Speter	}
1457169702Skan    }
1458169702Skan  else
1459169702Skan    {
1460169702Skan      extract_insn (insn);
1461169702Skan      insn_code = INSN_CODE (insn);
1462169702Skan    }
146318334Speter
1464169702Skan  /* In the general case, we expect virtual registers to appear only in
1465169702Skan     operands, and then only as either bare registers or inside memories.  */
1466169702Skan  for (i = 0; i < recog_data.n_operands; ++i)
1467169702Skan    {
1468169702Skan      x = recog_data.operand[i];
1469169702Skan      switch (GET_CODE (x))
147018334Speter	{
1471169702Skan	case MEM:
1472169702Skan	  {
1473169702Skan	    rtx addr = XEXP (x, 0);
1474169702Skan	    bool changed = false;
147518334Speter
1476169702Skan	    for_each_rtx (&addr, instantiate_virtual_regs_in_rtx, &changed);
1477169702Skan	    if (!changed)
1478169702Skan	      continue;
147918334Speter
1480169702Skan	    start_sequence ();
1481169702Skan	    x = replace_equiv_address (x, addr);
1482169702Skan	    seq = get_insns ();
1483169702Skan	    end_sequence ();
1484169702Skan	    if (seq)
1485169702Skan	      emit_insn_before (seq, insn);
1486169702Skan	  }
1487169702Skan	  break;
148818334Speter
1489169702Skan	case REG:
1490169702Skan	  new = instantiate_new_reg (x, &offset);
1491169702Skan	  if (new == NULL)
1492169702Skan	    continue;
1493169702Skan	  if (offset == 0)
1494169702Skan	    x = new;
149552268Sobrien	  else
149618334Speter	    {
1497169702Skan	      start_sequence ();
149818334Speter
1499169702Skan	      /* Careful, special mode predicates may have stuff in
1500169702Skan		 insn_data[insn_code].operand[i].mode that isn't useful
1501169702Skan		 to us for computing a new value.  */
1502169702Skan	      /* ??? Recognize address_operand and/or "p" constraints
1503169702Skan		 to see if (plus new offset) is a valid before we put
1504169702Skan		 this through expand_simple_binop.  */
1505169702Skan	      x = expand_simple_binop (GET_MODE (x), PLUS, new,
1506169702Skan				       GEN_INT (offset), NULL_RTX,
1507169702Skan				       1, OPTAB_LIB_WIDEN);
1508169702Skan	      seq = get_insns ();
1509169702Skan	      end_sequence ();
1510169702Skan	      emit_insn_before (seq, insn);
151118334Speter	    }
1512169702Skan	  break;
151318334Speter
1514169702Skan	case SUBREG:
1515169702Skan	  new = instantiate_new_reg (SUBREG_REG (x), &offset);
1516169702Skan	  if (new == NULL)
1517169702Skan	    continue;
1518169702Skan	  if (offset != 0)
151918334Speter	    {
1520169702Skan	      start_sequence ();
1521169702Skan	      new = expand_simple_binop (GET_MODE (new), PLUS, new,
1522169702Skan					 GEN_INT (offset), NULL_RTX,
1523169702Skan					 1, OPTAB_LIB_WIDEN);
1524169702Skan	      seq = get_insns ();
1525169702Skan	      end_sequence ();
1526169702Skan	      emit_insn_before (seq, insn);
152718334Speter	    }
1528169702Skan	  x = simplify_gen_subreg (recog_data.operand_mode[i], new,
1529169702Skan				   GET_MODE (new), SUBREG_BYTE (x));
1530169702Skan	  break;
153118334Speter
1532169702Skan	default:
1533169702Skan	  continue;
153418334Speter	}
153518334Speter
1536169702Skan      /* At this point, X contains the new value for the operand.
1537169702Skan	 Validate the new value vs the insn predicate.  Note that
1538169702Skan	 asm insns will have insn_code -1 here.  */
1539169702Skan      if (!safe_insn_predicate (insn_code, i, x))
154052268Sobrien	{
1541169702Skan	  start_sequence ();
1542169702Skan	  x = force_reg (insn_data[insn_code].operand[i].mode, x);
1543169702Skan	  seq = get_insns ();
1544169702Skan	  end_sequence ();
1545169702Skan	  if (seq)
1546169702Skan	    emit_insn_before (seq, insn);
154752268Sobrien	}
154852268Sobrien
1549169702Skan      *recog_data.operand_loc[i] = recog_data.operand[i] = x;
1550169702Skan      any_change = true;
1551169702Skan    }
155290091Sobrien
1553169702Skan  if (any_change)
1554169702Skan    {
1555169702Skan      /* Propagate operand changes into the duplicates.  */
1556169702Skan      for (i = 0; i < recog_data.n_dups; ++i)
1557169702Skan	*recog_data.dup_loc[i]
1558169702Skan	  = recog_data.operand[(unsigned)recog_data.dup_num[i]];
155918334Speter
1560169702Skan      /* Force re-recognition of the instruction for validation.  */
1561169702Skan      INSN_CODE (insn) = -1;
156218334Speter    }
156318334Speter
1564169702Skan  if (asm_noperands (PATTERN (insn)) >= 0)
156518334Speter    {
1566169702Skan      if (!check_asm_operands (PATTERN (insn)))
156718334Speter	{
1568169702Skan	  error_for_asm (insn, "impossible constraint in %<asm%>");
1569169702Skan	  delete_insn (insn);
157018334Speter	}
157118334Speter    }
1572169702Skan  else
1573169702Skan    {
1574169702Skan      if (recog_memoized (insn) < 0)
1575169702Skan	fatal_insn_not_found (insn);
1576169702Skan    }
157718334Speter}
157818334Speter
1579169702Skan/* Subroutine of instantiate_decls.  Given RTL representing a decl,
1580169702Skan   do any instantiation required.  */
158196283Sobrien
1582169702Skanstatic void
1583169702Skaninstantiate_decl (rtx x)
158418334Speter{
1585169702Skan  rtx addr;
158618334Speter
1587169702Skan  if (x == 0)
1588169702Skan    return;
158918334Speter
1590169702Skan  /* If this is a CONCAT, recurse for the pieces.  */
1591169702Skan  if (GET_CODE (x) == CONCAT)
1592169702Skan    {
1593169702Skan      instantiate_decl (XEXP (x, 0));
1594169702Skan      instantiate_decl (XEXP (x, 1));
1595169702Skan      return;
1596169702Skan    }
159796283Sobrien
1598169702Skan  /* If this is not a MEM, no need to do anything.  Similarly if the
1599169702Skan     address is a constant or a register that is not a virtual register.  */
1600169702Skan  if (!MEM_P (x))
1601169702Skan    return;
160290091Sobrien
1603169702Skan  addr = XEXP (x, 0);
1604169702Skan  if (CONSTANT_P (addr)
1605169702Skan      || (REG_P (addr)
1606169702Skan	  && (REGNO (addr) < FIRST_VIRTUAL_REGISTER
1607169702Skan	      || REGNO (addr) > LAST_VIRTUAL_REGISTER)))
1608169702Skan    return;
1609117404Skan
1610169702Skan  for_each_rtx (&XEXP (x, 0), instantiate_virtual_regs_in_rtx, NULL);
161118334Speter}
161218334Speter
1613169702Skan/* Helper for instantiate_decls called via walk_tree: Process all decls
1614169702Skan   in the given DECL_VALUE_EXPR.  */
161518334Speter
1616169702Skanstatic tree
1617169702Skaninstantiate_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
161818334Speter{
1619169702Skan  tree t = *tp;
1620169702Skan  if (! EXPR_P (t))
162118334Speter    {
1622169702Skan      *walk_subtrees = 0;
1623169702Skan      if (DECL_P (t) && DECL_RTL_SET_P (t))
1624169702Skan	instantiate_decl (DECL_RTL (t));
162518334Speter    }
1626169702Skan  return NULL;
162718334Speter}
162818334Speter
1629169702Skan/* Subroutine of instantiate_decls: Process all decls in the given
1630169702Skan   BLOCK node and all its subblocks.  */
1631169702Skan
1632169702Skanstatic void
1633169702Skaninstantiate_decls_1 (tree let)
163418334Speter{
1635169702Skan  tree t;
163618334Speter
1637169702Skan  for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
163818334Speter    {
1639169702Skan      if (DECL_RTL_SET_P (t))
1640169702Skan	instantiate_decl (DECL_RTL (t));
1641169702Skan      if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
164218334Speter	{
1643169702Skan	  tree v = DECL_VALUE_EXPR (t);
1644169702Skan	  walk_tree (&v, instantiate_expr, NULL, NULL);
164518334Speter	}
164618334Speter    }
164718334Speter
1648169702Skan  /* Process all subblocks.  */
1649169702Skan  for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
1650169702Skan    instantiate_decls_1 (t);
165118334Speter}
165218334Speter
1653169702Skan/* Scan all decls in FNDECL (both variables and parameters) and instantiate
1654169702Skan   all virtual registers in their DECL_RTL's.  */
165518334Speter
165618334Speterstatic void
1657169702Skaninstantiate_decls (tree fndecl)
165818334Speter{
1659169702Skan  tree decl;
166018334Speter
1661169702Skan  /* Process all parameters of the function.  */
1662169702Skan  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
166318334Speter    {
1664169702Skan      instantiate_decl (DECL_RTL (decl));
1665169702Skan      instantiate_decl (DECL_INCOMING_RTL (decl));
1666169702Skan      if (DECL_HAS_VALUE_EXPR_P (decl))
166718334Speter	{
1668169702Skan	  tree v = DECL_VALUE_EXPR (decl);
1669169702Skan	  walk_tree (&v, instantiate_expr, NULL, NULL);
1670169702Skan	}
1671169702Skan    }
167218334Speter
1673169702Skan  /* Now process all variables defined in the function or its subblocks.  */
1674169702Skan  instantiate_decls_1 (DECL_INITIAL (fndecl));
1675169702Skan}
167618334Speter
1677169702Skan/* Pass through the INSNS of function FNDECL and convert virtual register
1678169702Skan   references to hard register references.  */
167918334Speter
1680169702Skanstatic unsigned int
1681169702Skaninstantiate_virtual_regs (void)
1682169702Skan{
1683169702Skan  rtx insn;
168418334Speter
1685169702Skan  /* Compute the offsets to use for this function.  */
1686169702Skan  in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
1687169702Skan  var_offset = STARTING_FRAME_OFFSET;
1688169702Skan  dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
1689169702Skan  out_arg_offset = STACK_POINTER_OFFSET;
1690169702Skan#ifdef FRAME_POINTER_CFA_OFFSET
1691169702Skan  cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
1692169702Skan#else
1693169702Skan  cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
1694169702Skan#endif
169518334Speter
1696169702Skan  /* Initialize recognition, indicating that volatile is OK.  */
1697169702Skan  init_recog ();
169818334Speter
1699169702Skan  /* Scan through all the insns, instantiating every virtual register still
1700169702Skan     present.  */
1701169702Skan  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1702169702Skan    if (INSN_P (insn))
1703169702Skan      {
1704169702Skan	/* These patterns in the instruction stream can never be recognized.
1705169702Skan	   Fortunately, they shouldn't contain virtual registers either.  */
1706169702Skan	if (GET_CODE (PATTERN (insn)) == USE
1707169702Skan	    || GET_CODE (PATTERN (insn)) == CLOBBER
1708169702Skan	    || GET_CODE (PATTERN (insn)) == ADDR_VEC
1709169702Skan	    || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
1710169702Skan	    || GET_CODE (PATTERN (insn)) == ASM_INPUT)
1711169702Skan	  continue;
171218334Speter
1713169702Skan	instantiate_virtual_regs_in_insn (insn);
171418334Speter
1715169702Skan	if (INSN_DELETED_P (insn))
1716169702Skan	  continue;
171718334Speter
1718169702Skan	for_each_rtx (&REG_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL);
171918334Speter
1720169702Skan	/* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
1721169702Skan	if (GET_CODE (insn) == CALL_INSN)
1722169702Skan	  for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn),
1723169702Skan			instantiate_virtual_regs_in_rtx, NULL);
1724169702Skan      }
172518334Speter
1726169702Skan  /* Instantiate the virtual registers in the DECLs for debugging purposes.  */
1727169702Skan  instantiate_decls (current_function_decl);
172818334Speter
1729169702Skan  /* Indicate that, from now on, assign_stack_local should use
1730169702Skan     frame_pointer_rtx.  */
1731169702Skan  virtuals_instantiated = 1;
1732169702Skan  return 0;
1733169702Skan}
173418334Speter
1735169702Skanstruct tree_opt_pass pass_instantiate_virtual_regs =
1736169702Skan{
1737169702Skan  "vregs",                              /* name */
1738169702Skan  NULL,                                 /* gate */
1739169702Skan  instantiate_virtual_regs,             /* execute */
1740169702Skan  NULL,                                 /* sub */
1741169702Skan  NULL,                                 /* next */
1742169702Skan  0,                                    /* static_pass_number */
1743169702Skan  0,                                    /* tv_id */
1744169702Skan  0,                                    /* properties_required */
1745169702Skan  0,                                    /* properties_provided */
1746169702Skan  0,                                    /* properties_destroyed */
1747169702Skan  0,                                    /* todo_flags_start */
1748169702Skan  TODO_dump_func,                       /* todo_flags_finish */
1749169702Skan  0                                     /* letter */
1750169702Skan};
175118334Speter
175218334Speter
1753169702Skan/* Return 1 if EXP is an aggregate type (or a value with aggregate type).
1754169702Skan   This means a type for which function calls must pass an address to the
1755169702Skan   function or get an address back from the function.
1756169702Skan   EXP may be a type node or an expression (whose type is tested).  */
175718334Speter
1758169702Skanint
1759169702Skanaggregate_value_p (tree exp, tree fntype)
1760169702Skan{
1761169702Skan  int i, regno, nregs;
1762169702Skan  rtx reg;
176318334Speter
1764169702Skan  tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
176518334Speter
1766169702Skan  /* DECL node associated with FNTYPE when relevant, which we might need to
1767169702Skan     check for by-invisible-reference returns, typically for CALL_EXPR input
1768169702Skan     EXPressions.  */
1769169702Skan  tree fndecl = NULL_TREE;
1770169702Skan
1771169702Skan  if (fntype)
1772169702Skan    switch (TREE_CODE (fntype))
1773169702Skan      {
1774169702Skan      case CALL_EXPR:
1775169702Skan	fndecl = get_callee_fndecl (fntype);
1776169702Skan	fntype = fndecl ? TREE_TYPE (fndecl) : 0;
1777169702Skan	break;
1778169702Skan      case FUNCTION_DECL:
1779169702Skan	fndecl = fntype;
1780169702Skan	fntype = TREE_TYPE (fndecl);
1781169702Skan	break;
1782169702Skan      case FUNCTION_TYPE:
1783169702Skan      case METHOD_TYPE:
1784169702Skan        break;
1785169702Skan      case IDENTIFIER_NODE:
1786169702Skan	fntype = 0;
1787169702Skan	break;
1788169702Skan      default:
1789169702Skan	/* We don't expect other rtl types here.  */
1790169702Skan	gcc_unreachable ();
1791169702Skan      }
179218334Speter
1793169702Skan  if (TREE_CODE (type) == VOID_TYPE)
1794169702Skan    return 0;
179518334Speter
1796169702Skan  /* If the front end has decided that this needs to be passed by
1797169702Skan     reference, do so.  */
1798169702Skan  if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
1799169702Skan      && DECL_BY_REFERENCE (exp))
1800169702Skan    return 1;
180118334Speter
1802169702Skan  /* If the EXPression is a CALL_EXPR, honor DECL_BY_REFERENCE set on the
1803169702Skan     called function RESULT_DECL, meaning the function returns in memory by
1804169702Skan     invisible reference.  This check lets front-ends not set TREE_ADDRESSABLE
1805169702Skan     on the function type, which used to be the way to request such a return
1806169702Skan     mechanism but might now be causing troubles at gimplification time if
1807169702Skan     temporaries with the function type need to be created.  */
1808169702Skan  if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl)
1809169702Skan      && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
1810169702Skan    return 1;
1811169702Skan
1812169702Skan  if (targetm.calls.return_in_memory (type, fntype))
1813169702Skan    return 1;
1814169702Skan  /* Types that are TREE_ADDRESSABLE must be constructed in memory,
1815169702Skan     and thus can't be returned in registers.  */
1816169702Skan  if (TREE_ADDRESSABLE (type))
1817169702Skan    return 1;
1818169702Skan  if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
1819169702Skan    return 1;
1820169702Skan  /* Make sure we have suitable call-clobbered regs to return
1821169702Skan     the value in; if not, we must return it in memory.  */
1822169702Skan  reg = hard_function_value (type, 0, fntype, 0);
182318334Speter
1824169702Skan  /* If we have something other than a REG (e.g. a PARALLEL), then assume
1825169702Skan     it is OK.  */
1826169702Skan  if (!REG_P (reg))
1827169702Skan    return 0;
182818334Speter
1829169702Skan  regno = REGNO (reg);
1830169702Skan  nregs = hard_regno_nregs[regno][TYPE_MODE (type)];
1831169702Skan  for (i = 0; i < nregs; i++)
1832169702Skan    if (! call_used_regs[regno + i])
1833169702Skan      return 1;
1834169702Skan  return 0;
1835169702Skan}
1836169702Skan
1837169702Skan/* Return true if we should assign DECL a pseudo register; false if it
1838169702Skan   should live on the local stack.  */
183918334Speter
1840169702Skanbool
1841169702Skanuse_register_for_decl (tree decl)
184252268Sobrien{
1843169702Skan  /* Honor volatile.  */
1844169702Skan  if (TREE_SIDE_EFFECTS (decl))
1845169702Skan    return false;
184690091Sobrien
1847169702Skan  /* Honor addressability.  */
1848169702Skan  if (TREE_ADDRESSABLE (decl))
1849169702Skan    return false;
185090091Sobrien
1851169702Skan  /* Only register-like things go in registers.  */
1852169702Skan  if (DECL_MODE (decl) == BLKmode)
1853169702Skan    return false;
185452268Sobrien
1855169702Skan  /* If -ffloat-store specified, don't put explicit float variables
1856169702Skan     into registers.  */
1857169702Skan  /* ??? This should be checked after DECL_ARTIFICIAL, but tree-ssa
1858169702Skan     propagates values across these stores, and it probably shouldn't.  */
1859169702Skan  if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (decl)))
1860169702Skan    return false;
186152268Sobrien
1862169702Skan  /* If we're not interested in tracking debugging information for
1863169702Skan     this decl, then we can certainly put it in a register.  */
1864169702Skan  if (DECL_IGNORED_P (decl))
1865169702Skan    return true;
186652268Sobrien
1867169702Skan  return (optimize || DECL_REGISTER (decl));
1868169702Skan}
186990091Sobrien
1870169702Skan/* Return true if TYPE should be passed by invisible reference.  */
187190091Sobrien
1872169702Skanbool
1873169702Skanpass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode,
1874169702Skan		   tree type, bool named_arg)
1875169702Skan{
1876169702Skan  if (type)
1877132732Skan    {
1878169702Skan      /* If this type contains non-trivial constructors, then it is
1879169702Skan	 forbidden for the middle-end to create any new copies.  */
1880169702Skan      if (TREE_ADDRESSABLE (type))
1881169702Skan	return true;
188290091Sobrien
1883169702Skan      /* GCC post 3.4 passes *all* variable sized types by reference.  */
1884169702Skan      if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1885169702Skan	return true;
1886132732Skan    }
1887132732Skan
1888169702Skan  return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
188952268Sobrien}
189052268Sobrien
1891169702Skan/* Return true if TYPE, which is passed by reference, should be callee
1892169702Skan   copied instead of caller copied.  */
189352268Sobrien
1894169702Skanbool
1895169702Skanreference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode,
1896169702Skan			 tree type, bool named_arg)
189752268Sobrien{
1898169702Skan  if (type && TREE_ADDRESSABLE (type))
1899169702Skan    return false;
1900169702Skan  return targetm.calls.callee_copies (ca, mode, type, named_arg);
190152268Sobrien}
190252268Sobrien
1903169702Skan/* Structures to communicate between the subroutines of assign_parms.
1904169702Skan   The first holds data persistent across all parameters, the second
1905169702Skan   is cleared out for each parameter.  */
190652268Sobrien
1907169702Skanstruct assign_parm_data_all
1908169702Skan{
1909169702Skan  CUMULATIVE_ARGS args_so_far;
1910169702Skan  struct args_size stack_args_size;
1911169702Skan  tree function_result_decl;
1912169702Skan  tree orig_fnargs;
1913169702Skan  rtx conversion_insns;
1914169702Skan  HOST_WIDE_INT pretend_args_size;
1915169702Skan  HOST_WIDE_INT extra_pretend_bytes;
1916169702Skan  int reg_parm_stack_space;
1917169702Skan};
1918169702Skan
1919169702Skanstruct assign_parm_data_one
1920169702Skan{
1921169702Skan  tree nominal_type;
1922169702Skan  tree passed_type;
1923169702Skan  rtx entry_parm;
1924169702Skan  rtx stack_parm;
1925169702Skan  enum machine_mode nominal_mode;
1926169702Skan  enum machine_mode passed_mode;
1927169702Skan  enum machine_mode promoted_mode;
1928169702Skan  struct locate_and_pad_arg_data locate;
1929169702Skan  int partial;
1930169702Skan  BOOL_BITFIELD named_arg : 1;
1931169702Skan  BOOL_BITFIELD passed_pointer : 1;
1932169702Skan  BOOL_BITFIELD on_stack : 1;
1933169702Skan  BOOL_BITFIELD loaded_in_reg : 1;
1934169702Skan};
1935169702Skan
1936169702Skan/* A subroutine of assign_parms.  Initialize ALL.  */
1937169702Skan
193852268Sobrienstatic void
1939169702Skanassign_parms_initialize_all (struct assign_parm_data_all *all)
194052268Sobrien{
1941169702Skan  tree fntype;
194290091Sobrien
1943169702Skan  memset (all, 0, sizeof (*all));
194452268Sobrien
1945169702Skan  fntype = TREE_TYPE (current_function_decl);
194652268Sobrien
1947169702Skan#ifdef INIT_CUMULATIVE_INCOMING_ARGS
1948169702Skan  INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far, fntype, NULL_RTX);
1949169702Skan#else
1950169702Skan  INIT_CUMULATIVE_ARGS (all->args_so_far, fntype, NULL_RTX,
1951169702Skan			current_function_decl, -1);
1952169702Skan#endif
195390091Sobrien
1954169702Skan#ifdef REG_PARM_STACK_SPACE
1955169702Skan  all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl);
1956169702Skan#endif
195752268Sobrien}
195852268Sobrien
1959169702Skan/* If ARGS contains entries with complex types, split the entry into two
1960169702Skan   entries of the component type.  Return a new list of substitutions are
1961169702Skan   needed, else the old list.  */
196252518Sobrien
1963169702Skanstatic tree
1964169702Skansplit_complex_args (tree args)
196552268Sobrien{
1966169702Skan  tree p;
196752268Sobrien
1968169702Skan  /* Before allocating memory, check for the common case of no complex.  */
1969169702Skan  for (p = args; p; p = TREE_CHAIN (p))
197052268Sobrien    {
1971169702Skan      tree type = TREE_TYPE (p);
1972169702Skan      if (TREE_CODE (type) == COMPLEX_TYPE
1973169702Skan	  && targetm.calls.split_complex_arg (type))
1974169702Skan        goto found;
197590091Sobrien    }
1976169702Skan  return args;
197790091Sobrien
1978169702Skan found:
1979169702Skan  args = copy_list (args);
1980117404Skan
1981169702Skan  for (p = args; p; p = TREE_CHAIN (p))
198252268Sobrien    {
1983169702Skan      tree type = TREE_TYPE (p);
1984169702Skan      if (TREE_CODE (type) == COMPLEX_TYPE
1985169702Skan	  && targetm.calls.split_complex_arg (type))
198652268Sobrien	{
1987169702Skan	  tree decl;
1988169702Skan	  tree subtype = TREE_TYPE (type);
1989169702Skan	  bool addressable = TREE_ADDRESSABLE (p);
199052518Sobrien
1991169702Skan	  /* Rewrite the PARM_DECL's type with its component.  */
1992169702Skan	  TREE_TYPE (p) = subtype;
1993169702Skan	  DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
1994169702Skan	  DECL_MODE (p) = VOIDmode;
1995169702Skan	  DECL_SIZE (p) = NULL;
1996169702Skan	  DECL_SIZE_UNIT (p) = NULL;
1997169702Skan	  /* If this arg must go in memory, put it in a pseudo here.
1998169702Skan	     We can't allow it to go in memory as per normal parms,
1999169702Skan	     because the usual place might not have the imag part
2000169702Skan	     adjacent to the real part.  */
2001169702Skan	  DECL_ARTIFICIAL (p) = addressable;
2002169702Skan	  DECL_IGNORED_P (p) = addressable;
2003169702Skan	  TREE_ADDRESSABLE (p) = 0;
2004169702Skan	  layout_decl (p, 0);
2005132732Skan
2006169702Skan	  /* Build a second synthetic decl.  */
2007169702Skan	  decl = build_decl (PARM_DECL, NULL_TREE, subtype);
2008169702Skan	  DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
2009169702Skan	  DECL_ARTIFICIAL (decl) = addressable;
2010169702Skan	  DECL_IGNORED_P (decl) = addressable;
2011169702Skan	  layout_decl (decl, 0);
201252518Sobrien
2013169702Skan	  /* Splice it in; skip the new decl.  */
2014169702Skan	  TREE_CHAIN (decl) = TREE_CHAIN (p);
2015169702Skan	  TREE_CHAIN (p) = decl;
2016169702Skan	  p = decl;
2017169702Skan	}
2018169702Skan    }
201952518Sobrien
2020169702Skan  return args;
2021169702Skan}
202252518Sobrien
2023169702Skan/* A subroutine of assign_parms.  Adjust the parameter list to incorporate
2024169702Skan   the hidden struct return argument, and (abi willing) complex args.
2025169702Skan   Return the new parameter list.  */
202652518Sobrien
2027169702Skanstatic tree
2028169702Skanassign_parms_augmented_arg_list (struct assign_parm_data_all *all)
2029169702Skan{
2030169702Skan  tree fndecl = current_function_decl;
2031169702Skan  tree fntype = TREE_TYPE (fndecl);
2032169702Skan  tree fnargs = DECL_ARGUMENTS (fndecl);
203352518Sobrien
2034169702Skan  /* If struct value address is treated as the first argument, make it so.  */
2035169702Skan  if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2036169702Skan      && ! current_function_returns_pcc_struct
2037169702Skan      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2038169702Skan    {
2039169702Skan      tree type = build_pointer_type (TREE_TYPE (fntype));
2040169702Skan      tree decl;
204190091Sobrien
2042169702Skan      decl = build_decl (PARM_DECL, NULL_TREE, type);
2043169702Skan      DECL_ARG_TYPE (decl) = type;
2044169702Skan      DECL_ARTIFICIAL (decl) = 1;
2045169702Skan      DECL_IGNORED_P (decl) = 1;
204652518Sobrien
2047169702Skan      TREE_CHAIN (decl) = fnargs;
2048169702Skan      fnargs = decl;
2049169702Skan      all->function_result_decl = decl;
2050169702Skan    }
205152518Sobrien
2052169702Skan  all->orig_fnargs = fnargs;
2053132732Skan
2054169702Skan  /* If the target wants to split complex arguments into scalars, do so.  */
2055169702Skan  if (targetm.calls.split_complex_arg)
2056169702Skan    fnargs = split_complex_args (fnargs);
2057132732Skan
2058169702Skan  return fnargs;
2059169702Skan}
206052518Sobrien
2061169702Skan/* A subroutine of assign_parms.  Examine PARM and pull out type and mode
2062169702Skan   data for the parameter.  Incorporate ABI specifics such as pass-by-
2063169702Skan   reference and type promotion.  */
206452518Sobrien
2065169702Skanstatic void
2066169702Skanassign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
2067169702Skan			     struct assign_parm_data_one *data)
2068169702Skan{
2069169702Skan  tree nominal_type, passed_type;
2070169702Skan  enum machine_mode nominal_mode, passed_mode, promoted_mode;
2071117404Skan
2072169702Skan  memset (data, 0, sizeof (*data));
207352518Sobrien
2074169702Skan  /* NAMED_ARG is a mis-nomer.  We really mean 'non-varadic'. */
2075169702Skan  if (!current_function_stdarg)
2076169702Skan    data->named_arg = 1;  /* No varadic parms.  */
2077169702Skan  else if (TREE_CHAIN (parm))
2078169702Skan    data->named_arg = 1;  /* Not the last non-varadic parm. */
2079169702Skan  else if (targetm.calls.strict_argument_naming (&all->args_so_far))
2080169702Skan    data->named_arg = 1;  /* Only varadic ones are unnamed.  */
2081169702Skan  else
2082169702Skan    data->named_arg = 0;  /* Treat as varadic.  */
208352518Sobrien
2084169702Skan  nominal_type = TREE_TYPE (parm);
2085169702Skan  passed_type = DECL_ARG_TYPE (parm);
208652518Sobrien
2087169702Skan  /* Look out for errors propagating this far.  Also, if the parameter's
2088169702Skan     type is void then its value doesn't matter.  */
2089169702Skan  if (TREE_TYPE (parm) == error_mark_node
2090169702Skan      /* This can happen after weird syntax errors
2091169702Skan	 or if an enum type is defined among the parms.  */
2092169702Skan      || TREE_CODE (parm) != PARM_DECL
2093169702Skan      || passed_type == NULL
2094169702Skan      || VOID_TYPE_P (nominal_type))
2095169702Skan    {
2096169702Skan      nominal_type = passed_type = void_type_node;
2097169702Skan      nominal_mode = passed_mode = promoted_mode = VOIDmode;
2098169702Skan      goto egress;
2099169702Skan    }
210090091Sobrien
2101169702Skan  /* Find mode of arg as it is passed, and mode of arg as it should be
2102169702Skan     during execution of this function.  */
2103169702Skan  passed_mode = TYPE_MODE (passed_type);
2104169702Skan  nominal_mode = TYPE_MODE (nominal_type);
210552518Sobrien
2106169702Skan  /* If the parm is to be passed as a transparent union, use the type of
2107169702Skan     the first field for the tests below.  We have already verified that
2108169702Skan     the modes are the same.  */
2109169702Skan  if (TREE_CODE (passed_type) == UNION_TYPE
2110169702Skan      && TYPE_TRANSPARENT_UNION (passed_type))
2111169702Skan    passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
211252518Sobrien
2113169702Skan  /* See if this arg was passed by invisible reference.  */
2114169702Skan  if (pass_by_reference (&all->args_so_far, passed_mode,
2115169702Skan			 passed_type, data->named_arg))
2116169702Skan    {
2117169702Skan      passed_type = nominal_type = build_pointer_type (passed_type);
2118169702Skan      data->passed_pointer = true;
2119169702Skan      passed_mode = nominal_mode = Pmode;
212052268Sobrien    }
212152268Sobrien
2122169702Skan  /* Find mode as it is passed by the ABI.  */
2123169702Skan  promoted_mode = passed_mode;
2124169702Skan  if (targetm.calls.promote_function_args (TREE_TYPE (current_function_decl)))
212552268Sobrien    {
2126169702Skan      int unsignedp = TYPE_UNSIGNED (passed_type);
2127169702Skan      promoted_mode = promote_mode (passed_type, promoted_mode,
2128169702Skan				    &unsignedp, 1);
212952268Sobrien    }
213090091Sobrien
2131169702Skan egress:
2132169702Skan  data->nominal_type = nominal_type;
2133169702Skan  data->passed_type = passed_type;
2134169702Skan  data->nominal_mode = nominal_mode;
2135169702Skan  data->passed_mode = passed_mode;
2136169702Skan  data->promoted_mode = promoted_mode;
213752268Sobrien}
213852268Sobrien
2139169702Skan/* A subroutine of assign_parms.  Invoke setup_incoming_varargs.  */
214052518Sobrien
2141169702Skanstatic void
2142169702Skanassign_parms_setup_varargs (struct assign_parm_data_all *all,
2143169702Skan			    struct assign_parm_data_one *data, bool no_rtl)
214452518Sobrien{
2145169702Skan  int varargs_pretend_bytes = 0;
214652518Sobrien
2147169702Skan  targetm.calls.setup_incoming_varargs (&all->args_so_far,
2148169702Skan					data->promoted_mode,
2149169702Skan					data->passed_type,
2150169702Skan					&varargs_pretend_bytes, no_rtl);
215152518Sobrien
2152169702Skan  /* If the back-end has requested extra stack space, record how much is
2153169702Skan     needed.  Do not change pretend_args_size otherwise since it may be
2154169702Skan     nonzero from an earlier partial argument.  */
2155169702Skan  if (varargs_pretend_bytes > 0)
2156169702Skan    all->pretend_args_size = varargs_pretend_bytes;
215752518Sobrien}
215852518Sobrien
2159169702Skan/* A subroutine of assign_parms.  Set DATA->ENTRY_PARM corresponding to
2160169702Skan   the incoming location of the current parameter.  */
2161169702Skan
2162169702Skanstatic void
2163169702Skanassign_parm_find_entry_rtl (struct assign_parm_data_all *all,
2164169702Skan			    struct assign_parm_data_one *data)
216590091Sobrien{
2166169702Skan  HOST_WIDE_INT pretend_bytes = 0;
2167169702Skan  rtx entry_parm;
2168169702Skan  bool in_regs;
216952518Sobrien
2170169702Skan  if (data->promoted_mode == VOIDmode)
2171169702Skan    {
2172169702Skan      data->entry_parm = data->stack_parm = const0_rtx;
2173169702Skan      return;
2174169702Skan    }
217552518Sobrien
2176169702Skan#ifdef FUNCTION_INCOMING_ARG
2177169702Skan  entry_parm = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode,
2178169702Skan				      data->passed_type, data->named_arg);
2179169702Skan#else
2180169702Skan  entry_parm = FUNCTION_ARG (all->args_so_far, data->promoted_mode,
2181169702Skan			     data->passed_type, data->named_arg);
2182169702Skan#endif
218352518Sobrien
2184169702Skan  if (entry_parm == 0)
2185169702Skan    data->promoted_mode = data->passed_mode;
218652518Sobrien
2187169702Skan  /* Determine parm's home in the stack, in case it arrives in the stack
2188169702Skan     or we should pretend it did.  Compute the stack position and rtx where
2189169702Skan     the argument arrives and its size.
219052518Sobrien
2191169702Skan     There is one complexity here:  If this was a parameter that would
2192169702Skan     have been passed in registers, but wasn't only because it is
2193169702Skan     __builtin_va_alist, we want locate_and_pad_parm to treat it as if
2194169702Skan     it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
2195169702Skan     In this case, we call FUNCTION_ARG with NAMED set to 1 instead of 0
2196169702Skan     as it was the previous time.  */
2197169702Skan  in_regs = entry_parm != 0;
2198169702Skan#ifdef STACK_PARMS_IN_REG_PARM_AREA
2199169702Skan  in_regs = true;
2200169702Skan#endif
2201169702Skan  if (!in_regs && !data->named_arg)
2202117404Skan    {
2203169702Skan      if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far))
2204117404Skan	{
2205169702Skan	  rtx tem;
2206169702Skan#ifdef FUNCTION_INCOMING_ARG
2207169702Skan	  tem = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode,
2208169702Skan				       data->passed_type, true);
2209169702Skan#else
2210169702Skan	  tem = FUNCTION_ARG (all->args_so_far, data->promoted_mode,
2211169702Skan			      data->passed_type, true);
2212169702Skan#endif
2213169702Skan	  in_regs = tem != NULL;
2214117404Skan	}
2215117404Skan    }
221652518Sobrien
2217169702Skan  /* If this parameter was passed both in registers and in the stack, use
2218169702Skan     the copy on the stack.  */
2219169702Skan  if (targetm.calls.must_pass_in_stack (data->promoted_mode,
2220169702Skan					data->passed_type))
2221169702Skan    entry_parm = 0;
222252518Sobrien
2223169702Skan  if (entry_parm)
2224169702Skan    {
2225169702Skan      int partial;
222652518Sobrien
2227169702Skan      partial = targetm.calls.arg_partial_bytes (&all->args_so_far,
2228169702Skan						 data->promoted_mode,
2229169702Skan						 data->passed_type,
2230169702Skan						 data->named_arg);
2231169702Skan      data->partial = partial;
223252518Sobrien
2233169702Skan      /* The caller might already have allocated stack space for the
2234169702Skan	 register parameters.  */
2235169702Skan      if (partial != 0 && all->reg_parm_stack_space == 0)
223652518Sobrien	{
2237169702Skan	  /* Part of this argument is passed in registers and part
2238169702Skan	     is passed on the stack.  Ask the prologue code to extend
2239169702Skan	     the stack part so that we can recreate the full value.
224052518Sobrien
2241169702Skan	     PRETEND_BYTES is the size of the registers we need to store.
2242169702Skan	     CURRENT_FUNCTION_PRETEND_ARGS_SIZE is the amount of extra
2243169702Skan	     stack space that the prologue should allocate.
224490091Sobrien
2245169702Skan	     Internally, gcc assumes that the argument pointer is aligned
2246169702Skan	     to STACK_BOUNDARY bits.  This is used both for alignment
2247169702Skan	     optimizations (see init_emit) and to locate arguments that are
2248169702Skan	     aligned to more than PARM_BOUNDARY bits.  We must preserve this
2249169702Skan	     invariant by rounding CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to
2250169702Skan	     a stack boundary.  */
225190091Sobrien
2252169702Skan	  /* We assume at most one partial arg, and it must be the first
2253169702Skan	     argument on the stack.  */
2254169702Skan	  gcc_assert (!all->extra_pretend_bytes && !all->pretend_args_size);
225552268Sobrien
2256169702Skan	  pretend_bytes = partial;
2257169702Skan	  all->pretend_args_size = CEIL_ROUND (pretend_bytes, STACK_BYTES);
225890091Sobrien
2259169702Skan	  /* We want to align relative to the actual stack pointer, so
2260169702Skan	     don't include this in the stack size until later.  */
2261169702Skan	  all->extra_pretend_bytes = all->pretend_args_size;
2262169702Skan	}
2263169702Skan    }
226452518Sobrien
2265169702Skan  locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs,
2266169702Skan		       entry_parm ? data->partial : 0, current_function_decl,
2267169702Skan		       &all->stack_args_size, &data->locate);
2268132732Skan
2269169702Skan  /* Adjust offsets to include the pretend args.  */
2270169702Skan  pretend_bytes = all->extra_pretend_bytes - pretend_bytes;
2271169702Skan  data->locate.slot_offset.constant += pretend_bytes;
2272169702Skan  data->locate.offset.constant += pretend_bytes;
227390091Sobrien
2274169702Skan  data->entry_parm = entry_parm;
2275169702Skan}
227690091Sobrien
2277169702Skan/* A subroutine of assign_parms.  If there is actually space on the stack
2278169702Skan   for this parm, count it in stack_args_size and return true.  */
227952518Sobrien
2280169702Skanstatic bool
2281169702Skanassign_parm_is_stack_parm (struct assign_parm_data_all *all,
2282169702Skan			   struct assign_parm_data_one *data)
2283169702Skan{
2284169702Skan  /* Trivially true if we've no incoming register.  */
2285169702Skan  if (data->entry_parm == NULL)
2286169702Skan    ;
2287169702Skan  /* Also true if we're partially in registers and partially not,
2288169702Skan     since we've arranged to drop the entire argument on the stack.  */
2289169702Skan  else if (data->partial != 0)
2290169702Skan    ;
2291169702Skan  /* Also true if the target says that it's passed in both registers
2292169702Skan     and on the stack.  */
2293169702Skan  else if (GET_CODE (data->entry_parm) == PARALLEL
2294169702Skan	   && XEXP (XVECEXP (data->entry_parm, 0, 0), 0) == NULL_RTX)
2295169702Skan    ;
2296169702Skan  /* Also true if the target says that there's stack allocated for
2297169702Skan     all register parameters.  */
2298169702Skan  else if (all->reg_parm_stack_space > 0)
2299169702Skan    ;
2300169702Skan  /* Otherwise, no, this parameter has no ABI defined stack slot.  */
2301169702Skan  else
2302169702Skan    return false;
2303132732Skan
2304169702Skan  all->stack_args_size.constant += data->locate.size.constant;
2305169702Skan  if (data->locate.size.var)
2306169702Skan    ADD_PARM_SIZE (all->stack_args_size, data->locate.size.var);
2307132732Skan
2308169702Skan  return true;
2309169702Skan}
231072564Sobrien
2311169702Skan/* A subroutine of assign_parms.  Given that this parameter is allocated
2312169702Skan   stack space by the ABI, find it.  */
231372564Sobrien
2314169702Skanstatic void
2315169702Skanassign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
2316169702Skan{
2317169702Skan  rtx offset_rtx, stack_parm;
2318169702Skan  unsigned int align, boundary;
231972564Sobrien
2320169702Skan  /* If we're passing this arg using a reg, make its stack home the
2321169702Skan     aligned stack slot.  */
2322169702Skan  if (data->entry_parm)
2323169702Skan    offset_rtx = ARGS_SIZE_RTX (data->locate.slot_offset);
2324169702Skan  else
2325169702Skan    offset_rtx = ARGS_SIZE_RTX (data->locate.offset);
232672564Sobrien
2327169702Skan  stack_parm = current_function_internal_arg_pointer;
2328169702Skan  if (offset_rtx != const0_rtx)
2329169702Skan    stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx);
2330169702Skan  stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm);
233190091Sobrien
2332169702Skan  set_mem_attributes (stack_parm, parm, 1);
233390091Sobrien
2334169702Skan  boundary = data->locate.boundary;
2335169702Skan  align = BITS_PER_UNIT;
2336169702Skan
2337169702Skan  /* If we're padding upward, we know that the alignment of the slot
2338169702Skan     is FUNCTION_ARG_BOUNDARY.  If we're using slot_offset, we're
2339169702Skan     intentionally forcing upward padding.  Otherwise we have to come
2340169702Skan     up with a guess at the alignment based on OFFSET_RTX.  */
2341169702Skan  if (data->locate.where_pad != downward || data->entry_parm)
2342169702Skan    align = boundary;
2343169702Skan  else if (GET_CODE (offset_rtx) == CONST_INT)
234490091Sobrien    {
2345169702Skan      align = INTVAL (offset_rtx) * BITS_PER_UNIT | boundary;
2346169702Skan      align = align & -align;
234790091Sobrien    }
2348169702Skan  set_mem_align (stack_parm, align);
234990091Sobrien
2350169702Skan  if (data->entry_parm)
2351169702Skan    set_reg_attrs_for_parm (data->entry_parm, stack_parm);
2352117404Skan
2353169702Skan  data->stack_parm = stack_parm;
235490091Sobrien}
235590091Sobrien
2356169702Skan/* A subroutine of assign_parms.  Adjust DATA->ENTRY_RTL such that it's
2357169702Skan   always valid and contiguous.  */
235890091Sobrien
2359169702Skanstatic void
2360169702Skanassign_parm_adjust_entry_rtl (struct assign_parm_data_one *data)
2361169702Skan{
2362169702Skan  rtx entry_parm = data->entry_parm;
2363169702Skan  rtx stack_parm = data->stack_parm;
236490091Sobrien
2365169702Skan  /* If this parm was passed part in regs and part in memory, pretend it
2366169702Skan     arrived entirely in memory by pushing the register-part onto the stack.
2367169702Skan     In the special case of a DImode or DFmode that is split, we could put
2368169702Skan     it together in a pseudoreg directly, but for now that's not worth
2369169702Skan     bothering with.  */
2370169702Skan  if (data->partial != 0)
237190091Sobrien    {
2372169702Skan      /* Handle calls that pass values in multiple non-contiguous
2373169702Skan	 locations.  The Irix 6 ABI has examples of this.  */
2374169702Skan      if (GET_CODE (entry_parm) == PARALLEL)
2375169702Skan	emit_group_store (validize_mem (stack_parm), entry_parm,
2376169702Skan			  data->passed_type,
2377169702Skan			  int_size_in_bytes (data->passed_type));
2378169702Skan      else
237990091Sobrien	{
2380169702Skan	  gcc_assert (data->partial % UNITS_PER_WORD == 0);
2381169702Skan	  move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
2382169702Skan			       data->partial / UNITS_PER_WORD);
238390091Sobrien	}
2384169702Skan
2385169702Skan      entry_parm = stack_parm;
238690091Sobrien    }
238718334Speter
2388169702Skan  /* If we didn't decide this parm came in a register, by default it came
2389169702Skan     on the stack.  */
2390169702Skan  else if (entry_parm == NULL)
2391169702Skan    entry_parm = stack_parm;
239218334Speter
2393169702Skan  /* When an argument is passed in multiple locations, we can't make use
2394169702Skan     of this information, but we can save some copying if the whole argument
2395169702Skan     is passed in a single register.  */
2396169702Skan  else if (GET_CODE (entry_parm) == PARALLEL
2397169702Skan	   && data->nominal_mode != BLKmode
2398169702Skan	   && data->passed_mode != BLKmode)
2399169702Skan    {
2400169702Skan      size_t i, len = XVECLEN (entry_parm, 0);
240118334Speter
2402169702Skan      for (i = 0; i < len; i++)
2403169702Skan	if (XEXP (XVECEXP (entry_parm, 0, i), 0) != NULL_RTX
2404169702Skan	    && REG_P (XEXP (XVECEXP (entry_parm, 0, i), 0))
2405169702Skan	    && (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0))
2406169702Skan		== data->passed_mode)
2407169702Skan	    && INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0)
2408169702Skan	  {
2409169702Skan	    entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0);
2410169702Skan	    break;
2411169702Skan	  }
2412169702Skan    }
241318334Speter
2414169702Skan  data->entry_parm = entry_parm;
241518334Speter}
241618334Speter
2417169702Skan/* A subroutine of assign_parms.  Adjust DATA->STACK_RTL such that it's
2418169702Skan   always valid and properly aligned.  */
241918334Speter
242018334Speterstatic void
2421169702Skanassign_parm_adjust_stack_rtl (struct assign_parm_data_one *data)
242218334Speter{
2423169702Skan  rtx stack_parm = data->stack_parm;
242418334Speter
2425169702Skan  /* If we can't trust the parm stack slot to be aligned enough for its
2426169702Skan     ultimate type, don't use that slot after entry.  We'll make another
2427169702Skan     stack slot, if we need one.  */
2428169702Skan  if (stack_parm
2429169702Skan      && ((STRICT_ALIGNMENT
2430169702Skan	   && GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm))
2431169702Skan	  || (data->nominal_type
2432169702Skan	      && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
2433169702Skan	      && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY)))
2434169702Skan    stack_parm = NULL;
243552268Sobrien
2436169702Skan  /* If parm was passed in memory, and we need to convert it on entry,
2437169702Skan     don't store it back in that same slot.  */
2438169702Skan  else if (data->entry_parm == stack_parm
2439169702Skan	   && data->nominal_mode != BLKmode
2440169702Skan	   && data->nominal_mode != data->passed_mode)
2441169702Skan    stack_parm = NULL;
244252268Sobrien
2443169702Skan  /* If stack protection is in effect for this function, don't leave any
2444169702Skan     pointers in their passed stack slots.  */
2445169702Skan  else if (cfun->stack_protect_guard
2446169702Skan	   && (flag_stack_protect == 2
2447169702Skan	       || data->passed_pointer
2448169702Skan	       || POINTER_TYPE_P (data->nominal_type)))
2449169702Skan    stack_parm = NULL;
245018334Speter
2451169702Skan  data->stack_parm = stack_parm;
245218334Speter}
245318334Speter
2454169702Skan/* A subroutine of assign_parms.  Return true if the current parameter
2455169702Skan   should be stored as a BLKmode in the current frame.  */
245618334Speter
2457169702Skanstatic bool
2458169702Skanassign_parm_setup_block_p (struct assign_parm_data_one *data)
245918334Speter{
2460169702Skan  if (data->nominal_mode == BLKmode)
2461169702Skan    return true;
2462169702Skan  if (GET_CODE (data->entry_parm) == PARALLEL)
2463169702Skan    return true;
246418334Speter
2465169702Skan#ifdef BLOCK_REG_PADDING
2466169702Skan  /* Only assign_parm_setup_block knows how to deal with register arguments
2467169702Skan     that are padded at the least significant end.  */
2468169702Skan  if (REG_P (data->entry_parm)
2469169702Skan      && GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD
2470169702Skan      && (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
2471169702Skan	  == (BYTES_BIG_ENDIAN ? upward : downward)))
2472169702Skan    return true;
2473169702Skan#endif
247418334Speter
2475169702Skan  return false;
247618334Speter}
247718334Speter
2478169702Skan/* A subroutine of assign_parms.  Arrange for the parameter to be
2479169702Skan   present and valid in DATA->STACK_RTL.  */
248018334Speter
248118334Speterstatic void
2482169702Skanassign_parm_setup_block (struct assign_parm_data_all *all,
2483169702Skan			 tree parm, struct assign_parm_data_one *data)
248418334Speter{
2485169702Skan  rtx entry_parm = data->entry_parm;
2486169702Skan  rtx stack_parm = data->stack_parm;
2487169702Skan  HOST_WIDE_INT size;
2488169702Skan  HOST_WIDE_INT size_stored;
2489169702Skan  rtx orig_entry_parm = entry_parm;
249018334Speter
2491169702Skan  if (GET_CODE (entry_parm) == PARALLEL)
2492169702Skan    entry_parm = emit_group_move_into_temps (entry_parm);
2493146908Skan
2494169702Skan  /* If we've a non-block object that's nevertheless passed in parts,
2495169702Skan     reconstitute it in register operations rather than on the stack.  */
2496169702Skan  if (GET_CODE (entry_parm) == PARALLEL
2497169702Skan      && data->nominal_mode != BLKmode)
2498146908Skan    {
2499169702Skan      rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0);
2500146908Skan
2501169702Skan      if ((XVECLEN (entry_parm, 0) > 1
2502169702Skan	   || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1)
2503169702Skan	  && use_register_for_decl (parm))
2504169702Skan	{
2505169702Skan	  rtx parmreg = gen_reg_rtx (data->nominal_mode);
250618334Speter
2507169702Skan	  push_to_sequence (all->conversion_insns);
250818334Speter
2509169702Skan	  /* For values returned in multiple registers, handle possible
2510169702Skan	     incompatible calls to emit_group_store.
251118334Speter
2512169702Skan	     For example, the following would be invalid, and would have to
2513169702Skan	     be fixed by the conditional below:
251418334Speter
2515169702Skan	     emit_group_store ((reg:SF), (parallel:DF))
2516169702Skan	     emit_group_store ((reg:SI), (parallel:DI))
251718334Speter
2518169702Skan	     An example of this are doubles in e500 v2:
2519169702Skan	     (parallel:DF (expr_list (reg:SI) (const_int 0))
2520169702Skan	     (expr_list (reg:SI) (const_int 4))).  */
2521169702Skan	  if (data->nominal_mode != data->passed_mode)
2522169702Skan	    {
2523169702Skan	      rtx t = gen_reg_rtx (GET_MODE (entry_parm));
2524169702Skan	      emit_group_store (t, entry_parm, NULL_TREE,
2525169702Skan				GET_MODE_SIZE (GET_MODE (entry_parm)));
2526169702Skan	      convert_move (parmreg, t, 0);
2527169702Skan	    }
2528169702Skan	  else
2529169702Skan	    emit_group_store (parmreg, entry_parm, data->nominal_type,
2530169702Skan			      int_size_in_bytes (data->nominal_type));
253190091Sobrien
2532169702Skan	  all->conversion_insns = get_insns ();
2533169702Skan	  end_sequence ();
253418334Speter
2535169702Skan	  SET_DECL_RTL (parm, parmreg);
253652268Sobrien	  return;
2537169702Skan	}
253852268Sobrien    }
253918334Speter
2540169702Skan  size = int_size_in_bytes (data->passed_type);
2541169702Skan  size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
2542169702Skan  if (stack_parm == 0)
2543117404Skan    {
2544169702Skan      DECL_ALIGN (parm) = MAX (DECL_ALIGN (parm), BITS_PER_WORD);
2545169702Skan      stack_parm = assign_stack_local (BLKmode, size_stored,
2546169702Skan				       DECL_ALIGN (parm));
2547169702Skan      if (GET_MODE_SIZE (GET_MODE (entry_parm)) == size)
2548169702Skan	PUT_MODE (stack_parm, GET_MODE (entry_parm));
2549169702Skan      set_mem_attributes (stack_parm, parm, 1);
2550117404Skan    }
255118334Speter
2552169702Skan  /* If a BLKmode arrives in registers, copy it to a stack slot.  Handle
2553169702Skan     calls that pass values in multiple non-contiguous locations.  */
2554169702Skan  if (REG_P (entry_parm) || GET_CODE (entry_parm) == PARALLEL)
2555169702Skan    {
2556169702Skan      rtx mem;
255718334Speter
2558169702Skan      /* Note that we will be storing an integral number of words.
2559169702Skan	 So we have to be careful to ensure that we allocate an
2560169702Skan	 integral number of words.  We do this above when we call
2561169702Skan	 assign_stack_local if space was not allocated in the argument
2562169702Skan	 list.  If it was, this will not work if PARM_BOUNDARY is not
2563169702Skan	 a multiple of BITS_PER_WORD.  It isn't clear how to fix this
2564169702Skan	 if it becomes a problem.  Exception is when BLKmode arrives
2565169702Skan	 with arguments not conforming to word_mode.  */
256618334Speter
2567169702Skan      if (data->stack_parm == 0)
2568169702Skan	;
2569169702Skan      else if (GET_CODE (entry_parm) == PARALLEL)
2570169702Skan	;
2571169702Skan      else
2572169702Skan	gcc_assert (!size || !(PARM_BOUNDARY % BITS_PER_WORD));
257318334Speter
2574169702Skan      mem = validize_mem (stack_parm);
257518334Speter
2576169702Skan      /* Handle values in multiple non-contiguous locations.  */
2577169702Skan      if (GET_CODE (entry_parm) == PARALLEL)
257890091Sobrien	{
2579169702Skan	  push_to_sequence (all->conversion_insns);
2580169702Skan	  emit_group_store (mem, entry_parm, data->passed_type, size);
2581169702Skan	  all->conversion_insns = get_insns ();
258218334Speter	  end_sequence ();
258318334Speter	}
258418334Speter
2585169702Skan      else if (size == 0)
2586169702Skan	;
258718334Speter
2588169702Skan      /* If SIZE is that of a mode no bigger than a word, just use
2589169702Skan	 that mode's store operation.  */
2590169702Skan      else if (size <= UNITS_PER_WORD)
259118334Speter	{
2592169702Skan	  enum machine_mode mode
2593169702Skan	    = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
259418334Speter
2595169702Skan	  if (mode != BLKmode
2596169702Skan#ifdef BLOCK_REG_PADDING
2597169702Skan	      && (size == UNITS_PER_WORD
2598169702Skan		  || (BLOCK_REG_PADDING (mode, data->passed_type, 1)
2599169702Skan		      != (BYTES_BIG_ENDIAN ? upward : downward)))
260090091Sobrien#endif
2601169702Skan	      )
260218334Speter	    {
2603169702Skan	      rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
2604169702Skan	      emit_move_insn (change_address (mem, mode, 0), reg);
260518334Speter	    }
260618334Speter
2607169702Skan	  /* Blocks smaller than a word on a BYTES_BIG_ENDIAN
2608169702Skan	     machine must be aligned to the left before storing
2609169702Skan	     to memory.  Note that the previous test doesn't
2610169702Skan	     handle all cases (e.g. SIZE == 3).  */
2611169702Skan	  else if (size != UNITS_PER_WORD
2612169702Skan#ifdef BLOCK_REG_PADDING
2613169702Skan		   && (BLOCK_REG_PADDING (mode, data->passed_type, 1)
2614169702Skan		       == downward)
2615169702Skan#else
2616169702Skan		   && BYTES_BIG_ENDIAN
261718334Speter#endif
2618169702Skan		   )
261918334Speter	    {
2620169702Skan	      rtx tem, x;
2621169702Skan	      int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
2622169702Skan	      rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
262318334Speter
2624169702Skan	      x = expand_shift (LSHIFT_EXPR, word_mode, reg,
2625169702Skan				build_int_cst (NULL_TREE, by),
2626169702Skan				NULL_RTX, 1);
2627169702Skan	      tem = change_address (mem, word_mode, 0);
2628169702Skan	      emit_move_insn (tem, x);
262918334Speter	    }
2630169702Skan	  else
2631169702Skan	    move_block_from_reg (REGNO (entry_parm), mem,
2632169702Skan				 size_stored / UNITS_PER_WORD);
263318334Speter	}
2634169702Skan      else
2635169702Skan	move_block_from_reg (REGNO (entry_parm), mem,
2636169702Skan			     size_stored / UNITS_PER_WORD);
263718334Speter    }
2638169702Skan  else if (data->stack_parm == 0)
263918334Speter    {
2640169702Skan      push_to_sequence (all->conversion_insns);
2641169702Skan      emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
2642169702Skan		       BLOCK_OP_NORMAL);
2643169702Skan      all->conversion_insns = get_insns ();
2644169702Skan      end_sequence ();
264518334Speter    }
264618334Speter
2647169702Skan  data->stack_parm = stack_parm;
2648169702Skan  SET_DECL_RTL (parm, stack_parm);
264918334Speter}
265018334Speter
2651169702Skan/* A subroutine of assign_parms.  Allocate a pseudo to hold the current
2652169702Skan   parameter.  Get it there.  Perform all ABI specified conversions.  */
265318334Speter
2654169702Skanstatic void
2655169702Skanassign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
2656169702Skan		       struct assign_parm_data_one *data)
265718334Speter{
2658169702Skan  rtx parmreg;
2659169702Skan  enum machine_mode promoted_nominal_mode;
2660169702Skan  int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm));
2661169702Skan  bool did_conversion = false;
266218334Speter
2663169702Skan  /* Store the parm in a pseudoregister during the function, but we may
2664169702Skan     need to do it in a wider mode.  */
266590091Sobrien
2666169702Skan  /* This is not really promoting for a call.  However we need to be
2667169702Skan     consistent with assign_parm_find_data_types and expand_expr_real_1.  */
2668169702Skan  promoted_nominal_mode
2669169702Skan    = promote_mode (data->nominal_type, data->nominal_mode, &unsignedp, 1);
2670132732Skan
2671169702Skan  parmreg = gen_reg_rtx (promoted_nominal_mode);
267252268Sobrien
2673169702Skan  if (!DECL_ARTIFICIAL (parm))
2674169702Skan    mark_user_reg (parmreg);
267552268Sobrien
2676169702Skan  /* If this was an item that we received a pointer to,
2677169702Skan     set DECL_RTL appropriately.  */
2678169702Skan  if (data->passed_pointer)
2679169702Skan    {
2680169702Skan      rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg);
2681169702Skan      set_mem_attributes (x, parm, 1);
2682169702Skan      SET_DECL_RTL (parm, x);
2683169702Skan    }
268418334Speter  else
2685169702Skan    SET_DECL_RTL (parm, parmreg);
268618334Speter
2687169702Skan  /* Copy the value into the register.  */
2688169702Skan  if (data->nominal_mode != data->passed_mode
2689169702Skan      || promoted_nominal_mode != data->promoted_mode)
269018334Speter    {
2691169702Skan      int save_tree_used;
269218334Speter
2693169702Skan      /* ENTRY_PARM has been converted to PROMOTED_MODE, its
2694169702Skan	 mode, by the caller.  We now have to convert it to
2695169702Skan	 NOMINAL_MODE, if different.  However, PARMREG may be in
2696169702Skan	 a different mode than NOMINAL_MODE if it is being stored
2697169702Skan	 promoted.
269818334Speter
2699169702Skan	 If ENTRY_PARM is a hard register, it might be in a register
2700169702Skan	 not valid for operating in its mode (e.g., an odd-numbered
2701169702Skan	 register for a DFmode).  In that case, moves are the only
2702169702Skan	 thing valid, so we can't do a convert from there.  This
2703169702Skan	 occurs when the calling sequence allow such misaligned
2704169702Skan	 usages.
270590091Sobrien
2706169702Skan	 In addition, the conversion may involve a call, which could
2707169702Skan	 clobber parameters which haven't been copied to pseudo
2708169702Skan	 registers yet.  Therefore, we must first copy the parm to
2709169702Skan	 a pseudo reg here, and save the conversion until after all
2710169702Skan	 parameters have been moved.  */
2711132732Skan
2712169702Skan      rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
271318334Speter
2714169702Skan      emit_move_insn (tempreg, validize_mem (data->entry_parm));
2715132732Skan
2716169702Skan      push_to_sequence (all->conversion_insns);
2717169702Skan      tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp);
2718132732Skan
2719169702Skan      if (GET_CODE (tempreg) == SUBREG
2720169702Skan	  && GET_MODE (tempreg) == data->nominal_mode
2721169702Skan	  && REG_P (SUBREG_REG (tempreg))
2722169702Skan	  && data->nominal_mode == data->passed_mode
2723169702Skan	  && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (data->entry_parm)
2724169702Skan	  && GET_MODE_SIZE (GET_MODE (tempreg))
2725169702Skan	     < GET_MODE_SIZE (GET_MODE (data->entry_parm)))
272690091Sobrien	{
2727169702Skan	  /* The argument is already sign/zero extended, so note it
2728169702Skan	     into the subreg.  */
2729169702Skan	  SUBREG_PROMOTED_VAR_P (tempreg) = 1;
2730169702Skan	  SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp);
273190091Sobrien	}
273218334Speter
2733169702Skan      /* TREE_USED gets set erroneously during expand_assignment.  */
2734169702Skan      save_tree_used = TREE_USED (parm);
2735169702Skan      expand_assignment (parm, make_tree (data->nominal_type, tempreg));
2736169702Skan      TREE_USED (parm) = save_tree_used;
2737169702Skan      all->conversion_insns = get_insns ();
2738169702Skan      end_sequence ();
273918334Speter
2740169702Skan      did_conversion = true;
2741169702Skan    }
2742169702Skan  else
2743169702Skan    emit_move_insn (parmreg, validize_mem (data->entry_parm));
274418334Speter
2745169702Skan  /* If we were passed a pointer but the actual value can safely live
2746169702Skan     in a register, put it in one.  */
2747169702Skan  if (data->passed_pointer
2748169702Skan      && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
2749169702Skan      /* If by-reference argument was promoted, demote it.  */
2750169702Skan      && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
2751169702Skan	  || use_register_for_decl (parm)))
2752169702Skan    {
2753169702Skan      /* We can't use nominal_mode, because it will have been set to
2754169702Skan	 Pmode above.  We must use the actual mode of the parm.  */
2755169702Skan      parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
2756169702Skan      mark_user_reg (parmreg);
275718334Speter
2758169702Skan      if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
275918334Speter	{
2760169702Skan	  rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm)));
2761169702Skan	  int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm));
276218334Speter
2763169702Skan	  push_to_sequence (all->conversion_insns);
2764169702Skan	  emit_move_insn (tempreg, DECL_RTL (parm));
2765169702Skan	  tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p);
2766169702Skan	  emit_move_insn (parmreg, tempreg);
2767169702Skan	  all->conversion_insns = get_insns ();
2768169702Skan	  end_sequence ();
276918334Speter
2770169702Skan	  did_conversion = true;
2771132732Skan	}
2772169702Skan      else
2773169702Skan	emit_move_insn (parmreg, DECL_RTL (parm));
277418334Speter
2775169702Skan      SET_DECL_RTL (parm, parmreg);
277618334Speter
2777169702Skan      /* STACK_PARM is the pointer, not the parm, and PARMREG is
2778169702Skan	 now the parm.  */
2779169702Skan      data->stack_parm = NULL;
2780169702Skan    }
278118334Speter
2782169702Skan  /* Mark the register as eliminable if we did no conversion and it was
2783169702Skan     copied from memory at a fixed offset, and the arg pointer was not
2784169702Skan     copied to a pseudo-reg.  If the arg pointer is a pseudo reg or the
2785169702Skan     offset formed an invalid address, such memory-equivalences as we
2786169702Skan     make here would screw up life analysis for it.  */
2787169702Skan  if (data->nominal_mode == data->passed_mode
2788169702Skan      && !did_conversion
2789169702Skan      && data->stack_parm != 0
2790169702Skan      && MEM_P (data->stack_parm)
2791169702Skan      && data->locate.offset.var == 0
2792169702Skan      && reg_mentioned_p (virtual_incoming_args_rtx,
2793169702Skan			  XEXP (data->stack_parm, 0)))
2794169702Skan    {
2795169702Skan      rtx linsn = get_last_insn ();
2796169702Skan      rtx sinsn, set;
279718334Speter
2798169702Skan      /* Mark complex types separately.  */
2799169702Skan      if (GET_CODE (parmreg) == CONCAT)
280018334Speter	{
2801169702Skan	  enum machine_mode submode
2802169702Skan	    = GET_MODE_INNER (GET_MODE (parmreg));
2803169702Skan	  int regnor = REGNO (XEXP (parmreg, 0));
2804169702Skan	  int regnoi = REGNO (XEXP (parmreg, 1));
2805169702Skan	  rtx stackr = adjust_address_nv (data->stack_parm, submode, 0);
2806169702Skan	  rtx stacki = adjust_address_nv (data->stack_parm, submode,
2807169702Skan					  GET_MODE_SIZE (submode));
2808132732Skan
2809169702Skan	  /* Scan backwards for the set of the real and
2810169702Skan	     imaginary parts.  */
2811169702Skan	  for (sinsn = linsn; sinsn != 0;
2812169702Skan	       sinsn = prev_nonnote_insn (sinsn))
2813132732Skan	    {
2814169702Skan	      set = single_set (sinsn);
2815169702Skan	      if (set == 0)
2816169702Skan		continue;
2817132732Skan
2818169702Skan	      if (SET_DEST (set) == regno_reg_rtx [regnoi])
2819169702Skan		REG_NOTES (sinsn)
2820169702Skan		  = gen_rtx_EXPR_LIST (REG_EQUIV, stacki,
2821169702Skan				       REG_NOTES (sinsn));
2822169702Skan	      else if (SET_DEST (set) == regno_reg_rtx [regnor])
2823169702Skan		REG_NOTES (sinsn)
2824169702Skan		  = gen_rtx_EXPR_LIST (REG_EQUIV, stackr,
2825169702Skan				       REG_NOTES (sinsn));
2826132732Skan	    }
2827132732Skan	}
2828169702Skan      else if ((set = single_set (linsn)) != 0
2829169702Skan	       && SET_DEST (set) == parmreg)
2830169702Skan	REG_NOTES (linsn)
2831169702Skan	  = gen_rtx_EXPR_LIST (REG_EQUIV,
2832169702Skan			       data->stack_parm, REG_NOTES (linsn));
2833169702Skan    }
2834132732Skan
2835169702Skan  /* For pointer data type, suggest pointer register.  */
2836169702Skan  if (POINTER_TYPE_P (TREE_TYPE (parm)))
2837169702Skan    mark_reg_pointer (parmreg,
2838169702Skan		      TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
2839169702Skan}
2840132732Skan
2841169702Skan/* A subroutine of assign_parms.  Allocate stack space to hold the current
2842169702Skan   parameter.  Get it there.  Perform all ABI specified conversions.  */
284318334Speter
2844169702Skanstatic void
2845169702Skanassign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
2846169702Skan		         struct assign_parm_data_one *data)
2847169702Skan{
2848169702Skan  /* Value must be stored in the stack slot STACK_PARM during function
2849169702Skan     execution.  */
2850169702Skan  bool to_conversion = false;
2851132732Skan
2852169702Skan  if (data->promoted_mode != data->nominal_mode)
2853169702Skan    {
2854169702Skan      /* Conversion is required.  */
2855169702Skan      rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
285618334Speter
2857169702Skan      emit_move_insn (tempreg, validize_mem (data->entry_parm));
2858132732Skan
2859169702Skan      push_to_sequence (all->conversion_insns);
2860169702Skan      to_conversion = true;
2861132732Skan
2862169702Skan      data->entry_parm = convert_to_mode (data->nominal_mode, tempreg,
2863169702Skan					  TYPE_UNSIGNED (TREE_TYPE (parm)));
2864132732Skan
2865169702Skan      if (data->stack_parm)
2866169702Skan	/* ??? This may need a big-endian conversion on sparc64.  */
2867169702Skan	data->stack_parm
2868169702Skan	  = adjust_address (data->stack_parm, data->nominal_mode, 0);
2869169702Skan    }
287018334Speter
2871169702Skan  if (data->entry_parm != data->stack_parm)
2872169702Skan    {
2873169702Skan      rtx src, dest;
287418334Speter
2875169702Skan      if (data->stack_parm == 0)
287618334Speter	{
2877169702Skan	  data->stack_parm
2878169702Skan	    = assign_stack_local (GET_MODE (data->entry_parm),
2879169702Skan				  GET_MODE_SIZE (GET_MODE (data->entry_parm)),
2880169702Skan				  TYPE_ALIGN (data->passed_type));
2881169702Skan	  set_mem_attributes (data->stack_parm, parm, 1);
288218334Speter	}
288318334Speter
2884169702Skan      dest = validize_mem (data->stack_parm);
2885169702Skan      src = validize_mem (data->entry_parm);
288618334Speter
2887169702Skan      if (MEM_P (src))
2888169702Skan	{
2889169702Skan	  /* Use a block move to handle potentially misaligned entry_parm.  */
2890169702Skan	  if (!to_conversion)
2891169702Skan	    push_to_sequence (all->conversion_insns);
2892169702Skan	  to_conversion = true;
289318334Speter
2894169702Skan	  emit_block_move (dest, src,
2895169702Skan			   GEN_INT (int_size_in_bytes (data->passed_type)),
2896169702Skan			   BLOCK_OP_NORMAL);
289718334Speter	}
289818334Speter      else
2899169702Skan	emit_move_insn (dest, src);
2900169702Skan    }
290118334Speter
2902169702Skan  if (to_conversion)
2903169702Skan    {
2904169702Skan      all->conversion_insns = get_insns ();
2905169702Skan      end_sequence ();
2906169702Skan    }
290718334Speter
2908169702Skan  SET_DECL_RTL (parm, data->stack_parm);
2909169702Skan}
291018334Speter
2911169702Skan/* A subroutine of assign_parms.  If the ABI splits complex arguments, then
2912169702Skan   undo the frobbing that we did in assign_parms_augmented_arg_list.  */
291318334Speter
2914169702Skanstatic void
2915169702Skanassign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs)
2916169702Skan{
2917169702Skan  tree parm;
2918169702Skan  tree orig_fnargs = all->orig_fnargs;
291918334Speter
2920169702Skan  for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm))
2921169702Skan    {
2922169702Skan      if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
2923169702Skan	  && targetm.calls.split_complex_arg (TREE_TYPE (parm)))
292418334Speter	{
2925169702Skan	  rtx tmp, real, imag;
2926169702Skan	  enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
292718334Speter
2928169702Skan	  real = DECL_RTL (fnargs);
2929169702Skan	  imag = DECL_RTL (TREE_CHAIN (fnargs));
2930169702Skan	  if (inner != GET_MODE (real))
2931132732Skan	    {
2932169702Skan	      real = gen_lowpart_SUBREG (inner, real);
2933169702Skan	      imag = gen_lowpart_SUBREG (inner, imag);
2934132732Skan	    }
2935132732Skan
2936169702Skan	  if (TREE_ADDRESSABLE (parm))
293718334Speter	    {
2938169702Skan	      rtx rmem, imem;
2939169702Skan	      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm));
294018334Speter
2941169702Skan	      /* split_complex_arg put the real and imag parts in
2942169702Skan		 pseudos.  Move them to memory.  */
2943169702Skan	      tmp = assign_stack_local (DECL_MODE (parm), size,
2944169702Skan					TYPE_ALIGN (TREE_TYPE (parm)));
2945169702Skan	      set_mem_attributes (tmp, parm, 1);
2946169702Skan	      rmem = adjust_address_nv (tmp, inner, 0);
2947169702Skan	      imem = adjust_address_nv (tmp, inner, GET_MODE_SIZE (inner));
2948169702Skan	      push_to_sequence (all->conversion_insns);
2949169702Skan	      emit_move_insn (rmem, real);
2950169702Skan	      emit_move_insn (imem, imag);
2951169702Skan	      all->conversion_insns = get_insns ();
295218334Speter	      end_sequence ();
295318334Speter	    }
295418334Speter	  else
2955169702Skan	    tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
2956169702Skan	  SET_DECL_RTL (parm, tmp);
295718334Speter
2958169702Skan	  real = DECL_INCOMING_RTL (fnargs);
2959169702Skan	  imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
2960169702Skan	  if (inner != GET_MODE (real))
296118334Speter	    {
2962169702Skan	      real = gen_lowpart_SUBREG (inner, real);
2963169702Skan	      imag = gen_lowpart_SUBREG (inner, imag);
296418334Speter	    }
2965169702Skan	  tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
2966169702Skan	  set_decl_incoming_rtl (parm, tmp);
2967169702Skan	  fnargs = TREE_CHAIN (fnargs);
2968169702Skan	}
2969169702Skan      else
2970169702Skan	{
2971169702Skan	  SET_DECL_RTL (parm, DECL_RTL (fnargs));
2972169702Skan	  set_decl_incoming_rtl (parm, DECL_INCOMING_RTL (fnargs));
297318334Speter
2974169702Skan	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
2975169702Skan	     instead of the copy of decl, i.e. FNARGS.  */
2976169702Skan	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
2977169702Skan	    set_mem_expr (DECL_INCOMING_RTL (parm), parm);
2978169702Skan	}
297918334Speter
2980169702Skan      fnargs = TREE_CHAIN (fnargs);
2981169702Skan    }
2982169702Skan}
298318334Speter
2984169702Skan/* Assign RTL expressions to the function's parameters.  This may involve
2985169702Skan   copying them into registers and using those registers as the DECL_RTL.  */
298618334Speter
2987169702Skanstatic void
2988169702Skanassign_parms (tree fndecl)
2989169702Skan{
2990169702Skan  struct assign_parm_data_all all;
2991169702Skan  tree fnargs, parm;
299218334Speter
2993169702Skan  current_function_internal_arg_pointer
2994169702Skan    = targetm.calls.internal_arg_pointer ();
299518334Speter
2996169702Skan  assign_parms_initialize_all (&all);
2997169702Skan  fnargs = assign_parms_augmented_arg_list (&all);
299818334Speter
2999169702Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
3000169702Skan    {
3001169702Skan      struct assign_parm_data_one data;
300218334Speter
3003169702Skan      /* Extract the type of PARM; adjust it according to ABI.  */
3004169702Skan      assign_parm_find_data_types (&all, parm, &data);
300518334Speter
3006169702Skan      /* Early out for errors and void parameters.  */
3007169702Skan      if (data.passed_mode == VOIDmode)
3008169702Skan	{
3009169702Skan	  SET_DECL_RTL (parm, const0_rtx);
3010169702Skan	  DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
3011169702Skan	  continue;
3012169702Skan	}
301318334Speter
3014169702Skan      if (current_function_stdarg && !TREE_CHAIN (parm))
3015169702Skan	assign_parms_setup_varargs (&all, &data, false);
301618334Speter
3017169702Skan      /* Find out where the parameter arrives in this function.  */
3018169702Skan      assign_parm_find_entry_rtl (&all, &data);
301918334Speter
3020169702Skan      /* Find out where stack space for this parameter might be.  */
3021169702Skan      if (assign_parm_is_stack_parm (&all, &data))
3022169702Skan	{
3023169702Skan	  assign_parm_find_stack_rtl (parm, &data);
3024169702Skan	  assign_parm_adjust_entry_rtl (&data);
3025169702Skan	}
302618334Speter
3027169702Skan      /* Record permanently how this parm was passed.  */
3028169702Skan      set_decl_incoming_rtl (parm, data.entry_parm);
302918334Speter
3030169702Skan      /* Update info on where next arg arrives in registers.  */
3031169702Skan      FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
3032169702Skan			    data.passed_type, data.named_arg);
303318334Speter
3034169702Skan      assign_parm_adjust_stack_rtl (&data);
303518334Speter
3036169702Skan      if (assign_parm_setup_block_p (&data))
3037169702Skan	assign_parm_setup_block (&all, parm, &data);
3038169702Skan      else if (data.passed_pointer || use_register_for_decl (parm))
3039169702Skan	assign_parm_setup_reg (&all, parm, &data);
304018334Speter      else
3041169702Skan	assign_parm_setup_stack (&all, parm, &data);
3042132732Skan    }
304390091Sobrien
3044169702Skan  if (targetm.calls.split_complex_arg && fnargs != all.orig_fnargs)
3045169702Skan    assign_parms_unsplit_complex (&all, fnargs);
304618334Speter
304718334Speter  /* Output all parameter conversion instructions (possibly including calls)
304818334Speter     now that all parameters have been copied out of hard registers.  */
3049169702Skan  emit_insn (all.conversion_insns);
305018334Speter
3051132732Skan  /* If we are receiving a struct value address as the first argument, set up
3052132732Skan     the RTL for the function result. As this might require code to convert
3053132732Skan     the transmitted address to Pmode, we do this here to ensure that possible
3054132732Skan     preliminary conversions of the address have been emitted already.  */
3055169702Skan  if (all.function_result_decl)
3056132732Skan    {
3057169702Skan      tree result = DECL_RESULT (current_function_decl);
3058169702Skan      rtx addr = DECL_RTL (all.function_result_decl);
3059132732Skan      rtx x;
3060132732Skan
3061169702Skan      if (DECL_BY_REFERENCE (result))
3062169702Skan	x = addr;
3063169702Skan      else
3064169702Skan	{
3065169702Skan	  addr = convert_memory_address (Pmode, addr);
3066169702Skan	  x = gen_rtx_MEM (DECL_MODE (result), addr);
3067169702Skan	  set_mem_attributes (x, result, 1);
3068169702Skan	}
3069132732Skan      SET_DECL_RTL (result, x);
3070132732Skan    }
3071132732Skan
3072169702Skan  /* We have aligned all the args, so add space for the pretend args.  */
3073169702Skan  current_function_pretend_args_size = all.pretend_args_size;
3074169702Skan  all.stack_args_size.constant += all.extra_pretend_bytes;
3075169702Skan  current_function_args_size = all.stack_args_size.constant;
307618334Speter
307718334Speter  /* Adjust function incoming argument size for alignment and
307818334Speter     minimum length.  */
307918334Speter
308018334Speter#ifdef REG_PARM_STACK_SPACE
308118334Speter  current_function_args_size = MAX (current_function_args_size,
308218334Speter				    REG_PARM_STACK_SPACE (fndecl));
308318334Speter#endif
308418334Speter
3085169702Skan  current_function_args_size = CEIL_ROUND (current_function_args_size,
3086169702Skan					   PARM_BOUNDARY / BITS_PER_UNIT);
308718334Speter
308818334Speter#ifdef ARGS_GROW_DOWNWARD
308918334Speter  current_function_arg_offset_rtx
3090169702Skan    = (all.stack_args_size.var == 0 ? GEN_INT (-all.stack_args_size.constant)
3091169702Skan       : expand_expr (size_diffop (all.stack_args_size.var,
3092169702Skan				   size_int (-all.stack_args_size.constant)),
309390091Sobrien		      NULL_RTX, VOIDmode, 0));
309418334Speter#else
3095169702Skan  current_function_arg_offset_rtx = ARGS_SIZE_RTX (all.stack_args_size);
309618334Speter#endif
309718334Speter
309818334Speter  /* See how many bytes, if any, of its args a function should try to pop
309918334Speter     on return.  */
310018334Speter
310118334Speter  current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl),
310218334Speter						 current_function_args_size);
310318334Speter
310418334Speter  /* For stdarg.h function, save info about
310518334Speter     regs and stack space used by the named args.  */
310618334Speter
3107169702Skan  current_function_args_info = all.args_so_far;
310818334Speter
310918334Speter  /* Set the rtx used for the function return value.  Put this in its
311018334Speter     own variable so any optimizers that need this information don't have
311118334Speter     to include tree.h.  Do this here so it gets done when an inlined
311218334Speter     function gets output.  */
311318334Speter
311490091Sobrien  current_function_return_rtx
311590091Sobrien    = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
311690091Sobrien       ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
311796283Sobrien
311896283Sobrien  /* If scalar return value was computed in a pseudo-reg, or was a named
311996283Sobrien     return value that got dumped to the stack, copy that to the hard
312096283Sobrien     return register.  */
312196283Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
312296283Sobrien    {
312396283Sobrien      tree decl_result = DECL_RESULT (fndecl);
312496283Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
312596283Sobrien
312696283Sobrien      if (REG_P (decl_rtl)
312796283Sobrien	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
312896283Sobrien	  : DECL_REGISTER (decl_result))
312996283Sobrien	{
313096283Sobrien	  rtx real_decl_rtl;
313196283Sobrien
3132169702Skan	  real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result),
3133169702Skan							fndecl, true);
313496283Sobrien	  REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
313596283Sobrien	  /* The delay slot scheduler assumes that current_function_return_rtx
313696283Sobrien	     holds the hard register containing the return value, not a
313796283Sobrien	     temporary pseudo.  */
313896283Sobrien	  current_function_return_rtx = real_decl_rtl;
313996283Sobrien	}
314096283Sobrien    }
314118334Speter}
3142132732Skan
3143169702Skan/* A subroutine of gimplify_parameters, invoked via walk_tree.
3144169702Skan   For all seen types, gimplify their sizes.  */
3145132732Skan
3146132732Skanstatic tree
3147169702Skangimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
3148132732Skan{
3149169702Skan  tree t = *tp;
3150132732Skan
3151169702Skan  *walk_subtrees = 0;
3152169702Skan  if (TYPE_P (t))
3153132732Skan    {
3154169702Skan      if (POINTER_TYPE_P (t))
3155169702Skan	*walk_subtrees = 1;
3156169702Skan      else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
3157169702Skan	       && !TYPE_SIZES_GIMPLIFIED (t))
3158169702Skan	{
3159169702Skan	  gimplify_type_sizes (t, (tree *) data);
3160169702Skan	  *walk_subtrees = 1;
3161169702Skan	}
3162132732Skan    }
3163132732Skan
3164169702Skan  return NULL;
3165169702Skan}
3166132732Skan
3167169702Skan/* Gimplify the parameter list for current_function_decl.  This involves
3168169702Skan   evaluating SAVE_EXPRs of variable sized parameters and generating code
3169169702Skan   to implement callee-copies reference parameters.  Returns a list of
3170169702Skan   statements to add to the beginning of the function, or NULL if nothing
3171169702Skan   to do.  */
3172169702Skan
3173169702Skantree
3174169702Skangimplify_parameters (void)
3175169702Skan{
3176169702Skan  struct assign_parm_data_all all;
3177169702Skan  tree fnargs, parm, stmts = NULL;
3178169702Skan
3179169702Skan  assign_parms_initialize_all (&all);
3180169702Skan  fnargs = assign_parms_augmented_arg_list (&all);
3181169702Skan
3182169702Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
3183132732Skan    {
3184169702Skan      struct assign_parm_data_one data;
3185169702Skan
3186169702Skan      /* Extract the type of PARM; adjust it according to ABI.  */
3187169702Skan      assign_parm_find_data_types (&all, parm, &data);
3188169702Skan
3189169702Skan      /* Early out for errors and void parameters.  */
3190169702Skan      if (data.passed_mode == VOIDmode || DECL_SIZE (parm) == NULL)
3191169702Skan	continue;
3192169702Skan
3193169702Skan      /* Update info on where next arg arrives in registers.  */
3194169702Skan      FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
3195169702Skan			    data.passed_type, data.named_arg);
3196169702Skan
3197169702Skan      /* ??? Once upon a time variable_size stuffed parameter list
3198169702Skan	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
3199169702Skan	 turned out to be less than manageable in the gimple world.
3200169702Skan	 Now we have to hunt them down ourselves.  */
3201169702Skan      walk_tree_without_duplicates (&data.passed_type,
3202169702Skan				    gimplify_parm_type, &stmts);
3203169702Skan
3204169702Skan      if (!TREE_CONSTANT (DECL_SIZE (parm)))
3205132732Skan	{
3206169702Skan	  gimplify_one_sizepos (&DECL_SIZE (parm), &stmts);
3207169702Skan	  gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
3208169702Skan	}
3209132732Skan
3210169702Skan      if (data.passed_pointer)
3211169702Skan	{
3212169702Skan          tree type = TREE_TYPE (data.passed_type);
3213169702Skan	  if (reference_callee_copied (&all.args_so_far, TYPE_MODE (type),
3214169702Skan				       type, data.named_arg))
3215169702Skan	    {
3216169702Skan	      tree local, t;
3217132732Skan
3218169702Skan	      /* For constant sized objects, this is trivial; for
3219169702Skan		 variable-sized objects, we have to play games.  */
3220169702Skan	      if (TREE_CONSTANT (DECL_SIZE (parm)))
3221169702Skan		{
3222169702Skan		  local = create_tmp_var (type, get_name (parm));
3223169702Skan		  DECL_IGNORED_P (local) = 0;
3224169702Skan		}
3225169702Skan	      else
3226169702Skan		{
3227169702Skan		  tree ptr_type, addr, args;
3228132732Skan
3229169702Skan		  ptr_type = build_pointer_type (type);
3230169702Skan		  addr = create_tmp_var (ptr_type, get_name (parm));
3231169702Skan		  DECL_IGNORED_P (addr) = 0;
3232169702Skan		  local = build_fold_indirect_ref (addr);
3233169702Skan
3234169702Skan		  args = tree_cons (NULL, DECL_SIZE_UNIT (parm), NULL);
3235169702Skan		  t = built_in_decls[BUILT_IN_ALLOCA];
3236169702Skan		  t = build_function_call_expr (t, args);
3237169702Skan		  t = fold_convert (ptr_type, t);
3238169702Skan		  t = build2 (MODIFY_EXPR, void_type_node, addr, t);
3239169702Skan		  gimplify_and_add (t, &stmts);
3240169702Skan		}
3241169702Skan
3242169702Skan	      t = build2 (MODIFY_EXPR, void_type_node, local, parm);
3243169702Skan	      gimplify_and_add (t, &stmts);
3244169702Skan
3245169702Skan	      SET_DECL_VALUE_EXPR (parm, local);
3246169702Skan	      DECL_HAS_VALUE_EXPR_P (parm) = 1;
3247169702Skan	    }
3248132732Skan	}
3249132732Skan    }
3250132732Skan
3251169702Skan  return stmts;
3252132732Skan}
325318334Speter
325418334Speter/* Indicate whether REGNO is an incoming argument to the current function
325518334Speter   that was promoted to a wider mode.  If so, return the RTX for the
325618334Speter   register (to get its mode).  PMODE and PUNSIGNEDP are set to the mode
325718334Speter   that REGNO is promoted from and whether the promotion was signed or
325818334Speter   unsigned.  */
325918334Speter
326018334Speterrtx
3261132732Skanpromoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp)
326218334Speter{
326318334Speter  tree arg;
326418334Speter
326518334Speter  for (arg = DECL_ARGUMENTS (current_function_decl); arg;
326618334Speter       arg = TREE_CHAIN (arg))
3267169702Skan    if (REG_P (DECL_INCOMING_RTL (arg))
326818334Speter	&& REGNO (DECL_INCOMING_RTL (arg)) == regno
326918334Speter	&& TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
327018334Speter      {
327118334Speter	enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
3272169702Skan	int unsignedp = TYPE_UNSIGNED (TREE_TYPE (arg));
327318334Speter
327418334Speter	mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1);
327518334Speter	if (mode == GET_MODE (DECL_INCOMING_RTL (arg))
327618334Speter	    && mode != DECL_MODE (arg))
327718334Speter	  {
327818334Speter	    *pmode = DECL_MODE (arg);
327918334Speter	    *punsignedp = unsignedp;
328018334Speter	    return DECL_INCOMING_RTL (arg);
328118334Speter	  }
328218334Speter      }
328318334Speter
328418334Speter  return 0;
328518334Speter}
328618334Speter
328718334Speter
328818334Speter/* Compute the size and offset from the start of the stacked arguments for a
328918334Speter   parm passed in mode PASSED_MODE and with type TYPE.
329018334Speter
329118334Speter   INITIAL_OFFSET_PTR points to the current offset into the stacked
329218334Speter   arguments.
329318334Speter
3294132732Skan   The starting offset and size for this parm are returned in
3295132732Skan   LOCATE->OFFSET and LOCATE->SIZE, respectively.  When IN_REGS is
3296132732Skan   nonzero, the offset is that of stack slot, which is returned in
3297132732Skan   LOCATE->SLOT_OFFSET.  LOCATE->ALIGNMENT_PAD is the amount of
3298132732Skan   padding required from the initial offset ptr to the stack slot.
329918334Speter
3300117404Skan   IN_REGS is nonzero if the argument will be passed in registers.  It will
330118334Speter   never be set if REG_PARM_STACK_SPACE is not defined.
330218334Speter
330318334Speter   FNDECL is the function in which the argument was defined.
330418334Speter
330518334Speter   There are two types of rounding that are done.  The first, controlled by
330618334Speter   FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
330718334Speter   list to be aligned to the specific boundary (in bits).  This rounding
330818334Speter   affects the initial and starting offsets, but not the argument size.
330918334Speter
331018334Speter   The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
331118334Speter   optionally rounds the size of the parm to PARM_BOUNDARY.  The
331218334Speter   initial offset is not affected by this rounding, while the size always
331318334Speter   is and the starting offset may be.  */
331418334Speter
3315132732Skan/*  LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
3316132732Skan    INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
331718334Speter    callers pass in the total size of args so far as
3318132732Skan    INITIAL_OFFSET_PTR.  LOCATE->SIZE is always positive.  */
331918334Speter
332018334Spetervoid
3321132732Skanlocate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
3322132732Skan		     int partial, tree fndecl ATTRIBUTE_UNUSED,
3323132732Skan		     struct args_size *initial_offset_ptr,
3324132732Skan		     struct locate_and_pad_arg_data *locate)
3325132732Skan{
3326132732Skan  tree sizetree;
3327132732Skan  enum direction where_pad;
3328169702Skan  unsigned int boundary;
3329132732Skan  int reg_parm_stack_space = 0;
3330132732Skan  int part_size_in_regs;
333190091Sobrien
3332132732Skan#ifdef REG_PARM_STACK_SPACE
3333132732Skan  reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
333418334Speter
333518334Speter  /* If we have found a stack parm before we reach the end of the
333618334Speter     area reserved for registers, skip that area.  */
333718334Speter  if (! in_regs)
333818334Speter    {
333918334Speter      if (reg_parm_stack_space > 0)
334018334Speter	{
334118334Speter	  if (initial_offset_ptr->var)
334218334Speter	    {
334318334Speter	      initial_offset_ptr->var
334418334Speter		= size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
334590091Sobrien			      ssize_int (reg_parm_stack_space));
334618334Speter	      initial_offset_ptr->constant = 0;
334718334Speter	    }
334818334Speter	  else if (initial_offset_ptr->constant < reg_parm_stack_space)
334918334Speter	    initial_offset_ptr->constant = reg_parm_stack_space;
335018334Speter	}
335118334Speter    }
335218334Speter#endif /* REG_PARM_STACK_SPACE */
335318334Speter
3354169702Skan  part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0);
335518334Speter
3356132732Skan  sizetree
3357132732Skan    = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
3358132732Skan  where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
3359132732Skan  boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
3360132732Skan  locate->where_pad = where_pad;
3361169702Skan  locate->boundary = boundary;
3362132732Skan
3363169702Skan  /* Remember if the outgoing parameter requires extra alignment on the
3364169702Skan     calling function side.  */
3365169702Skan  if (boundary > PREFERRED_STACK_BOUNDARY)
3366169702Skan    boundary = PREFERRED_STACK_BOUNDARY;
3367169702Skan  if (cfun->stack_alignment_needed < boundary)
3368169702Skan    cfun->stack_alignment_needed = boundary;
3369169702Skan
337018334Speter#ifdef ARGS_GROW_DOWNWARD
3371132732Skan  locate->slot_offset.constant = -initial_offset_ptr->constant;
337218334Speter  if (initial_offset_ptr->var)
3373132732Skan    locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
3374132732Skan					  initial_offset_ptr->var);
3375117404Skan
3376132732Skan  {
3377132732Skan    tree s2 = sizetree;
3378132732Skan    if (where_pad != none
3379132732Skan	&& (!host_integerp (sizetree, 1)
3380132732Skan	    || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
3381132732Skan      s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
3382132732Skan    SUB_PARM_SIZE (locate->slot_offset, s2);
3383132732Skan  }
3384117404Skan
3385132732Skan  locate->slot_offset.constant += part_size_in_regs;
3386132732Skan
3387117404Skan  if (!in_regs
3388117404Skan#ifdef REG_PARM_STACK_SPACE
3389117404Skan      || REG_PARM_STACK_SPACE (fndecl) > 0
3390117404Skan#endif
3391117404Skan     )
3392132732Skan    pad_to_arg_alignment (&locate->slot_offset, boundary,
3393132732Skan			  &locate->alignment_pad);
3394117404Skan
3395132732Skan  locate->size.constant = (-initial_offset_ptr->constant
3396132732Skan			   - locate->slot_offset.constant);
339718334Speter  if (initial_offset_ptr->var)
3398132732Skan    locate->size.var = size_binop (MINUS_EXPR,
3399132732Skan				   size_binop (MINUS_EXPR,
3400132732Skan					       ssize_int (0),
3401132732Skan					       initial_offset_ptr->var),
3402132732Skan				   locate->slot_offset.var);
340390091Sobrien
3404132732Skan  /* Pad_below needs the pre-rounded size to know how much to pad
3405132732Skan     below.  */
3406132732Skan  locate->offset = locate->slot_offset;
3407132732Skan  if (where_pad == downward)
3408132732Skan    pad_below (&locate->offset, passed_mode, sizetree);
340990091Sobrien
341018334Speter#else /* !ARGS_GROW_DOWNWARD */
341190091Sobrien  if (!in_regs
341290091Sobrien#ifdef REG_PARM_STACK_SPACE
341390091Sobrien      || REG_PARM_STACK_SPACE (fndecl) > 0
341490091Sobrien#endif
341590091Sobrien      )
3416132732Skan    pad_to_arg_alignment (initial_offset_ptr, boundary,
3417132732Skan			  &locate->alignment_pad);
3418132732Skan  locate->slot_offset = *initial_offset_ptr;
341918334Speter
342018334Speter#ifdef PUSH_ROUNDING
342118334Speter  if (passed_mode != BLKmode)
342218334Speter    sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
342318334Speter#endif
342418334Speter
342518334Speter  /* Pad_below needs the pre-rounded size to know how much to pad below
342618334Speter     so this must be done before rounding up.  */
3427132732Skan  locate->offset = locate->slot_offset;
3428132732Skan  if (where_pad == downward)
3429132732Skan    pad_below (&locate->offset, passed_mode, sizetree);
343018334Speter
343118334Speter  if (where_pad != none
343290091Sobrien      && (!host_integerp (sizetree, 1)
343390091Sobrien	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
343418334Speter    sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
343518334Speter
3436132732Skan  ADD_PARM_SIZE (locate->size, sizetree);
3437132732Skan
3438132732Skan  locate->size.constant -= part_size_in_regs;
343918334Speter#endif /* ARGS_GROW_DOWNWARD */
344018334Speter}
344118334Speter
344218334Speter/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
344318334Speter   BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */
344418334Speter
344518334Speterstatic void
3446132732Skanpad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
3447132732Skan		      struct args_size *alignment_pad)
344818334Speter{
344990091Sobrien  tree save_var = NULL_TREE;
345090091Sobrien  HOST_WIDE_INT save_constant = 0;
345118334Speter  int boundary_in_bytes = boundary / BITS_PER_UNIT;
3452132732Skan  HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET;
345390091Sobrien
3454132732Skan#ifdef SPARC_STACK_BOUNDARY_HACK
3455169702Skan  /* ??? The SPARC port may claim a STACK_BOUNDARY higher than
3456169702Skan     the real alignment of %sp.  However, when it does this, the
3457169702Skan     alignment of %sp+STACK_POINTER_OFFSET is STACK_BOUNDARY.  */
3458132732Skan  if (SPARC_STACK_BOUNDARY_HACK)
3459132732Skan    sp_offset = 0;
3460132732Skan#endif
3461132732Skan
346290091Sobrien  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
346390091Sobrien    {
346490091Sobrien      save_var = offset_ptr->var;
346590091Sobrien      save_constant = offset_ptr->constant;
346690091Sobrien    }
346790091Sobrien
346890091Sobrien  alignment_pad->var = NULL_TREE;
346990091Sobrien  alignment_pad->constant = 0;
347090091Sobrien
347118334Speter  if (boundary > BITS_PER_UNIT)
347218334Speter    {
347318334Speter      if (offset_ptr->var)
347418334Speter	{
3475132732Skan	  tree sp_offset_tree = ssize_int (sp_offset);
3476132732Skan	  tree offset = size_binop (PLUS_EXPR,
3477132732Skan				    ARGS_SIZE_TREE (*offset_ptr),
3478132732Skan				    sp_offset_tree);
347918334Speter#ifdef ARGS_GROW_DOWNWARD
3480132732Skan	  tree rounded = round_down (offset, boundary / BITS_PER_UNIT);
348118334Speter#else
3482132732Skan	  tree rounded = round_up   (offset, boundary / BITS_PER_UNIT);
348318334Speter#endif
3484132732Skan
3485132732Skan	  offset_ptr->var = size_binop (MINUS_EXPR, rounded, sp_offset_tree);
3486132732Skan	  /* ARGS_SIZE_TREE includes constant term.  */
3487132732Skan	  offset_ptr->constant = 0;
3488117404Skan	  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
3489117404Skan	    alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
349090091Sobrien					     save_var);
349118334Speter	}
349218334Speter      else
349390091Sobrien	{
3494132732Skan	  offset_ptr->constant = -sp_offset +
349518334Speter#ifdef ARGS_GROW_DOWNWARD
3496132732Skan	    FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
349718334Speter#else
3498132732Skan	    CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
349918334Speter#endif
350090091Sobrien	    if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
350190091Sobrien	      alignment_pad->constant = offset_ptr->constant - save_constant;
350290091Sobrien	}
350318334Speter    }
350418334Speter}
350518334Speter
350618334Speterstatic void
3507132732Skanpad_below (struct args_size *offset_ptr, enum machine_mode passed_mode, tree sizetree)
350818334Speter{
350918334Speter  if (passed_mode != BLKmode)
351018334Speter    {
351118334Speter      if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
351218334Speter	offset_ptr->constant
351318334Speter	  += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
351418334Speter	       / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
351518334Speter	      - GET_MODE_SIZE (passed_mode));
351618334Speter    }
351718334Speter  else
351818334Speter    {
351918334Speter      if (TREE_CODE (sizetree) != INTEGER_CST
352018334Speter	  || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
352118334Speter	{
352218334Speter	  /* Round the size up to multiple of PARM_BOUNDARY bits.  */
352318334Speter	  tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
352418334Speter	  /* Add it in.  */
352518334Speter	  ADD_PARM_SIZE (*offset_ptr, s2);
352618334Speter	  SUB_PARM_SIZE (*offset_ptr, sizetree);
352718334Speter	}
352818334Speter    }
352918334Speter}
353018334Speter
353118334Speter/* Walk the tree of blocks describing the binding levels within a function
3532169702Skan   and warn about variables the might be killed by setjmp or vfork.
353318334Speter   This is done after calling flow_analysis and before global_alloc
353418334Speter   clobbers the pseudo-regs to hard regs.  */
353518334Speter
353618334Spetervoid
3537169702Skansetjmp_vars_warning (tree block)
353818334Speter{
353990091Sobrien  tree decl, sub;
3540169702Skan
354118334Speter  for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
354218334Speter    {
3543169702Skan      if (TREE_CODE (decl) == VAR_DECL
3544132732Skan	  && DECL_RTL_SET_P (decl)
3545169702Skan	  && REG_P (DECL_RTL (decl))
354618334Speter	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3547169702Skan	warning (0, "variable %q+D might be clobbered by %<longjmp%>"
3548169702Skan		 " or %<vfork%>",
3549169702Skan		 decl);
355018334Speter    }
3551169702Skan
355218334Speter  for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
3553169702Skan    setjmp_vars_warning (sub);
355418334Speter}
355518334Speter
3556169702Skan/* Do the appropriate part of setjmp_vars_warning
355718334Speter   but for arguments instead of local variables.  */
355818334Speter
355918334Spetervoid
3560132732Skansetjmp_args_warning (void)
356118334Speter{
356290091Sobrien  tree decl;
356318334Speter  for (decl = DECL_ARGUMENTS (current_function_decl);
356418334Speter       decl; decl = TREE_CHAIN (decl))
356518334Speter    if (DECL_RTL (decl) != 0
3566169702Skan	&& REG_P (DECL_RTL (decl))
356718334Speter	&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3568169702Skan      warning (0, "argument %q+D might be clobbered by %<longjmp%> or %<vfork%>",
3569169702Skan	       decl);
357018334Speter}
357118334Speter
357218334Speter
357390091Sobrien/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
357490091Sobrien   and create duplicate blocks.  */
357590091Sobrien/* ??? Need an option to either create block fragments or to create
357690091Sobrien   abstract origin duplicates of a source block.  It really depends
357790091Sobrien   on what optimization has been performed.  */
357818334Speter
357990091Sobrienvoid
3580132732Skanreorder_blocks (void)
358190091Sobrien{
358290091Sobrien  tree block = DECL_INITIAL (current_function_decl);
3583169702Skan  VEC(tree,heap) *block_stack;
358490091Sobrien
358590091Sobrien  if (block == NULL_TREE)
358690091Sobrien    return;
358790091Sobrien
3588169702Skan  block_stack = VEC_alloc (tree, heap, 10);
358990091Sobrien
359090091Sobrien  /* Reset the TREE_ASM_WRITTEN bit for all blocks.  */
3591169702Skan  clear_block_marks (block);
359290091Sobrien
359390091Sobrien  /* Prune the old trees away, so that they don't get in the way.  */
359490091Sobrien  BLOCK_SUBBLOCKS (block) = NULL_TREE;
359590091Sobrien  BLOCK_CHAIN (block) = NULL_TREE;
359690091Sobrien
359790091Sobrien  /* Recreate the block tree from the note nesting.  */
359890091Sobrien  reorder_blocks_1 (get_insns (), block, &block_stack);
359990091Sobrien  BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));
360090091Sobrien
3601169702Skan  VEC_free (tree, heap, block_stack);
360290091Sobrien}
360390091Sobrien
360490091Sobrien/* Helper function for reorder_blocks.  Reset TREE_ASM_WRITTEN.  */
360590091Sobrien
3606169702Skanvoid
3607169702Skanclear_block_marks (tree block)
360890091Sobrien{
360990091Sobrien  while (block)
361090091Sobrien    {
361190091Sobrien      TREE_ASM_WRITTEN (block) = 0;
3612169702Skan      clear_block_marks (BLOCK_SUBBLOCKS (block));
361390091Sobrien      block = BLOCK_CHAIN (block);
361490091Sobrien    }
361590091Sobrien}
361690091Sobrien
361790091Sobrienstatic void
3618169702Skanreorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
361918334Speter{
362018334Speter  rtx insn;
362118334Speter
362290091Sobrien  for (insn = insns; insn; insn = NEXT_INSN (insn))
362390091Sobrien    {
3624169702Skan      if (NOTE_P (insn))
362590091Sobrien	{
362690091Sobrien	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
362790091Sobrien	    {
362890091Sobrien	      tree block = NOTE_BLOCK (insn);
3629169702Skan	      tree origin;
363018334Speter
3631169702Skan	      origin = (BLOCK_FRAGMENT_ORIGIN (block)
3632169702Skan			? BLOCK_FRAGMENT_ORIGIN (block)
3633169702Skan			: block);
3634169702Skan
363590091Sobrien	      /* If we have seen this block before, that means it now
363690091Sobrien		 spans multiple address regions.  Create a new fragment.  */
363790091Sobrien	      if (TREE_ASM_WRITTEN (block))
363890091Sobrien		{
363990091Sobrien		  tree new_block = copy_node (block);
364018334Speter
364190091Sobrien		  BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
364290091Sobrien		  BLOCK_FRAGMENT_CHAIN (new_block)
364390091Sobrien		    = BLOCK_FRAGMENT_CHAIN (origin);
364490091Sobrien		  BLOCK_FRAGMENT_CHAIN (origin) = new_block;
364518334Speter
364690091Sobrien		  NOTE_BLOCK (insn) = new_block;
364790091Sobrien		  block = new_block;
364890091Sobrien		}
364990091Sobrien
365090091Sobrien	      BLOCK_SUBBLOCKS (block) = 0;
365190091Sobrien	      TREE_ASM_WRITTEN (block) = 1;
3652132732Skan	      /* When there's only one block for the entire function,
3653132732Skan		 current_block == block and we mustn't do this, it
3654132732Skan		 will cause infinite recursion.  */
3655132732Skan	      if (block != current_block)
3656132732Skan		{
3657169702Skan		  if (block != origin)
3658169702Skan		    gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block);
3659169702Skan
3660132732Skan		  BLOCK_SUPERCONTEXT (block) = current_block;
3661132732Skan		  BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
3662132732Skan		  BLOCK_SUBBLOCKS (current_block) = block;
3663169702Skan		  current_block = origin;
3664132732Skan		}
3665169702Skan	      VEC_safe_push (tree, heap, *p_block_stack, block);
366690091Sobrien	    }
366790091Sobrien	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
366890091Sobrien	    {
3669169702Skan	      NOTE_BLOCK (insn) = VEC_pop (tree, *p_block_stack);
367090091Sobrien	      BLOCK_SUBBLOCKS (current_block)
367190091Sobrien		= blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
367290091Sobrien	      current_block = BLOCK_SUPERCONTEXT (current_block);
367390091Sobrien	    }
367490091Sobrien	}
367590091Sobrien    }
367618334Speter}
367718334Speter
367818334Speter/* Reverse the order of elements in the chain T of blocks,
367918334Speter   and return the new head of the chain (old last element).  */
368018334Speter
3681169702Skantree
3682132732Skanblocks_nreverse (tree t)
368318334Speter{
368490091Sobrien  tree prev = 0, decl, next;
368518334Speter  for (decl = t; decl; decl = next)
368618334Speter    {
368718334Speter      next = BLOCK_CHAIN (decl);
368818334Speter      BLOCK_CHAIN (decl) = prev;
368918334Speter      prev = decl;
369018334Speter    }
369118334Speter  return prev;
369218334Speter}
369318334Speter
369490091Sobrien/* Count the subblocks of the list starting with BLOCK.  If VECTOR is
369590091Sobrien   non-NULL, list them all into VECTOR, in a depth-first preorder
369690091Sobrien   traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
369752268Sobrien   blocks.  */
369818334Speter
369918334Speterstatic int
3700132732Skanall_blocks (tree block, tree *vector)
370118334Speter{
370252268Sobrien  int n_blocks = 0;
370318334Speter
370452268Sobrien  while (block)
370552268Sobrien    {
370652268Sobrien      TREE_ASM_WRITTEN (block) = 0;
370718334Speter
370852268Sobrien      /* Record this block.  */
370952268Sobrien      if (vector)
371052268Sobrien	vector[n_blocks] = block;
371118334Speter
371252268Sobrien      ++n_blocks;
371390091Sobrien
371452268Sobrien      /* Record the subblocks, and their subblocks...  */
371552268Sobrien      n_blocks += all_blocks (BLOCK_SUBBLOCKS (block),
371652268Sobrien			      vector ? vector + n_blocks : 0);
371752268Sobrien      block = BLOCK_CHAIN (block);
371852268Sobrien    }
371952268Sobrien
372018334Speter  return n_blocks;
372118334Speter}
372218334Speter
372390091Sobrien/* Return a vector containing all the blocks rooted at BLOCK.  The
372490091Sobrien   number of elements in the vector is stored in N_BLOCKS_P.  The
372590091Sobrien   vector is dynamically allocated; it is the caller's responsibility
372690091Sobrien   to call `free' on the pointer returned.  */
372790091Sobrien
372890091Sobrienstatic tree *
3729132732Skanget_block_vector (tree block, int *n_blocks_p)
373090091Sobrien{
373190091Sobrien  tree *block_vector;
373290091Sobrien
373390091Sobrien  *n_blocks_p = all_blocks (block, NULL);
3734169702Skan  block_vector = XNEWVEC (tree, *n_blocks_p);
373590091Sobrien  all_blocks (block, block_vector);
373690091Sobrien
373790091Sobrien  return block_vector;
373890091Sobrien}
373990091Sobrien
3740132732Skanstatic GTY(()) int next_block_index = 2;
374190091Sobrien
374290091Sobrien/* Set BLOCK_NUMBER for all the blocks in FN.  */
374390091Sobrien
374418334Spetervoid
3745132732Skannumber_blocks (tree fn)
374618334Speter{
374790091Sobrien  int i;
374890091Sobrien  int n_blocks;
374990091Sobrien  tree *block_vector;
375090091Sobrien
375190091Sobrien  /* For SDB and XCOFF debugging output, we start numbering the blocks
375290091Sobrien     from 1 within each function, rather than keeping a running
375390091Sobrien     count.  */
375490091Sobrien#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
375590091Sobrien  if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
375690091Sobrien    next_block_index = 1;
375790091Sobrien#endif
375890091Sobrien
375990091Sobrien  block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks);
376090091Sobrien
376190091Sobrien  /* The top-level BLOCK isn't numbered at all.  */
376290091Sobrien  for (i = 1; i < n_blocks; ++i)
376390091Sobrien    /* We number the blocks from two.  */
376490091Sobrien    BLOCK_NUMBER (block_vector[i]) = next_block_index++;
376590091Sobrien
376690091Sobrien  free (block_vector);
376790091Sobrien
376890091Sobrien  return;
376990091Sobrien}
377090091Sobrien
377190091Sobrien/* If VAR is present in a subblock of BLOCK, return the subblock.  */
377290091Sobrien
377390091Sobrientree
3774132732Skandebug_find_var_in_block_tree (tree var, tree block)
377590091Sobrien{
377690091Sobrien  tree t;
377790091Sobrien
377890091Sobrien  for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
377990091Sobrien    if (t == var)
378090091Sobrien      return block;
378190091Sobrien
378290091Sobrien  for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
378390091Sobrien    {
378490091Sobrien      tree ret = debug_find_var_in_block_tree (var, t);
378590091Sobrien      if (ret)
378690091Sobrien	return ret;
378790091Sobrien    }
378890091Sobrien
378990091Sobrien  return NULL_TREE;
379090091Sobrien}
379190091Sobrien
3792132732Skan/* Allocate a function structure for FNDECL and set its contents
3793132732Skan   to the defaults.  */
379490091Sobrien
3795132732Skanvoid
3796132732Skanallocate_struct_function (tree fndecl)
379790091Sobrien{
3798132732Skan  tree result;
3799169702Skan  tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE;
380090091Sobrien
3801132732Skan  cfun = ggc_alloc_cleared (sizeof (struct function));
380218334Speter
3803132732Skan  cfun->stack_alignment_needed = STACK_BOUNDARY;
3804132732Skan  cfun->preferred_stack_boundary = STACK_BOUNDARY;
380518334Speter
3806132732Skan  current_function_funcdef_no = funcdef_no++;
380718334Speter
3808132732Skan  cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
380918334Speter
3810132732Skan  init_eh_for_function ();
381118334Speter
3812169702Skan  lang_hooks.function.init (cfun);
3813132732Skan  if (init_machine_status)
3814132732Skan    cfun->machine = (*init_machine_status) ();
381518334Speter
3816132732Skan  if (fndecl == NULL)
3817132732Skan    return;
381818334Speter
3819169702Skan  DECL_STRUCT_FUNCTION (fndecl) = cfun;
3820132732Skan  cfun->decl = fndecl;
382118334Speter
3822261188Spfg  /* APPLE LOCAL begin radar 5732232 - blocks */
3823261188Spfg  /* We cannot support blocks which return aggregates because at this
3824261188Spfg     point we do not have info on the return type. */
3825261188Spfg  if (!cur_block)
3826261188Spfg  {
3827261188Spfg    result = DECL_RESULT (fndecl);
3828261188Spfg    if (aggregate_value_p (result, fndecl))
3829132732Skan    {
3830132732Skan#ifdef PCC_STATIC_STRUCT_RETURN
3831132732Skan      current_function_returns_pcc_struct = 1;
3832132732Skan#endif
3833132732Skan      current_function_returns_struct = 1;
3834132732Skan    }
3835261188Spfg    /* This code is not used anywhere ! */
3836261188Spfg    current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
3837261188Spfg  }
3838261188Spfg  /* APPLE LOCAL end radar 5732232 - blocks */
3839169702Skan  current_function_stdarg
3840169702Skan    = (fntype
3841169702Skan       && TYPE_ARG_TYPES (fntype) != 0
3842169702Skan       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3843169702Skan	   != void_type_node));
3844169702Skan
3845169702Skan  /* Assume all registers in stdarg functions need to be saved.  */
3846169702Skan  cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
3847169702Skan  cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
3848132732Skan}
384918334Speter
3850132732Skan/* Reset cfun, and other non-struct-function variables to defaults as
3851132732Skan   appropriate for emitting rtl at the start of a function.  */
385218334Speter
3853132732Skanstatic void
3854132732Skanprepare_function_start (tree fndecl)
3855132732Skan{
3856169702Skan  if (fndecl && DECL_STRUCT_FUNCTION (fndecl))
3857169702Skan    cfun = DECL_STRUCT_FUNCTION (fndecl);
3858132732Skan  else
3859132732Skan    allocate_struct_function (fndecl);
3860132732Skan  init_emit ();
3861132732Skan  init_varasm_status (cfun);
3862132732Skan  init_expr ();
386318334Speter
3864132732Skan  cse_not_expected = ! optimize;
386518334Speter
3866132732Skan  /* Caller save not needed yet.  */
3867132732Skan  caller_save_needed = 0;
386818334Speter
3869132732Skan  /* We haven't done register allocation yet.  */
3870132732Skan  reg_renumber = 0;
387118334Speter
387290091Sobrien  /* Indicate that we have not instantiated virtual registers yet.  */
387390091Sobrien  virtuals_instantiated = 0;
387490091Sobrien
387590091Sobrien  /* Indicate that we want CONCATs now.  */
387690091Sobrien  generating_concat_p = 1;
387790091Sobrien
387890091Sobrien  /* Indicate we have no need of a frame pointer yet.  */
387990091Sobrien  frame_pointer_needed = 0;
388090091Sobrien}
388190091Sobrien
388290091Sobrien/* Initialize the rtl expansion mechanism so that we can do simple things
388390091Sobrien   like generate sequences.  This is used to provide a context during global
388490091Sobrien   initialization of some passes.  */
388590091Sobrienvoid
3886132732Skaninit_dummy_function_start (void)
388790091Sobrien{
3888132732Skan  prepare_function_start (NULL);
388990091Sobrien}
389090091Sobrien
389190091Sobrien/* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
389290091Sobrien   and initialize static variables for generating RTL for the statements
389390091Sobrien   of the function.  */
389490091Sobrien
389590091Sobrienvoid
3896132732Skaninit_function_start (tree subr)
389790091Sobrien{
3898132732Skan  prepare_function_start (subr);
389990091Sobrien
3900132732Skan  /* Prevent ever trying to delete the first instruction of a
3901132732Skan     function.  Also tell final how to output a linenum before the
3902132732Skan     function prologue.  Note linenums could be missing, e.g. when
3903132732Skan     compiling a Java .class file.  */
3904169702Skan  if (! DECL_IS_BUILTIN (subr))
3905132732Skan    emit_line_note (DECL_SOURCE_LOCATION (subr));
390618334Speter
390718334Speter  /* Make sure first insn is a note even if we don't want linenums.
390818334Speter     This makes sure the first insn will never be deleted.
390918334Speter     Also, final expects a note to appear there.  */
3910132732Skan  emit_note (NOTE_INSN_DELETED);
391118334Speter
391218334Speter  /* Warn if this value is an aggregate type,
391318334Speter     regardless of which calling convention we are using for it.  */
3914169702Skan  if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
3915169702Skan    warning (OPT_Waggregate_return, "function returns an aggregate");
391690091Sobrien}
391718334Speter
391890091Sobrien/* Make sure all values used by the optimization passes have sane
391990091Sobrien   defaults.  */
3920169702Skanunsigned int
3921132732Skaninit_function_for_compilation (void)
392290091Sobrien{
392390091Sobrien  reg_renumber = 0;
392418334Speter
3925169702Skan  /* No prologue/epilogue insns yet.  Make sure that these vectors are
3926169702Skan     empty.  */
3927169702Skan  gcc_assert (VEC_length (int, prologue) == 0);
3928169702Skan  gcc_assert (VEC_length (int, epilogue) == 0);
3929169702Skan  gcc_assert (VEC_length (int, sibcall_epilogue) == 0);
3930169702Skan  return 0;
393118334Speter}
393218334Speter
3933169702Skanstruct tree_opt_pass pass_init_function =
3934169702Skan{
3935169702Skan  NULL,                                 /* name */
3936169702Skan  NULL,                                 /* gate */
3937169702Skan  init_function_for_compilation,        /* execute */
3938169702Skan  NULL,                                 /* sub */
3939169702Skan  NULL,                                 /* next */
3940169702Skan  0,                                    /* static_pass_number */
3941169702Skan  0,                                    /* tv_id */
3942169702Skan  0,                                    /* properties_required */
3943169702Skan  0,                                    /* properties_provided */
3944169702Skan  0,                                    /* properties_destroyed */
3945169702Skan  0,                                    /* todo_flags_start */
3946169702Skan  0,                                    /* todo_flags_finish */
3947169702Skan  0                                     /* letter */
3948169702Skan};
394918334Speter
395018334Speter
395118334Spetervoid
3952132732Skanexpand_main_function (void)
395318334Speter{
3954169702Skan#if (defined(INVOKE__main)				\
3955169702Skan     || (!defined(HAS_INIT_SECTION)			\
3956169702Skan	 && !defined(INIT_SECTION_ASM_OP)		\
3957169702Skan	 && !defined(INIT_ARRAY_SECTION_ASM_OP)))
3958169702Skan  emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
3959169702Skan#endif
3960169702Skan}
3961169702Skan
3962169702Skan/* Expand code to initialize the stack_protect_guard.  This is invoked at
3963169702Skan   the beginning of a function to be protected.  */
396490091Sobrien
3965169702Skan#ifndef HAVE_stack_protect_set
3966169702Skan# define HAVE_stack_protect_set		0
3967169702Skan# define gen_stack_protect_set(x,y)	(gcc_unreachable (), NULL_RTX)
396890091Sobrien#endif
3969117404Skan
3970169702Skanvoid
3971169702Skanstack_protect_prologue (void)
3972169702Skan{
3973169702Skan  tree guard_decl = targetm.stack_protect_guard ();
3974169702Skan  rtx x, y;
397590091Sobrien
3976169702Skan  /* Avoid expand_expr here, because we don't want guard_decl pulled
3977169702Skan     into registers unless absolutely necessary.  And we know that
3978169702Skan     cfun->stack_protect_guard is a local stack slot, so this skips
3979169702Skan     all the fluff.  */
3980169702Skan  x = validize_mem (DECL_RTL (cfun->stack_protect_guard));
3981169702Skan  y = validize_mem (DECL_RTL (guard_decl));
3982169702Skan
3983169702Skan  /* Allow the target to copy from Y to X without leaking Y into a
3984169702Skan     register.  */
3985169702Skan  if (HAVE_stack_protect_set)
3986169702Skan    {
3987169702Skan      rtx insn = gen_stack_protect_set (x, y);
3988169702Skan      if (insn)
3989169702Skan	{
3990169702Skan	  emit_insn (insn);
3991169702Skan	  return;
3992169702Skan	}
399390091Sobrien    }
399490091Sobrien
3995169702Skan  /* Otherwise do a straight move.  */
3996169702Skan  emit_move_insn (x, y);
399718334Speter}
399890091Sobrien
3999169702Skan/* Expand code to verify the stack_protect_guard.  This is invoked at
4000169702Skan   the end of a function to be protected.  */
4001169702Skan
4002169702Skan#ifndef HAVE_stack_protect_test
4003169702Skan# define HAVE_stack_protect_test		0
4004169702Skan# define gen_stack_protect_test(x, y, z)	(gcc_unreachable (), NULL_RTX)
4005169702Skan#endif
4006169702Skan
400790091Sobrienvoid
4008169702Skanstack_protect_epilogue (void)
400990091Sobrien{
4010169702Skan  tree guard_decl = targetm.stack_protect_guard ();
4011169702Skan  rtx label = gen_label_rtx ();
4012169702Skan  rtx x, y, tmp;
401390091Sobrien
4014169702Skan  /* Avoid expand_expr here, because we don't want guard_decl pulled
4015169702Skan     into registers unless absolutely necessary.  And we know that
4016169702Skan     cfun->stack_protect_guard is a local stack slot, so this skips
4017169702Skan     all the fluff.  */
4018169702Skan  x = validize_mem (DECL_RTL (cfun->stack_protect_guard));
4019169702Skan  y = validize_mem (DECL_RTL (guard_decl));
4020169702Skan
4021169702Skan  /* Allow the target to compare Y with X without leaking either into
4022169702Skan     a register.  */
4023222207Sbenl  if (HAVE_stack_protect_test != 0)
402490091Sobrien    {
4025169702Skan      tmp = gen_stack_protect_test (x, y, label);
4026169702Skan      if (tmp)
4027169702Skan	{
4028169702Skan	  emit_insn (tmp);
4029222207Sbenl	  goto done;
4030169702Skan	}
403190091Sobrien    }
4032169702Skan
4033222207Sbenl  emit_cmp_and_jump_insns (x, y, EQ, NULL_RTX, ptr_mode, 1, label);
4034222207Sbenl done:
4035222207Sbenl
4036169702Skan  /* The noreturn predictor has been moved to the tree level.  The rtl-level
4037169702Skan     predictors estimate this branch about 20%, which isn't enough to get
4038169702Skan     things moved out of line.  Since this is the only extant case of adding
4039169702Skan     a noreturn function at the rtl level, it doesn't seem worth doing ought
4040169702Skan     except adding the prediction by hand.  */
4041169702Skan  tmp = get_last_insn ();
4042169702Skan  if (JUMP_P (tmp))
4043169702Skan    predict_insn_def (tmp, PRED_NORETURN, TAKEN);
4044169702Skan
4045169702Skan  expand_expr_stmt (targetm.stack_protect_fail ());
4046169702Skan  emit_label (label);
404790091Sobrien}
4048169702Skan
404918334Speter/* Start the RTL for a new function, and set variables used for
405018334Speter   emitting RTL.
405118334Speter   SUBR is the FUNCTION_DECL node.
405218334Speter   PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
405318334Speter   the function's parameters, which must be run at any return statement.  */
405418334Speter
405518334Spetervoid
4056169702Skanexpand_function_start (tree subr)
405718334Speter{
405818334Speter  /* Make sure volatile mem refs aren't considered
405918334Speter     valid operands of arithmetic insns.  */
406018334Speter  init_recog_no_volatile ();
406118334Speter
406290091Sobrien  current_function_profile
406390091Sobrien    = (profile_flag
406490091Sobrien       && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
406590091Sobrien
406690091Sobrien  current_function_limit_stack
406790091Sobrien    = (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr));
406890091Sobrien
406990091Sobrien  /* Make the label for return statements to jump to.  Do not special
407090091Sobrien     case machines with special return instructions -- they will be
407190091Sobrien     handled later during jump, ifcvt, or epilogue creation.  */
407218334Speter  return_label = gen_label_rtx ();
407318334Speter
407418334Speter  /* Initialize rtx used to return the value.  */
407518334Speter  /* Do this before assign_parms so that we copy the struct value address
407618334Speter     before any library calls that assign parms might generate.  */
407718334Speter
407818334Speter  /* Decide whether to return the value in memory or in a register.  */
4079132732Skan  if (aggregate_value_p (DECL_RESULT (subr), subr))
408018334Speter    {
408118334Speter      /* Returning something that won't go in a register.  */
408290091Sobrien      rtx value_address = 0;
408318334Speter
408418334Speter#ifdef PCC_STATIC_STRUCT_RETURN
408518334Speter      if (current_function_returns_pcc_struct)
408618334Speter	{
408718334Speter	  int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
408818334Speter	  value_address = assemble_static_space (size);
408918334Speter	}
409018334Speter      else
409118334Speter#endif
409218334Speter	{
4093169702Skan	  rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 2);
409418334Speter	  /* Expect to be passed the address of a place to store the value.
409518334Speter	     If it is passed as an argument, assign_parms will take care of
409618334Speter	     it.  */
4097132732Skan	  if (sv)
409818334Speter	    {
409918334Speter	      value_address = gen_reg_rtx (Pmode);
4100132732Skan	      emit_move_insn (value_address, sv);
410118334Speter	    }
410218334Speter	}
410318334Speter      if (value_address)
410418334Speter	{
4105169702Skan	  rtx x = value_address;
4106169702Skan	  if (!DECL_BY_REFERENCE (DECL_RESULT (subr)))
4107169702Skan	    {
4108169702Skan	      x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), x);
4109169702Skan	      set_mem_attributes (x, DECL_RESULT (subr), 1);
4110169702Skan	    }
411190091Sobrien	  SET_DECL_RTL (DECL_RESULT (subr), x);
411218334Speter	}
411318334Speter    }
411418334Speter  else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
411518334Speter    /* If return mode is void, this decl rtl should not be used.  */
411690091Sobrien    SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX);
411790091Sobrien  else
411818334Speter    {
411990091Sobrien      /* Compute the return values into a pseudo reg, which we will copy
412090091Sobrien	 into the true return register after the cleanups are done.  */
4121169702Skan      tree return_type = TREE_TYPE (DECL_RESULT (subr));
4122169702Skan      if (TYPE_MODE (return_type) != BLKmode
4123169702Skan	  && targetm.calls.return_in_msb (return_type))
4124169702Skan	/* expand_function_end will insert the appropriate padding in
4125169702Skan	   this case.  Use the return value's natural (unpadded) mode
4126169702Skan	   within the function proper.  */
4127169702Skan	SET_DECL_RTL (DECL_RESULT (subr),
4128169702Skan		      gen_reg_rtx (TYPE_MODE (return_type)));
4129169702Skan      else
4130169702Skan	{
4131169702Skan	  /* In order to figure out what mode to use for the pseudo, we
4132169702Skan	     figure out what the mode of the eventual return register will
4133169702Skan	     actually be, and use that.  */
4134169702Skan	  rtx hard_reg = hard_function_value (return_type, subr, 0, 1);
413518334Speter
4136169702Skan	  /* Structures that are returned in registers are not
4137169702Skan	     aggregate_value_p, so we may see a PARALLEL or a REG.  */
4138169702Skan	  if (REG_P (hard_reg))
4139169702Skan	    SET_DECL_RTL (DECL_RESULT (subr),
4140169702Skan			  gen_reg_rtx (GET_MODE (hard_reg)));
4141169702Skan	  else
4142169702Skan	    {
4143169702Skan	      gcc_assert (GET_CODE (hard_reg) == PARALLEL);
4144169702Skan	      SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg));
4145169702Skan	    }
4146169702Skan	}
414718334Speter
4148117404Skan      /* Set DECL_REGISTER flag so that expand_function_end will copy the
4149117404Skan	 result to the real return register(s).  */
4150117404Skan      DECL_REGISTER (DECL_RESULT (subr)) = 1;
415118334Speter    }
415218334Speter
415318334Speter  /* Initialize rtx for parameters and local variables.
415418334Speter     In some cases this requires emitting insns.  */
415590091Sobrien  assign_parms (subr);
415618334Speter
4157169702Skan  /* If function gets a static chain arg, store it.  */
4158169702Skan  if (cfun->static_chain_decl)
4159169702Skan    {
4160169702Skan      tree parm = cfun->static_chain_decl;
4161169702Skan      rtx local = gen_reg_rtx (Pmode);
416218334Speter
4163169702Skan      set_decl_incoming_rtl (parm, static_chain_incoming_rtx);
4164169702Skan      SET_DECL_RTL (parm, local);
4165169702Skan      mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
416618334Speter
4167169702Skan      emit_move_insn (local, static_chain_incoming_rtx);
4168169702Skan    }
4169169702Skan
4170169702Skan  /* If the function receives a non-local goto, then store the
4171169702Skan     bits we need to restore the frame pointer.  */
4172169702Skan  if (cfun->nonlocal_goto_save_area)
4173169702Skan    {
4174169702Skan      tree t_save;
4175169702Skan      rtx r_save;
4176169702Skan
4177169702Skan      /* ??? We need to do this save early.  Unfortunately here is
4178169702Skan	 before the frame variable gets declared.  Help out...  */
4179169702Skan      expand_var (TREE_OPERAND (cfun->nonlocal_goto_save_area, 0));
4180169702Skan
4181169702Skan      t_save = build4 (ARRAY_REF, ptr_type_node,
4182169702Skan		       cfun->nonlocal_goto_save_area,
4183169702Skan		       integer_zero_node, NULL_TREE, NULL_TREE);
4184169702Skan      r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
4185169702Skan      r_save = convert_memory_address (Pmode, r_save);
4186169702Skan
4187169702Skan      emit_move_insn (r_save, virtual_stack_vars_rtx);
4188169702Skan      update_nonlocal_goto_save_area ();
4189169702Skan    }
4190169702Skan
419118334Speter  /* The following was moved from init_function_start.
419218334Speter     The move is supposed to make sdb output more accurate.  */
419318334Speter  /* Indicate the beginning of the function body,
419418334Speter     as opposed to parm setup.  */
4195132732Skan  emit_note (NOTE_INSN_FUNCTION_BEG);
419618334Speter
4197169702Skan  gcc_assert (NOTE_P (get_last_insn ()));
4198169702Skan
419918334Speter  parm_birth_insn = get_last_insn ();
420018334Speter
420196283Sobrien  if (current_function_profile)
420296283Sobrien    {
420390091Sobrien#ifdef PROFILE_HOOK
4204117404Skan      PROFILE_HOOK (current_function_funcdef_no);
420590091Sobrien#endif
420696283Sobrien    }
420790091Sobrien
4208169702Skan  /* After the display initializations is where the stack checking
4209169702Skan     probe should go.  */
4210169702Skan  if(flag_stack_check)
4211169702Skan    stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
421218334Speter
421318334Speter  /* Make sure there is a line number after the function entry setup code.  */
421418334Speter  force_next_line_note ();
421518334Speter}
421618334Speter
421790091Sobrien/* Undo the effects of init_dummy_function_start.  */
421890091Sobrienvoid
4219132732Skanexpand_dummy_function_end (void)
422090091Sobrien{
422190091Sobrien  /* End any sequences that failed to be closed due to syntax errors.  */
422290091Sobrien  while (in_sequence_p ())
422390091Sobrien    end_sequence ();
422490091Sobrien
422590091Sobrien  /* Outside function body, can't compute type's actual size
422690091Sobrien     until next function's body starts.  */
422790091Sobrien
422890091Sobrien  free_after_parsing (cfun);
422990091Sobrien  free_after_compilation (cfun);
423090091Sobrien  cfun = 0;
423190091Sobrien}
423290091Sobrien
423390091Sobrien/* Call DOIT for each hard register used as a return value from
423490091Sobrien   the current function.  */
423590091Sobrien
423690091Sobrienvoid
4237132732Skandiddle_return_value (void (*doit) (rtx, void *), void *arg)
423890091Sobrien{
423990091Sobrien  rtx outgoing = current_function_return_rtx;
424090091Sobrien
424190091Sobrien  if (! outgoing)
424290091Sobrien    return;
424390091Sobrien
4244169702Skan  if (REG_P (outgoing))
424590091Sobrien    (*doit) (outgoing, arg);
424690091Sobrien  else if (GET_CODE (outgoing) == PARALLEL)
424790091Sobrien    {
424890091Sobrien      int i;
424990091Sobrien
425090091Sobrien      for (i = 0; i < XVECLEN (outgoing, 0); i++)
425190091Sobrien	{
425290091Sobrien	  rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);
425390091Sobrien
4254169702Skan	  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
425590091Sobrien	    (*doit) (x, arg);
425690091Sobrien	}
425790091Sobrien    }
425890091Sobrien}
425990091Sobrien
426090091Sobrienstatic void
4261132732Skando_clobber_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
426290091Sobrien{
426390091Sobrien  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg));
426490091Sobrien}
426590091Sobrien
426690091Sobrienvoid
4267132732Skanclobber_return_register (void)
426890091Sobrien{
426990091Sobrien  diddle_return_value (do_clobber_return_reg, NULL);
427090091Sobrien
427190091Sobrien  /* In case we do use pseudo to return value, clobber it too.  */
427290091Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
427390091Sobrien    {
427490091Sobrien      tree decl_result = DECL_RESULT (current_function_decl);
427590091Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
427690091Sobrien      if (REG_P (decl_rtl) && REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER)
427790091Sobrien	{
427890091Sobrien	  do_clobber_return_reg (decl_rtl, NULL);
427990091Sobrien	}
428090091Sobrien    }
428190091Sobrien}
428290091Sobrien
428390091Sobrienstatic void
4284132732Skando_use_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
428590091Sobrien{
428690091Sobrien  emit_insn (gen_rtx_USE (VOIDmode, reg));
428790091Sobrien}
428890091Sobrien
4289169702Skanstatic void
4290132732Skanuse_return_register (void)
429190091Sobrien{
429290091Sobrien  diddle_return_value (do_use_return_reg, NULL);
429390091Sobrien}
429490091Sobrien
4295132732Skan/* Possibly warn about unused parameters.  */
4296132732Skanvoid
4297132732Skando_warn_unused_parameter (tree fn)
4298132732Skan{
4299132732Skan  tree decl;
4300132732Skan
4301132732Skan  for (decl = DECL_ARGUMENTS (fn);
4302132732Skan       decl; decl = TREE_CHAIN (decl))
4303132732Skan    if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
4304132732Skan	&& DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))
4305169702Skan      warning (OPT_Wunused_parameter, "unused parameter %q+D", decl);
4306132732Skan}
4307132732Skan
4308117404Skanstatic GTY(()) rtx initial_trampoline;
4309117404Skan
4310132732Skan/* Generate RTL for the end of the current function.  */
431118334Speter
431218334Spetervoid
4313132732Skanexpand_function_end (void)
431418334Speter{
431590091Sobrien  rtx clobber_after;
431618334Speter
431790091Sobrien  /* If arg_pointer_save_area was referenced only from a nested
431890091Sobrien     function, we will not have initialized it yet.  Do that now.  */
431990091Sobrien  if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init)
432090091Sobrien    get_arg_pointer_save_area (cfun);
432190091Sobrien
432252268Sobrien  /* If we are doing stack checking and this function makes calls,
432352268Sobrien     do a stack probe at the start of the function to ensure we have enough
432452268Sobrien     space for another stack frame.  */
432552268Sobrien  if (flag_stack_check && ! STACK_CHECK_BUILTIN)
432652268Sobrien    {
432752268Sobrien      rtx insn, seq;
432852268Sobrien
432952268Sobrien      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4330169702Skan	if (CALL_P (insn))
433152268Sobrien	  {
433252268Sobrien	    start_sequence ();
433352268Sobrien	    probe_stack_range (STACK_CHECK_PROTECT,
433452268Sobrien			       GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
433552268Sobrien	    seq = get_insns ();
433652268Sobrien	    end_sequence ();
4337169702Skan	    emit_insn_before (seq, stack_check_probe_note);
433852268Sobrien	    break;
433952268Sobrien	  }
434052268Sobrien    }
434152268Sobrien
4342132732Skan  /* Possibly warn about unused parameters.
4343132732Skan     When frontend does unit-at-a-time, the warning is already
4344132732Skan     issued at finalization time.  */
4345132732Skan  if (warn_unused_parameter
4346132732Skan      && !lang_hooks.callgraph.expand_function)
4347132732Skan    do_warn_unused_parameter (current_function_decl);
434818334Speter
434918334Speter  /* End any sequences that failed to be closed due to syntax errors.  */
435018334Speter  while (in_sequence_p ())
435118334Speter    end_sequence ();
435218334Speter
435318334Speter  clear_pending_stack_adjust ();
435418334Speter  do_pending_stack_adjust ();
435518334Speter
435618334Speter  /* Mark the end of the function body.
435718334Speter     If control reaches this insn, the function can drop through
435818334Speter     without returning a value.  */
4359132732Skan  emit_note (NOTE_INSN_FUNCTION_END);
436018334Speter
436152268Sobrien  /* Must mark the last line number note in the function, so that the test
436252268Sobrien     coverage code can avoid counting the last line twice.  This just tells
436352268Sobrien     the code to ignore the immediately following line note, since there
436452268Sobrien     already exists a copy of this note somewhere above.  This line number
436552268Sobrien     note is still needed for debugging though, so we can't delete it.  */
436652268Sobrien  if (flag_test_coverage)
4367132732Skan    emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
436852268Sobrien
436918334Speter  /* Output a linenumber for the end of the function.
437018334Speter     SDB depends on this.  */
4371132732Skan  force_next_line_note ();
4372132732Skan  emit_line_note (input_location);
437318334Speter
437490091Sobrien  /* Before the return label (if any), clobber the return
437590091Sobrien     registers so that they are not propagated live to the rest of
437690091Sobrien     the function.  This can only happen with functions that drop
437790091Sobrien     through; if there had been a return statement, there would
437890091Sobrien     have either been a return rtx, or a jump to the return label.
437990091Sobrien
438090091Sobrien     We delay actual code generation after the current_function_value_rtx
438190091Sobrien     is computed.  */
438290091Sobrien  clobber_after = get_last_insn ();
438390091Sobrien
4384169702Skan  /* Output the label for the actual return from the function.  */
4385169702Skan  emit_label (return_label);
438618334Speter
4387124167Sbde#ifdef TARGET_PROFILER_EPILOGUE
4388124160Skan  if (current_function_profile && TARGET_PROFILER_EPILOGUE)
4389124160Skan    {
4390124160Skan      static rtx mexitcount_libfunc;
4391124160Skan      static int initialized;
4392124160Skan
4393124160Skan      if (!initialized)
4394124160Skan	{
4395124160Skan	  mexitcount_libfunc = init_one_libfunc (".mexitcount");
4396169702Skan	  initialized = 0;
4397124160Skan	}
4398124160Skan      emit_library_call (mexitcount_libfunc, LCT_NORMAL, VOIDmode, 0);
4399124160Skan    }
4400124167Sbde#endif
4401124160Skan
4402169702Skan  if (USING_SJLJ_EXCEPTIONS)
4403132732Skan    {
4404169702Skan      /* Let except.c know where it should emit the call to unregister
4405169702Skan	 the function context for sjlj exceptions.  */
4406169702Skan      if (flag_exceptions)
4407169702Skan	sjlj_emit_function_exit_after (get_last_insn ());
4408132732Skan    }
4409169702Skan  else
4410169702Skan    {
4411169702Skan      /* @@@ This is a kludge.  We want to ensure that instructions that
4412169702Skan	 may trap are not moved into the epilogue by scheduling, because
4413169702Skan	 we don't always emit unwind information for the epilogue.
4414169702Skan	 However, not all machine descriptions define a blockage insn, so
4415169702Skan	 emit an ASM_INPUT to act as one.  */
4416169702Skan      if (flag_non_call_exceptions)
4417169702Skan	emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
4418169702Skan    }
441918334Speter
4420169702Skan  /* If this is an implementation of throw, do what's necessary to
4421169702Skan     communicate between __builtin_eh_return and the epilogue.  */
4422169702Skan  expand_eh_return ();
4423169702Skan
442490091Sobrien  /* If scalar return value was computed in a pseudo-reg, or was a named
442590091Sobrien     return value that got dumped to the stack, copy that to the hard
442690091Sobrien     return register.  */
442790091Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
442818334Speter    {
442990091Sobrien      tree decl_result = DECL_RESULT (current_function_decl);
443090091Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
443118334Speter
443290091Sobrien      if (REG_P (decl_rtl)
443390091Sobrien	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
443490091Sobrien	  : DECL_REGISTER (decl_result))
443590091Sobrien	{
443696283Sobrien	  rtx real_decl_rtl = current_function_return_rtx;
443790091Sobrien
443896283Sobrien	  /* This should be set in assign_parms.  */
4439169702Skan	  gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl));
444052268Sobrien
444190091Sobrien	  /* If this is a BLKmode structure being returned in registers,
444290091Sobrien	     then use the mode computed in expand_return.  Note that if
4443117404Skan	     decl_rtl is memory, then its mode may have been changed,
444490091Sobrien	     but that current_function_return_rtx has not.  */
444590091Sobrien	  if (GET_MODE (real_decl_rtl) == BLKmode)
444696283Sobrien	    PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl));
444790091Sobrien
4448169702Skan	  /* If a non-BLKmode return value should be padded at the least
4449169702Skan	     significant end of the register, shift it left by the appropriate
4450169702Skan	     amount.  BLKmode results are handled using the group load/store
4451169702Skan	     machinery.  */
4452169702Skan	  if (TYPE_MODE (TREE_TYPE (decl_result)) != BLKmode
4453169702Skan	      && targetm.calls.return_in_msb (TREE_TYPE (decl_result)))
4454169702Skan	    {
4455169702Skan	      emit_move_insn (gen_rtx_REG (GET_MODE (decl_rtl),
4456169702Skan					   REGNO (real_decl_rtl)),
4457169702Skan			      decl_rtl);
4458169702Skan	      shift_return_value (GET_MODE (decl_rtl), true, real_decl_rtl);
4459169702Skan	    }
446090091Sobrien	  /* If a named return value dumped decl_return to memory, then
4461117404Skan	     we may need to re-do the PROMOTE_MODE signed/unsigned
446290091Sobrien	     extension.  */
4463169702Skan	  else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
446490091Sobrien	    {
4465169702Skan	      int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
446690091Sobrien
4467132732Skan	      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
4468132732Skan		promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
4469132732Skan			      &unsignedp, 1);
447090091Sobrien
447190091Sobrien	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
447290091Sobrien	    }
447390091Sobrien	  else if (GET_CODE (real_decl_rtl) == PARALLEL)
4474117404Skan	    {
4475117404Skan	      /* If expand_function_start has created a PARALLEL for decl_rtl,
4476117404Skan		 move the result to the real return registers.  Otherwise, do
4477117404Skan		 a group load from decl_rtl for a named return.  */
4478117404Skan	      if (GET_CODE (decl_rtl) == PARALLEL)
4479117404Skan		emit_group_move (real_decl_rtl, decl_rtl);
4480117404Skan	      else
4481117404Skan		emit_group_load (real_decl_rtl, decl_rtl,
4482132732Skan				 TREE_TYPE (decl_result),
4483117404Skan				 int_size_in_bytes (TREE_TYPE (decl_result)));
4484117404Skan	    }
4485169702Skan	  /* In the case of complex integer modes smaller than a word, we'll
4486169702Skan	     need to generate some non-trivial bitfield insertions.  Do that
4487169702Skan	     on a pseudo and not the hard register.  */
4488169702Skan	  else if (GET_CODE (decl_rtl) == CONCAT
4489169702Skan		   && GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT
4490169702Skan		   && GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD)
4491169702Skan	    {
4492169702Skan	      int old_generating_concat_p;
4493169702Skan	      rtx tmp;
4494169702Skan
4495169702Skan	      old_generating_concat_p = generating_concat_p;
4496169702Skan	      generating_concat_p = 0;
4497169702Skan	      tmp = gen_reg_rtx (GET_MODE (decl_rtl));
4498169702Skan	      generating_concat_p = old_generating_concat_p;
4499169702Skan
4500169702Skan	      emit_move_insn (tmp, decl_rtl);
4501169702Skan	      emit_move_insn (real_decl_rtl, tmp);
4502169702Skan	    }
450390091Sobrien	  else
450490091Sobrien	    emit_move_insn (real_decl_rtl, decl_rtl);
450590091Sobrien	}
450618334Speter    }
450718334Speter
450818334Speter  /* If returning a structure, arrange to return the address of the value
450918334Speter     in a place where debuggers expect to find it.
451018334Speter
451118334Speter     If returning a structure PCC style,
451218334Speter     the caller also depends on this value.
451318334Speter     And current_function_returns_pcc_struct is not necessarily set.  */
451418334Speter  if (current_function_returns_struct
451518334Speter      || current_function_returns_pcc_struct)
451618334Speter    {
4517169702Skan      rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl));
451818334Speter      tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
4519169702Skan      rtx outgoing;
452018334Speter
4521169702Skan      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
4522169702Skan	type = TREE_TYPE (type);
4523169702Skan      else
4524169702Skan	value_address = XEXP (value_address, 0);
4525169702Skan
4526169702Skan      outgoing = targetm.calls.function_value (build_pointer_type (type),
4527169702Skan					       current_function_decl, true);
4528169702Skan
452918334Speter      /* Mark this as a function return value so integrate will delete the
453018334Speter	 assignment and USE below when inlining this function.  */
453118334Speter      REG_FUNCTION_VALUE_P (outgoing) = 1;
453218334Speter
453390091Sobrien      /* The address may be ptr_mode and OUTGOING may be Pmode.  */
4534132732Skan      value_address = convert_memory_address (GET_MODE (outgoing),
4535132732Skan					      value_address);
453690091Sobrien
453718334Speter      emit_move_insn (outgoing, value_address);
453890091Sobrien
453990091Sobrien      /* Show return register used to hold result (in this case the address
454090091Sobrien	 of the result.  */
454190091Sobrien      current_function_return_rtx = outgoing;
454218334Speter    }
454318334Speter
454490091Sobrien  /* Emit the actual code to clobber return register.  */
454590091Sobrien  {
4546169702Skan    rtx seq;
4547117404Skan
454890091Sobrien    start_sequence ();
454990091Sobrien    clobber_return_register ();
4550169702Skan    expand_naked_return ();
4551117404Skan    seq = get_insns ();
455290091Sobrien    end_sequence ();
455318334Speter
4554169702Skan    emit_insn_after (seq, clobber_after);
455590091Sobrien  }
455618334Speter
4557169702Skan  /* Output the label for the naked return from the function.  */
4558169702Skan  emit_label (naked_return_label);
4559132732Skan
4560169702Skan  /* If stack protection is enabled for this function, check the guard.  */
4561169702Skan  if (cfun->stack_protect_guard)
4562169702Skan    stack_protect_epilogue ();
4563169702Skan
4564169702Skan  /* If we had calls to alloca, and this machine needs
4565169702Skan     an accurate stack pointer to exit the function,
4566169702Skan     insert some code to save and restore the stack pointer.  */
4567169702Skan  if (! EXIT_IGNORE_STACK
4568169702Skan      && current_function_calls_alloca)
4569169702Skan    {
4570169702Skan      rtx tem = 0;
4571169702Skan
4572169702Skan      emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
4573169702Skan      emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
4574169702Skan    }
4575169702Skan
457690091Sobrien  /* ??? This should no longer be necessary since stupid is no longer with
457790091Sobrien     us, but there are some parts of the compiler (eg reload_combine, and
457890091Sobrien     sh mach_dep_reorg) that still try and compute their own lifetime info
457990091Sobrien     instead of using the general framework.  */
458090091Sobrien  use_return_register ();
458118334Speter}
458218334Speter
458390091Sobrienrtx
4584132732Skanget_arg_pointer_save_area (struct function *f)
458590091Sobrien{
458690091Sobrien  rtx ret = f->x_arg_pointer_save_area;
458718334Speter
458890091Sobrien  if (! ret)
458990091Sobrien    {
459090091Sobrien      ret = assign_stack_local_1 (Pmode, GET_MODE_SIZE (Pmode), 0, f);
459190091Sobrien      f->x_arg_pointer_save_area = ret;
459290091Sobrien    }
459318334Speter
459490091Sobrien  if (f == cfun && ! f->arg_pointer_save_area_init)
459590091Sobrien    {
459690091Sobrien      rtx seq;
459790091Sobrien
4598117404Skan      /* Save the arg pointer at the beginning of the function.  The
459990091Sobrien	 generated stack slot may not be a valid memory address, so we
460090091Sobrien	 have to check it and fix it if necessary.  */
460190091Sobrien      start_sequence ();
460290091Sobrien      emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx);
4603117404Skan      seq = get_insns ();
460490091Sobrien      end_sequence ();
460590091Sobrien
460690091Sobrien      push_topmost_sequence ();
4607169702Skan      emit_insn_after (seq, entry_of_function ());
460890091Sobrien      pop_topmost_sequence ();
460990091Sobrien    }
461090091Sobrien
461190091Sobrien  return ret;
461290091Sobrien}
461390091Sobrien
4614117404Skan/* Extend a vector that records the INSN_UIDs of INSNS
4615117404Skan   (a list of one or more insns).  */
461690091Sobrien
461790091Sobrienstatic void
4618169702Skanrecord_insns (rtx insns, VEC(int,heap) **vecp)
461918334Speter{
4620117404Skan  rtx tmp;
4621117404Skan
4622169702Skan  for (tmp = insns; tmp != NULL_RTX; tmp = NEXT_INSN (tmp))
4623169702Skan    VEC_safe_push (int, heap, *vecp, INSN_UID (tmp));
462418334Speter}
462518334Speter
4626132732Skan/* Set the locator of the insn chain starting at INSN to LOC.  */
4627132732Skanstatic void
4628132732Skanset_insn_locators (rtx insn, int loc)
4629132732Skan{
4630132732Skan  while (insn != NULL_RTX)
4631132732Skan    {
4632132732Skan      if (INSN_P (insn))
4633132732Skan	INSN_LOCATOR (insn) = loc;
4634132732Skan      insn = NEXT_INSN (insn);
4635132732Skan    }
4636132732Skan}
4637132732Skan
4638117404Skan/* Determine how many INSN_UIDs in VEC are part of INSN.  Because we can
4639117404Skan   be running after reorg, SEQUENCE rtl is possible.  */
464018334Speter
464118334Speterstatic int
4642169702Skancontains (rtx insn, VEC(int,heap) **vec)
464318334Speter{
464490091Sobrien  int i, j;
464518334Speter
4646169702Skan  if (NONJUMP_INSN_P (insn)
464718334Speter      && GET_CODE (PATTERN (insn)) == SEQUENCE)
464818334Speter    {
464918334Speter      int count = 0;
465018334Speter      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
4651169702Skan	for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
4652169702Skan	  if (INSN_UID (XVECEXP (PATTERN (insn), 0, i))
4653169702Skan	      == VEC_index (int, *vec, j))
465418334Speter	    count++;
465518334Speter      return count;
465618334Speter    }
465718334Speter  else
465818334Speter    {
4659169702Skan      for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
4660169702Skan	if (INSN_UID (insn) == VEC_index (int, *vec, j))
466118334Speter	  return 1;
466218334Speter    }
466318334Speter  return 0;
466418334Speter}
466518334Speter
466690091Sobrienint
4667132732Skanprologue_epilogue_contains (rtx insn)
466890091Sobrien{
4669169702Skan  if (contains (insn, &prologue))
467090091Sobrien    return 1;
4671169702Skan  if (contains (insn, &epilogue))
467290091Sobrien    return 1;
467390091Sobrien  return 0;
467490091Sobrien}
467590091Sobrien
467690091Sobrienint
4677132732Skansibcall_epilogue_contains (rtx insn)
467890091Sobrien{
467990091Sobrien  if (sibcall_epilogue)
4680169702Skan    return contains (insn, &sibcall_epilogue);
468190091Sobrien  return 0;
468290091Sobrien}
468390091Sobrien
468490091Sobrien#ifdef HAVE_return
468590091Sobrien/* Insert gen_return at the end of block BB.  This also means updating
468690091Sobrien   block_for_insn appropriately.  */
468790091Sobrien
468890091Sobrienstatic void
4689132732Skanemit_return_into_block (basic_block bb, rtx line_note)
469090091Sobrien{
4691132732Skan  emit_jump_insn_after (gen_return (), BB_END (bb));
469290091Sobrien  if (line_note)
4693132732Skan    emit_note_copy_after (line_note, PREV_INSN (BB_END (bb)));
469490091Sobrien}
469590091Sobrien#endif /* HAVE_return */
469690091Sobrien
469790091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
469890091Sobrien
4699169702Skan/* These functions convert the epilogue into a variant that does not
4700169702Skan   modify the stack pointer.  This is used in cases where a function
4701169702Skan   returns an object whose size is not known until it is computed.
4702169702Skan   The called function leaves the object on the stack, leaves the
4703169702Skan   stack depressed, and returns a pointer to the object.
470490091Sobrien
4705169702Skan   What we need to do is track all modifications and references to the
4706169702Skan   stack pointer, deleting the modifications and changing the
4707169702Skan   references to point to the location the stack pointer would have
4708169702Skan   pointed to had the modifications taken place.
470990091Sobrien
4710169702Skan   These functions need to be portable so we need to make as few
4711169702Skan   assumptions about the epilogue as we can.  However, the epilogue
4712169702Skan   basically contains three things: instructions to reset the stack
4713169702Skan   pointer, instructions to reload registers, possibly including the
4714169702Skan   frame pointer, and an instruction to return to the caller.
471590091Sobrien
4716169702Skan   We must be sure of what a relevant epilogue insn is doing.  We also
4717169702Skan   make no attempt to validate the insns we make since if they are
4718169702Skan   invalid, we probably can't do anything valid.  The intent is that
4719169702Skan   these routines get "smarter" as more and more machines start to use
4720169702Skan   them and they try operating on different epilogues.
472190091Sobrien
4722169702Skan   We use the following structure to track what the part of the
4723169702Skan   epilogue that we've already processed has done.  We keep two copies
4724169702Skan   of the SP equivalence, one for use during the insn we are
4725169702Skan   processing and one for use in the next insn.  The difference is
4726169702Skan   because one part of a PARALLEL may adjust SP and the other may use
4727169702Skan   it.  */
472890091Sobrien
472990091Sobrienstruct epi_info
473090091Sobrien{
473190091Sobrien  rtx sp_equiv_reg;		/* REG that SP is set from, perhaps SP.  */
473290091Sobrien  HOST_WIDE_INT sp_offset;	/* Offset from SP_EQUIV_REG of present SP.  */
473390091Sobrien  rtx new_sp_equiv_reg;		/* REG to be used at end of insn.  */
473490091Sobrien  HOST_WIDE_INT new_sp_offset;	/* Offset to be used at end of insn.  */
473590091Sobrien  rtx equiv_reg_src;		/* If nonzero, the value that SP_EQUIV_REG
473690091Sobrien				   should be set to once we no longer need
473790091Sobrien				   its value.  */
4738132732Skan  rtx const_equiv[FIRST_PSEUDO_REGISTER]; /* Any known constant equivalences
4739132732Skan					     for registers.  */
474090091Sobrien};
474190091Sobrien
4742132732Skanstatic void handle_epilogue_set (rtx, struct epi_info *);
4743132732Skanstatic void update_epilogue_consts (rtx, rtx, void *);
4744132732Skanstatic void emit_equiv_load (struct epi_info *);
474590091Sobrien
4746117404Skan/* Modify INSN, a list of one or more insns that is part of the epilogue, to
4747117404Skan   no modifications to the stack pointer.  Return the new list of insns.  */
474890091Sobrien
474990091Sobrienstatic rtx
4750132732Skankeep_stack_depressed (rtx insns)
475190091Sobrien{
4752117404Skan  int j;
475390091Sobrien  struct epi_info info;
4754117404Skan  rtx insn, next;
475590091Sobrien
4756132732Skan  /* If the epilogue is just a single instruction, it must be OK as is.  */
4757117404Skan  if (NEXT_INSN (insns) == NULL_RTX)
4758117404Skan    return insns;
475990091Sobrien
476090091Sobrien  /* Otherwise, start a sequence, initialize the information we have, and
476190091Sobrien     process all the insns we were given.  */
476290091Sobrien  start_sequence ();
476390091Sobrien
476490091Sobrien  info.sp_equiv_reg = stack_pointer_rtx;
476590091Sobrien  info.sp_offset = 0;
476690091Sobrien  info.equiv_reg_src = 0;
476790091Sobrien
4768132732Skan  for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
4769132732Skan    info.const_equiv[j] = 0;
4770132732Skan
4771117404Skan  insn = insns;
4772117404Skan  next = NULL_RTX;
4773117404Skan  while (insn != NULL_RTX)
477490091Sobrien    {
4775117404Skan      next = NEXT_INSN (insn);
477690091Sobrien
477790091Sobrien      if (!INSN_P (insn))
477890091Sobrien	{
477990091Sobrien	  add_insn (insn);
4780117404Skan	  insn = next;
478190091Sobrien	  continue;
478290091Sobrien	}
478390091Sobrien
478490091Sobrien      /* If this insn references the register that SP is equivalent to and
478590091Sobrien	 we have a pending load to that register, we must force out the load
478690091Sobrien	 first and then indicate we no longer know what SP's equivalent is.  */
478790091Sobrien      if (info.equiv_reg_src != 0
478890091Sobrien	  && reg_referenced_p (info.sp_equiv_reg, PATTERN (insn)))
478990091Sobrien	{
479090091Sobrien	  emit_equiv_load (&info);
479190091Sobrien	  info.sp_equiv_reg = 0;
479290091Sobrien	}
479390091Sobrien
479490091Sobrien      info.new_sp_equiv_reg = info.sp_equiv_reg;
479590091Sobrien      info.new_sp_offset = info.sp_offset;
479690091Sobrien
479790091Sobrien      /* If this is a (RETURN) and the return address is on the stack,
479890091Sobrien	 update the address and change to an indirect jump.  */
479990091Sobrien      if (GET_CODE (PATTERN (insn)) == RETURN
480090091Sobrien	  || (GET_CODE (PATTERN (insn)) == PARALLEL
480190091Sobrien	      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == RETURN))
480290091Sobrien	{
480390091Sobrien	  rtx retaddr = INCOMING_RETURN_ADDR_RTX;
480490091Sobrien	  rtx base = 0;
480590091Sobrien	  HOST_WIDE_INT offset = 0;
480690091Sobrien	  rtx jump_insn, jump_set;
480790091Sobrien
480890091Sobrien	  /* If the return address is in a register, we can emit the insn
480990091Sobrien	     unchanged.  Otherwise, it must be a MEM and we see what the
481090091Sobrien	     base register and offset are.  In any case, we have to emit any
481190091Sobrien	     pending load to the equivalent reg of SP, if any.  */
4812169702Skan	  if (REG_P (retaddr))
481390091Sobrien	    {
481490091Sobrien	      emit_equiv_load (&info);
481590091Sobrien	      add_insn (insn);
4816117404Skan	      insn = next;
481790091Sobrien	      continue;
481890091Sobrien	    }
4819169702Skan	  else
482090091Sobrien	    {
4821169702Skan	      rtx ret_ptr;
4822169702Skan	      gcc_assert (MEM_P (retaddr));
4823169702Skan
4824169702Skan	      ret_ptr = XEXP (retaddr, 0);
4825169702Skan
4826169702Skan	      if (REG_P (ret_ptr))
4827169702Skan		{
4828169702Skan		  base = gen_rtx_REG (Pmode, REGNO (ret_ptr));
4829169702Skan		  offset = 0;
4830169702Skan		}
4831169702Skan	      else
4832169702Skan		{
4833169702Skan		  gcc_assert (GET_CODE (ret_ptr) == PLUS
4834169702Skan			      && REG_P (XEXP (ret_ptr, 0))
4835169702Skan			      && GET_CODE (XEXP (ret_ptr, 1)) == CONST_INT);
4836169702Skan		  base = gen_rtx_REG (Pmode, REGNO (XEXP (ret_ptr, 0)));
4837169702Skan		  offset = INTVAL (XEXP (ret_ptr, 1));
4838169702Skan		}
483990091Sobrien	    }
484090091Sobrien
484190091Sobrien	  /* If the base of the location containing the return pointer
484290091Sobrien	     is SP, we must update it with the replacement address.  Otherwise,
484390091Sobrien	     just build the necessary MEM.  */
484490091Sobrien	  retaddr = plus_constant (base, offset);
484590091Sobrien	  if (base == stack_pointer_rtx)
484690091Sobrien	    retaddr = simplify_replace_rtx (retaddr, stack_pointer_rtx,
484790091Sobrien					    plus_constant (info.sp_equiv_reg,
484890091Sobrien							   info.sp_offset));
484990091Sobrien
485090091Sobrien	  retaddr = gen_rtx_MEM (Pmode, retaddr);
4851169702Skan	  MEM_NOTRAP_P (retaddr) = 1;
485290091Sobrien
485390091Sobrien	  /* If there is a pending load to the equivalent register for SP
485490091Sobrien	     and we reference that register, we must load our address into
485590091Sobrien	     a scratch register and then do that load.  */
485690091Sobrien	  if (info.equiv_reg_src
485790091Sobrien	      && reg_overlap_mentioned_p (info.equiv_reg_src, retaddr))
485890091Sobrien	    {
485990091Sobrien	      unsigned int regno;
486090091Sobrien	      rtx reg;
486190091Sobrien
486290091Sobrien	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
486390091Sobrien		if (HARD_REGNO_MODE_OK (regno, Pmode)
486490091Sobrien		    && !fixed_regs[regno]
486590091Sobrien		    && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
4866169702Skan		    && !REGNO_REG_SET_P
4867169702Skan		         (EXIT_BLOCK_PTR->il.rtl->global_live_at_start, regno)
486890091Sobrien		    && !refers_to_regno_p (regno,
4869169702Skan					   regno + hard_regno_nregs[regno]
4870169702Skan								   [Pmode],
4871132732Skan					   info.equiv_reg_src, NULL)
4872132732Skan		    && info.const_equiv[regno] == 0)
487390091Sobrien		  break;
487490091Sobrien
4875169702Skan	      gcc_assert (regno < FIRST_PSEUDO_REGISTER);
487690091Sobrien
487790091Sobrien	      reg = gen_rtx_REG (Pmode, regno);
487890091Sobrien	      emit_move_insn (reg, retaddr);
487990091Sobrien	      retaddr = reg;
488090091Sobrien	    }
488190091Sobrien
488290091Sobrien	  emit_equiv_load (&info);
488390091Sobrien	  jump_insn = emit_jump_insn (gen_indirect_jump (retaddr));
488490091Sobrien
488590091Sobrien	  /* Show the SET in the above insn is a RETURN.  */
488690091Sobrien	  jump_set = single_set (jump_insn);
4887169702Skan	  gcc_assert (jump_set);
4888169702Skan	  SET_IS_RETURN_P (jump_set) = 1;
488990091Sobrien	}
489090091Sobrien
489190091Sobrien      /* If SP is not mentioned in the pattern and its equivalent register, if
489290091Sobrien	 any, is not modified, just emit it.  Otherwise, if neither is set,
489390091Sobrien	 replace the reference to SP and emit the insn.  If none of those are
489490091Sobrien	 true, handle each SET individually.  */
489590091Sobrien      else if (!reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))
489690091Sobrien	       && (info.sp_equiv_reg == stack_pointer_rtx
489790091Sobrien		   || !reg_set_p (info.sp_equiv_reg, insn)))
489890091Sobrien	add_insn (insn);
489990091Sobrien      else if (! reg_set_p (stack_pointer_rtx, insn)
490090091Sobrien	       && (info.sp_equiv_reg == stack_pointer_rtx
490190091Sobrien		   || !reg_set_p (info.sp_equiv_reg, insn)))
490290091Sobrien	{
4903169702Skan	  int changed;
490490091Sobrien
4905169702Skan	  changed = validate_replace_rtx (stack_pointer_rtx,
4906169702Skan					  plus_constant (info.sp_equiv_reg,
4907169702Skan							 info.sp_offset),
4908169702Skan					  insn);
4909169702Skan	  gcc_assert (changed);
4910169702Skan
491190091Sobrien	  add_insn (insn);
491290091Sobrien	}
491390091Sobrien      else if (GET_CODE (PATTERN (insn)) == SET)
491490091Sobrien	handle_epilogue_set (PATTERN (insn), &info);
491590091Sobrien      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
491690091Sobrien	{
491790091Sobrien	  for (j = 0; j < XVECLEN (PATTERN (insn), 0); j++)
491890091Sobrien	    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET)
491990091Sobrien	      handle_epilogue_set (XVECEXP (PATTERN (insn), 0, j), &info);
492090091Sobrien	}
492190091Sobrien      else
492290091Sobrien	add_insn (insn);
492390091Sobrien
492490091Sobrien      info.sp_equiv_reg = info.new_sp_equiv_reg;
492590091Sobrien      info.sp_offset = info.new_sp_offset;
4926117404Skan
4927132732Skan      /* Now update any constants this insn sets.  */
4928132732Skan      note_stores (PATTERN (insn), update_epilogue_consts, &info);
4929117404Skan      insn = next;
493090091Sobrien    }
493190091Sobrien
4932117404Skan  insns = get_insns ();
493390091Sobrien  end_sequence ();
4934117404Skan  return insns;
493590091Sobrien}
493690091Sobrien
493790091Sobrien/* SET is a SET from an insn in the epilogue.  P is a pointer to the epi_info
493890091Sobrien   structure that contains information about what we've seen so far.  We
4939117404Skan   process this SET by either updating that data or by emitting one or
494090091Sobrien   more insns.  */
494190091Sobrien
494290091Sobrienstatic void
4943132732Skanhandle_epilogue_set (rtx set, struct epi_info *p)
494490091Sobrien{
494590091Sobrien  /* First handle the case where we are setting SP.  Record what it is being
4946169702Skan     set from, which we must be able to determine  */
494790091Sobrien  if (reg_set_p (stack_pointer_rtx, set))
494890091Sobrien    {
4949169702Skan      gcc_assert (SET_DEST (set) == stack_pointer_rtx);
495090091Sobrien
4951132732Skan      if (GET_CODE (SET_SRC (set)) == PLUS)
495290091Sobrien	{
495390091Sobrien	  p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
4954132732Skan	  if (GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
4955132732Skan	    p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
4956132732Skan	  else
4957169702Skan	    {
4958169702Skan	      gcc_assert (REG_P (XEXP (SET_SRC (set), 1))
4959169702Skan			  && (REGNO (XEXP (SET_SRC (set), 1))
4960169702Skan			      < FIRST_PSEUDO_REGISTER)
4961169702Skan			  && p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
4962169702Skan	      p->new_sp_offset
4963169702Skan		= INTVAL (p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
4964169702Skan	    }
496590091Sobrien	}
496690091Sobrien      else
496790091Sobrien	p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0;
496890091Sobrien
496990091Sobrien      /* If we are adjusting SP, we adjust from the old data.  */
497090091Sobrien      if (p->new_sp_equiv_reg == stack_pointer_rtx)
497190091Sobrien	{
497290091Sobrien	  p->new_sp_equiv_reg = p->sp_equiv_reg;
497390091Sobrien	  p->new_sp_offset += p->sp_offset;
497490091Sobrien	}
497590091Sobrien
4976169702Skan      gcc_assert (p->new_sp_equiv_reg && REG_P (p->new_sp_equiv_reg));
497790091Sobrien
497890091Sobrien      return;
497990091Sobrien    }
498090091Sobrien
4981169702Skan  /* Next handle the case where we are setting SP's equivalent
4982169702Skan     register.  We must not already have a value to set it to.  We
4983169702Skan     could update, but there seems little point in handling that case.
4984169702Skan     Note that we have to allow for the case where we are setting the
4985169702Skan     register set in the previous part of a PARALLEL inside a single
4986169702Skan     insn.  But use the old offset for any updates within this insn.
4987169702Skan     We must allow for the case where the register is being set in a
4988169702Skan     different (usually wider) mode than Pmode).  */
498990091Sobrien  else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
499090091Sobrien    {
4991169702Skan      gcc_assert (!p->equiv_reg_src
4992169702Skan		  && REG_P (p->new_sp_equiv_reg)
4993169702Skan		  && REG_P (SET_DEST (set))
4994169702Skan		  && (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set)))
4995169702Skan		      <= BITS_PER_WORD)
4996169702Skan		  && REGNO (p->new_sp_equiv_reg) == REGNO (SET_DEST (set)));
4997169702Skan      p->equiv_reg_src
4998169702Skan	= simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
4999169702Skan				plus_constant (p->sp_equiv_reg,
5000169702Skan					       p->sp_offset));
500190091Sobrien    }
500290091Sobrien
500390091Sobrien  /* Otherwise, replace any references to SP in the insn to its new value
500490091Sobrien     and emit the insn.  */
500590091Sobrien  else
500690091Sobrien    {
500790091Sobrien      SET_SRC (set) = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
500890091Sobrien					    plus_constant (p->sp_equiv_reg,
500990091Sobrien							   p->sp_offset));
501090091Sobrien      SET_DEST (set) = simplify_replace_rtx (SET_DEST (set), stack_pointer_rtx,
501190091Sobrien					     plus_constant (p->sp_equiv_reg,
501290091Sobrien							    p->sp_offset));
501390091Sobrien      emit_insn (set);
501490091Sobrien    }
501590091Sobrien}
501690091Sobrien
5017132732Skan/* Update the tracking information for registers set to constants.  */
5018132732Skan
5019132732Skanstatic void
5020132732Skanupdate_epilogue_consts (rtx dest, rtx x, void *data)
5021132732Skan{
5022132732Skan  struct epi_info *p = (struct epi_info *) data;
5023169702Skan  rtx new;
5024132732Skan
5025169702Skan  if (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER)
5026132732Skan    return;
5027169702Skan
5028169702Skan  /* If we are either clobbering a register or doing a partial set,
5029169702Skan     show we don't know the value.  */
5030169702Skan  else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x)))
5031132732Skan    p->const_equiv[REGNO (dest)] = 0;
5032169702Skan
5033169702Skan  /* If we are setting it to a constant, record that constant.  */
5034169702Skan  else if (GET_CODE (SET_SRC (x)) == CONST_INT)
5035169702Skan    p->const_equiv[REGNO (dest)] = SET_SRC (x);
5036169702Skan
5037169702Skan  /* If this is a binary operation between a register we have been tracking
5038169702Skan     and a constant, see if we can compute a new constant value.  */
5039169702Skan  else if (ARITHMETIC_P (SET_SRC (x))
5040169702Skan	   && REG_P (XEXP (SET_SRC (x), 0))
5041169702Skan	   && REGNO (XEXP (SET_SRC (x), 0)) < FIRST_PSEUDO_REGISTER
5042169702Skan	   && p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))] != 0
5043169702Skan	   && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
5044169702Skan	   && 0 != (new = simplify_binary_operation
5045169702Skan		    (GET_CODE (SET_SRC (x)), GET_MODE (dest),
5046169702Skan		     p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))],
5047169702Skan		     XEXP (SET_SRC (x), 1)))
5048169702Skan	   && GET_CODE (new) == CONST_INT)
5049169702Skan    p->const_equiv[REGNO (dest)] = new;
5050169702Skan
5051169702Skan  /* Otherwise, we can't do anything with this value.  */
5052132732Skan  else
5053169702Skan    p->const_equiv[REGNO (dest)] = 0;
5054132732Skan}
5055132732Skan
505690091Sobrien/* Emit an insn to do the load shown in p->equiv_reg_src, if needed.  */
505790091Sobrien
505890091Sobrienstatic void
5059132732Skanemit_equiv_load (struct epi_info *p)
506090091Sobrien{
506190091Sobrien  if (p->equiv_reg_src != 0)
5062132732Skan    {
5063132732Skan      rtx dest = p->sp_equiv_reg;
506490091Sobrien
5065132732Skan      if (GET_MODE (p->equiv_reg_src) != GET_MODE (dest))
5066132732Skan	dest = gen_rtx_REG (GET_MODE (p->equiv_reg_src),
5067132732Skan			    REGNO (p->sp_equiv_reg));
5068132732Skan
5069132732Skan      emit_move_insn (dest, p->equiv_reg_src);
5070132732Skan      p->equiv_reg_src = 0;
5071132732Skan    }
507290091Sobrien}
507390091Sobrien#endif
507490091Sobrien
5075261188Spfg/* APPLE LOCAL begin radar 6163705, Blocks prologues  */
5076261188Spfg
5077261188Spfg/* The function should only be called for Blocks functions.
5078261188Spfg
5079261188Spfg   On being called, the main instruction list for the Blocks function
5080261188Spfg   may contain instructions for setting up the ref_decl and byref_decl
5081261188Spfg   variables in the Block.  Those isns really need to go before the
5082261188Spfg   function prologue note rather than after.  If such instructions are
5083261188Spfg   present, they are identifiable by their source line number, which
5084261188Spfg   will be one line preceding the declaration of the function.  If
5085261188Spfg   they are present, there will also be a source line note instruction
5086261188Spfg   for that line.
5087261188Spfg
5088261188Spfg   This function does a set of things:
5089261188Spfg   - It finds the first such prologue insn.
5090261188Spfg   - It finds the last such prologue insn.
5091261188Spfg   - It changes the insn locator of all such prologue insns to
5092261188Spfg     the prologue locator.
5093261188Spfg   - It finds the source line note for the bogus location and
5094261188Spfg     removes it.
5095261188Spfg   - It decides if it is safe to place the prolgoue end note
5096261188Spfg     after the last prologue insn it finds, and if so, returns
5097261188Spfg     the last prologue insn (otherwise it returns NULL).
5098261188Spfg
5099261188Spfg   This function makes the following checks to determine if it is
5100261188Spfg   safe to move the prologue end note to just below the last
5101261188Spfg   prologue insn it finds.  If ALL of the checks succeed then it
5102261188Spfg   is safe.  If any check fails, this function returns NULL.  The
5103261188Spfg   checks it makes are:
5104261188Spfg
5105261188Spfg	- There were no INSN_P instructions that occurred before the
5106261188Spfg	  first prologue insn.
5107261188Spfg	- If there are any non-prologue insns between the first & last
5108261188Spfg	  prologue insn, the non-prologue insns do not outnumber the
5109261188Spfg	 prologue insns.
5110261188Spfg	- The first prologue insn & the last prologue insn are in the
5111261188Spfg	  same basic block.
5112261188Spfg*/
5113261188Spfg
5114261188Spfgstatic rtx
5115261188Spfgfind_block_prologue_insns (void)
5116261188Spfg{
5117261188Spfg  rtx first_prologue_insn = NULL;
5118261188Spfg  rtx last_prologue_insn = NULL;
5119261188Spfg  rtx line_number_note = NULL;
5120261188Spfg  rtx tmp_insn;
5121261188Spfg  int num_prologue_insns = 0;
5122261188Spfg  int total_insns = 0;
5123261188Spfg  int prologue_line = DECL_SOURCE_LINE (cfun->decl) - 1;
5124261188Spfg  bool other_insns_before_prologue = false;
5125261188Spfg  bool start_of_fnbody_found = false;
5126261188Spfg
5127261188Spfg  /* Go through all the insns and find the first prologue insn, the
5128261188Spfg     last prologue insn, the source line location note, and whether or
5129261188Spfg     not there are any "real" insns that occur before the first
5130261188Spfg     prologue insn.  Re-set the insn locator for prologue insns to the
5131261188Spfg     prologue locator.  */
5132261188Spfg
5133261188Spfg  for (tmp_insn = get_insns(); tmp_insn; tmp_insn = NEXT_INSN (tmp_insn))
5134261188Spfg    {
5135261188Spfg      if (INSN_P (tmp_insn))
5136261188Spfg	{
5137261188Spfg	  if (insn_line (tmp_insn) == prologue_line)
5138261188Spfg	    {
5139261188Spfg	      if (!first_prologue_insn)
5140261188Spfg		first_prologue_insn = tmp_insn;
5141261188Spfg	      num_prologue_insns++;
5142261188Spfg	      last_prologue_insn = tmp_insn;
5143261188Spfg	      INSN_LOCATOR (tmp_insn) = prologue_locator;
5144261188Spfg	    }
5145261188Spfg	  else if (!first_prologue_insn
5146261188Spfg		   && start_of_fnbody_found)
5147261188Spfg	    other_insns_before_prologue = true;
5148261188Spfg	}
5149261188Spfg      else if (NOTE_P (tmp_insn)
5150261188Spfg	       && NOTE_LINE_NUMBER (tmp_insn) == NOTE_INSN_FUNCTION_BEG)
5151261188Spfg	start_of_fnbody_found = true;
5152261188Spfg      else if (NOTE_P (tmp_insn)
5153261188Spfg	       && (XINT (tmp_insn, 5) == prologue_line))
5154261188Spfg	line_number_note = tmp_insn;
5155261188Spfg    }
5156261188Spfg
5157261188Spfg  /* If there were no prologue insns, return now.  */
5158261188Spfg
5159261188Spfg  if (!first_prologue_insn)
5160261188Spfg    return NULL;
5161261188Spfg
5162261188Spfg  /* If the source location note for the line before the beginning of the
5163261188Spfg     function was found, remove it.  */
5164261188Spfg
5165261188Spfg  if (line_number_note)
5166261188Spfg    remove_insn (line_number_note);
5167261188Spfg
5168261188Spfg  /* If other real insns got moved above the prologue insns, we can't
5169261188Spfg     pull out the prologue insns, so return now.  */
5170261188Spfg
5171261188Spfg  if (other_insns_before_prologue && (optimize > 0))
5172261188Spfg    return NULL;
5173261188Spfg
5174261188Spfg  /* Count the number of insns between the first prologue insn and the
5175261188Spfg     last prologue insn; also count the number of non-prologue insns
5176261188Spfg     between the first prologue insn and the last prologue insn.  */
5177261188Spfg
5178261188Spfg  tmp_insn = first_prologue_insn;
5179261188Spfg  while (tmp_insn != last_prologue_insn)
5180261188Spfg    {
5181261188Spfg      total_insns++;
5182261188Spfg      tmp_insn = NEXT_INSN (tmp_insn);
5183261188Spfg    }
5184261188Spfg  total_insns++;
5185261188Spfg
5186261188Spfg  /* If more than half of the insns between the first & last prologue
5187261188Spfg     insns are not prologue insns, then there is too much code that
5188261188Spfg     got moved in between prologue insns (by optimizations), so we
5189261188Spfg     will not try to pull it out.  */
5190261188Spfg
5191261188Spfg  if ((num_prologue_insns * 2) <= total_insns)
5192261188Spfg    return NULL;
5193261188Spfg
5194261188Spfg  /* Make sure all the prologue insns are within one basic block.
5195261188Spfg     If the insns cross a basic block boundary, then there is a chance
5196261188Spfg     that moving them will cause incorrect code, so don't do it.  */
5197261188Spfg
5198261188Spfg  gcc_assert (first_prologue_insn != NULL);
5199261188Spfg  gcc_assert (last_prologue_insn != NULL);
5200261188Spfg
5201261188Spfg  if (BLOCK_FOR_INSN (first_prologue_insn) !=
5202261188Spfg      BLOCK_FOR_INSN (last_prologue_insn))
5203261188Spfg    return NULL;
5204261188Spfg
5205261188Spfg  return last_prologue_insn;
5206261188Spfg}
5207261188Spfg/* APPLE LOCAL end radar 6163705, Blocks prologues  */
5208261188Spfg
520918334Speter/* Generate the prologue and epilogue RTL if the machine supports it.  Thread
521018334Speter   this into place with notes indicating where the prologue ends and where
521118334Speter   the epilogue begins.  Update the basic block information when possible.  */
521218334Speter
521318334Spetervoid
5214132732Skanthread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
521518334Speter{
521660970Sobrien  int inserted = 0;
521790091Sobrien  edge e;
521890091Sobrien#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)
521990091Sobrien  rtx seq;
522090091Sobrien#endif
522160970Sobrien#ifdef HAVE_prologue
522260970Sobrien  rtx prologue_end = NULL_RTX;
522360970Sobrien#endif
522490091Sobrien#if defined (HAVE_epilogue) || defined(HAVE_return)
522590091Sobrien  rtx epilogue_end = NULL_RTX;
522690091Sobrien#endif
5227169702Skan  edge_iterator ei;
522852518Sobrien
522918334Speter#ifdef HAVE_prologue
523018334Speter  if (HAVE_prologue)
523118334Speter    {
5232261188Spfg      /* APPLE LOCAL begin radar 6163705, Blocks prologues  */
5233261188Spfg      rtx last_prologue_insn = NULL;
5234261188Spfg
5235261188Spfg      if (BLOCK_SYNTHESIZED_FUNC (cfun->decl))
5236261188Spfg	last_prologue_insn = find_block_prologue_insns();
5237261188Spfg      /* APPLE LOCAL end radar 6163705, Blocks prologues  */
5238261188Spfg
523952518Sobrien      start_sequence ();
524090091Sobrien      seq = gen_prologue ();
524152518Sobrien      emit_insn (seq);
524218334Speter
524352518Sobrien      /* Retain a map of the prologue insns.  */
524490091Sobrien      record_insns (seq, &prologue);
5245261188Spfg      /* APPLE LOCAL begin radar 6163705, Blocks prologues  */
5246261188Spfg      if (!last_prologue_insn)
5247261188Spfg	prologue_end = emit_note (NOTE_INSN_PROLOGUE_END);
5248261188Spfg      /* APPLE LOCAL end radar 6163705, Blocks prologues  */
5249171836Skan
5250171836Skan#ifndef PROFILE_BEFORE_PROLOGUE
5251171836Skan      /* Ensure that instructions are not moved into the prologue when
5252171836Skan	 profiling is on.  The call to the profiling routine can be
5253171836Skan	 emitted within the live range of a call-clobbered register.  */
5254171836Skan      if (current_function_profile)
5255171836Skan	emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
5256171836Skan#endif
525718334Speter
5258117404Skan      seq = get_insns ();
525952518Sobrien      end_sequence ();
5260132732Skan      set_insn_locators (seq, prologue_locator);
526152518Sobrien
526290091Sobrien      /* Can't deal with multiple successors of the entry block
526390091Sobrien         at the moment.  Function should always have at least one
526490091Sobrien         entry point.  */
5265169702Skan      gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));
526652518Sobrien
5267169702Skan      insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
526890091Sobrien      inserted = 1;
5269261188Spfg
5270261188Spfg      /* APPLE LOCAL begin radar 6163705, Blocks prologues  */
5271261188Spfg      if (last_prologue_insn)
5272261188Spfg	emit_note_after (NOTE_INSN_PROLOGUE_END, last_prologue_insn);
5273261188Spfg      /* APPLE LOCAL end radar 6163705, Blocks prologues  */    }
527418334Speter#endif
527518334Speter
527690091Sobrien  /* If the exit block has no non-fake predecessors, we don't need
527790091Sobrien     an epilogue.  */
5278169702Skan  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
527990091Sobrien    if ((e->flags & EDGE_FAKE) == 0)
528090091Sobrien      break;
528190091Sobrien  if (e == NULL)
528290091Sobrien    goto epilogue_done;
528390091Sobrien
528490091Sobrien#ifdef HAVE_return
528590091Sobrien  if (optimize && HAVE_return)
528618334Speter    {
528790091Sobrien      /* If we're allowed to generate a simple return instruction,
528890091Sobrien	 then by definition we don't need a full epilogue.  Examine
528990091Sobrien	 the block that falls through to EXIT.   If it does not
529090091Sobrien	 contain any code, examine its predecessors and try to
529190091Sobrien	 emit (conditional) return instructions.  */
529218334Speter
529390091Sobrien      basic_block last;
529490091Sobrien      rtx label;
529552518Sobrien
5296169702Skan      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
529790091Sobrien	if (e->flags & EDGE_FALLTHRU)
529890091Sobrien	  break;
529990091Sobrien      if (e == NULL)
530090091Sobrien	goto epilogue_done;
530190091Sobrien      last = e->src;
530290091Sobrien
530390091Sobrien      /* Verify that there are no active instructions in the last block.  */
5304132732Skan      label = BB_END (last);
5305169702Skan      while (label && !LABEL_P (label))
530618334Speter	{
530790091Sobrien	  if (active_insn_p (label))
530852518Sobrien	    break;
530990091Sobrien	  label = PREV_INSN (label);
531090091Sobrien	}
531118334Speter
5312169702Skan      if (BB_HEAD (last) == label && LABEL_P (label))
531390091Sobrien	{
5314169702Skan	  edge_iterator ei2;
531590091Sobrien	  rtx epilogue_line_note = NULL_RTX;
531652518Sobrien
531790091Sobrien	  /* Locate the line number associated with the closing brace,
531890091Sobrien	     if we can find one.  */
531990091Sobrien	  for (seq = get_last_insn ();
532090091Sobrien	       seq && ! active_insn_p (seq);
532190091Sobrien	       seq = PREV_INSN (seq))
5322169702Skan	    if (NOTE_P (seq) && NOTE_LINE_NUMBER (seq) > 0)
532390091Sobrien	      {
532490091Sobrien		epilogue_line_note = seq;
532590091Sobrien		break;
532690091Sobrien	      }
532752518Sobrien
5328169702Skan	  for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); )
532990091Sobrien	    {
533090091Sobrien	      basic_block bb = e->src;
533190091Sobrien	      rtx jump;
533252518Sobrien
533390091Sobrien	      if (bb == ENTRY_BLOCK_PTR)
5334169702Skan		{
5335169702Skan		  ei_next (&ei2);
5336169702Skan		  continue;
5337169702Skan		}
533852518Sobrien
5339132732Skan	      jump = BB_END (bb);
5340169702Skan	      if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
5341169702Skan		{
5342169702Skan		  ei_next (&ei2);
5343169702Skan		  continue;
5344169702Skan		}
534552518Sobrien
534690091Sobrien	      /* If we have an unconditional jump, we can replace that
534790091Sobrien		 with a simple return instruction.  */
534890091Sobrien	      if (simplejump_p (jump))
534990091Sobrien		{
535090091Sobrien		  emit_return_into_block (bb, epilogue_line_note);
535190091Sobrien		  delete_insn (jump);
535290091Sobrien		}
535352518Sobrien
535490091Sobrien	      /* If we have a conditional jump, we can try to replace
535590091Sobrien		 that with a conditional return instruction.  */
535690091Sobrien	      else if (condjump_p (jump))
535790091Sobrien		{
5358117404Skan		  if (! redirect_jump (jump, 0, 0))
5359169702Skan		    {
5360169702Skan		      ei_next (&ei2);
5361169702Skan		      continue;
5362169702Skan		    }
536318334Speter
536490091Sobrien		  /* If this block has only one successor, it both jumps
536590091Sobrien		     and falls through to the fallthru block, so we can't
536690091Sobrien		     delete the edge.  */
5367169702Skan		  if (single_succ_p (bb))
5368169702Skan		    {
5369169702Skan		      ei_next (&ei2);
5370169702Skan		      continue;
5371169702Skan		    }
537290091Sobrien		}
537390091Sobrien	      else
5374169702Skan		{
5375169702Skan		  ei_next (&ei2);
5376169702Skan		  continue;
5377169702Skan		}
537818334Speter
537990091Sobrien	      /* Fix up the CFG for the successful change we just made.  */
538090091Sobrien	      redirect_edge_succ (e, EXIT_BLOCK_PTR);
538190091Sobrien	    }
538218334Speter
538390091Sobrien	  /* Emit a return insn for the exit fallthru block.  Whether
538490091Sobrien	     this is still reachable will be determined later.  */
538518334Speter
5386132732Skan	  emit_barrier_after (BB_END (last));
538790091Sobrien	  emit_return_into_block (last, epilogue_line_note);
5388132732Skan	  epilogue_end = BB_END (last);
5389169702Skan	  single_succ_edge (last)->flags &= ~EDGE_FALLTHRU;
539090091Sobrien	  goto epilogue_done;
539190091Sobrien	}
539290091Sobrien    }
539390091Sobrien#endif
5394169702Skan  /* Find the edge that falls through to EXIT.  Other edges may exist
5395169702Skan     due to RETURN instructions, but those don't need epilogues.
5396169702Skan     There really shouldn't be a mixture -- either all should have
5397169702Skan     been converted or none, however...  */
5398169702Skan
5399169702Skan  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
5400169702Skan    if (e->flags & EDGE_FALLTHRU)
5401169702Skan      break;
5402169702Skan  if (e == NULL)
5403169702Skan    goto epilogue_done;
5404169702Skan
540590091Sobrien#ifdef HAVE_epilogue
540690091Sobrien  if (HAVE_epilogue)
540790091Sobrien    {
540890091Sobrien      start_sequence ();
5409132732Skan      epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
541052518Sobrien
541190091Sobrien      seq = gen_epilogue ();
541290091Sobrien
541390091Sobrien#ifdef INCOMING_RETURN_ADDR_RTX
541490091Sobrien      /* If this function returns with the stack depressed and we can support
541590091Sobrien	 it, massage the epilogue to actually do that.  */
541690091Sobrien      if (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
541790091Sobrien	  && TYPE_RETURNS_STACK_DEPRESSED (TREE_TYPE (current_function_decl)))
541890091Sobrien	seq = keep_stack_depressed (seq);
541990091Sobrien#endif
542090091Sobrien
542190091Sobrien      emit_jump_insn (seq);
542290091Sobrien
542390091Sobrien      /* Retain a map of the epilogue insns.  */
542490091Sobrien      record_insns (seq, &epilogue);
5425132732Skan      set_insn_locators (seq, epilogue_locator);
542690091Sobrien
5427117404Skan      seq = get_insns ();
542890091Sobrien      end_sequence ();
542990091Sobrien
543090091Sobrien      insert_insn_on_edge (seq, e);
543190091Sobrien      inserted = 1;
543218334Speter    }
5433169702Skan  else
543418334Speter#endif
5435169702Skan    {
5436169702Skan      basic_block cur_bb;
5437169702Skan
5438169702Skan      if (! next_active_insn (BB_END (e->src)))
5439169702Skan	goto epilogue_done;
5440169702Skan      /* We have a fall-through edge to the exit block, the source is not
5441169702Skan         at the end of the function, and there will be an assembler epilogue
5442169702Skan         at the end of the function.
5443169702Skan         We can't use force_nonfallthru here, because that would try to
5444169702Skan         use return.  Inserting a jump 'by hand' is extremely messy, so
5445169702Skan	 we take advantage of cfg_layout_finalize using
5446169702Skan	fixup_fallthru_exit_predecessor.  */
5447169702Skan      cfg_layout_initialize (0);
5448169702Skan      FOR_EACH_BB (cur_bb)
5449169702Skan	if (cur_bb->index >= NUM_FIXED_BLOCKS
5450169702Skan	    && cur_bb->next_bb->index >= NUM_FIXED_BLOCKS)
5451169702Skan	  cur_bb->aux = cur_bb->next_bb;
5452169702Skan      cfg_layout_finalize ();
5453169702Skan    }
545490091Sobrienepilogue_done:
545552518Sobrien
545660970Sobrien  if (inserted)
545752518Sobrien    commit_edge_insertions ();
545860970Sobrien
545990091Sobrien#ifdef HAVE_sibcall_epilogue
546090091Sobrien  /* Emit sibling epilogues before any sibling call sites.  */
5461169702Skan  for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); )
546290091Sobrien    {
546390091Sobrien      basic_block bb = e->src;
5464132732Skan      rtx insn = BB_END (bb);
546590091Sobrien
5466169702Skan      if (!CALL_P (insn)
546790091Sobrien	  || ! SIBLING_CALL_P (insn))
5468169702Skan	{
5469169702Skan	  ei_next (&ei);
5470169702Skan	  continue;
5471169702Skan	}
547290091Sobrien
547390091Sobrien      start_sequence ();
5474117404Skan      emit_insn (gen_sibcall_epilogue ());
5475117404Skan      seq = get_insns ();
547690091Sobrien      end_sequence ();
547790091Sobrien
5478117404Skan      /* Retain a map of the epilogue insns.  Used in life analysis to
5479117404Skan	 avoid getting rid of sibcall epilogue insns.  Do this before we
5480117404Skan	 actually emit the sequence.  */
5481117404Skan      record_insns (seq, &sibcall_epilogue);
5482132732Skan      set_insn_locators (seq, epilogue_locator);
5483117404Skan
5484169702Skan      emit_insn_before (seq, insn);
5485169702Skan      ei_next (&ei);
548690091Sobrien    }
548790091Sobrien#endif
548890091Sobrien
548960970Sobrien#ifdef HAVE_prologue
5490132732Skan  /* This is probably all useless now that we use locators.  */
549160970Sobrien  if (prologue_end)
549260970Sobrien    {
549360970Sobrien      rtx insn, prev;
549460970Sobrien
549560970Sobrien      /* GDB handles `break f' by setting a breakpoint on the first
549690091Sobrien	 line note after the prologue.  Which means (1) that if
549760970Sobrien	 there are line number notes before where we inserted the
549890091Sobrien	 prologue we should move them, and (2) we should generate a
549990091Sobrien	 note before the end of the first basic block, if there isn't
550090091Sobrien	 one already there.
550160970Sobrien
5502117404Skan	 ??? This behavior is completely broken when dealing with
550390091Sobrien	 multiple entry functions.  We simply place the note always
550490091Sobrien	 into first basic block and let alternate entry points
550590091Sobrien	 to be missed.
550690091Sobrien       */
550790091Sobrien
550890091Sobrien      for (insn = prologue_end; insn; insn = prev)
550960970Sobrien	{
551060970Sobrien	  prev = PREV_INSN (insn);
5511169702Skan	  if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
551260970Sobrien	    {
551360970Sobrien	      /* Note that we cannot reorder the first insn in the
551460970Sobrien		 chain, since rest_of_compilation relies on that
551590091Sobrien		 remaining constant.  */
551660970Sobrien	      if (prev == NULL)
551790091Sobrien		break;
551890091Sobrien	      reorder_insns (insn, insn, prologue_end);
551960970Sobrien	    }
552060970Sobrien	}
552160970Sobrien
552290091Sobrien      /* Find the last line number note in the first block.  */
5523132732Skan      for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb);
552490091Sobrien	   insn != prologue_end && insn;
552590091Sobrien	   insn = PREV_INSN (insn))
5526169702Skan	if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
552790091Sobrien	  break;
552890091Sobrien
552990091Sobrien      /* If we didn't find one, make a copy of the first line number
553090091Sobrien	 we run across.  */
553190091Sobrien      if (! insn)
553260970Sobrien	{
553390091Sobrien	  for (insn = next_active_insn (prologue_end);
553490091Sobrien	       insn;
553590091Sobrien	       insn = PREV_INSN (insn))
5536169702Skan	    if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
553790091Sobrien	      {
5538132732Skan		emit_note_copy_after (insn, prologue_end);
553990091Sobrien		break;
554090091Sobrien	      }
554160970Sobrien	}
554290091Sobrien    }
554390091Sobrien#endif
554490091Sobrien#ifdef HAVE_epilogue
554590091Sobrien  if (epilogue_end)
554690091Sobrien    {
554790091Sobrien      rtx insn, next;
554890091Sobrien
554990091Sobrien      /* Similarly, move any line notes that appear after the epilogue.
555090091Sobrien         There is no need, however, to be quite so anal about the existence
5551132732Skan	 of such a note.  Also move the NOTE_INSN_FUNCTION_END and (possibly)
5552132732Skan	 NOTE_INSN_FUNCTION_BEG notes, as those can be relevant for debug
5553132732Skan	 info generation.  */
555490091Sobrien      for (insn = epilogue_end; insn; insn = next)
555590091Sobrien	{
555690091Sobrien	  next = NEXT_INSN (insn);
5557169702Skan	  if (NOTE_P (insn)
5558132732Skan	      && (NOTE_LINE_NUMBER (insn) > 0
5559132732Skan		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
5560132732Skan		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END))
556190091Sobrien	    reorder_insns (insn, insn, PREV_INSN (epilogue_end));
556290091Sobrien	}
556390091Sobrien    }
556490091Sobrien#endif
556518334Speter}
556618334Speter
556718334Speter/* Reposition the prologue-end and epilogue-begin notes after instruction
556818334Speter   scheduling and delayed branch scheduling.  */
556918334Speter
557018334Spetervoid
5571132732Skanreposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED)
557218334Speter{
557318334Speter#if defined (HAVE_prologue) || defined (HAVE_epilogue)
557496283Sobrien  rtx insn, last, note;
557590091Sobrien  int len;
557690091Sobrien
5577169702Skan  if ((len = VEC_length (int, prologue)) > 0)
557818334Speter    {
557996283Sobrien      last = 0, note = 0;
558018334Speter
558190091Sobrien      /* Scan from the beginning until we reach the last prologue insn.
558290091Sobrien	 We apparently can't depend on basic_block_{head,end} after
558390091Sobrien	 reorg has run.  */
558496283Sobrien      for (insn = f; insn; insn = NEXT_INSN (insn))
558518334Speter	{
5586169702Skan	  if (NOTE_P (insn))
558718334Speter	    {
558890091Sobrien	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
558990091Sobrien		note = insn;
559090091Sobrien	    }
5591169702Skan	  else if (contains (insn, &prologue))
559290091Sobrien	    {
559396283Sobrien	      last = insn;
559496283Sobrien	      if (--len == 0)
559596283Sobrien		break;
559696283Sobrien	    }
559796283Sobrien	}
5598117404Skan
559996283Sobrien      if (last)
560096283Sobrien	{
560196283Sobrien	  /* Find the prologue-end note if we haven't already, and
560296283Sobrien	     move it to just after the last prologue insn.  */
560396283Sobrien	  if (note == 0)
560496283Sobrien	    {
560596283Sobrien	      for (note = last; (note = NEXT_INSN (note));)
5606169702Skan		if (NOTE_P (note)
560796283Sobrien		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END)
560896283Sobrien		  break;
560996283Sobrien	    }
561052518Sobrien
561196283Sobrien	  /* Avoid placing note between CODE_LABEL and BASIC_BLOCK note.  */
5612169702Skan	  if (LABEL_P (last))
561396283Sobrien	    last = NEXT_INSN (last);
561496283Sobrien	  reorder_insns (note, note, last);
561518334Speter	}
561690091Sobrien    }
561718334Speter
5618169702Skan  if ((len = VEC_length (int, epilogue)) > 0)
561990091Sobrien    {
562096283Sobrien      last = 0, note = 0;
562190091Sobrien
562290091Sobrien      /* Scan from the end until we reach the first epilogue insn.
562390091Sobrien	 We apparently can't depend on basic_block_{head,end} after
562490091Sobrien	 reorg has run.  */
562596283Sobrien      for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
562618334Speter	{
5627169702Skan	  if (NOTE_P (insn))
562818334Speter	    {
562990091Sobrien	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
563090091Sobrien		note = insn;
563190091Sobrien	    }
5632169702Skan	  else if (contains (insn, &epilogue))
563390091Sobrien	    {
563496283Sobrien	      last = insn;
563596283Sobrien	      if (--len == 0)
563696283Sobrien		break;
563796283Sobrien	    }
563896283Sobrien	}
563952518Sobrien
564096283Sobrien      if (last)
564196283Sobrien	{
564296283Sobrien	  /* Find the epilogue-begin note if we haven't already, and
564396283Sobrien	     move it to just before the first epilogue insn.  */
564496283Sobrien	  if (note == 0)
564596283Sobrien	    {
564696283Sobrien	      for (note = insn; (note = PREV_INSN (note));)
5647169702Skan		if (NOTE_P (note)
564896283Sobrien		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
564996283Sobrien		  break;
565096283Sobrien	    }
565152518Sobrien
565296283Sobrien	  if (PREV_INSN (last) != note)
565396283Sobrien	    reorder_insns (note, note, PREV_INSN (last));
565418334Speter	}
565518334Speter    }
565618334Speter#endif /* HAVE_prologue or HAVE_epilogue */
565718334Speter}
565890091Sobrien
5659169702Skan/* Resets insn_block_boundaries array.  */
566090091Sobrien
566190091Sobrienvoid
5662169702Skanreset_block_changes (void)
566390091Sobrien{
5664169702Skan  cfun->ib_boundaries_block = VEC_alloc (tree, gc, 100);
5665169702Skan  VEC_quick_push (tree, cfun->ib_boundaries_block, NULL_TREE);
566690091Sobrien}
5667117404Skan
5668169702Skan/* Record the boundary for BLOCK.  */
5669169702Skanvoid
5670169702Skanrecord_block_change (tree block)
5671169702Skan{
5672169702Skan  int i, n;
5673169702Skan  tree last_block;
5674169702Skan
5675169702Skan  if (!block)
5676169702Skan    return;
5677169702Skan
5678169702Skan  if(!cfun->ib_boundaries_block)
5679169702Skan    return;
5680169702Skan
5681169702Skan  last_block = VEC_pop (tree, cfun->ib_boundaries_block);
5682169702Skan  n = get_max_uid ();
5683169702Skan  for (i = VEC_length (tree, cfun->ib_boundaries_block); i < n; i++)
5684169702Skan    VEC_safe_push (tree, gc, cfun->ib_boundaries_block, last_block);
5685169702Skan
5686169702Skan  VEC_safe_push (tree, gc, cfun->ib_boundaries_block, block);
5687169702Skan}
5688169702Skan
5689169702Skan/* Finishes record of boundaries.  */
5690169702Skanvoid
5691169702Skanfinalize_block_changes (void)
5692169702Skan{
5693169702Skan  record_block_change (DECL_INITIAL (current_function_decl));
5694169702Skan}
5695169702Skan
5696169702Skan/* For INSN return the BLOCK it belongs to.  */
5697169702Skanvoid
5698169702Skancheck_block_change (rtx insn, tree *block)
5699169702Skan{
5700169702Skan  unsigned uid = INSN_UID (insn);
5701169702Skan
5702169702Skan  if (uid >= VEC_length (tree, cfun->ib_boundaries_block))
5703169702Skan    return;
5704169702Skan
5705169702Skan  *block = VEC_index (tree, cfun->ib_boundaries_block, uid);
5706169702Skan}
5707169702Skan
5708169702Skan/* Releases the ib_boundaries_block records.  */
5709169702Skanvoid
5710169702Skanfree_block_changes (void)
5711169702Skan{
5712169702Skan  VEC_free (tree, gc, cfun->ib_boundaries_block);
5713169702Skan}
5714169702Skan
5715132732Skan/* Returns the name of the current function.  */
5716132732Skanconst char *
5717132732Skancurrent_function_name (void)
5718132732Skan{
5719169702Skan  return lang_hooks.decl_printable_name (cfun->decl, 2);
5720132732Skan}
5721169702Skan
5722132732Skan
5723169702Skanstatic unsigned int
5724169702Skanrest_of_handle_check_leaf_regs (void)
5725169702Skan{
5726169702Skan#ifdef LEAF_REGISTERS
5727169702Skan  current_function_uses_only_leaf_regs
5728169702Skan    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
5729169702Skan#endif
5730169702Skan  return 0;
5731169702Skan}
5732169702Skan
5733169702Skan/* Insert a TYPE into the used types hash table of CFUN.  */
5734169702Skanstatic void
5735169702Skanused_types_insert_helper (tree type, struct function *func)
5736169702Skan{
5737169702Skan  if (type != NULL && func != NULL)
5738169702Skan    {
5739169702Skan      void **slot;
5740169702Skan
5741169702Skan      if (func->used_types_hash == NULL)
5742169702Skan	func->used_types_hash = htab_create_ggc (37, htab_hash_pointer,
5743169702Skan						 htab_eq_pointer, NULL);
5744169702Skan      slot = htab_find_slot (func->used_types_hash, type, INSERT);
5745169702Skan      if (*slot == NULL)
5746169702Skan	*slot = type;
5747169702Skan    }
5748169702Skan}
5749169702Skan
5750169702Skan/* Given a type, insert it into the used hash table in cfun.  */
5751169702Skanvoid
5752169702Skanused_types_insert (tree t)
5753169702Skan{
5754169702Skan  while (POINTER_TYPE_P (t) || TREE_CODE (t) == ARRAY_TYPE)
5755169702Skan    t = TREE_TYPE (t);
5756169702Skan  t = TYPE_MAIN_VARIANT (t);
5757169702Skan  if (debug_info_level > DINFO_LEVEL_NONE)
5758169702Skan    used_types_insert_helper (t, cfun);
5759169702Skan}
5760169702Skan
5761169702Skanstruct tree_opt_pass pass_leaf_regs =
5762169702Skan{
5763169702Skan  NULL,                                 /* name */
5764169702Skan  NULL,                                 /* gate */
5765169702Skan  rest_of_handle_check_leaf_regs,       /* execute */
5766169702Skan  NULL,                                 /* sub */
5767169702Skan  NULL,                                 /* next */
5768169702Skan  0,                                    /* static_pass_number */
5769169702Skan  0,                                    /* tv_id */
5770169702Skan  0,                                    /* properties_required */
5771169702Skan  0,                                    /* properties_provided */
5772169702Skan  0,                                    /* properties_destroyed */
5773169702Skan  0,                                    /* todo_flags_start */
5774169702Skan  0,                                    /* todo_flags_finish */
5775169702Skan  0                                     /* letter */
5776169702Skan};
5777169702Skan
5778169702Skan
5779117404Skan#include "gt-function.h"
5780