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
119117404Skan/* Assign unique numbers to labels generated for profiling, debugging, etc.  */
120132732Skanstatic GTY(()) int funcdef_no;
12196283Sobrien
12290091Sobrien/* These variables hold pointers to functions to create and destroy
12390091Sobrien   target specific, per-function data structures.  */
124132732Skanstruct machine_function * (*init_machine_status) (void);
12552518Sobrien
12690091Sobrien/* The currently compiled function.  */
12790091Sobrienstruct function *cfun = 0;
12818334Speter
12990091Sobrien/* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
130169702Skanstatic VEC(int,heap) *prologue;
131169702Skanstatic VEC(int,heap) *epilogue;
13218334Speter
13390091Sobrien/* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
13418334Speter   in this function.  */
135169702Skanstatic VEC(int,heap) *sibcall_epilogue;
13618334Speter
13718334Speter/* In order to evaluate some expressions, such as function calls returning
13818334Speter   structures in memory, we need to temporarily allocate stack locations.
13918334Speter   We record each allocated temporary in the following structure.
14018334Speter
14118334Speter   Associated with each temporary slot is a nesting level.  When we pop up
14218334Speter   one level, all temporaries associated with the previous level are freed.
14318334Speter   Normally, all temporaries are freed after the execution of the statement
14418334Speter   in which they were created.  However, if we are inside a ({...}) grouping,
14518334Speter   the result may be in a temporary and hence must be preserved.  If the
14618334Speter   result could be in a temporary, we preserve it if we can determine which
14718334Speter   one it is in.  If we cannot determine which temporary may contain the
14818334Speter   result, all temporaries are preserved.  A temporary is preserved by
14918334Speter   pretending it was allocated at the previous nesting level.
15018334Speter
15118334Speter   Automatic variables are also assigned temporary slots, at the nesting
15218334Speter   level where they are defined.  They are marked a "kept" so that
15318334Speter   free_temp_slots will not free them.  */
15418334Speter
155117404Skanstruct temp_slot GTY(())
15618334Speter{
15718334Speter  /* Points to next temporary slot.  */
15818334Speter  struct temp_slot *next;
159169702Skan  /* Points to previous temporary slot.  */
160169702Skan  struct temp_slot *prev;
161169702Skan
16252268Sobrien  /* The rtx to used to reference the slot.  */
16318334Speter  rtx slot;
16418334Speter  /* The rtx used to represent the address if not the address of the
16518334Speter     slot above.  May be an EXPR_LIST if multiple addresses exist.  */
16618334Speter  rtx address;
16790091Sobrien  /* The alignment (in bits) of the slot.  */
16890091Sobrien  unsigned int align;
16918334Speter  /* The size, in units, of the slot.  */
17052268Sobrien  HOST_WIDE_INT size;
17190091Sobrien  /* The type of the object in the slot, or zero if it doesn't correspond
17290091Sobrien     to a type.  We use this to determine whether a slot can be reused.
17390091Sobrien     It can be reused if objects of the type of the new slot will always
17490091Sobrien     conflict with objects of the type of the old slot.  */
17590091Sobrien  tree type;
176117404Skan  /* Nonzero if this temporary is currently in use.  */
17718334Speter  char in_use;
178117404Skan  /* Nonzero if this temporary has its address taken.  */
17918334Speter  char addr_taken;
18018334Speter  /* Nesting level at which this slot is being used.  */
18118334Speter  int level;
182117404Skan  /* Nonzero if this should survive a call to free_temp_slots.  */
18318334Speter  int keep;
18418334Speter  /* The offset of the slot from the frame_pointer, including extra space
18518334Speter     for alignment.  This info is for combine_temp_slots.  */
18652268Sobrien  HOST_WIDE_INT base_offset;
18718334Speter  /* The size of the slot, including extra space for alignment.  This
18818334Speter     info is for combine_temp_slots.  */
18952268Sobrien  HOST_WIDE_INT full_size;
19018334Speter};
19152268Sobrien
19218334Speter/* Forward declarations.  */
19318334Speter
194132732Skanstatic rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
195132732Skan				 struct function *);
196132732Skanstatic struct temp_slot *find_temp_slot_from_address (rtx);
197132732Skanstatic void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
198132732Skanstatic void pad_below (struct args_size *, enum machine_mode, tree);
199169702Skanstatic void reorder_blocks_1 (rtx, tree, VEC(tree,heap) **);
200132732Skanstatic int all_blocks (tree, tree *);
201132732Skanstatic tree *get_block_vector (tree, int *);
202132732Skanextern tree debug_find_var_in_block_tree (tree, tree);
203169702Skan/* We always define `record_insns' even if it's not used so that we
20490091Sobrien   can always export `prologue_epilogue_contains'.  */
205169702Skanstatic void record_insns (rtx, VEC(int,heap) **) ATTRIBUTE_UNUSED;
206169702Skanstatic int contains (rtx, VEC(int,heap) **);
20790091Sobrien#ifdef HAVE_return
208132732Skanstatic void emit_return_into_block (basic_block, rtx);
20952268Sobrien#endif
21090091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
211132732Skanstatic rtx keep_stack_depressed (rtx);
21290091Sobrien#endif
213132732Skanstatic void prepare_function_start (tree);
214132732Skanstatic void do_clobber_return_reg (rtx, void *);
215132732Skanstatic void do_use_return_reg (rtx, void *);
216132732Skanstatic void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
21718334Speter
21818334Speter/* Pointer to chain of `struct function' for containing functions.  */
219132732Skanstruct function *outer_function_chain;
22018334Speter
22118334Speter/* Given a function decl for a containing function,
22218334Speter   return the `struct function' for it.  */
22318334Speter
22418334Speterstruct function *
225132732Skanfind_function_data (tree decl)
22618334Speter{
22718334Speter  struct function *p;
22852268Sobrien
22990091Sobrien  for (p = outer_function_chain; p; p = p->outer)
23018334Speter    if (p->decl == decl)
23118334Speter      return p;
23252268Sobrien
233169702Skan  gcc_unreachable ();
23418334Speter}
23518334Speter
23618334Speter/* Save the current context for compilation of a nested function.
23790091Sobrien   This is called from language-specific code.  The caller should use
238117404Skan   the enter_nested langhook to save any language-specific state,
23990091Sobrien   since this function knows only about language-independent
24090091Sobrien   variables.  */
24118334Speter
24218334Spetervoid
243169702Skanpush_function_context_to (tree context ATTRIBUTE_UNUSED)
24418334Speter{
24590091Sobrien  struct function *p;
24618334Speter
24790091Sobrien  if (cfun == 0)
24890091Sobrien    init_dummy_function_start ();
24990091Sobrien  p = cfun;
25090091Sobrien
25190091Sobrien  p->outer = outer_function_chain;
25218334Speter  outer_function_chain = p;
25318334Speter
254169702Skan  lang_hooks.function.enter_nested (p);
25590091Sobrien
25690091Sobrien  cfun = 0;
25718334Speter}
25818334Speter
25918334Spetervoid
260132732Skanpush_function_context (void)
26118334Speter{
26218334Speter  push_function_context_to (current_function_decl);
26318334Speter}
26418334Speter
26518334Speter/* Restore the last saved context, at the end of a nested function.
26618334Speter   This function is called from language-specific code.  */
26718334Speter
26818334Spetervoid
269132732Skanpop_function_context_from (tree context ATTRIBUTE_UNUSED)
27018334Speter{
27118334Speter  struct function *p = outer_function_chain;
27218334Speter
27390091Sobrien  cfun = p;
27490091Sobrien  outer_function_chain = p->outer;
27518334Speter
27618334Speter  current_function_decl = p->decl;
27718334Speter
278169702Skan  lang_hooks.function.leave_nested (p);
27918334Speter
28018334Speter  /* Reset variables that have known state during rtx generation.  */
28118334Speter  virtuals_instantiated = 0;
28290091Sobrien  generating_concat_p = 1;
28318334Speter}
28418334Speter
28590091Sobrienvoid
286132732Skanpop_function_context (void)
28718334Speter{
28818334Speter  pop_function_context_from (current_function_decl);
28918334Speter}
29090091Sobrien
29190091Sobrien/* Clear out all parts of the state in F that can safely be discarded
29290091Sobrien   after the function has been parsed, but not compiled, to let
29390091Sobrien   garbage collection reclaim the memory.  */
29490091Sobrien
29590091Sobrienvoid
296132732Skanfree_after_parsing (struct function *f)
29790091Sobrien{
29890091Sobrien  /* f->expr->forced_labels is used by code generation.  */
29990091Sobrien  /* f->emit->regno_reg_rtx is used by code generation.  */
30090091Sobrien  /* f->varasm is used by code generation.  */
30190091Sobrien  /* f->eh->eh_return_stub_label is used by code generation.  */
30290091Sobrien
303169702Skan  lang_hooks.function.final (f);
30490091Sobrien}
30590091Sobrien
30690091Sobrien/* Clear out all parts of the state in F that can safely be discarded
30790091Sobrien   after the function has been compiled, to let garbage collection
30890091Sobrien   reclaim the memory.  */
30990091Sobrien
31090091Sobrienvoid
311132732Skanfree_after_compilation (struct function *f)
31290091Sobrien{
313169702Skan  VEC_free (int, heap, prologue);
314169702Skan  VEC_free (int, heap, epilogue);
315169702Skan  VEC_free (int, heap, sibcall_epilogue);
316169702Skan
317117404Skan  f->eh = NULL;
318117404Skan  f->expr = NULL;
319117404Skan  f->emit = NULL;
320117404Skan  f->varasm = NULL;
321117404Skan  f->machine = NULL;
322169702Skan  f->cfg = NULL;
32390091Sobrien
324169702Skan  f->x_avail_temp_slots = NULL;
325169702Skan  f->x_used_temp_slots = NULL;
32690091Sobrien  f->arg_offset_rtx = NULL;
32790091Sobrien  f->return_rtx = NULL;
32890091Sobrien  f->internal_arg_pointer = NULL;
32990091Sobrien  f->x_nonlocal_goto_handler_labels = NULL;
33090091Sobrien  f->x_return_label = NULL;
331132732Skan  f->x_naked_return_label = NULL;
33290091Sobrien  f->x_stack_slot_list = NULL;
333169702Skan  f->x_stack_check_probe_note = NULL;
33490091Sobrien  f->x_arg_pointer_save_area = NULL;
33590091Sobrien  f->x_parm_birth_insn = NULL;
33690091Sobrien  f->epilogue_delay_list = NULL;
33790091Sobrien}
33818334Speter
33918334Speter/* Allocate fixed slots in the stack frame of the current function.  */
34018334Speter
34190091Sobrien/* Return size needed for stack frame based on slots so far allocated in
34290091Sobrien   function F.
34352518Sobrien   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
34418334Speter   the caller may have to do that.  */
34518334Speter
346169702Skanstatic HOST_WIDE_INT
347132732Skanget_func_frame_size (struct function *f)
34818334Speter{
349169702Skan  if (FRAME_GROWS_DOWNWARD)
350169702Skan    return -f->x_frame_offset;
351169702Skan  else
352169702Skan    return f->x_frame_offset;
35318334Speter}
35418334Speter
35590091Sobrien/* Return size needed for stack frame based on slots so far allocated.
35690091Sobrien   This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
35790091Sobrien   the caller may have to do that.  */
358169702Skan
35990091SobrienHOST_WIDE_INT
360132732Skanget_frame_size (void)
36190091Sobrien{
36290091Sobrien  return get_func_frame_size (cfun);
36390091Sobrien}
36490091Sobrien
365169702Skan/* Issue an error message and return TRUE if frame OFFSET overflows in
366169702Skan   the signed target pointer arithmetics for function FUNC.  Otherwise
367169702Skan   return FALSE.  */
368169702Skan
369169702Skanbool
370169702Skanframe_offset_overflow (HOST_WIDE_INT offset, tree func)
371169702Skan{
372169702Skan  unsigned HOST_WIDE_INT size = FRAME_GROWS_DOWNWARD ? -offset : offset;
373169702Skan
374169702Skan  if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1))
375169702Skan	       /* Leave room for the fixed part of the frame.  */
376169702Skan	       - 64 * UNITS_PER_WORD)
377169702Skan    {
378169702Skan      error ("%Jtotal size of local objects too large", func);
379169702Skan      return TRUE;
380169702Skan    }
381169702Skan
382169702Skan  return FALSE;
383169702Skan}
384169702Skan
38518334Speter/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
38618334Speter   with machine mode MODE.
38790091Sobrien
38818334Speter   ALIGN controls the amount of alignment for the address of the slot:
38918334Speter   0 means according to MODE,
39018334Speter   -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
391146908Skan   -2 means use BITS_PER_UNIT,
39218334Speter   positive specifies alignment boundary in bits.
39318334Speter
39490091Sobrien   We do not round to stack_boundary here.
39518334Speter
39690091Sobrien   FUNCTION specifies the function to allocate in.  */
39790091Sobrien
39890091Sobrienstatic rtx
399132732Skanassign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
400132732Skan		      struct function *function)
40118334Speter{
40290091Sobrien  rtx x, addr;
40318334Speter  int bigend_correction = 0;
404169702Skan  unsigned int alignment;
40590091Sobrien  int frame_off, frame_alignment, frame_phase;
40618334Speter
40718334Speter  if (align == 0)
40818334Speter    {
40952518Sobrien      tree type;
41052518Sobrien
41118334Speter      if (mode == BLKmode)
41252518Sobrien	alignment = BIGGEST_ALIGNMENT;
41390091Sobrien      else
41490091Sobrien	alignment = GET_MODE_ALIGNMENT (mode);
41552518Sobrien
41652518Sobrien      /* Allow the target to (possibly) increase the alignment of this
41752518Sobrien	 stack slot.  */
418169702Skan      type = lang_hooks.types.type_for_mode (mode, 0);
41952518Sobrien      if (type)
42052518Sobrien	alignment = LOCAL_ALIGNMENT (type, alignment);
42152518Sobrien
42252518Sobrien      alignment /= BITS_PER_UNIT;
42318334Speter    }
42418334Speter  else if (align == -1)
42518334Speter    {
42618334Speter      alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
42718334Speter      size = CEIL_ROUND (size, alignment);
42818334Speter    }
429146908Skan  else if (align == -2)
430146908Skan    alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */
43118334Speter  else
43218334Speter    alignment = align / BITS_PER_UNIT;
43318334Speter
434169702Skan  if (FRAME_GROWS_DOWNWARD)
435169702Skan    function->x_frame_offset -= size;
43652518Sobrien
43790091Sobrien  /* Ignore alignment we can't do with expected alignment of the boundary.  */
43890091Sobrien  if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
43990091Sobrien    alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
44090091Sobrien
44190091Sobrien  if (function->stack_alignment_needed < alignment * BITS_PER_UNIT)
44290091Sobrien    function->stack_alignment_needed = alignment * BITS_PER_UNIT;
44390091Sobrien
44490091Sobrien  /* Calculate how many bytes the start of local variables is off from
44590091Sobrien     stack alignment.  */
44690091Sobrien  frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
44790091Sobrien  frame_off = STARTING_FRAME_OFFSET % frame_alignment;
44890091Sobrien  frame_phase = frame_off ? frame_alignment - frame_off : 0;
44990091Sobrien
450132732Skan  /* Round the frame offset to the specified alignment.  The default is
451132732Skan     to always honor requests to align the stack but a port may choose to
452132732Skan     do its own stack alignment by defining STACK_ALIGNMENT_NEEDED.  */
453132732Skan  if (STACK_ALIGNMENT_NEEDED
454132732Skan      || mode != BLKmode
455132732Skan      || size != 0)
456132732Skan    {
457132732Skan      /*  We must be careful here, since FRAME_OFFSET might be negative and
458132732Skan	  division with a negative dividend isn't as well defined as we might
459132732Skan	  like.  So we instead assume that ALIGNMENT is a power of two and
460132732Skan	  use logical operations which are unambiguous.  */
461169702Skan      if (FRAME_GROWS_DOWNWARD)
462169702Skan	function->x_frame_offset
463169702Skan	  = (FLOOR_ROUND (function->x_frame_offset - frame_phase,
464169702Skan			  (unsigned HOST_WIDE_INT) alignment)
465169702Skan	     + frame_phase);
466169702Skan      else
467169702Skan	function->x_frame_offset
468169702Skan	  = (CEIL_ROUND (function->x_frame_offset - frame_phase,
469169702Skan			 (unsigned HOST_WIDE_INT) alignment)
470169702Skan	     + frame_phase);
471132732Skan    }
47218334Speter
47318334Speter  /* On a big-endian machine, if we are allocating more space than we will use,
47418334Speter     use the least significant bytes of those that are allocated.  */
475169702Skan  if (BYTES_BIG_ENDIAN && mode != BLKmode && GET_MODE_SIZE (mode) < size)
47618334Speter    bigend_correction = size - GET_MODE_SIZE (mode);
47718334Speter
47818334Speter  /* If we have already instantiated virtual registers, return the actual
47918334Speter     address relative to the frame pointer.  */
48090091Sobrien  if (function == cfun && virtuals_instantiated)
48118334Speter    addr = plus_constant (frame_pointer_rtx,
482132732Skan			  trunc_int_for_mode
48318334Speter			  (frame_offset + bigend_correction
484132732Skan			   + STARTING_FRAME_OFFSET, Pmode));
48518334Speter  else
48618334Speter    addr = plus_constant (virtual_stack_vars_rtx,
487132732Skan			  trunc_int_for_mode
488132732Skan			  (function->x_frame_offset + bigend_correction,
489132732Skan			   Pmode));
49018334Speter
491169702Skan  if (!FRAME_GROWS_DOWNWARD)
492169702Skan    function->x_frame_offset += size;
49318334Speter
49452268Sobrien  x = gen_rtx_MEM (mode, addr);
495169702Skan  MEM_NOTRAP_P (x) = 1;
49618334Speter
49790091Sobrien  function->x_stack_slot_list
49890091Sobrien    = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
49918334Speter
500169702Skan  if (frame_offset_overflow (function->x_frame_offset, function->decl))
501169702Skan    function->x_frame_offset = 0;
502169702Skan
50318334Speter  return x;
50418334Speter}
50518334Speter
50690091Sobrien/* Wrapper around assign_stack_local_1;  assign a local stack slot for the
50790091Sobrien   current function.  */
50818334Speter
50990091Sobrienrtx
510132732Skanassign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
51118334Speter{
51290091Sobrien  return assign_stack_local_1 (mode, size, align, cfun);
51318334Speter}
514169702Skan
51518334Speter
516169702Skan/* Removes temporary slot TEMP from LIST.  */
517169702Skan
518169702Skanstatic void
519169702Skancut_slot_from_list (struct temp_slot *temp, struct temp_slot **list)
520169702Skan{
521169702Skan  if (temp->next)
522169702Skan    temp->next->prev = temp->prev;
523169702Skan  if (temp->prev)
524169702Skan    temp->prev->next = temp->next;
525169702Skan  else
526169702Skan    *list = temp->next;
527169702Skan
528169702Skan  temp->prev = temp->next = NULL;
529169702Skan}
530169702Skan
531169702Skan/* Inserts temporary slot TEMP to LIST.  */
532169702Skan
533169702Skanstatic void
534169702Skaninsert_slot_to_list (struct temp_slot *temp, struct temp_slot **list)
535169702Skan{
536169702Skan  temp->next = *list;
537169702Skan  if (*list)
538169702Skan    (*list)->prev = temp;
539169702Skan  temp->prev = NULL;
540169702Skan  *list = temp;
541169702Skan}
542169702Skan
543169702Skan/* Returns the list of used temp slots at LEVEL.  */
544169702Skan
545169702Skanstatic struct temp_slot **
546169702Skantemp_slots_at_level (int level)
547169702Skan{
548169702Skan  if (level >= (int) VEC_length (temp_slot_p, used_temp_slots))
549169702Skan    {
550169702Skan      size_t old_length = VEC_length (temp_slot_p, used_temp_slots);
551169702Skan      temp_slot_p *p;
552169702Skan
553169702Skan      VEC_safe_grow (temp_slot_p, gc, used_temp_slots, level + 1);
554169702Skan      p = VEC_address (temp_slot_p, used_temp_slots);
555169702Skan      memset (&p[old_length], 0,
556169702Skan	      sizeof (temp_slot_p) * (level + 1 - old_length));
557169702Skan    }
558169702Skan
559169702Skan  return &(VEC_address (temp_slot_p, used_temp_slots)[level]);
560169702Skan}
561169702Skan
562169702Skan/* Returns the maximal temporary slot level.  */
563169702Skan
564169702Skanstatic int
565169702Skanmax_slot_level (void)
566169702Skan{
567169702Skan  if (!used_temp_slots)
568169702Skan    return -1;
569169702Skan
570169702Skan  return VEC_length (temp_slot_p, used_temp_slots) - 1;
571169702Skan}
572169702Skan
573169702Skan/* Moves temporary slot TEMP to LEVEL.  */
574169702Skan
575169702Skanstatic void
576169702Skanmove_slot_to_level (struct temp_slot *temp, int level)
577169702Skan{
578169702Skan  cut_slot_from_list (temp, temp_slots_at_level (temp->level));
579169702Skan  insert_slot_to_list (temp, temp_slots_at_level (level));
580169702Skan  temp->level = level;
581169702Skan}
582169702Skan
583169702Skan/* Make temporary slot TEMP available.  */
584169702Skan
585169702Skanstatic void
586169702Skanmake_slot_available (struct temp_slot *temp)
587169702Skan{
588169702Skan  cut_slot_from_list (temp, temp_slots_at_level (temp->level));
589169702Skan  insert_slot_to_list (temp, &avail_temp_slots);
590169702Skan  temp->in_use = 0;
591169702Skan  temp->level = -1;
592169702Skan}
593169702Skan
59418334Speter/* Allocate a temporary stack slot and record it for possible later
59518334Speter   reuse.
59618334Speter
59718334Speter   MODE is the machine mode to be given to the returned rtx.
59818334Speter
59918334Speter   SIZE is the size in units of the space required.  We do no rounding here
60018334Speter   since assign_stack_local will do any required rounding.
60118334Speter
60218334Speter   KEEP is 1 if this slot is to be retained after a call to
60318334Speter   free_temp_slots.  Automatic variables for a block are allocated
604169702Skan   with this flag.  KEEP values of 2 or 3 were needed respectively
605169702Skan   for variables whose lifetime is controlled by CLEANUP_POINT_EXPRs
606169702Skan   or for SAVE_EXPRs, but they are now unused.
60718334Speter
60852518Sobrien   TYPE is the type that will be used for the stack slot.  */
60952518Sobrien
61090091Sobrienrtx
611169702Skanassign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size,
612169702Skan			    int keep, tree type)
61318334Speter{
61490091Sobrien  unsigned int align;
615169702Skan  struct temp_slot *p, *best_p = 0, *selected = NULL, **pp;
616102794Skan  rtx slot;
61718334Speter
61818334Speter  /* If SIZE is -1 it means that somebody tried to allocate a temporary
61918334Speter     of a variable size.  */
620169702Skan  gcc_assert (size != -1);
62118334Speter
622169702Skan  /* These are now unused.  */
623169702Skan  gcc_assert (keep <= 1);
624169702Skan
62552518Sobrien  if (mode == BLKmode)
62652518Sobrien    align = BIGGEST_ALIGNMENT;
62790091Sobrien  else
62890091Sobrien    align = GET_MODE_ALIGNMENT (mode);
62952518Sobrien
63052518Sobrien  if (! type)
631169702Skan    type = lang_hooks.types.type_for_mode (mode, 0);
63290091Sobrien
63352518Sobrien  if (type)
63452518Sobrien    align = LOCAL_ALIGNMENT (type, align);
63552518Sobrien
63652518Sobrien  /* Try to find an available, already-allocated temporary of the proper
63752518Sobrien     mode which meets the size and alignment requirements.  Choose the
638169702Skan     smallest one with the closest alignment.
639169702Skan
640169702Skan     If assign_stack_temp is called outside of the tree->rtl expansion,
641169702Skan     we cannot reuse the stack slots (that may still refer to
642169702Skan     VIRTUAL_STACK_VARS_REGNUM).  */
643169702Skan  if (!virtuals_instantiated)
644169702Skan    {
645169702Skan      for (p = avail_temp_slots; p; p = p->next)
646169702Skan	{
647169702Skan	  if (p->align >= align && p->size >= size
648169702Skan	      && GET_MODE (p->slot) == mode
649169702Skan	      && objects_must_conflict_p (p->type, type)
650169702Skan	      && (best_p == 0 || best_p->size > p->size
651169702Skan		  || (best_p->size == p->size && best_p->align > p->align)))
652169702Skan	    {
653169702Skan	      if (p->align == align && p->size == size)
654169702Skan		{
655169702Skan		  selected = p;
656169702Skan		  cut_slot_from_list (selected, &avail_temp_slots);
657169702Skan		  best_p = 0;
658169702Skan		  break;
659169702Skan		}
660169702Skan	      best_p = p;
661169702Skan	    }
662169702Skan	}
663169702Skan    }
66418334Speter
66518334Speter  /* Make our best, if any, the one to use.  */
66618334Speter  if (best_p)
66718334Speter    {
668169702Skan      selected = best_p;
669169702Skan      cut_slot_from_list (selected, &avail_temp_slots);
670169702Skan
67118334Speter      /* If there are enough aligned bytes left over, make them into a new
67218334Speter	 temp_slot so that the extra bytes don't get wasted.  Do this only
67318334Speter	 for BLKmode slots, so that we can be sure of the alignment.  */
67490091Sobrien      if (GET_MODE (best_p->slot) == BLKmode)
67518334Speter	{
67652518Sobrien	  int alignment = best_p->align / BITS_PER_UNIT;
67752268Sobrien	  HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
67818334Speter
67918334Speter	  if (best_p->size - rounded_size >= alignment)
68018334Speter	    {
681132732Skan	      p = ggc_alloc (sizeof (struct temp_slot));
68218334Speter	      p->in_use = p->addr_taken = 0;
68318334Speter	      p->size = best_p->size - rounded_size;
68418334Speter	      p->base_offset = best_p->base_offset + rounded_size;
68518334Speter	      p->full_size = best_p->full_size - rounded_size;
686169702Skan	      p->slot = adjust_address_nv (best_p->slot, BLKmode, rounded_size);
68752518Sobrien	      p->align = best_p->align;
68818334Speter	      p->address = 0;
68990091Sobrien	      p->type = best_p->type;
690169702Skan	      insert_slot_to_list (p, &avail_temp_slots);
69118334Speter
69252268Sobrien	      stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, p->slot,
69352268Sobrien						   stack_slot_list);
69418334Speter
69518334Speter	      best_p->size = rounded_size;
69618334Speter	      best_p->full_size = rounded_size;
69718334Speter	    }
69818334Speter	}
69918334Speter    }
70090091Sobrien
70118334Speter  /* If we still didn't find one, make a new temporary.  */
702169702Skan  if (selected == 0)
70318334Speter    {
70452268Sobrien      HOST_WIDE_INT frame_offset_old = frame_offset;
70552268Sobrien
706132732Skan      p = ggc_alloc (sizeof (struct temp_slot));
70752268Sobrien
70852518Sobrien      /* We are passing an explicit alignment request to assign_stack_local.
70952518Sobrien	 One side effect of that is assign_stack_local will not round SIZE
71052518Sobrien	 to ensure the frame offset remains suitably aligned.
71152268Sobrien
71252518Sobrien	 So for requests which depended on the rounding of SIZE, we go ahead
71352518Sobrien	 and round it now.  We also make sure ALIGNMENT is at least
71452518Sobrien	 BIGGEST_ALIGNMENT.  */
715169702Skan      gcc_assert (mode != BLKmode || align == BIGGEST_ALIGNMENT);
71652518Sobrien      p->slot = assign_stack_local (mode,
71752763Sobrien				    (mode == BLKmode
718132732Skan				     ? CEIL_ROUND (size, (int) align / BITS_PER_UNIT)
71952763Sobrien				     : size),
72052518Sobrien				    align);
72152518Sobrien
72252518Sobrien      p->align = align;
72352518Sobrien
72418334Speter      /* The following slot size computation is necessary because we don't
72518334Speter	 know the actual size of the temporary slot until assign_stack_local
72618334Speter	 has performed all the frame alignment and size rounding for the
72718334Speter	 requested temporary.  Note that extra space added for alignment
72818334Speter	 can be either above or below this stack slot depending on which
72918334Speter	 way the frame grows.  We include the extra space if and only if it
73018334Speter	 is above this slot.  */
731169702Skan      if (FRAME_GROWS_DOWNWARD)
732169702Skan	p->size = frame_offset_old - frame_offset;
733169702Skan      else
734169702Skan	p->size = size;
73552268Sobrien
73618334Speter      /* Now define the fields used by combine_temp_slots.  */
737169702Skan      if (FRAME_GROWS_DOWNWARD)
738169702Skan	{
739169702Skan	  p->base_offset = frame_offset;
740169702Skan	  p->full_size = frame_offset_old - frame_offset;
741169702Skan	}
742169702Skan      else
743169702Skan	{
744169702Skan	  p->base_offset = frame_offset_old;
745169702Skan	  p->full_size = frame_offset - frame_offset_old;
746169702Skan	}
74718334Speter      p->address = 0;
748169702Skan
749169702Skan      selected = p;
75018334Speter    }
75118334Speter
752169702Skan  p = selected;
75318334Speter  p->in_use = 1;
75418334Speter  p->addr_taken = 0;
75590091Sobrien  p->type = type;
756169702Skan  p->level = temp_slot_level;
757169702Skan  p->keep = keep;
75818334Speter
759169702Skan  pp = temp_slots_at_level (p->level);
760169702Skan  insert_slot_to_list (p, pp);
76152268Sobrien
762102794Skan  /* Create a new MEM rtx to avoid clobbering MEM flags of old slots.  */
763102794Skan  slot = gen_rtx_MEM (mode, XEXP (p->slot, 0));
764102794Skan  stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, slot, stack_slot_list);
765102794Skan
76690091Sobrien  /* If we know the alias set for the memory that will be used, use
76790091Sobrien     it.  If there's no TYPE, then we don't know anything about the
76890091Sobrien     alias set for the memory.  */
769102794Skan  set_mem_alias_set (slot, type ? get_alias_set (type) : 0);
770102794Skan  set_mem_align (slot, align);
77190091Sobrien
77290091Sobrien  /* If a type is specified, set the relevant flags.  */
77390091Sobrien  if (type != 0)
77490091Sobrien    {
775102794Skan      MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type);
776102794Skan      MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type));
77790091Sobrien    }
778169702Skan  MEM_NOTRAP_P (slot) = 1;
77990091Sobrien
780102794Skan  return slot;
78118334Speter}
78252518Sobrien
78352518Sobrien/* Allocate a temporary stack slot and record it for possible later
78452518Sobrien   reuse.  First three arguments are same as in preceding function.  */
78552518Sobrien
78652518Sobrienrtx
787132732Skanassign_stack_temp (enum machine_mode mode, HOST_WIDE_INT size, int keep)
78852518Sobrien{
78952518Sobrien  return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
79052518Sobrien}
79152268Sobrien
79296283Sobrien/* Assign a temporary.
79396283Sobrien   If TYPE_OR_DECL is a decl, then we are doing it on behalf of the decl
79496283Sobrien   and so that should be used in error messages.  In either case, we
79596283Sobrien   allocate of the given type.
79652268Sobrien   KEEP is as for assign_stack_temp.
79752268Sobrien   MEMORY_REQUIRED is 1 if the result must be addressable stack memory;
79852268Sobrien   it is 0 if a register is OK.
79952268Sobrien   DONT_PROMOTE is 1 if we should not promote values in register
80052268Sobrien   to wider modes.  */
80118334Speter
80252268Sobrienrtx
803132732Skanassign_temp (tree type_or_decl, int keep, int memory_required,
804132732Skan	     int dont_promote ATTRIBUTE_UNUSED)
80552268Sobrien{
80696283Sobrien  tree type, decl;
80796283Sobrien  enum machine_mode mode;
808169702Skan#ifdef PROMOTE_MODE
80996283Sobrien  int unsignedp;
81090091Sobrien#endif
81152268Sobrien
81296283Sobrien  if (DECL_P (type_or_decl))
81396283Sobrien    decl = type_or_decl, type = TREE_TYPE (decl);
81496283Sobrien  else
81596283Sobrien    decl = NULL, type = type_or_decl;
81696283Sobrien
81796283Sobrien  mode = TYPE_MODE (type);
818169702Skan#ifdef PROMOTE_MODE
819169702Skan  unsignedp = TYPE_UNSIGNED (type);
82096283Sobrien#endif
82196283Sobrien
82252268Sobrien  if (mode == BLKmode || memory_required)
82352268Sobrien    {
82452268Sobrien      HOST_WIDE_INT size = int_size_in_bytes (type);
82552268Sobrien      rtx tmp;
82652268Sobrien
82790091Sobrien      /* Zero sized arrays are GNU C extension.  Set size to 1 to avoid
82890091Sobrien	 problems with allocating the stack space.  */
82990091Sobrien      if (size == 0)
83090091Sobrien	size = 1;
83190091Sobrien
83252268Sobrien      /* Unfortunately, we don't yet know how to allocate variable-sized
833169702Skan	 temporaries.  However, sometimes we can find a fixed upper limit on
834169702Skan	 the size, so try that instead.  */
835169702Skan      else if (size == -1)
836169702Skan	size = max_int_size_in_bytes (type);
83752268Sobrien
83896283Sobrien      /* The size of the temporary may be too large to fit into an integer.  */
83996283Sobrien      /* ??? Not sure this should happen except for user silliness, so limit
840117404Skan	 this to things that aren't compiler-generated temporaries.  The
841169702Skan	 rest of the time we'll die in assign_stack_temp_for_type.  */
84296283Sobrien      if (decl && size == -1
84396283Sobrien	  && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
84496283Sobrien	{
845169702Skan	  error ("size of variable %q+D is too large", decl);
84696283Sobrien	  size = 1;
84796283Sobrien	}
84896283Sobrien
84952518Sobrien      tmp = assign_stack_temp_for_type (mode, size, keep, type);
85052268Sobrien      return tmp;
85152268Sobrien    }
85252268Sobrien
853169702Skan#ifdef PROMOTE_MODE
85452268Sobrien  if (! dont_promote)
85552268Sobrien    mode = promote_mode (type, mode, &unsignedp, 0);
85652268Sobrien#endif
85752268Sobrien
85852268Sobrien  return gen_reg_rtx (mode);
85952268Sobrien}
86052268Sobrien
86118334Speter/* Combine temporary stack slots which are adjacent on the stack.
86218334Speter
86318334Speter   This allows for better use of already allocated stack space.  This is only
86418334Speter   done for BLKmode slots because we can be sure that we won't have alignment
86518334Speter   problems in this case.  */
86618334Speter
867169702Skanstatic void
868132732Skancombine_temp_slots (void)
86918334Speter{
870169702Skan  struct temp_slot *p, *q, *next, *next_q;
87152268Sobrien  int num_slots;
87218334Speter
87352518Sobrien  /* We can't combine slots, because the information about which slot
87452518Sobrien     is in which alias set will be lost.  */
87552518Sobrien  if (flag_strict_aliasing)
87652518Sobrien    return;
87752518Sobrien
87890091Sobrien  /* If there are a lot of temp slots, don't do anything unless
87990091Sobrien     high levels of optimization.  */
88052268Sobrien  if (! flag_expensive_optimizations)
881169702Skan    for (p = avail_temp_slots, num_slots = 0; p; p = p->next, num_slots++)
88252268Sobrien      if (num_slots > 100 || (num_slots > 10 && optimize == 0))
88352268Sobrien	return;
88452268Sobrien
885169702Skan  for (p = avail_temp_slots; p; p = next)
88618334Speter    {
88718334Speter      int delete_p = 0;
88852268Sobrien
889169702Skan      next = p->next;
890169702Skan
891169702Skan      if (GET_MODE (p->slot) != BLKmode)
892169702Skan	continue;
893169702Skan
894169702Skan      for (q = p->next; q; q = next_q)
895169702Skan	{
896169702Skan       	  int delete_q = 0;
897169702Skan
898169702Skan	  next_q = q->next;
899169702Skan
900169702Skan	  if (GET_MODE (q->slot) != BLKmode)
901169702Skan	    continue;
902169702Skan
903169702Skan	  if (p->base_offset + p->full_size == q->base_offset)
904169702Skan	    {
905169702Skan	      /* Q comes after P; combine Q into P.  */
906169702Skan	      p->size += q->size;
907169702Skan	      p->full_size += q->full_size;
908169702Skan	      delete_q = 1;
909169702Skan	    }
910169702Skan	  else if (q->base_offset + q->full_size == p->base_offset)
911169702Skan	    {
912169702Skan	      /* P comes after Q; combine P into Q.  */
913169702Skan	      q->size += p->size;
914169702Skan	      q->full_size += p->full_size;
915169702Skan	      delete_p = 1;
916169702Skan	      break;
917169702Skan	    }
918169702Skan	  if (delete_q)
919169702Skan	    cut_slot_from_list (q, &avail_temp_slots);
920169702Skan	}
921169702Skan
92218334Speter      /* Either delete P or advance past it.  */
92318334Speter      if (delete_p)
924169702Skan	cut_slot_from_list (p, &avail_temp_slots);
92518334Speter    }
92618334Speter}
92718334Speter
92818334Speter/* Find the temp slot corresponding to the object at address X.  */
92918334Speter
93018334Speterstatic struct temp_slot *
931132732Skanfind_temp_slot_from_address (rtx x)
93218334Speter{
93318334Speter  struct temp_slot *p;
93418334Speter  rtx next;
935169702Skan  int i;
93618334Speter
937169702Skan  for (i = max_slot_level (); i >= 0; i--)
938169702Skan    for (p = *temp_slots_at_level (i); p; p = p->next)
939169702Skan      {
940169702Skan	if (XEXP (p->slot, 0) == x
941169702Skan	    || p->address == x
942169702Skan	    || (GET_CODE (x) == PLUS
943169702Skan		&& XEXP (x, 0) == virtual_stack_vars_rtx
944169702Skan		&& GET_CODE (XEXP (x, 1)) == CONST_INT
945169702Skan		&& INTVAL (XEXP (x, 1)) >= p->base_offset
946169702Skan		&& INTVAL (XEXP (x, 1)) < p->base_offset + p->full_size))
947169702Skan	  return p;
94852268Sobrien
949169702Skan	else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST)
950169702Skan	  for (next = p->address; next; next = XEXP (next, 1))
951169702Skan	    if (XEXP (next, 0) == x)
952169702Skan	      return p;
953169702Skan      }
95418334Speter
95590091Sobrien  /* If we have a sum involving a register, see if it points to a temp
95690091Sobrien     slot.  */
957169702Skan  if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0))
95890091Sobrien      && (p = find_temp_slot_from_address (XEXP (x, 0))) != 0)
95990091Sobrien    return p;
960169702Skan  else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 1))
96190091Sobrien	   && (p = find_temp_slot_from_address (XEXP (x, 1))) != 0)
96290091Sobrien    return p;
96390091Sobrien
96418334Speter  return 0;
96518334Speter}
96690091Sobrien
96718334Speter/* Indicate that NEW is an alternate way of referring to the temp slot
96852268Sobrien   that previously was known by OLD.  */
96918334Speter
97018334Spetervoid
971132732Skanupdate_temp_slot_address (rtx old, rtx new)
97218334Speter{
97390091Sobrien  struct temp_slot *p;
97418334Speter
97590091Sobrien  if (rtx_equal_p (old, new))
97690091Sobrien    return;
97790091Sobrien
97890091Sobrien  p = find_temp_slot_from_address (old);
97990091Sobrien
98090091Sobrien  /* If we didn't find one, see if both OLD is a PLUS.  If so, and NEW
98190091Sobrien     is a register, see if one operand of the PLUS is a temporary
98290091Sobrien     location.  If so, NEW points into it.  Otherwise, if both OLD and
98390091Sobrien     NEW are a PLUS and if there is a register in common between them.
98490091Sobrien     If so, try a recursive call on those values.  */
98518334Speter  if (p == 0)
98690091Sobrien    {
98790091Sobrien      if (GET_CODE (old) != PLUS)
98890091Sobrien	return;
98990091Sobrien
990169702Skan      if (REG_P (new))
99190091Sobrien	{
99290091Sobrien	  update_temp_slot_address (XEXP (old, 0), new);
99390091Sobrien	  update_temp_slot_address (XEXP (old, 1), new);
99490091Sobrien	  return;
99590091Sobrien	}
99690091Sobrien      else if (GET_CODE (new) != PLUS)
99790091Sobrien	return;
99890091Sobrien
99990091Sobrien      if (rtx_equal_p (XEXP (old, 0), XEXP (new, 0)))
100090091Sobrien	update_temp_slot_address (XEXP (old, 1), XEXP (new, 1));
100190091Sobrien      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 0)))
100290091Sobrien	update_temp_slot_address (XEXP (old, 0), XEXP (new, 1));
100390091Sobrien      else if (rtx_equal_p (XEXP (old, 0), XEXP (new, 1)))
100490091Sobrien	update_temp_slot_address (XEXP (old, 1), XEXP (new, 0));
100590091Sobrien      else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 1)))
100690091Sobrien	update_temp_slot_address (XEXP (old, 0), XEXP (new, 0));
100790091Sobrien
100890091Sobrien      return;
100990091Sobrien    }
101090091Sobrien
101190091Sobrien  /* Otherwise add an alias for the temp's address.  */
101218334Speter  else if (p->address == 0)
101318334Speter    p->address = new;
101418334Speter  else
101518334Speter    {
101618334Speter      if (GET_CODE (p->address) != EXPR_LIST)
101752268Sobrien	p->address = gen_rtx_EXPR_LIST (VOIDmode, p->address, NULL_RTX);
101818334Speter
101952268Sobrien      p->address = gen_rtx_EXPR_LIST (VOIDmode, new, p->address);
102018334Speter    }
102118334Speter}
102218334Speter
102318334Speter/* If X could be a reference to a temporary slot, mark the fact that its
102418334Speter   address was taken.  */
102518334Speter
102618334Spetervoid
1027132732Skanmark_temp_addr_taken (rtx x)
102818334Speter{
102918334Speter  struct temp_slot *p;
103018334Speter
103118334Speter  if (x == 0)
103218334Speter    return;
103318334Speter
103418334Speter  /* If X is not in memory or is at a constant address, it cannot be in
103518334Speter     a temporary slot.  */
1036169702Skan  if (!MEM_P (x) || CONSTANT_P (XEXP (x, 0)))
103718334Speter    return;
103818334Speter
103918334Speter  p = find_temp_slot_from_address (XEXP (x, 0));
104018334Speter  if (p != 0)
104118334Speter    p->addr_taken = 1;
104218334Speter}
104318334Speter
104452268Sobrien/* If X could be a reference to a temporary slot, mark that slot as
104552268Sobrien   belonging to the to one level higher than the current level.  If X
104652268Sobrien   matched one of our slots, just mark that one.  Otherwise, we can't
104752268Sobrien   easily predict which it is, so upgrade all of them.  Kept slots
104852268Sobrien   need not be touched.
104918334Speter
105018334Speter   This is called when an ({...}) construct occurs and a statement
105118334Speter   returns a value in memory.  */
105218334Speter
105318334Spetervoid
1054132732Skanpreserve_temp_slots (rtx x)
105518334Speter{
1056169702Skan  struct temp_slot *p = 0, *next;
105718334Speter
105818334Speter  /* If there is no result, we still might have some objects whose address
105918334Speter     were taken, so we need to make sure they stay around.  */
106018334Speter  if (x == 0)
106118334Speter    {
1062169702Skan      for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1063169702Skan	{
1064169702Skan	  next = p->next;
106518334Speter
1066169702Skan	  if (p->addr_taken)
1067169702Skan	    move_slot_to_level (p, temp_slot_level - 1);
1068169702Skan	}
1069169702Skan
107018334Speter      return;
107118334Speter    }
107218334Speter
107318334Speter  /* If X is a register that is being used as a pointer, see if we have
107418334Speter     a temporary slot we know it points to.  To be consistent with
107518334Speter     the code below, we really should preserve all non-kept slots
107618334Speter     if we can't find a match, but that seems to be much too costly.  */
1077169702Skan  if (REG_P (x) && REG_POINTER (x))
107818334Speter    p = find_temp_slot_from_address (x);
107918334Speter
108018334Speter  /* If X is not in memory or is at a constant address, it cannot be in
108118334Speter     a temporary slot, but it can contain something whose address was
108218334Speter     taken.  */
1083169702Skan  if (p == 0 && (!MEM_P (x) || CONSTANT_P (XEXP (x, 0))))
108418334Speter    {
1085169702Skan      for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1086169702Skan	{
1087169702Skan	  next = p->next;
108818334Speter
1089169702Skan	  if (p->addr_taken)
1090169702Skan	    move_slot_to_level (p, temp_slot_level - 1);
1091169702Skan	}
1092169702Skan
109318334Speter      return;
109418334Speter    }
109518334Speter
109618334Speter  /* First see if we can find a match.  */
109718334Speter  if (p == 0)
109818334Speter    p = find_temp_slot_from_address (XEXP (x, 0));
109918334Speter
110018334Speter  if (p != 0)
110118334Speter    {
110218334Speter      /* Move everything at our level whose address was taken to our new
110318334Speter	 level in case we used its address.  */
110418334Speter      struct temp_slot *q;
110518334Speter
110652268Sobrien      if (p->level == temp_slot_level)
110752268Sobrien	{
1108169702Skan	  for (q = *temp_slots_at_level (temp_slot_level); q; q = next)
1109169702Skan	    {
1110169702Skan	      next = q->next;
111118334Speter
1112169702Skan	      if (p != q && q->addr_taken)
1113169702Skan		move_slot_to_level (q, temp_slot_level - 1);
1114169702Skan	    }
1115169702Skan
1116169702Skan	  move_slot_to_level (p, temp_slot_level - 1);
111752268Sobrien	  p->addr_taken = 0;
111852268Sobrien	}
111918334Speter      return;
112018334Speter    }
112118334Speter
112218334Speter  /* Otherwise, preserve all non-kept slots at this level.  */
1123169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1124169702Skan    {
1125169702Skan      next = p->next;
112618334Speter
1127169702Skan      if (!p->keep)
1128169702Skan	move_slot_to_level (p, temp_slot_level - 1);
112918334Speter    }
113018334Speter}
113118334Speter
1132169702Skan/* Free all temporaries used so far.  This is normally called at the
1133169702Skan   end of generating code for a statement.  */
113418334Speter
113518334Spetervoid
1136132732Skanfree_temp_slots (void)
113718334Speter{
1138169702Skan  struct temp_slot *p, *next;
113918334Speter
1140169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1141169702Skan    {
1142169702Skan      next = p->next;
114318334Speter
1144169702Skan      if (!p->keep)
1145169702Skan	make_slot_available (p);
1146169702Skan    }
114718334Speter
114818334Speter  combine_temp_slots ();
114918334Speter}
115018334Speter
115118334Speter/* Push deeper into the nesting level for stack temporaries.  */
115218334Speter
115318334Spetervoid
1154132732Skanpush_temp_slots (void)
115518334Speter{
115618334Speter  temp_slot_level++;
115718334Speter}
115818334Speter
115918334Speter/* Pop a temporary nesting level.  All slots in use in the current level
116018334Speter   are freed.  */
116118334Speter
116218334Spetervoid
1163132732Skanpop_temp_slots (void)
116418334Speter{
1165169702Skan  struct temp_slot *p, *next;
116618334Speter
1167169702Skan  for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
1168169702Skan    {
1169169702Skan      next = p->next;
1170169702Skan      make_slot_available (p);
1171169702Skan    }
117218334Speter
117318334Speter  combine_temp_slots ();
117418334Speter
117518334Speter  temp_slot_level--;
117618334Speter}
117752268Sobrien
117852268Sobrien/* Initialize temporary slots.  */
117952268Sobrien
118052268Sobrienvoid
1181132732Skaninit_temp_slots (void)
118252268Sobrien{
118352268Sobrien  /* We have not allocated any temporaries yet.  */
1184169702Skan  avail_temp_slots = 0;
1185169702Skan  used_temp_slots = 0;
118652268Sobrien  temp_slot_level = 0;
118752268Sobrien}
118818334Speter
1189169702Skan/* These routines are responsible for converting virtual register references
1190169702Skan   to the actual hard register references once RTL generation is complete.
119118334Speter
1192169702Skan   The following four variables are used for communication between the
1193169702Skan   routines.  They contain the offsets of the virtual registers from their
1194169702Skan   respective hard registers.  */
119518334Speter
1196169702Skanstatic int in_arg_offset;
1197169702Skanstatic int var_offset;
1198169702Skanstatic int dynamic_offset;
1199169702Skanstatic int out_arg_offset;
1200169702Skanstatic int cfa_offset;
120118334Speter
1202169702Skan/* In most machines, the stack pointer register is equivalent to the bottom
1203169702Skan   of the stack.  */
120418334Speter
1205169702Skan#ifndef STACK_POINTER_OFFSET
1206169702Skan#define STACK_POINTER_OFFSET	0
1207169702Skan#endif
120818334Speter
1209169702Skan/* If not defined, pick an appropriate default for the offset of dynamically
1210169702Skan   allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
1211169702Skan   REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE.  */
121218334Speter
1213169702Skan#ifndef STACK_DYNAMIC_OFFSET
121418334Speter
1215169702Skan/* The bottom of the stack points to the actual arguments.  If
1216169702Skan   REG_PARM_STACK_SPACE is defined, this includes the space for the register
1217169702Skan   parameters.  However, if OUTGOING_REG_PARM_STACK space is not defined,
1218169702Skan   stack space for register parameters is not pushed by the caller, but
1219169702Skan   rather part of the fixed stack areas and hence not included in
1220169702Skan   `current_function_outgoing_args_size'.  Nevertheless, we must allow
1221169702Skan   for it when allocating stack dynamic objects.  */
122218334Speter
1223169702Skan#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
1224169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL)	\
1225169702Skan((ACCUMULATE_OUTGOING_ARGS						      \
1226169702Skan  ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\
1227169702Skan + (STACK_POINTER_OFFSET))						      \
1228169702Skan
1229169702Skan#else
1230169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL)	\
1231169702Skan((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0)	      \
1232169702Skan + (STACK_POINTER_OFFSET))
123352268Sobrien#endif
1234169702Skan#endif
123552268Sobrien
1236169702Skan
1237169702Skan/* Given a piece of RTX and a pointer to a HOST_WIDE_INT, if the RTX
1238169702Skan   is a virtual register, return the equivalent hard register and set the
1239169702Skan   offset indirectly through the pointer.  Otherwise, return 0.  */
124052268Sobrien
1241169702Skanstatic rtx
1242169702Skaninstantiate_new_reg (rtx x, HOST_WIDE_INT *poffset)
1243169702Skan{
1244169702Skan  rtx new;
1245169702Skan  HOST_WIDE_INT offset;
124618334Speter
1247169702Skan  if (x == virtual_incoming_args_rtx)
1248169702Skan    new = arg_pointer_rtx, offset = in_arg_offset;
1249169702Skan  else if (x == virtual_stack_vars_rtx)
1250169702Skan    new = frame_pointer_rtx, offset = var_offset;
1251169702Skan  else if (x == virtual_stack_dynamic_rtx)
1252169702Skan    new = stack_pointer_rtx, offset = dynamic_offset;
1253169702Skan  else if (x == virtual_outgoing_args_rtx)
1254169702Skan    new = stack_pointer_rtx, offset = out_arg_offset;
1255169702Skan  else if (x == virtual_cfa_rtx)
125652268Sobrien    {
1257169702Skan#ifdef FRAME_POINTER_CFA_OFFSET
1258169702Skan      new = frame_pointer_rtx;
125918334Speter#else
1260169702Skan      new = arg_pointer_rtx;
126118334Speter#endif
1262169702Skan      offset = cfa_offset;
126318334Speter    }
126452268Sobrien  else
1265169702Skan    return NULL_RTX;
126618334Speter
1267169702Skan  *poffset = offset;
1268169702Skan  return new;
126990091Sobrien}
127052268Sobrien
1271169702Skan/* A subroutine of instantiate_virtual_regs, called via for_each_rtx.
1272169702Skan   Instantiate any virtual registers present inside of *LOC.  The expression
1273169702Skan   is simplified, as much as possible, but is not to be considered "valid"
1274169702Skan   in any sense implied by the target.  If any change is made, set CHANGED
1275169702Skan   to true.  */
127690091Sobrien
1277169702Skanstatic int
1278169702Skaninstantiate_virtual_regs_in_rtx (rtx *loc, void *data)
127990091Sobrien{
1280169702Skan  HOST_WIDE_INT offset;
1281169702Skan  bool *changed = (bool *) data;
1282169702Skan  rtx x, new;
128390091Sobrien
1284169702Skan  x = *loc;
1285169702Skan  if (x == 0)
1286169702Skan    return 0;
128718334Speter
1288169702Skan  switch (GET_CODE (x))
128990091Sobrien    {
1290169702Skan    case REG:
1291169702Skan      new = instantiate_new_reg (x, &offset);
1292169702Skan      if (new)
1293169702Skan	{
1294169702Skan	  *loc = plus_constant (new, offset);
1295169702Skan	  if (changed)
1296169702Skan	    *changed = true;
1297169702Skan	}
1298169702Skan      return -1;
129918334Speter
1300169702Skan    case PLUS:
1301169702Skan      new = instantiate_new_reg (XEXP (x, 0), &offset);
1302169702Skan      if (new)
130318334Speter	{
1304169702Skan	  new = plus_constant (new, offset);
1305169702Skan	  *loc = simplify_gen_binary (PLUS, GET_MODE (x), new, XEXP (x, 1));
1306169702Skan	  if (changed)
1307169702Skan	    *changed = true;
1308169702Skan	  return -1;
130918334Speter	}
131018334Speter
1311169702Skan      /* FIXME -- from old code */
1312169702Skan	  /* If we have (plus (subreg (virtual-reg)) (const_int)), we know
1313169702Skan	     we can commute the PLUS and SUBREG because pointers into the
1314169702Skan	     frame are well-behaved.  */
1315169702Skan      break;
131618334Speter
1317169702Skan    default:
1318169702Skan      break;
131918334Speter    }
132018334Speter
1321169702Skan  return 0;
132218334Speter}
132318334Speter
1324169702Skan/* A subroutine of instantiate_virtual_regs_in_insn.  Return true if X
1325169702Skan   matches the predicate for insn CODE operand OPERAND.  */
132618334Speter
1327169702Skanstatic int
1328169702Skansafe_insn_predicate (int code, int operand, rtx x)
132918334Speter{
1330169702Skan  const struct insn_operand_data *op_data;
133152268Sobrien
1332169702Skan  if (code < 0)
1333169702Skan    return true;
133490091Sobrien
1335169702Skan  op_data = &insn_data[code].operand[operand];
1336169702Skan  if (op_data->predicate == NULL)
1337169702Skan    return true;
133818334Speter
1339169702Skan  return op_data->predicate (x, op_data->mode);
134090091Sobrien}
134118334Speter
1342169702Skan/* A subroutine of instantiate_virtual_regs.  Instantiate any virtual
1343169702Skan   registers present inside of insn.  The result will be a valid insn.  */
134418334Speter
134590091Sobrienstatic void
1346169702Skaninstantiate_virtual_regs_in_insn (rtx insn)
134790091Sobrien{
1348169702Skan  HOST_WIDE_INT offset;
1349169702Skan  int insn_code, i;
1350169702Skan  bool any_change = false;
1351169702Skan  rtx set, new, x, seq;
135218334Speter
1353169702Skan  /* There are some special cases to be handled first.  */
1354169702Skan  set = single_set (insn);
1355169702Skan  if (set)
135690091Sobrien    {
1357169702Skan      /* We're allowed to assign to a virtual register.  This is interpreted
1358169702Skan	 to mean that the underlying register gets assigned the inverse
1359169702Skan	 transformation.  This is used, for example, in the handling of
1360169702Skan	 non-local gotos.  */
1361169702Skan      new = instantiate_new_reg (SET_DEST (set), &offset);
1362169702Skan      if (new)
136390091Sobrien	{
1364169702Skan	  start_sequence ();
136518334Speter
1366169702Skan	  for_each_rtx (&SET_SRC (set), instantiate_virtual_regs_in_rtx, NULL);
1367169702Skan	  x = simplify_gen_binary (PLUS, GET_MODE (new), SET_SRC (set),
1368169702Skan				   GEN_INT (-offset));
1369169702Skan	  x = force_operand (x, new);
1370169702Skan	  if (x != new)
1371169702Skan	    emit_move_insn (new, x);
137290091Sobrien
1373169702Skan	  seq = get_insns ();
1374169702Skan	  end_sequence ();
137590091Sobrien
1376169702Skan	  emit_insn_before (seq, insn);
1377169702Skan	  delete_insn (insn);
1378169702Skan	  return;
137918334Speter	}
138052518Sobrien
1381169702Skan      /* Handle a straight copy from a virtual register by generating a
1382169702Skan	 new add insn.  The difference between this and falling through
1383169702Skan	 to the generic case is avoiding a new pseudo and eliminating a
1384169702Skan	 move insn in the initial rtl stream.  */
1385169702Skan      new = instantiate_new_reg (SET_SRC (set), &offset);
1386169702Skan      if (new && offset != 0
1387169702Skan	  && REG_P (SET_DEST (set))
1388169702Skan	  && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
138952518Sobrien	{
1390169702Skan	  start_sequence ();
139190091Sobrien
1392169702Skan	  x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS,
1393169702Skan				   new, GEN_INT (offset), SET_DEST (set),
1394169702Skan				   1, OPTAB_LIB_WIDEN);
1395169702Skan	  if (x != SET_DEST (set))
1396169702Skan	    emit_move_insn (SET_DEST (set), x);
139790091Sobrien
1398169702Skan	  seq = get_insns ();
1399169702Skan	  end_sequence ();
140090091Sobrien
1401169702Skan	  emit_insn_before (seq, insn);
1402169702Skan	  delete_insn (insn);
1403169702Skan	  return;
140452518Sobrien	}
140590091Sobrien
1406169702Skan      extract_insn (insn);
1407169702Skan      insn_code = INSN_CODE (insn);
140818334Speter
1409169702Skan      /* Handle a plus involving a virtual register by determining if the
1410169702Skan	 operands remain valid if they're modified in place.  */
1411169702Skan      if (GET_CODE (SET_SRC (set)) == PLUS
1412169702Skan	  && recog_data.n_operands >= 3
1413169702Skan	  && recog_data.operand_loc[1] == &XEXP (SET_SRC (set), 0)
1414169702Skan	  && recog_data.operand_loc[2] == &XEXP (SET_SRC (set), 1)
1415169702Skan	  && GET_CODE (recog_data.operand[2]) == CONST_INT
1416169702Skan	  && (new = instantiate_new_reg (recog_data.operand[1], &offset)))
141752268Sobrien	{
1418169702Skan	  offset += INTVAL (recog_data.operand[2]);
141952268Sobrien
1420169702Skan	  /* If the sum is zero, then replace with a plain move.  */
1421169702Skan	  if (offset == 0
1422169702Skan	      && REG_P (SET_DEST (set))
1423169702Skan	      && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER)
142452268Sobrien	    {
142552518Sobrien	      start_sequence ();
1426169702Skan	      emit_move_insn (SET_DEST (set), new);
1427117404Skan	      seq = get_insns ();
142852518Sobrien	      end_sequence ();
142952518Sobrien
143052518Sobrien	      emit_insn_before (seq, insn);
1431169702Skan	      delete_insn (insn);
1432169702Skan	      return;
143352268Sobrien	    }
143452268Sobrien
1435169702Skan	  x = gen_int_mode (offset, recog_data.operand_mode[2]);
143618334Speter
1437169702Skan	  /* Using validate_change and apply_change_group here leaves
1438169702Skan	     recog_data in an invalid state.  Since we know exactly what
1439169702Skan	     we want to check, do those two by hand.  */
1440169702Skan	  if (safe_insn_predicate (insn_code, 1, new)
1441169702Skan	      && safe_insn_predicate (insn_code, 2, x))
144218334Speter	    {
1443169702Skan	      *recog_data.operand_loc[1] = recog_data.operand[1] = new;
1444169702Skan	      *recog_data.operand_loc[2] = recog_data.operand[2] = x;
1445169702Skan	      any_change = true;
1446169702Skan
1447169702Skan	      /* Fall through into the regular operand fixup loop in
1448169702Skan		 order to take care of operands other than 1 and 2.  */
144918334Speter	    }
145018334Speter	}
1451169702Skan    }
1452169702Skan  else
1453169702Skan    {
1454169702Skan      extract_insn (insn);
1455169702Skan      insn_code = INSN_CODE (insn);
1456169702Skan    }
145718334Speter
1458169702Skan  /* In the general case, we expect virtual registers to appear only in
1459169702Skan     operands, and then only as either bare registers or inside memories.  */
1460169702Skan  for (i = 0; i < recog_data.n_operands; ++i)
1461169702Skan    {
1462169702Skan      x = recog_data.operand[i];
1463169702Skan      switch (GET_CODE (x))
146418334Speter	{
1465169702Skan	case MEM:
1466169702Skan	  {
1467169702Skan	    rtx addr = XEXP (x, 0);
1468169702Skan	    bool changed = false;
146918334Speter
1470169702Skan	    for_each_rtx (&addr, instantiate_virtual_regs_in_rtx, &changed);
1471169702Skan	    if (!changed)
1472169702Skan	      continue;
147318334Speter
1474169702Skan	    start_sequence ();
1475169702Skan	    x = replace_equiv_address (x, addr);
1476169702Skan	    seq = get_insns ();
1477169702Skan	    end_sequence ();
1478169702Skan	    if (seq)
1479169702Skan	      emit_insn_before (seq, insn);
1480169702Skan	  }
1481169702Skan	  break;
148218334Speter
1483169702Skan	case REG:
1484169702Skan	  new = instantiate_new_reg (x, &offset);
1485169702Skan	  if (new == NULL)
1486169702Skan	    continue;
1487169702Skan	  if (offset == 0)
1488169702Skan	    x = new;
148952268Sobrien	  else
149018334Speter	    {
1491169702Skan	      start_sequence ();
149218334Speter
1493169702Skan	      /* Careful, special mode predicates may have stuff in
1494169702Skan		 insn_data[insn_code].operand[i].mode that isn't useful
1495169702Skan		 to us for computing a new value.  */
1496169702Skan	      /* ??? Recognize address_operand and/or "p" constraints
1497169702Skan		 to see if (plus new offset) is a valid before we put
1498169702Skan		 this through expand_simple_binop.  */
1499169702Skan	      x = expand_simple_binop (GET_MODE (x), PLUS, new,
1500169702Skan				       GEN_INT (offset), NULL_RTX,
1501169702Skan				       1, OPTAB_LIB_WIDEN);
1502169702Skan	      seq = get_insns ();
1503169702Skan	      end_sequence ();
1504169702Skan	      emit_insn_before (seq, insn);
150518334Speter	    }
1506169702Skan	  break;
150718334Speter
1508169702Skan	case SUBREG:
1509169702Skan	  new = instantiate_new_reg (SUBREG_REG (x), &offset);
1510169702Skan	  if (new == NULL)
1511169702Skan	    continue;
1512169702Skan	  if (offset != 0)
151318334Speter	    {
1514169702Skan	      start_sequence ();
1515169702Skan	      new = expand_simple_binop (GET_MODE (new), PLUS, new,
1516169702Skan					 GEN_INT (offset), NULL_RTX,
1517169702Skan					 1, OPTAB_LIB_WIDEN);
1518169702Skan	      seq = get_insns ();
1519169702Skan	      end_sequence ();
1520169702Skan	      emit_insn_before (seq, insn);
152118334Speter	    }
1522169702Skan	  x = simplify_gen_subreg (recog_data.operand_mode[i], new,
1523169702Skan				   GET_MODE (new), SUBREG_BYTE (x));
1524169702Skan	  break;
152518334Speter
1526169702Skan	default:
1527169702Skan	  continue;
152818334Speter	}
152918334Speter
1530169702Skan      /* At this point, X contains the new value for the operand.
1531169702Skan	 Validate the new value vs the insn predicate.  Note that
1532169702Skan	 asm insns will have insn_code -1 here.  */
1533169702Skan      if (!safe_insn_predicate (insn_code, i, x))
153452268Sobrien	{
1535169702Skan	  start_sequence ();
1536169702Skan	  x = force_reg (insn_data[insn_code].operand[i].mode, x);
1537169702Skan	  seq = get_insns ();
1538169702Skan	  end_sequence ();
1539169702Skan	  if (seq)
1540169702Skan	    emit_insn_before (seq, insn);
154152268Sobrien	}
154252268Sobrien
1543169702Skan      *recog_data.operand_loc[i] = recog_data.operand[i] = x;
1544169702Skan      any_change = true;
1545169702Skan    }
154690091Sobrien
1547169702Skan  if (any_change)
1548169702Skan    {
1549169702Skan      /* Propagate operand changes into the duplicates.  */
1550169702Skan      for (i = 0; i < recog_data.n_dups; ++i)
1551169702Skan	*recog_data.dup_loc[i]
1552169702Skan	  = recog_data.operand[(unsigned)recog_data.dup_num[i]];
155318334Speter
1554169702Skan      /* Force re-recognition of the instruction for validation.  */
1555169702Skan      INSN_CODE (insn) = -1;
155618334Speter    }
155718334Speter
1558169702Skan  if (asm_noperands (PATTERN (insn)) >= 0)
155918334Speter    {
1560169702Skan      if (!check_asm_operands (PATTERN (insn)))
156118334Speter	{
1562169702Skan	  error_for_asm (insn, "impossible constraint in %<asm%>");
1563169702Skan	  delete_insn (insn);
156418334Speter	}
156518334Speter    }
1566169702Skan  else
1567169702Skan    {
1568169702Skan      if (recog_memoized (insn) < 0)
1569169702Skan	fatal_insn_not_found (insn);
1570169702Skan    }
157118334Speter}
157218334Speter
1573169702Skan/* Subroutine of instantiate_decls.  Given RTL representing a decl,
1574169702Skan   do any instantiation required.  */
157596283Sobrien
1576169702Skanstatic void
1577169702Skaninstantiate_decl (rtx x)
157818334Speter{
1579169702Skan  rtx addr;
158018334Speter
1581169702Skan  if (x == 0)
1582169702Skan    return;
158318334Speter
1584169702Skan  /* If this is a CONCAT, recurse for the pieces.  */
1585169702Skan  if (GET_CODE (x) == CONCAT)
1586169702Skan    {
1587169702Skan      instantiate_decl (XEXP (x, 0));
1588169702Skan      instantiate_decl (XEXP (x, 1));
1589169702Skan      return;
1590169702Skan    }
159196283Sobrien
1592169702Skan  /* If this is not a MEM, no need to do anything.  Similarly if the
1593169702Skan     address is a constant or a register that is not a virtual register.  */
1594169702Skan  if (!MEM_P (x))
1595169702Skan    return;
159690091Sobrien
1597169702Skan  addr = XEXP (x, 0);
1598169702Skan  if (CONSTANT_P (addr)
1599169702Skan      || (REG_P (addr)
1600169702Skan	  && (REGNO (addr) < FIRST_VIRTUAL_REGISTER
1601169702Skan	      || REGNO (addr) > LAST_VIRTUAL_REGISTER)))
1602169702Skan    return;
1603117404Skan
1604169702Skan  for_each_rtx (&XEXP (x, 0), instantiate_virtual_regs_in_rtx, NULL);
160518334Speter}
160618334Speter
1607169702Skan/* Helper for instantiate_decls called via walk_tree: Process all decls
1608169702Skan   in the given DECL_VALUE_EXPR.  */
160918334Speter
1610169702Skanstatic tree
1611169702Skaninstantiate_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
161218334Speter{
1613169702Skan  tree t = *tp;
1614169702Skan  if (! EXPR_P (t))
161518334Speter    {
1616169702Skan      *walk_subtrees = 0;
1617169702Skan      if (DECL_P (t) && DECL_RTL_SET_P (t))
1618169702Skan	instantiate_decl (DECL_RTL (t));
161918334Speter    }
1620169702Skan  return NULL;
162118334Speter}
162218334Speter
1623169702Skan/* Subroutine of instantiate_decls: Process all decls in the given
1624169702Skan   BLOCK node and all its subblocks.  */
1625169702Skan
1626169702Skanstatic void
1627169702Skaninstantiate_decls_1 (tree let)
162818334Speter{
1629169702Skan  tree t;
163018334Speter
1631169702Skan  for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
163218334Speter    {
1633169702Skan      if (DECL_RTL_SET_P (t))
1634169702Skan	instantiate_decl (DECL_RTL (t));
1635169702Skan      if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t))
163618334Speter	{
1637169702Skan	  tree v = DECL_VALUE_EXPR (t);
1638169702Skan	  walk_tree (&v, instantiate_expr, NULL, NULL);
163918334Speter	}
164018334Speter    }
164118334Speter
1642169702Skan  /* Process all subblocks.  */
1643169702Skan  for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
1644169702Skan    instantiate_decls_1 (t);
164518334Speter}
164618334Speter
1647169702Skan/* Scan all decls in FNDECL (both variables and parameters) and instantiate
1648169702Skan   all virtual registers in their DECL_RTL's.  */
164918334Speter
165018334Speterstatic void
1651169702Skaninstantiate_decls (tree fndecl)
165218334Speter{
1653169702Skan  tree decl;
165418334Speter
1655169702Skan  /* Process all parameters of the function.  */
1656169702Skan  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
165718334Speter    {
1658169702Skan      instantiate_decl (DECL_RTL (decl));
1659169702Skan      instantiate_decl (DECL_INCOMING_RTL (decl));
1660169702Skan      if (DECL_HAS_VALUE_EXPR_P (decl))
166118334Speter	{
1662169702Skan	  tree v = DECL_VALUE_EXPR (decl);
1663169702Skan	  walk_tree (&v, instantiate_expr, NULL, NULL);
1664169702Skan	}
1665169702Skan    }
166618334Speter
1667169702Skan  /* Now process all variables defined in the function or its subblocks.  */
1668169702Skan  instantiate_decls_1 (DECL_INITIAL (fndecl));
1669169702Skan}
167018334Speter
1671169702Skan/* Pass through the INSNS of function FNDECL and convert virtual register
1672169702Skan   references to hard register references.  */
167318334Speter
1674169702Skanstatic unsigned int
1675169702Skaninstantiate_virtual_regs (void)
1676169702Skan{
1677169702Skan  rtx insn;
167818334Speter
1679169702Skan  /* Compute the offsets to use for this function.  */
1680169702Skan  in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
1681169702Skan  var_offset = STARTING_FRAME_OFFSET;
1682169702Skan  dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
1683169702Skan  out_arg_offset = STACK_POINTER_OFFSET;
1684169702Skan#ifdef FRAME_POINTER_CFA_OFFSET
1685169702Skan  cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
1686169702Skan#else
1687169702Skan  cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
1688169702Skan#endif
168918334Speter
1690169702Skan  /* Initialize recognition, indicating that volatile is OK.  */
1691169702Skan  init_recog ();
169218334Speter
1693169702Skan  /* Scan through all the insns, instantiating every virtual register still
1694169702Skan     present.  */
1695169702Skan  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1696169702Skan    if (INSN_P (insn))
1697169702Skan      {
1698169702Skan	/* These patterns in the instruction stream can never be recognized.
1699169702Skan	   Fortunately, they shouldn't contain virtual registers either.  */
1700169702Skan	if (GET_CODE (PATTERN (insn)) == USE
1701169702Skan	    || GET_CODE (PATTERN (insn)) == CLOBBER
1702169702Skan	    || GET_CODE (PATTERN (insn)) == ADDR_VEC
1703169702Skan	    || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
1704169702Skan	    || GET_CODE (PATTERN (insn)) == ASM_INPUT)
1705169702Skan	  continue;
170618334Speter
1707169702Skan	instantiate_virtual_regs_in_insn (insn);
170818334Speter
1709169702Skan	if (INSN_DELETED_P (insn))
1710169702Skan	  continue;
171118334Speter
1712169702Skan	for_each_rtx (&REG_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL);
171318334Speter
1714169702Skan	/* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
1715169702Skan	if (GET_CODE (insn) == CALL_INSN)
1716169702Skan	  for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn),
1717169702Skan			instantiate_virtual_regs_in_rtx, NULL);
1718169702Skan      }
171918334Speter
1720169702Skan  /* Instantiate the virtual registers in the DECLs for debugging purposes.  */
1721169702Skan  instantiate_decls (current_function_decl);
172218334Speter
1723169702Skan  /* Indicate that, from now on, assign_stack_local should use
1724169702Skan     frame_pointer_rtx.  */
1725169702Skan  virtuals_instantiated = 1;
1726169702Skan  return 0;
1727169702Skan}
172818334Speter
1729169702Skanstruct tree_opt_pass pass_instantiate_virtual_regs =
1730169702Skan{
1731169702Skan  "vregs",                              /* name */
1732169702Skan  NULL,                                 /* gate */
1733169702Skan  instantiate_virtual_regs,             /* execute */
1734169702Skan  NULL,                                 /* sub */
1735169702Skan  NULL,                                 /* next */
1736169702Skan  0,                                    /* static_pass_number */
1737169702Skan  0,                                    /* tv_id */
1738169702Skan  0,                                    /* properties_required */
1739169702Skan  0,                                    /* properties_provided */
1740169702Skan  0,                                    /* properties_destroyed */
1741169702Skan  0,                                    /* todo_flags_start */
1742169702Skan  TODO_dump_func,                       /* todo_flags_finish */
1743169702Skan  0                                     /* letter */
1744169702Skan};
174518334Speter
174618334Speter
1747169702Skan/* Return 1 if EXP is an aggregate type (or a value with aggregate type).
1748169702Skan   This means a type for which function calls must pass an address to the
1749169702Skan   function or get an address back from the function.
1750169702Skan   EXP may be a type node or an expression (whose type is tested).  */
175118334Speter
1752169702Skanint
1753169702Skanaggregate_value_p (tree exp, tree fntype)
1754169702Skan{
1755169702Skan  int i, regno, nregs;
1756169702Skan  rtx reg;
175718334Speter
1758169702Skan  tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
175918334Speter
1760169702Skan  /* DECL node associated with FNTYPE when relevant, which we might need to
1761169702Skan     check for by-invisible-reference returns, typically for CALL_EXPR input
1762169702Skan     EXPressions.  */
1763169702Skan  tree fndecl = NULL_TREE;
1764169702Skan
1765169702Skan  if (fntype)
1766169702Skan    switch (TREE_CODE (fntype))
1767169702Skan      {
1768169702Skan      case CALL_EXPR:
1769169702Skan	fndecl = get_callee_fndecl (fntype);
1770169702Skan	fntype = fndecl ? TREE_TYPE (fndecl) : 0;
1771169702Skan	break;
1772169702Skan      case FUNCTION_DECL:
1773169702Skan	fndecl = fntype;
1774169702Skan	fntype = TREE_TYPE (fndecl);
1775169702Skan	break;
1776169702Skan      case FUNCTION_TYPE:
1777169702Skan      case METHOD_TYPE:
1778169702Skan        break;
1779169702Skan      case IDENTIFIER_NODE:
1780169702Skan	fntype = 0;
1781169702Skan	break;
1782169702Skan      default:
1783169702Skan	/* We don't expect other rtl types here.  */
1784169702Skan	gcc_unreachable ();
1785169702Skan      }
178618334Speter
1787169702Skan  if (TREE_CODE (type) == VOID_TYPE)
1788169702Skan    return 0;
178918334Speter
1790169702Skan  /* If the front end has decided that this needs to be passed by
1791169702Skan     reference, do so.  */
1792169702Skan  if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL)
1793169702Skan      && DECL_BY_REFERENCE (exp))
1794169702Skan    return 1;
179518334Speter
1796169702Skan  /* If the EXPression is a CALL_EXPR, honor DECL_BY_REFERENCE set on the
1797169702Skan     called function RESULT_DECL, meaning the function returns in memory by
1798169702Skan     invisible reference.  This check lets front-ends not set TREE_ADDRESSABLE
1799169702Skan     on the function type, which used to be the way to request such a return
1800169702Skan     mechanism but might now be causing troubles at gimplification time if
1801169702Skan     temporaries with the function type need to be created.  */
1802169702Skan  if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl)
1803169702Skan      && DECL_BY_REFERENCE (DECL_RESULT (fndecl)))
1804169702Skan    return 1;
1805169702Skan
1806169702Skan  if (targetm.calls.return_in_memory (type, fntype))
1807169702Skan    return 1;
1808169702Skan  /* Types that are TREE_ADDRESSABLE must be constructed in memory,
1809169702Skan     and thus can't be returned in registers.  */
1810169702Skan  if (TREE_ADDRESSABLE (type))
1811169702Skan    return 1;
1812169702Skan  if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
1813169702Skan    return 1;
1814169702Skan  /* Make sure we have suitable call-clobbered regs to return
1815169702Skan     the value in; if not, we must return it in memory.  */
1816169702Skan  reg = hard_function_value (type, 0, fntype, 0);
181718334Speter
1818169702Skan  /* If we have something other than a REG (e.g. a PARALLEL), then assume
1819169702Skan     it is OK.  */
1820169702Skan  if (!REG_P (reg))
1821169702Skan    return 0;
182218334Speter
1823169702Skan  regno = REGNO (reg);
1824169702Skan  nregs = hard_regno_nregs[regno][TYPE_MODE (type)];
1825169702Skan  for (i = 0; i < nregs; i++)
1826169702Skan    if (! call_used_regs[regno + i])
1827169702Skan      return 1;
1828169702Skan  return 0;
1829169702Skan}
1830169702Skan
1831169702Skan/* Return true if we should assign DECL a pseudo register; false if it
1832169702Skan   should live on the local stack.  */
183318334Speter
1834169702Skanbool
1835169702Skanuse_register_for_decl (tree decl)
183652268Sobrien{
1837169702Skan  /* Honor volatile.  */
1838169702Skan  if (TREE_SIDE_EFFECTS (decl))
1839169702Skan    return false;
184090091Sobrien
1841169702Skan  /* Honor addressability.  */
1842169702Skan  if (TREE_ADDRESSABLE (decl))
1843169702Skan    return false;
184490091Sobrien
1845169702Skan  /* Only register-like things go in registers.  */
1846169702Skan  if (DECL_MODE (decl) == BLKmode)
1847169702Skan    return false;
184852268Sobrien
1849169702Skan  /* If -ffloat-store specified, don't put explicit float variables
1850169702Skan     into registers.  */
1851169702Skan  /* ??? This should be checked after DECL_ARTIFICIAL, but tree-ssa
1852169702Skan     propagates values across these stores, and it probably shouldn't.  */
1853169702Skan  if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (decl)))
1854169702Skan    return false;
185552268Sobrien
1856169702Skan  /* If we're not interested in tracking debugging information for
1857169702Skan     this decl, then we can certainly put it in a register.  */
1858169702Skan  if (DECL_IGNORED_P (decl))
1859169702Skan    return true;
186052268Sobrien
1861169702Skan  return (optimize || DECL_REGISTER (decl));
1862169702Skan}
186390091Sobrien
1864169702Skan/* Return true if TYPE should be passed by invisible reference.  */
186590091Sobrien
1866169702Skanbool
1867169702Skanpass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode,
1868169702Skan		   tree type, bool named_arg)
1869169702Skan{
1870169702Skan  if (type)
1871132732Skan    {
1872169702Skan      /* If this type contains non-trivial constructors, then it is
1873169702Skan	 forbidden for the middle-end to create any new copies.  */
1874169702Skan      if (TREE_ADDRESSABLE (type))
1875169702Skan	return true;
187690091Sobrien
1877169702Skan      /* GCC post 3.4 passes *all* variable sized types by reference.  */
1878169702Skan      if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1879169702Skan	return true;
1880132732Skan    }
1881132732Skan
1882169702Skan  return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
188352268Sobrien}
188452268Sobrien
1885169702Skan/* Return true if TYPE, which is passed by reference, should be callee
1886169702Skan   copied instead of caller copied.  */
188752268Sobrien
1888169702Skanbool
1889169702Skanreference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode,
1890169702Skan			 tree type, bool named_arg)
189152268Sobrien{
1892169702Skan  if (type && TREE_ADDRESSABLE (type))
1893169702Skan    return false;
1894169702Skan  return targetm.calls.callee_copies (ca, mode, type, named_arg);
189552268Sobrien}
189652268Sobrien
1897169702Skan/* Structures to communicate between the subroutines of assign_parms.
1898169702Skan   The first holds data persistent across all parameters, the second
1899169702Skan   is cleared out for each parameter.  */
190052268Sobrien
1901169702Skanstruct assign_parm_data_all
1902169702Skan{
1903169702Skan  CUMULATIVE_ARGS args_so_far;
1904169702Skan  struct args_size stack_args_size;
1905169702Skan  tree function_result_decl;
1906169702Skan  tree orig_fnargs;
1907169702Skan  rtx conversion_insns;
1908169702Skan  HOST_WIDE_INT pretend_args_size;
1909169702Skan  HOST_WIDE_INT extra_pretend_bytes;
1910169702Skan  int reg_parm_stack_space;
1911169702Skan};
1912169702Skan
1913169702Skanstruct assign_parm_data_one
1914169702Skan{
1915169702Skan  tree nominal_type;
1916169702Skan  tree passed_type;
1917169702Skan  rtx entry_parm;
1918169702Skan  rtx stack_parm;
1919169702Skan  enum machine_mode nominal_mode;
1920169702Skan  enum machine_mode passed_mode;
1921169702Skan  enum machine_mode promoted_mode;
1922169702Skan  struct locate_and_pad_arg_data locate;
1923169702Skan  int partial;
1924169702Skan  BOOL_BITFIELD named_arg : 1;
1925169702Skan  BOOL_BITFIELD passed_pointer : 1;
1926169702Skan  BOOL_BITFIELD on_stack : 1;
1927169702Skan  BOOL_BITFIELD loaded_in_reg : 1;
1928169702Skan};
1929169702Skan
1930169702Skan/* A subroutine of assign_parms.  Initialize ALL.  */
1931169702Skan
193252268Sobrienstatic void
1933169702Skanassign_parms_initialize_all (struct assign_parm_data_all *all)
193452268Sobrien{
1935169702Skan  tree fntype;
193690091Sobrien
1937169702Skan  memset (all, 0, sizeof (*all));
193852268Sobrien
1939169702Skan  fntype = TREE_TYPE (current_function_decl);
194052268Sobrien
1941169702Skan#ifdef INIT_CUMULATIVE_INCOMING_ARGS
1942169702Skan  INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far, fntype, NULL_RTX);
1943169702Skan#else
1944169702Skan  INIT_CUMULATIVE_ARGS (all->args_so_far, fntype, NULL_RTX,
1945169702Skan			current_function_decl, -1);
1946169702Skan#endif
194790091Sobrien
1948169702Skan#ifdef REG_PARM_STACK_SPACE
1949169702Skan  all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl);
1950169702Skan#endif
195152268Sobrien}
195252268Sobrien
1953169702Skan/* If ARGS contains entries with complex types, split the entry into two
1954169702Skan   entries of the component type.  Return a new list of substitutions are
1955169702Skan   needed, else the old list.  */
195652518Sobrien
1957169702Skanstatic tree
1958169702Skansplit_complex_args (tree args)
195952268Sobrien{
1960169702Skan  tree p;
196152268Sobrien
1962169702Skan  /* Before allocating memory, check for the common case of no complex.  */
1963169702Skan  for (p = args; p; p = TREE_CHAIN (p))
196452268Sobrien    {
1965169702Skan      tree type = TREE_TYPE (p);
1966169702Skan      if (TREE_CODE (type) == COMPLEX_TYPE
1967169702Skan	  && targetm.calls.split_complex_arg (type))
1968169702Skan        goto found;
196990091Sobrien    }
1970169702Skan  return args;
197190091Sobrien
1972169702Skan found:
1973169702Skan  args = copy_list (args);
1974117404Skan
1975169702Skan  for (p = args; p; p = TREE_CHAIN (p))
197652268Sobrien    {
1977169702Skan      tree type = TREE_TYPE (p);
1978169702Skan      if (TREE_CODE (type) == COMPLEX_TYPE
1979169702Skan	  && targetm.calls.split_complex_arg (type))
198052268Sobrien	{
1981169702Skan	  tree decl;
1982169702Skan	  tree subtype = TREE_TYPE (type);
1983169702Skan	  bool addressable = TREE_ADDRESSABLE (p);
198452518Sobrien
1985169702Skan	  /* Rewrite the PARM_DECL's type with its component.  */
1986169702Skan	  TREE_TYPE (p) = subtype;
1987169702Skan	  DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
1988169702Skan	  DECL_MODE (p) = VOIDmode;
1989169702Skan	  DECL_SIZE (p) = NULL;
1990169702Skan	  DECL_SIZE_UNIT (p) = NULL;
1991169702Skan	  /* If this arg must go in memory, put it in a pseudo here.
1992169702Skan	     We can't allow it to go in memory as per normal parms,
1993169702Skan	     because the usual place might not have the imag part
1994169702Skan	     adjacent to the real part.  */
1995169702Skan	  DECL_ARTIFICIAL (p) = addressable;
1996169702Skan	  DECL_IGNORED_P (p) = addressable;
1997169702Skan	  TREE_ADDRESSABLE (p) = 0;
1998169702Skan	  layout_decl (p, 0);
1999132732Skan
2000169702Skan	  /* Build a second synthetic decl.  */
2001169702Skan	  decl = build_decl (PARM_DECL, NULL_TREE, subtype);
2002169702Skan	  DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
2003169702Skan	  DECL_ARTIFICIAL (decl) = addressable;
2004169702Skan	  DECL_IGNORED_P (decl) = addressable;
2005169702Skan	  layout_decl (decl, 0);
200652518Sobrien
2007169702Skan	  /* Splice it in; skip the new decl.  */
2008169702Skan	  TREE_CHAIN (decl) = TREE_CHAIN (p);
2009169702Skan	  TREE_CHAIN (p) = decl;
2010169702Skan	  p = decl;
2011169702Skan	}
2012169702Skan    }
201352518Sobrien
2014169702Skan  return args;
2015169702Skan}
201652518Sobrien
2017169702Skan/* A subroutine of assign_parms.  Adjust the parameter list to incorporate
2018169702Skan   the hidden struct return argument, and (abi willing) complex args.
2019169702Skan   Return the new parameter list.  */
202052518Sobrien
2021169702Skanstatic tree
2022169702Skanassign_parms_augmented_arg_list (struct assign_parm_data_all *all)
2023169702Skan{
2024169702Skan  tree fndecl = current_function_decl;
2025169702Skan  tree fntype = TREE_TYPE (fndecl);
2026169702Skan  tree fnargs = DECL_ARGUMENTS (fndecl);
202752518Sobrien
2028169702Skan  /* If struct value address is treated as the first argument, make it so.  */
2029169702Skan  if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
2030169702Skan      && ! current_function_returns_pcc_struct
2031169702Skan      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
2032169702Skan    {
2033169702Skan      tree type = build_pointer_type (TREE_TYPE (fntype));
2034169702Skan      tree decl;
203590091Sobrien
2036169702Skan      decl = build_decl (PARM_DECL, NULL_TREE, type);
2037169702Skan      DECL_ARG_TYPE (decl) = type;
2038169702Skan      DECL_ARTIFICIAL (decl) = 1;
2039169702Skan      DECL_IGNORED_P (decl) = 1;
204052518Sobrien
2041169702Skan      TREE_CHAIN (decl) = fnargs;
2042169702Skan      fnargs = decl;
2043169702Skan      all->function_result_decl = decl;
2044169702Skan    }
204552518Sobrien
2046169702Skan  all->orig_fnargs = fnargs;
2047132732Skan
2048169702Skan  /* If the target wants to split complex arguments into scalars, do so.  */
2049169702Skan  if (targetm.calls.split_complex_arg)
2050169702Skan    fnargs = split_complex_args (fnargs);
2051132732Skan
2052169702Skan  return fnargs;
2053169702Skan}
205452518Sobrien
2055169702Skan/* A subroutine of assign_parms.  Examine PARM and pull out type and mode
2056169702Skan   data for the parameter.  Incorporate ABI specifics such as pass-by-
2057169702Skan   reference and type promotion.  */
205852518Sobrien
2059169702Skanstatic void
2060169702Skanassign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
2061169702Skan			     struct assign_parm_data_one *data)
2062169702Skan{
2063169702Skan  tree nominal_type, passed_type;
2064169702Skan  enum machine_mode nominal_mode, passed_mode, promoted_mode;
2065117404Skan
2066169702Skan  memset (data, 0, sizeof (*data));
206752518Sobrien
2068169702Skan  /* NAMED_ARG is a mis-nomer.  We really mean 'non-varadic'. */
2069169702Skan  if (!current_function_stdarg)
2070169702Skan    data->named_arg = 1;  /* No varadic parms.  */
2071169702Skan  else if (TREE_CHAIN (parm))
2072169702Skan    data->named_arg = 1;  /* Not the last non-varadic parm. */
2073169702Skan  else if (targetm.calls.strict_argument_naming (&all->args_so_far))
2074169702Skan    data->named_arg = 1;  /* Only varadic ones are unnamed.  */
2075169702Skan  else
2076169702Skan    data->named_arg = 0;  /* Treat as varadic.  */
207752518Sobrien
2078169702Skan  nominal_type = TREE_TYPE (parm);
2079169702Skan  passed_type = DECL_ARG_TYPE (parm);
208052518Sobrien
2081169702Skan  /* Look out for errors propagating this far.  Also, if the parameter's
2082169702Skan     type is void then its value doesn't matter.  */
2083169702Skan  if (TREE_TYPE (parm) == error_mark_node
2084169702Skan      /* This can happen after weird syntax errors
2085169702Skan	 or if an enum type is defined among the parms.  */
2086169702Skan      || TREE_CODE (parm) != PARM_DECL
2087169702Skan      || passed_type == NULL
2088169702Skan      || VOID_TYPE_P (nominal_type))
2089169702Skan    {
2090169702Skan      nominal_type = passed_type = void_type_node;
2091169702Skan      nominal_mode = passed_mode = promoted_mode = VOIDmode;
2092169702Skan      goto egress;
2093169702Skan    }
209490091Sobrien
2095169702Skan  /* Find mode of arg as it is passed, and mode of arg as it should be
2096169702Skan     during execution of this function.  */
2097169702Skan  passed_mode = TYPE_MODE (passed_type);
2098169702Skan  nominal_mode = TYPE_MODE (nominal_type);
209952518Sobrien
2100169702Skan  /* If the parm is to be passed as a transparent union, use the type of
2101169702Skan     the first field for the tests below.  We have already verified that
2102169702Skan     the modes are the same.  */
2103169702Skan  if (TREE_CODE (passed_type) == UNION_TYPE
2104169702Skan      && TYPE_TRANSPARENT_UNION (passed_type))
2105169702Skan    passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
210652518Sobrien
2107169702Skan  /* See if this arg was passed by invisible reference.  */
2108169702Skan  if (pass_by_reference (&all->args_so_far, passed_mode,
2109169702Skan			 passed_type, data->named_arg))
2110169702Skan    {
2111169702Skan      passed_type = nominal_type = build_pointer_type (passed_type);
2112169702Skan      data->passed_pointer = true;
2113169702Skan      passed_mode = nominal_mode = Pmode;
211452268Sobrien    }
211552268Sobrien
2116169702Skan  /* Find mode as it is passed by the ABI.  */
2117169702Skan  promoted_mode = passed_mode;
2118169702Skan  if (targetm.calls.promote_function_args (TREE_TYPE (current_function_decl)))
211952268Sobrien    {
2120169702Skan      int unsignedp = TYPE_UNSIGNED (passed_type);
2121169702Skan      promoted_mode = promote_mode (passed_type, promoted_mode,
2122169702Skan				    &unsignedp, 1);
212352268Sobrien    }
212490091Sobrien
2125169702Skan egress:
2126169702Skan  data->nominal_type = nominal_type;
2127169702Skan  data->passed_type = passed_type;
2128169702Skan  data->nominal_mode = nominal_mode;
2129169702Skan  data->passed_mode = passed_mode;
2130169702Skan  data->promoted_mode = promoted_mode;
213152268Sobrien}
213252268Sobrien
2133169702Skan/* A subroutine of assign_parms.  Invoke setup_incoming_varargs.  */
213452518Sobrien
2135169702Skanstatic void
2136169702Skanassign_parms_setup_varargs (struct assign_parm_data_all *all,
2137169702Skan			    struct assign_parm_data_one *data, bool no_rtl)
213852518Sobrien{
2139169702Skan  int varargs_pretend_bytes = 0;
214052518Sobrien
2141169702Skan  targetm.calls.setup_incoming_varargs (&all->args_so_far,
2142169702Skan					data->promoted_mode,
2143169702Skan					data->passed_type,
2144169702Skan					&varargs_pretend_bytes, no_rtl);
214552518Sobrien
2146169702Skan  /* If the back-end has requested extra stack space, record how much is
2147169702Skan     needed.  Do not change pretend_args_size otherwise since it may be
2148169702Skan     nonzero from an earlier partial argument.  */
2149169702Skan  if (varargs_pretend_bytes > 0)
2150169702Skan    all->pretend_args_size = varargs_pretend_bytes;
215152518Sobrien}
215252518Sobrien
2153169702Skan/* A subroutine of assign_parms.  Set DATA->ENTRY_PARM corresponding to
2154169702Skan   the incoming location of the current parameter.  */
2155169702Skan
2156169702Skanstatic void
2157169702Skanassign_parm_find_entry_rtl (struct assign_parm_data_all *all,
2158169702Skan			    struct assign_parm_data_one *data)
215990091Sobrien{
2160169702Skan  HOST_WIDE_INT pretend_bytes = 0;
2161169702Skan  rtx entry_parm;
2162169702Skan  bool in_regs;
216352518Sobrien
2164169702Skan  if (data->promoted_mode == VOIDmode)
2165169702Skan    {
2166169702Skan      data->entry_parm = data->stack_parm = const0_rtx;
2167169702Skan      return;
2168169702Skan    }
216952518Sobrien
2170169702Skan#ifdef FUNCTION_INCOMING_ARG
2171169702Skan  entry_parm = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode,
2172169702Skan				      data->passed_type, data->named_arg);
2173169702Skan#else
2174169702Skan  entry_parm = FUNCTION_ARG (all->args_so_far, data->promoted_mode,
2175169702Skan			     data->passed_type, data->named_arg);
2176169702Skan#endif
217752518Sobrien
2178169702Skan  if (entry_parm == 0)
2179169702Skan    data->promoted_mode = data->passed_mode;
218052518Sobrien
2181169702Skan  /* Determine parm's home in the stack, in case it arrives in the stack
2182169702Skan     or we should pretend it did.  Compute the stack position and rtx where
2183169702Skan     the argument arrives and its size.
218452518Sobrien
2185169702Skan     There is one complexity here:  If this was a parameter that would
2186169702Skan     have been passed in registers, but wasn't only because it is
2187169702Skan     __builtin_va_alist, we want locate_and_pad_parm to treat it as if
2188169702Skan     it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
2189169702Skan     In this case, we call FUNCTION_ARG with NAMED set to 1 instead of 0
2190169702Skan     as it was the previous time.  */
2191169702Skan  in_regs = entry_parm != 0;
2192169702Skan#ifdef STACK_PARMS_IN_REG_PARM_AREA
2193169702Skan  in_regs = true;
2194169702Skan#endif
2195169702Skan  if (!in_regs && !data->named_arg)
2196117404Skan    {
2197169702Skan      if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far))
2198117404Skan	{
2199169702Skan	  rtx tem;
2200169702Skan#ifdef FUNCTION_INCOMING_ARG
2201169702Skan	  tem = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode,
2202169702Skan				       data->passed_type, true);
2203169702Skan#else
2204169702Skan	  tem = FUNCTION_ARG (all->args_so_far, data->promoted_mode,
2205169702Skan			      data->passed_type, true);
2206169702Skan#endif
2207169702Skan	  in_regs = tem != NULL;
2208117404Skan	}
2209117404Skan    }
221052518Sobrien
2211169702Skan  /* If this parameter was passed both in registers and in the stack, use
2212169702Skan     the copy on the stack.  */
2213169702Skan  if (targetm.calls.must_pass_in_stack (data->promoted_mode,
2214169702Skan					data->passed_type))
2215169702Skan    entry_parm = 0;
221652518Sobrien
2217169702Skan  if (entry_parm)
2218169702Skan    {
2219169702Skan      int partial;
222052518Sobrien
2221169702Skan      partial = targetm.calls.arg_partial_bytes (&all->args_so_far,
2222169702Skan						 data->promoted_mode,
2223169702Skan						 data->passed_type,
2224169702Skan						 data->named_arg);
2225169702Skan      data->partial = partial;
222652518Sobrien
2227169702Skan      /* The caller might already have allocated stack space for the
2228169702Skan	 register parameters.  */
2229169702Skan      if (partial != 0 && all->reg_parm_stack_space == 0)
223052518Sobrien	{
2231169702Skan	  /* Part of this argument is passed in registers and part
2232169702Skan	     is passed on the stack.  Ask the prologue code to extend
2233169702Skan	     the stack part so that we can recreate the full value.
223452518Sobrien
2235169702Skan	     PRETEND_BYTES is the size of the registers we need to store.
2236169702Skan	     CURRENT_FUNCTION_PRETEND_ARGS_SIZE is the amount of extra
2237169702Skan	     stack space that the prologue should allocate.
223890091Sobrien
2239169702Skan	     Internally, gcc assumes that the argument pointer is aligned
2240169702Skan	     to STACK_BOUNDARY bits.  This is used both for alignment
2241169702Skan	     optimizations (see init_emit) and to locate arguments that are
2242169702Skan	     aligned to more than PARM_BOUNDARY bits.  We must preserve this
2243169702Skan	     invariant by rounding CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to
2244169702Skan	     a stack boundary.  */
224590091Sobrien
2246169702Skan	  /* We assume at most one partial arg, and it must be the first
2247169702Skan	     argument on the stack.  */
2248169702Skan	  gcc_assert (!all->extra_pretend_bytes && !all->pretend_args_size);
224952268Sobrien
2250169702Skan	  pretend_bytes = partial;
2251169702Skan	  all->pretend_args_size = CEIL_ROUND (pretend_bytes, STACK_BYTES);
225290091Sobrien
2253169702Skan	  /* We want to align relative to the actual stack pointer, so
2254169702Skan	     don't include this in the stack size until later.  */
2255169702Skan	  all->extra_pretend_bytes = all->pretend_args_size;
2256169702Skan	}
2257169702Skan    }
225852518Sobrien
2259169702Skan  locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs,
2260169702Skan		       entry_parm ? data->partial : 0, current_function_decl,
2261169702Skan		       &all->stack_args_size, &data->locate);
2262132732Skan
2263169702Skan  /* Adjust offsets to include the pretend args.  */
2264169702Skan  pretend_bytes = all->extra_pretend_bytes - pretend_bytes;
2265169702Skan  data->locate.slot_offset.constant += pretend_bytes;
2266169702Skan  data->locate.offset.constant += pretend_bytes;
226790091Sobrien
2268169702Skan  data->entry_parm = entry_parm;
2269169702Skan}
227090091Sobrien
2271169702Skan/* A subroutine of assign_parms.  If there is actually space on the stack
2272169702Skan   for this parm, count it in stack_args_size and return true.  */
227352518Sobrien
2274169702Skanstatic bool
2275169702Skanassign_parm_is_stack_parm (struct assign_parm_data_all *all,
2276169702Skan			   struct assign_parm_data_one *data)
2277169702Skan{
2278169702Skan  /* Trivially true if we've no incoming register.  */
2279169702Skan  if (data->entry_parm == NULL)
2280169702Skan    ;
2281169702Skan  /* Also true if we're partially in registers and partially not,
2282169702Skan     since we've arranged to drop the entire argument on the stack.  */
2283169702Skan  else if (data->partial != 0)
2284169702Skan    ;
2285169702Skan  /* Also true if the target says that it's passed in both registers
2286169702Skan     and on the stack.  */
2287169702Skan  else if (GET_CODE (data->entry_parm) == PARALLEL
2288169702Skan	   && XEXP (XVECEXP (data->entry_parm, 0, 0), 0) == NULL_RTX)
2289169702Skan    ;
2290169702Skan  /* Also true if the target says that there's stack allocated for
2291169702Skan     all register parameters.  */
2292169702Skan  else if (all->reg_parm_stack_space > 0)
2293169702Skan    ;
2294169702Skan  /* Otherwise, no, this parameter has no ABI defined stack slot.  */
2295169702Skan  else
2296169702Skan    return false;
2297132732Skan
2298169702Skan  all->stack_args_size.constant += data->locate.size.constant;
2299169702Skan  if (data->locate.size.var)
2300169702Skan    ADD_PARM_SIZE (all->stack_args_size, data->locate.size.var);
2301132732Skan
2302169702Skan  return true;
2303169702Skan}
230472564Sobrien
2305169702Skan/* A subroutine of assign_parms.  Given that this parameter is allocated
2306169702Skan   stack space by the ABI, find it.  */
230772564Sobrien
2308169702Skanstatic void
2309169702Skanassign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data)
2310169702Skan{
2311169702Skan  rtx offset_rtx, stack_parm;
2312169702Skan  unsigned int align, boundary;
231372564Sobrien
2314169702Skan  /* If we're passing this arg using a reg, make its stack home the
2315169702Skan     aligned stack slot.  */
2316169702Skan  if (data->entry_parm)
2317169702Skan    offset_rtx = ARGS_SIZE_RTX (data->locate.slot_offset);
2318169702Skan  else
2319169702Skan    offset_rtx = ARGS_SIZE_RTX (data->locate.offset);
232072564Sobrien
2321169702Skan  stack_parm = current_function_internal_arg_pointer;
2322169702Skan  if (offset_rtx != const0_rtx)
2323169702Skan    stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx);
2324169702Skan  stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm);
232590091Sobrien
2326169702Skan  set_mem_attributes (stack_parm, parm, 1);
232790091Sobrien
2328169702Skan  boundary = data->locate.boundary;
2329169702Skan  align = BITS_PER_UNIT;
2330169702Skan
2331169702Skan  /* If we're padding upward, we know that the alignment of the slot
2332169702Skan     is FUNCTION_ARG_BOUNDARY.  If we're using slot_offset, we're
2333169702Skan     intentionally forcing upward padding.  Otherwise we have to come
2334169702Skan     up with a guess at the alignment based on OFFSET_RTX.  */
2335169702Skan  if (data->locate.where_pad != downward || data->entry_parm)
2336169702Skan    align = boundary;
2337169702Skan  else if (GET_CODE (offset_rtx) == CONST_INT)
233890091Sobrien    {
2339169702Skan      align = INTVAL (offset_rtx) * BITS_PER_UNIT | boundary;
2340169702Skan      align = align & -align;
234190091Sobrien    }
2342169702Skan  set_mem_align (stack_parm, align);
234390091Sobrien
2344169702Skan  if (data->entry_parm)
2345169702Skan    set_reg_attrs_for_parm (data->entry_parm, stack_parm);
2346117404Skan
2347169702Skan  data->stack_parm = stack_parm;
234890091Sobrien}
234990091Sobrien
2350169702Skan/* A subroutine of assign_parms.  Adjust DATA->ENTRY_RTL such that it's
2351169702Skan   always valid and contiguous.  */
235290091Sobrien
2353169702Skanstatic void
2354169702Skanassign_parm_adjust_entry_rtl (struct assign_parm_data_one *data)
2355169702Skan{
2356169702Skan  rtx entry_parm = data->entry_parm;
2357169702Skan  rtx stack_parm = data->stack_parm;
235890091Sobrien
2359169702Skan  /* If this parm was passed part in regs and part in memory, pretend it
2360169702Skan     arrived entirely in memory by pushing the register-part onto the stack.
2361169702Skan     In the special case of a DImode or DFmode that is split, we could put
2362169702Skan     it together in a pseudoreg directly, but for now that's not worth
2363169702Skan     bothering with.  */
2364169702Skan  if (data->partial != 0)
236590091Sobrien    {
2366169702Skan      /* Handle calls that pass values in multiple non-contiguous
2367169702Skan	 locations.  The Irix 6 ABI has examples of this.  */
2368169702Skan      if (GET_CODE (entry_parm) == PARALLEL)
2369169702Skan	emit_group_store (validize_mem (stack_parm), entry_parm,
2370169702Skan			  data->passed_type,
2371169702Skan			  int_size_in_bytes (data->passed_type));
2372169702Skan      else
237390091Sobrien	{
2374169702Skan	  gcc_assert (data->partial % UNITS_PER_WORD == 0);
2375169702Skan	  move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
2376169702Skan			       data->partial / UNITS_PER_WORD);
237790091Sobrien	}
2378169702Skan
2379169702Skan      entry_parm = stack_parm;
238090091Sobrien    }
238118334Speter
2382169702Skan  /* If we didn't decide this parm came in a register, by default it came
2383169702Skan     on the stack.  */
2384169702Skan  else if (entry_parm == NULL)
2385169702Skan    entry_parm = stack_parm;
238618334Speter
2387169702Skan  /* When an argument is passed in multiple locations, we can't make use
2388169702Skan     of this information, but we can save some copying if the whole argument
2389169702Skan     is passed in a single register.  */
2390169702Skan  else if (GET_CODE (entry_parm) == PARALLEL
2391169702Skan	   && data->nominal_mode != BLKmode
2392169702Skan	   && data->passed_mode != BLKmode)
2393169702Skan    {
2394169702Skan      size_t i, len = XVECLEN (entry_parm, 0);
239518334Speter
2396169702Skan      for (i = 0; i < len; i++)
2397169702Skan	if (XEXP (XVECEXP (entry_parm, 0, i), 0) != NULL_RTX
2398169702Skan	    && REG_P (XEXP (XVECEXP (entry_parm, 0, i), 0))
2399169702Skan	    && (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0))
2400169702Skan		== data->passed_mode)
2401169702Skan	    && INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0)
2402169702Skan	  {
2403169702Skan	    entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0);
2404169702Skan	    break;
2405169702Skan	  }
2406169702Skan    }
240718334Speter
2408169702Skan  data->entry_parm = entry_parm;
240918334Speter}
241018334Speter
2411169702Skan/* A subroutine of assign_parms.  Adjust DATA->STACK_RTL such that it's
2412169702Skan   always valid and properly aligned.  */
241318334Speter
241418334Speterstatic void
2415169702Skanassign_parm_adjust_stack_rtl (struct assign_parm_data_one *data)
241618334Speter{
2417169702Skan  rtx stack_parm = data->stack_parm;
241818334Speter
2419169702Skan  /* If we can't trust the parm stack slot to be aligned enough for its
2420169702Skan     ultimate type, don't use that slot after entry.  We'll make another
2421169702Skan     stack slot, if we need one.  */
2422169702Skan  if (stack_parm
2423169702Skan      && ((STRICT_ALIGNMENT
2424169702Skan	   && GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm))
2425169702Skan	  || (data->nominal_type
2426169702Skan	      && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
2427169702Skan	      && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY)))
2428169702Skan    stack_parm = NULL;
242952268Sobrien
2430169702Skan  /* If parm was passed in memory, and we need to convert it on entry,
2431169702Skan     don't store it back in that same slot.  */
2432169702Skan  else if (data->entry_parm == stack_parm
2433169702Skan	   && data->nominal_mode != BLKmode
2434169702Skan	   && data->nominal_mode != data->passed_mode)
2435169702Skan    stack_parm = NULL;
243652268Sobrien
2437169702Skan  /* If stack protection is in effect for this function, don't leave any
2438169702Skan     pointers in their passed stack slots.  */
2439169702Skan  else if (cfun->stack_protect_guard
2440169702Skan	   && (flag_stack_protect == 2
2441169702Skan	       || data->passed_pointer
2442169702Skan	       || POINTER_TYPE_P (data->nominal_type)))
2443169702Skan    stack_parm = NULL;
244418334Speter
2445169702Skan  data->stack_parm = stack_parm;
244618334Speter}
244718334Speter
2448169702Skan/* A subroutine of assign_parms.  Return true if the current parameter
2449169702Skan   should be stored as a BLKmode in the current frame.  */
245018334Speter
2451169702Skanstatic bool
2452169702Skanassign_parm_setup_block_p (struct assign_parm_data_one *data)
245318334Speter{
2454169702Skan  if (data->nominal_mode == BLKmode)
2455169702Skan    return true;
2456169702Skan  if (GET_CODE (data->entry_parm) == PARALLEL)
2457169702Skan    return true;
245818334Speter
2459169702Skan#ifdef BLOCK_REG_PADDING
2460169702Skan  /* Only assign_parm_setup_block knows how to deal with register arguments
2461169702Skan     that are padded at the least significant end.  */
2462169702Skan  if (REG_P (data->entry_parm)
2463169702Skan      && GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD
2464169702Skan      && (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
2465169702Skan	  == (BYTES_BIG_ENDIAN ? upward : downward)))
2466169702Skan    return true;
2467169702Skan#endif
246818334Speter
2469169702Skan  return false;
247018334Speter}
247118334Speter
2472169702Skan/* A subroutine of assign_parms.  Arrange for the parameter to be
2473169702Skan   present and valid in DATA->STACK_RTL.  */
247418334Speter
247518334Speterstatic void
2476169702Skanassign_parm_setup_block (struct assign_parm_data_all *all,
2477169702Skan			 tree parm, struct assign_parm_data_one *data)
247818334Speter{
2479169702Skan  rtx entry_parm = data->entry_parm;
2480169702Skan  rtx stack_parm = data->stack_parm;
2481169702Skan  HOST_WIDE_INT size;
2482169702Skan  HOST_WIDE_INT size_stored;
2483169702Skan  rtx orig_entry_parm = entry_parm;
248418334Speter
2485169702Skan  if (GET_CODE (entry_parm) == PARALLEL)
2486169702Skan    entry_parm = emit_group_move_into_temps (entry_parm);
2487146908Skan
2488169702Skan  /* If we've a non-block object that's nevertheless passed in parts,
2489169702Skan     reconstitute it in register operations rather than on the stack.  */
2490169702Skan  if (GET_CODE (entry_parm) == PARALLEL
2491169702Skan      && data->nominal_mode != BLKmode)
2492146908Skan    {
2493169702Skan      rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0);
2494146908Skan
2495169702Skan      if ((XVECLEN (entry_parm, 0) > 1
2496169702Skan	   || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1)
2497169702Skan	  && use_register_for_decl (parm))
2498169702Skan	{
2499169702Skan	  rtx parmreg = gen_reg_rtx (data->nominal_mode);
250018334Speter
2501169702Skan	  push_to_sequence (all->conversion_insns);
250218334Speter
2503169702Skan	  /* For values returned in multiple registers, handle possible
2504169702Skan	     incompatible calls to emit_group_store.
250518334Speter
2506169702Skan	     For example, the following would be invalid, and would have to
2507169702Skan	     be fixed by the conditional below:
250818334Speter
2509169702Skan	     emit_group_store ((reg:SF), (parallel:DF))
2510169702Skan	     emit_group_store ((reg:SI), (parallel:DI))
251118334Speter
2512169702Skan	     An example of this are doubles in e500 v2:
2513169702Skan	     (parallel:DF (expr_list (reg:SI) (const_int 0))
2514169702Skan	     (expr_list (reg:SI) (const_int 4))).  */
2515169702Skan	  if (data->nominal_mode != data->passed_mode)
2516169702Skan	    {
2517169702Skan	      rtx t = gen_reg_rtx (GET_MODE (entry_parm));
2518169702Skan	      emit_group_store (t, entry_parm, NULL_TREE,
2519169702Skan				GET_MODE_SIZE (GET_MODE (entry_parm)));
2520169702Skan	      convert_move (parmreg, t, 0);
2521169702Skan	    }
2522169702Skan	  else
2523169702Skan	    emit_group_store (parmreg, entry_parm, data->nominal_type,
2524169702Skan			      int_size_in_bytes (data->nominal_type));
252590091Sobrien
2526169702Skan	  all->conversion_insns = get_insns ();
2527169702Skan	  end_sequence ();
252818334Speter
2529169702Skan	  SET_DECL_RTL (parm, parmreg);
253052268Sobrien	  return;
2531169702Skan	}
253252268Sobrien    }
253318334Speter
2534169702Skan  size = int_size_in_bytes (data->passed_type);
2535169702Skan  size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
2536169702Skan  if (stack_parm == 0)
2537117404Skan    {
2538169702Skan      DECL_ALIGN (parm) = MAX (DECL_ALIGN (parm), BITS_PER_WORD);
2539169702Skan      stack_parm = assign_stack_local (BLKmode, size_stored,
2540169702Skan				       DECL_ALIGN (parm));
2541169702Skan      if (GET_MODE_SIZE (GET_MODE (entry_parm)) == size)
2542169702Skan	PUT_MODE (stack_parm, GET_MODE (entry_parm));
2543169702Skan      set_mem_attributes (stack_parm, parm, 1);
2544117404Skan    }
254518334Speter
2546169702Skan  /* If a BLKmode arrives in registers, copy it to a stack slot.  Handle
2547169702Skan     calls that pass values in multiple non-contiguous locations.  */
2548169702Skan  if (REG_P (entry_parm) || GET_CODE (entry_parm) == PARALLEL)
2549169702Skan    {
2550169702Skan      rtx mem;
255118334Speter
2552169702Skan      /* Note that we will be storing an integral number of words.
2553169702Skan	 So we have to be careful to ensure that we allocate an
2554169702Skan	 integral number of words.  We do this above when we call
2555169702Skan	 assign_stack_local if space was not allocated in the argument
2556169702Skan	 list.  If it was, this will not work if PARM_BOUNDARY is not
2557169702Skan	 a multiple of BITS_PER_WORD.  It isn't clear how to fix this
2558169702Skan	 if it becomes a problem.  Exception is when BLKmode arrives
2559169702Skan	 with arguments not conforming to word_mode.  */
256018334Speter
2561169702Skan      if (data->stack_parm == 0)
2562169702Skan	;
2563169702Skan      else if (GET_CODE (entry_parm) == PARALLEL)
2564169702Skan	;
2565169702Skan      else
2566169702Skan	gcc_assert (!size || !(PARM_BOUNDARY % BITS_PER_WORD));
256718334Speter
2568169702Skan      mem = validize_mem (stack_parm);
256918334Speter
2570169702Skan      /* Handle values in multiple non-contiguous locations.  */
2571169702Skan      if (GET_CODE (entry_parm) == PARALLEL)
257290091Sobrien	{
2573169702Skan	  push_to_sequence (all->conversion_insns);
2574169702Skan	  emit_group_store (mem, entry_parm, data->passed_type, size);
2575169702Skan	  all->conversion_insns = get_insns ();
257618334Speter	  end_sequence ();
257718334Speter	}
257818334Speter
2579169702Skan      else if (size == 0)
2580169702Skan	;
258118334Speter
2582169702Skan      /* If SIZE is that of a mode no bigger than a word, just use
2583169702Skan	 that mode's store operation.  */
2584169702Skan      else if (size <= UNITS_PER_WORD)
258518334Speter	{
2586169702Skan	  enum machine_mode mode
2587169702Skan	    = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
258818334Speter
2589169702Skan	  if (mode != BLKmode
2590169702Skan#ifdef BLOCK_REG_PADDING
2591169702Skan	      && (size == UNITS_PER_WORD
2592169702Skan		  || (BLOCK_REG_PADDING (mode, data->passed_type, 1)
2593169702Skan		      != (BYTES_BIG_ENDIAN ? upward : downward)))
259490091Sobrien#endif
2595169702Skan	      )
259618334Speter	    {
2597169702Skan	      rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
2598169702Skan	      emit_move_insn (change_address (mem, mode, 0), reg);
259918334Speter	    }
260018334Speter
2601169702Skan	  /* Blocks smaller than a word on a BYTES_BIG_ENDIAN
2602169702Skan	     machine must be aligned to the left before storing
2603169702Skan	     to memory.  Note that the previous test doesn't
2604169702Skan	     handle all cases (e.g. SIZE == 3).  */
2605169702Skan	  else if (size != UNITS_PER_WORD
2606169702Skan#ifdef BLOCK_REG_PADDING
2607169702Skan		   && (BLOCK_REG_PADDING (mode, data->passed_type, 1)
2608169702Skan		       == downward)
2609169702Skan#else
2610169702Skan		   && BYTES_BIG_ENDIAN
261118334Speter#endif
2612169702Skan		   )
261318334Speter	    {
2614169702Skan	      rtx tem, x;
2615169702Skan	      int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
2616169702Skan	      rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
261718334Speter
2618169702Skan	      x = expand_shift (LSHIFT_EXPR, word_mode, reg,
2619169702Skan				build_int_cst (NULL_TREE, by),
2620169702Skan				NULL_RTX, 1);
2621169702Skan	      tem = change_address (mem, word_mode, 0);
2622169702Skan	      emit_move_insn (tem, x);
262318334Speter	    }
2624169702Skan	  else
2625169702Skan	    move_block_from_reg (REGNO (entry_parm), mem,
2626169702Skan				 size_stored / UNITS_PER_WORD);
262718334Speter	}
2628169702Skan      else
2629169702Skan	move_block_from_reg (REGNO (entry_parm), mem,
2630169702Skan			     size_stored / UNITS_PER_WORD);
263118334Speter    }
2632169702Skan  else if (data->stack_parm == 0)
263318334Speter    {
2634169702Skan      push_to_sequence (all->conversion_insns);
2635169702Skan      emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
2636169702Skan		       BLOCK_OP_NORMAL);
2637169702Skan      all->conversion_insns = get_insns ();
2638169702Skan      end_sequence ();
263918334Speter    }
264018334Speter
2641169702Skan  data->stack_parm = stack_parm;
2642169702Skan  SET_DECL_RTL (parm, stack_parm);
264318334Speter}
264418334Speter
2645169702Skan/* A subroutine of assign_parms.  Allocate a pseudo to hold the current
2646169702Skan   parameter.  Get it there.  Perform all ABI specified conversions.  */
264718334Speter
2648169702Skanstatic void
2649169702Skanassign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
2650169702Skan		       struct assign_parm_data_one *data)
265118334Speter{
2652169702Skan  rtx parmreg;
2653169702Skan  enum machine_mode promoted_nominal_mode;
2654169702Skan  int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm));
2655169702Skan  bool did_conversion = false;
265618334Speter
2657169702Skan  /* Store the parm in a pseudoregister during the function, but we may
2658169702Skan     need to do it in a wider mode.  */
265990091Sobrien
2660169702Skan  /* This is not really promoting for a call.  However we need to be
2661169702Skan     consistent with assign_parm_find_data_types and expand_expr_real_1.  */
2662169702Skan  promoted_nominal_mode
2663169702Skan    = promote_mode (data->nominal_type, data->nominal_mode, &unsignedp, 1);
2664132732Skan
2665169702Skan  parmreg = gen_reg_rtx (promoted_nominal_mode);
266652268Sobrien
2667169702Skan  if (!DECL_ARTIFICIAL (parm))
2668169702Skan    mark_user_reg (parmreg);
266952268Sobrien
2670169702Skan  /* If this was an item that we received a pointer to,
2671169702Skan     set DECL_RTL appropriately.  */
2672169702Skan  if (data->passed_pointer)
2673169702Skan    {
2674169702Skan      rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg);
2675169702Skan      set_mem_attributes (x, parm, 1);
2676169702Skan      SET_DECL_RTL (parm, x);
2677169702Skan    }
267818334Speter  else
2679169702Skan    SET_DECL_RTL (parm, parmreg);
268018334Speter
2681169702Skan  /* Copy the value into the register.  */
2682169702Skan  if (data->nominal_mode != data->passed_mode
2683169702Skan      || promoted_nominal_mode != data->promoted_mode)
268418334Speter    {
2685169702Skan      int save_tree_used;
268618334Speter
2687169702Skan      /* ENTRY_PARM has been converted to PROMOTED_MODE, its
2688169702Skan	 mode, by the caller.  We now have to convert it to
2689169702Skan	 NOMINAL_MODE, if different.  However, PARMREG may be in
2690169702Skan	 a different mode than NOMINAL_MODE if it is being stored
2691169702Skan	 promoted.
269218334Speter
2693169702Skan	 If ENTRY_PARM is a hard register, it might be in a register
2694169702Skan	 not valid for operating in its mode (e.g., an odd-numbered
2695169702Skan	 register for a DFmode).  In that case, moves are the only
2696169702Skan	 thing valid, so we can't do a convert from there.  This
2697169702Skan	 occurs when the calling sequence allow such misaligned
2698169702Skan	 usages.
269990091Sobrien
2700169702Skan	 In addition, the conversion may involve a call, which could
2701169702Skan	 clobber parameters which haven't been copied to pseudo
2702169702Skan	 registers yet.  Therefore, we must first copy the parm to
2703169702Skan	 a pseudo reg here, and save the conversion until after all
2704169702Skan	 parameters have been moved.  */
2705132732Skan
2706169702Skan      rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
270718334Speter
2708169702Skan      emit_move_insn (tempreg, validize_mem (data->entry_parm));
2709132732Skan
2710169702Skan      push_to_sequence (all->conversion_insns);
2711169702Skan      tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp);
2712132732Skan
2713169702Skan      if (GET_CODE (tempreg) == SUBREG
2714169702Skan	  && GET_MODE (tempreg) == data->nominal_mode
2715169702Skan	  && REG_P (SUBREG_REG (tempreg))
2716169702Skan	  && data->nominal_mode == data->passed_mode
2717169702Skan	  && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (data->entry_parm)
2718169702Skan	  && GET_MODE_SIZE (GET_MODE (tempreg))
2719169702Skan	     < GET_MODE_SIZE (GET_MODE (data->entry_parm)))
272090091Sobrien	{
2721169702Skan	  /* The argument is already sign/zero extended, so note it
2722169702Skan	     into the subreg.  */
2723169702Skan	  SUBREG_PROMOTED_VAR_P (tempreg) = 1;
2724169702Skan	  SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp);
272590091Sobrien	}
272618334Speter
2727169702Skan      /* TREE_USED gets set erroneously during expand_assignment.  */
2728169702Skan      save_tree_used = TREE_USED (parm);
2729169702Skan      expand_assignment (parm, make_tree (data->nominal_type, tempreg));
2730169702Skan      TREE_USED (parm) = save_tree_used;
2731169702Skan      all->conversion_insns = get_insns ();
2732169702Skan      end_sequence ();
273318334Speter
2734169702Skan      did_conversion = true;
2735169702Skan    }
2736169702Skan  else
2737169702Skan    emit_move_insn (parmreg, validize_mem (data->entry_parm));
273818334Speter
2739169702Skan  /* If we were passed a pointer but the actual value can safely live
2740169702Skan     in a register, put it in one.  */
2741169702Skan  if (data->passed_pointer
2742169702Skan      && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
2743169702Skan      /* If by-reference argument was promoted, demote it.  */
2744169702Skan      && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
2745169702Skan	  || use_register_for_decl (parm)))
2746169702Skan    {
2747169702Skan      /* We can't use nominal_mode, because it will have been set to
2748169702Skan	 Pmode above.  We must use the actual mode of the parm.  */
2749169702Skan      parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
2750169702Skan      mark_user_reg (parmreg);
275118334Speter
2752169702Skan      if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
275318334Speter	{
2754169702Skan	  rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm)));
2755169702Skan	  int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm));
275618334Speter
2757169702Skan	  push_to_sequence (all->conversion_insns);
2758169702Skan	  emit_move_insn (tempreg, DECL_RTL (parm));
2759169702Skan	  tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p);
2760169702Skan	  emit_move_insn (parmreg, tempreg);
2761169702Skan	  all->conversion_insns = get_insns ();
2762169702Skan	  end_sequence ();
276318334Speter
2764169702Skan	  did_conversion = true;
2765132732Skan	}
2766169702Skan      else
2767169702Skan	emit_move_insn (parmreg, DECL_RTL (parm));
276818334Speter
2769169702Skan      SET_DECL_RTL (parm, parmreg);
277018334Speter
2771169702Skan      /* STACK_PARM is the pointer, not the parm, and PARMREG is
2772169702Skan	 now the parm.  */
2773169702Skan      data->stack_parm = NULL;
2774169702Skan    }
277518334Speter
2776169702Skan  /* Mark the register as eliminable if we did no conversion and it was
2777169702Skan     copied from memory at a fixed offset, and the arg pointer was not
2778169702Skan     copied to a pseudo-reg.  If the arg pointer is a pseudo reg or the
2779169702Skan     offset formed an invalid address, such memory-equivalences as we
2780169702Skan     make here would screw up life analysis for it.  */
2781169702Skan  if (data->nominal_mode == data->passed_mode
2782169702Skan      && !did_conversion
2783169702Skan      && data->stack_parm != 0
2784169702Skan      && MEM_P (data->stack_parm)
2785169702Skan      && data->locate.offset.var == 0
2786169702Skan      && reg_mentioned_p (virtual_incoming_args_rtx,
2787169702Skan			  XEXP (data->stack_parm, 0)))
2788169702Skan    {
2789169702Skan      rtx linsn = get_last_insn ();
2790169702Skan      rtx sinsn, set;
279118334Speter
2792169702Skan      /* Mark complex types separately.  */
2793169702Skan      if (GET_CODE (parmreg) == CONCAT)
279418334Speter	{
2795169702Skan	  enum machine_mode submode
2796169702Skan	    = GET_MODE_INNER (GET_MODE (parmreg));
2797169702Skan	  int regnor = REGNO (XEXP (parmreg, 0));
2798169702Skan	  int regnoi = REGNO (XEXP (parmreg, 1));
2799169702Skan	  rtx stackr = adjust_address_nv (data->stack_parm, submode, 0);
2800169702Skan	  rtx stacki = adjust_address_nv (data->stack_parm, submode,
2801169702Skan					  GET_MODE_SIZE (submode));
2802132732Skan
2803169702Skan	  /* Scan backwards for the set of the real and
2804169702Skan	     imaginary parts.  */
2805169702Skan	  for (sinsn = linsn; sinsn != 0;
2806169702Skan	       sinsn = prev_nonnote_insn (sinsn))
2807132732Skan	    {
2808169702Skan	      set = single_set (sinsn);
2809169702Skan	      if (set == 0)
2810169702Skan		continue;
2811132732Skan
2812169702Skan	      if (SET_DEST (set) == regno_reg_rtx [regnoi])
2813169702Skan		REG_NOTES (sinsn)
2814169702Skan		  = gen_rtx_EXPR_LIST (REG_EQUIV, stacki,
2815169702Skan				       REG_NOTES (sinsn));
2816169702Skan	      else if (SET_DEST (set) == regno_reg_rtx [regnor])
2817169702Skan		REG_NOTES (sinsn)
2818169702Skan		  = gen_rtx_EXPR_LIST (REG_EQUIV, stackr,
2819169702Skan				       REG_NOTES (sinsn));
2820132732Skan	    }
2821132732Skan	}
2822169702Skan      else if ((set = single_set (linsn)) != 0
2823169702Skan	       && SET_DEST (set) == parmreg)
2824169702Skan	REG_NOTES (linsn)
2825169702Skan	  = gen_rtx_EXPR_LIST (REG_EQUIV,
2826169702Skan			       data->stack_parm, REG_NOTES (linsn));
2827169702Skan    }
2828132732Skan
2829169702Skan  /* For pointer data type, suggest pointer register.  */
2830169702Skan  if (POINTER_TYPE_P (TREE_TYPE (parm)))
2831169702Skan    mark_reg_pointer (parmreg,
2832169702Skan		      TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
2833169702Skan}
2834132732Skan
2835169702Skan/* A subroutine of assign_parms.  Allocate stack space to hold the current
2836169702Skan   parameter.  Get it there.  Perform all ABI specified conversions.  */
283718334Speter
2838169702Skanstatic void
2839169702Skanassign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
2840169702Skan		         struct assign_parm_data_one *data)
2841169702Skan{
2842169702Skan  /* Value must be stored in the stack slot STACK_PARM during function
2843169702Skan     execution.  */
2844169702Skan  bool to_conversion = false;
2845132732Skan
2846169702Skan  if (data->promoted_mode != data->nominal_mode)
2847169702Skan    {
2848169702Skan      /* Conversion is required.  */
2849169702Skan      rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm));
285018334Speter
2851169702Skan      emit_move_insn (tempreg, validize_mem (data->entry_parm));
2852132732Skan
2853169702Skan      push_to_sequence (all->conversion_insns);
2854169702Skan      to_conversion = true;
2855132732Skan
2856169702Skan      data->entry_parm = convert_to_mode (data->nominal_mode, tempreg,
2857169702Skan					  TYPE_UNSIGNED (TREE_TYPE (parm)));
2858132732Skan
2859169702Skan      if (data->stack_parm)
2860169702Skan	/* ??? This may need a big-endian conversion on sparc64.  */
2861169702Skan	data->stack_parm
2862169702Skan	  = adjust_address (data->stack_parm, data->nominal_mode, 0);
2863169702Skan    }
286418334Speter
2865169702Skan  if (data->entry_parm != data->stack_parm)
2866169702Skan    {
2867169702Skan      rtx src, dest;
286818334Speter
2869169702Skan      if (data->stack_parm == 0)
287018334Speter	{
2871169702Skan	  data->stack_parm
2872169702Skan	    = assign_stack_local (GET_MODE (data->entry_parm),
2873169702Skan				  GET_MODE_SIZE (GET_MODE (data->entry_parm)),
2874169702Skan				  TYPE_ALIGN (data->passed_type));
2875169702Skan	  set_mem_attributes (data->stack_parm, parm, 1);
287618334Speter	}
287718334Speter
2878169702Skan      dest = validize_mem (data->stack_parm);
2879169702Skan      src = validize_mem (data->entry_parm);
288018334Speter
2881169702Skan      if (MEM_P (src))
2882169702Skan	{
2883169702Skan	  /* Use a block move to handle potentially misaligned entry_parm.  */
2884169702Skan	  if (!to_conversion)
2885169702Skan	    push_to_sequence (all->conversion_insns);
2886169702Skan	  to_conversion = true;
288718334Speter
2888169702Skan	  emit_block_move (dest, src,
2889169702Skan			   GEN_INT (int_size_in_bytes (data->passed_type)),
2890169702Skan			   BLOCK_OP_NORMAL);
289118334Speter	}
289218334Speter      else
2893169702Skan	emit_move_insn (dest, src);
2894169702Skan    }
289518334Speter
2896169702Skan  if (to_conversion)
2897169702Skan    {
2898169702Skan      all->conversion_insns = get_insns ();
2899169702Skan      end_sequence ();
2900169702Skan    }
290118334Speter
2902169702Skan  SET_DECL_RTL (parm, data->stack_parm);
2903169702Skan}
290418334Speter
2905169702Skan/* A subroutine of assign_parms.  If the ABI splits complex arguments, then
2906169702Skan   undo the frobbing that we did in assign_parms_augmented_arg_list.  */
290718334Speter
2908169702Skanstatic void
2909169702Skanassign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs)
2910169702Skan{
2911169702Skan  tree parm;
2912169702Skan  tree orig_fnargs = all->orig_fnargs;
291318334Speter
2914169702Skan  for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm))
2915169702Skan    {
2916169702Skan      if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
2917169702Skan	  && targetm.calls.split_complex_arg (TREE_TYPE (parm)))
291818334Speter	{
2919169702Skan	  rtx tmp, real, imag;
2920169702Skan	  enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
292118334Speter
2922169702Skan	  real = DECL_RTL (fnargs);
2923169702Skan	  imag = DECL_RTL (TREE_CHAIN (fnargs));
2924169702Skan	  if (inner != GET_MODE (real))
2925132732Skan	    {
2926169702Skan	      real = gen_lowpart_SUBREG (inner, real);
2927169702Skan	      imag = gen_lowpart_SUBREG (inner, imag);
2928132732Skan	    }
2929132732Skan
2930169702Skan	  if (TREE_ADDRESSABLE (parm))
293118334Speter	    {
2932169702Skan	      rtx rmem, imem;
2933169702Skan	      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm));
293418334Speter
2935169702Skan	      /* split_complex_arg put the real and imag parts in
2936169702Skan		 pseudos.  Move them to memory.  */
2937169702Skan	      tmp = assign_stack_local (DECL_MODE (parm), size,
2938169702Skan					TYPE_ALIGN (TREE_TYPE (parm)));
2939169702Skan	      set_mem_attributes (tmp, parm, 1);
2940169702Skan	      rmem = adjust_address_nv (tmp, inner, 0);
2941169702Skan	      imem = adjust_address_nv (tmp, inner, GET_MODE_SIZE (inner));
2942169702Skan	      push_to_sequence (all->conversion_insns);
2943169702Skan	      emit_move_insn (rmem, real);
2944169702Skan	      emit_move_insn (imem, imag);
2945169702Skan	      all->conversion_insns = get_insns ();
294618334Speter	      end_sequence ();
294718334Speter	    }
294818334Speter	  else
2949169702Skan	    tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
2950169702Skan	  SET_DECL_RTL (parm, tmp);
295118334Speter
2952169702Skan	  real = DECL_INCOMING_RTL (fnargs);
2953169702Skan	  imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
2954169702Skan	  if (inner != GET_MODE (real))
295518334Speter	    {
2956169702Skan	      real = gen_lowpart_SUBREG (inner, real);
2957169702Skan	      imag = gen_lowpart_SUBREG (inner, imag);
295818334Speter	    }
2959169702Skan	  tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
2960169702Skan	  set_decl_incoming_rtl (parm, tmp);
2961169702Skan	  fnargs = TREE_CHAIN (fnargs);
2962169702Skan	}
2963169702Skan      else
2964169702Skan	{
2965169702Skan	  SET_DECL_RTL (parm, DECL_RTL (fnargs));
2966169702Skan	  set_decl_incoming_rtl (parm, DECL_INCOMING_RTL (fnargs));
296718334Speter
2968169702Skan	  /* Set MEM_EXPR to the original decl, i.e. to PARM,
2969169702Skan	     instead of the copy of decl, i.e. FNARGS.  */
2970169702Skan	  if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
2971169702Skan	    set_mem_expr (DECL_INCOMING_RTL (parm), parm);
2972169702Skan	}
297318334Speter
2974169702Skan      fnargs = TREE_CHAIN (fnargs);
2975169702Skan    }
2976169702Skan}
297718334Speter
2978169702Skan/* Assign RTL expressions to the function's parameters.  This may involve
2979169702Skan   copying them into registers and using those registers as the DECL_RTL.  */
298018334Speter
2981169702Skanstatic void
2982169702Skanassign_parms (tree fndecl)
2983169702Skan{
2984169702Skan  struct assign_parm_data_all all;
2985169702Skan  tree fnargs, parm;
298618334Speter
2987169702Skan  current_function_internal_arg_pointer
2988169702Skan    = targetm.calls.internal_arg_pointer ();
298918334Speter
2990169702Skan  assign_parms_initialize_all (&all);
2991169702Skan  fnargs = assign_parms_augmented_arg_list (&all);
299218334Speter
2993169702Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
2994169702Skan    {
2995169702Skan      struct assign_parm_data_one data;
299618334Speter
2997169702Skan      /* Extract the type of PARM; adjust it according to ABI.  */
2998169702Skan      assign_parm_find_data_types (&all, parm, &data);
299918334Speter
3000169702Skan      /* Early out for errors and void parameters.  */
3001169702Skan      if (data.passed_mode == VOIDmode)
3002169702Skan	{
3003169702Skan	  SET_DECL_RTL (parm, const0_rtx);
3004169702Skan	  DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
3005169702Skan	  continue;
3006169702Skan	}
300718334Speter
3008169702Skan      if (current_function_stdarg && !TREE_CHAIN (parm))
3009169702Skan	assign_parms_setup_varargs (&all, &data, false);
301018334Speter
3011169702Skan      /* Find out where the parameter arrives in this function.  */
3012169702Skan      assign_parm_find_entry_rtl (&all, &data);
301318334Speter
3014169702Skan      /* Find out where stack space for this parameter might be.  */
3015169702Skan      if (assign_parm_is_stack_parm (&all, &data))
3016169702Skan	{
3017169702Skan	  assign_parm_find_stack_rtl (parm, &data);
3018169702Skan	  assign_parm_adjust_entry_rtl (&data);
3019169702Skan	}
302018334Speter
3021169702Skan      /* Record permanently how this parm was passed.  */
3022169702Skan      set_decl_incoming_rtl (parm, data.entry_parm);
302318334Speter
3024169702Skan      /* Update info on where next arg arrives in registers.  */
3025169702Skan      FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
3026169702Skan			    data.passed_type, data.named_arg);
302718334Speter
3028169702Skan      assign_parm_adjust_stack_rtl (&data);
302918334Speter
3030169702Skan      if (assign_parm_setup_block_p (&data))
3031169702Skan	assign_parm_setup_block (&all, parm, &data);
3032169702Skan      else if (data.passed_pointer || use_register_for_decl (parm))
3033169702Skan	assign_parm_setup_reg (&all, parm, &data);
303418334Speter      else
3035169702Skan	assign_parm_setup_stack (&all, parm, &data);
3036132732Skan    }
303790091Sobrien
3038169702Skan  if (targetm.calls.split_complex_arg && fnargs != all.orig_fnargs)
3039169702Skan    assign_parms_unsplit_complex (&all, fnargs);
304018334Speter
304118334Speter  /* Output all parameter conversion instructions (possibly including calls)
304218334Speter     now that all parameters have been copied out of hard registers.  */
3043169702Skan  emit_insn (all.conversion_insns);
304418334Speter
3045132732Skan  /* If we are receiving a struct value address as the first argument, set up
3046132732Skan     the RTL for the function result. As this might require code to convert
3047132732Skan     the transmitted address to Pmode, we do this here to ensure that possible
3048132732Skan     preliminary conversions of the address have been emitted already.  */
3049169702Skan  if (all.function_result_decl)
3050132732Skan    {
3051169702Skan      tree result = DECL_RESULT (current_function_decl);
3052169702Skan      rtx addr = DECL_RTL (all.function_result_decl);
3053132732Skan      rtx x;
3054132732Skan
3055169702Skan      if (DECL_BY_REFERENCE (result))
3056169702Skan	x = addr;
3057169702Skan      else
3058169702Skan	{
3059169702Skan	  addr = convert_memory_address (Pmode, addr);
3060169702Skan	  x = gen_rtx_MEM (DECL_MODE (result), addr);
3061169702Skan	  set_mem_attributes (x, result, 1);
3062169702Skan	}
3063132732Skan      SET_DECL_RTL (result, x);
3064132732Skan    }
3065132732Skan
3066169702Skan  /* We have aligned all the args, so add space for the pretend args.  */
3067169702Skan  current_function_pretend_args_size = all.pretend_args_size;
3068169702Skan  all.stack_args_size.constant += all.extra_pretend_bytes;
3069169702Skan  current_function_args_size = all.stack_args_size.constant;
307018334Speter
307118334Speter  /* Adjust function incoming argument size for alignment and
307218334Speter     minimum length.  */
307318334Speter
307418334Speter#ifdef REG_PARM_STACK_SPACE
307518334Speter  current_function_args_size = MAX (current_function_args_size,
307618334Speter				    REG_PARM_STACK_SPACE (fndecl));
307718334Speter#endif
307818334Speter
3079169702Skan  current_function_args_size = CEIL_ROUND (current_function_args_size,
3080169702Skan					   PARM_BOUNDARY / BITS_PER_UNIT);
308118334Speter
308218334Speter#ifdef ARGS_GROW_DOWNWARD
308318334Speter  current_function_arg_offset_rtx
3084169702Skan    = (all.stack_args_size.var == 0 ? GEN_INT (-all.stack_args_size.constant)
3085169702Skan       : expand_expr (size_diffop (all.stack_args_size.var,
3086169702Skan				   size_int (-all.stack_args_size.constant)),
308790091Sobrien		      NULL_RTX, VOIDmode, 0));
308818334Speter#else
3089169702Skan  current_function_arg_offset_rtx = ARGS_SIZE_RTX (all.stack_args_size);
309018334Speter#endif
309118334Speter
309218334Speter  /* See how many bytes, if any, of its args a function should try to pop
309318334Speter     on return.  */
309418334Speter
309518334Speter  current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl),
309618334Speter						 current_function_args_size);
309718334Speter
309818334Speter  /* For stdarg.h function, save info about
309918334Speter     regs and stack space used by the named args.  */
310018334Speter
3101169702Skan  current_function_args_info = all.args_so_far;
310218334Speter
310318334Speter  /* Set the rtx used for the function return value.  Put this in its
310418334Speter     own variable so any optimizers that need this information don't have
310518334Speter     to include tree.h.  Do this here so it gets done when an inlined
310618334Speter     function gets output.  */
310718334Speter
310890091Sobrien  current_function_return_rtx
310990091Sobrien    = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
311090091Sobrien       ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
311196283Sobrien
311296283Sobrien  /* If scalar return value was computed in a pseudo-reg, or was a named
311396283Sobrien     return value that got dumped to the stack, copy that to the hard
311496283Sobrien     return register.  */
311596283Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
311696283Sobrien    {
311796283Sobrien      tree decl_result = DECL_RESULT (fndecl);
311896283Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
311996283Sobrien
312096283Sobrien      if (REG_P (decl_rtl)
312196283Sobrien	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
312296283Sobrien	  : DECL_REGISTER (decl_result))
312396283Sobrien	{
312496283Sobrien	  rtx real_decl_rtl;
312596283Sobrien
3126169702Skan	  real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result),
3127169702Skan							fndecl, true);
312896283Sobrien	  REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
312996283Sobrien	  /* The delay slot scheduler assumes that current_function_return_rtx
313096283Sobrien	     holds the hard register containing the return value, not a
313196283Sobrien	     temporary pseudo.  */
313296283Sobrien	  current_function_return_rtx = real_decl_rtl;
313396283Sobrien	}
313496283Sobrien    }
313518334Speter}
3136132732Skan
3137169702Skan/* A subroutine of gimplify_parameters, invoked via walk_tree.
3138169702Skan   For all seen types, gimplify their sizes.  */
3139132732Skan
3140132732Skanstatic tree
3141169702Skangimplify_parm_type (tree *tp, int *walk_subtrees, void *data)
3142132732Skan{
3143169702Skan  tree t = *tp;
3144132732Skan
3145169702Skan  *walk_subtrees = 0;
3146169702Skan  if (TYPE_P (t))
3147132732Skan    {
3148169702Skan      if (POINTER_TYPE_P (t))
3149169702Skan	*walk_subtrees = 1;
3150169702Skan      else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
3151169702Skan	       && !TYPE_SIZES_GIMPLIFIED (t))
3152169702Skan	{
3153169702Skan	  gimplify_type_sizes (t, (tree *) data);
3154169702Skan	  *walk_subtrees = 1;
3155169702Skan	}
3156132732Skan    }
3157132732Skan
3158169702Skan  return NULL;
3159169702Skan}
3160132732Skan
3161169702Skan/* Gimplify the parameter list for current_function_decl.  This involves
3162169702Skan   evaluating SAVE_EXPRs of variable sized parameters and generating code
3163169702Skan   to implement callee-copies reference parameters.  Returns a list of
3164169702Skan   statements to add to the beginning of the function, or NULL if nothing
3165169702Skan   to do.  */
3166169702Skan
3167169702Skantree
3168169702Skangimplify_parameters (void)
3169169702Skan{
3170169702Skan  struct assign_parm_data_all all;
3171169702Skan  tree fnargs, parm, stmts = NULL;
3172169702Skan
3173169702Skan  assign_parms_initialize_all (&all);
3174169702Skan  fnargs = assign_parms_augmented_arg_list (&all);
3175169702Skan
3176169702Skan  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
3177132732Skan    {
3178169702Skan      struct assign_parm_data_one data;
3179169702Skan
3180169702Skan      /* Extract the type of PARM; adjust it according to ABI.  */
3181169702Skan      assign_parm_find_data_types (&all, parm, &data);
3182169702Skan
3183169702Skan      /* Early out for errors and void parameters.  */
3184169702Skan      if (data.passed_mode == VOIDmode || DECL_SIZE (parm) == NULL)
3185169702Skan	continue;
3186169702Skan
3187169702Skan      /* Update info on where next arg arrives in registers.  */
3188169702Skan      FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode,
3189169702Skan			    data.passed_type, data.named_arg);
3190169702Skan
3191169702Skan      /* ??? Once upon a time variable_size stuffed parameter list
3192169702Skan	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
3193169702Skan	 turned out to be less than manageable in the gimple world.
3194169702Skan	 Now we have to hunt them down ourselves.  */
3195169702Skan      walk_tree_without_duplicates (&data.passed_type,
3196169702Skan				    gimplify_parm_type, &stmts);
3197169702Skan
3198169702Skan      if (!TREE_CONSTANT (DECL_SIZE (parm)))
3199132732Skan	{
3200169702Skan	  gimplify_one_sizepos (&DECL_SIZE (parm), &stmts);
3201169702Skan	  gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
3202169702Skan	}
3203132732Skan
3204169702Skan      if (data.passed_pointer)
3205169702Skan	{
3206169702Skan          tree type = TREE_TYPE (data.passed_type);
3207169702Skan	  if (reference_callee_copied (&all.args_so_far, TYPE_MODE (type),
3208169702Skan				       type, data.named_arg))
3209169702Skan	    {
3210169702Skan	      tree local, t;
3211132732Skan
3212169702Skan	      /* For constant sized objects, this is trivial; for
3213169702Skan		 variable-sized objects, we have to play games.  */
3214169702Skan	      if (TREE_CONSTANT (DECL_SIZE (parm)))
3215169702Skan		{
3216169702Skan		  local = create_tmp_var (type, get_name (parm));
3217169702Skan		  DECL_IGNORED_P (local) = 0;
3218169702Skan		}
3219169702Skan	      else
3220169702Skan		{
3221169702Skan		  tree ptr_type, addr, args;
3222132732Skan
3223169702Skan		  ptr_type = build_pointer_type (type);
3224169702Skan		  addr = create_tmp_var (ptr_type, get_name (parm));
3225169702Skan		  DECL_IGNORED_P (addr) = 0;
3226169702Skan		  local = build_fold_indirect_ref (addr);
3227169702Skan
3228169702Skan		  args = tree_cons (NULL, DECL_SIZE_UNIT (parm), NULL);
3229169702Skan		  t = built_in_decls[BUILT_IN_ALLOCA];
3230169702Skan		  t = build_function_call_expr (t, args);
3231169702Skan		  t = fold_convert (ptr_type, t);
3232169702Skan		  t = build2 (MODIFY_EXPR, void_type_node, addr, t);
3233169702Skan		  gimplify_and_add (t, &stmts);
3234169702Skan		}
3235169702Skan
3236169702Skan	      t = build2 (MODIFY_EXPR, void_type_node, local, parm);
3237169702Skan	      gimplify_and_add (t, &stmts);
3238169702Skan
3239169702Skan	      SET_DECL_VALUE_EXPR (parm, local);
3240169702Skan	      DECL_HAS_VALUE_EXPR_P (parm) = 1;
3241169702Skan	    }
3242132732Skan	}
3243132732Skan    }
3244132732Skan
3245169702Skan  return stmts;
3246132732Skan}
324718334Speter
324818334Speter/* Indicate whether REGNO is an incoming argument to the current function
324918334Speter   that was promoted to a wider mode.  If so, return the RTX for the
325018334Speter   register (to get its mode).  PMODE and PUNSIGNEDP are set to the mode
325118334Speter   that REGNO is promoted from and whether the promotion was signed or
325218334Speter   unsigned.  */
325318334Speter
325418334Speterrtx
3255132732Skanpromoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp)
325618334Speter{
325718334Speter  tree arg;
325818334Speter
325918334Speter  for (arg = DECL_ARGUMENTS (current_function_decl); arg;
326018334Speter       arg = TREE_CHAIN (arg))
3261169702Skan    if (REG_P (DECL_INCOMING_RTL (arg))
326218334Speter	&& REGNO (DECL_INCOMING_RTL (arg)) == regno
326318334Speter	&& TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
326418334Speter      {
326518334Speter	enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
3266169702Skan	int unsignedp = TYPE_UNSIGNED (TREE_TYPE (arg));
326718334Speter
326818334Speter	mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1);
326918334Speter	if (mode == GET_MODE (DECL_INCOMING_RTL (arg))
327018334Speter	    && mode != DECL_MODE (arg))
327118334Speter	  {
327218334Speter	    *pmode = DECL_MODE (arg);
327318334Speter	    *punsignedp = unsignedp;
327418334Speter	    return DECL_INCOMING_RTL (arg);
327518334Speter	  }
327618334Speter      }
327718334Speter
327818334Speter  return 0;
327918334Speter}
328018334Speter
328118334Speter
328218334Speter/* Compute the size and offset from the start of the stacked arguments for a
328318334Speter   parm passed in mode PASSED_MODE and with type TYPE.
328418334Speter
328518334Speter   INITIAL_OFFSET_PTR points to the current offset into the stacked
328618334Speter   arguments.
328718334Speter
3288132732Skan   The starting offset and size for this parm are returned in
3289132732Skan   LOCATE->OFFSET and LOCATE->SIZE, respectively.  When IN_REGS is
3290132732Skan   nonzero, the offset is that of stack slot, which is returned in
3291132732Skan   LOCATE->SLOT_OFFSET.  LOCATE->ALIGNMENT_PAD is the amount of
3292132732Skan   padding required from the initial offset ptr to the stack slot.
329318334Speter
3294117404Skan   IN_REGS is nonzero if the argument will be passed in registers.  It will
329518334Speter   never be set if REG_PARM_STACK_SPACE is not defined.
329618334Speter
329718334Speter   FNDECL is the function in which the argument was defined.
329818334Speter
329918334Speter   There are two types of rounding that are done.  The first, controlled by
330018334Speter   FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
330118334Speter   list to be aligned to the specific boundary (in bits).  This rounding
330218334Speter   affects the initial and starting offsets, but not the argument size.
330318334Speter
330418334Speter   The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
330518334Speter   optionally rounds the size of the parm to PARM_BOUNDARY.  The
330618334Speter   initial offset is not affected by this rounding, while the size always
330718334Speter   is and the starting offset may be.  */
330818334Speter
3309132732Skan/*  LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
3310132732Skan    INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
331118334Speter    callers pass in the total size of args so far as
3312132732Skan    INITIAL_OFFSET_PTR.  LOCATE->SIZE is always positive.  */
331318334Speter
331418334Spetervoid
3315132732Skanlocate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
3316132732Skan		     int partial, tree fndecl ATTRIBUTE_UNUSED,
3317132732Skan		     struct args_size *initial_offset_ptr,
3318132732Skan		     struct locate_and_pad_arg_data *locate)
3319132732Skan{
3320132732Skan  tree sizetree;
3321132732Skan  enum direction where_pad;
3322169702Skan  unsigned int boundary;
3323132732Skan  int reg_parm_stack_space = 0;
3324132732Skan  int part_size_in_regs;
332590091Sobrien
3326132732Skan#ifdef REG_PARM_STACK_SPACE
3327132732Skan  reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
332818334Speter
332918334Speter  /* If we have found a stack parm before we reach the end of the
333018334Speter     area reserved for registers, skip that area.  */
333118334Speter  if (! in_regs)
333218334Speter    {
333318334Speter      if (reg_parm_stack_space > 0)
333418334Speter	{
333518334Speter	  if (initial_offset_ptr->var)
333618334Speter	    {
333718334Speter	      initial_offset_ptr->var
333818334Speter		= size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
333990091Sobrien			      ssize_int (reg_parm_stack_space));
334018334Speter	      initial_offset_ptr->constant = 0;
334118334Speter	    }
334218334Speter	  else if (initial_offset_ptr->constant < reg_parm_stack_space)
334318334Speter	    initial_offset_ptr->constant = reg_parm_stack_space;
334418334Speter	}
334518334Speter    }
334618334Speter#endif /* REG_PARM_STACK_SPACE */
334718334Speter
3348169702Skan  part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0);
334918334Speter
3350132732Skan  sizetree
3351132732Skan    = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
3352132732Skan  where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
3353132732Skan  boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
3354132732Skan  locate->where_pad = where_pad;
3355169702Skan  locate->boundary = boundary;
3356132732Skan
3357169702Skan  /* Remember if the outgoing parameter requires extra alignment on the
3358169702Skan     calling function side.  */
3359169702Skan  if (boundary > PREFERRED_STACK_BOUNDARY)
3360169702Skan    boundary = PREFERRED_STACK_BOUNDARY;
3361169702Skan  if (cfun->stack_alignment_needed < boundary)
3362169702Skan    cfun->stack_alignment_needed = boundary;
3363169702Skan
336418334Speter#ifdef ARGS_GROW_DOWNWARD
3365132732Skan  locate->slot_offset.constant = -initial_offset_ptr->constant;
336618334Speter  if (initial_offset_ptr->var)
3367132732Skan    locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
3368132732Skan					  initial_offset_ptr->var);
3369117404Skan
3370132732Skan  {
3371132732Skan    tree s2 = sizetree;
3372132732Skan    if (where_pad != none
3373132732Skan	&& (!host_integerp (sizetree, 1)
3374132732Skan	    || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
3375132732Skan      s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
3376132732Skan    SUB_PARM_SIZE (locate->slot_offset, s2);
3377132732Skan  }
3378117404Skan
3379132732Skan  locate->slot_offset.constant += part_size_in_regs;
3380132732Skan
3381117404Skan  if (!in_regs
3382117404Skan#ifdef REG_PARM_STACK_SPACE
3383117404Skan      || REG_PARM_STACK_SPACE (fndecl) > 0
3384117404Skan#endif
3385117404Skan     )
3386132732Skan    pad_to_arg_alignment (&locate->slot_offset, boundary,
3387132732Skan			  &locate->alignment_pad);
3388117404Skan
3389132732Skan  locate->size.constant = (-initial_offset_ptr->constant
3390132732Skan			   - locate->slot_offset.constant);
339118334Speter  if (initial_offset_ptr->var)
3392132732Skan    locate->size.var = size_binop (MINUS_EXPR,
3393132732Skan				   size_binop (MINUS_EXPR,
3394132732Skan					       ssize_int (0),
3395132732Skan					       initial_offset_ptr->var),
3396132732Skan				   locate->slot_offset.var);
339790091Sobrien
3398132732Skan  /* Pad_below needs the pre-rounded size to know how much to pad
3399132732Skan     below.  */
3400132732Skan  locate->offset = locate->slot_offset;
3401132732Skan  if (where_pad == downward)
3402132732Skan    pad_below (&locate->offset, passed_mode, sizetree);
340390091Sobrien
340418334Speter#else /* !ARGS_GROW_DOWNWARD */
340590091Sobrien  if (!in_regs
340690091Sobrien#ifdef REG_PARM_STACK_SPACE
340790091Sobrien      || REG_PARM_STACK_SPACE (fndecl) > 0
340890091Sobrien#endif
340990091Sobrien      )
3410132732Skan    pad_to_arg_alignment (initial_offset_ptr, boundary,
3411132732Skan			  &locate->alignment_pad);
3412132732Skan  locate->slot_offset = *initial_offset_ptr;
341318334Speter
341418334Speter#ifdef PUSH_ROUNDING
341518334Speter  if (passed_mode != BLKmode)
341618334Speter    sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
341718334Speter#endif
341818334Speter
341918334Speter  /* Pad_below needs the pre-rounded size to know how much to pad below
342018334Speter     so this must be done before rounding up.  */
3421132732Skan  locate->offset = locate->slot_offset;
3422132732Skan  if (where_pad == downward)
3423132732Skan    pad_below (&locate->offset, passed_mode, sizetree);
342418334Speter
342518334Speter  if (where_pad != none
342690091Sobrien      && (!host_integerp (sizetree, 1)
342790091Sobrien	  || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
342818334Speter    sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
342918334Speter
3430132732Skan  ADD_PARM_SIZE (locate->size, sizetree);
3431132732Skan
3432132732Skan  locate->size.constant -= part_size_in_regs;
343318334Speter#endif /* ARGS_GROW_DOWNWARD */
343418334Speter}
343518334Speter
343618334Speter/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
343718334Speter   BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */
343818334Speter
343918334Speterstatic void
3440132732Skanpad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
3441132732Skan		      struct args_size *alignment_pad)
344218334Speter{
344390091Sobrien  tree save_var = NULL_TREE;
344490091Sobrien  HOST_WIDE_INT save_constant = 0;
344518334Speter  int boundary_in_bytes = boundary / BITS_PER_UNIT;
3446132732Skan  HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET;
344790091Sobrien
3448132732Skan#ifdef SPARC_STACK_BOUNDARY_HACK
3449169702Skan  /* ??? The SPARC port may claim a STACK_BOUNDARY higher than
3450169702Skan     the real alignment of %sp.  However, when it does this, the
3451169702Skan     alignment of %sp+STACK_POINTER_OFFSET is STACK_BOUNDARY.  */
3452132732Skan  if (SPARC_STACK_BOUNDARY_HACK)
3453132732Skan    sp_offset = 0;
3454132732Skan#endif
3455132732Skan
345690091Sobrien  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
345790091Sobrien    {
345890091Sobrien      save_var = offset_ptr->var;
345990091Sobrien      save_constant = offset_ptr->constant;
346090091Sobrien    }
346190091Sobrien
346290091Sobrien  alignment_pad->var = NULL_TREE;
346390091Sobrien  alignment_pad->constant = 0;
346490091Sobrien
346518334Speter  if (boundary > BITS_PER_UNIT)
346618334Speter    {
346718334Speter      if (offset_ptr->var)
346818334Speter	{
3469132732Skan	  tree sp_offset_tree = ssize_int (sp_offset);
3470132732Skan	  tree offset = size_binop (PLUS_EXPR,
3471132732Skan				    ARGS_SIZE_TREE (*offset_ptr),
3472132732Skan				    sp_offset_tree);
347318334Speter#ifdef ARGS_GROW_DOWNWARD
3474132732Skan	  tree rounded = round_down (offset, boundary / BITS_PER_UNIT);
347518334Speter#else
3476132732Skan	  tree rounded = round_up   (offset, boundary / BITS_PER_UNIT);
347718334Speter#endif
3478132732Skan
3479132732Skan	  offset_ptr->var = size_binop (MINUS_EXPR, rounded, sp_offset_tree);
3480132732Skan	  /* ARGS_SIZE_TREE includes constant term.  */
3481132732Skan	  offset_ptr->constant = 0;
3482117404Skan	  if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
3483117404Skan	    alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
348490091Sobrien					     save_var);
348518334Speter	}
348618334Speter      else
348790091Sobrien	{
3488132732Skan	  offset_ptr->constant = -sp_offset +
348918334Speter#ifdef ARGS_GROW_DOWNWARD
3490132732Skan	    FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
349118334Speter#else
3492132732Skan	    CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
349318334Speter#endif
349490091Sobrien	    if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
349590091Sobrien	      alignment_pad->constant = offset_ptr->constant - save_constant;
349690091Sobrien	}
349718334Speter    }
349818334Speter}
349918334Speter
350018334Speterstatic void
3501132732Skanpad_below (struct args_size *offset_ptr, enum machine_mode passed_mode, tree sizetree)
350218334Speter{
350318334Speter  if (passed_mode != BLKmode)
350418334Speter    {
350518334Speter      if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
350618334Speter	offset_ptr->constant
350718334Speter	  += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
350818334Speter	       / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
350918334Speter	      - GET_MODE_SIZE (passed_mode));
351018334Speter    }
351118334Speter  else
351218334Speter    {
351318334Speter      if (TREE_CODE (sizetree) != INTEGER_CST
351418334Speter	  || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
351518334Speter	{
351618334Speter	  /* Round the size up to multiple of PARM_BOUNDARY bits.  */
351718334Speter	  tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
351818334Speter	  /* Add it in.  */
351918334Speter	  ADD_PARM_SIZE (*offset_ptr, s2);
352018334Speter	  SUB_PARM_SIZE (*offset_ptr, sizetree);
352118334Speter	}
352218334Speter    }
352318334Speter}
352418334Speter
352518334Speter/* Walk the tree of blocks describing the binding levels within a function
3526169702Skan   and warn about variables the might be killed by setjmp or vfork.
352718334Speter   This is done after calling flow_analysis and before global_alloc
352818334Speter   clobbers the pseudo-regs to hard regs.  */
352918334Speter
353018334Spetervoid
3531169702Skansetjmp_vars_warning (tree block)
353218334Speter{
353390091Sobrien  tree decl, sub;
3534169702Skan
353518334Speter  for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
353618334Speter    {
3537169702Skan      if (TREE_CODE (decl) == VAR_DECL
3538132732Skan	  && DECL_RTL_SET_P (decl)
3539169702Skan	  && REG_P (DECL_RTL (decl))
354018334Speter	  && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3541169702Skan	warning (0, "variable %q+D might be clobbered by %<longjmp%>"
3542169702Skan		 " or %<vfork%>",
3543169702Skan		 decl);
354418334Speter    }
3545169702Skan
354618334Speter  for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
3547169702Skan    setjmp_vars_warning (sub);
354818334Speter}
354918334Speter
3550169702Skan/* Do the appropriate part of setjmp_vars_warning
355118334Speter   but for arguments instead of local variables.  */
355218334Speter
355318334Spetervoid
3554132732Skansetjmp_args_warning (void)
355518334Speter{
355690091Sobrien  tree decl;
355718334Speter  for (decl = DECL_ARGUMENTS (current_function_decl);
355818334Speter       decl; decl = TREE_CHAIN (decl))
355918334Speter    if (DECL_RTL (decl) != 0
3560169702Skan	&& REG_P (DECL_RTL (decl))
356118334Speter	&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3562169702Skan      warning (0, "argument %q+D might be clobbered by %<longjmp%> or %<vfork%>",
3563169702Skan	       decl);
356418334Speter}
356518334Speter
356618334Speter
356790091Sobrien/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
356890091Sobrien   and create duplicate blocks.  */
356990091Sobrien/* ??? Need an option to either create block fragments or to create
357090091Sobrien   abstract origin duplicates of a source block.  It really depends
357190091Sobrien   on what optimization has been performed.  */
357218334Speter
357390091Sobrienvoid
3574132732Skanreorder_blocks (void)
357590091Sobrien{
357690091Sobrien  tree block = DECL_INITIAL (current_function_decl);
3577169702Skan  VEC(tree,heap) *block_stack;
357890091Sobrien
357990091Sobrien  if (block == NULL_TREE)
358090091Sobrien    return;
358190091Sobrien
3582169702Skan  block_stack = VEC_alloc (tree, heap, 10);
358390091Sobrien
358490091Sobrien  /* Reset the TREE_ASM_WRITTEN bit for all blocks.  */
3585169702Skan  clear_block_marks (block);
358690091Sobrien
358790091Sobrien  /* Prune the old trees away, so that they don't get in the way.  */
358890091Sobrien  BLOCK_SUBBLOCKS (block) = NULL_TREE;
358990091Sobrien  BLOCK_CHAIN (block) = NULL_TREE;
359090091Sobrien
359190091Sobrien  /* Recreate the block tree from the note nesting.  */
359290091Sobrien  reorder_blocks_1 (get_insns (), block, &block_stack);
359390091Sobrien  BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));
359490091Sobrien
3595169702Skan  VEC_free (tree, heap, block_stack);
359690091Sobrien}
359790091Sobrien
359890091Sobrien/* Helper function for reorder_blocks.  Reset TREE_ASM_WRITTEN.  */
359990091Sobrien
3600169702Skanvoid
3601169702Skanclear_block_marks (tree block)
360290091Sobrien{
360390091Sobrien  while (block)
360490091Sobrien    {
360590091Sobrien      TREE_ASM_WRITTEN (block) = 0;
3606169702Skan      clear_block_marks (BLOCK_SUBBLOCKS (block));
360790091Sobrien      block = BLOCK_CHAIN (block);
360890091Sobrien    }
360990091Sobrien}
361090091Sobrien
361190091Sobrienstatic void
3612169702Skanreorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack)
361318334Speter{
361418334Speter  rtx insn;
361518334Speter
361690091Sobrien  for (insn = insns; insn; insn = NEXT_INSN (insn))
361790091Sobrien    {
3618169702Skan      if (NOTE_P (insn))
361990091Sobrien	{
362090091Sobrien	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
362190091Sobrien	    {
362290091Sobrien	      tree block = NOTE_BLOCK (insn);
3623169702Skan	      tree origin;
362418334Speter
3625169702Skan	      origin = (BLOCK_FRAGMENT_ORIGIN (block)
3626169702Skan			? BLOCK_FRAGMENT_ORIGIN (block)
3627169702Skan			: block);
3628169702Skan
362990091Sobrien	      /* If we have seen this block before, that means it now
363090091Sobrien		 spans multiple address regions.  Create a new fragment.  */
363190091Sobrien	      if (TREE_ASM_WRITTEN (block))
363290091Sobrien		{
363390091Sobrien		  tree new_block = copy_node (block);
363418334Speter
363590091Sobrien		  BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
363690091Sobrien		  BLOCK_FRAGMENT_CHAIN (new_block)
363790091Sobrien		    = BLOCK_FRAGMENT_CHAIN (origin);
363890091Sobrien		  BLOCK_FRAGMENT_CHAIN (origin) = new_block;
363918334Speter
364090091Sobrien		  NOTE_BLOCK (insn) = new_block;
364190091Sobrien		  block = new_block;
364290091Sobrien		}
364390091Sobrien
364490091Sobrien	      BLOCK_SUBBLOCKS (block) = 0;
364590091Sobrien	      TREE_ASM_WRITTEN (block) = 1;
3646132732Skan	      /* When there's only one block for the entire function,
3647132732Skan		 current_block == block and we mustn't do this, it
3648132732Skan		 will cause infinite recursion.  */
3649132732Skan	      if (block != current_block)
3650132732Skan		{
3651169702Skan		  if (block != origin)
3652169702Skan		    gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block);
3653169702Skan
3654132732Skan		  BLOCK_SUPERCONTEXT (block) = current_block;
3655132732Skan		  BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
3656132732Skan		  BLOCK_SUBBLOCKS (current_block) = block;
3657169702Skan		  current_block = origin;
3658132732Skan		}
3659169702Skan	      VEC_safe_push (tree, heap, *p_block_stack, block);
366090091Sobrien	    }
366190091Sobrien	  else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
366290091Sobrien	    {
3663169702Skan	      NOTE_BLOCK (insn) = VEC_pop (tree, *p_block_stack);
366490091Sobrien	      BLOCK_SUBBLOCKS (current_block)
366590091Sobrien		= blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
366690091Sobrien	      current_block = BLOCK_SUPERCONTEXT (current_block);
366790091Sobrien	    }
366890091Sobrien	}
366990091Sobrien    }
367018334Speter}
367118334Speter
367218334Speter/* Reverse the order of elements in the chain T of blocks,
367318334Speter   and return the new head of the chain (old last element).  */
367418334Speter
3675169702Skantree
3676132732Skanblocks_nreverse (tree t)
367718334Speter{
367890091Sobrien  tree prev = 0, decl, next;
367918334Speter  for (decl = t; decl; decl = next)
368018334Speter    {
368118334Speter      next = BLOCK_CHAIN (decl);
368218334Speter      BLOCK_CHAIN (decl) = prev;
368318334Speter      prev = decl;
368418334Speter    }
368518334Speter  return prev;
368618334Speter}
368718334Speter
368890091Sobrien/* Count the subblocks of the list starting with BLOCK.  If VECTOR is
368990091Sobrien   non-NULL, list them all into VECTOR, in a depth-first preorder
369090091Sobrien   traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
369152268Sobrien   blocks.  */
369218334Speter
369318334Speterstatic int
3694132732Skanall_blocks (tree block, tree *vector)
369518334Speter{
369652268Sobrien  int n_blocks = 0;
369718334Speter
369852268Sobrien  while (block)
369952268Sobrien    {
370052268Sobrien      TREE_ASM_WRITTEN (block) = 0;
370118334Speter
370252268Sobrien      /* Record this block.  */
370352268Sobrien      if (vector)
370452268Sobrien	vector[n_blocks] = block;
370518334Speter
370652268Sobrien      ++n_blocks;
370790091Sobrien
370852268Sobrien      /* Record the subblocks, and their subblocks...  */
370952268Sobrien      n_blocks += all_blocks (BLOCK_SUBBLOCKS (block),
371052268Sobrien			      vector ? vector + n_blocks : 0);
371152268Sobrien      block = BLOCK_CHAIN (block);
371252268Sobrien    }
371352268Sobrien
371418334Speter  return n_blocks;
371518334Speter}
371618334Speter
371790091Sobrien/* Return a vector containing all the blocks rooted at BLOCK.  The
371890091Sobrien   number of elements in the vector is stored in N_BLOCKS_P.  The
371990091Sobrien   vector is dynamically allocated; it is the caller's responsibility
372090091Sobrien   to call `free' on the pointer returned.  */
372190091Sobrien
372290091Sobrienstatic tree *
3723132732Skanget_block_vector (tree block, int *n_blocks_p)
372490091Sobrien{
372590091Sobrien  tree *block_vector;
372690091Sobrien
372790091Sobrien  *n_blocks_p = all_blocks (block, NULL);
3728169702Skan  block_vector = XNEWVEC (tree, *n_blocks_p);
372990091Sobrien  all_blocks (block, block_vector);
373090091Sobrien
373190091Sobrien  return block_vector;
373290091Sobrien}
373390091Sobrien
3734132732Skanstatic GTY(()) int next_block_index = 2;
373590091Sobrien
373690091Sobrien/* Set BLOCK_NUMBER for all the blocks in FN.  */
373790091Sobrien
373818334Spetervoid
3739132732Skannumber_blocks (tree fn)
374018334Speter{
374190091Sobrien  int i;
374290091Sobrien  int n_blocks;
374390091Sobrien  tree *block_vector;
374490091Sobrien
374590091Sobrien  /* For SDB and XCOFF debugging output, we start numbering the blocks
374690091Sobrien     from 1 within each function, rather than keeping a running
374790091Sobrien     count.  */
374890091Sobrien#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
374990091Sobrien  if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
375090091Sobrien    next_block_index = 1;
375190091Sobrien#endif
375290091Sobrien
375390091Sobrien  block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks);
375490091Sobrien
375590091Sobrien  /* The top-level BLOCK isn't numbered at all.  */
375690091Sobrien  for (i = 1; i < n_blocks; ++i)
375790091Sobrien    /* We number the blocks from two.  */
375890091Sobrien    BLOCK_NUMBER (block_vector[i]) = next_block_index++;
375990091Sobrien
376090091Sobrien  free (block_vector);
376190091Sobrien
376290091Sobrien  return;
376390091Sobrien}
376490091Sobrien
376590091Sobrien/* If VAR is present in a subblock of BLOCK, return the subblock.  */
376690091Sobrien
376790091Sobrientree
3768132732Skandebug_find_var_in_block_tree (tree var, tree block)
376990091Sobrien{
377090091Sobrien  tree t;
377190091Sobrien
377290091Sobrien  for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
377390091Sobrien    if (t == var)
377490091Sobrien      return block;
377590091Sobrien
377690091Sobrien  for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
377790091Sobrien    {
377890091Sobrien      tree ret = debug_find_var_in_block_tree (var, t);
377990091Sobrien      if (ret)
378090091Sobrien	return ret;
378190091Sobrien    }
378290091Sobrien
378390091Sobrien  return NULL_TREE;
378490091Sobrien}
378590091Sobrien
3786132732Skan/* Allocate a function structure for FNDECL and set its contents
3787132732Skan   to the defaults.  */
378890091Sobrien
3789132732Skanvoid
3790132732Skanallocate_struct_function (tree fndecl)
379190091Sobrien{
3792132732Skan  tree result;
3793169702Skan  tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE;
379490091Sobrien
3795132732Skan  cfun = ggc_alloc_cleared (sizeof (struct function));
379618334Speter
3797132732Skan  cfun->stack_alignment_needed = STACK_BOUNDARY;
3798132732Skan  cfun->preferred_stack_boundary = STACK_BOUNDARY;
379918334Speter
3800132732Skan  current_function_funcdef_no = funcdef_no++;
380118334Speter
3802132732Skan  cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
380318334Speter
3804132732Skan  init_eh_for_function ();
380518334Speter
3806169702Skan  lang_hooks.function.init (cfun);
3807132732Skan  if (init_machine_status)
3808132732Skan    cfun->machine = (*init_machine_status) ();
380918334Speter
3810132732Skan  if (fndecl == NULL)
3811132732Skan    return;
381218334Speter
3813169702Skan  DECL_STRUCT_FUNCTION (fndecl) = cfun;
3814132732Skan  cfun->decl = fndecl;
381518334Speter
3816132732Skan  result = DECL_RESULT (fndecl);
3817132732Skan  if (aggregate_value_p (result, fndecl))
3818132732Skan    {
3819132732Skan#ifdef PCC_STATIC_STRUCT_RETURN
3820132732Skan      current_function_returns_pcc_struct = 1;
3821132732Skan#endif
3822132732Skan      current_function_returns_struct = 1;
3823132732Skan    }
382418334Speter
3825132732Skan  current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
382618334Speter
3827169702Skan  current_function_stdarg
3828169702Skan    = (fntype
3829169702Skan       && TYPE_ARG_TYPES (fntype) != 0
3830169702Skan       && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3831169702Skan	   != void_type_node));
3832169702Skan
3833169702Skan  /* Assume all registers in stdarg functions need to be saved.  */
3834169702Skan  cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
3835169702Skan  cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
3836132732Skan}
383718334Speter
3838132732Skan/* Reset cfun, and other non-struct-function variables to defaults as
3839132732Skan   appropriate for emitting rtl at the start of a function.  */
384018334Speter
3841132732Skanstatic void
3842132732Skanprepare_function_start (tree fndecl)
3843132732Skan{
3844169702Skan  if (fndecl && DECL_STRUCT_FUNCTION (fndecl))
3845169702Skan    cfun = DECL_STRUCT_FUNCTION (fndecl);
3846132732Skan  else
3847132732Skan    allocate_struct_function (fndecl);
3848132732Skan  init_emit ();
3849132732Skan  init_varasm_status (cfun);
3850132732Skan  init_expr ();
385118334Speter
3852132732Skan  cse_not_expected = ! optimize;
385318334Speter
3854132732Skan  /* Caller save not needed yet.  */
3855132732Skan  caller_save_needed = 0;
385618334Speter
3857132732Skan  /* We haven't done register allocation yet.  */
3858132732Skan  reg_renumber = 0;
385918334Speter
386090091Sobrien  /* Indicate that we have not instantiated virtual registers yet.  */
386190091Sobrien  virtuals_instantiated = 0;
386290091Sobrien
386390091Sobrien  /* Indicate that we want CONCATs now.  */
386490091Sobrien  generating_concat_p = 1;
386590091Sobrien
386690091Sobrien  /* Indicate we have no need of a frame pointer yet.  */
386790091Sobrien  frame_pointer_needed = 0;
386890091Sobrien}
386990091Sobrien
387090091Sobrien/* Initialize the rtl expansion mechanism so that we can do simple things
387190091Sobrien   like generate sequences.  This is used to provide a context during global
387290091Sobrien   initialization of some passes.  */
387390091Sobrienvoid
3874132732Skaninit_dummy_function_start (void)
387590091Sobrien{
3876132732Skan  prepare_function_start (NULL);
387790091Sobrien}
387890091Sobrien
387990091Sobrien/* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
388090091Sobrien   and initialize static variables for generating RTL for the statements
388190091Sobrien   of the function.  */
388290091Sobrien
388390091Sobrienvoid
3884132732Skaninit_function_start (tree subr)
388590091Sobrien{
3886132732Skan  prepare_function_start (subr);
388790091Sobrien
3888132732Skan  /* Prevent ever trying to delete the first instruction of a
3889132732Skan     function.  Also tell final how to output a linenum before the
3890132732Skan     function prologue.  Note linenums could be missing, e.g. when
3891132732Skan     compiling a Java .class file.  */
3892169702Skan  if (! DECL_IS_BUILTIN (subr))
3893132732Skan    emit_line_note (DECL_SOURCE_LOCATION (subr));
389418334Speter
389518334Speter  /* Make sure first insn is a note even if we don't want linenums.
389618334Speter     This makes sure the first insn will never be deleted.
389718334Speter     Also, final expects a note to appear there.  */
3898132732Skan  emit_note (NOTE_INSN_DELETED);
389918334Speter
390018334Speter  /* Warn if this value is an aggregate type,
390118334Speter     regardless of which calling convention we are using for it.  */
3902169702Skan  if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
3903169702Skan    warning (OPT_Waggregate_return, "function returns an aggregate");
390490091Sobrien}
390518334Speter
390690091Sobrien/* Make sure all values used by the optimization passes have sane
390790091Sobrien   defaults.  */
3908169702Skanunsigned int
3909132732Skaninit_function_for_compilation (void)
391090091Sobrien{
391190091Sobrien  reg_renumber = 0;
391218334Speter
3913169702Skan  /* No prologue/epilogue insns yet.  Make sure that these vectors are
3914169702Skan     empty.  */
3915169702Skan  gcc_assert (VEC_length (int, prologue) == 0);
3916169702Skan  gcc_assert (VEC_length (int, epilogue) == 0);
3917169702Skan  gcc_assert (VEC_length (int, sibcall_epilogue) == 0);
3918169702Skan  return 0;
391918334Speter}
392018334Speter
3921169702Skanstruct tree_opt_pass pass_init_function =
3922169702Skan{
3923169702Skan  NULL,                                 /* name */
3924169702Skan  NULL,                                 /* gate */
3925169702Skan  init_function_for_compilation,        /* execute */
3926169702Skan  NULL,                                 /* sub */
3927169702Skan  NULL,                                 /* next */
3928169702Skan  0,                                    /* static_pass_number */
3929169702Skan  0,                                    /* tv_id */
3930169702Skan  0,                                    /* properties_required */
3931169702Skan  0,                                    /* properties_provided */
3932169702Skan  0,                                    /* properties_destroyed */
3933169702Skan  0,                                    /* todo_flags_start */
3934169702Skan  0,                                    /* todo_flags_finish */
3935169702Skan  0                                     /* letter */
3936169702Skan};
393718334Speter
393818334Speter
393918334Spetervoid
3940132732Skanexpand_main_function (void)
394118334Speter{
3942169702Skan#if (defined(INVOKE__main)				\
3943169702Skan     || (!defined(HAS_INIT_SECTION)			\
3944169702Skan	 && !defined(INIT_SECTION_ASM_OP)		\
3945169702Skan	 && !defined(INIT_ARRAY_SECTION_ASM_OP)))
3946169702Skan  emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
3947169702Skan#endif
3948169702Skan}
3949169702Skan
3950169702Skan/* Expand code to initialize the stack_protect_guard.  This is invoked at
3951169702Skan   the beginning of a function to be protected.  */
395290091Sobrien
3953169702Skan#ifndef HAVE_stack_protect_set
3954169702Skan# define HAVE_stack_protect_set		0
3955169702Skan# define gen_stack_protect_set(x,y)	(gcc_unreachable (), NULL_RTX)
395690091Sobrien#endif
3957117404Skan
3958169702Skanvoid
3959169702Skanstack_protect_prologue (void)
3960169702Skan{
3961169702Skan  tree guard_decl = targetm.stack_protect_guard ();
3962169702Skan  rtx x, y;
396390091Sobrien
3964169702Skan  /* Avoid expand_expr here, because we don't want guard_decl pulled
3965169702Skan     into registers unless absolutely necessary.  And we know that
3966169702Skan     cfun->stack_protect_guard is a local stack slot, so this skips
3967169702Skan     all the fluff.  */
3968169702Skan  x = validize_mem (DECL_RTL (cfun->stack_protect_guard));
3969169702Skan  y = validize_mem (DECL_RTL (guard_decl));
3970169702Skan
3971169702Skan  /* Allow the target to copy from Y to X without leaking Y into a
3972169702Skan     register.  */
3973169702Skan  if (HAVE_stack_protect_set)
3974169702Skan    {
3975169702Skan      rtx insn = gen_stack_protect_set (x, y);
3976169702Skan      if (insn)
3977169702Skan	{
3978169702Skan	  emit_insn (insn);
3979169702Skan	  return;
3980169702Skan	}
398190091Sobrien    }
398290091Sobrien
3983169702Skan  /* Otherwise do a straight move.  */
3984169702Skan  emit_move_insn (x, y);
398518334Speter}
398690091Sobrien
3987169702Skan/* Expand code to verify the stack_protect_guard.  This is invoked at
3988169702Skan   the end of a function to be protected.  */
3989169702Skan
3990169702Skan#ifndef HAVE_stack_protect_test
3991169702Skan# define HAVE_stack_protect_test		0
3992169702Skan# define gen_stack_protect_test(x, y, z)	(gcc_unreachable (), NULL_RTX)
3993169702Skan#endif
3994169702Skan
399590091Sobrienvoid
3996169702Skanstack_protect_epilogue (void)
399790091Sobrien{
3998169702Skan  tree guard_decl = targetm.stack_protect_guard ();
3999169702Skan  rtx label = gen_label_rtx ();
4000169702Skan  rtx x, y, tmp;
400190091Sobrien
4002169702Skan  /* Avoid expand_expr here, because we don't want guard_decl pulled
4003169702Skan     into registers unless absolutely necessary.  And we know that
4004169702Skan     cfun->stack_protect_guard is a local stack slot, so this skips
4005169702Skan     all the fluff.  */
4006169702Skan  x = validize_mem (DECL_RTL (cfun->stack_protect_guard));
4007169702Skan  y = validize_mem (DECL_RTL (guard_decl));
4008169702Skan
4009169702Skan  /* Allow the target to compare Y with X without leaking either into
4010169702Skan     a register.  */
4011222207Sbenl  if (HAVE_stack_protect_test != 0)
401290091Sobrien    {
4013169702Skan      tmp = gen_stack_protect_test (x, y, label);
4014169702Skan      if (tmp)
4015169702Skan	{
4016169702Skan	  emit_insn (tmp);
4017222207Sbenl	  goto done;
4018169702Skan	}
401990091Sobrien    }
4020169702Skan
4021222207Sbenl  emit_cmp_and_jump_insns (x, y, EQ, NULL_RTX, ptr_mode, 1, label);
4022222207Sbenl done:
4023222207Sbenl
4024169702Skan  /* The noreturn predictor has been moved to the tree level.  The rtl-level
4025169702Skan     predictors estimate this branch about 20%, which isn't enough to get
4026169702Skan     things moved out of line.  Since this is the only extant case of adding
4027169702Skan     a noreturn function at the rtl level, it doesn't seem worth doing ought
4028169702Skan     except adding the prediction by hand.  */
4029169702Skan  tmp = get_last_insn ();
4030169702Skan  if (JUMP_P (tmp))
4031169702Skan    predict_insn_def (tmp, PRED_NORETURN, TAKEN);
4032169702Skan
4033169702Skan  expand_expr_stmt (targetm.stack_protect_fail ());
4034169702Skan  emit_label (label);
403590091Sobrien}
4036169702Skan
403718334Speter/* Start the RTL for a new function, and set variables used for
403818334Speter   emitting RTL.
403918334Speter   SUBR is the FUNCTION_DECL node.
404018334Speter   PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
404118334Speter   the function's parameters, which must be run at any return statement.  */
404218334Speter
404318334Spetervoid
4044169702Skanexpand_function_start (tree subr)
404518334Speter{
404618334Speter  /* Make sure volatile mem refs aren't considered
404718334Speter     valid operands of arithmetic insns.  */
404818334Speter  init_recog_no_volatile ();
404918334Speter
405090091Sobrien  current_function_profile
405190091Sobrien    = (profile_flag
405290091Sobrien       && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
405390091Sobrien
405490091Sobrien  current_function_limit_stack
405590091Sobrien    = (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr));
405690091Sobrien
405790091Sobrien  /* Make the label for return statements to jump to.  Do not special
405890091Sobrien     case machines with special return instructions -- they will be
405990091Sobrien     handled later during jump, ifcvt, or epilogue creation.  */
406018334Speter  return_label = gen_label_rtx ();
406118334Speter
406218334Speter  /* Initialize rtx used to return the value.  */
406318334Speter  /* Do this before assign_parms so that we copy the struct value address
406418334Speter     before any library calls that assign parms might generate.  */
406518334Speter
406618334Speter  /* Decide whether to return the value in memory or in a register.  */
4067132732Skan  if (aggregate_value_p (DECL_RESULT (subr), subr))
406818334Speter    {
406918334Speter      /* Returning something that won't go in a register.  */
407090091Sobrien      rtx value_address = 0;
407118334Speter
407218334Speter#ifdef PCC_STATIC_STRUCT_RETURN
407318334Speter      if (current_function_returns_pcc_struct)
407418334Speter	{
407518334Speter	  int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
407618334Speter	  value_address = assemble_static_space (size);
407718334Speter	}
407818334Speter      else
407918334Speter#endif
408018334Speter	{
4081169702Skan	  rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 2);
408218334Speter	  /* Expect to be passed the address of a place to store the value.
408318334Speter	     If it is passed as an argument, assign_parms will take care of
408418334Speter	     it.  */
4085132732Skan	  if (sv)
408618334Speter	    {
408718334Speter	      value_address = gen_reg_rtx (Pmode);
4088132732Skan	      emit_move_insn (value_address, sv);
408918334Speter	    }
409018334Speter	}
409118334Speter      if (value_address)
409218334Speter	{
4093169702Skan	  rtx x = value_address;
4094169702Skan	  if (!DECL_BY_REFERENCE (DECL_RESULT (subr)))
4095169702Skan	    {
4096169702Skan	      x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), x);
4097169702Skan	      set_mem_attributes (x, DECL_RESULT (subr), 1);
4098169702Skan	    }
409990091Sobrien	  SET_DECL_RTL (DECL_RESULT (subr), x);
410018334Speter	}
410118334Speter    }
410218334Speter  else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
410318334Speter    /* If return mode is void, this decl rtl should not be used.  */
410490091Sobrien    SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX);
410590091Sobrien  else
410618334Speter    {
410790091Sobrien      /* Compute the return values into a pseudo reg, which we will copy
410890091Sobrien	 into the true return register after the cleanups are done.  */
4109169702Skan      tree return_type = TREE_TYPE (DECL_RESULT (subr));
4110169702Skan      if (TYPE_MODE (return_type) != BLKmode
4111169702Skan	  && targetm.calls.return_in_msb (return_type))
4112169702Skan	/* expand_function_end will insert the appropriate padding in
4113169702Skan	   this case.  Use the return value's natural (unpadded) mode
4114169702Skan	   within the function proper.  */
4115169702Skan	SET_DECL_RTL (DECL_RESULT (subr),
4116169702Skan		      gen_reg_rtx (TYPE_MODE (return_type)));
4117169702Skan      else
4118169702Skan	{
4119169702Skan	  /* In order to figure out what mode to use for the pseudo, we
4120169702Skan	     figure out what the mode of the eventual return register will
4121169702Skan	     actually be, and use that.  */
4122169702Skan	  rtx hard_reg = hard_function_value (return_type, subr, 0, 1);
412318334Speter
4124169702Skan	  /* Structures that are returned in registers are not
4125169702Skan	     aggregate_value_p, so we may see a PARALLEL or a REG.  */
4126169702Skan	  if (REG_P (hard_reg))
4127169702Skan	    SET_DECL_RTL (DECL_RESULT (subr),
4128169702Skan			  gen_reg_rtx (GET_MODE (hard_reg)));
4129169702Skan	  else
4130169702Skan	    {
4131169702Skan	      gcc_assert (GET_CODE (hard_reg) == PARALLEL);
4132169702Skan	      SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg));
4133169702Skan	    }
4134169702Skan	}
413518334Speter
4136117404Skan      /* Set DECL_REGISTER flag so that expand_function_end will copy the
4137117404Skan	 result to the real return register(s).  */
4138117404Skan      DECL_REGISTER (DECL_RESULT (subr)) = 1;
413918334Speter    }
414018334Speter
414118334Speter  /* Initialize rtx for parameters and local variables.
414218334Speter     In some cases this requires emitting insns.  */
414390091Sobrien  assign_parms (subr);
414418334Speter
4145169702Skan  /* If function gets a static chain arg, store it.  */
4146169702Skan  if (cfun->static_chain_decl)
4147169702Skan    {
4148169702Skan      tree parm = cfun->static_chain_decl;
4149169702Skan      rtx local = gen_reg_rtx (Pmode);
415018334Speter
4151169702Skan      set_decl_incoming_rtl (parm, static_chain_incoming_rtx);
4152169702Skan      SET_DECL_RTL (parm, local);
4153169702Skan      mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
415418334Speter
4155169702Skan      emit_move_insn (local, static_chain_incoming_rtx);
4156169702Skan    }
4157169702Skan
4158169702Skan  /* If the function receives a non-local goto, then store the
4159169702Skan     bits we need to restore the frame pointer.  */
4160169702Skan  if (cfun->nonlocal_goto_save_area)
4161169702Skan    {
4162169702Skan      tree t_save;
4163169702Skan      rtx r_save;
4164169702Skan
4165169702Skan      /* ??? We need to do this save early.  Unfortunately here is
4166169702Skan	 before the frame variable gets declared.  Help out...  */
4167169702Skan      expand_var (TREE_OPERAND (cfun->nonlocal_goto_save_area, 0));
4168169702Skan
4169169702Skan      t_save = build4 (ARRAY_REF, ptr_type_node,
4170169702Skan		       cfun->nonlocal_goto_save_area,
4171169702Skan		       integer_zero_node, NULL_TREE, NULL_TREE);
4172169702Skan      r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE);
4173169702Skan      r_save = convert_memory_address (Pmode, r_save);
4174169702Skan
4175169702Skan      emit_move_insn (r_save, virtual_stack_vars_rtx);
4176169702Skan      update_nonlocal_goto_save_area ();
4177169702Skan    }
4178169702Skan
417918334Speter  /* The following was moved from init_function_start.
418018334Speter     The move is supposed to make sdb output more accurate.  */
418118334Speter  /* Indicate the beginning of the function body,
418218334Speter     as opposed to parm setup.  */
4183132732Skan  emit_note (NOTE_INSN_FUNCTION_BEG);
418418334Speter
4185169702Skan  gcc_assert (NOTE_P (get_last_insn ()));
4186169702Skan
418718334Speter  parm_birth_insn = get_last_insn ();
418818334Speter
418996283Sobrien  if (current_function_profile)
419096283Sobrien    {
419190091Sobrien#ifdef PROFILE_HOOK
4192117404Skan      PROFILE_HOOK (current_function_funcdef_no);
419390091Sobrien#endif
419496283Sobrien    }
419590091Sobrien
4196169702Skan  /* After the display initializations is where the stack checking
4197169702Skan     probe should go.  */
4198169702Skan  if(flag_stack_check)
4199169702Skan    stack_check_probe_note = emit_note (NOTE_INSN_DELETED);
420018334Speter
420118334Speter  /* Make sure there is a line number after the function entry setup code.  */
420218334Speter  force_next_line_note ();
420318334Speter}
420418334Speter
420590091Sobrien/* Undo the effects of init_dummy_function_start.  */
420690091Sobrienvoid
4207132732Skanexpand_dummy_function_end (void)
420890091Sobrien{
420990091Sobrien  /* End any sequences that failed to be closed due to syntax errors.  */
421090091Sobrien  while (in_sequence_p ())
421190091Sobrien    end_sequence ();
421290091Sobrien
421390091Sobrien  /* Outside function body, can't compute type's actual size
421490091Sobrien     until next function's body starts.  */
421590091Sobrien
421690091Sobrien  free_after_parsing (cfun);
421790091Sobrien  free_after_compilation (cfun);
421890091Sobrien  cfun = 0;
421990091Sobrien}
422090091Sobrien
422190091Sobrien/* Call DOIT for each hard register used as a return value from
422290091Sobrien   the current function.  */
422390091Sobrien
422490091Sobrienvoid
4225132732Skandiddle_return_value (void (*doit) (rtx, void *), void *arg)
422690091Sobrien{
422790091Sobrien  rtx outgoing = current_function_return_rtx;
422890091Sobrien
422990091Sobrien  if (! outgoing)
423090091Sobrien    return;
423190091Sobrien
4232169702Skan  if (REG_P (outgoing))
423390091Sobrien    (*doit) (outgoing, arg);
423490091Sobrien  else if (GET_CODE (outgoing) == PARALLEL)
423590091Sobrien    {
423690091Sobrien      int i;
423790091Sobrien
423890091Sobrien      for (i = 0; i < XVECLEN (outgoing, 0); i++)
423990091Sobrien	{
424090091Sobrien	  rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);
424190091Sobrien
4242169702Skan	  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
424390091Sobrien	    (*doit) (x, arg);
424490091Sobrien	}
424590091Sobrien    }
424690091Sobrien}
424790091Sobrien
424890091Sobrienstatic void
4249132732Skando_clobber_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
425090091Sobrien{
425190091Sobrien  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg));
425290091Sobrien}
425390091Sobrien
425490091Sobrienvoid
4255132732Skanclobber_return_register (void)
425690091Sobrien{
425790091Sobrien  diddle_return_value (do_clobber_return_reg, NULL);
425890091Sobrien
425990091Sobrien  /* In case we do use pseudo to return value, clobber it too.  */
426090091Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
426190091Sobrien    {
426290091Sobrien      tree decl_result = DECL_RESULT (current_function_decl);
426390091Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
426490091Sobrien      if (REG_P (decl_rtl) && REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER)
426590091Sobrien	{
426690091Sobrien	  do_clobber_return_reg (decl_rtl, NULL);
426790091Sobrien	}
426890091Sobrien    }
426990091Sobrien}
427090091Sobrien
427190091Sobrienstatic void
4272132732Skando_use_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
427390091Sobrien{
427490091Sobrien  emit_insn (gen_rtx_USE (VOIDmode, reg));
427590091Sobrien}
427690091Sobrien
4277169702Skanstatic void
4278132732Skanuse_return_register (void)
427990091Sobrien{
428090091Sobrien  diddle_return_value (do_use_return_reg, NULL);
428190091Sobrien}
428290091Sobrien
4283132732Skan/* Possibly warn about unused parameters.  */
4284132732Skanvoid
4285132732Skando_warn_unused_parameter (tree fn)
4286132732Skan{
4287132732Skan  tree decl;
4288132732Skan
4289132732Skan  for (decl = DECL_ARGUMENTS (fn);
4290132732Skan       decl; decl = TREE_CHAIN (decl))
4291132732Skan    if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
4292132732Skan	&& DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))
4293169702Skan      warning (OPT_Wunused_parameter, "unused parameter %q+D", decl);
4294132732Skan}
4295132732Skan
4296117404Skanstatic GTY(()) rtx initial_trampoline;
4297117404Skan
4298132732Skan/* Generate RTL for the end of the current function.  */
429918334Speter
430018334Spetervoid
4301132732Skanexpand_function_end (void)
430218334Speter{
430390091Sobrien  rtx clobber_after;
430418334Speter
430590091Sobrien  /* If arg_pointer_save_area was referenced only from a nested
430690091Sobrien     function, we will not have initialized it yet.  Do that now.  */
430790091Sobrien  if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init)
430890091Sobrien    get_arg_pointer_save_area (cfun);
430990091Sobrien
431052268Sobrien  /* If we are doing stack checking and this function makes calls,
431152268Sobrien     do a stack probe at the start of the function to ensure we have enough
431252268Sobrien     space for another stack frame.  */
431352268Sobrien  if (flag_stack_check && ! STACK_CHECK_BUILTIN)
431452268Sobrien    {
431552268Sobrien      rtx insn, seq;
431652268Sobrien
431752268Sobrien      for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4318169702Skan	if (CALL_P (insn))
431952268Sobrien	  {
432052268Sobrien	    start_sequence ();
432152268Sobrien	    probe_stack_range (STACK_CHECK_PROTECT,
432252268Sobrien			       GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
432352268Sobrien	    seq = get_insns ();
432452268Sobrien	    end_sequence ();
4325169702Skan	    emit_insn_before (seq, stack_check_probe_note);
432652268Sobrien	    break;
432752268Sobrien	  }
432852268Sobrien    }
432952268Sobrien
4330132732Skan  /* Possibly warn about unused parameters.
4331132732Skan     When frontend does unit-at-a-time, the warning is already
4332132732Skan     issued at finalization time.  */
4333132732Skan  if (warn_unused_parameter
4334132732Skan      && !lang_hooks.callgraph.expand_function)
4335132732Skan    do_warn_unused_parameter (current_function_decl);
433618334Speter
433718334Speter  /* End any sequences that failed to be closed due to syntax errors.  */
433818334Speter  while (in_sequence_p ())
433918334Speter    end_sequence ();
434018334Speter
434118334Speter  clear_pending_stack_adjust ();
434218334Speter  do_pending_stack_adjust ();
434318334Speter
434418334Speter  /* Mark the end of the function body.
434518334Speter     If control reaches this insn, the function can drop through
434618334Speter     without returning a value.  */
4347132732Skan  emit_note (NOTE_INSN_FUNCTION_END);
434818334Speter
434952268Sobrien  /* Must mark the last line number note in the function, so that the test
435052268Sobrien     coverage code can avoid counting the last line twice.  This just tells
435152268Sobrien     the code to ignore the immediately following line note, since there
435252268Sobrien     already exists a copy of this note somewhere above.  This line number
435352268Sobrien     note is still needed for debugging though, so we can't delete it.  */
435452268Sobrien  if (flag_test_coverage)
4355132732Skan    emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
435652268Sobrien
435718334Speter  /* Output a linenumber for the end of the function.
435818334Speter     SDB depends on this.  */
4359132732Skan  force_next_line_note ();
4360132732Skan  emit_line_note (input_location);
436118334Speter
436290091Sobrien  /* Before the return label (if any), clobber the return
436390091Sobrien     registers so that they are not propagated live to the rest of
436490091Sobrien     the function.  This can only happen with functions that drop
436590091Sobrien     through; if there had been a return statement, there would
436690091Sobrien     have either been a return rtx, or a jump to the return label.
436790091Sobrien
436890091Sobrien     We delay actual code generation after the current_function_value_rtx
436990091Sobrien     is computed.  */
437090091Sobrien  clobber_after = get_last_insn ();
437190091Sobrien
4372169702Skan  /* Output the label for the actual return from the function.  */
4373169702Skan  emit_label (return_label);
437418334Speter
4375124167Sbde#ifdef TARGET_PROFILER_EPILOGUE
4376124160Skan  if (current_function_profile && TARGET_PROFILER_EPILOGUE)
4377124160Skan    {
4378124160Skan      static rtx mexitcount_libfunc;
4379124160Skan      static int initialized;
4380124160Skan
4381124160Skan      if (!initialized)
4382124160Skan	{
4383124160Skan	  mexitcount_libfunc = init_one_libfunc (".mexitcount");
4384169702Skan	  initialized = 0;
4385124160Skan	}
4386124160Skan      emit_library_call (mexitcount_libfunc, LCT_NORMAL, VOIDmode, 0);
4387124160Skan    }
4388124167Sbde#endif
4389124160Skan
4390169702Skan  if (USING_SJLJ_EXCEPTIONS)
4391132732Skan    {
4392169702Skan      /* Let except.c know where it should emit the call to unregister
4393169702Skan	 the function context for sjlj exceptions.  */
4394169702Skan      if (flag_exceptions)
4395169702Skan	sjlj_emit_function_exit_after (get_last_insn ());
4396132732Skan    }
4397169702Skan  else
4398169702Skan    {
4399169702Skan      /* @@@ This is a kludge.  We want to ensure that instructions that
4400169702Skan	 may trap are not moved into the epilogue by scheduling, because
4401169702Skan	 we don't always emit unwind information for the epilogue.
4402169702Skan	 However, not all machine descriptions define a blockage insn, so
4403169702Skan	 emit an ASM_INPUT to act as one.  */
4404169702Skan      if (flag_non_call_exceptions)
4405169702Skan	emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
4406169702Skan    }
440718334Speter
4408169702Skan  /* If this is an implementation of throw, do what's necessary to
4409169702Skan     communicate between __builtin_eh_return and the epilogue.  */
4410169702Skan  expand_eh_return ();
4411169702Skan
441290091Sobrien  /* If scalar return value was computed in a pseudo-reg, or was a named
441390091Sobrien     return value that got dumped to the stack, copy that to the hard
441490091Sobrien     return register.  */
441590091Sobrien  if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
441618334Speter    {
441790091Sobrien      tree decl_result = DECL_RESULT (current_function_decl);
441890091Sobrien      rtx decl_rtl = DECL_RTL (decl_result);
441918334Speter
442090091Sobrien      if (REG_P (decl_rtl)
442190091Sobrien	  ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
442290091Sobrien	  : DECL_REGISTER (decl_result))
442390091Sobrien	{
442496283Sobrien	  rtx real_decl_rtl = current_function_return_rtx;
442590091Sobrien
442696283Sobrien	  /* This should be set in assign_parms.  */
4427169702Skan	  gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl));
442852268Sobrien
442990091Sobrien	  /* If this is a BLKmode structure being returned in registers,
443090091Sobrien	     then use the mode computed in expand_return.  Note that if
4431117404Skan	     decl_rtl is memory, then its mode may have been changed,
443290091Sobrien	     but that current_function_return_rtx has not.  */
443390091Sobrien	  if (GET_MODE (real_decl_rtl) == BLKmode)
443496283Sobrien	    PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl));
443590091Sobrien
4436169702Skan	  /* If a non-BLKmode return value should be padded at the least
4437169702Skan	     significant end of the register, shift it left by the appropriate
4438169702Skan	     amount.  BLKmode results are handled using the group load/store
4439169702Skan	     machinery.  */
4440169702Skan	  if (TYPE_MODE (TREE_TYPE (decl_result)) != BLKmode
4441169702Skan	      && targetm.calls.return_in_msb (TREE_TYPE (decl_result)))
4442169702Skan	    {
4443169702Skan	      emit_move_insn (gen_rtx_REG (GET_MODE (decl_rtl),
4444169702Skan					   REGNO (real_decl_rtl)),
4445169702Skan			      decl_rtl);
4446169702Skan	      shift_return_value (GET_MODE (decl_rtl), true, real_decl_rtl);
4447169702Skan	    }
444890091Sobrien	  /* If a named return value dumped decl_return to memory, then
4449117404Skan	     we may need to re-do the PROMOTE_MODE signed/unsigned
445090091Sobrien	     extension.  */
4451169702Skan	  else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
445290091Sobrien	    {
4453169702Skan	      int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result));
445490091Sobrien
4455132732Skan	      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
4456132732Skan		promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
4457132732Skan			      &unsignedp, 1);
445890091Sobrien
445990091Sobrien	      convert_move (real_decl_rtl, decl_rtl, unsignedp);
446090091Sobrien	    }
446190091Sobrien	  else if (GET_CODE (real_decl_rtl) == PARALLEL)
4462117404Skan	    {
4463117404Skan	      /* If expand_function_start has created a PARALLEL for decl_rtl,
4464117404Skan		 move the result to the real return registers.  Otherwise, do
4465117404Skan		 a group load from decl_rtl for a named return.  */
4466117404Skan	      if (GET_CODE (decl_rtl) == PARALLEL)
4467117404Skan		emit_group_move (real_decl_rtl, decl_rtl);
4468117404Skan	      else
4469117404Skan		emit_group_load (real_decl_rtl, decl_rtl,
4470132732Skan				 TREE_TYPE (decl_result),
4471117404Skan				 int_size_in_bytes (TREE_TYPE (decl_result)));
4472117404Skan	    }
4473169702Skan	  /* In the case of complex integer modes smaller than a word, we'll
4474169702Skan	     need to generate some non-trivial bitfield insertions.  Do that
4475169702Skan	     on a pseudo and not the hard register.  */
4476169702Skan	  else if (GET_CODE (decl_rtl) == CONCAT
4477169702Skan		   && GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT
4478169702Skan		   && GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD)
4479169702Skan	    {
4480169702Skan	      int old_generating_concat_p;
4481169702Skan	      rtx tmp;
4482169702Skan
4483169702Skan	      old_generating_concat_p = generating_concat_p;
4484169702Skan	      generating_concat_p = 0;
4485169702Skan	      tmp = gen_reg_rtx (GET_MODE (decl_rtl));
4486169702Skan	      generating_concat_p = old_generating_concat_p;
4487169702Skan
4488169702Skan	      emit_move_insn (tmp, decl_rtl);
4489169702Skan	      emit_move_insn (real_decl_rtl, tmp);
4490169702Skan	    }
449190091Sobrien	  else
449290091Sobrien	    emit_move_insn (real_decl_rtl, decl_rtl);
449390091Sobrien	}
449418334Speter    }
449518334Speter
449618334Speter  /* If returning a structure, arrange to return the address of the value
449718334Speter     in a place where debuggers expect to find it.
449818334Speter
449918334Speter     If returning a structure PCC style,
450018334Speter     the caller also depends on this value.
450118334Speter     And current_function_returns_pcc_struct is not necessarily set.  */
450218334Speter  if (current_function_returns_struct
450318334Speter      || current_function_returns_pcc_struct)
450418334Speter    {
4505169702Skan      rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl));
450618334Speter      tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
4507169702Skan      rtx outgoing;
450818334Speter
4509169702Skan      if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl)))
4510169702Skan	type = TREE_TYPE (type);
4511169702Skan      else
4512169702Skan	value_address = XEXP (value_address, 0);
4513169702Skan
4514169702Skan      outgoing = targetm.calls.function_value (build_pointer_type (type),
4515169702Skan					       current_function_decl, true);
4516169702Skan
451718334Speter      /* Mark this as a function return value so integrate will delete the
451818334Speter	 assignment and USE below when inlining this function.  */
451918334Speter      REG_FUNCTION_VALUE_P (outgoing) = 1;
452018334Speter
452190091Sobrien      /* The address may be ptr_mode and OUTGOING may be Pmode.  */
4522132732Skan      value_address = convert_memory_address (GET_MODE (outgoing),
4523132732Skan					      value_address);
452490091Sobrien
452518334Speter      emit_move_insn (outgoing, value_address);
452690091Sobrien
452790091Sobrien      /* Show return register used to hold result (in this case the address
452890091Sobrien	 of the result.  */
452990091Sobrien      current_function_return_rtx = outgoing;
453018334Speter    }
453118334Speter
453290091Sobrien  /* Emit the actual code to clobber return register.  */
453390091Sobrien  {
4534169702Skan    rtx seq;
4535117404Skan
453690091Sobrien    start_sequence ();
453790091Sobrien    clobber_return_register ();
4538169702Skan    expand_naked_return ();
4539117404Skan    seq = get_insns ();
454090091Sobrien    end_sequence ();
454118334Speter
4542169702Skan    emit_insn_after (seq, clobber_after);
454390091Sobrien  }
454418334Speter
4545169702Skan  /* Output the label for the naked return from the function.  */
4546169702Skan  emit_label (naked_return_label);
4547132732Skan
4548169702Skan  /* If stack protection is enabled for this function, check the guard.  */
4549169702Skan  if (cfun->stack_protect_guard)
4550169702Skan    stack_protect_epilogue ();
4551169702Skan
4552169702Skan  /* If we had calls to alloca, and this machine needs
4553169702Skan     an accurate stack pointer to exit the function,
4554169702Skan     insert some code to save and restore the stack pointer.  */
4555169702Skan  if (! EXIT_IGNORE_STACK
4556169702Skan      && current_function_calls_alloca)
4557169702Skan    {
4558169702Skan      rtx tem = 0;
4559169702Skan
4560169702Skan      emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
4561169702Skan      emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
4562169702Skan    }
4563169702Skan
456490091Sobrien  /* ??? This should no longer be necessary since stupid is no longer with
456590091Sobrien     us, but there are some parts of the compiler (eg reload_combine, and
456690091Sobrien     sh mach_dep_reorg) that still try and compute their own lifetime info
456790091Sobrien     instead of using the general framework.  */
456890091Sobrien  use_return_register ();
456918334Speter}
457018334Speter
457190091Sobrienrtx
4572132732Skanget_arg_pointer_save_area (struct function *f)
457390091Sobrien{
457490091Sobrien  rtx ret = f->x_arg_pointer_save_area;
457518334Speter
457690091Sobrien  if (! ret)
457790091Sobrien    {
457890091Sobrien      ret = assign_stack_local_1 (Pmode, GET_MODE_SIZE (Pmode), 0, f);
457990091Sobrien      f->x_arg_pointer_save_area = ret;
458090091Sobrien    }
458118334Speter
458290091Sobrien  if (f == cfun && ! f->arg_pointer_save_area_init)
458390091Sobrien    {
458490091Sobrien      rtx seq;
458590091Sobrien
4586117404Skan      /* Save the arg pointer at the beginning of the function.  The
458790091Sobrien	 generated stack slot may not be a valid memory address, so we
458890091Sobrien	 have to check it and fix it if necessary.  */
458990091Sobrien      start_sequence ();
459090091Sobrien      emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx);
4591117404Skan      seq = get_insns ();
459290091Sobrien      end_sequence ();
459390091Sobrien
459490091Sobrien      push_topmost_sequence ();
4595169702Skan      emit_insn_after (seq, entry_of_function ());
459690091Sobrien      pop_topmost_sequence ();
459790091Sobrien    }
459890091Sobrien
459990091Sobrien  return ret;
460090091Sobrien}
460190091Sobrien
4602117404Skan/* Extend a vector that records the INSN_UIDs of INSNS
4603117404Skan   (a list of one or more insns).  */
460490091Sobrien
460590091Sobrienstatic void
4606169702Skanrecord_insns (rtx insns, VEC(int,heap) **vecp)
460718334Speter{
4608117404Skan  rtx tmp;
4609117404Skan
4610169702Skan  for (tmp = insns; tmp != NULL_RTX; tmp = NEXT_INSN (tmp))
4611169702Skan    VEC_safe_push (int, heap, *vecp, INSN_UID (tmp));
461218334Speter}
461318334Speter
4614132732Skan/* Set the locator of the insn chain starting at INSN to LOC.  */
4615132732Skanstatic void
4616132732Skanset_insn_locators (rtx insn, int loc)
4617132732Skan{
4618132732Skan  while (insn != NULL_RTX)
4619132732Skan    {
4620132732Skan      if (INSN_P (insn))
4621132732Skan	INSN_LOCATOR (insn) = loc;
4622132732Skan      insn = NEXT_INSN (insn);
4623132732Skan    }
4624132732Skan}
4625132732Skan
4626117404Skan/* Determine how many INSN_UIDs in VEC are part of INSN.  Because we can
4627117404Skan   be running after reorg, SEQUENCE rtl is possible.  */
462818334Speter
462918334Speterstatic int
4630169702Skancontains (rtx insn, VEC(int,heap) **vec)
463118334Speter{
463290091Sobrien  int i, j;
463318334Speter
4634169702Skan  if (NONJUMP_INSN_P (insn)
463518334Speter      && GET_CODE (PATTERN (insn)) == SEQUENCE)
463618334Speter    {
463718334Speter      int count = 0;
463818334Speter      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
4639169702Skan	for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
4640169702Skan	  if (INSN_UID (XVECEXP (PATTERN (insn), 0, i))
4641169702Skan	      == VEC_index (int, *vec, j))
464218334Speter	    count++;
464318334Speter      return count;
464418334Speter    }
464518334Speter  else
464618334Speter    {
4647169702Skan      for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
4648169702Skan	if (INSN_UID (insn) == VEC_index (int, *vec, j))
464918334Speter	  return 1;
465018334Speter    }
465118334Speter  return 0;
465218334Speter}
465318334Speter
465490091Sobrienint
4655132732Skanprologue_epilogue_contains (rtx insn)
465690091Sobrien{
4657169702Skan  if (contains (insn, &prologue))
465890091Sobrien    return 1;
4659169702Skan  if (contains (insn, &epilogue))
466090091Sobrien    return 1;
466190091Sobrien  return 0;
466290091Sobrien}
466390091Sobrien
466490091Sobrienint
4665132732Skansibcall_epilogue_contains (rtx insn)
466690091Sobrien{
466790091Sobrien  if (sibcall_epilogue)
4668169702Skan    return contains (insn, &sibcall_epilogue);
466990091Sobrien  return 0;
467090091Sobrien}
467190091Sobrien
467290091Sobrien#ifdef HAVE_return
467390091Sobrien/* Insert gen_return at the end of block BB.  This also means updating
467490091Sobrien   block_for_insn appropriately.  */
467590091Sobrien
467690091Sobrienstatic void
4677132732Skanemit_return_into_block (basic_block bb, rtx line_note)
467890091Sobrien{
4679132732Skan  emit_jump_insn_after (gen_return (), BB_END (bb));
468090091Sobrien  if (line_note)
4681132732Skan    emit_note_copy_after (line_note, PREV_INSN (BB_END (bb)));
468290091Sobrien}
468390091Sobrien#endif /* HAVE_return */
468490091Sobrien
468590091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
468690091Sobrien
4687169702Skan/* These functions convert the epilogue into a variant that does not
4688169702Skan   modify the stack pointer.  This is used in cases where a function
4689169702Skan   returns an object whose size is not known until it is computed.
4690169702Skan   The called function leaves the object on the stack, leaves the
4691169702Skan   stack depressed, and returns a pointer to the object.
469290091Sobrien
4693169702Skan   What we need to do is track all modifications and references to the
4694169702Skan   stack pointer, deleting the modifications and changing the
4695169702Skan   references to point to the location the stack pointer would have
4696169702Skan   pointed to had the modifications taken place.
469790091Sobrien
4698169702Skan   These functions need to be portable so we need to make as few
4699169702Skan   assumptions about the epilogue as we can.  However, the epilogue
4700169702Skan   basically contains three things: instructions to reset the stack
4701169702Skan   pointer, instructions to reload registers, possibly including the
4702169702Skan   frame pointer, and an instruction to return to the caller.
470390091Sobrien
4704169702Skan   We must be sure of what a relevant epilogue insn is doing.  We also
4705169702Skan   make no attempt to validate the insns we make since if they are
4706169702Skan   invalid, we probably can't do anything valid.  The intent is that
4707169702Skan   these routines get "smarter" as more and more machines start to use
4708169702Skan   them and they try operating on different epilogues.
470990091Sobrien
4710169702Skan   We use the following structure to track what the part of the
4711169702Skan   epilogue that we've already processed has done.  We keep two copies
4712169702Skan   of the SP equivalence, one for use during the insn we are
4713169702Skan   processing and one for use in the next insn.  The difference is
4714169702Skan   because one part of a PARALLEL may adjust SP and the other may use
4715169702Skan   it.  */
471690091Sobrien
471790091Sobrienstruct epi_info
471890091Sobrien{
471990091Sobrien  rtx sp_equiv_reg;		/* REG that SP is set from, perhaps SP.  */
472090091Sobrien  HOST_WIDE_INT sp_offset;	/* Offset from SP_EQUIV_REG of present SP.  */
472190091Sobrien  rtx new_sp_equiv_reg;		/* REG to be used at end of insn.  */
472290091Sobrien  HOST_WIDE_INT new_sp_offset;	/* Offset to be used at end of insn.  */
472390091Sobrien  rtx equiv_reg_src;		/* If nonzero, the value that SP_EQUIV_REG
472490091Sobrien				   should be set to once we no longer need
472590091Sobrien				   its value.  */
4726132732Skan  rtx const_equiv[FIRST_PSEUDO_REGISTER]; /* Any known constant equivalences
4727132732Skan					     for registers.  */
472890091Sobrien};
472990091Sobrien
4730132732Skanstatic void handle_epilogue_set (rtx, struct epi_info *);
4731132732Skanstatic void update_epilogue_consts (rtx, rtx, void *);
4732132732Skanstatic void emit_equiv_load (struct epi_info *);
473390091Sobrien
4734117404Skan/* Modify INSN, a list of one or more insns that is part of the epilogue, to
4735117404Skan   no modifications to the stack pointer.  Return the new list of insns.  */
473690091Sobrien
473790091Sobrienstatic rtx
4738132732Skankeep_stack_depressed (rtx insns)
473990091Sobrien{
4740117404Skan  int j;
474190091Sobrien  struct epi_info info;
4742117404Skan  rtx insn, next;
474390091Sobrien
4744132732Skan  /* If the epilogue is just a single instruction, it must be OK as is.  */
4745117404Skan  if (NEXT_INSN (insns) == NULL_RTX)
4746117404Skan    return insns;
474790091Sobrien
474890091Sobrien  /* Otherwise, start a sequence, initialize the information we have, and
474990091Sobrien     process all the insns we were given.  */
475090091Sobrien  start_sequence ();
475190091Sobrien
475290091Sobrien  info.sp_equiv_reg = stack_pointer_rtx;
475390091Sobrien  info.sp_offset = 0;
475490091Sobrien  info.equiv_reg_src = 0;
475590091Sobrien
4756132732Skan  for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
4757132732Skan    info.const_equiv[j] = 0;
4758132732Skan
4759117404Skan  insn = insns;
4760117404Skan  next = NULL_RTX;
4761117404Skan  while (insn != NULL_RTX)
476290091Sobrien    {
4763117404Skan      next = NEXT_INSN (insn);
476490091Sobrien
476590091Sobrien      if (!INSN_P (insn))
476690091Sobrien	{
476790091Sobrien	  add_insn (insn);
4768117404Skan	  insn = next;
476990091Sobrien	  continue;
477090091Sobrien	}
477190091Sobrien
477290091Sobrien      /* If this insn references the register that SP is equivalent to and
477390091Sobrien	 we have a pending load to that register, we must force out the load
477490091Sobrien	 first and then indicate we no longer know what SP's equivalent is.  */
477590091Sobrien      if (info.equiv_reg_src != 0
477690091Sobrien	  && reg_referenced_p (info.sp_equiv_reg, PATTERN (insn)))
477790091Sobrien	{
477890091Sobrien	  emit_equiv_load (&info);
477990091Sobrien	  info.sp_equiv_reg = 0;
478090091Sobrien	}
478190091Sobrien
478290091Sobrien      info.new_sp_equiv_reg = info.sp_equiv_reg;
478390091Sobrien      info.new_sp_offset = info.sp_offset;
478490091Sobrien
478590091Sobrien      /* If this is a (RETURN) and the return address is on the stack,
478690091Sobrien	 update the address and change to an indirect jump.  */
478790091Sobrien      if (GET_CODE (PATTERN (insn)) == RETURN
478890091Sobrien	  || (GET_CODE (PATTERN (insn)) == PARALLEL
478990091Sobrien	      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == RETURN))
479090091Sobrien	{
479190091Sobrien	  rtx retaddr = INCOMING_RETURN_ADDR_RTX;
479290091Sobrien	  rtx base = 0;
479390091Sobrien	  HOST_WIDE_INT offset = 0;
479490091Sobrien	  rtx jump_insn, jump_set;
479590091Sobrien
479690091Sobrien	  /* If the return address is in a register, we can emit the insn
479790091Sobrien	     unchanged.  Otherwise, it must be a MEM and we see what the
479890091Sobrien	     base register and offset are.  In any case, we have to emit any
479990091Sobrien	     pending load to the equivalent reg of SP, if any.  */
4800169702Skan	  if (REG_P (retaddr))
480190091Sobrien	    {
480290091Sobrien	      emit_equiv_load (&info);
480390091Sobrien	      add_insn (insn);
4804117404Skan	      insn = next;
480590091Sobrien	      continue;
480690091Sobrien	    }
4807169702Skan	  else
480890091Sobrien	    {
4809169702Skan	      rtx ret_ptr;
4810169702Skan	      gcc_assert (MEM_P (retaddr));
4811169702Skan
4812169702Skan	      ret_ptr = XEXP (retaddr, 0);
4813169702Skan
4814169702Skan	      if (REG_P (ret_ptr))
4815169702Skan		{
4816169702Skan		  base = gen_rtx_REG (Pmode, REGNO (ret_ptr));
4817169702Skan		  offset = 0;
4818169702Skan		}
4819169702Skan	      else
4820169702Skan		{
4821169702Skan		  gcc_assert (GET_CODE (ret_ptr) == PLUS
4822169702Skan			      && REG_P (XEXP (ret_ptr, 0))
4823169702Skan			      && GET_CODE (XEXP (ret_ptr, 1)) == CONST_INT);
4824169702Skan		  base = gen_rtx_REG (Pmode, REGNO (XEXP (ret_ptr, 0)));
4825169702Skan		  offset = INTVAL (XEXP (ret_ptr, 1));
4826169702Skan		}
482790091Sobrien	    }
482890091Sobrien
482990091Sobrien	  /* If the base of the location containing the return pointer
483090091Sobrien	     is SP, we must update it with the replacement address.  Otherwise,
483190091Sobrien	     just build the necessary MEM.  */
483290091Sobrien	  retaddr = plus_constant (base, offset);
483390091Sobrien	  if (base == stack_pointer_rtx)
483490091Sobrien	    retaddr = simplify_replace_rtx (retaddr, stack_pointer_rtx,
483590091Sobrien					    plus_constant (info.sp_equiv_reg,
483690091Sobrien							   info.sp_offset));
483790091Sobrien
483890091Sobrien	  retaddr = gen_rtx_MEM (Pmode, retaddr);
4839169702Skan	  MEM_NOTRAP_P (retaddr) = 1;
484090091Sobrien
484190091Sobrien	  /* If there is a pending load to the equivalent register for SP
484290091Sobrien	     and we reference that register, we must load our address into
484390091Sobrien	     a scratch register and then do that load.  */
484490091Sobrien	  if (info.equiv_reg_src
484590091Sobrien	      && reg_overlap_mentioned_p (info.equiv_reg_src, retaddr))
484690091Sobrien	    {
484790091Sobrien	      unsigned int regno;
484890091Sobrien	      rtx reg;
484990091Sobrien
485090091Sobrien	      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
485190091Sobrien		if (HARD_REGNO_MODE_OK (regno, Pmode)
485290091Sobrien		    && !fixed_regs[regno]
485390091Sobrien		    && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
4854169702Skan		    && !REGNO_REG_SET_P
4855169702Skan		         (EXIT_BLOCK_PTR->il.rtl->global_live_at_start, regno)
485690091Sobrien		    && !refers_to_regno_p (regno,
4857169702Skan					   regno + hard_regno_nregs[regno]
4858169702Skan								   [Pmode],
4859132732Skan					   info.equiv_reg_src, NULL)
4860132732Skan		    && info.const_equiv[regno] == 0)
486190091Sobrien		  break;
486290091Sobrien
4863169702Skan	      gcc_assert (regno < FIRST_PSEUDO_REGISTER);
486490091Sobrien
486590091Sobrien	      reg = gen_rtx_REG (Pmode, regno);
486690091Sobrien	      emit_move_insn (reg, retaddr);
486790091Sobrien	      retaddr = reg;
486890091Sobrien	    }
486990091Sobrien
487090091Sobrien	  emit_equiv_load (&info);
487190091Sobrien	  jump_insn = emit_jump_insn (gen_indirect_jump (retaddr));
487290091Sobrien
487390091Sobrien	  /* Show the SET in the above insn is a RETURN.  */
487490091Sobrien	  jump_set = single_set (jump_insn);
4875169702Skan	  gcc_assert (jump_set);
4876169702Skan	  SET_IS_RETURN_P (jump_set) = 1;
487790091Sobrien	}
487890091Sobrien
487990091Sobrien      /* If SP is not mentioned in the pattern and its equivalent register, if
488090091Sobrien	 any, is not modified, just emit it.  Otherwise, if neither is set,
488190091Sobrien	 replace the reference to SP and emit the insn.  If none of those are
488290091Sobrien	 true, handle each SET individually.  */
488390091Sobrien      else if (!reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))
488490091Sobrien	       && (info.sp_equiv_reg == stack_pointer_rtx
488590091Sobrien		   || !reg_set_p (info.sp_equiv_reg, insn)))
488690091Sobrien	add_insn (insn);
488790091Sobrien      else if (! reg_set_p (stack_pointer_rtx, insn)
488890091Sobrien	       && (info.sp_equiv_reg == stack_pointer_rtx
488990091Sobrien		   || !reg_set_p (info.sp_equiv_reg, insn)))
489090091Sobrien	{
4891169702Skan	  int changed;
489290091Sobrien
4893169702Skan	  changed = validate_replace_rtx (stack_pointer_rtx,
4894169702Skan					  plus_constant (info.sp_equiv_reg,
4895169702Skan							 info.sp_offset),
4896169702Skan					  insn);
4897169702Skan	  gcc_assert (changed);
4898169702Skan
489990091Sobrien	  add_insn (insn);
490090091Sobrien	}
490190091Sobrien      else if (GET_CODE (PATTERN (insn)) == SET)
490290091Sobrien	handle_epilogue_set (PATTERN (insn), &info);
490390091Sobrien      else if (GET_CODE (PATTERN (insn)) == PARALLEL)
490490091Sobrien	{
490590091Sobrien	  for (j = 0; j < XVECLEN (PATTERN (insn), 0); j++)
490690091Sobrien	    if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET)
490790091Sobrien	      handle_epilogue_set (XVECEXP (PATTERN (insn), 0, j), &info);
490890091Sobrien	}
490990091Sobrien      else
491090091Sobrien	add_insn (insn);
491190091Sobrien
491290091Sobrien      info.sp_equiv_reg = info.new_sp_equiv_reg;
491390091Sobrien      info.sp_offset = info.new_sp_offset;
4914117404Skan
4915132732Skan      /* Now update any constants this insn sets.  */
4916132732Skan      note_stores (PATTERN (insn), update_epilogue_consts, &info);
4917117404Skan      insn = next;
491890091Sobrien    }
491990091Sobrien
4920117404Skan  insns = get_insns ();
492190091Sobrien  end_sequence ();
4922117404Skan  return insns;
492390091Sobrien}
492490091Sobrien
492590091Sobrien/* SET is a SET from an insn in the epilogue.  P is a pointer to the epi_info
492690091Sobrien   structure that contains information about what we've seen so far.  We
4927117404Skan   process this SET by either updating that data or by emitting one or
492890091Sobrien   more insns.  */
492990091Sobrien
493090091Sobrienstatic void
4931132732Skanhandle_epilogue_set (rtx set, struct epi_info *p)
493290091Sobrien{
493390091Sobrien  /* First handle the case where we are setting SP.  Record what it is being
4934169702Skan     set from, which we must be able to determine  */
493590091Sobrien  if (reg_set_p (stack_pointer_rtx, set))
493690091Sobrien    {
4937169702Skan      gcc_assert (SET_DEST (set) == stack_pointer_rtx);
493890091Sobrien
4939132732Skan      if (GET_CODE (SET_SRC (set)) == PLUS)
494090091Sobrien	{
494190091Sobrien	  p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
4942132732Skan	  if (GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
4943132732Skan	    p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
4944132732Skan	  else
4945169702Skan	    {
4946169702Skan	      gcc_assert (REG_P (XEXP (SET_SRC (set), 1))
4947169702Skan			  && (REGNO (XEXP (SET_SRC (set), 1))
4948169702Skan			      < FIRST_PSEUDO_REGISTER)
4949169702Skan			  && p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
4950169702Skan	      p->new_sp_offset
4951169702Skan		= INTVAL (p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
4952169702Skan	    }
495390091Sobrien	}
495490091Sobrien      else
495590091Sobrien	p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0;
495690091Sobrien
495790091Sobrien      /* If we are adjusting SP, we adjust from the old data.  */
495890091Sobrien      if (p->new_sp_equiv_reg == stack_pointer_rtx)
495990091Sobrien	{
496090091Sobrien	  p->new_sp_equiv_reg = p->sp_equiv_reg;
496190091Sobrien	  p->new_sp_offset += p->sp_offset;
496290091Sobrien	}
496390091Sobrien
4964169702Skan      gcc_assert (p->new_sp_equiv_reg && REG_P (p->new_sp_equiv_reg));
496590091Sobrien
496690091Sobrien      return;
496790091Sobrien    }
496890091Sobrien
4969169702Skan  /* Next handle the case where we are setting SP's equivalent
4970169702Skan     register.  We must not already have a value to set it to.  We
4971169702Skan     could update, but there seems little point in handling that case.
4972169702Skan     Note that we have to allow for the case where we are setting the
4973169702Skan     register set in the previous part of a PARALLEL inside a single
4974169702Skan     insn.  But use the old offset for any updates within this insn.
4975169702Skan     We must allow for the case where the register is being set in a
4976169702Skan     different (usually wider) mode than Pmode).  */
497790091Sobrien  else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
497890091Sobrien    {
4979169702Skan      gcc_assert (!p->equiv_reg_src
4980169702Skan		  && REG_P (p->new_sp_equiv_reg)
4981169702Skan		  && REG_P (SET_DEST (set))
4982169702Skan		  && (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set)))
4983169702Skan		      <= BITS_PER_WORD)
4984169702Skan		  && REGNO (p->new_sp_equiv_reg) == REGNO (SET_DEST (set)));
4985169702Skan      p->equiv_reg_src
4986169702Skan	= simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
4987169702Skan				plus_constant (p->sp_equiv_reg,
4988169702Skan					       p->sp_offset));
498990091Sobrien    }
499090091Sobrien
499190091Sobrien  /* Otherwise, replace any references to SP in the insn to its new value
499290091Sobrien     and emit the insn.  */
499390091Sobrien  else
499490091Sobrien    {
499590091Sobrien      SET_SRC (set) = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
499690091Sobrien					    plus_constant (p->sp_equiv_reg,
499790091Sobrien							   p->sp_offset));
499890091Sobrien      SET_DEST (set) = simplify_replace_rtx (SET_DEST (set), stack_pointer_rtx,
499990091Sobrien					     plus_constant (p->sp_equiv_reg,
500090091Sobrien							    p->sp_offset));
500190091Sobrien      emit_insn (set);
500290091Sobrien    }
500390091Sobrien}
500490091Sobrien
5005132732Skan/* Update the tracking information for registers set to constants.  */
5006132732Skan
5007132732Skanstatic void
5008132732Skanupdate_epilogue_consts (rtx dest, rtx x, void *data)
5009132732Skan{
5010132732Skan  struct epi_info *p = (struct epi_info *) data;
5011169702Skan  rtx new;
5012132732Skan
5013169702Skan  if (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER)
5014132732Skan    return;
5015169702Skan
5016169702Skan  /* If we are either clobbering a register or doing a partial set,
5017169702Skan     show we don't know the value.  */
5018169702Skan  else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x)))
5019132732Skan    p->const_equiv[REGNO (dest)] = 0;
5020169702Skan
5021169702Skan  /* If we are setting it to a constant, record that constant.  */
5022169702Skan  else if (GET_CODE (SET_SRC (x)) == CONST_INT)
5023169702Skan    p->const_equiv[REGNO (dest)] = SET_SRC (x);
5024169702Skan
5025169702Skan  /* If this is a binary operation between a register we have been tracking
5026169702Skan     and a constant, see if we can compute a new constant value.  */
5027169702Skan  else if (ARITHMETIC_P (SET_SRC (x))
5028169702Skan	   && REG_P (XEXP (SET_SRC (x), 0))
5029169702Skan	   && REGNO (XEXP (SET_SRC (x), 0)) < FIRST_PSEUDO_REGISTER
5030169702Skan	   && p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))] != 0
5031169702Skan	   && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
5032169702Skan	   && 0 != (new = simplify_binary_operation
5033169702Skan		    (GET_CODE (SET_SRC (x)), GET_MODE (dest),
5034169702Skan		     p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))],
5035169702Skan		     XEXP (SET_SRC (x), 1)))
5036169702Skan	   && GET_CODE (new) == CONST_INT)
5037169702Skan    p->const_equiv[REGNO (dest)] = new;
5038169702Skan
5039169702Skan  /* Otherwise, we can't do anything with this value.  */
5040132732Skan  else
5041169702Skan    p->const_equiv[REGNO (dest)] = 0;
5042132732Skan}
5043132732Skan
504490091Sobrien/* Emit an insn to do the load shown in p->equiv_reg_src, if needed.  */
504590091Sobrien
504690091Sobrienstatic void
5047132732Skanemit_equiv_load (struct epi_info *p)
504890091Sobrien{
504990091Sobrien  if (p->equiv_reg_src != 0)
5050132732Skan    {
5051132732Skan      rtx dest = p->sp_equiv_reg;
505290091Sobrien
5053132732Skan      if (GET_MODE (p->equiv_reg_src) != GET_MODE (dest))
5054132732Skan	dest = gen_rtx_REG (GET_MODE (p->equiv_reg_src),
5055132732Skan			    REGNO (p->sp_equiv_reg));
5056132732Skan
5057132732Skan      emit_move_insn (dest, p->equiv_reg_src);
5058132732Skan      p->equiv_reg_src = 0;
5059132732Skan    }
506090091Sobrien}
506190091Sobrien#endif
506290091Sobrien
506318334Speter/* Generate the prologue and epilogue RTL if the machine supports it.  Thread
506418334Speter   this into place with notes indicating where the prologue ends and where
506518334Speter   the epilogue begins.  Update the basic block information when possible.  */
506618334Speter
506718334Spetervoid
5068132732Skanthread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
506918334Speter{
507060970Sobrien  int inserted = 0;
507190091Sobrien  edge e;
507290091Sobrien#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)
507390091Sobrien  rtx seq;
507490091Sobrien#endif
507560970Sobrien#ifdef HAVE_prologue
507660970Sobrien  rtx prologue_end = NULL_RTX;
507760970Sobrien#endif
507890091Sobrien#if defined (HAVE_epilogue) || defined(HAVE_return)
507990091Sobrien  rtx epilogue_end = NULL_RTX;
508090091Sobrien#endif
5081169702Skan  edge_iterator ei;
508252518Sobrien
508318334Speter#ifdef HAVE_prologue
508418334Speter  if (HAVE_prologue)
508518334Speter    {
508652518Sobrien      start_sequence ();
508790091Sobrien      seq = gen_prologue ();
508852518Sobrien      emit_insn (seq);
508918334Speter
509052518Sobrien      /* Retain a map of the prologue insns.  */
509190091Sobrien      record_insns (seq, &prologue);
5092132732Skan      prologue_end = emit_note (NOTE_INSN_PROLOGUE_END);
5093171836Skan
5094171836Skan#ifndef PROFILE_BEFORE_PROLOGUE
5095171836Skan      /* Ensure that instructions are not moved into the prologue when
5096171836Skan	 profiling is on.  The call to the profiling routine can be
5097171836Skan	 emitted within the live range of a call-clobbered register.  */
5098171836Skan      if (current_function_profile)
5099171836Skan	emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
5100171836Skan#endif
510118334Speter
5102117404Skan      seq = get_insns ();
510352518Sobrien      end_sequence ();
5104132732Skan      set_insn_locators (seq, prologue_locator);
510552518Sobrien
510690091Sobrien      /* Can't deal with multiple successors of the entry block
510790091Sobrien         at the moment.  Function should always have at least one
510890091Sobrien         entry point.  */
5109169702Skan      gcc_assert (single_succ_p (ENTRY_BLOCK_PTR));
511052518Sobrien
5111169702Skan      insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
511290091Sobrien      inserted = 1;
511318334Speter    }
511418334Speter#endif
511518334Speter
511690091Sobrien  /* If the exit block has no non-fake predecessors, we don't need
511790091Sobrien     an epilogue.  */
5118169702Skan  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
511990091Sobrien    if ((e->flags & EDGE_FAKE) == 0)
512090091Sobrien      break;
512190091Sobrien  if (e == NULL)
512290091Sobrien    goto epilogue_done;
512390091Sobrien
512490091Sobrien#ifdef HAVE_return
512590091Sobrien  if (optimize && HAVE_return)
512618334Speter    {
512790091Sobrien      /* If we're allowed to generate a simple return instruction,
512890091Sobrien	 then by definition we don't need a full epilogue.  Examine
512990091Sobrien	 the block that falls through to EXIT.   If it does not
513090091Sobrien	 contain any code, examine its predecessors and try to
513190091Sobrien	 emit (conditional) return instructions.  */
513218334Speter
513390091Sobrien      basic_block last;
513490091Sobrien      rtx label;
513552518Sobrien
5136169702Skan      FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
513790091Sobrien	if (e->flags & EDGE_FALLTHRU)
513890091Sobrien	  break;
513990091Sobrien      if (e == NULL)
514090091Sobrien	goto epilogue_done;
514190091Sobrien      last = e->src;
514290091Sobrien
514390091Sobrien      /* Verify that there are no active instructions in the last block.  */
5144132732Skan      label = BB_END (last);
5145169702Skan      while (label && !LABEL_P (label))
514618334Speter	{
514790091Sobrien	  if (active_insn_p (label))
514852518Sobrien	    break;
514990091Sobrien	  label = PREV_INSN (label);
515090091Sobrien	}
515118334Speter
5152169702Skan      if (BB_HEAD (last) == label && LABEL_P (label))
515390091Sobrien	{
5154169702Skan	  edge_iterator ei2;
515590091Sobrien	  rtx epilogue_line_note = NULL_RTX;
515652518Sobrien
515790091Sobrien	  /* Locate the line number associated with the closing brace,
515890091Sobrien	     if we can find one.  */
515990091Sobrien	  for (seq = get_last_insn ();
516090091Sobrien	       seq && ! active_insn_p (seq);
516190091Sobrien	       seq = PREV_INSN (seq))
5162169702Skan	    if (NOTE_P (seq) && NOTE_LINE_NUMBER (seq) > 0)
516390091Sobrien	      {
516490091Sobrien		epilogue_line_note = seq;
516590091Sobrien		break;
516690091Sobrien	      }
516752518Sobrien
5168169702Skan	  for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); )
516990091Sobrien	    {
517090091Sobrien	      basic_block bb = e->src;
517190091Sobrien	      rtx jump;
517252518Sobrien
517390091Sobrien	      if (bb == ENTRY_BLOCK_PTR)
5174169702Skan		{
5175169702Skan		  ei_next (&ei2);
5176169702Skan		  continue;
5177169702Skan		}
517852518Sobrien
5179132732Skan	      jump = BB_END (bb);
5180169702Skan	      if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
5181169702Skan		{
5182169702Skan		  ei_next (&ei2);
5183169702Skan		  continue;
5184169702Skan		}
518552518Sobrien
518690091Sobrien	      /* If we have an unconditional jump, we can replace that
518790091Sobrien		 with a simple return instruction.  */
518890091Sobrien	      if (simplejump_p (jump))
518990091Sobrien		{
519090091Sobrien		  emit_return_into_block (bb, epilogue_line_note);
519190091Sobrien		  delete_insn (jump);
519290091Sobrien		}
519352518Sobrien
519490091Sobrien	      /* If we have a conditional jump, we can try to replace
519590091Sobrien		 that with a conditional return instruction.  */
519690091Sobrien	      else if (condjump_p (jump))
519790091Sobrien		{
5198117404Skan		  if (! redirect_jump (jump, 0, 0))
5199169702Skan		    {
5200169702Skan		      ei_next (&ei2);
5201169702Skan		      continue;
5202169702Skan		    }
520318334Speter
520490091Sobrien		  /* If this block has only one successor, it both jumps
520590091Sobrien		     and falls through to the fallthru block, so we can't
520690091Sobrien		     delete the edge.  */
5207169702Skan		  if (single_succ_p (bb))
5208169702Skan		    {
5209169702Skan		      ei_next (&ei2);
5210169702Skan		      continue;
5211169702Skan		    }
521290091Sobrien		}
521390091Sobrien	      else
5214169702Skan		{
5215169702Skan		  ei_next (&ei2);
5216169702Skan		  continue;
5217169702Skan		}
521818334Speter
521990091Sobrien	      /* Fix up the CFG for the successful change we just made.  */
522090091Sobrien	      redirect_edge_succ (e, EXIT_BLOCK_PTR);
522190091Sobrien	    }
522218334Speter
522390091Sobrien	  /* Emit a return insn for the exit fallthru block.  Whether
522490091Sobrien	     this is still reachable will be determined later.  */
522518334Speter
5226132732Skan	  emit_barrier_after (BB_END (last));
522790091Sobrien	  emit_return_into_block (last, epilogue_line_note);
5228132732Skan	  epilogue_end = BB_END (last);
5229169702Skan	  single_succ_edge (last)->flags &= ~EDGE_FALLTHRU;
523090091Sobrien	  goto epilogue_done;
523190091Sobrien	}
523290091Sobrien    }
523390091Sobrien#endif
5234169702Skan  /* Find the edge that falls through to EXIT.  Other edges may exist
5235169702Skan     due to RETURN instructions, but those don't need epilogues.
5236169702Skan     There really shouldn't be a mixture -- either all should have
5237169702Skan     been converted or none, however...  */
5238169702Skan
5239169702Skan  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
5240169702Skan    if (e->flags & EDGE_FALLTHRU)
5241169702Skan      break;
5242169702Skan  if (e == NULL)
5243169702Skan    goto epilogue_done;
5244169702Skan
524590091Sobrien#ifdef HAVE_epilogue
524690091Sobrien  if (HAVE_epilogue)
524790091Sobrien    {
524890091Sobrien      start_sequence ();
5249132732Skan      epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
525052518Sobrien
525190091Sobrien      seq = gen_epilogue ();
525290091Sobrien
525390091Sobrien#ifdef INCOMING_RETURN_ADDR_RTX
525490091Sobrien      /* If this function returns with the stack depressed and we can support
525590091Sobrien	 it, massage the epilogue to actually do that.  */
525690091Sobrien      if (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
525790091Sobrien	  && TYPE_RETURNS_STACK_DEPRESSED (TREE_TYPE (current_function_decl)))
525890091Sobrien	seq = keep_stack_depressed (seq);
525990091Sobrien#endif
526090091Sobrien
526190091Sobrien      emit_jump_insn (seq);
526290091Sobrien
526390091Sobrien      /* Retain a map of the epilogue insns.  */
526490091Sobrien      record_insns (seq, &epilogue);
5265132732Skan      set_insn_locators (seq, epilogue_locator);
526690091Sobrien
5267117404Skan      seq = get_insns ();
526890091Sobrien      end_sequence ();
526990091Sobrien
527090091Sobrien      insert_insn_on_edge (seq, e);
527190091Sobrien      inserted = 1;
527218334Speter    }
5273169702Skan  else
527418334Speter#endif
5275169702Skan    {
5276169702Skan      basic_block cur_bb;
5277169702Skan
5278169702Skan      if (! next_active_insn (BB_END (e->src)))
5279169702Skan	goto epilogue_done;
5280169702Skan      /* We have a fall-through edge to the exit block, the source is not
5281169702Skan         at the end of the function, and there will be an assembler epilogue
5282169702Skan         at the end of the function.
5283169702Skan         We can't use force_nonfallthru here, because that would try to
5284169702Skan         use return.  Inserting a jump 'by hand' is extremely messy, so
5285169702Skan	 we take advantage of cfg_layout_finalize using
5286169702Skan	fixup_fallthru_exit_predecessor.  */
5287169702Skan      cfg_layout_initialize (0);
5288169702Skan      FOR_EACH_BB (cur_bb)
5289169702Skan	if (cur_bb->index >= NUM_FIXED_BLOCKS
5290169702Skan	    && cur_bb->next_bb->index >= NUM_FIXED_BLOCKS)
5291169702Skan	  cur_bb->aux = cur_bb->next_bb;
5292169702Skan      cfg_layout_finalize ();
5293169702Skan    }
529490091Sobrienepilogue_done:
529552518Sobrien
529660970Sobrien  if (inserted)
529752518Sobrien    commit_edge_insertions ();
529860970Sobrien
529990091Sobrien#ifdef HAVE_sibcall_epilogue
530090091Sobrien  /* Emit sibling epilogues before any sibling call sites.  */
5301169702Skan  for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); )
530290091Sobrien    {
530390091Sobrien      basic_block bb = e->src;
5304132732Skan      rtx insn = BB_END (bb);
530590091Sobrien
5306169702Skan      if (!CALL_P (insn)
530790091Sobrien	  || ! SIBLING_CALL_P (insn))
5308169702Skan	{
5309169702Skan	  ei_next (&ei);
5310169702Skan	  continue;
5311169702Skan	}
531290091Sobrien
531390091Sobrien      start_sequence ();
5314117404Skan      emit_insn (gen_sibcall_epilogue ());
5315117404Skan      seq = get_insns ();
531690091Sobrien      end_sequence ();
531790091Sobrien
5318117404Skan      /* Retain a map of the epilogue insns.  Used in life analysis to
5319117404Skan	 avoid getting rid of sibcall epilogue insns.  Do this before we
5320117404Skan	 actually emit the sequence.  */
5321117404Skan      record_insns (seq, &sibcall_epilogue);
5322132732Skan      set_insn_locators (seq, epilogue_locator);
5323117404Skan
5324169702Skan      emit_insn_before (seq, insn);
5325169702Skan      ei_next (&ei);
532690091Sobrien    }
532790091Sobrien#endif
532890091Sobrien
532960970Sobrien#ifdef HAVE_prologue
5330132732Skan  /* This is probably all useless now that we use locators.  */
533160970Sobrien  if (prologue_end)
533260970Sobrien    {
533360970Sobrien      rtx insn, prev;
533460970Sobrien
533560970Sobrien      /* GDB handles `break f' by setting a breakpoint on the first
533690091Sobrien	 line note after the prologue.  Which means (1) that if
533760970Sobrien	 there are line number notes before where we inserted the
533890091Sobrien	 prologue we should move them, and (2) we should generate a
533990091Sobrien	 note before the end of the first basic block, if there isn't
534090091Sobrien	 one already there.
534160970Sobrien
5342117404Skan	 ??? This behavior is completely broken when dealing with
534390091Sobrien	 multiple entry functions.  We simply place the note always
534490091Sobrien	 into first basic block and let alternate entry points
534590091Sobrien	 to be missed.
534690091Sobrien       */
534790091Sobrien
534890091Sobrien      for (insn = prologue_end; insn; insn = prev)
534960970Sobrien	{
535060970Sobrien	  prev = PREV_INSN (insn);
5351169702Skan	  if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
535260970Sobrien	    {
535360970Sobrien	      /* Note that we cannot reorder the first insn in the
535460970Sobrien		 chain, since rest_of_compilation relies on that
535590091Sobrien		 remaining constant.  */
535660970Sobrien	      if (prev == NULL)
535790091Sobrien		break;
535890091Sobrien	      reorder_insns (insn, insn, prologue_end);
535960970Sobrien	    }
536060970Sobrien	}
536160970Sobrien
536290091Sobrien      /* Find the last line number note in the first block.  */
5363132732Skan      for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb);
536490091Sobrien	   insn != prologue_end && insn;
536590091Sobrien	   insn = PREV_INSN (insn))
5366169702Skan	if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
536790091Sobrien	  break;
536890091Sobrien
536990091Sobrien      /* If we didn't find one, make a copy of the first line number
537090091Sobrien	 we run across.  */
537190091Sobrien      if (! insn)
537260970Sobrien	{
537390091Sobrien	  for (insn = next_active_insn (prologue_end);
537490091Sobrien	       insn;
537590091Sobrien	       insn = PREV_INSN (insn))
5376169702Skan	    if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
537790091Sobrien	      {
5378132732Skan		emit_note_copy_after (insn, prologue_end);
537990091Sobrien		break;
538090091Sobrien	      }
538160970Sobrien	}
538290091Sobrien    }
538390091Sobrien#endif
538490091Sobrien#ifdef HAVE_epilogue
538590091Sobrien  if (epilogue_end)
538690091Sobrien    {
538790091Sobrien      rtx insn, next;
538890091Sobrien
538990091Sobrien      /* Similarly, move any line notes that appear after the epilogue.
539090091Sobrien         There is no need, however, to be quite so anal about the existence
5391132732Skan	 of such a note.  Also move the NOTE_INSN_FUNCTION_END and (possibly)
5392132732Skan	 NOTE_INSN_FUNCTION_BEG notes, as those can be relevant for debug
5393132732Skan	 info generation.  */
539490091Sobrien      for (insn = epilogue_end; insn; insn = next)
539590091Sobrien	{
539690091Sobrien	  next = NEXT_INSN (insn);
5397169702Skan	  if (NOTE_P (insn)
5398132732Skan	      && (NOTE_LINE_NUMBER (insn) > 0
5399132732Skan		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
5400132732Skan		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END))
540190091Sobrien	    reorder_insns (insn, insn, PREV_INSN (epilogue_end));
540290091Sobrien	}
540390091Sobrien    }
540490091Sobrien#endif
540518334Speter}
540618334Speter
540718334Speter/* Reposition the prologue-end and epilogue-begin notes after instruction
540818334Speter   scheduling and delayed branch scheduling.  */
540918334Speter
541018334Spetervoid
5411132732Skanreposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED)
541218334Speter{
541318334Speter#if defined (HAVE_prologue) || defined (HAVE_epilogue)
541496283Sobrien  rtx insn, last, note;
541590091Sobrien  int len;
541690091Sobrien
5417169702Skan  if ((len = VEC_length (int, prologue)) > 0)
541818334Speter    {
541996283Sobrien      last = 0, note = 0;
542018334Speter
542190091Sobrien      /* Scan from the beginning until we reach the last prologue insn.
542290091Sobrien	 We apparently can't depend on basic_block_{head,end} after
542390091Sobrien	 reorg has run.  */
542496283Sobrien      for (insn = f; insn; insn = NEXT_INSN (insn))
542518334Speter	{
5426169702Skan	  if (NOTE_P (insn))
542718334Speter	    {
542890091Sobrien	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
542990091Sobrien		note = insn;
543090091Sobrien	    }
5431169702Skan	  else if (contains (insn, &prologue))
543290091Sobrien	    {
543396283Sobrien	      last = insn;
543496283Sobrien	      if (--len == 0)
543596283Sobrien		break;
543696283Sobrien	    }
543796283Sobrien	}
5438117404Skan
543996283Sobrien      if (last)
544096283Sobrien	{
544196283Sobrien	  /* Find the prologue-end note if we haven't already, and
544296283Sobrien	     move it to just after the last prologue insn.  */
544396283Sobrien	  if (note == 0)
544496283Sobrien	    {
544596283Sobrien	      for (note = last; (note = NEXT_INSN (note));)
5446169702Skan		if (NOTE_P (note)
544796283Sobrien		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END)
544896283Sobrien		  break;
544996283Sobrien	    }
545052518Sobrien
545196283Sobrien	  /* Avoid placing note between CODE_LABEL and BASIC_BLOCK note.  */
5452169702Skan	  if (LABEL_P (last))
545396283Sobrien	    last = NEXT_INSN (last);
545496283Sobrien	  reorder_insns (note, note, last);
545518334Speter	}
545690091Sobrien    }
545718334Speter
5458169702Skan  if ((len = VEC_length (int, epilogue)) > 0)
545990091Sobrien    {
546096283Sobrien      last = 0, note = 0;
546190091Sobrien
546290091Sobrien      /* Scan from the end until we reach the first epilogue insn.
546390091Sobrien	 We apparently can't depend on basic_block_{head,end} after
546490091Sobrien	 reorg has run.  */
546596283Sobrien      for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
546618334Speter	{
5467169702Skan	  if (NOTE_P (insn))
546818334Speter	    {
546990091Sobrien	      if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
547090091Sobrien		note = insn;
547190091Sobrien	    }
5472169702Skan	  else if (contains (insn, &epilogue))
547390091Sobrien	    {
547496283Sobrien	      last = insn;
547596283Sobrien	      if (--len == 0)
547696283Sobrien		break;
547796283Sobrien	    }
547896283Sobrien	}
547952518Sobrien
548096283Sobrien      if (last)
548196283Sobrien	{
548296283Sobrien	  /* Find the epilogue-begin note if we haven't already, and
548396283Sobrien	     move it to just before the first epilogue insn.  */
548496283Sobrien	  if (note == 0)
548596283Sobrien	    {
548696283Sobrien	      for (note = insn; (note = PREV_INSN (note));)
5487169702Skan		if (NOTE_P (note)
548896283Sobrien		    && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
548996283Sobrien		  break;
549096283Sobrien	    }
549152518Sobrien
549296283Sobrien	  if (PREV_INSN (last) != note)
549396283Sobrien	    reorder_insns (note, note, PREV_INSN (last));
549418334Speter	}
549518334Speter    }
549618334Speter#endif /* HAVE_prologue or HAVE_epilogue */
549718334Speter}
549890091Sobrien
5499169702Skan/* Resets insn_block_boundaries array.  */
550090091Sobrien
550190091Sobrienvoid
5502169702Skanreset_block_changes (void)
550390091Sobrien{
5504169702Skan  cfun->ib_boundaries_block = VEC_alloc (tree, gc, 100);
5505169702Skan  VEC_quick_push (tree, cfun->ib_boundaries_block, NULL_TREE);
550690091Sobrien}
5507117404Skan
5508169702Skan/* Record the boundary for BLOCK.  */
5509169702Skanvoid
5510169702Skanrecord_block_change (tree block)
5511169702Skan{
5512169702Skan  int i, n;
5513169702Skan  tree last_block;
5514169702Skan
5515169702Skan  if (!block)
5516169702Skan    return;
5517169702Skan
5518169702Skan  if(!cfun->ib_boundaries_block)
5519169702Skan    return;
5520169702Skan
5521169702Skan  last_block = VEC_pop (tree, cfun->ib_boundaries_block);
5522169702Skan  n = get_max_uid ();
5523169702Skan  for (i = VEC_length (tree, cfun->ib_boundaries_block); i < n; i++)
5524169702Skan    VEC_safe_push (tree, gc, cfun->ib_boundaries_block, last_block);
5525169702Skan
5526169702Skan  VEC_safe_push (tree, gc, cfun->ib_boundaries_block, block);
5527169702Skan}
5528169702Skan
5529169702Skan/* Finishes record of boundaries.  */
5530169702Skanvoid
5531169702Skanfinalize_block_changes (void)
5532169702Skan{
5533169702Skan  record_block_change (DECL_INITIAL (current_function_decl));
5534169702Skan}
5535169702Skan
5536169702Skan/* For INSN return the BLOCK it belongs to.  */
5537169702Skanvoid
5538169702Skancheck_block_change (rtx insn, tree *block)
5539169702Skan{
5540169702Skan  unsigned uid = INSN_UID (insn);
5541169702Skan
5542169702Skan  if (uid >= VEC_length (tree, cfun->ib_boundaries_block))
5543169702Skan    return;
5544169702Skan
5545169702Skan  *block = VEC_index (tree, cfun->ib_boundaries_block, uid);
5546169702Skan}
5547169702Skan
5548169702Skan/* Releases the ib_boundaries_block records.  */
5549169702Skanvoid
5550169702Skanfree_block_changes (void)
5551169702Skan{
5552169702Skan  VEC_free (tree, gc, cfun->ib_boundaries_block);
5553169702Skan}
5554169702Skan
5555132732Skan/* Returns the name of the current function.  */
5556132732Skanconst char *
5557132732Skancurrent_function_name (void)
5558132732Skan{
5559169702Skan  return lang_hooks.decl_printable_name (cfun->decl, 2);
5560132732Skan}
5561169702Skan
5562132732Skan
5563169702Skanstatic unsigned int
5564169702Skanrest_of_handle_check_leaf_regs (void)
5565169702Skan{
5566169702Skan#ifdef LEAF_REGISTERS
5567169702Skan  current_function_uses_only_leaf_regs
5568169702Skan    = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
5569169702Skan#endif
5570169702Skan  return 0;
5571169702Skan}
5572169702Skan
5573169702Skan/* Insert a TYPE into the used types hash table of CFUN.  */
5574169702Skanstatic void
5575169702Skanused_types_insert_helper (tree type, struct function *func)
5576169702Skan{
5577169702Skan  if (type != NULL && func != NULL)
5578169702Skan    {
5579169702Skan      void **slot;
5580169702Skan
5581169702Skan      if (func->used_types_hash == NULL)
5582169702Skan	func->used_types_hash = htab_create_ggc (37, htab_hash_pointer,
5583169702Skan						 htab_eq_pointer, NULL);
5584169702Skan      slot = htab_find_slot (func->used_types_hash, type, INSERT);
5585169702Skan      if (*slot == NULL)
5586169702Skan	*slot = type;
5587169702Skan    }
5588169702Skan}
5589169702Skan
5590169702Skan/* Given a type, insert it into the used hash table in cfun.  */
5591169702Skanvoid
5592169702Skanused_types_insert (tree t)
5593169702Skan{
5594169702Skan  while (POINTER_TYPE_P (t) || TREE_CODE (t) == ARRAY_TYPE)
5595169702Skan    t = TREE_TYPE (t);
5596169702Skan  t = TYPE_MAIN_VARIANT (t);
5597169702Skan  if (debug_info_level > DINFO_LEVEL_NONE)
5598169702Skan    used_types_insert_helper (t, cfun);
5599169702Skan}
5600169702Skan
5601169702Skanstruct tree_opt_pass pass_leaf_regs =
5602169702Skan{
5603169702Skan  NULL,                                 /* name */
5604169702Skan  NULL,                                 /* gate */
5605169702Skan  rest_of_handle_check_leaf_regs,       /* execute */
5606169702Skan  NULL,                                 /* sub */
5607169702Skan  NULL,                                 /* next */
5608169702Skan  0,                                    /* static_pass_number */
5609169702Skan  0,                                    /* tv_id */
5610169702Skan  0,                                    /* properties_required */
5611169702Skan  0,                                    /* properties_provided */
5612169702Skan  0,                                    /* properties_destroyed */
5613169702Skan  0,                                    /* todo_flags_start */
5614169702Skan  0,                                    /* todo_flags_finish */
5615169702Skan  0                                     /* letter */
5616169702Skan};
5617169702Skan
5618169702Skan
5619117404Skan#include "gt-function.h"
5620