• Main Page
  • Modules
  • Data Types
  • Files

osprey/kg++fe/gnu/function.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2003, 2004, 2005, 2006 PathScale, Inc.  All Rights Reserved.
00003  */
00004 
00005 /* Expands front end tree to back end RTL for GNU C-Compiler
00006    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
00007    1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
00008 
00009 This file is part of GCC.
00010 
00011 GCC is free software; you can redistribute it and/or modify it under
00012 the terms of the GNU General Public License as published by the Free
00013 Software Foundation; either version 2, or (at your option) any later
00014 version.
00015 
00016 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00017 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019 for more details.
00020 
00021 You should have received a copy of the GNU General Public License
00022 along with GCC; see the file COPYING.  If not, write to the Free
00023 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
00024 02111-1307, USA.  */
00025 
00026 /* This file handles the generation of rtl code from tree structure
00027    at the level of the function as a whole.
00028    It creates the rtl expressions for parameters and auto variables
00029    and has full responsibility for allocating stack slots.
00030 
00031    `expand_function_start' is called at the beginning of a function,
00032    before the function body is parsed, and `expand_function_end' is
00033    called after parsing the body.
00034 
00035    Call `assign_stack_local' to allocate a stack slot for a local variable.
00036    This is usually done during the RTL generation for the function body,
00037    but it can also be done in the reload pass when a pseudo-register does
00038    not get a hard register.
00039 
00040    Call `put_var_into_stack' when you learn, belatedly, that a variable
00041    previously given a pseudo-register must in fact go in the stack.
00042    This function changes the DECL_RTL to be a stack slot instead of a reg
00043    then scans all the RTL instructions so far generated to correct them.  */
00044 
00045 #include "config.h"
00046 #include "system.h"
00047 #include "rtl.h"
00048 #include "tree.h"
00049 #include "flags.h"
00050 #include "except.h"
00051 #include "function.h"
00052 #include "expr.h"
00053 #include "libfuncs.h"
00054 #include "regs.h"
00055 #include "hard-reg-set.h"
00056 #include "insn-config.h"
00057 #include "recog.h"
00058 #include "output.h"
00059 #include "basic-block.h"
00060 #include "toplev.h"
00061 #include "hashtab.h"
00062 #include "ggc.h"
00063 #include "tm_p.h"
00064 #include "integrate.h"
00065 #include "langhooks.h"
00066 #ifdef SGI_MONGOOSE
00067 #ifndef KEY // We should not use this file any more
00068 #include "MIPS/elf.h"
00069 #endif // !KEY
00070 // To get PREFERRED_STACK_BOUNDARY
00071 #include "defaults.h"
00072 #endif /* SGI_MONGOOSE */
00073 
00074 #ifndef TRAMPOLINE_ALIGNMENT
00075 #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
00076 #endif
00077 
00078 #ifndef LOCAL_ALIGNMENT
00079 #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
00080 #endif
00081 
00082 /* Some systems use __main in a way incompatible with its use in gcc, in these
00083    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
00084    give the same symbol without quotes for an alternative entry point.  You
00085    must define both, or neither.  */
00086 #ifndef NAME__MAIN
00087 #define NAME__MAIN "__main"
00088 #endif
00089 
00090 /* Round a value to the lowest integer less than it that is a multiple of
00091    the required alignment.  Avoid using division in case the value is
00092    negative.  Assume the alignment is a power of two.  */
00093 #define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))
00094 
00095 /* Similar, but round to the next highest integer that meets the
00096    alignment.  */
00097 #define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
00098 
00099 /* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp
00100    during rtl generation.  If they are different register numbers, this is
00101    always true.  It may also be true if
00102    FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl
00103    generation.  See fix_lexical_addr for details.  */
00104 
00105 #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
00106 #define NEED_SEPARATE_AP
00107 #endif
00108 
00109 /* Nonzero if function being compiled doesn't contain any calls
00110    (ignoring the prologue and epilogue).  This is set prior to
00111    local register allocation and is valid for the remaining
00112    compiler passes.  */
00113 int current_function_is_leaf;
00114 
00115 /* Nonzero if function being compiled doesn't contain any instructions
00116    that can throw an exception.  This is set prior to final.  */
00117 
00118 int current_function_nothrow;
00119 
00120 /* Nonzero if function being compiled doesn't modify the stack pointer
00121    (ignoring the prologue and epilogue).  This is only valid after
00122    life_analysis has run.  */
00123 int current_function_sp_is_unchanging;
00124 
00125 /* Nonzero if the function being compiled is a leaf function which only
00126    uses leaf registers.  This is valid after reload (specifically after
00127    sched2) and is useful only if the port defines LEAF_REGISTERS.  */
00128 int current_function_uses_only_leaf_regs;
00129 
00130 /* Nonzero once virtual register instantiation has been done.
00131    assign_stack_local uses frame_pointer_rtx when this is nonzero.
00132    calls.c:emit_library_call_value_1 uses it to set up
00133    post-instantiation libcalls.  */
00134 int virtuals_instantiated;
00135 
00136 /* Nonzero if at least one trampoline has been created.  */
00137 int trampolines_created;
00138 
00139 /* Assign unique numbers to labels generated for profiling, debugging, etc.  */
00140 static int funcdef_no;
00141 
00142 /* These variables hold pointers to functions to create and destroy
00143    target specific, per-function data structures.  */
00144 struct machine_function * (*init_machine_status) PARAMS ((void));
00145 
00146 /* The FUNCTION_DECL for an inline function currently being expanded.  */
00147 tree inline_function_decl;
00148 
00149 /* The currently compiled function.  */
00150 struct function *cfun = 0;
00151 
00152 /* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
00153 static GTY(()) varray_type prologue;
00154 static GTY(()) varray_type epilogue;
00155 
00156 /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
00157    in this function.  */
00158 static GTY(()) varray_type sibcall_epilogue;
00159 
00160 /* In order to evaluate some expressions, such as function calls returning
00161    structures in memory, we need to temporarily allocate stack locations.
00162    We record each allocated temporary in the following structure.
00163 
00164    Associated with each temporary slot is a nesting level.  When we pop up
00165    one level, all temporaries associated with the previous level are freed.
00166    Normally, all temporaries are freed after the execution of the statement
00167    in which they were created.  However, if we are inside a ({...}) grouping,
00168    the result may be in a temporary and hence must be preserved.  If the
00169    result could be in a temporary, we preserve it if we can determine which
00170    one it is in.  If we cannot determine which temporary may contain the
00171    result, all temporaries are preserved.  A temporary is preserved by
00172    pretending it was allocated at the previous nesting level.
00173 
00174    Automatic variables are also assigned temporary slots, at the nesting
00175    level where they are defined.  They are marked a "kept" so that
00176    free_temp_slots will not free them.  */
00177 
00178 struct temp_slot GTY(())
00179 {
00180   /* Points to next temporary slot.  */
00181   struct temp_slot *next;
00182   /* The rtx to used to reference the slot.  */
00183   rtx slot;
00184   /* The rtx used to represent the address if not the address of the
00185      slot above.  May be an EXPR_LIST if multiple addresses exist.  */
00186   rtx address;
00187   /* The alignment (in bits) of the slot.  */
00188   unsigned int align;
00189   /* The size, in units, of the slot.  */
00190   HOST_WIDE_INT size;
00191   /* The type of the object in the slot, or zero if it doesn't correspond
00192      to a type.  We use this to determine whether a slot can be reused.
00193      It can be reused if objects of the type of the new slot will always
00194      conflict with objects of the type of the old slot.  */
00195   tree type;
00196   /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
00197   tree rtl_expr;
00198   /* Nonzero if this temporary is currently in use.  */
00199   char in_use;
00200   /* Nonzero if this temporary has its address taken.  */
00201   char addr_taken;
00202   /* Nesting level at which this slot is being used.  */
00203   int level;
00204   /* Nonzero if this should survive a call to free_temp_slots.  */
00205   int keep;
00206   /* The offset of the slot from the frame_pointer, including extra space
00207      for alignment.  This info is for combine_temp_slots.  */
00208   HOST_WIDE_INT base_offset;
00209   /* The size of the slot, including extra space for alignment.  This
00210      info is for combine_temp_slots.  */
00211   HOST_WIDE_INT full_size;
00212 };
00213 
00214 /* This structure is used to record MEMs or pseudos used to replace VAR, any
00215    SUBREGs of VAR, and any MEMs containing VAR as an address.  We need to
00216    maintain this list in case two operands of an insn were required to match;
00217    in that case we must ensure we use the same replacement.  */
00218 
00219 struct fixup_replacement GTY(())
00220 {
00221   rtx old;
00222   rtx new;
00223   struct fixup_replacement *next;
00224 };
00225 
00226 struct insns_for_mem_entry
00227 {
00228   /* A MEM.  */
00229   rtx key;
00230   /* These are the INSNs which reference the MEM.  */
00231   rtx insns;
00232 };
00233 
00234 /* Forward declarations.  */
00235 
00236 static rtx assign_stack_local_1 PARAMS ((enum machine_mode, HOST_WIDE_INT,
00237            int, struct function *));
00238 static struct temp_slot *find_temp_slot_from_address  PARAMS ((rtx));
00239 static void put_reg_into_stack  PARAMS ((struct function *, rtx, tree,
00240            enum machine_mode, enum machine_mode,
00241            int, unsigned int, int,
00242            htab_t));
00243 static void schedule_fixup_var_refs PARAMS ((struct function *, rtx, tree,
00244                enum machine_mode,
00245                htab_t));
00246 static void fixup_var_refs  PARAMS ((rtx, enum machine_mode, int, rtx,
00247            htab_t));
00248 static struct fixup_replacement
00249   *find_fixup_replacement PARAMS ((struct fixup_replacement **, rtx));
00250 static void fixup_var_refs_insns PARAMS ((rtx, rtx, enum machine_mode,
00251             int, int, rtx));
00252 static void fixup_var_refs_insns_with_hash
00253         PARAMS ((htab_t, rtx,
00254            enum machine_mode, int, rtx));
00255 static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
00256            int, int, rtx));
00257 static void fixup_var_refs_1  PARAMS ((rtx, enum machine_mode, rtx *, rtx,
00258            struct fixup_replacement **, rtx));
00259 static rtx fixup_memory_subreg  PARAMS ((rtx, rtx, enum machine_mode, int));
00260 static rtx walk_fixup_memory_subreg  PARAMS ((rtx, rtx, enum machine_mode,
00261                 int));
00262 static rtx fixup_stack_1  PARAMS ((rtx, rtx));
00263 static void optimize_bit_field  PARAMS ((rtx, rtx, rtx *));
00264 static void instantiate_decls PARAMS ((tree, int));
00265 static void instantiate_decls_1 PARAMS ((tree, int));
00266 static void instantiate_decl  PARAMS ((rtx, HOST_WIDE_INT, int));
00267 static rtx instantiate_new_reg  PARAMS ((rtx, HOST_WIDE_INT *));
00268 static int instantiate_virtual_regs_1 PARAMS ((rtx *, rtx, int));
00269 static void delete_handlers PARAMS ((void));
00270 static void pad_to_arg_alignment PARAMS ((struct args_size *, int,
00271             struct args_size *));
00272 static void pad_below   PARAMS ((struct args_size *, enum machine_mode,
00273            tree));
00274 static rtx round_trampoline_addr PARAMS ((rtx));
00275 static rtx adjust_trampoline_addr PARAMS ((rtx));
00276 static tree *identify_blocks_1  PARAMS ((rtx, tree *, tree *, tree *));
00277 static void reorder_blocks_0  PARAMS ((tree));
00278 static void reorder_blocks_1  PARAMS ((rtx, tree, varray_type *));
00279 static void reorder_fix_fragments PARAMS ((tree));
00280 static tree blocks_nreverse PARAMS ((tree));
00281 static int all_blocks   PARAMS ((tree, tree *));
00282 static tree *get_block_vector   PARAMS ((tree, int *));
00283 extern tree debug_find_var_in_block_tree PARAMS ((tree, tree));
00284 /* We always define `record_insns' even if its not used so that we
00285    can always export `prologue_epilogue_contains'.  */
00286 static void record_insns  PARAMS ((rtx, varray_type *)) ATTRIBUTE_UNUSED;
00287 static int contains   PARAMS ((rtx, varray_type));
00288 #ifdef HAVE_return
00289 static void emit_return_into_block PARAMS ((basic_block, rtx));
00290 #endif
00291 static void put_addressof_into_stack PARAMS ((rtx, htab_t));
00292 static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int,
00293             htab_t));
00294 static void purge_single_hard_subreg_set PARAMS ((rtx));
00295 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
00296 static rtx keep_stack_depressed PARAMS ((rtx));
00297 #endif
00298 static int is_addressof   PARAMS ((rtx *, void *));
00299 static hashval_t insns_for_mem_hash PARAMS ((const void *));
00300 static int insns_for_mem_comp PARAMS ((const void *, const void *));
00301 static int insns_for_mem_walk   PARAMS ((rtx *, void *));
00302 static void compute_insns_for_mem PARAMS ((rtx, rtx, htab_t));
00303 static void prepare_function_start PARAMS ((void));
00304 static void do_clobber_return_reg PARAMS ((rtx, void *));
00305 static void do_use_return_reg PARAMS ((rtx, void *));
00306 static void instantiate_virtual_regs_lossage PARAMS ((rtx));
00307 
00308 /* Pointer to chain of `struct function' for containing functions.  */
00309 static GTY(()) struct function *outer_function_chain;
00310 
00311 /* Given a function decl for a containing function,
00312    return the `struct function' for it.  */
00313 
00314 struct function *
00315 find_function_data (decl)
00316      tree decl;
00317 {
00318   struct function *p;
00319 
00320   for (p = outer_function_chain; p; p = p->outer)
00321     if (p->decl == decl)
00322       return p;
00323 
00324   abort ();
00325 }
00326 
00327 /* Save the current context for compilation of a nested function.
00328    This is called from language-specific code.  The caller should use
00329    the enter_nested langhook to save any language-specific state,
00330    since this function knows only about language-independent
00331    variables.  */
00332 
00333 void
00334 push_function_context_to (context)
00335      tree context;
00336 {
00337   struct function *p;
00338 
00339   if (context)
00340     {
00341       if (context == current_function_decl)
00342   cfun->contains_functions = 1;
00343       else
00344   {
00345     struct function *containing = find_function_data (context);
00346     containing->contains_functions = 1;
00347   }
00348     }
00349 
00350   if (cfun == 0)
00351     init_dummy_function_start ();
00352   p = cfun;
00353 
00354   p->outer = outer_function_chain;
00355   outer_function_chain = p;
00356   p->fixup_var_refs_queue = 0;
00357 
00358   (*lang_hooks.function.enter_nested) (p);
00359 
00360   cfun = 0;
00361 }
00362 
00363 void
00364 push_function_context ()
00365 {
00366   push_function_context_to (current_function_decl);
00367 }
00368 
00369 /* Restore the last saved context, at the end of a nested function.
00370    This function is called from language-specific code.  */
00371 
00372 void
00373 pop_function_context_from (context)
00374      tree context ATTRIBUTE_UNUSED;
00375 {
00376   struct function *p = outer_function_chain;
00377   struct var_refs_queue *queue;
00378 
00379   cfun = p;
00380   outer_function_chain = p->outer;
00381 
00382   current_function_decl = p->decl;
00383   reg_renumber = 0;
00384 
00385   restore_emit_status (p);
00386 
00387   (*lang_hooks.function.leave_nested) (p);
00388 
00389   /* Finish doing put_var_into_stack for any of our variables which became
00390      addressable during the nested function.  If only one entry has to be
00391      fixed up, just do that one.  Otherwise, first make a list of MEMs that
00392      are not to be unshared.  */
00393   if (p->fixup_var_refs_queue == 0)
00394     ;
00395   else if (p->fixup_var_refs_queue->next == 0)
00396     fixup_var_refs (p->fixup_var_refs_queue->modified,
00397         p->fixup_var_refs_queue->promoted_mode,
00398         p->fixup_var_refs_queue->unsignedp,
00399         p->fixup_var_refs_queue->modified, 0);
00400   else
00401     {
00402       rtx list = 0;
00403 
00404       for (queue = p->fixup_var_refs_queue; queue; queue = queue->next)
00405   list = gen_rtx_EXPR_LIST (VOIDmode, queue->modified, list);
00406 
00407       for (queue = p->fixup_var_refs_queue; queue; queue = queue->next)
00408   fixup_var_refs (queue->modified, queue->promoted_mode,
00409       queue->unsignedp, list, 0);
00410 
00411     }
00412 
00413   p->fixup_var_refs_queue = 0;
00414 
00415   /* Reset variables that have known state during rtx generation.  */
00416   rtx_equal_function_value_matters = 1;
00417   virtuals_instantiated = 0;
00418   generating_concat_p = 1;
00419 }
00420 
00421 void
00422 pop_function_context ()
00423 {
00424   pop_function_context_from (current_function_decl);
00425 }
00426 
00427 /* Clear out all parts of the state in F that can safely be discarded
00428    after the function has been parsed, but not compiled, to let
00429    garbage collection reclaim the memory.  */
00430 
00431 void
00432 free_after_parsing (f)
00433      struct function *f;
00434 {
00435   /* f->expr->forced_labels is used by code generation.  */
00436   /* f->emit->regno_reg_rtx is used by code generation.  */
00437   /* f->varasm is used by code generation.  */
00438   /* f->eh->eh_return_stub_label is used by code generation.  */
00439 
00440   (*lang_hooks.function.final) (f);
00441   f->stmt = NULL;
00442 }
00443 
00444 /* Clear out all parts of the state in F that can safely be discarded
00445    after the function has been compiled, to let garbage collection
00446    reclaim the memory.  */
00447 
00448 void
00449 free_after_compilation (f)
00450      struct function *f;
00451 {
00452   f->eh = NULL;
00453   f->expr = NULL;
00454   f->emit = NULL;
00455   f->varasm = NULL;
00456   f->machine = NULL;
00457 
00458   f->x_temp_slots = NULL;
00459   f->arg_offset_rtx = NULL;
00460   f->return_rtx = NULL;
00461   f->internal_arg_pointer = NULL;
00462   f->x_nonlocal_labels = NULL;
00463   f->x_nonlocal_goto_handler_slots = NULL;
00464   f->x_nonlocal_goto_handler_labels = NULL;
00465   f->x_nonlocal_goto_stack_level = NULL;
00466   f->x_cleanup_label = NULL;
00467   f->x_return_label = NULL;
00468   f->computed_goto_common_label = NULL;
00469   f->computed_goto_common_reg = NULL;
00470   f->x_save_expr_regs = NULL;
00471   f->x_stack_slot_list = NULL;
00472   f->x_rtl_expr_chain = NULL;
00473   f->x_tail_recursion_label = NULL;
00474   f->x_tail_recursion_reentry = NULL;
00475   f->x_arg_pointer_save_area = NULL;
00476   f->x_clobber_return_insn = NULL;
00477   f->x_context_display = NULL;
00478   f->x_trampoline_list = NULL;
00479   f->x_parm_birth_insn = NULL;
00480   f->x_last_parm_insn = NULL;
00481   f->x_parm_reg_stack_loc = NULL;
00482   f->fixup_var_refs_queue = NULL;
00483   f->original_arg_vector = NULL;
00484   f->original_decl_initial = NULL;
00485   f->inl_last_parm_insn = NULL;
00486   f->epilogue_delay_list = NULL;
00487 }
00488 
00489 /* Allocate fixed slots in the stack frame of the current function.  */
00490 
00491 /* Return size needed for stack frame based on slots so far allocated in
00492    function F.
00493    This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
00494    the caller may have to do that.  */
00495 
00496 HOST_WIDE_INT
00497 get_func_frame_size (f)
00498      struct function *f;
00499 {
00500 #ifdef FRAME_GROWS_DOWNWARD
00501   return -f->x_frame_offset;
00502 #else
00503   return f->x_frame_offset;
00504 #endif
00505 }
00506 
00507 /* Return size needed for stack frame based on slots so far allocated.
00508    This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
00509    the caller may have to do that.  */
00510 HOST_WIDE_INT
00511 get_frame_size ()
00512 {
00513   return get_func_frame_size (cfun);
00514 }
00515 
00516 /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
00517    with machine mode MODE.
00518 
00519    ALIGN controls the amount of alignment for the address of the slot:
00520    0 means according to MODE,
00521    -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
00522    positive specifies alignment boundary in bits.
00523 
00524    We do not round to stack_boundary here.
00525 
00526    FUNCTION specifies the function to allocate in.  */
00527 
00528 static rtx
00529 assign_stack_local_1 (mode, size, align, function)
00530      enum machine_mode mode;
00531      HOST_WIDE_INT size;
00532      int align;
00533      struct function *function;
00534 {
00535   rtx x, addr;
00536   int bigend_correction = 0;
00537   int alignment;
00538   int frame_off, frame_alignment, frame_phase;
00539 
00540   if (align == 0)
00541     {
00542       tree type;
00543 
00544       if (mode == BLKmode)
00545   alignment = BIGGEST_ALIGNMENT;
00546       else
00547   alignment = GET_MODE_ALIGNMENT (mode);
00548 
00549       /* Allow the target to (possibly) increase the alignment of this
00550    stack slot.  */
00551       type = (*lang_hooks.types.type_for_mode) (mode, 0);
00552       if (type)
00553   alignment = LOCAL_ALIGNMENT (type, alignment);
00554 
00555       alignment /= BITS_PER_UNIT;
00556     }
00557   else if (align == -1)
00558     {
00559       alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
00560       size = CEIL_ROUND (size, alignment);
00561     }
00562   else
00563     alignment = align / BITS_PER_UNIT;
00564 
00565 #ifdef FRAME_GROWS_DOWNWARD
00566   function->x_frame_offset -= size;
00567 #endif
00568 
00569   /* Ignore alignment we can't do with expected alignment of the boundary.  */
00570   if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
00571     alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
00572 
00573   if (function->stack_alignment_needed < alignment * BITS_PER_UNIT)
00574     function->stack_alignment_needed = alignment * BITS_PER_UNIT;
00575 
00576   /* Calculate how many bytes the start of local variables is off from
00577      stack alignment.  */
00578   frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
00579   frame_off = STARTING_FRAME_OFFSET % frame_alignment;
00580   frame_phase = frame_off ? frame_alignment - frame_off : 0;
00581 
00582   /* Round frame offset to that alignment.
00583      We must be careful here, since FRAME_OFFSET might be negative and
00584      division with a negative dividend isn't as well defined as we might
00585      like.  So we instead assume that ALIGNMENT is a power of two and
00586      use logical operations which are unambiguous.  */
00587 #ifdef FRAME_GROWS_DOWNWARD
00588   function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
00589 #else
00590   function->x_frame_offset = CEIL_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
00591 #endif
00592 
00593   /* On a big-endian machine, if we are allocating more space than we will use,
00594      use the least significant bytes of those that are allocated.  */
00595   if (BYTES_BIG_ENDIAN && mode != BLKmode)
00596     bigend_correction = size - GET_MODE_SIZE (mode);
00597 
00598   /* If we have already instantiated virtual registers, return the actual
00599      address relative to the frame pointer.  */
00600   if (function == cfun && virtuals_instantiated)
00601     addr = plus_constant (frame_pointer_rtx,
00602         (frame_offset + bigend_correction
00603          + STARTING_FRAME_OFFSET));
00604   else
00605     addr = plus_constant (virtual_stack_vars_rtx,
00606         function->x_frame_offset + bigend_correction);
00607 
00608 #ifndef FRAME_GROWS_DOWNWARD
00609   function->x_frame_offset += size;
00610 #endif
00611 
00612   x = gen_rtx_MEM (mode, addr);
00613 
00614   function->x_stack_slot_list
00615     = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
00616 
00617   return x;
00618 }
00619 
00620 /* Wrapper around assign_stack_local_1;  assign a local stack slot for the
00621    current function.  */
00622 
00623 rtx
00624 assign_stack_local (mode, size, align)
00625      enum machine_mode mode;
00626      HOST_WIDE_INT size;
00627      int align;
00628 {
00629   return assign_stack_local_1 (mode, size, align, cfun);
00630 }
00631 
00632 /* Allocate a temporary stack slot and record it for possible later
00633    reuse.
00634 
00635    MODE is the machine mode to be given to the returned rtx.
00636 
00637    SIZE is the size in units of the space required.  We do no rounding here
00638    since assign_stack_local will do any required rounding.
00639 
00640    KEEP is 1 if this slot is to be retained after a call to
00641    free_temp_slots.  Automatic variables for a block are allocated
00642    with this flag.  KEEP is 2 if we allocate a longer term temporary,
00643    whose lifetime is controlled by CLEANUP_POINT_EXPRs.  KEEP is 3
00644    if we are to allocate something at an inner level to be treated as
00645    a variable in the block (e.g., a SAVE_EXPR).
00646 
00647    TYPE is the type that will be used for the stack slot.  */
00648 
00649 rtx
00650 assign_stack_temp_for_type (mode, size, keep, type)
00651      enum machine_mode mode;
00652      HOST_WIDE_INT size;
00653      int keep;
00654      tree type;
00655 {
00656   unsigned int align;
00657   struct temp_slot *p, *best_p = 0;
00658   rtx slot;
00659 
00660   /* If SIZE is -1 it means that somebody tried to allocate a temporary
00661      of a variable size.  */
00662   if (size == -1)
00663     abort ();
00664 
00665   if (mode == BLKmode)
00666     align = BIGGEST_ALIGNMENT;
00667   else
00668     align = GET_MODE_ALIGNMENT (mode);
00669 
00670   if (! type)
00671     type = (*lang_hooks.types.type_for_mode) (mode, 0);
00672 
00673   if (type)
00674     align = LOCAL_ALIGNMENT (type, align);
00675 
00676   /* Try to find an available, already-allocated temporary of the proper
00677      mode which meets the size and alignment requirements.  Choose the
00678      smallest one with the closest alignment.  */
00679   for (p = temp_slots; p; p = p->next)
00680     if (p->align >= align && p->size >= size && GET_MODE (p->slot) == mode
00681   && ! p->in_use
00682   && objects_must_conflict_p (p->type, type)
00683   && (best_p == 0 || best_p->size > p->size
00684       || (best_p->size == p->size && best_p->align > p->align)))
00685       {
00686   if (p->align == align && p->size == size)
00687     {
00688       best_p = 0;
00689       break;
00690     }
00691   best_p = p;
00692       }
00693 
00694   /* Make our best, if any, the one to use.  */
00695   if (best_p)
00696     {
00697       /* If there are enough aligned bytes left over, make them into a new
00698    temp_slot so that the extra bytes don't get wasted.  Do this only
00699    for BLKmode slots, so that we can be sure of the alignment.  */
00700       if (GET_MODE (best_p->slot) == BLKmode)
00701   {
00702     int alignment = best_p->align / BITS_PER_UNIT;
00703     HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment);
00704 
00705     if (best_p->size - rounded_size >= alignment)
00706       {
00707         p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));
00708         p->in_use = p->addr_taken = 0;
00709         p->size = best_p->size - rounded_size;
00710         p->base_offset = best_p->base_offset + rounded_size;
00711         p->full_size = best_p->full_size - rounded_size;
00712         p->slot = gen_rtx_MEM (BLKmode,
00713              plus_constant (XEXP (best_p->slot, 0),
00714                 rounded_size));
00715         p->align = best_p->align;
00716         p->address = 0;
00717         p->rtl_expr = 0;
00718         p->type = best_p->type;
00719         p->next = temp_slots;
00720         temp_slots = p;
00721 
00722         stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, p->slot,
00723                stack_slot_list);
00724 
00725         best_p->size = rounded_size;
00726         best_p->full_size = rounded_size;
00727       }
00728   }
00729 
00730       p = best_p;
00731     }
00732 
00733   /* If we still didn't find one, make a new temporary.  */
00734   if (p == 0)
00735     {
00736       HOST_WIDE_INT frame_offset_old = frame_offset;
00737 
00738       p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));
00739 
00740       /* We are passing an explicit alignment request to assign_stack_local.
00741    One side effect of that is assign_stack_local will not round SIZE
00742    to ensure the frame offset remains suitably aligned.
00743 
00744    So for requests which depended on the rounding of SIZE, we go ahead
00745    and round it now.  We also make sure ALIGNMENT is at least
00746    BIGGEST_ALIGNMENT.  */
00747       if (mode == BLKmode && align < BIGGEST_ALIGNMENT)
00748   abort ();
00749       p->slot = assign_stack_local (mode,
00750             (mode == BLKmode
00751              ? CEIL_ROUND (size, align / BITS_PER_UNIT)
00752              : size),
00753             align);
00754 
00755       p->align = align;
00756 
00757       /* The following slot size computation is necessary because we don't
00758    know the actual size of the temporary slot until assign_stack_local
00759    has performed all the frame alignment and size rounding for the
00760    requested temporary.  Note that extra space added for alignment
00761    can be either above or below this stack slot depending on which
00762    way the frame grows.  We include the extra space if and only if it
00763    is above this slot.  */
00764 #ifdef FRAME_GROWS_DOWNWARD
00765       p->size = frame_offset_old - frame_offset;
00766 #else
00767       p->size = size;
00768 #endif
00769 
00770       /* Now define the fields used by combine_temp_slots.  */
00771 #ifdef FRAME_GROWS_DOWNWARD
00772       p->base_offset = frame_offset;
00773       p->full_size = frame_offset_old - frame_offset;
00774 #else
00775       p->base_offset = frame_offset_old;
00776       p->full_size = frame_offset - frame_offset_old;
00777 #endif
00778       p->address = 0;
00779       p->next = temp_slots;
00780       temp_slots = p;
00781     }
00782 
00783   p->in_use = 1;
00784   p->addr_taken = 0;
00785   p->rtl_expr = seq_rtl_expr;
00786   p->type = type;
00787 
00788   if (keep == 2)
00789     {
00790       p->level = target_temp_slot_level;
00791       p->keep = 0;
00792     }
00793   else if (keep == 3)
00794     {
00795       p->level = var_temp_slot_level;
00796       p->keep = 0;
00797     }
00798   else
00799     {
00800       p->level = temp_slot_level;
00801       p->keep = keep;
00802     }
00803 
00804 
00805   /* Create a new MEM rtx to avoid clobbering MEM flags of old slots.  */
00806   slot = gen_rtx_MEM (mode, XEXP (p->slot, 0));
00807   stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, slot, stack_slot_list);
00808 
00809   /* If we know the alias set for the memory that will be used, use
00810      it.  If there's no TYPE, then we don't know anything about the
00811      alias set for the memory.  */
00812   set_mem_alias_set (slot, type ? get_alias_set (type) : 0);
00813   set_mem_align (slot, align);
00814 
00815   /* If a type is specified, set the relevant flags.  */
00816   if (type != 0)
00817     {
00818       RTX_UNCHANGING_P (slot) = (lang_hooks.honor_readonly 
00819          && TYPE_READONLY (type));
00820       MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type);
00821       MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type));
00822     }
00823 
00824   return slot;
00825 }
00826 
00827 /* Allocate a temporary stack slot and record it for possible later
00828    reuse.  First three arguments are same as in preceding function.  */
00829 
00830 rtx
00831 assign_stack_temp (mode, size, keep)
00832      enum machine_mode mode;
00833      HOST_WIDE_INT size;
00834      int keep;
00835 {
00836   return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
00837 }
00838 
00839 /* Assign a temporary.
00840    If TYPE_OR_DECL is a decl, then we are doing it on behalf of the decl
00841    and so that should be used in error messages.  In either case, we
00842    allocate of the given type.
00843    KEEP is as for assign_stack_temp.
00844    MEMORY_REQUIRED is 1 if the result must be addressable stack memory;
00845    it is 0 if a register is OK.
00846    DONT_PROMOTE is 1 if we should not promote values in register
00847    to wider modes.  */
00848 
00849 rtx
00850 assign_temp (type_or_decl, keep, memory_required, dont_promote)
00851      tree type_or_decl;
00852      int keep;
00853      int memory_required;
00854      int dont_promote ATTRIBUTE_UNUSED;
00855 {
00856   tree type, decl;
00857   enum machine_mode mode;
00858 #ifndef PROMOTE_FOR_CALL_ONLY
00859   int unsignedp;
00860 #endif
00861 
00862   if (DECL_P (type_or_decl))
00863     decl = type_or_decl, type = TREE_TYPE (decl);
00864   else
00865     decl = NULL, type = type_or_decl;
00866 
00867   mode = TYPE_MODE (type);
00868 #ifndef PROMOTE_FOR_CALL_ONLY
00869   unsignedp = TREE_UNSIGNED (type);
00870 #endif
00871 
00872   if (mode == BLKmode || memory_required)
00873     {
00874       HOST_WIDE_INT size = int_size_in_bytes (type);
00875       rtx tmp;
00876 
00877       /* Zero sized arrays are GNU C extension.  Set size to 1 to avoid
00878    problems with allocating the stack space.  */
00879       if (size == 0)
00880   size = 1;
00881 
00882       /* Unfortunately, we don't yet know how to allocate variable-sized
00883    temporaries.  However, sometimes we have a fixed upper limit on
00884    the size (which is stored in TYPE_ARRAY_MAX_SIZE) and can use that
00885    instead.  This is the case for Chill variable-sized strings.  */
00886       if (size == -1 && TREE_CODE (type) == ARRAY_TYPE
00887     && TYPE_ARRAY_MAX_SIZE (type) != NULL_TREE
00888     && host_integerp (TYPE_ARRAY_MAX_SIZE (type), 1))
00889   size = tree_low_cst (TYPE_ARRAY_MAX_SIZE (type), 1);
00890 
00891       /* The size of the temporary may be too large to fit into an integer.  */
00892       /* ??? Not sure this should happen except for user silliness, so limit
00893    this to things that aren't compiler-generated temporaries.  The
00894    rest of the time we'll abort in assign_stack_temp_for_type.  */
00895       if (decl && size == -1
00896     && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
00897   {
00898     error_with_decl (decl, "size of variable `%s' is too large");
00899     size = 1;
00900   }
00901 
00902       tmp = assign_stack_temp_for_type (mode, size, keep, type);
00903       return tmp;
00904     }
00905 
00906 #ifndef PROMOTE_FOR_CALL_ONLY
00907   if (! dont_promote)
00908     mode = promote_mode (type, mode, &unsignedp, 0);
00909 #endif
00910 
00911   return gen_reg_rtx (mode);
00912 }
00913 
00914 /* Combine temporary stack slots which are adjacent on the stack.
00915 
00916    This allows for better use of already allocated stack space.  This is only
00917    done for BLKmode slots because we can be sure that we won't have alignment
00918    problems in this case.  */
00919 
00920 void
00921 combine_temp_slots ()
00922 {
00923   struct temp_slot *p, *q;
00924   struct temp_slot *prev_p, *prev_q;
00925   int num_slots;
00926 
00927   /* We can't combine slots, because the information about which slot
00928      is in which alias set will be lost.  */
00929   if (flag_strict_aliasing)
00930     return;
00931 
00932   /* If there are a lot of temp slots, don't do anything unless
00933      high levels of optimization.  */
00934   if (! flag_expensive_optimizations)
00935     for (p = temp_slots, num_slots = 0; p; p = p->next, num_slots++)
00936       if (num_slots > 100 || (num_slots > 10 && optimize == 0))
00937   return;
00938 
00939   for (p = temp_slots, prev_p = 0; p; p = prev_p ? prev_p->next : temp_slots)
00940     {
00941       int delete_p = 0;
00942 
00943       if (! p->in_use && GET_MODE (p->slot) == BLKmode)
00944   for (q = p->next, prev_q = p; q; q = prev_q->next)
00945     {
00946       int delete_q = 0;
00947       if (! q->in_use && GET_MODE (q->slot) == BLKmode)
00948         {
00949     if (p->base_offset + p->full_size == q->base_offset)
00950       {
00951         /* Q comes after P; combine Q into P.  */
00952         p->size += q->size;
00953         p->full_size += q->full_size;
00954         delete_q = 1;
00955       }
00956     else if (q->base_offset + q->full_size == p->base_offset)
00957       {
00958         /* P comes after Q; combine P into Q.  */
00959         q->size += p->size;
00960         q->full_size += p->full_size;
00961         delete_p = 1;
00962         break;
00963       }
00964         }
00965       /* Either delete Q or advance past it.  */
00966       if (delete_q)
00967         prev_q->next = q->next;
00968       else
00969         prev_q = q;
00970     }
00971       /* Either delete P or advance past it.  */
00972       if (delete_p)
00973   {
00974     if (prev_p)
00975       prev_p->next = p->next;
00976     else
00977       temp_slots = p->next;
00978   }
00979       else
00980   prev_p = p;
00981     }
00982 }
00983 
00984 /* Find the temp slot corresponding to the object at address X.  */
00985 
00986 static struct temp_slot *
00987 find_temp_slot_from_address (x)
00988      rtx x;
00989 {
00990   struct temp_slot *p;
00991   rtx next;
00992 
00993   for (p = temp_slots; p; p = p->next)
00994     {
00995       if (! p->in_use)
00996   continue;
00997 
00998       else if (XEXP (p->slot, 0) == x
00999          || p->address == x
01000          || (GET_CODE (x) == PLUS
01001        && XEXP (x, 0) == virtual_stack_vars_rtx
01002        && GET_CODE (XEXP (x, 1)) == CONST_INT
01003        && INTVAL (XEXP (x, 1)) >= p->base_offset
01004        && INTVAL (XEXP (x, 1)) < p->base_offset + p->full_size))
01005   return p;
01006 
01007       else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST)
01008   for (next = p->address; next; next = XEXP (next, 1))
01009     if (XEXP (next, 0) == x)
01010       return p;
01011     }
01012 
01013   /* If we have a sum involving a register, see if it points to a temp
01014      slot.  */
01015   if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG
01016       && (p = find_temp_slot_from_address (XEXP (x, 0))) != 0)
01017     return p;
01018   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG
01019      && (p = find_temp_slot_from_address (XEXP (x, 1))) != 0)
01020     return p;
01021 
01022   return 0;
01023 }
01024 
01025 /* Indicate that NEW is an alternate way of referring to the temp slot
01026    that previously was known by OLD.  */
01027 
01028 void
01029 update_temp_slot_address (old, new)
01030      rtx old, new;
01031 {
01032   struct temp_slot *p;
01033 
01034   if (rtx_equal_p (old, new))
01035     return;
01036 
01037   p = find_temp_slot_from_address (old);
01038 
01039   /* If we didn't find one, see if both OLD is a PLUS.  If so, and NEW
01040      is a register, see if one operand of the PLUS is a temporary
01041      location.  If so, NEW points into it.  Otherwise, if both OLD and
01042      NEW are a PLUS and if there is a register in common between them.
01043      If so, try a recursive call on those values.  */
01044   if (p == 0)
01045     {
01046       if (GET_CODE (old) != PLUS)
01047   return;
01048 
01049       if (GET_CODE (new) == REG)
01050   {
01051     update_temp_slot_address (XEXP (old, 0), new);
01052     update_temp_slot_address (XEXP (old, 1), new);
01053     return;
01054   }
01055       else if (GET_CODE (new) != PLUS)
01056   return;
01057 
01058       if (rtx_equal_p (XEXP (old, 0), XEXP (new, 0)))
01059   update_temp_slot_address (XEXP (old, 1), XEXP (new, 1));
01060       else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 0)))
01061   update_temp_slot_address (XEXP (old, 0), XEXP (new, 1));
01062       else if (rtx_equal_p (XEXP (old, 0), XEXP (new, 1)))
01063   update_temp_slot_address (XEXP (old, 1), XEXP (new, 0));
01064       else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 1)))
01065   update_temp_slot_address (XEXP (old, 0), XEXP (new, 0));
01066 
01067       return;
01068     }
01069 
01070   /* Otherwise add an alias for the temp's address.  */
01071   else if (p->address == 0)
01072     p->address = new;
01073   else
01074     {
01075       if (GET_CODE (p->address) != EXPR_LIST)
01076   p->address = gen_rtx_EXPR_LIST (VOIDmode, p->address, NULL_RTX);
01077 
01078       p->address = gen_rtx_EXPR_LIST (VOIDmode, new, p->address);
01079     }
01080 }
01081 
01082 /* If X could be a reference to a temporary slot, mark the fact that its
01083    address was taken.  */
01084 
01085 void
01086 mark_temp_addr_taken (x)
01087      rtx x;
01088 {
01089   struct temp_slot *p;
01090 
01091   if (x == 0)
01092     return;
01093 
01094   /* If X is not in memory or is at a constant address, it cannot be in
01095      a temporary slot.  */
01096   if (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
01097     return;
01098 
01099   p = find_temp_slot_from_address (XEXP (x, 0));
01100   if (p != 0)
01101     p->addr_taken = 1;
01102 }
01103 
01104 /* If X could be a reference to a temporary slot, mark that slot as
01105    belonging to the to one level higher than the current level.  If X
01106    matched one of our slots, just mark that one.  Otherwise, we can't
01107    easily predict which it is, so upgrade all of them.  Kept slots
01108    need not be touched.
01109 
01110    This is called when an ({...}) construct occurs and a statement
01111    returns a value in memory.  */
01112 
01113 void
01114 preserve_temp_slots (x)
01115      rtx x;
01116 {
01117   struct temp_slot *p = 0;
01118 
01119   /* If there is no result, we still might have some objects whose address
01120      were taken, so we need to make sure they stay around.  */
01121   if (x == 0)
01122     {
01123       for (p = temp_slots; p; p = p->next)
01124   if (p->in_use && p->level == temp_slot_level && p->addr_taken)
01125     p->level--;
01126 
01127       return;
01128     }
01129 
01130   /* If X is a register that is being used as a pointer, see if we have
01131      a temporary slot we know it points to.  To be consistent with
01132      the code below, we really should preserve all non-kept slots
01133      if we can't find a match, but that seems to be much too costly.  */
01134   if (GET_CODE (x) == REG && REG_POINTER (x))
01135     p = find_temp_slot_from_address (x);
01136 
01137   /* If X is not in memory or is at a constant address, it cannot be in
01138      a temporary slot, but it can contain something whose address was
01139      taken.  */
01140   if (p == 0 && (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0))))
01141     {
01142       for (p = temp_slots; p; p = p->next)
01143   if (p->in_use && p->level == temp_slot_level && p->addr_taken)
01144     p->level--;
01145 
01146       return;
01147     }
01148 
01149   /* First see if we can find a match.  */
01150   if (p == 0)
01151     p = find_temp_slot_from_address (XEXP (x, 0));
01152 
01153   if (p != 0)
01154     {
01155       /* Move everything at our level whose address was taken to our new
01156    level in case we used its address.  */
01157       struct temp_slot *q;
01158 
01159       if (p->level == temp_slot_level)
01160   {
01161     for (q = temp_slots; q; q = q->next)
01162       if (q != p && q->addr_taken && q->level == p->level)
01163         q->level--;
01164 
01165     p->level--;
01166     p->addr_taken = 0;
01167   }
01168       return;
01169     }
01170 
01171   /* Otherwise, preserve all non-kept slots at this level.  */
01172   for (p = temp_slots; p; p = p->next)
01173     if (p->in_use && p->level == temp_slot_level && ! p->keep)
01174       p->level--;
01175 }
01176 
01177 /* X is the result of an RTL_EXPR.  If it is a temporary slot associated
01178    with that RTL_EXPR, promote it into a temporary slot at the present
01179    level so it will not be freed when we free slots made in the
01180    RTL_EXPR.  */
01181 
01182 void
01183 preserve_rtl_expr_result (x)
01184      rtx x;
01185 {
01186   struct temp_slot *p;
01187 
01188   /* If X is not in memory or is at a constant address, it cannot be in
01189      a temporary slot.  */
01190   if (x == 0 || GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
01191     return;
01192 
01193   /* If we can find a match, move it to our level unless it is already at
01194      an upper level.  */
01195   p = find_temp_slot_from_address (XEXP (x, 0));
01196   if (p != 0)
01197     {
01198       p->level = MIN (p->level, temp_slot_level);
01199       p->rtl_expr = 0;
01200     }
01201 
01202   return;
01203 }
01204 
01205 /* Free all temporaries used so far.  This is normally called at the end
01206    of generating code for a statement.  Don't free any temporaries
01207    currently in use for an RTL_EXPR that hasn't yet been emitted.
01208    We could eventually do better than this since it can be reused while
01209    generating the same RTL_EXPR, but this is complex and probably not
01210    worthwhile.  */
01211 
01212 void
01213 free_temp_slots ()
01214 {
01215   struct temp_slot *p;
01216 
01217   for (p = temp_slots; p; p = p->next)
01218     if (p->in_use && p->level == temp_slot_level && ! p->keep
01219   && p->rtl_expr == 0)
01220       p->in_use = 0;
01221 
01222   combine_temp_slots ();
01223 }
01224 
01225 /* Free all temporary slots used in T, an RTL_EXPR node.  */
01226 
01227 void
01228 free_temps_for_rtl_expr (t)
01229      tree t;
01230 {
01231   struct temp_slot *p;
01232 
01233   for (p = temp_slots; p; p = p->next)
01234     if (p->rtl_expr == t)
01235       {
01236   /* If this slot is below the current TEMP_SLOT_LEVEL, then it
01237      needs to be preserved.  This can happen if a temporary in
01238      the RTL_EXPR was addressed; preserve_temp_slots will move
01239      the temporary into a higher level.  */
01240   if (temp_slot_level <= p->level)
01241     p->in_use = 0;
01242   else
01243     p->rtl_expr = NULL_TREE;
01244       }
01245 
01246   combine_temp_slots ();
01247 }
01248 
01249 /* Mark all temporaries ever allocated in this function as not suitable
01250    for reuse until the current level is exited.  */
01251 
01252 void
01253 mark_all_temps_used ()
01254 {
01255   struct temp_slot *p;
01256 
01257   for (p = temp_slots; p; p = p->next)
01258     {
01259       p->in_use = p->keep = 1;
01260       p->level = MIN (p->level, temp_slot_level);
01261     }
01262 }
01263 
01264 /* Push deeper into the nesting level for stack temporaries.  */
01265 
01266 void
01267 push_temp_slots ()
01268 {
01269   temp_slot_level++;
01270 }
01271 
01272 /* Likewise, but save the new level as the place to allocate variables
01273    for blocks.  */
01274 
01275 #if 0
01276 void
01277 push_temp_slots_for_block ()
01278 {
01279   push_temp_slots ();
01280 
01281   var_temp_slot_level = temp_slot_level;
01282 }
01283 
01284 /* Likewise, but save the new level as the place to allocate temporaries
01285    for TARGET_EXPRs.  */
01286 
01287 void
01288 push_temp_slots_for_target ()
01289 {
01290   push_temp_slots ();
01291 
01292   target_temp_slot_level = temp_slot_level;
01293 }
01294 
01295 /* Set and get the value of target_temp_slot_level.  The only
01296    permitted use of these functions is to save and restore this value.  */
01297 
01298 int
01299 get_target_temp_slot_level ()
01300 {
01301   return target_temp_slot_level;
01302 }
01303 
01304 void
01305 set_target_temp_slot_level (level)
01306      int level;
01307 {
01308   target_temp_slot_level = level;
01309 }
01310 #endif
01311 
01312 /* Pop a temporary nesting level.  All slots in use in the current level
01313    are freed.  */
01314 
01315 void
01316 pop_temp_slots ()
01317 {
01318   struct temp_slot *p;
01319 
01320   for (p = temp_slots; p; p = p->next)
01321     if (p->in_use && p->level == temp_slot_level && p->rtl_expr == 0)
01322       p->in_use = 0;
01323 
01324   combine_temp_slots ();
01325 
01326   temp_slot_level--;
01327 }
01328 
01329 /* Initialize temporary slots.  */
01330 
01331 void
01332 init_temp_slots ()
01333 {
01334   /* We have not allocated any temporaries yet.  */
01335   temp_slots = 0;
01336   temp_slot_level = 0;
01337   var_temp_slot_level = 0;
01338   target_temp_slot_level = 0;
01339 }
01340 
01341 /* Retroactively move an auto variable from a register to a stack
01342    slot.  This is done when an address-reference to the variable is
01343    seen.  If RESCAN is true, all previously emitted instructions are
01344    examined and modified to handle the fact that DECL is now
01345    addressable.  */
01346 
01347 void
01348 put_var_into_stack (decl, rescan)
01349      tree decl;
01350      int rescan;
01351 {
01352   rtx reg;
01353   enum machine_mode promoted_mode, decl_mode;
01354   struct function *function = 0;
01355   tree context;
01356   int can_use_addressof;
01357   int volatilep = TREE_CODE (decl) != SAVE_EXPR && TREE_THIS_VOLATILE (decl);
01358   int usedp = (TREE_USED (decl)
01359          || (TREE_CODE (decl) != SAVE_EXPR && DECL_INITIAL (decl) != 0));
01360 
01361   context = decl_function_context (decl);
01362 
01363   /* Get the current rtl used for this object and its original mode.  */
01364   reg = (TREE_CODE (decl) == SAVE_EXPR
01365    ? SAVE_EXPR_RTL (decl)
01366    : DECL_RTL_IF_SET (decl));
01367 
01368   /* No need to do anything if decl has no rtx yet
01369      since in that case caller is setting TREE_ADDRESSABLE
01370      and a stack slot will be assigned when the rtl is made.  */
01371   if (reg == 0)
01372     return;
01373 
01374   /* Get the declared mode for this object.  */
01375   decl_mode = (TREE_CODE (decl) == SAVE_EXPR ? TYPE_MODE (TREE_TYPE (decl))
01376          : DECL_MODE (decl));
01377   /* Get the mode it's actually stored in.  */
01378   promoted_mode = GET_MODE (reg);
01379 
01380   /* If this variable comes from an outer function, find that
01381      function's saved context.  Don't use find_function_data here,
01382      because it might not be in any active function.
01383      FIXME: Is that really supposed to happen?
01384      It does in ObjC at least.  */
01385   if (context != current_function_decl && context != inline_function_decl)
01386     for (function = outer_function_chain; function; function = function->outer)
01387       if (function->decl == context)
01388   break;
01389 
01390   /* If this is a variable-size object with a pseudo to address it,
01391      put that pseudo into the stack, if the var is nonlocal.  */
01392   if (TREE_CODE (decl) != SAVE_EXPR && DECL_NONLOCAL (decl)
01393       && GET_CODE (reg) == MEM
01394       && GET_CODE (XEXP (reg, 0)) == REG
01395       && REGNO (XEXP (reg, 0)) > LAST_VIRTUAL_REGISTER)
01396     {
01397       reg = XEXP (reg, 0);
01398       decl_mode = promoted_mode = GET_MODE (reg);
01399     }
01400 
01401   can_use_addressof
01402     = (function == 0
01403        && optimize > 0
01404        /* FIXME make it work for promoted modes too */
01405        && decl_mode == promoted_mode
01406 #ifdef NON_SAVING_SETJMP
01407        && ! (NON_SAVING_SETJMP && current_function_calls_setjmp)
01408 #endif
01409        );
01410 
01411   /* If we can't use ADDRESSOF, make sure we see through one we already
01412      generated.  */
01413   if (! can_use_addressof && GET_CODE (reg) == MEM
01414       && GET_CODE (XEXP (reg, 0)) == ADDRESSOF)
01415     reg = XEXP (XEXP (reg, 0), 0);
01416 
01417   /* Now we should have a value that resides in one or more pseudo regs.  */
01418 
01419   if (GET_CODE (reg) == REG)
01420     {
01421       /* If this variable lives in the current function and we don't need
01422    to put things in the stack for the sake of setjmp, try to keep it
01423    in a register until we know we actually need the address.  */
01424       if (can_use_addressof)
01425   gen_mem_addressof (reg, decl, rescan);
01426       else
01427   put_reg_into_stack (function, reg, TREE_TYPE (decl), promoted_mode,
01428           decl_mode, volatilep, 0, usedp, 0);
01429     }
01430   else if (GET_CODE (reg) == CONCAT)
01431     {
01432       /* A CONCAT contains two pseudos; put them both in the stack.
01433    We do it so they end up consecutive.
01434    We fixup references to the parts only after we fixup references
01435    to the whole CONCAT, lest we do double fixups for the latter
01436    references.  */
01437       enum machine_mode part_mode = GET_MODE (XEXP (reg, 0));
01438       tree part_type = (*lang_hooks.types.type_for_mode) (part_mode, 0);
01439       rtx lopart = XEXP (reg, 0);
01440       rtx hipart = XEXP (reg, 1);
01441 #ifdef FRAME_GROWS_DOWNWARD
01442       /* Since part 0 should have a lower address, do it second.  */
01443       put_reg_into_stack (function, hipart, part_type, part_mode,
01444         part_mode, volatilep, 0, 0, 0);
01445       put_reg_into_stack (function, lopart, part_type, part_mode,
01446         part_mode, volatilep, 0, 0, 0);
01447 #else
01448       put_reg_into_stack (function, lopart, part_type, part_mode,
01449         part_mode, volatilep, 0, 0, 0);
01450       put_reg_into_stack (function, hipart, part_type, part_mode,
01451         part_mode, volatilep, 0, 0, 0);
01452 #endif
01453 
01454       /* Change the CONCAT into a combined MEM for both parts.  */
01455       PUT_CODE (reg, MEM);
01456       MEM_ATTRS (reg) = 0;
01457 
01458       /* set_mem_attributes uses DECL_RTL to avoid re-generating of
01459          already computed alias sets.  Here we want to re-generate.  */
01460       if (DECL_P (decl))
01461   SET_DECL_RTL (decl, NULL);
01462       set_mem_attributes (reg, decl, 1);
01463       if (DECL_P (decl))
01464   SET_DECL_RTL (decl, reg);
01465 
01466       /* The two parts are in memory order already.
01467    Use the lower parts address as ours.  */
01468       XEXP (reg, 0) = XEXP (XEXP (reg, 0), 0);
01469       /* Prevent sharing of rtl that might lose.  */
01470       if (GET_CODE (XEXP (reg, 0)) == PLUS)
01471   XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
01472       if (usedp && rescan)
01473   {
01474     schedule_fixup_var_refs (function, reg, TREE_TYPE (decl),
01475            promoted_mode, 0);
01476     schedule_fixup_var_refs (function, lopart, part_type, part_mode, 0);
01477     schedule_fixup_var_refs (function, hipart, part_type, part_mode, 0);
01478   }
01479     }
01480   else
01481     return;
01482 }
01483 
01484 /* Subroutine of put_var_into_stack.  This puts a single pseudo reg REG
01485    into the stack frame of FUNCTION (0 means the current function).
01486    DECL_MODE is the machine mode of the user-level data type.
01487    PROMOTED_MODE is the machine mode of the register.
01488    VOLATILE_P is nonzero if this is for a "volatile" decl.
01489    USED_P is nonzero if this reg might have already been used in an insn.  */
01490 
01491 static void
01492 put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
01493         original_regno, used_p, ht)
01494      struct function *function;
01495      rtx reg;
01496      tree type;
01497      enum machine_mode promoted_mode, decl_mode;
01498      int volatile_p;
01499      unsigned int original_regno;
01500      int used_p;
01501      htab_t ht;
01502 {
01503   struct function *func = function ? function : cfun;
01504   rtx new = 0;
01505   unsigned int regno = original_regno;
01506 
01507   if (regno == 0)
01508     regno = REGNO (reg);
01509 
01510   if (regno < func->x_max_parm_reg)
01511     new = func->x_parm_reg_stack_loc[regno];
01512 
01513   if (new == 0)
01514     new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
01515 
01516   PUT_CODE (reg, MEM);
01517   PUT_MODE (reg, decl_mode);
01518   XEXP (reg, 0) = XEXP (new, 0);
01519   MEM_ATTRS (reg) = 0;
01520   /* `volatil' bit means one thing for MEMs, another entirely for REGs.  */
01521   MEM_VOLATILE_P (reg) = volatile_p;
01522 
01523   /* If this is a memory ref that contains aggregate components,
01524      mark it as such for cse and loop optimize.  If we are reusing a
01525      previously generated stack slot, then we need to copy the bit in
01526      case it was set for other reasons.  For instance, it is set for
01527      __builtin_va_alist.  */
01528   if (type)
01529     {
01530       MEM_SET_IN_STRUCT_P (reg,
01531          AGGREGATE_TYPE_P (type) || MEM_IN_STRUCT_P (new));
01532       set_mem_alias_set (reg, get_alias_set (type));
01533     }
01534 
01535   if (used_p)
01536     schedule_fixup_var_refs (function, reg, type, promoted_mode, ht);
01537 }
01538 
01539 /* Make sure that all refs to the variable, previously made
01540    when it was a register, are fixed up to be valid again.
01541    See function above for meaning of arguments.  */
01542 
01543 static void
01544 schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
01545      struct function *function;
01546      rtx reg;
01547      tree type;
01548      enum machine_mode promoted_mode;
01549      htab_t ht;
01550 {
01551   int unsigned_p = type ? TREE_UNSIGNED (type) : 0;
01552 
01553   if (function != 0)
01554     {
01555       struct var_refs_queue *temp;
01556 
01557       temp
01558   = (struct var_refs_queue *) ggc_alloc (sizeof (struct var_refs_queue));
01559       temp->modified = reg;
01560       temp->promoted_mode = promoted_mode;
01561       temp->unsignedp = unsigned_p;
01562       temp->next = function->fixup_var_refs_queue;
01563       function->fixup_var_refs_queue = temp;
01564     }
01565   else
01566     /* Variable is local; fix it up now.  */
01567     fixup_var_refs (reg, promoted_mode, unsigned_p, reg, ht);
01568 }
01569 
01570 static void
01571 fixup_var_refs (var, promoted_mode, unsignedp, may_share, ht)
01572      rtx var;
01573      enum machine_mode promoted_mode;
01574      int unsignedp;
01575      htab_t ht;
01576      rtx may_share;
01577 {
01578   tree pending;
01579   rtx first_insn = get_insns ();
01580   struct sequence_stack *stack = seq_stack;
01581   tree rtl_exps = rtl_expr_chain;
01582 
01583   /* If there's a hash table, it must record all uses of VAR.  */
01584   if (ht)
01585     {
01586       if (stack != 0)
01587   abort ();
01588       fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp,
01589               may_share);
01590       return;
01591     }
01592 
01593   fixup_var_refs_insns (first_insn, var, promoted_mode, unsignedp,
01594       stack == 0, may_share);
01595 
01596   /* Scan all pending sequences too.  */
01597   for (; stack; stack = stack->next)
01598     {
01599       push_to_full_sequence (stack->first, stack->last);
01600       fixup_var_refs_insns (stack->first, var, promoted_mode, unsignedp,
01601           stack->next != 0, may_share);
01602       /* Update remembered end of sequence
01603    in case we added an insn at the end.  */
01604       stack->last = get_last_insn ();
01605       end_sequence ();
01606     }
01607 
01608   /* Scan all waiting RTL_EXPRs too.  */
01609   for (pending = rtl_exps; pending; pending = TREE_CHAIN (pending))
01610     {
01611       rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
01612       if (seq != const0_rtx && seq != 0)
01613   {
01614     push_to_sequence (seq);
01615     fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
01616         may_share);
01617     end_sequence ();
01618   }
01619     }
01620 }
01621 
01622 /* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
01623    some part of an insn.  Return a struct fixup_replacement whose OLD
01624    value is equal to X.  Allocate a new structure if no such entry exists.  */
01625 
01626 static struct fixup_replacement *
01627 find_fixup_replacement (replacements, x)
01628      struct fixup_replacement **replacements;
01629      rtx x;
01630 {
01631   struct fixup_replacement *p;
01632 
01633   /* See if we have already replaced this.  */
01634   for (p = *replacements; p != 0 && ! rtx_equal_p (p->old, x); p = p->next)
01635     ;
01636 
01637   if (p == 0)
01638     {
01639       p = (struct fixup_replacement *) xmalloc (sizeof (struct fixup_replacement));
01640       p->old = x;
01641       p->new = 0;
01642       p->next = *replacements;
01643       *replacements = p;
01644     }
01645 
01646   return p;
01647 }
01648 
01649 /* Scan the insn-chain starting with INSN for refs to VAR and fix them
01650    up.  TOPLEVEL is nonzero if this chain is the main chain of insns
01651    for the current function.  MAY_SHARE is either a MEM that is not
01652    to be unshared or a list of them.  */
01653 
01654 static void
01655 fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel, may_share)
01656      rtx insn;
01657      rtx var;
01658      enum machine_mode promoted_mode;
01659      int unsignedp;
01660      int toplevel;
01661      rtx may_share;
01662 {
01663   while (insn)
01664     {
01665       /* fixup_var_refs_insn might modify insn, so save its next
01666          pointer now.  */
01667       rtx next = NEXT_INSN (insn);
01668 
01669       /* CALL_PLACEHOLDERs are special; we have to switch into each of
01670    the three sequences they (potentially) contain, and process
01671    them recursively.  The CALL_INSN itself is not interesting.  */
01672 
01673       if (GET_CODE (insn) == CALL_INSN
01674     && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
01675   {
01676     int i;
01677 
01678     /* Look at the Normal call, sibling call and tail recursion
01679        sequences attached to the CALL_PLACEHOLDER.  */
01680     for (i = 0; i < 3; i++)
01681       {
01682         rtx seq = XEXP (PATTERN (insn), i);
01683         if (seq)
01684     {
01685       push_to_sequence (seq);
01686       fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
01687           may_share);
01688       XEXP (PATTERN (insn), i) = get_insns ();
01689       end_sequence ();
01690     }
01691       }
01692   }
01693 
01694       else if (INSN_P (insn))
01695   fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel,
01696            may_share);
01697 
01698       insn = next;
01699     }
01700 }
01701 
01702 /* Look up the insns which reference VAR in HT and fix them up.  Other
01703    arguments are the same as fixup_var_refs_insns.
01704 
01705    N.B. No need for special processing of CALL_PLACEHOLDERs here,
01706    because the hash table will point straight to the interesting insn
01707    (inside the CALL_PLACEHOLDER).  */
01708 
01709 static void
01710 fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp, may_share)
01711      htab_t ht;
01712      rtx var;
01713      enum machine_mode promoted_mode;
01714      int unsignedp;
01715      rtx may_share;
01716 {
01717   struct insns_for_mem_entry tmp;
01718   struct insns_for_mem_entry *ime;
01719   rtx insn_list;
01720 
01721   tmp.key = var;
01722   ime = (struct insns_for_mem_entry *) htab_find (ht, &tmp);
01723   for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
01724     if (INSN_P (XEXP (insn_list, 0)))
01725       fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
01726          unsignedp, 1, may_share);
01727 }
01728 
01729 
01730 /* Per-insn processing by fixup_var_refs_insns(_with_hash).  INSN is
01731    the insn under examination, VAR is the variable to fix up
01732    references to, PROMOTED_MODE and UNSIGNEDP describe VAR, and
01733    TOPLEVEL is nonzero if this is the main insn chain for this
01734    function.  */
01735 
01736 static void
01737 fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
01738      rtx insn;
01739      rtx var;
01740      enum machine_mode promoted_mode;
01741      int unsignedp;
01742      int toplevel;
01743      rtx no_share;
01744 {
01745   rtx call_dest = 0;
01746   rtx set, prev, prev_set;
01747   rtx note;
01748 
01749   /* Remember the notes in case we delete the insn.  */
01750   note = REG_NOTES (insn);
01751 
01752   /* If this is a CLOBBER of VAR, delete it.
01753 
01754      If it has a REG_LIBCALL note, delete the REG_LIBCALL
01755      and REG_RETVAL notes too.  */
01756   if (GET_CODE (PATTERN (insn)) == CLOBBER
01757       && (XEXP (PATTERN (insn), 0) == var
01758     || (GET_CODE (XEXP (PATTERN (insn), 0)) == CONCAT
01759         && (XEXP (XEXP (PATTERN (insn), 0), 0) == var
01760       || XEXP (XEXP (PATTERN (insn), 0), 1) == var))))
01761     {
01762       if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0)
01763   /* The REG_LIBCALL note will go away since we are going to
01764      turn INSN into a NOTE, so just delete the
01765      corresponding REG_RETVAL note.  */
01766   remove_note (XEXP (note, 0),
01767          find_reg_note (XEXP (note, 0), REG_RETVAL,
01768             NULL_RTX));
01769 
01770       delete_insn (insn);
01771     }
01772 
01773   /* The insn to load VAR from a home in the arglist
01774      is now a no-op.  When we see it, just delete it.
01775      Similarly if this is storing VAR from a register from which
01776      it was loaded in the previous insn.  This will occur
01777      when an ADDRESSOF was made for an arglist slot.  */
01778   else if (toplevel
01779      && (set = single_set (insn)) != 0
01780      && SET_DEST (set) == var
01781      /* If this represents the result of an insn group,
01782         don't delete the insn.  */
01783      && find_reg_note (insn, REG_RETVAL, NULL_RTX) == 0
01784      && (rtx_equal_p (SET_SRC (set), var)
01785          || (GET_CODE (SET_SRC (set)) == REG
01786        && (prev = prev_nonnote_insn (insn)) != 0
01787        && (prev_set = single_set (prev)) != 0
01788        && SET_DEST (prev_set) == SET_SRC (set)
01789        && rtx_equal_p (SET_SRC (prev_set), var))))
01790     {
01791       delete_insn (insn);
01792     }
01793   else
01794     {
01795       struct fixup_replacement *replacements = 0;
01796       rtx next_insn = NEXT_INSN (insn);
01797 
01798       if (SMALL_REGISTER_CLASSES)
01799   {
01800     /* If the insn that copies the results of a CALL_INSN
01801        into a pseudo now references VAR, we have to use an
01802        intermediate pseudo since we want the life of the
01803        return value register to be only a single insn.
01804 
01805        If we don't use an intermediate pseudo, such things as
01806        address computations to make the address of VAR valid
01807        if it is not can be placed between the CALL_INSN and INSN.
01808 
01809        To make sure this doesn't happen, we record the destination
01810        of the CALL_INSN and see if the next insn uses both that
01811        and VAR.  */
01812 
01813     if (call_dest != 0 && GET_CODE (insn) == INSN
01814         && reg_mentioned_p (var, PATTERN (insn))
01815         && reg_mentioned_p (call_dest, PATTERN (insn)))
01816       {
01817         rtx temp = gen_reg_rtx (GET_MODE (call_dest));
01818 
01819         emit_insn_before (gen_move_insn (temp, call_dest), insn);
01820 
01821         PATTERN (insn) = replace_rtx (PATTERN (insn),
01822               call_dest, temp);
01823       }
01824 
01825     if (GET_CODE (insn) == CALL_INSN
01826         && GET_CODE (PATTERN (insn)) == SET)
01827       call_dest = SET_DEST (PATTERN (insn));
01828     else if (GET_CODE (insn) == CALL_INSN
01829        && GET_CODE (PATTERN (insn)) == PARALLEL
01830        && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
01831       call_dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
01832     else
01833       call_dest = 0;
01834   }
01835 
01836       /* See if we have to do anything to INSN now that VAR is in
01837    memory.  If it needs to be loaded into a pseudo, use a single
01838    pseudo for the entire insn in case there is a MATCH_DUP
01839    between two operands.  We pass a pointer to the head of
01840    a list of struct fixup_replacements.  If fixup_var_refs_1
01841    needs to allocate pseudos or replacement MEMs (for SUBREGs),
01842    it will record them in this list.
01843 
01844    If it allocated a pseudo for any replacement, we copy into
01845    it here.  */
01846 
01847       fixup_var_refs_1 (var, promoted_mode, &PATTERN (insn), insn,
01848       &replacements, no_share);
01849 
01850       /* If this is last_parm_insn, and any instructions were output
01851    after it to fix it up, then we must set last_parm_insn to
01852    the last such instruction emitted.  */
01853       if (insn == last_parm_insn)
01854   last_parm_insn = PREV_INSN (next_insn);
01855 
01856       while (replacements)
01857   {
01858     struct fixup_replacement *next;
01859 
01860     if (GET_CODE (replacements->new) == REG)
01861       {
01862         rtx insert_before;
01863         rtx seq;
01864 
01865         /* OLD might be a (subreg (mem)).  */
01866         if (GET_CODE (replacements->old) == SUBREG)
01867     replacements->old
01868       = fixup_memory_subreg (replacements->old, insn,
01869            promoted_mode, 0);
01870         else
01871     replacements->old
01872       = fixup_stack_1 (replacements->old, insn);
01873 
01874         insert_before = insn;
01875 
01876         /* If we are changing the mode, do a conversion.
01877      This might be wasteful, but combine.c will
01878      eliminate much of the waste.  */
01879 
01880         if (GET_MODE (replacements->new)
01881       != GET_MODE (replacements->old))
01882     {
01883       start_sequence ();
01884       convert_move (replacements->new,
01885         replacements->old, unsignedp);
01886       seq = get_insns ();
01887       end_sequence ();
01888     }
01889         else
01890     seq = gen_move_insn (replacements->new,
01891              replacements->old);
01892 
01893         emit_insn_before (seq, insert_before);
01894       }
01895 
01896     next = replacements->next;
01897     free (replacements);
01898     replacements = next;
01899   }
01900     }
01901 
01902   /* Also fix up any invalid exprs in the REG_NOTES of this insn.
01903      But don't touch other insns referred to by reg-notes;
01904      we will get them elsewhere.  */
01905   while (note)
01906     {
01907       if (GET_CODE (note) != INSN_LIST)
01908   XEXP (note, 0)
01909     = walk_fixup_memory_subreg (XEXP (note, 0), insn,
01910               promoted_mode, 1);
01911       note = XEXP (note, 1);
01912     }
01913 }
01914 
01915 /* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
01916    See if the rtx expression at *LOC in INSN needs to be changed.
01917 
01918    REPLACEMENTS is a pointer to a list head that starts out zero, but may
01919    contain a list of original rtx's and replacements. If we find that we need
01920    to modify this insn by replacing a memory reference with a pseudo or by
01921    making a new MEM to implement a SUBREG, we consult that list to see if
01922    we have already chosen a replacement. If none has already been allocated,
01923    we allocate it and update the list.  fixup_var_refs_insn will copy VAR
01924    or the SUBREG, as appropriate, to the pseudo.  */
01925 
01926 static void
01927 fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
01928      rtx var;
01929      enum machine_mode promoted_mode;
01930      rtx *loc;
01931      rtx insn;
01932      struct fixup_replacement **replacements;
01933      rtx no_share;
01934 {
01935   int i;
01936   rtx x = *loc;
01937   RTX_CODE code = GET_CODE (x);
01938   const char *fmt;
01939   rtx tem, tem1;
01940   struct fixup_replacement *replacement;
01941 
01942   switch (code)
01943     {
01944     case ADDRESSOF:
01945       if (XEXP (x, 0) == var)
01946   {
01947     /* Prevent sharing of rtl that might lose.  */
01948     rtx sub = copy_rtx (XEXP (var, 0));
01949 
01950     if (! validate_change (insn, loc, sub, 0))
01951       {
01952         rtx y = gen_reg_rtx (GET_MODE (sub));
01953         rtx seq, new_insn;
01954 
01955         /* We should be able to replace with a register or all is lost.
01956      Note that we can't use validate_change to verify this, since
01957      we're not caring for replacing all dups simultaneously.  */
01958         if (! validate_replace_rtx (*loc, y, insn))
01959     abort ();
01960 
01961         /* Careful!  First try to recognize a direct move of the
01962      value, mimicking how things are done in gen_reload wrt
01963      PLUS.  Consider what happens when insn is a conditional
01964      move instruction and addsi3 clobbers flags.  */
01965 
01966         start_sequence ();
01967         new_insn = emit_insn (gen_rtx_SET (VOIDmode, y, sub));
01968         seq = get_insns ();
01969         end_sequence ();
01970 
01971         if (recog_memoized (new_insn) < 0)
01972     {
01973       /* That failed.  Fall back on force_operand and hope.  */
01974 
01975       start_sequence ();
01976       sub = force_operand (sub, y);
01977       if (sub != y)
01978         emit_insn (gen_move_insn (y, sub));
01979       seq = get_insns ();
01980       end_sequence ();
01981     }
01982 
01983 #ifdef HAVE_cc0
01984         /* Don't separate setter from user.  */
01985         if (PREV_INSN (insn) && sets_cc0_p (PREV_INSN (insn)))
01986     insn = PREV_INSN (insn);
01987 #endif
01988 
01989         emit_insn_before (seq, insn);
01990       }
01991   }
01992       return;
01993 
01994     case MEM:
01995       if (var == x)
01996   {
01997     /* If we already have a replacement, use it.  Otherwise,
01998        try to fix up this address in case it is invalid.  */
01999 
02000     replacement = find_fixup_replacement (replacements, var);
02001     if (replacement->new)
02002       {
02003         *loc = replacement->new;
02004         return;
02005       }
02006 
02007     *loc = replacement->new = x = fixup_stack_1 (x, insn);
02008 
02009     /* Unless we are forcing memory to register or we changed the mode,
02010        we can leave things the way they are if the insn is valid.  */
02011 
02012     INSN_CODE (insn) = -1;
02013     if (! flag_force_mem && GET_MODE (x) == promoted_mode
02014         && recog_memoized (insn) >= 0)
02015       return;
02016 
02017     *loc = replacement->new = gen_reg_rtx (promoted_mode);
02018     return;
02019   }
02020 
02021       /* If X contains VAR, we need to unshare it here so that we update
02022    each occurrence separately.  But all identical MEMs in one insn
02023    must be replaced with the same rtx because of the possibility of
02024    MATCH_DUPs.  */
02025 
02026       if (reg_mentioned_p (var, x))
02027   {
02028     replacement = find_fixup_replacement (replacements, x);
02029     if (replacement->new == 0)
02030       replacement->new = copy_most_rtx (x, no_share);
02031 
02032     *loc = x = replacement->new;
02033     code = GET_CODE (x);
02034   }
02035       break;
02036 
02037     case REG:
02038     case CC0:
02039     case PC:
02040     case CONST_INT:
02041     case CONST:
02042     case SYMBOL_REF:
02043     case LABEL_REF:
02044     case CONST_DOUBLE:
02045     case CONST_VECTOR:
02046       return;
02047 
02048     case SIGN_EXTRACT:
02049     case ZERO_EXTRACT:
02050       /* Note that in some cases those types of expressions are altered
02051    by optimize_bit_field, and do not survive to get here.  */
02052       if (XEXP (x, 0) == var
02053     || (GET_CODE (XEXP (x, 0)) == SUBREG
02054         && SUBREG_REG (XEXP (x, 0)) == var))
02055   {
02056     /* Get TEM as a valid MEM in the mode presently in the insn.
02057 
02058        We don't worry about the possibility of MATCH_DUP here; it
02059        is highly unlikely and would be tricky to handle.  */
02060 
02061     tem = XEXP (x, 0);
02062     if (GET_CODE (tem) == SUBREG)
02063       {
02064         if (GET_MODE_BITSIZE (GET_MODE (tem))
02065       > GET_MODE_BITSIZE (GET_MODE (var)))
02066     {
02067       replacement = find_fixup_replacement (replacements, var);
02068       if (replacement->new == 0)
02069         replacement->new = gen_reg_rtx (GET_MODE (var));
02070       SUBREG_REG (tem) = replacement->new;
02071 
02072       /* The following code works only if we have a MEM, so we
02073          need to handle the subreg here.  We directly substitute
02074          it assuming that a subreg must be OK here.  We already
02075          scheduled a replacement to copy the mem into the
02076          subreg.  */
02077       XEXP (x, 0) = tem;
02078       return;
02079     }
02080         else
02081     tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
02082       }
02083     else
02084       tem = fixup_stack_1 (tem, insn);
02085 
02086     /* Unless we want to load from memory, get TEM into the proper mode
02087        for an extract from memory.  This can only be done if the
02088        extract is at a constant position and length.  */
02089 
02090     if (! flag_force_mem && GET_CODE (XEXP (x, 1)) == CONST_INT
02091         && GET_CODE (XEXP (x, 2)) == CONST_INT
02092         && ! mode_dependent_address_p (XEXP (tem, 0))
02093         && ! MEM_VOLATILE_P (tem))
02094       {
02095         enum machine_mode wanted_mode = VOIDmode;
02096         enum machine_mode is_mode = GET_MODE (tem);
02097         HOST_WIDE_INT pos = INTVAL (XEXP (x, 2));
02098 
02099         if (GET_CODE (x) == ZERO_EXTRACT)
02100     {
02101       enum machine_mode new_mode
02102         = mode_for_extraction (EP_extzv, 1);
02103       if (new_mode != MAX_MACHINE_MODE)
02104         wanted_mode = new_mode;
02105     }
02106         else if (GET_CODE (x) == SIGN_EXTRACT)
02107     {
02108       enum machine_mode new_mode
02109         = mode_for_extraction (EP_extv, 1);
02110       if (new_mode != MAX_MACHINE_MODE)
02111         wanted_mode = new_mode;
02112     }
02113 
02114         /* If we have a narrower mode, we can do something.  */
02115         if (wanted_mode != VOIDmode
02116       && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
02117     {
02118       HOST_WIDE_INT offset = pos / BITS_PER_UNIT;
02119       rtx old_pos = XEXP (x, 2);
02120       rtx newmem;
02121 
02122       /* If the bytes and bits are counted differently, we
02123          must adjust the offset.  */
02124       if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
02125         offset = (GET_MODE_SIZE (is_mode)
02126             - GET_MODE_SIZE (wanted_mode) - offset);
02127 
02128       pos %= GET_MODE_BITSIZE (wanted_mode);
02129 
02130       newmem = adjust_address_nv (tem, wanted_mode, offset);
02131 
02132       /* Make the change and see if the insn remains valid.  */
02133       INSN_CODE (insn) = -1;
02134       XEXP (x, 0) = newmem;
02135       XEXP (x, 2) = GEN_INT (pos);
02136 
02137       if (recog_memoized (insn) >= 0)
02138         return;
02139 
02140       /* Otherwise, restore old position.  XEXP (x, 0) will be
02141          restored later.  */
02142       XEXP (x, 2) = old_pos;
02143     }
02144       }
02145 
02146     /* If we get here, the bitfield extract insn can't accept a memory
02147        reference.  Copy the input into a register.  */
02148 
02149     tem1 = gen_reg_rtx (GET_MODE (tem));
02150     emit_insn_before (gen_move_insn (tem1, tem), insn);
02151     XEXP (x, 0) = tem1;
02152     return;
02153   }
02154       break;
02155 
02156     case SUBREG:
02157       if (SUBREG_REG (x) == var)
02158   {
02159     /* If this is a special SUBREG made because VAR was promoted
02160        from a wider mode, replace it with VAR and call ourself
02161        recursively, this time saying that the object previously
02162        had its current mode (by virtue of the SUBREG).  */
02163 
02164     if (SUBREG_PROMOTED_VAR_P (x))
02165       {
02166         *loc = var;
02167         fixup_var_refs_1 (var, GET_MODE (var), loc, insn, replacements,
02168         no_share);
02169         return;
02170       }
02171 
02172     /* If this SUBREG makes VAR wider, it has become a paradoxical
02173        SUBREG with VAR in memory, but these aren't allowed at this
02174        stage of the compilation.  So load VAR into a pseudo and take
02175        a SUBREG of that pseudo.  */
02176     if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (var)))
02177       {
02178         replacement = find_fixup_replacement (replacements, var);
02179         if (replacement->new == 0)
02180     replacement->new = gen_reg_rtx (promoted_mode);
02181         SUBREG_REG (x) = replacement->new;
02182         return;
02183       }
02184 
02185     /* See if we have already found a replacement for this SUBREG.
02186        If so, use it.  Otherwise, make a MEM and see if the insn
02187        is recognized.  If not, or if we should force MEM into a register,
02188        make a pseudo for this SUBREG.  */
02189     replacement = find_fixup_replacement (replacements, x);
02190     if (replacement->new)
02191       {
02192         *loc = replacement->new;
02193         return;
02194       }
02195 
02196     replacement->new = *loc = fixup_memory_subreg (x, insn,
02197                promoted_mode, 0);
02198 
02199     INSN_CODE (insn) = -1;
02200     if (! flag_force_mem && recog_memoized (insn) >= 0)
02201       return;
02202 
02203     *loc = replacement->new = gen_reg_rtx (GET_MODE (x));
02204     return;
02205   }
02206       break;
02207 
02208     case SET:
02209       /* First do special simplification of bit-field references.  */
02210       if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
02211     || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
02212   optimize_bit_field (x, insn, 0);
02213       if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
02214     || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
02215   optimize_bit_field (x, insn, 0);
02216 
02217       /* For a paradoxical SUBREG inside a ZERO_EXTRACT, load the object
02218    into a register and then store it back out.  */
02219       if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
02220     && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG
02221     && SUBREG_REG (XEXP (SET_DEST (x), 0)) == var
02222     && (GET_MODE_SIZE (GET_MODE (XEXP (SET_DEST (x), 0)))
02223         > GET_MODE_SIZE (GET_MODE (var))))
02224   {
02225     replacement = find_fixup_replacement (replacements, var);
02226     if (replacement->new == 0)
02227       replacement->new = gen_reg_rtx (GET_MODE (var));
02228 
02229     SUBREG_REG (XEXP (SET_DEST (x), 0)) = replacement->new;
02230     emit_insn_after (gen_move_insn (var, replacement->new), insn);
02231   }
02232 
02233       /* If SET_DEST is now a paradoxical SUBREG, put the result of this
02234    insn into a pseudo and store the low part of the pseudo into VAR.  */
02235       if (GET_CODE (SET_DEST (x)) == SUBREG
02236     && SUBREG_REG (SET_DEST (x)) == var
02237     && (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
02238         > GET_MODE_SIZE (GET_MODE (var))))
02239   {
02240     SET_DEST (x) = tem = gen_reg_rtx (GET_MODE (SET_DEST (x)));
02241     emit_insn_after (gen_move_insn (var, gen_lowpart (GET_MODE (var),
02242                   tem)),
02243          insn);
02244     break;
02245   }
02246 
02247       {
02248   rtx dest = SET_DEST (x);
02249   rtx src = SET_SRC (x);
02250   rtx outerdest = dest;
02251 
02252   while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
02253          || GET_CODE (dest) == SIGN_EXTRACT
02254          || GET_CODE (dest) == ZERO_EXTRACT)
02255     dest = XEXP (dest, 0);
02256 
02257   if (GET_CODE (src) == SUBREG)
02258     src = SUBREG_REG (src);
02259 
02260   /* If VAR does not appear at the top level of the SET
02261      just scan the lower levels of the tree.  */
02262 
02263   if (src != var && dest != var)
02264     break;
02265 
02266   /* We will need to rerecognize this insn.  */
02267   INSN_CODE (insn) = -1;
02268 
02269   if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var
02270       && mode_for_extraction (EP_insv, -1) != MAX_MACHINE_MODE)
02271     {
02272       /* Since this case will return, ensure we fixup all the
02273          operands here.  */
02274       fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 1),
02275             insn, replacements, no_share);
02276       fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 2),
02277             insn, replacements, no_share);
02278       fixup_var_refs_1 (var, promoted_mode, &SET_SRC (x),
02279             insn, replacements, no_share);
02280 
02281       tem = XEXP (outerdest, 0);
02282 
02283       /* Clean up (SUBREG:SI (MEM:mode ...) 0)
02284          that may appear inside a ZERO_EXTRACT.
02285          This was legitimate when the MEM was a REG.  */
02286       if (GET_CODE (tem) == SUBREG
02287     && SUBREG_REG (tem) == var)
02288         tem = fixup_memory_subreg (tem, insn, promoted_mode, 0);
02289       else
02290         tem = fixup_stack_1 (tem, insn);
02291 
02292       if (GET_CODE (XEXP (outerdest, 1)) == CONST_INT
02293     && GET_CODE (XEXP (outerdest, 2)) == CONST_INT
02294     && ! mode_dependent_address_p (XEXP (tem, 0))
02295     && ! MEM_VOLATILE_P (tem))
02296         {
02297     enum machine_mode wanted_mode;
02298     enum machine_mode is_mode = GET_MODE (tem);
02299     HOST_WIDE_INT pos = INTVAL (XEXP (outerdest, 2));
02300 
02301     wanted_mode = mode_for_extraction (EP_insv, 0);
02302 
02303     /* If we have a narrower mode, we can do something.  */
02304     if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
02305       {
02306         HOST_WIDE_INT offset = pos / BITS_PER_UNIT;
02307         rtx old_pos = XEXP (outerdest, 2);
02308         rtx newmem;
02309 
02310         if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
02311           offset = (GET_MODE_SIZE (is_mode)
02312         - GET_MODE_SIZE (wanted_mode) - offset);
02313 
02314         pos %= GET_MODE_BITSIZE (wanted_mode);
02315 
02316         newmem = adjust_address_nv (tem, wanted_mode, offset);
02317 
02318         /* Make the change and see if the insn remains valid.  */
02319         INSN_CODE (insn) = -1;
02320         XEXP (outerdest, 0) = newmem;
02321         XEXP (outerdest, 2) = GEN_INT (pos);
02322 
02323         if (recog_memoized (insn) >= 0)
02324           return;
02325 
02326         /* Otherwise, restore old position.  XEXP (x, 0) will be
02327            restored later.  */
02328         XEXP (outerdest, 2) = old_pos;
02329       }
02330         }
02331 
02332       /* If we get here, the bit-field store doesn't allow memory
02333          or isn't located at a constant position.  Load the value into
02334          a register, do the store, and put it back into memory.  */
02335 
02336       tem1 = gen_reg_rtx (GET_MODE (tem));
02337       emit_insn_before (gen_move_insn (tem1, tem), insn);
02338       emit_insn_after (gen_move_insn (tem, tem1), insn);
02339       XEXP (outerdest, 0) = tem1;
02340       return;
02341     }
02342 
02343   /* STRICT_LOW_PART is a no-op on memory references
02344      and it can cause combinations to be unrecognizable,
02345      so eliminate it.  */
02346 
02347   if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
02348     SET_DEST (x) = XEXP (SET_DEST (x), 0);
02349 
02350   /* A valid insn to copy VAR into or out of a register
02351      must be left alone, to avoid an infinite loop here.
02352      If the reference to VAR is by a subreg, fix that up,
02353      since SUBREG is not valid for a memref.
02354      Also fix up the address of the stack slot.
02355 
02356      Note that we must not try to recognize the insn until
02357      after we know that we have valid addresses and no
02358      (subreg (mem ...) ...) constructs, since these interfere
02359      with determining the validity of the insn.  */
02360 
02361   if ((SET_SRC (x) == var
02362        || (GET_CODE (SET_SRC (x)) == SUBREG
02363      && SUBREG_REG (SET_SRC (x)) == var))
02364       && (GET_CODE (SET_DEST (x)) == REG
02365     || (GET_CODE (SET_DEST (x)) == SUBREG
02366         && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
02367       && GET_MODE (var) == promoted_mode
02368       && x == single_set (insn))
02369     {
02370       rtx pat, last;
02371 
02372       if (GET_CODE (SET_SRC (x)) == SUBREG
02373     && (GET_MODE_SIZE (GET_MODE (SET_SRC (x)))
02374         > GET_MODE_SIZE (GET_MODE (var))))
02375         {
02376     /* This (subreg VAR) is now a paradoxical subreg.  We need
02377        to replace VAR instead of the subreg.  */
02378     replacement = find_fixup_replacement (replacements, var);
02379     if (replacement->new == NULL_RTX)
02380       replacement->new = gen_reg_rtx (GET_MODE (var));
02381     SUBREG_REG (SET_SRC (x)) = replacement->new;
02382         }
02383       else
02384         {
02385     replacement = find_fixup_replacement (replacements, SET_SRC (x));
02386     if (replacement->new)
02387       SET_SRC (x) = replacement->new;
02388     else if (GET_CODE (SET_SRC (x)) == SUBREG)
02389       SET_SRC (x) = replacement->new
02390         = fixup_memory_subreg (SET_SRC (x), insn, promoted_mode,
02391              0);
02392     else
02393       SET_SRC (x) = replacement->new
02394         = fixup_stack_1 (SET_SRC (x), insn);
02395         }
02396 
02397       if (recog_memoized (insn) >= 0)
02398         return;
02399 
02400       /* INSN is not valid, but we know that we want to
02401          copy SET_SRC (x) to SET_DEST (x) in some way.  So
02402          we generate the move and see whether it requires more
02403          than one insn.  If it does, we emit those insns and
02404          delete INSN.  Otherwise, we can just replace the pattern
02405          of INSN; we have already verified above that INSN has
02406          no other function that to do X.  */
02407 
02408       pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
02409       if (NEXT_INSN (pat) != NULL_RTX)
02410         {
02411     last = emit_insn_before (pat, insn);
02412 
02413     /* INSN might have REG_RETVAL or other important notes, so
02414        we need to store the pattern of the last insn in the
02415        sequence into INSN similarly to the normal case.  LAST
02416        should not have REG_NOTES, but we allow them if INSN has
02417        no REG_NOTES.  */
02418     if (REG_NOTES (last) && REG_NOTES (insn))
02419       abort ();
02420     if (REG_NOTES (last))
02421       REG_NOTES (insn) = REG_NOTES (last);
02422     PATTERN (insn) = PATTERN (last);
02423 
02424     delete_insn (last);
02425         }
02426       else
02427         PATTERN (insn) = PATTERN (pat);
02428 
02429       return;
02430     }
02431 
02432   if ((SET_DEST (x) == var
02433        || (GET_CODE (SET_DEST (x)) == SUBREG
02434      && SUBREG_REG (SET_DEST (x)) == var))
02435       && (GET_CODE (SET_SRC (x)) == REG
02436     || (GET_CODE (SET_SRC (x)) == SUBREG
02437         && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG))
02438       && GET_MODE (var) == promoted_mode
02439       && x == single_set (insn))
02440     {
02441       rtx pat, last;
02442 
02443       if (GET_CODE (SET_DEST (x)) == SUBREG)
02444         SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn,
02445               promoted_mode, 0);
02446       else
02447         SET_DEST (x) = fixup_stack_1 (SET_DEST (x), insn);
02448 
02449       if (recog_memoized (insn) >= 0)
02450         return;
02451 
02452       pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
02453       if (NEXT_INSN (pat) != NULL_RTX)
02454         {
02455     last = emit_insn_before (pat, insn);
02456 
02457     /* INSN might have REG_RETVAL or other important notes, so
02458        we need to store the pattern of the last insn in the
02459        sequence into INSN similarly to the normal case.  LAST
02460        should not have REG_NOTES, but we allow them if INSN has
02461        no REG_NOTES.  */
02462     if (REG_NOTES (last) && REG_NOTES (insn))
02463       abort ();
02464     if (REG_NOTES (last))
02465       REG_NOTES (insn) = REG_NOTES (last);
02466     PATTERN (insn) = PATTERN (last);
02467 
02468     delete_insn (last);
02469         }
02470       else
02471         PATTERN (insn) = PATTERN (pat);
02472 
02473       return;
02474     }
02475 
02476   /* Otherwise, storing into VAR must be handled specially
02477      by storing into a temporary and copying that into VAR
02478      with a new insn after this one.  Note that this case
02479      will be used when storing into a promoted scalar since
02480      the insn will now have different modes on the input
02481      and output and hence will be invalid (except for the case
02482      of setting it to a constant, which does not need any
02483      change if it is valid).  We generate extra code in that case,
02484      but combine.c will eliminate it.  */
02485 
02486   if (dest == var)
02487     {
02488       rtx temp;
02489       rtx fixeddest = SET_DEST (x);
02490       enum machine_mode temp_mode;
02491 
02492       /* STRICT_LOW_PART can be discarded, around a MEM.  */
02493       if (GET_CODE (fixeddest) == STRICT_LOW_PART)
02494         fixeddest = XEXP (fixeddest, 0);
02495       /* Convert (SUBREG (MEM)) to a MEM in a changed mode.  */
02496       if (GET_CODE (fixeddest) == SUBREG)
02497         {
02498     fixeddest = fixup_memory_subreg (fixeddest, insn,
02499              promoted_mode, 0);
02500     temp_mode = GET_MODE (fixeddest);
02501         }
02502       else
02503         {
02504     fixeddest = fixup_stack_1 (fixeddest, insn);
02505     temp_mode = promoted_mode;
02506         }
02507 
02508       temp = gen_reg_rtx (temp_mode);
02509 
02510       emit_insn_after (gen_move_insn (fixeddest,
02511               gen_lowpart (GET_MODE (fixeddest),
02512                temp)),
02513            insn);
02514 
02515       SET_DEST (x) = temp;
02516     }
02517       }
02518 
02519     default:
02520       break;
02521     }
02522 
02523   /* Nothing special about this RTX; fix its operands.  */
02524 
02525   fmt = GET_RTX_FORMAT (code);
02526   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02527     {
02528       if (fmt[i] == 'e')
02529   fixup_var_refs_1 (var, promoted_mode, &XEXP (x, i), insn, replacements,
02530         no_share);
02531       else if (fmt[i] == 'E')
02532   {
02533     int j;
02534     for (j = 0; j < XVECLEN (x, i); j++)
02535       fixup_var_refs_1 (var, promoted_mode, &XVECEXP (x, i, j),
02536             insn, replacements, no_share);
02537   }
02538     }
02539 }
02540 
02541 /* Previously, X had the form (SUBREG:m1 (REG:PROMOTED_MODE ...)).
02542    The REG  was placed on the stack, so X now has the form (SUBREG:m1
02543    (MEM:m2 ...)).
02544 
02545    Return an rtx (MEM:m1 newaddr) which is equivalent.  If any insns
02546    must be emitted to compute NEWADDR, put them before INSN.
02547 
02548    UNCRITICAL nonzero means accept paradoxical subregs.
02549    This is used for subregs found inside REG_NOTES.  */
02550 
02551 static rtx
02552 fixup_memory_subreg (x, insn, promoted_mode, uncritical)
02553      rtx x;
02554      rtx insn;
02555      enum machine_mode promoted_mode;
02556      int uncritical;
02557 {
02558   int offset;
02559   rtx mem = SUBREG_REG (x);
02560   rtx addr = XEXP (mem, 0);
02561   enum machine_mode mode = GET_MODE (x);
02562   rtx result, seq;
02563 
02564   /* Paradoxical SUBREGs are usually invalid during RTL generation.  */
02565   if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (mem)) && ! uncritical)
02566     abort ();
02567 
02568   offset = SUBREG_BYTE (x);
02569   if (BYTES_BIG_ENDIAN)
02570     /* If the PROMOTED_MODE is wider than the mode of the MEM, adjust
02571        the offset so that it points to the right location within the
02572        MEM.  */
02573     offset -= (GET_MODE_SIZE (promoted_mode) - GET_MODE_SIZE (GET_MODE (mem)));
02574 
02575   if (!flag_force_addr
02576       && memory_address_p (mode, plus_constant (addr, offset)))
02577     /* Shortcut if no insns need be emitted.  */
02578     return adjust_address (mem, mode, offset);
02579 
02580   start_sequence ();
02581   result = adjust_address (mem, mode, offset);
02582   seq = get_insns ();
02583   end_sequence ();
02584 
02585   emit_insn_before (seq, insn);
02586   return result;
02587 }
02588 
02589 /* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
02590    Replace subexpressions of X in place.
02591    If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
02592    Otherwise return X, with its contents possibly altered.
02593 
02594    INSN, PROMOTED_MODE and UNCRITICAL are as for
02595    fixup_memory_subreg.  */
02596 
02597 static rtx
02598 walk_fixup_memory_subreg (x, insn, promoted_mode, uncritical)
02599      rtx x;
02600      rtx insn;
02601      enum machine_mode promoted_mode;
02602      int uncritical;
02603 {
02604   enum rtx_code code;
02605   const char *fmt;
02606   int i;
02607 
02608   if (x == 0)
02609     return 0;
02610 
02611   code = GET_CODE (x);
02612 
02613   if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
02614     return fixup_memory_subreg (x, insn, promoted_mode, uncritical);
02615 
02616   /* Nothing special about this RTX; fix its operands.  */
02617 
02618   fmt = GET_RTX_FORMAT (code);
02619   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02620     {
02621       if (fmt[i] == 'e')
02622   XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn,
02623             promoted_mode, uncritical);
02624       else if (fmt[i] == 'E')
02625   {
02626     int j;
02627     for (j = 0; j < XVECLEN (x, i); j++)
02628       XVECEXP (x, i, j)
02629         = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn,
02630             promoted_mode, uncritical);
02631   }
02632     }
02633   return x;
02634 }
02635 
02636 /* For each memory ref within X, if it refers to a stack slot
02637    with an out of range displacement, put the address in a temp register
02638    (emitting new insns before INSN to load these registers)
02639    and alter the memory ref to use that register.
02640    Replace each such MEM rtx with a copy, to avoid clobberage.  */
02641 
02642 static rtx
02643 fixup_stack_1 (x, insn)
02644      rtx x;
02645      rtx insn;
02646 {
02647   int i;
02648   RTX_CODE code = GET_CODE (x);
02649   const char *fmt;
02650 
02651   if (code == MEM)
02652     {
02653       rtx ad = XEXP (x, 0);
02654       /* If we have address of a stack slot but it's not valid
02655    (displacement is too large), compute the sum in a register.  */
02656       if (GET_CODE (ad) == PLUS
02657     && GET_CODE (XEXP (ad, 0)) == REG
02658     && ((REGNO (XEXP (ad, 0)) >= FIRST_VIRTUAL_REGISTER
02659          && REGNO (XEXP (ad, 0)) <= LAST_VIRTUAL_REGISTER)
02660         || REGNO (XEXP (ad, 0)) == FRAME_POINTER_REGNUM
02661 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
02662         || REGNO (XEXP (ad, 0)) == HARD_FRAME_POINTER_REGNUM
02663 #endif
02664         || REGNO (XEXP (ad, 0)) == STACK_POINTER_REGNUM
02665         || REGNO (XEXP (ad, 0)) == ARG_POINTER_REGNUM
02666         || XEXP (ad, 0) == current_function_internal_arg_pointer)
02667     && GET_CODE (XEXP (ad, 1)) == CONST_INT)
02668   {
02669     rtx temp, seq;
02670     if (memory_address_p (GET_MODE (x), ad))
02671       return x;
02672 
02673     start_sequence ();
02674     temp = copy_to_reg (ad);
02675     seq = get_insns ();
02676     end_sequence ();
02677     emit_insn_before (seq, insn);
02678     return replace_equiv_address (x, temp);
02679   }
02680       return x;
02681     }
02682 
02683   fmt = GET_RTX_FORMAT (code);
02684   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02685     {
02686       if (fmt[i] == 'e')
02687   XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
02688       else if (fmt[i] == 'E')
02689   {
02690     int j;
02691     for (j = 0; j < XVECLEN (x, i); j++)
02692       XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
02693   }
02694     }
02695   return x;
02696 }
02697 
02698 /* Optimization: a bit-field instruction whose field
02699    happens to be a byte or halfword in memory
02700    can be changed to a move instruction.
02701 
02702    We call here when INSN is an insn to examine or store into a bit-field.
02703    BODY is the SET-rtx to be altered.
02704 
02705    EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
02706    (Currently this is called only from function.c, and EQUIV_MEM
02707    is always 0.)  */
02708 
02709 static void
02710 optimize_bit_field (body, insn, equiv_mem)
02711      rtx body;
02712      rtx insn;
02713      rtx *equiv_mem;
02714 {
02715 #ifndef SGI_MONGOOSE
02716   rtx bitfield;
02717   int destflag;
02718   rtx seq = 0;
02719   enum machine_mode mode;
02720 
02721   if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
02722       || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
02723     bitfield = SET_DEST (body), destflag = 1;
02724   else
02725     bitfield = SET_SRC (body), destflag = 0;
02726 
02727   /* First check that the field being stored has constant size and position
02728      and is in fact a byte or halfword suitably aligned.  */
02729 
02730   if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
02731       && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
02732       && ((mode = mode_for_size (INTVAL (XEXP (bitfield, 1)), MODE_INT, 1))
02733     != BLKmode)
02734       && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
02735     {
02736       rtx memref = 0;
02737 
02738       /* Now check that the containing word is memory, not a register,
02739    and that it is safe to change the machine mode.  */
02740 
02741       if (GET_CODE (XEXP (bitfield, 0)) == MEM)
02742   memref = XEXP (bitfield, 0);
02743       else if (GET_CODE (XEXP (bitfield, 0)) == REG
02744          && equiv_mem != 0)
02745   memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
02746       else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
02747          && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
02748   memref = SUBREG_REG (XEXP (bitfield, 0));
02749       else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
02750          && equiv_mem != 0
02751          && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
02752   memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];
02753 
02754       if (memref
02755     && ! mode_dependent_address_p (XEXP (memref, 0))
02756     && ! MEM_VOLATILE_P (memref))
02757   {
02758     /* Now adjust the address, first for any subreg'ing
02759        that we are now getting rid of,
02760        and then for which byte of the word is wanted.  */
02761 
02762     HOST_WIDE_INT offset = INTVAL (XEXP (bitfield, 2));
02763     rtx insns;
02764 
02765     /* Adjust OFFSET to count bits from low-address byte.  */
02766     if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
02767       offset = (GET_MODE_BITSIZE (GET_MODE (XEXP (bitfield, 0)))
02768           - offset - INTVAL (XEXP (bitfield, 1)));
02769 
02770     /* Adjust OFFSET to count bytes from low-address byte.  */
02771     offset /= BITS_PER_UNIT;
02772     if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
02773       {
02774         offset += (SUBREG_BYTE (XEXP (bitfield, 0))
02775        / UNITS_PER_WORD) * UNITS_PER_WORD;
02776         if (BYTES_BIG_ENDIAN)
02777     offset -= (MIN (UNITS_PER_WORD,
02778         GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
02779          - MIN (UNITS_PER_WORD,
02780           GET_MODE_SIZE (GET_MODE (memref))));
02781       }
02782 
02783     start_sequence ();
02784     memref = adjust_address (memref, mode, offset);
02785     insns = get_insns ();
02786     end_sequence ();
02787     emit_insn_before (insns, insn);
02788 
02789     /* Store this memory reference where
02790        we found the bit field reference.  */
02791 
02792     if (destflag)
02793       {
02794         validate_change (insn, &SET_DEST (body), memref, 1);
02795         if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
02796     {
02797       rtx src = SET_SRC (body);
02798       while (GET_CODE (src) == SUBREG
02799        && SUBREG_BYTE (src) == 0)
02800         src = SUBREG_REG (src);
02801       if (GET_MODE (src) != GET_MODE (memref))
02802         src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
02803       validate_change (insn, &SET_SRC (body), src, 1);
02804     }
02805         else if (GET_MODE (SET_SRC (body)) != VOIDmode
02806            && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
02807     /* This shouldn't happen because anything that didn't have
02808        one of these modes should have got converted explicitly
02809        and then referenced through a subreg.
02810        This is so because the original bit-field was
02811        handled by agg_mode and so its tree structure had
02812        the same mode that memref now has.  */
02813     abort ();
02814       }
02815     else
02816       {
02817         rtx dest = SET_DEST (body);
02818 
02819         while (GET_CODE (dest) == SUBREG
02820          && SUBREG_BYTE (dest) == 0
02821          && (GET_MODE_CLASS (GET_MODE (dest))
02822        == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest))))
02823          && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
02824        <= UNITS_PER_WORD))
02825     dest = SUBREG_REG (dest);
02826 
02827         validate_change (insn, &SET_DEST (body), dest, 1);
02828 
02829         if (GET_MODE (dest) == GET_MODE (memref))
02830     validate_change (insn, &SET_SRC (body), memref, 1);
02831         else
02832     {
02833       /* Convert the mem ref to the destination mode.  */
02834       rtx newreg = gen_reg_rtx (GET_MODE (dest));
02835 
02836       start_sequence ();
02837       convert_move (newreg, memref,
02838         GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
02839       seq = get_insns ();
02840       end_sequence ();
02841 
02842       validate_change (insn, &SET_SRC (body), newreg, 1);
02843     }
02844       }
02845 
02846     /* See if we can convert this extraction or insertion into
02847        a simple move insn.  We might not be able to do so if this
02848        was, for example, part of a PARALLEL.
02849 
02850        If we succeed, write out any needed conversions.  If we fail,
02851        it is hard to guess why we failed, so don't do anything
02852        special; just let the optimization be suppressed.  */
02853 
02854     if (apply_change_group () && seq)
02855       emit_insn_before (seq, insn);
02856   }
02857     }
02858 #endif /* SGI_MONGOOSE */
02859 }
02860 
02861 /* These routines are responsible for converting virtual register references
02862    to the actual hard register references once RTL generation is complete.
02863 
02864    The following four variables are used for communication between the
02865    routines.  They contain the offsets of the virtual registers from their
02866    respective hard registers.  */
02867 
02868 static int in_arg_offset;
02869 static int var_offset;
02870 static int dynamic_offset;
02871 static int out_arg_offset;
02872 static int cfa_offset;
02873 
02874 /* In most machines, the stack pointer register is equivalent to the bottom
02875    of the stack.  */
02876 
02877 #ifndef STACK_POINTER_OFFSET
02878 #define STACK_POINTER_OFFSET  0
02879 #endif
02880 
02881 /* If not defined, pick an appropriate default for the offset of dynamically
02882    allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
02883    REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE.  */
02884 
02885 #ifndef STACK_DYNAMIC_OFFSET
02886 
02887 /* The bottom of the stack points to the actual arguments.  If
02888    REG_PARM_STACK_SPACE is defined, this includes the space for the register
02889    parameters.  However, if OUTGOING_REG_PARM_STACK space is not defined,
02890    stack space for register parameters is not pushed by the caller, but
02891    rather part of the fixed stack areas and hence not included in
02892    `current_function_outgoing_args_size'.  Nevertheless, we must allow
02893    for it when allocating stack dynamic objects.  */
02894 
02895 #if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
02896 #define STACK_DYNAMIC_OFFSET(FNDECL)  \
02897 ((ACCUMULATE_OUTGOING_ARGS                  \
02898   ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\
02899  + (STACK_POINTER_OFFSET))                  \
02900 
02901 #else
02902 #define STACK_DYNAMIC_OFFSET(FNDECL)  \
02903 ((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0)       \
02904  + (STACK_POINTER_OFFSET))
02905 #endif
02906 #endif
02907 
02908 /* On most machines, the CFA coincides with the first incoming parm.  */
02909 
02910 #ifndef ARG_POINTER_CFA_OFFSET
02911 #define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
02912 #endif
02913 
02914 /* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just
02915    had its address taken.  DECL is the decl or SAVE_EXPR for the
02916    object stored in the register, for later use if we do need to force
02917    REG into the stack.  REG is overwritten by the MEM like in
02918    put_reg_into_stack.  RESCAN is true if previously emitted
02919    instructions must be rescanned and modified now that the REG has
02920    been transformed.  */
02921 
02922 rtx
02923 gen_mem_addressof (reg, decl, rescan)
02924      rtx reg;
02925      tree decl;
02926      int rescan;
02927 {
02928   rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)),
02929            REGNO (reg), decl);
02930 
02931   /* Calculate this before we start messing with decl's RTL.  */
02932   HOST_WIDE_INT set = decl ? get_alias_set (decl) : 0;
02933 
02934   /* If the original REG was a user-variable, then so is the REG whose
02935      address is being taken.  Likewise for unchanging.  */
02936   REG_USERVAR_P (XEXP (r, 0)) = REG_USERVAR_P (reg);
02937   RTX_UNCHANGING_P (XEXP (r, 0)) = RTX_UNCHANGING_P (reg);
02938 
02939   PUT_CODE (reg, MEM);
02940   MEM_ATTRS (reg) = 0;
02941   XEXP (reg, 0) = r;
02942 
02943   if (decl)
02944     {
02945       tree type = TREE_TYPE (decl);
02946       enum machine_mode decl_mode
02947   = (DECL_P (decl) ? DECL_MODE (decl) : TYPE_MODE (TREE_TYPE (decl)));
02948       rtx decl_rtl = (TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl)
02949           : DECL_RTL_IF_SET (decl));
02950 
02951       PUT_MODE (reg, decl_mode);
02952 
02953       /* Clear DECL_RTL momentarily so functions below will work
02954    properly, then set it again.  */
02955       if (DECL_P (decl) && decl_rtl == reg)
02956   SET_DECL_RTL (decl, 0);
02957 
02958       set_mem_attributes (reg, decl, 1);
02959       set_mem_alias_set (reg, set);
02960 
02961       if (DECL_P (decl) && decl_rtl == reg)
02962   SET_DECL_RTL (decl, reg);
02963 
02964       if (rescan 
02965     && (TREE_USED (decl) || (DECL_P (decl) && DECL_INITIAL (decl) != 0)))
02966   fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), reg, 0);
02967     }
02968   else if (rescan)
02969     fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);
02970 
02971   return reg;
02972 }
02973 
02974 /* If DECL has an RTL that is an ADDRESSOF rtx, put it into the stack.  */
02975 
02976 void
02977 flush_addressof (decl)
02978      tree decl;
02979 {
02980   if ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL)
02981       && DECL_RTL (decl) != 0
02982       && GET_CODE (DECL_RTL (decl)) == MEM
02983       && GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF
02984       && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == REG)
02985     put_addressof_into_stack (XEXP (DECL_RTL (decl), 0), 0);
02986 }
02987 
02988 /* Force the register pointed to by R, an ADDRESSOF rtx, into the stack.  */
02989 
02990 static void
02991 put_addressof_into_stack (r, ht)
02992      rtx r;
02993      htab_t ht;
02994 {
02995   tree decl, type;
02996   int volatile_p, used_p;
02997 
02998   rtx reg = XEXP (r, 0);
02999 
03000   if (GET_CODE (reg) != REG)
03001     abort ();
03002 
03003   decl = ADDRESSOF_DECL (r);
03004   if (decl)
03005     {
03006       type = TREE_TYPE (decl);
03007       volatile_p = (TREE_CODE (decl) != SAVE_EXPR
03008         && TREE_THIS_VOLATILE (decl));
03009       used_p = (TREE_USED (decl)
03010     || (DECL_P (decl) && DECL_INITIAL (decl) != 0));
03011     }
03012   else
03013     {
03014       type = NULL_TREE;
03015       volatile_p = 0;
03016       used_p = 1;
03017     }
03018 
03019   put_reg_into_stack (0, reg, type, GET_MODE (reg), GET_MODE (reg),
03020           volatile_p, ADDRESSOF_REGNO (r), used_p, ht);
03021 }
03022 
03023 /* List of replacements made below in purge_addressof_1 when creating
03024    bitfield insertions.  */
03025 static rtx purge_bitfield_addressof_replacements;
03026 
03027 /* List of replacements made below in purge_addressof_1 for patterns
03028    (MEM (ADDRESSOF (REG ...))).  The key of the list entry is the
03029    corresponding (ADDRESSOF (REG ...)) and value is a substitution for
03030    the all pattern.  List PURGE_BITFIELD_ADDRESSOF_REPLACEMENTS is not
03031    enough in complex cases, e.g. when some field values can be
03032    extracted by usage MEM with narrower mode.  */
03033 static rtx purge_addressof_replacements;
03034 
03035 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
03036    in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
03037    the stack.  If the function returns FALSE then the replacement could not
03038    be made.  */
03039 
03040 static bool
03041 purge_addressof_1 (loc, insn, force, store, ht)
03042      rtx *loc;
03043      rtx insn;
03044      int force, store;
03045      htab_t ht;
03046 {
03047   rtx x;
03048   RTX_CODE code;
03049   int i, j;
03050   const char *fmt;
03051   bool result = true;
03052 
03053   /* Re-start here to avoid recursion in common cases.  */
03054  restart:
03055 
03056   x = *loc;
03057   if (x == 0)
03058     return true;
03059 
03060   code = GET_CODE (x);
03061 
03062   /* If we don't return in any of the cases below, we will recurse inside
03063      the RTX, which will normally result in any ADDRESSOF being forced into
03064      memory.  */
03065   if (code == SET)
03066     {
03067       result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
03068       result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
03069       return result;
03070     }
03071   else if (code == ADDRESSOF)
03072     {
03073       rtx sub, insns;
03074 
03075       if (GET_CODE (XEXP (x, 0)) != MEM)
03076   put_addressof_into_stack (x, ht);
03077 
03078       /* We must create a copy of the rtx because it was created by
03079    overwriting a REG rtx which is always shared.  */
03080       sub = copy_rtx (XEXP (XEXP (x, 0), 0));
03081       if (validate_change (insn, loc, sub, 0)
03082     || validate_replace_rtx (x, sub, insn))
03083   return true;
03084 
03085       start_sequence ();
03086       sub = force_operand (sub, NULL_RTX);
03087       if (! validate_change (insn, loc, sub, 0)
03088     && ! validate_replace_rtx (x, sub, insn))
03089   abort ();
03090 
03091       insns = get_insns ();
03092       end_sequence ();
03093       emit_insn_before (insns, insn);
03094       return true;
03095     }
03096 
03097   else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
03098     {
03099       rtx sub = XEXP (XEXP (x, 0), 0);
03100 
03101       if (GET_CODE (sub) == MEM)
03102   sub = adjust_address_nv (sub, GET_MODE (x), 0);
03103       else if (GET_CODE (sub) == REG
03104          && (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
03105   ;
03106       else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
03107   {
03108     int size_x, size_sub;
03109 
03110     if (!insn)
03111       {
03112         /* When processing REG_NOTES look at the list of
03113      replacements done on the insn to find the register that X
03114      was replaced by.  */
03115         rtx tem;
03116 
03117         for (tem = purge_bitfield_addressof_replacements;
03118        tem != NULL_RTX;
03119        tem = XEXP (XEXP (tem, 1), 1))
03120     if (rtx_equal_p (x, XEXP (tem, 0)))
03121       {
03122         *loc = XEXP (XEXP (tem, 1), 0);
03123         return true;
03124       }
03125 
03126         /* See comment for purge_addressof_replacements.  */
03127         for (tem = purge_addressof_replacements;
03128        tem != NULL_RTX;
03129        tem = XEXP (XEXP (tem, 1), 1))
03130     if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
03131       {
03132         rtx z = XEXP (XEXP (tem, 1), 0);
03133 
03134         if (GET_MODE (x) == GET_MODE (z)
03135       || (GET_CODE (XEXP (XEXP (tem, 1), 0)) != REG
03136           && GET_CODE (XEXP (XEXP (tem, 1), 0)) != SUBREG))
03137           abort ();
03138 
03139         /* It can happen that the note may speak of things
03140            in a wider (or just different) mode than the
03141            code did.  This is especially true of
03142            REG_RETVAL.  */
03143 
03144         if (GET_CODE (z) == SUBREG && SUBREG_BYTE (z) == 0)
03145           z = SUBREG_REG (z);
03146 
03147         if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
03148       && (GET_MODE_SIZE (GET_MODE (x))
03149           > GET_MODE_SIZE (GET_MODE (z))))
03150           {
03151       /* This can occur as a result in invalid
03152          pointer casts, e.g. float f; ...
03153          *(long long int *)&f.
03154          ??? We could emit a warning here, but
03155          without a line number that wouldn't be
03156          very helpful.  */
03157       z = gen_rtx_SUBREG (GET_MODE (x), z, 0);
03158           }
03159         else
03160           z = gen_lowpart (GET_MODE (x), z);
03161 
03162         *loc = z;
03163         return true;
03164       }
03165 
03166         /* Sometimes we may not be able to find the replacement.  For
03167      example when the original insn was a MEM in a wider mode,
03168      and the note is part of a sign extension of a narrowed
03169      version of that MEM.  Gcc testcase compile/990829-1.c can
03170      generate an example of this situation.  Rather than complain
03171      we return false, which will prompt our caller to remove the
03172      offending note.  */
03173         return false;
03174       }
03175 
03176     size_x = GET_MODE_BITSIZE (GET_MODE (x));
03177     size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
03178 
03179     /* Do not frob unchanging MEMs.  If a later reference forces the
03180        pseudo to the stack, we can wind up with multiple writes to
03181        an unchanging memory, which is invalid.  */
03182     if (RTX_UNCHANGING_P (x) && size_x != size_sub)
03183       ;
03184 
03185     /* Don't even consider working with paradoxical subregs,
03186        or the moral equivalent seen here.  */
03187     else if (size_x <= size_sub
03188              && int_mode_for_mode (GET_MODE (sub)) != BLKmode)
03189       {
03190         /* Do a bitfield insertion to mirror what would happen
03191      in memory.  */
03192 
03193         rtx val, seq;
03194 
03195         if (store)
03196     {
03197       rtx p = PREV_INSN (insn);
03198 
03199       start_sequence ();
03200       val = gen_reg_rtx (GET_MODE (x));
03201       if (! validate_change (insn, loc, val, 0))
03202         {
03203           /* Discard the current sequence and put the
03204        ADDRESSOF on stack.  */
03205           end_sequence ();
03206           goto give_up;
03207         }
03208       seq = get_insns ();
03209       end_sequence ();
03210       emit_insn_before (seq, insn);
03211       compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
03212            insn, ht);
03213 
03214       start_sequence ();
03215       store_bit_field (sub, size_x, 0, GET_MODE (x),
03216            val, GET_MODE_SIZE (GET_MODE (sub)));
03217 
03218       /* Make sure to unshare any shared rtl that store_bit_field
03219          might have created.  */
03220       unshare_all_rtl_again (get_insns ());
03221 
03222       seq = get_insns ();
03223       end_sequence ();
03224       p = emit_insn_after (seq, insn);
03225       if (NEXT_INSN (insn))
03226         compute_insns_for_mem (NEXT_INSN (insn),
03227              p ? NEXT_INSN (p) : NULL_RTX,
03228              ht);
03229     }
03230         else
03231     {
03232       rtx p = PREV_INSN (insn);
03233 
03234       start_sequence ();
03235       val = extract_bit_field (sub, size_x, 0, 1, NULL_RTX,
03236              GET_MODE (x), GET_MODE (x),
03237              GET_MODE_SIZE (GET_MODE (sub)));
03238 
03239       if (! validate_change (insn, loc, val, 0))
03240         {
03241           /* Discard the current sequence and put the
03242        ADDRESSOF on stack.  */
03243           end_sequence ();
03244           goto give_up;
03245         }
03246 
03247       seq = get_insns ();
03248       end_sequence ();
03249       emit_insn_before (seq, insn);
03250       compute_insns_for_mem (p ? NEXT_INSN (p) : get_insns (),
03251            insn, ht);
03252     }
03253 
03254         /* Remember the replacement so that the same one can be done
03255      on the REG_NOTES.  */
03256         purge_bitfield_addressof_replacements
03257     = gen_rtx_EXPR_LIST (VOIDmode, x,
03258              gen_rtx_EXPR_LIST
03259              (VOIDmode, val,
03260               purge_bitfield_addressof_replacements));
03261 
03262         /* We replaced with a reg -- all done.  */
03263         return true;
03264       }
03265   }
03266 
03267       else if (validate_change (insn, loc, sub, 0))
03268   {
03269     /* Remember the replacement so that the same one can be done
03270        on the REG_NOTES.  */
03271     if (GET_CODE (sub) == REG || GET_CODE (sub) == SUBREG)
03272       {
03273         rtx tem;
03274 
03275         for (tem = purge_addressof_replacements;
03276        tem != NULL_RTX;
03277        tem = XEXP (XEXP (tem, 1), 1))
03278     if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
03279       {
03280         XEXP (XEXP (tem, 1), 0) = sub;
03281         return true;
03282       }
03283         purge_addressof_replacements
03284     = gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
03285          gen_rtx_EXPR_LIST (VOIDmode, sub,
03286                 purge_addressof_replacements));
03287         return true;
03288       }
03289     goto restart;
03290   }
03291     }
03292 
03293  give_up:
03294   /* Scan all subexpressions.  */
03295   fmt = GET_RTX_FORMAT (code);
03296   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
03297     {
03298       if (*fmt == 'e')
03299   result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
03300       else if (*fmt == 'E')
03301   for (j = 0; j < XVECLEN (x, i); j++)
03302     result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
03303     }
03304 
03305   return result;
03306 }
03307 
03308 /* Return a hash value for K, a REG.  */
03309 
03310 static hashval_t
03311 insns_for_mem_hash (k)
03312      const void * k;
03313 {
03314   /* Use the address of the key for the hash value.  */
03315   struct insns_for_mem_entry *m = (struct insns_for_mem_entry *) k;
03316   return htab_hash_pointer (m->key);
03317 }
03318 
03319 /* Return nonzero if K1 and K2 (two REGs) are the same.  */
03320 
03321 static int
03322 insns_for_mem_comp (k1, k2)
03323      const void * k1;
03324      const void * k2;
03325 {
03326   struct insns_for_mem_entry *m1 = (struct insns_for_mem_entry *) k1;
03327   struct insns_for_mem_entry *m2 = (struct insns_for_mem_entry *) k2;
03328   return m1->key == m2->key;
03329 }
03330 
03331 struct insns_for_mem_walk_info
03332 {
03333   /* The hash table that we are using to record which INSNs use which
03334      MEMs.  */
03335   htab_t ht;
03336 
03337   /* The INSN we are currently processing.  */
03338   rtx insn;
03339 
03340   /* Zero if we are walking to find ADDRESSOFs, one if we are walking
03341      to find the insns that use the REGs in the ADDRESSOFs.  */
03342   int pass;
03343 };
03344 
03345 /* Called from compute_insns_for_mem via for_each_rtx.  If R is a REG
03346    that might be used in an ADDRESSOF expression, record this INSN in
03347    the hash table given by DATA (which is really a pointer to an
03348    insns_for_mem_walk_info structure).  */
03349 
03350 static int
03351 insns_for_mem_walk (r, data)
03352      rtx *r;
03353      void *data;
03354 {
03355   struct insns_for_mem_walk_info *ifmwi
03356     = (struct insns_for_mem_walk_info *) data;
03357   struct insns_for_mem_entry tmp;
03358   tmp.insns = NULL_RTX;
03359 
03360   if (ifmwi->pass == 0 && *r && GET_CODE (*r) == ADDRESSOF
03361       && GET_CODE (XEXP (*r, 0)) == REG)
03362     {
03363       PTR *e;
03364       tmp.key = XEXP (*r, 0);
03365       e = htab_find_slot (ifmwi->ht, &tmp, INSERT);
03366       if (*e == NULL)
03367   {
03368     *e = ggc_alloc (sizeof (tmp));
03369     memcpy (*e, &tmp, sizeof (tmp));
03370   }
03371     }
03372   else if (ifmwi->pass == 1 && *r && GET_CODE (*r) == REG)
03373     {
03374       struct insns_for_mem_entry *ifme;
03375       tmp.key = *r;
03376       ifme = (struct insns_for_mem_entry *) htab_find (ifmwi->ht, &tmp);
03377 
03378       /* If we have not already recorded this INSN, do so now.  Since
03379    we process the INSNs in order, we know that if we have
03380    recorded it it must be at the front of the list.  */
03381       if (ifme && (!ifme->insns || XEXP (ifme->insns, 0) != ifmwi->insn))
03382   ifme->insns = gen_rtx_EXPR_LIST (VOIDmode, ifmwi->insn,
03383            ifme->insns);
03384     }
03385 
03386   return 0;
03387 }
03388 
03389 /* Walk the INSNS, until we reach LAST_INSN, recording which INSNs use
03390    which REGs in HT.  */
03391 
03392 static void
03393 compute_insns_for_mem (insns, last_insn, ht)
03394      rtx insns;
03395      rtx last_insn;
03396      htab_t ht;
03397 {
03398   rtx insn;
03399   struct insns_for_mem_walk_info ifmwi;
03400   ifmwi.ht = ht;
03401 
03402   for (ifmwi.pass = 0; ifmwi.pass < 2; ++ifmwi.pass)
03403     for (insn = insns; insn != last_insn; insn = NEXT_INSN (insn))
03404       if (INSN_P (insn))
03405   {
03406     ifmwi.insn = insn;
03407     for_each_rtx (&insn, insns_for_mem_walk, &ifmwi);
03408   }
03409 }
03410 
03411 /* Helper function for purge_addressof called through for_each_rtx.
03412    Returns true iff the rtl is an ADDRESSOF.  */
03413 
03414 static int
03415 is_addressof (rtl, data)
03416      rtx *rtl;
03417      void *data ATTRIBUTE_UNUSED;
03418 {
03419   return GET_CODE (*rtl) == ADDRESSOF;
03420 }
03421 
03422 /* Eliminate all occurrences of ADDRESSOF from INSNS.  Elide any remaining
03423    (MEM (ADDRESSOF)) patterns, and force any needed registers into the
03424    stack.  */
03425 
03426 void
03427 purge_addressof (insns)
03428      rtx insns;
03429 {
03430   rtx insn;
03431   htab_t ht;
03432 
03433   /* When we actually purge ADDRESSOFs, we turn REGs into MEMs.  That
03434      requires a fixup pass over the instruction stream to correct
03435      INSNs that depended on the REG being a REG, and not a MEM.  But,
03436      these fixup passes are slow.  Furthermore, most MEMs are not
03437      mentioned in very many instructions.  So, we speed up the process
03438      by pre-calculating which REGs occur in which INSNs; that allows
03439      us to perform the fixup passes much more quickly.  */
03440   ht = htab_create_ggc (1000, insns_for_mem_hash, insns_for_mem_comp, NULL);
03441   compute_insns_for_mem (insns, NULL_RTX, ht);
03442 
03443   for (insn = insns; insn; insn = NEXT_INSN (insn))
03444     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
03445   || GET_CODE (insn) == CALL_INSN)
03446       {
03447   if (! purge_addressof_1 (&PATTERN (insn), insn,
03448          asm_noperands (PATTERN (insn)) > 0, 0, ht))
03449     /* If we could not replace the ADDRESSOFs in the insn,
03450        something is wrong.  */
03451     abort ();
03452 
03453   if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, ht))
03454     {
03455       /* If we could not replace the ADDRESSOFs in the insn's notes,
03456          we can just remove the offending notes instead.  */
03457       rtx note;
03458 
03459       for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
03460         {
03461     /* If we find a REG_RETVAL note then the insn is a libcall.
03462        Such insns must have REG_EQUAL notes as well, in order
03463        for later passes of the compiler to work.  So it is not
03464        safe to delete the notes here, and instead we abort.  */
03465     if (REG_NOTE_KIND (note) == REG_RETVAL)
03466       abort ();
03467     if (for_each_rtx (&note, is_addressof, NULL))
03468       remove_note (insn, note);
03469         }
03470     }
03471       }
03472 
03473   /* Clean up.  */
03474   purge_bitfield_addressof_replacements = 0;
03475   purge_addressof_replacements = 0;
03476 
03477   /* REGs are shared.  purge_addressof will destructively replace a REG
03478      with a MEM, which creates shared MEMs.
03479 
03480      Unfortunately, the children of put_reg_into_stack assume that MEMs
03481      referring to the same stack slot are shared (fixup_var_refs and
03482      the associated hash table code).
03483 
03484      So, we have to do another unsharing pass after we have flushed any
03485      REGs that had their address taken into the stack.
03486 
03487      It may be worth tracking whether or not we converted any REGs into
03488      MEMs to avoid this overhead when it is not needed.  */
03489   unshare_all_rtl_again (get_insns ());
03490 }
03491 
03492 /* Convert a SET of a hard subreg to a set of the appropriate hard
03493    register.  A subroutine of purge_hard_subreg_sets.  */
03494 
03495 static void
03496 purge_single_hard_subreg_set (pattern)
03497      rtx pattern;
03498 {
03499   rtx reg = SET_DEST (pattern);
03500   enum machine_mode mode = GET_MODE (SET_DEST (pattern));
03501   int offset = 0;
03502 
03503   if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG
03504       && REGNO (SUBREG_REG (reg)) < FIRST_PSEUDO_REGISTER)
03505     {
03506       offset = subreg_regno_offset (REGNO (SUBREG_REG (reg)),
03507             GET_MODE (SUBREG_REG (reg)),
03508             SUBREG_BYTE (reg),
03509             GET_MODE (reg));
03510       reg = SUBREG_REG (reg);
03511     }
03512 
03513 
03514   if (GET_CODE (reg) == REG && REGNO (reg) < FIRST_PSEUDO_REGISTER)
03515     {
03516       reg = gen_rtx_REG (mode, REGNO (reg) + offset);
03517       SET_DEST (pattern) = reg;
03518     }
03519 }
03520 
03521 /* Eliminate all occurrences of SETs of hard subregs from INSNS.  The
03522    only such SETs that we expect to see are those left in because
03523    integrate can't handle sets of parts of a return value register.
03524 
03525    We don't use alter_subreg because we only want to eliminate subregs
03526    of hard registers.  */
03527 
03528 void
03529 purge_hard_subreg_sets (insn)
03530      rtx insn;
03531 {
03532   for (; insn; insn = NEXT_INSN (insn))
03533     {
03534       if (INSN_P (insn))
03535   {
03536     rtx pattern = PATTERN (insn);
03537     switch (GET_CODE (pattern))
03538       {
03539       case SET:
03540         if (GET_CODE (SET_DEST (pattern)) == SUBREG)
03541     purge_single_hard_subreg_set (pattern);
03542         break;
03543       case PARALLEL:
03544         {
03545     int j;
03546     for (j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
03547       {
03548         rtx inner_pattern = XVECEXP (pattern, 0, j);
03549         if (GET_CODE (inner_pattern) == SET
03550       && GET_CODE (SET_DEST (inner_pattern)) == SUBREG)
03551           purge_single_hard_subreg_set (inner_pattern);
03552       }
03553         }
03554         break;
03555       default:
03556         break;
03557       }
03558   }
03559     }
03560 }
03561 
03562 /* Pass through the INSNS of function FNDECL and convert virtual register
03563    references to hard register references.  */
03564 
03565 void
03566 instantiate_virtual_regs (fndecl, insns)
03567      tree fndecl;
03568      rtx insns;
03569 {
03570   rtx insn;
03571   unsigned int i;
03572 
03573   /* Compute the offsets to use for this function.  */
03574   in_arg_offset = FIRST_PARM_OFFSET (fndecl);
03575   var_offset = STARTING_FRAME_OFFSET;
03576   dynamic_offset = STACK_DYNAMIC_OFFSET (fndecl);
03577   out_arg_offset = STACK_POINTER_OFFSET;
03578   cfa_offset = ARG_POINTER_CFA_OFFSET (fndecl);
03579 
03580   /* Scan all variables and parameters of this function.  For each that is
03581      in memory, instantiate all virtual registers if the result is a valid
03582      address.  If not, we do it later.  That will handle most uses of virtual
03583      regs on many machines.  */
03584   instantiate_decls (fndecl, 1);
03585 
03586   /* Initialize recognition, indicating that volatile is OK.  */
03587   init_recog ();
03588 
03589   /* Scan through all the insns, instantiating every virtual register still
03590      present.  */
03591   for (insn = insns; insn; insn = NEXT_INSN (insn))
03592     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
03593   || GET_CODE (insn) == CALL_INSN)
03594       {
03595   instantiate_virtual_regs_1 (&PATTERN (insn), insn, 1);
03596   if (INSN_DELETED_P (insn))
03597     continue;
03598   instantiate_virtual_regs_1 (&REG_NOTES (insn), NULL_RTX, 0);
03599   /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE.  */
03600   if (GET_CODE (insn) == CALL_INSN)
03601     instantiate_virtual_regs_1 (&CALL_INSN_FUNCTION_USAGE (insn),
03602               NULL_RTX, 0);
03603 
03604   /* Past this point all ASM statements should match.  Verify that
03605      to avoid failures later in the compilation process.  */
03606         if (asm_noperands (PATTERN (insn)) >= 0
03607       && ! check_asm_operands (PATTERN (insn)))
03608           instantiate_virtual_regs_lossage (insn);
03609       }
03610 
03611   /* Instantiate the stack slots for the parm registers, for later use in
03612      addressof elimination.  */
03613   for (i = 0; i < max_parm_reg; ++i)
03614     if (parm_reg_stack_loc[i])
03615       instantiate_virtual_regs_1 (&parm_reg_stack_loc[i], NULL_RTX, 0);
03616 
03617   /* Now instantiate the remaining register equivalences for debugging info.
03618      These will not be valid addresses.  */
03619   instantiate_decls (fndecl, 0);
03620 
03621   /* Indicate that, from now on, assign_stack_local should use
03622      frame_pointer_rtx.  */
03623   virtuals_instantiated = 1;
03624 }
03625 
03626 /* Scan all decls in FNDECL (both variables and parameters) and instantiate
03627    all virtual registers in their DECL_RTL's.
03628 
03629    If VALID_ONLY, do this only if the resulting address is still valid.
03630    Otherwise, always do it.  */
03631 
03632 static void
03633 instantiate_decls (fndecl, valid_only)
03634      tree fndecl;
03635      int valid_only;
03636 {
03637   tree decl;
03638 
03639   /* Process all parameters of the function.  */
03640   for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
03641     {
03642       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
03643       HOST_WIDE_INT size_rtl;
03644 
03645       instantiate_decl (DECL_RTL (decl), size, valid_only);
03646 
03647       /* If the parameter was promoted, then the incoming RTL mode may be
03648    larger than the declared type size.  We must use the larger of
03649    the two sizes.  */
03650       size_rtl = GET_MODE_SIZE (GET_MODE (DECL_INCOMING_RTL (decl)));
03651       size = MAX (size_rtl, size);
03652       instantiate_decl (DECL_INCOMING_RTL (decl), size, valid_only);
03653     }
03654 
03655   /* Now process all variables defined in the function or its subblocks.  */
03656   instantiate_decls_1 (DECL_INITIAL (fndecl), valid_only);
03657 }
03658 
03659 /* Subroutine of instantiate_decls: Process all decls in the given
03660    BLOCK node and all its subblocks.  */
03661 
03662 static void
03663 instantiate_decls_1 (let, valid_only)
03664      tree let;
03665      int valid_only;
03666 {
03667   tree t;
03668 
03669   for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
03670     if (DECL_RTL_SET_P (t))
03671       instantiate_decl (DECL_RTL (t),
03672       int_size_in_bytes (TREE_TYPE (t)),
03673       valid_only);
03674 
03675   /* Process all subblocks.  */
03676   for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
03677     instantiate_decls_1 (t, valid_only);
03678 }
03679 
03680 /* Subroutine of the preceding procedures: Given RTL representing a
03681    decl and the size of the object, do any instantiation required.
03682 
03683    If VALID_ONLY is nonzero, it means that the RTL should only be
03684    changed if the new address is valid.  */
03685 
03686 static void
03687 instantiate_decl (x, size, valid_only)
03688      rtx x;
03689      HOST_WIDE_INT size;
03690      int valid_only;
03691 {
03692   enum machine_mode mode;
03693   rtx addr;
03694 
03695   /* If this is not a MEM, no need to do anything.  Similarly if the
03696      address is a constant or a register that is not a virtual register.  */
03697 
03698   if (x == 0 || GET_CODE (x) != MEM)
03699     return;
03700 
03701   addr = XEXP (x, 0);
03702   if (CONSTANT_P (addr)
03703       || (GET_CODE (addr) == ADDRESSOF && GET_CODE (XEXP (addr, 0)) == REG)
03704       || (GET_CODE (addr) == REG
03705     && (REGNO (addr) < FIRST_VIRTUAL_REGISTER
03706         || REGNO (addr) > LAST_VIRTUAL_REGISTER)))
03707     return;
03708 
03709   /* If we should only do this if the address is valid, copy the address.
03710      We need to do this so we can undo any changes that might make the
03711      address invalid.  This copy is unfortunate, but probably can't be
03712      avoided.  */
03713 
03714   if (valid_only)
03715     addr = copy_rtx (addr);
03716 
03717   instantiate_virtual_regs_1 (&addr, NULL_RTX, 0);
03718 
03719   if (valid_only && size >= 0)
03720     {
03721       unsigned HOST_WIDE_INT decl_size = size;
03722 
03723       /* Now verify that the resulting address is valid for every integer or
03724    floating-point mode up to and including SIZE bytes long.  We do this
03725    since the object might be accessed in any mode and frame addresses
03726    are shared.  */
03727 
03728       for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
03729      mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
03730      mode = GET_MODE_WIDER_MODE (mode))
03731   if (! memory_address_p (mode, addr))
03732     return;
03733 
03734       for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
03735      mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
03736      mode = GET_MODE_WIDER_MODE (mode))
03737   if (! memory_address_p (mode, addr))
03738     return;
03739     }
03740 
03741   /* Put back the address now that we have updated it and we either know
03742      it is valid or we don't care whether it is valid.  */
03743 
03744   XEXP (x, 0) = addr;
03745 }
03746 
03747 /* Given a piece of RTX and a pointer to a HOST_WIDE_INT, if the RTX
03748    is a virtual register, return the equivalent hard register and set the
03749    offset indirectly through the pointer.  Otherwise, return 0.  */
03750 
03751 static rtx
03752 instantiate_new_reg (x, poffset)
03753      rtx x;
03754      HOST_WIDE_INT *poffset;
03755 {
03756   rtx new;
03757   HOST_WIDE_INT offset;
03758 
03759   if (x == virtual_incoming_args_rtx)
03760     new = arg_pointer_rtx, offset = in_arg_offset;
03761   else if (x == virtual_stack_vars_rtx)
03762     new = frame_pointer_rtx, offset = var_offset;
03763   else if (x == virtual_stack_dynamic_rtx)
03764     new = stack_pointer_rtx, offset = dynamic_offset;
03765   else if (x == virtual_outgoing_args_rtx)
03766     new = stack_pointer_rtx, offset = out_arg_offset;
03767   else if (x == virtual_cfa_rtx)
03768     new = arg_pointer_rtx, offset = cfa_offset;
03769   else
03770     return 0;
03771 
03772   *poffset = offset;
03773   return new;
03774 }
03775 
03776 
03777 /* Called when instantiate_virtual_regs has failed to update the instruction.
03778    Usually this means that non-matching instruction has been emit, however for
03779    asm statements it may be the problem in the constraints.  */
03780 static void
03781 instantiate_virtual_regs_lossage (insn)
03782      rtx insn;
03783 {
03784   if (asm_noperands (PATTERN (insn)) >= 0)
03785     {
03786       error_for_asm (insn, "impossible constraint in `asm'");
03787       delete_insn (insn);
03788     }
03789   else
03790     abort ();
03791 }
03792 /* Given a pointer to a piece of rtx and an optional pointer to the
03793    containing object, instantiate any virtual registers present in it.
03794 
03795    If EXTRA_INSNS, we always do the replacement and generate
03796    any extra insns before OBJECT.  If it zero, we do nothing if replacement
03797    is not valid.
03798 
03799    Return 1 if we either had nothing to do or if we were able to do the
03800    needed replacement.  Return 0 otherwise; we only return zero if
03801    EXTRA_INSNS is zero.
03802 
03803    We first try some simple transformations to avoid the creation of extra
03804    pseudos.  */
03805 
03806 static int
03807 instantiate_virtual_regs_1 (loc, object, extra_insns)
03808      rtx *loc;
03809      rtx object;
03810      int extra_insns;
03811 {
03812   rtx x;
03813   RTX_CODE code;
03814   rtx new = 0;
03815   HOST_WIDE_INT offset = 0;
03816   rtx temp;
03817   rtx seq;
03818   int i, j;
03819   const char *fmt;
03820 
03821   /* Re-start here to avoid recursion in common cases.  */
03822  restart:
03823 
03824   x = *loc;
03825   if (x == 0)
03826     return 1;
03827 
03828   /* We may have detected and deleted invalid asm statements.  */
03829   if (object && INSN_P (object) && INSN_DELETED_P (object))
03830     return 1;
03831 
03832   code = GET_CODE (x);
03833 
03834   /* Check for some special cases.  */
03835   switch (code)
03836     {
03837     case CONST_INT:
03838     case CONST_DOUBLE:
03839     case CONST_VECTOR:
03840     case CONST:
03841     case SYMBOL_REF:
03842     case CODE_LABEL:
03843     case PC:
03844     case CC0:
03845     case ASM_INPUT:
03846     case ADDR_VEC:
03847     case ADDR_DIFF_VEC:
03848     case RETURN:
03849       return 1;
03850 
03851     case SET:
03852       /* We are allowed to set the virtual registers.  This means that
03853    the actual register should receive the source minus the
03854    appropriate offset.  This is used, for example, in the handling
03855    of non-local gotos.  */
03856       if ((new = instantiate_new_reg (SET_DEST (x), &offset)) != 0)
03857   {
03858     rtx src = SET_SRC (x);
03859 
03860     /* We are setting the register, not using it, so the relevant
03861        offset is the negative of the offset to use were we using
03862        the register.  */
03863     offset = - offset;
03864     instantiate_virtual_regs_1 (&src, NULL_RTX, 0);
03865 
03866     /* The only valid sources here are PLUS or REG.  Just do
03867        the simplest possible thing to handle them.  */
03868     if (GET_CODE (src) != REG && GET_CODE (src) != PLUS)
03869       {
03870         instantiate_virtual_regs_lossage (object);
03871         return 1;
03872       }
03873 
03874     start_sequence ();
03875     if (GET_CODE (src) != REG)
03876       temp = force_operand (src, NULL_RTX);
03877     else
03878       temp = src;
03879     temp = force_operand (plus_constant (temp, offset), NULL_RTX);
03880     seq = get_insns ();
03881     end_sequence ();
03882 
03883     emit_insn_before (seq, object);
03884     SET_DEST (x) = new;
03885 
03886     if (! validate_change (object, &SET_SRC (x), temp, 0)
03887         || ! extra_insns)
03888       instantiate_virtual_regs_lossage (object);
03889 
03890     return 1;
03891   }
03892 
03893       instantiate_virtual_regs_1 (&SET_DEST (x), object, extra_insns);
03894       loc = &SET_SRC (x);
03895       goto restart;
03896 
03897     case PLUS:
03898       /* Handle special case of virtual register plus constant.  */
03899       if (CONSTANT_P (XEXP (x, 1)))
03900   {
03901     rtx old, new_offset;
03902 
03903     /* Check for (plus (plus VIRT foo) (const_int)) first.  */
03904     if (GET_CODE (XEXP (x, 0)) == PLUS)
03905       {
03906         if ((new = instantiate_new_reg (XEXP (XEXP (x, 0), 0), &offset)))
03907     {
03908       instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 1), object,
03909                 extra_insns);
03910       new = gen_rtx_PLUS (Pmode, new, XEXP (XEXP (x, 0), 1));
03911     }
03912         else
03913     {
03914       loc = &XEXP (x, 0);
03915       goto restart;
03916     }
03917       }
03918 
03919 #ifdef POINTERS_EXTEND_UNSIGNED
03920     /* If we have (plus (subreg (virtual-reg)) (const_int)), we know
03921        we can commute the PLUS and SUBREG because pointers into the
03922        frame are well-behaved.  */
03923     else if (GET_CODE (XEXP (x, 0)) == SUBREG && GET_MODE (x) == ptr_mode
03924        && GET_CODE (XEXP (x, 1)) == CONST_INT
03925        && 0 != (new
03926           = instantiate_new_reg (SUBREG_REG (XEXP (x, 0)),
03927                &offset))
03928        && validate_change (object, loc,
03929                plus_constant (gen_lowpart (ptr_mode,
03930                    new),
03931                   offset
03932                   + INTVAL (XEXP (x, 1))),
03933                0))
03934     return 1;
03935 #endif
03936     else if ((new = instantiate_new_reg (XEXP (x, 0), &offset)) == 0)
03937       {
03938         /* We know the second operand is a constant.  Unless the
03939      first operand is a REG (which has been already checked),
03940      it needs to be checked.  */
03941         if (GET_CODE (XEXP (x, 0)) != REG)
03942     {
03943       loc = &XEXP (x, 0);
03944       goto restart;
03945     }
03946         return 1;
03947       }
03948 
03949     new_offset = plus_constant (XEXP (x, 1), offset);
03950 
03951     /* If the new constant is zero, try to replace the sum with just
03952        the register.  */
03953     if (new_offset == const0_rtx
03954         && validate_change (object, loc, new, 0))
03955       return 1;
03956 
03957     /* Next try to replace the register and new offset.
03958        There are two changes to validate here and we can't assume that
03959        in the case of old offset equals new just changing the register
03960        will yield a valid insn.  In the interests of a little efficiency,
03961        however, we only call validate change once (we don't queue up the
03962        changes and then call apply_change_group).  */
03963 
03964     old = XEXP (x, 0);
03965     if (offset == 0
03966         ? ! validate_change (object, &XEXP (x, 0), new, 0)
03967         : (XEXP (x, 0) = new,
03968      ! validate_change (object, &XEXP (x, 1), new_offset, 0)))
03969       {
03970         if (! extra_insns)
03971     {
03972       XEXP (x, 0) = old;
03973       return 0;
03974     }
03975 
03976         /* Otherwise copy the new constant into a register and replace
03977      constant with that register.  */
03978         temp = gen_reg_rtx (Pmode);
03979         XEXP (x, 0) = new;
03980         if (validate_change (object, &XEXP (x, 1), temp, 0))
03981     emit_insn_before (gen_move_insn (temp, new_offset), object);
03982         else
03983     {
03984       /* If that didn't work, replace this expression with a
03985          register containing the sum.  */
03986 
03987       XEXP (x, 0) = old;
03988       new = gen_rtx_PLUS (Pmode, new, new_offset);
03989 
03990       start_sequence ();
03991       temp = force_operand (new, NULL_RTX);
03992       seq = get_insns ();
03993       end_sequence ();
03994 
03995       emit_insn_before (seq, object);
03996       if (! validate_change (object, loc, temp, 0)
03997           && ! validate_replace_rtx (x, temp, object))
03998         {
03999           instantiate_virtual_regs_lossage (object);
04000           return 1;
04001         }
04002     }
04003       }
04004 
04005     return 1;
04006   }
04007 
04008       /* Fall through to generic two-operand expression case.  */
04009     case EXPR_LIST:
04010     case CALL:
04011     case COMPARE:
04012     case MINUS:
04013     case MULT:
04014     case DIV:      case UDIV:
04015     case MOD:      case UMOD:
04016     case AND:      case IOR:      case XOR:
04017     case ROTATERT: case ROTATE:
04018     case ASHIFTRT: case LSHIFTRT: case ASHIFT:
04019     case NE:       case EQ:
04020     case GE:       case GT:       case GEU:    case GTU:
04021     case LE:       case LT:       case LEU:    case LTU:
04022       if (XEXP (x, 1) && ! CONSTANT_P (XEXP (x, 1)))
04023   instantiate_virtual_regs_1 (&XEXP (x, 1), object, extra_insns);
04024       loc = &XEXP (x, 0);
04025       goto restart;
04026 
04027     case MEM:
04028       /* Most cases of MEM that convert to valid addresses have already been
04029    handled by our scan of decls.  The only special handling we
04030    need here is to make a copy of the rtx to ensure it isn't being
04031    shared if we have to change it to a pseudo.
04032 
04033    If the rtx is a simple reference to an address via a virtual register,
04034    it can potentially be shared.  In such cases, first try to make it
04035    a valid address, which can also be shared.  Otherwise, copy it and
04036    proceed normally.
04037 
04038    First check for common cases that need no processing.  These are
04039    usually due to instantiation already being done on a previous instance
04040    of a shared rtx.  */
04041 
04042       temp = XEXP (x, 0);
04043       if (CONSTANT_ADDRESS_P (temp)
04044 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
04045     || temp == arg_pointer_rtx
04046 #endif
04047 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
04048     || temp == hard_frame_pointer_rtx
04049 #endif
04050     || temp == frame_pointer_rtx)
04051   return 1;
04052 
04053       if (GET_CODE (temp) == PLUS
04054     && CONSTANT_ADDRESS_P (XEXP (temp, 1))
04055     && (XEXP (temp, 0) == frame_pointer_rtx
04056 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
04057         || XEXP (temp, 0) == hard_frame_pointer_rtx
04058 #endif
04059 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
04060         || XEXP (temp, 0) == arg_pointer_rtx
04061 #endif
04062         ))
04063   return 1;
04064 
04065       if (temp == virtual_stack_vars_rtx
04066     || temp == virtual_incoming_args_rtx
04067     || (GET_CODE (temp) == PLUS
04068         && CONSTANT_ADDRESS_P (XEXP (temp, 1))
04069         && (XEXP (temp, 0) == virtual_stack_vars_rtx
04070       || XEXP (temp, 0) == virtual_incoming_args_rtx)))
04071   {
04072     /* This MEM may be shared.  If the substitution can be done without
04073        the need to generate new pseudos, we want to do it in place
04074        so all copies of the shared rtx benefit.  The call below will
04075        only make substitutions if the resulting address is still
04076        valid.
04077 
04078        Note that we cannot pass X as the object in the recursive call
04079        since the insn being processed may not allow all valid
04080        addresses.  However, if we were not passed on object, we can
04081        only modify X without copying it if X will have a valid
04082        address.
04083 
04084        ??? Also note that this can still lose if OBJECT is an insn that
04085        has less restrictions on an address that some other insn.
04086        In that case, we will modify the shared address.  This case
04087        doesn't seem very likely, though.  One case where this could
04088        happen is in the case of a USE or CLOBBER reference, but we
04089        take care of that below.  */
04090 
04091     if (instantiate_virtual_regs_1 (&XEXP (x, 0),
04092             object ? object : x, 0))
04093       return 1;
04094 
04095     /* Otherwise make a copy and process that copy.  We copy the entire
04096        RTL expression since it might be a PLUS which could also be
04097        shared.  */
04098     *loc = x = copy_rtx (x);
04099   }
04100 
04101       /* Fall through to generic unary operation case.  */
04102     case PREFETCH:
04103     case SUBREG:
04104     case STRICT_LOW_PART:
04105     case NEG:          case NOT:
04106     case PRE_DEC:      case PRE_INC:      case POST_DEC:    case POST_INC:
04107     case SIGN_EXTEND:  case ZERO_EXTEND:
04108     case TRUNCATE:     case FLOAT_EXTEND: case FLOAT_TRUNCATE:
04109     case FLOAT:        case FIX:
04110     case UNSIGNED_FIX: case UNSIGNED_FLOAT:
04111     case ABS:
04112     case SQRT:
04113     case FFS:
04114       /* These case either have just one operand or we know that we need not
04115    check the rest of the operands.  */
04116       loc = &XEXP (x, 0);
04117       goto restart;
04118 
04119     case USE:
04120     case CLOBBER:
04121       /* If the operand is a MEM, see if the change is a valid MEM.  If not,
04122    go ahead and make the invalid one, but do it to a copy.  For a REG,
04123    just make the recursive call, since there's no chance of a problem.  */
04124 
04125       if ((GET_CODE (XEXP (x, 0)) == MEM
04126      && instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 0), XEXP (x, 0),
04127             0))
04128     || (GET_CODE (XEXP (x, 0)) == REG
04129         && instantiate_virtual_regs_1 (&XEXP (x, 0), object, 0)))
04130   return 1;
04131 
04132       XEXP (x, 0) = copy_rtx (XEXP (x, 0));
04133       loc = &XEXP (x, 0);
04134       goto restart;
04135 
04136     case REG:
04137       /* Try to replace with a PLUS.  If that doesn't work, compute the sum
04138    in front of this insn and substitute the temporary.  */
04139       if ((new = instantiate_new_reg (x, &offset)) != 0)
04140   {
04141     temp = plus_constant (new, offset);
04142     if (!validate_change (object, loc, temp, 0))
04143       {
04144         if (! extra_insns)
04145     return 0;
04146 
04147         start_sequence ();
04148         temp = force_operand (temp, NULL_RTX);
04149         seq = get_insns ();
04150         end_sequence ();
04151 
04152         emit_insn_before (seq, object);
04153         if (! validate_change (object, loc, temp, 0)
04154       && ! validate_replace_rtx (x, temp, object))
04155           instantiate_virtual_regs_lossage (object);
04156       }
04157   }
04158 
04159       return 1;
04160 
04161     case ADDRESSOF:
04162       if (GET_CODE (XEXP (x, 0)) == REG)
04163   return 1;
04164 
04165       else if (GET_CODE (XEXP (x, 0)) == MEM)
04166   {
04167     /* If we have a (addressof (mem ..)), do any instantiation inside
04168        since we know we'll be making the inside valid when we finally
04169        remove the ADDRESSOF.  */
04170     instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 0), NULL_RTX, 0);
04171     return 1;
04172   }
04173       break;
04174 
04175     default:
04176       break;
04177     }
04178 
04179   /* Scan all subexpressions.  */
04180   fmt = GET_RTX_FORMAT (code);
04181   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
04182     if (*fmt == 'e')
04183       {
04184   if (!instantiate_virtual_regs_1 (&XEXP (x, i), object, extra_insns))
04185     return 0;
04186       }
04187     else if (*fmt == 'E')
04188       for (j = 0; j < XVECLEN (x, i); j++)
04189   if (! instantiate_virtual_regs_1 (&XVECEXP (x, i, j), object,
04190             extra_insns))
04191     return 0;
04192 
04193   return 1;
04194 }
04195 
04196 /* Optimization: assuming this function does not receive nonlocal gotos,
04197    delete the handlers for such, as well as the insns to establish
04198    and disestablish them.  */
04199 
04200 static void
04201 delete_handlers ()
04202 {
04203   rtx insn;
04204   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
04205     {
04206       /* Delete the handler by turning off the flag that would
04207    prevent jump_optimize from deleting it.
04208    Also permit deletion of the nonlocal labels themselves
04209    if nothing local refers to them.  */
04210       if (GET_CODE (insn) == CODE_LABEL)
04211   {
04212     tree t, last_t;
04213 
04214     LABEL_PRESERVE_P (insn) = 0;
04215 
04216     /* Remove it from the nonlocal_label list, to avoid confusing
04217        flow.  */
04218     for (t = nonlocal_labels, last_t = 0; t;
04219          last_t = t, t = TREE_CHAIN (t))
04220       if (DECL_RTL (TREE_VALUE (t)) == insn)
04221         break;
04222     if (t)
04223       {
04224         if (! last_t)
04225     nonlocal_labels = TREE_CHAIN (nonlocal_labels);
04226         else
04227     TREE_CHAIN (last_t) = TREE_CHAIN (t);
04228       }
04229   }
04230       if (GET_CODE (insn) == INSN)
04231   {
04232     int can_delete = 0;
04233     rtx t;
04234     for (t = nonlocal_goto_handler_slots; t != 0; t = XEXP (t, 1))
04235       if (reg_mentioned_p (t, PATTERN (insn)))
04236         {
04237     can_delete = 1;
04238     break;
04239         }
04240     if (can_delete
04241         || (nonlocal_goto_stack_level != 0
04242       && reg_mentioned_p (nonlocal_goto_stack_level,
04243               PATTERN (insn))))
04244       delete_related_insns (insn);
04245   }
04246     }
04247 }
04248 
04249 int
04250 max_parm_reg_num ()
04251 {
04252   return max_parm_reg;
04253 }
04254 
04255 /* Return the first insn following those generated by `assign_parms'.  */
04256 
04257 rtx
04258 get_first_nonparm_insn ()
04259 {
04260   if (last_parm_insn)
04261     return NEXT_INSN (last_parm_insn);
04262   return get_insns ();
04263 }
04264 
04265 /* Return the first NOTE_INSN_BLOCK_BEG note in the function.
04266    Crash if there is none.  */
04267 
04268 rtx
04269 get_first_block_beg ()
04270 {
04271   rtx searcher;
04272   rtx insn = get_first_nonparm_insn ();
04273 
04274   for (searcher = insn; searcher; searcher = NEXT_INSN (searcher))
04275     if (GET_CODE (searcher) == NOTE
04276   && NOTE_LINE_NUMBER (searcher) == NOTE_INSN_BLOCK_BEG)
04277       return searcher;
04278 
04279   abort (); /* Invalid call to this function.  (See comments above.)  */
04280   return NULL_RTX;
04281 }
04282 
04283 /* Return 1 if EXP is an aggregate type (or a value with aggregate type).
04284    This means a type for which function calls must pass an address to the
04285    function or get an address back from the function.
04286    EXP may be a type node or an expression (whose type is tested).  */
04287 
04288 int
04289 aggregate_value_p (exp)
04290      tree exp;
04291 {
04292   int i, regno, nregs;
04293   rtx reg;
04294 
04295   tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
04296 
04297   if (TREE_CODE (type) == VOID_TYPE)
04298     return 0;
04299   if (RETURN_IN_MEMORY (type))
04300     return 1;
04301   /* Types that are TREE_ADDRESSABLE must be constructed in memory,
04302      and thus can't be returned in registers.  */
04303   if (TREE_ADDRESSABLE (type))
04304     return 1;
04305   if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
04306     return 1;
04307   /* Make sure we have suitable call-clobbered regs to return
04308      the value in; if not, we must return it in memory.  */
04309   reg = hard_function_value (type, 0, 0);
04310 
04311   /* If we have something other than a REG (e.g. a PARALLEL), then assume
04312      it is OK.  */
04313   if (GET_CODE (reg) != REG)
04314     return 0;
04315 
04316   regno = REGNO (reg);
04317   nregs = HARD_REGNO_NREGS (regno, TYPE_MODE (type));
04318   for (i = 0; i < nregs; i++)
04319     if (! call_used_regs[regno + i])
04320       return 1;
04321   return 0;
04322 }
04323 
04324 /* Assign RTL expressions to the function's parameters.
04325    This may involve copying them into registers and using
04326    those registers as the RTL for them.  */
04327 
04328 void
04329 assign_parms (fndecl)
04330      tree fndecl;
04331 {
04332   tree parm;
04333   rtx entry_parm = 0;
04334   rtx stack_parm = 0;
04335   CUMULATIVE_ARGS args_so_far;
04336   enum machine_mode promoted_mode, passed_mode;
04337   enum machine_mode nominal_mode, promoted_nominal_mode;
04338   int unsignedp;
04339   /* Total space needed so far for args on the stack,
04340      given as a constant and a tree-expression.  */
04341   struct args_size stack_args_size;
04342   tree fntype = TREE_TYPE (fndecl);
04343   tree fnargs = DECL_ARGUMENTS (fndecl);
04344   /* This is used for the arg pointer when referring to stack args.  */
04345   rtx internal_arg_pointer;
04346   /* This is a dummy PARM_DECL that we used for the function result if
04347      the function returns a structure.  */
04348   tree function_result_decl = 0;
04349 #ifdef SETUP_INCOMING_VARARGS
04350   int varargs_setup = 0;
04351 #endif
04352   rtx conversion_insns = 0;
04353   struct args_size alignment_pad;
04354 
04355   /* Nonzero if function takes extra anonymous args.
04356      This means the last named arg must be on the stack
04357      right before the anonymous ones.  */
04358   int stdarg
04359     = (TYPE_ARG_TYPES (fntype) != 0
04360        && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
04361      != void_type_node));
04362 
04363   current_function_stdarg = stdarg;
04364 
04365   /* If the reg that the virtual arg pointer will be translated into is
04366      not a fixed reg or is the stack pointer, make a copy of the virtual
04367      arg pointer, and address parms via the copy.  The frame pointer is
04368      considered fixed even though it is not marked as such.
04369 
04370      The second time through, simply use ap to avoid generating rtx.  */
04371 
04372   if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
04373        || ! (fixed_regs[ARG_POINTER_REGNUM]
04374        || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
04375     internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
04376   else
04377     internal_arg_pointer = virtual_incoming_args_rtx;
04378   current_function_internal_arg_pointer = internal_arg_pointer;
04379 
04380   stack_args_size.constant = 0;
04381   stack_args_size.var = 0;
04382 
04383   /* If struct value address is treated as the first argument, make it so.  */
04384   if (aggregate_value_p (DECL_RESULT (fndecl))
04385       && ! current_function_returns_pcc_struct
04386       && struct_value_incoming_rtx == 0)
04387     {
04388       tree type = build_pointer_type (TREE_TYPE (fntype));
04389 
04390       function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
04391 
04392       DECL_ARG_TYPE (function_result_decl) = type;
04393       TREE_CHAIN (function_result_decl) = fnargs;
04394       fnargs = function_result_decl;
04395     }
04396 
04397   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
04398   parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
04399 
04400 #ifdef INIT_CUMULATIVE_INCOMING_ARGS
04401   INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
04402 #else
04403   INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0);
04404 #endif
04405 
04406   /* We haven't yet found an argument that we must push and pretend the
04407      caller did.  */
04408   current_function_pretend_args_size = 0;
04409 
04410   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
04411     {
04412       struct args_size stack_offset;
04413       struct args_size arg_size;
04414       int passed_pointer = 0;
04415       int did_conversion = 0;
04416       tree passed_type = DECL_ARG_TYPE (parm);
04417       tree nominal_type = TREE_TYPE (parm);
04418       int pretend_named;
04419       int last_named = 0, named_arg;
04420 
04421       /* Set LAST_NAMED if this is last named arg before last
04422    anonymous args.  */
04423       if (stdarg)
04424   {
04425     tree tem;
04426 
04427     for (tem = TREE_CHAIN (parm); tem; tem = TREE_CHAIN (tem))
04428       if (DECL_NAME (tem))
04429         break;
04430 
04431     if (tem == 0)
04432       last_named = 1;
04433   }
04434       /* Set NAMED_ARG if this arg should be treated as a named arg.  For
04435    most machines, if this is a varargs/stdarg function, then we treat
04436    the last named arg as if it were anonymous too.  */
04437       named_arg = STRICT_ARGUMENT_NAMING ? 1 : ! last_named;
04438 
04439       if (TREE_TYPE (parm) == error_mark_node
04440     /* This can happen after weird syntax errors
04441        or if an enum type is defined among the parms.  */
04442     || TREE_CODE (parm) != PARM_DECL
04443     || passed_type == NULL)
04444   {
04445     SET_DECL_RTL (parm, gen_rtx_MEM (BLKmode, const0_rtx));
04446     DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
04447     TREE_USED (parm) = 1;
04448     continue;
04449   }
04450 
04451       /* Find mode of arg as it is passed, and mode of arg
04452    as it should be during execution of this function.  */
04453       passed_mode = TYPE_MODE (passed_type);
04454       nominal_mode = TYPE_MODE (nominal_type);
04455 
04456       /* If the parm's mode is VOID, its value doesn't matter,
04457    and avoid the usual things like emit_move_insn that could crash.  */
04458       if (nominal_mode == VOIDmode)
04459   {
04460     SET_DECL_RTL (parm, const0_rtx);
04461     DECL_INCOMING_RTL (parm) = DECL_RTL (parm);
04462     continue;
04463   }
04464 
04465       /* If the parm is to be passed as a transparent union, use the
04466    type of the first field for the tests below.  We have already
04467    verified that the modes are the same.  */
04468       if (DECL_TRANSPARENT_UNION (parm)
04469     || (TREE_CODE (passed_type) == UNION_TYPE
04470         && TYPE_TRANSPARENT_UNION (passed_type)))
04471   passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
04472 
04473       /* See if this arg was passed by invisible reference.  It is if
04474    it is an object whose size depends on the contents of the
04475    object itself or if the machine requires these objects be passed
04476    that way.  */
04477 
04478       if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
04479      && contains_placeholder_p (TYPE_SIZE (passed_type)))
04480     || TREE_ADDRESSABLE (passed_type)
04481 #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
04482     || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
04483                 passed_type, named_arg)
04484 #endif
04485     )
04486   {
04487     passed_type = nominal_type = build_pointer_type (passed_type);
04488     passed_pointer = 1;
04489     passed_mode = nominal_mode = Pmode;
04490   }
04491       /* See if the frontend wants to pass this by invisible reference.  */
04492       else if (passed_type != nominal_type
04493          && POINTER_TYPE_P (passed_type)
04494          && TREE_TYPE (passed_type) == nominal_type)
04495   {
04496     nominal_type = passed_type;
04497     passed_pointer = 1;
04498     passed_mode = nominal_mode = Pmode;
04499   }
04500 
04501       promoted_mode = passed_mode;
04502 
04503 #ifdef PROMOTE_FUNCTION_ARGS
04504       /* Compute the mode in which the arg is actually extended to.  */
04505       unsignedp = TREE_UNSIGNED (passed_type);
04506       promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
04507 #endif
04508 
04509       /* Let machine desc say which reg (if any) the parm arrives in.
04510    0 means it arrives on the stack.  */
04511 #ifdef FUNCTION_INCOMING_ARG
04512       entry_parm = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
04513             passed_type, named_arg);
04514 #else
04515       entry_parm = FUNCTION_ARG (args_so_far, promoted_mode,
04516          passed_type, named_arg);
04517 #endif
04518 
04519       if (entry_parm == 0)
04520   promoted_mode = passed_mode;
04521 
04522 #ifdef SETUP_INCOMING_VARARGS
04523       /* If this is the last named parameter, do any required setup for
04524    varargs or stdargs.  We need to know about the case of this being an
04525    addressable type, in which case we skip the registers it
04526    would have arrived in.
04527 
04528    For stdargs, LAST_NAMED will be set for two parameters, the one that
04529    is actually the last named, and the dummy parameter.  We only
04530    want to do this action once.
04531 
04532    Also, indicate when RTL generation is to be suppressed.  */
04533       if (last_named && !varargs_setup)
04534   {
04535     SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
04536           current_function_pretend_args_size, 0);
04537     varargs_setup = 1;
04538   }
04539 #endif
04540 
04541       /* Determine parm's home in the stack,
04542    in case it arrives in the stack or we should pretend it did.
04543 
04544    Compute the stack position and rtx where the argument arrives
04545    and its size.
04546 
04547    There is one complexity here:  If this was a parameter that would
04548    have been passed in registers, but wasn't only because it is
04549    __builtin_va_alist, we want locate_and_pad_parm to treat it as if
04550    it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
04551    In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
04552    0 as it was the previous time.  */
04553 
04554       pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
04555       locate_and_pad_parm (promoted_mode, passed_type,
04556 #ifdef STACK_PARMS_IN_REG_PARM_AREA
04557          1,
04558 #else
04559 #ifdef FUNCTION_INCOMING_ARG
04560          FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
04561               passed_type,
04562               pretend_named) != 0,
04563 #else
04564          FUNCTION_ARG (args_so_far, promoted_mode,
04565            passed_type,
04566            pretend_named) != 0,
04567 #endif
04568 #endif
04569          fndecl, &stack_args_size, &stack_offset, &arg_size,
04570          &alignment_pad);
04571 
04572       {
04573   rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
04574 
04575   if (offset_rtx == const0_rtx)
04576     stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
04577   else
04578     stack_parm = gen_rtx_MEM (promoted_mode,
04579             gen_rtx_PLUS (Pmode,
04580               internal_arg_pointer,
04581               offset_rtx));
04582 
04583   set_mem_attributes (stack_parm, parm, 1);
04584       }
04585 
04586       /* If this parameter was passed both in registers and in the stack,
04587    use the copy on the stack.  */
04588       if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
04589   entry_parm = 0;
04590 
04591 #ifdef FUNCTION_ARG_PARTIAL_NREGS
04592       /* If this parm was passed part in regs and part in memory,
04593    pretend it arrived entirely in memory
04594    by pushing the register-part onto the stack.
04595 
04596    In the special case of a DImode or DFmode that is split,
04597    we could put it together in a pseudoreg directly,
04598    but for now that's not worth bothering with.  */
04599 
04600       if (entry_parm)
04601   {
04602     int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
04603               passed_type, named_arg);
04604 
04605     if (nregs > 0)
04606       {
04607 #if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
04608         /* When REG_PARM_STACK_SPACE is nonzero, stack space for
04609      split parameters was allocated by our caller, so we
04610      won't be pushing it in the prolog.  */
04611         if (REG_PARM_STACK_SPACE (fndecl) == 0)
04612 #endif
04613         current_function_pretend_args_size
04614     = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
04615        / (PARM_BOUNDARY / BITS_PER_UNIT)
04616        * (PARM_BOUNDARY / BITS_PER_UNIT));
04617 
04618         /* Handle calls that pass values in multiple non-contiguous
04619      locations.  The Irix 6 ABI has examples of this.  */
04620         if (GET_CODE (entry_parm) == PARALLEL)
04621     emit_group_store (validize_mem (stack_parm), entry_parm,
04622           int_size_in_bytes (TREE_TYPE (parm)));
04623 
04624         else
04625     move_block_from_reg (REGNO (entry_parm),
04626              validize_mem (stack_parm), nregs,
04627              int_size_in_bytes (TREE_TYPE (parm)));
04628 
04629         entry_parm = stack_parm;
04630       }
04631   }
04632 #endif
04633 
04634       /* If we didn't decide this parm came in a register,
04635    by default it came on the stack.  */
04636       if (entry_parm == 0)
04637   entry_parm = stack_parm;
04638 
04639       /* Record permanently how this parm was passed.  */
04640       DECL_INCOMING_RTL (parm) = entry_parm;
04641 
04642       /* If there is actually space on the stack for this parm,
04643    count it in stack_args_size; otherwise set stack_parm to 0
04644    to indicate there is no preallocated stack slot for the parm.  */
04645 
04646       if (entry_parm == stack_parm
04647     || (GET_CODE (entry_parm) == PARALLEL
04648         && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
04649 #if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
04650     /* On some machines, even if a parm value arrives in a register
04651        there is still an (uninitialized) stack slot allocated for it.
04652 
04653        ??? When MAYBE_REG_PARM_STACK_SPACE is defined, we can't tell
04654        whether this parameter already has a stack slot allocated,
04655        because an arg block exists only if current_function_args_size
04656        is larger than some threshold, and we haven't calculated that
04657        yet.  So, for now, we just assume that stack slots never exist
04658        in this case.  */
04659     || REG_PARM_STACK_SPACE (fndecl) > 0
04660 #endif
04661     )
04662   {
04663     stack_args_size.constant += arg_size.constant;
04664     if (arg_size.var)
04665       ADD_PARM_SIZE (stack_args_size, arg_size.var);
04666   }
04667       else
04668   /* No stack slot was pushed for this parm.  */
04669   stack_parm = 0;
04670 
04671       /* Update info on where next arg arrives in registers.  */
04672 
04673       FUNCTION_ARG_ADVANCE (args_so_far, promoted_mode,
04674           passed_type, named_arg);
04675 
04676       /* If we can't trust the parm stack slot to be aligned enough
04677    for its ultimate type, don't use that slot after entry.
04678    We'll make another stack slot, if we need one.  */
04679       {
04680   unsigned int thisparm_boundary
04681     = FUNCTION_ARG_BOUNDARY (promoted_mode, passed_type);
04682 
04683   if (GET_MODE_ALIGNMENT (nominal_mode) > thisparm_boundary)
04684     stack_parm = 0;
04685       }
04686 
04687       /* If parm was passed in memory, and we need to convert it on entry,
04688    don't store it back in that same slot.  */
04689       if (entry_parm != 0
04690     && nominal_mode != BLKmode && nominal_mode != passed_mode)
04691   stack_parm = 0;
04692 
04693       /* When an argument is passed in multiple locations, we can't
04694    make use of this information, but we can save some copying if
04695    the whole argument is passed in a single register.  */
04696       if (GET_CODE (entry_parm) == PARALLEL
04697     && nominal_mode != BLKmode && passed_mode != BLKmode)
04698   {
04699     int i, len = XVECLEN (entry_parm, 0);
04700 
04701     for (i = 0; i < len; i++)
04702       if (XEXP (XVECEXP (entry_parm, 0, i), 0) != NULL_RTX
04703     && GET_CODE (XEXP (XVECEXP (entry_parm, 0, i), 0)) == REG
04704     && (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0))
04705         == passed_mode)
04706     && INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0)
04707         {
04708     entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0);
04709     DECL_INCOMING_RTL (parm) = entry_parm;
04710     break;
04711         }
04712   }
04713 
04714       /* ENTRY_PARM is an RTX for the parameter as it arrives,
04715    in the mode in which it arrives.
04716    STACK_PARM is an RTX for a stack slot where the parameter can live
04717    during the function (in case we want to put it there).
04718    STACK_PARM is 0 if no stack slot was pushed for it.
04719 
04720    Now output code if necessary to convert ENTRY_PARM to
04721    the type in which this function declares it,
04722    and store that result in an appropriate place,
04723    which may be a pseudo reg, may be STACK_PARM,
04724    or may be a local stack slot if STACK_PARM is 0.
04725 
04726    Set DECL_RTL to that place.  */
04727 
04728       if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
04729   {
04730     /* If a BLKmode arrives in registers, copy it to a stack slot.
04731        Handle calls that pass values in multiple non-contiguous
04732        locations.  The Irix 6 ABI has examples of this.  */
04733     if (GET_CODE (entry_parm) == REG
04734         || GET_CODE (entry_parm) == PARALLEL)
04735       {
04736         int size_stored
04737     = CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
04738             UNITS_PER_WORD);
04739 
04740         /* Note that we will be storing an integral number of words.
04741      So we have to be careful to ensure that we allocate an
04742      integral number of words.  We do this below in the
04743      assign_stack_local if space was not allocated in the argument
04744      list.  If it was, this will not work if PARM_BOUNDARY is not
04745      a multiple of BITS_PER_WORD.  It isn't clear how to fix this
04746      if it becomes a problem.  */
04747 
04748         if (stack_parm == 0)
04749     {
04750       stack_parm
04751         = assign_stack_local (GET_MODE (entry_parm),
04752             size_stored, 0);
04753       set_mem_attributes (stack_parm, parm, 1);
04754     }
04755 
04756         else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
04757     abort ();
04758 
04759         /* Handle calls that pass values in multiple non-contiguous
04760      locations.  The Irix 6 ABI has examples of this.  */
04761         if (GET_CODE (entry_parm) == PARALLEL)
04762     emit_group_store (validize_mem (stack_parm), entry_parm,
04763           int_size_in_bytes (TREE_TYPE (parm)));
04764         else
04765     move_block_from_reg (REGNO (entry_parm),
04766              validize_mem (stack_parm),
04767              size_stored / UNITS_PER_WORD,
04768              int_size_in_bytes (TREE_TYPE (parm)));
04769       }
04770     SET_DECL_RTL (parm, stack_parm);
04771   }
04772       else if (! ((! optimize
04773        && ! DECL_REGISTER (parm))
04774       || TREE_SIDE_EFFECTS (parm)
04775       /* If -ffloat-store specified, don't put explicit
04776          float variables into registers.  */
04777       || (flag_float_store
04778           && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))
04779          /* Always assign pseudo to structure return or item passed
04780       by invisible reference.  */
04781          || passed_pointer || parm == function_result_decl)
04782   {
04783     /* Store the parm in a pseudoregister during the function, but we
04784        may need to do it in a wider mode.  */
04785 
04786     rtx parmreg;
04787     unsigned int regno, regnoi = 0, regnor = 0;
04788 
04789     unsignedp = TREE_UNSIGNED (TREE_TYPE (parm));
04790 
04791     promoted_nominal_mode
04792       = promote_mode (TREE_TYPE (parm), nominal_mode, &unsignedp, 0);
04793 
04794     parmreg = gen_reg_rtx (promoted_nominal_mode);
04795     mark_user_reg (parmreg);
04796 
04797     /* If this was an item that we received a pointer to, set DECL_RTL
04798        appropriately.  */
04799     if (passed_pointer)
04800       {
04801         rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (passed_type)),
04802            parmreg);
04803         set_mem_attributes (x, parm, 1);
04804         SET_DECL_RTL (parm, x);
04805       }
04806     else
04807       {
04808         SET_DECL_RTL (parm, parmreg);
04809         maybe_set_unchanging (DECL_RTL (parm), parm);
04810       }
04811 
04812     /* Copy the value into the register.  */
04813     if (nominal_mode != passed_mode
04814         || promoted_nominal_mode != promoted_mode)
04815       {
04816         int save_tree_used;
04817         /* ENTRY_PARM has been converted to PROMOTED_MODE, its
04818      mode, by the caller.  We now have to convert it to
04819      NOMINAL_MODE, if different.  However, PARMREG may be in
04820      a different mode than NOMINAL_MODE if it is being stored
04821      promoted.
04822 
04823      If ENTRY_PARM is a hard register, it might be in a register
04824      not valid for operating in its mode (e.g., an odd-numbered
04825      register for a DFmode).  In that case, moves are the only
04826      thing valid, so we can't do a convert from there.  This
04827      occurs when the calling sequence allow such misaligned
04828      usages.
04829 
04830      In addition, the conversion may involve a call, which could
04831      clobber parameters which haven't been copied to pseudo
04832      registers yet.  Therefore, we must first copy the parm to
04833      a pseudo reg here, and save the conversion until after all
04834      parameters have been moved.  */
04835 
04836         rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
04837 
04838         emit_move_insn (tempreg, validize_mem (entry_parm));
04839 
04840         push_to_sequence (conversion_insns);
04841         tempreg = convert_to_mode (nominal_mode, tempreg, unsignedp);
04842 
04843         if (GET_CODE (tempreg) == SUBREG
04844       && GET_MODE (tempreg) == nominal_mode
04845       && GET_CODE (SUBREG_REG (tempreg)) == REG
04846       && nominal_mode == passed_mode
04847       && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (entry_parm)
04848       && GET_MODE_SIZE (GET_MODE (tempreg))
04849          < GET_MODE_SIZE (GET_MODE (entry_parm)))
04850     {
04851       /* The argument is already sign/zero extended, so note it
04852          into the subreg.  */
04853       SUBREG_PROMOTED_VAR_P (tempreg) = 1;
04854       SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp);
04855     }
04856 
04857         /* TREE_USED gets set erroneously during expand_assignment.  */
04858         save_tree_used = TREE_USED (parm);
04859         expand_assignment (parm,
04860          make_tree (nominal_type, tempreg), 0, 0);
04861         TREE_USED (parm) = save_tree_used;
04862         conversion_insns = get_insns ();
04863         did_conversion = 1;
04864         end_sequence ();
04865       }
04866     else
04867       emit_move_insn (parmreg, validize_mem (entry_parm));
04868 
04869     /* If we were passed a pointer but the actual value
04870        can safely live in a register, put it in one.  */
04871     if (passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
04872         /* If by-reference argument was promoted, demote it.  */
04873         && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
04874       || ! ((! optimize
04875        && ! DECL_REGISTER (parm))
04876       || TREE_SIDE_EFFECTS (parm)
04877       /* If -ffloat-store specified, don't put explicit
04878          float variables into registers.  */
04879       || (flag_float_store
04880           && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))))
04881       {
04882         /* We can't use nominal_mode, because it will have been set to
04883      Pmode above.  We must use the actual mode of the parm.  */
04884         parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
04885         mark_user_reg (parmreg);
04886         if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
04887     {
04888       rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm)));
04889       int unsigned_p = TREE_UNSIGNED (TREE_TYPE (parm));
04890       push_to_sequence (conversion_insns);
04891       emit_move_insn (tempreg, DECL_RTL (parm));
04892       SET_DECL_RTL (parm,
04893         convert_to_mode (GET_MODE (parmreg),
04894              tempreg,
04895              unsigned_p));
04896       emit_move_insn (parmreg, DECL_RTL (parm));
04897       conversion_insns = get_insns();
04898       did_conversion = 1;
04899       end_sequence ();
04900     }
04901         else
04902     emit_move_insn (parmreg, DECL_RTL (parm));
04903         SET_DECL_RTL (parm, parmreg);
04904         /* STACK_PARM is the pointer, not the parm, and PARMREG is
04905      now the parm.  */
04906         stack_parm = 0;
04907       }
04908 #ifdef FUNCTION_ARG_CALLEE_COPIES
04909     /* If we are passed an arg by reference and it is our responsibility
04910        to make a copy, do it now.
04911        PASSED_TYPE and PASSED mode now refer to the pointer, not the
04912        original argument, so we must recreate them in the call to
04913        FUNCTION_ARG_CALLEE_COPIES.  */
04914     /* ??? Later add code to handle the case that if the argument isn't
04915        modified, don't do the copy.  */
04916 
04917     else if (passed_pointer
04918        && FUNCTION_ARG_CALLEE_COPIES (args_so_far,
04919               TYPE_MODE (DECL_ARG_TYPE (parm)),
04920               DECL_ARG_TYPE (parm),
04921               named_arg)
04922        && ! TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))
04923       {
04924         rtx copy;
04925         tree type = DECL_ARG_TYPE (parm);
04926 
04927         /* This sequence may involve a library call perhaps clobbering
04928      registers that haven't been copied to pseudos yet.  */
04929 
04930         push_to_sequence (conversion_insns);
04931 
04932         if (!COMPLETE_TYPE_P (type)
04933       || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
04934     /* This is a variable sized object.  */
04935     copy = gen_rtx_MEM (BLKmode,
04936             allocate_dynamic_stack_space
04937             (expr_size (parm), NULL_RTX,
04938              TYPE_ALIGN (type)));
04939         else
04940     copy = assign_stack_temp (TYPE_MODE (type),
04941             int_size_in_bytes (type), 1);
04942         set_mem_attributes (copy, parm, 1);
04943 
04944         store_expr (parm, copy, 0);
04945         emit_move_insn (parmreg, XEXP (copy, 0));
04946         conversion_insns = get_insns ();
04947         did_conversion = 1;
04948         end_sequence ();
04949       }
04950 #endif /* FUNCTION_ARG_CALLEE_COPIES */
04951 
04952     /* In any case, record the parm's desired stack location
04953        in case we later discover it must live in the stack.
04954 
04955        If it is a COMPLEX value, store the stack location for both
04956        halves.  */
04957 
04958     if (GET_CODE (parmreg) == CONCAT)
04959       regno = MAX (REGNO (XEXP (parmreg, 0)), REGNO (XEXP (parmreg, 1)));
04960     else
04961       regno = REGNO (parmreg);
04962 
04963     if (regno >= max_parm_reg)
04964       {
04965         rtx *new;
04966         int old_max_parm_reg = max_parm_reg;
04967 
04968         /* It's slow to expand this one register at a time,
04969      but it's also rare and we need max_parm_reg to be
04970      precisely correct.  */
04971         max_parm_reg = regno + 1;
04972         new = (rtx *) ggc_realloc (parm_reg_stack_loc,
04973               max_parm_reg * sizeof (rtx));
04974         memset ((char *) (new + old_max_parm_reg), 0,
04975          (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
04976         parm_reg_stack_loc = new;
04977       }
04978 
04979     if (GET_CODE (parmreg) == CONCAT)
04980       {
04981         enum machine_mode submode = GET_MODE (XEXP (parmreg, 0));
04982 
04983         regnor = REGNO (gen_realpart (submode, parmreg));
04984         regnoi = REGNO (gen_imagpart (submode, parmreg));
04985 
04986         if (stack_parm != 0)
04987     {
04988       parm_reg_stack_loc[regnor]
04989         = gen_realpart (submode, stack_parm);
04990       parm_reg_stack_loc[regnoi]
04991         = gen_imagpart (submode, stack_parm);
04992     }
04993         else
04994     {
04995       parm_reg_stack_loc[regnor] = 0;
04996       parm_reg_stack_loc[regnoi] = 0;
04997     }
04998       }
04999     else
05000       parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
05001 
05002     /* Mark the register as eliminable if we did no conversion
05003        and it was copied from memory at a fixed offset,
05004        and the arg pointer was not copied to a pseudo-reg.
05005        If the arg pointer is a pseudo reg or the offset formed
05006        an invalid address, such memory-equivalences
05007        as we make here would screw up life analysis for it.  */
05008     if (nominal_mode == passed_mode
05009         && ! did_conversion
05010         && stack_parm != 0
05011         && GET_CODE (stack_parm) == MEM
05012         && stack_offset.var == 0
05013         && reg_mentioned_p (virtual_incoming_args_rtx,
05014           XEXP (stack_parm, 0)))
05015       {
05016         rtx linsn = get_last_insn ();
05017         rtx sinsn, set;
05018 
05019         /* Mark complex types separately.  */
05020         if (GET_CODE (parmreg) == CONCAT)
05021     /* Scan backwards for the set of the real and
05022        imaginary parts.  */
05023     for (sinsn = linsn; sinsn != 0;
05024          sinsn = prev_nonnote_insn (sinsn))
05025       {
05026         set = single_set (sinsn);
05027         if (set != 0
05028       && SET_DEST (set) == regno_reg_rtx [regnoi])
05029           REG_NOTES (sinsn)
05030       = gen_rtx_EXPR_LIST (REG_EQUIV,
05031                parm_reg_stack_loc[regnoi],
05032                REG_NOTES (sinsn));
05033         else if (set != 0
05034            && SET_DEST (set) == regno_reg_rtx [regnor])
05035           REG_NOTES (sinsn)
05036       = gen_rtx_EXPR_LIST (REG_EQUIV,
05037                parm_reg_stack_loc[regnor],
05038                REG_NOTES (sinsn));
05039       }
05040         else if ((set = single_set (linsn)) != 0
05041            && SET_DEST (set) == parmreg)
05042     REG_NOTES (linsn)
05043       = gen_rtx_EXPR_LIST (REG_EQUIV,
05044                stack_parm, REG_NOTES (linsn));
05045       }
05046 
05047     /* For pointer data type, suggest pointer register.  */
05048     if (POINTER_TYPE_P (TREE_TYPE (parm)))
05049       mark_reg_pointer (parmreg,
05050             TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
05051 
05052     /* If something wants our address, try to use ADDRESSOF.  */
05053     if (TREE_ADDRESSABLE (parm))
05054       {
05055         /* If we end up putting something into the stack,
05056      fixup_var_refs_insns will need to make a pass over
05057      all the instructions.  It looks through the pending
05058      sequences -- but it can't see the ones in the
05059      CONVERSION_INSNS, if they're not on the sequence
05060      stack.  So, we go back to that sequence, just so that
05061      the fixups will happen.  */
05062         push_to_sequence (conversion_insns);
05063         put_var_into_stack (parm, /*rescan=*/true);
05064         conversion_insns = get_insns ();
05065         end_sequence ();
05066       }
05067   }
05068       else
05069   {
05070     /* Value must be stored in the stack slot STACK_PARM
05071        during function execution.  */
05072 
05073     if (promoted_mode != nominal_mode)
05074       {
05075         /* Conversion is required.  */
05076         rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
05077 
05078         emit_move_insn (tempreg, validize_mem (entry_parm));
05079 
05080         push_to_sequence (conversion_insns);
05081         entry_parm = convert_to_mode (nominal_mode, tempreg,
05082               TREE_UNSIGNED (TREE_TYPE (parm)));
05083         if (stack_parm)
05084     /* ??? This may need a big-endian conversion on sparc64.  */
05085     stack_parm = adjust_address (stack_parm, nominal_mode, 0);
05086 
05087         conversion_insns = get_insns ();
05088         did_conversion = 1;
05089         end_sequence ();
05090       }
05091 
05092     if (entry_parm != stack_parm)
05093       {
05094         if (stack_parm == 0)
05095     {
05096       stack_parm
05097         = assign_stack_local (GET_MODE (entry_parm),
05098             GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
05099       set_mem_attributes (stack_parm, parm, 1);
05100     }
05101 
05102         if (promoted_mode != nominal_mode)
05103     {
05104       push_to_sequence (conversion_insns);
05105       emit_move_insn (validize_mem (stack_parm),
05106           validize_mem (entry_parm));
05107       conversion_insns = get_insns ();
05108       end_sequence ();
05109     }
05110         else
05111     emit_move_insn (validize_mem (stack_parm),
05112         validize_mem (entry_parm));
05113       }
05114 
05115     SET_DECL_RTL (parm, stack_parm);
05116   }
05117 
05118       /* If this "parameter" was the place where we are receiving the
05119    function's incoming structure pointer, set up the result.  */
05120       if (parm == function_result_decl)
05121   {
05122     tree result = DECL_RESULT (fndecl);
05123     rtx addr = DECL_RTL (parm);
05124     rtx x;
05125 
05126 #ifdef POINTERS_EXTEND_UNSIGNED
05127     if (GET_MODE (addr) != Pmode)
05128       addr = convert_memory_address (Pmode, addr);
05129 #endif
05130 
05131     x = gen_rtx_MEM (DECL_MODE (result), addr);
05132     set_mem_attributes (x, result, 1);
05133     SET_DECL_RTL (result, x);
05134   }
05135 
05136       if (GET_CODE (DECL_RTL (parm)) == REG)
05137   REGNO_DECL (REGNO (DECL_RTL (parm))) = parm;
05138       else if (GET_CODE (DECL_RTL (parm)) == CONCAT)
05139   {
05140     REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 0))) = parm;
05141     REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 1))) = parm;
05142   }
05143 
05144     }
05145 
05146   /* Output all parameter conversion instructions (possibly including calls)
05147      now that all parameters have been copied out of hard registers.  */
05148   emit_insn (conversion_insns);
05149 
05150   last_parm_insn = get_last_insn ();
05151 
05152   current_function_args_size = stack_args_size.constant;
05153 
05154   /* Adjust function incoming argument size for alignment and
05155      minimum length.  */
05156 
05157 #ifdef REG_PARM_STACK_SPACE
05158 #ifndef MAYBE_REG_PARM_STACK_SPACE
05159   current_function_args_size = MAX (current_function_args_size,
05160             REG_PARM_STACK_SPACE (fndecl));
05161 #endif
05162 #endif
05163 
05164 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
05165 
05166   current_function_args_size
05167     = ((current_function_args_size + STACK_BYTES - 1)
05168        / STACK_BYTES) * STACK_BYTES;
05169 
05170 #ifdef ARGS_GROW_DOWNWARD
05171   current_function_arg_offset_rtx
05172     = (stack_args_size.var == 0 ? GEN_INT (-stack_args_size.constant)
05173        : expand_expr (size_diffop (stack_args_size.var,
05174            size_int (-stack_args_size.constant)),
05175           NULL_RTX, VOIDmode, 0));
05176 #else
05177   current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
05178 #endif
05179 
05180   /* See how many bytes, if any, of its args a function should try to pop
05181      on return.  */
05182 
05183   current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl),
05184              current_function_args_size);
05185 
05186   /* For stdarg.h function, save info about
05187      regs and stack space used by the named args.  */
05188 
05189   current_function_args_info = args_so_far;
05190 
05191   /* Set the rtx used for the function return value.  Put this in its
05192      own variable so any optimizers that need this information don't have
05193      to include tree.h.  Do this here so it gets done when an inlined
05194      function gets output.  */
05195 
05196   current_function_return_rtx
05197     = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
05198        ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
05199 
05200   /* If scalar return value was computed in a pseudo-reg, or was a named
05201      return value that got dumped to the stack, copy that to the hard
05202      return register.  */
05203   if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
05204     {
05205       tree decl_result = DECL_RESULT (fndecl);
05206       rtx decl_rtl = DECL_RTL (decl_result);
05207 
05208       if (REG_P (decl_rtl)
05209     ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
05210     : DECL_REGISTER (decl_result))
05211   {
05212     rtx real_decl_rtl;
05213 
05214 #ifdef FUNCTION_OUTGOING_VALUE
05215     real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
05216                fndecl);
05217 #else
05218     real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
05219             fndecl);
05220 #endif
05221     REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
05222     /* The delay slot scheduler assumes that current_function_return_rtx
05223        holds the hard register containing the return value, not a
05224        temporary pseudo.  */
05225     current_function_return_rtx = real_decl_rtl;
05226   }
05227     }
05228 }
05229 
05230 /* Indicate whether REGNO is an incoming argument to the current function
05231    that was promoted to a wider mode.  If so, return the RTX for the
05232    register (to get its mode).  PMODE and PUNSIGNEDP are set to the mode
05233    that REGNO is promoted from and whether the promotion was signed or
05234    unsigned.  */
05235 
05236 #ifdef PROMOTE_FUNCTION_ARGS
05237 
05238 rtx
05239 promoted_input_arg (regno, pmode, punsignedp)
05240      unsigned int regno;
05241      enum machine_mode *pmode;
05242      int *punsignedp;
05243 {
05244   tree arg;
05245 
05246   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
05247        arg = TREE_CHAIN (arg))
05248     if (GET_CODE (DECL_INCOMING_RTL (arg)) == REG
05249   && REGNO (DECL_INCOMING_RTL (arg)) == regno
05250   && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
05251       {
05252   enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
05253   int unsignedp = TREE_UNSIGNED (TREE_TYPE (arg));
05254 
05255   mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1);
05256   if (mode == GET_MODE (DECL_INCOMING_RTL (arg))
05257       && mode != DECL_MODE (arg))
05258     {
05259       *pmode = DECL_MODE (arg);
05260       *punsignedp = unsignedp;
05261       return DECL_INCOMING_RTL (arg);
05262     }
05263       }
05264 
05265   return 0;
05266 }
05267 
05268 #endif
05269 
05270 /* Compute the size and offset from the start of the stacked arguments for a
05271    parm passed in mode PASSED_MODE and with type TYPE.
05272 
05273    INITIAL_OFFSET_PTR points to the current offset into the stacked
05274    arguments.
05275 
05276    The starting offset and size for this parm are returned in *OFFSET_PTR
05277    and *ARG_SIZE_PTR, respectively.
05278 
05279    IN_REGS is nonzero if the argument will be passed in registers.  It will
05280    never be set if REG_PARM_STACK_SPACE is not defined.
05281 
05282    FNDECL is the function in which the argument was defined.
05283 
05284    There are two types of rounding that are done.  The first, controlled by
05285    FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
05286    list to be aligned to the specific boundary (in bits).  This rounding
05287    affects the initial and starting offsets, but not the argument size.
05288 
05289    The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
05290    optionally rounds the size of the parm to PARM_BOUNDARY.  The
05291    initial offset is not affected by this rounding, while the size always
05292    is and the starting offset may be.  */
05293 
05294 /*  offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
05295     initial_offset_ptr is positive because locate_and_pad_parm's
05296     callers pass in the total size of args so far as
05297     initial_offset_ptr. arg_size_ptr is always positive.  */
05298 
05299 void
05300 locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
05301          initial_offset_ptr, offset_ptr, arg_size_ptr,
05302          alignment_pad)
05303      enum machine_mode passed_mode;
05304      tree type;
05305      int in_regs ATTRIBUTE_UNUSED;
05306      tree fndecl ATTRIBUTE_UNUSED;
05307      struct args_size *initial_offset_ptr;
05308      struct args_size *offset_ptr;
05309      struct args_size *arg_size_ptr;
05310      struct args_size *alignment_pad;
05311 
05312 {
05313   tree sizetree
05314     = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
05315   enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
05316   int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
05317 #ifdef ARGS_GROW_DOWNWARD
05318   tree s2 = sizetree;
05319 #endif
05320 
05321 #ifdef REG_PARM_STACK_SPACE
05322   /* If we have found a stack parm before we reach the end of the
05323      area reserved for registers, skip that area.  */
05324   if (! in_regs)
05325     {
05326       int reg_parm_stack_space = 0;
05327 
05328 #ifdef MAYBE_REG_PARM_STACK_SPACE
05329       reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
05330 #else
05331       reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
05332 #endif
05333       if (reg_parm_stack_space > 0)
05334   {
05335     if (initial_offset_ptr->var)
05336       {
05337         initial_offset_ptr->var
05338     = size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
05339             ssize_int (reg_parm_stack_space));
05340         initial_offset_ptr->constant = 0;
05341       }
05342     else if (initial_offset_ptr->constant < reg_parm_stack_space)
05343       initial_offset_ptr->constant = reg_parm_stack_space;
05344   }
05345     }
05346 #endif /* REG_PARM_STACK_SPACE */
05347 
05348   arg_size_ptr->var = 0;
05349   arg_size_ptr->constant = 0;
05350   alignment_pad->var = 0;
05351   alignment_pad->constant = 0;
05352 
05353 #ifdef ARGS_GROW_DOWNWARD
05354   if (initial_offset_ptr->var)
05355     {
05356       offset_ptr->constant = 0;
05357       offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
05358             initial_offset_ptr->var);
05359     }
05360   else
05361     {
05362       offset_ptr->constant = -initial_offset_ptr->constant;
05363       offset_ptr->var = 0;
05364     }
05365 
05366   if (where_pad != none
05367       && (!host_integerp (sizetree, 1)
05368     || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
05369     s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
05370   SUB_PARM_SIZE (*offset_ptr, s2);
05371 
05372   if (!in_regs
05373 #ifdef REG_PARM_STACK_SPACE
05374       || REG_PARM_STACK_SPACE (fndecl) > 0
05375 #endif
05376      )
05377     pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
05378 
05379   if (initial_offset_ptr->var)
05380     arg_size_ptr->var = size_binop (MINUS_EXPR,
05381             size_binop (MINUS_EXPR,
05382             ssize_int (0),
05383             initial_offset_ptr->var),
05384             offset_ptr->var);
05385 
05386   else
05387     arg_size_ptr->constant = (-initial_offset_ptr->constant
05388             - offset_ptr->constant);
05389 
05390   /* Pad_below needs the pre-rounded size to know how much to pad below.
05391      We only pad parameters which are not in registers as they have their
05392      padding done elsewhere.  */
05393   if (where_pad == downward
05394       && !in_regs)
05395     pad_below (offset_ptr, passed_mode, sizetree);
05396 
05397 #else /* !ARGS_GROW_DOWNWARD */
05398   if (!in_regs
05399 #ifdef REG_PARM_STACK_SPACE
05400       || REG_PARM_STACK_SPACE (fndecl) > 0
05401 #endif
05402       )
05403     pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
05404   *offset_ptr = *initial_offset_ptr;
05405 
05406 #ifdef PUSH_ROUNDING
05407   if (passed_mode != BLKmode)
05408     sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
05409 #endif
05410 
05411   /* Pad_below needs the pre-rounded size to know how much to pad below
05412      so this must be done before rounding up.  */
05413   if (where_pad == downward
05414     /* However, BLKmode args passed in regs have their padding done elsewhere.
05415        The stack slot must be able to hold the entire register.  */
05416       && !(in_regs && passed_mode == BLKmode))
05417     pad_below (offset_ptr, passed_mode, sizetree);
05418 
05419   if (where_pad != none
05420       && (!host_integerp (sizetree, 1)
05421     || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
05422     sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
05423 
05424   ADD_PARM_SIZE (*arg_size_ptr, sizetree);
05425 #endif /* ARGS_GROW_DOWNWARD */
05426 }
05427 
05428 /* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
05429    BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */
05430 
05431 static void
05432 pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
05433      struct args_size *offset_ptr;
05434      int boundary;
05435      struct args_size *alignment_pad;
05436 {
05437   tree save_var = NULL_TREE;
05438   HOST_WIDE_INT save_constant = 0;
05439 
05440   int boundary_in_bytes = boundary / BITS_PER_UNIT;
05441 
05442   if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
05443     {
05444       save_var = offset_ptr->var;
05445       save_constant = offset_ptr->constant;
05446     }
05447 
05448   alignment_pad->var = NULL_TREE;
05449   alignment_pad->constant = 0;
05450 
05451   if (boundary > BITS_PER_UNIT)
05452     {
05453       if (offset_ptr->var)
05454   {
05455     offset_ptr->var =
05456 #ifdef ARGS_GROW_DOWNWARD
05457       round_down
05458 #else
05459       round_up
05460 #endif
05461         (ARGS_SIZE_TREE (*offset_ptr),
05462          boundary / BITS_PER_UNIT);
05463     offset_ptr->constant = 0; /*?*/
05464     if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
05465       alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
05466                save_var);
05467   }
05468       else
05469   {
05470     offset_ptr->constant =
05471 #ifdef ARGS_GROW_DOWNWARD
05472       FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
05473 #else
05474       CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
05475 #endif
05476       if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
05477         alignment_pad->constant = offset_ptr->constant - save_constant;
05478   }
05479     }
05480 }
05481 
05482 static void
05483 pad_below (offset_ptr, passed_mode, sizetree)
05484      struct args_size *offset_ptr;
05485      enum machine_mode passed_mode;
05486      tree sizetree;
05487 {
05488   if (passed_mode != BLKmode)
05489     {
05490       if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
05491   offset_ptr->constant
05492     += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
05493          / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
05494         - GET_MODE_SIZE (passed_mode));
05495     }
05496   else
05497     {
05498       if (TREE_CODE (sizetree) != INTEGER_CST
05499     || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
05500   {
05501     /* Round the size up to multiple of PARM_BOUNDARY bits.  */
05502     tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
05503     /* Add it in.  */
05504     ADD_PARM_SIZE (*offset_ptr, s2);
05505     SUB_PARM_SIZE (*offset_ptr, sizetree);
05506   }
05507     }
05508 }
05509 
05510 /* Walk the tree of blocks describing the binding levels within a function
05511    and warn about uninitialized variables.
05512    This is done after calling flow_analysis and before global_alloc
05513    clobbers the pseudo-regs to hard regs.  */
05514 
05515 void
05516 uninitialized_vars_warning (block)
05517      tree block;
05518 {
05519   tree decl, sub;
05520   for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
05521     {
05522       if (warn_uninitialized
05523     && TREE_CODE (decl) == VAR_DECL
05524     /* These warnings are unreliable for and aggregates
05525        because assigning the fields one by one can fail to convince
05526        flow.c that the entire aggregate was initialized.
05527        Unions are troublesome because members may be shorter.  */
05528     && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
05529     && DECL_RTL (decl) != 0
05530     && GET_CODE (DECL_RTL (decl)) == REG
05531     /* Global optimizations can make it difficult to determine if a
05532        particular variable has been initialized.  However, a VAR_DECL
05533        with a nonzero DECL_INITIAL had an initializer, so do not
05534        claim it is potentially uninitialized.
05535 
05536        We do not care about the actual value in DECL_INITIAL, so we do
05537        not worry that it may be a dangling pointer.  */
05538     && DECL_INITIAL (decl) == NULL_TREE
05539     && regno_uninitialized (REGNO (DECL_RTL (decl))))
05540   warning_with_decl (decl,
05541          "`%s' might be used uninitialized in this function");
05542       if (extra_warnings
05543     && TREE_CODE (decl) == VAR_DECL
05544     && DECL_RTL (decl) != 0
05545     && GET_CODE (DECL_RTL (decl)) == REG
05546     && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
05547   warning_with_decl (decl,
05548          "variable `%s' might be clobbered by `longjmp' or `vfork'");
05549     }
05550   for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
05551     uninitialized_vars_warning (sub);
05552 }
05553 
05554 /* Do the appropriate part of uninitialized_vars_warning
05555    but for arguments instead of local variables.  */
05556 
05557 void
05558 setjmp_args_warning ()
05559 {
05560   tree decl;
05561   for (decl = DECL_ARGUMENTS (current_function_decl);
05562        decl; decl = TREE_CHAIN (decl))
05563     if (DECL_RTL (decl) != 0
05564   && GET_CODE (DECL_RTL (decl)) == REG
05565   && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
05566       warning_with_decl (decl,
05567        "argument `%s' might be clobbered by `longjmp' or `vfork'");
05568 }
05569 
05570 /* If this function call setjmp, put all vars into the stack
05571    unless they were declared `register'.  */
05572 
05573 void
05574 setjmp_protect (block)
05575      tree block;
05576 {
05577   tree decl, sub;
05578   for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
05579     if ((TREE_CODE (decl) == VAR_DECL
05580    || TREE_CODE (decl) == PARM_DECL)
05581   && DECL_RTL (decl) != 0
05582   && (GET_CODE (DECL_RTL (decl)) == REG
05583       || (GET_CODE (DECL_RTL (decl)) == MEM
05584     && GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF))
05585   /* If this variable came from an inline function, it must be
05586      that its life doesn't overlap the setjmp.  If there was a
05587      setjmp in the function, it would already be in memory.  We
05588      must exclude such variable because their DECL_RTL might be
05589      set to strange things such as virtual_stack_vars_rtx.  */
05590   && ! DECL_FROM_INLINE (decl)
05591   && (
05592 #ifdef NON_SAVING_SETJMP
05593       /* If longjmp doesn't restore the registers,
05594          don't put anything in them.  */
05595       NON_SAVING_SETJMP
05596       ||
05597 #endif
05598       ! DECL_REGISTER (decl)))
05599       put_var_into_stack (decl, /*rescan=*/true);
05600   for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
05601     setjmp_protect (sub);
05602 }
05603 
05604 /* Like the previous function, but for args instead of local variables.  */
05605 
05606 void
05607 setjmp_protect_args ()
05608 {
05609   tree decl;
05610   for (decl = DECL_ARGUMENTS (current_function_decl);
05611        decl; decl = TREE_CHAIN (decl))
05612     if ((TREE_CODE (decl) == VAR_DECL
05613    || TREE_CODE (decl) == PARM_DECL)
05614   && DECL_RTL (decl) != 0
05615   && (GET_CODE (DECL_RTL (decl)) == REG
05616       || (GET_CODE (DECL_RTL (decl)) == MEM
05617     && GET_CODE (XEXP (DECL_RTL (decl), 0)) == ADDRESSOF))
05618   && (
05619       /* If longjmp doesn't restore the registers,
05620          don't put anything in them.  */
05621 #ifdef NON_SAVING_SETJMP
05622       NON_SAVING_SETJMP
05623       ||
05624 #endif
05625       ! DECL_REGISTER (decl)))
05626       put_var_into_stack (decl, /*rescan=*/true);
05627 }
05628 
05629 /* Return the context-pointer register corresponding to DECL,
05630    or 0 if it does not need one.  */
05631 
05632 rtx
05633 lookup_static_chain (decl)
05634      tree decl;
05635 {
05636   tree context = decl_function_context (decl);
05637   tree link;
05638 
05639   if (context == 0
05640       || (TREE_CODE (decl) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (decl)))
05641     return 0;
05642 
05643   /* We treat inline_function_decl as an alias for the current function
05644      because that is the inline function whose vars, types, etc.
05645      are being merged into the current function.
05646      See expand_inline_function.  */
05647   if (context == current_function_decl || context == inline_function_decl)
05648     return virtual_stack_vars_rtx;
05649 
05650   for (link = context_display; link; link = TREE_CHAIN (link))
05651     if (TREE_PURPOSE (link) == context)
05652       return RTL_EXPR_RTL (TREE_VALUE (link));
05653 
05654   abort ();
05655 }
05656 
05657 /* Convert a stack slot address ADDR for variable VAR
05658    (from a containing function)
05659    into an address valid in this function (using a static chain).  */
05660 
05661 rtx
05662 fix_lexical_addr (addr, var)
05663      rtx addr;
05664      tree var;
05665 {
05666   rtx basereg;
05667   HOST_WIDE_INT displacement;
05668   tree context = decl_function_context (var);
05669   struct function *fp;
05670   rtx base = 0;
05671 
05672   /* If this is the present function, we need not do anything.  */
05673   if (context == current_function_decl || context == inline_function_decl)
05674     return addr;
05675 
05676   fp = find_function_data (context);
05677 
05678   if (GET_CODE (addr) == ADDRESSOF && GET_CODE (XEXP (addr, 0)) == MEM)
05679     addr = XEXP (XEXP (addr, 0), 0);
05680 
05681   /* Decode given address as base reg plus displacement.  */
05682   if (GET_CODE (addr) == REG)
05683     basereg = addr, displacement = 0;
05684   else if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
05685     basereg = XEXP (addr, 0), displacement = INTVAL (XEXP (addr, 1));
05686   else
05687     abort ();
05688 
05689   /* We accept vars reached via the containing function's
05690      incoming arg pointer and via its stack variables pointer.  */
05691   if (basereg == fp->internal_arg_pointer)
05692     {
05693       /* If reached via arg pointer, get the arg pointer value
05694    out of that function's stack frame.
05695 
05696    There are two cases:  If a separate ap is needed, allocate a
05697    slot in the outer function for it and dereference it that way.
05698    This is correct even if the real ap is actually a pseudo.
05699    Otherwise, just adjust the offset from the frame pointer to
05700    compensate.  */
05701 
05702 #ifdef NEED_SEPARATE_AP
05703       rtx addr;
05704 
05705       addr = get_arg_pointer_save_area (fp);
05706       addr = fix_lexical_addr (XEXP (addr, 0), var);
05707       addr = memory_address (Pmode, addr);
05708 
05709       base = gen_rtx_MEM (Pmode, addr);
05710       set_mem_alias_set (base, get_frame_alias_set ());
05711       base = copy_to_reg (base);
05712 #else
05713       displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
05714       base = lookup_static_chain (var);
05715 #endif
05716     }
05717 
05718   else if (basereg == virtual_stack_vars_rtx)
05719     {
05720       /* This is the same code as lookup_static_chain, duplicated here to
05721    avoid an extra call to decl_function_context.  */
05722       tree link;
05723 
05724       for (link = context_display; link; link = TREE_CHAIN (link))
05725   if (TREE_PURPOSE (link) == context)
05726     {
05727       base = RTL_EXPR_RTL (TREE_VALUE (link));
05728       break;
05729     }
05730     }
05731 
05732   if (base == 0)
05733     abort ();
05734 
05735   /* Use same offset, relative to appropriate static chain or argument
05736      pointer.  */
05737   return plus_constant (base, displacement);
05738 }
05739 
05740 /* Return the address of the trampoline for entering nested fn FUNCTION.
05741    If necessary, allocate a trampoline (in the stack frame)
05742    and emit rtl to initialize its contents (at entry to this function).  */
05743 
05744 rtx
05745 trampoline_address (function)
05746      tree function;
05747 {
05748   tree link;
05749   tree rtlexp;
05750   rtx tramp;
05751   struct function *fp;
05752   tree fn_context;
05753 
05754   /* Find an existing trampoline and return it.  */
05755   for (link = trampoline_list; link; link = TREE_CHAIN (link))
05756     if (TREE_PURPOSE (link) == function)
05757       return
05758   adjust_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));
05759 
05760   for (fp = outer_function_chain; fp; fp = fp->outer)
05761     for (link = fp->x_trampoline_list; link; link = TREE_CHAIN (link))
05762       if (TREE_PURPOSE (link) == function)
05763   {
05764     tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
05765             function);
05766     return adjust_trampoline_addr (tramp);
05767   }
05768 
05769   /* None exists; we must make one.  */
05770 
05771   /* Find the `struct function' for the function containing FUNCTION.  */
05772   fp = 0;
05773   fn_context = decl_function_context (function);
05774   if (fn_context != current_function_decl
05775       && fn_context != inline_function_decl)
05776     fp = find_function_data (fn_context);
05777 
05778   /* Allocate run-time space for this trampoline
05779      (usually in the defining function's stack frame).  */
05780 #ifdef ALLOCATE_TRAMPOLINE
05781   tramp = ALLOCATE_TRAMPOLINE (fp);
05782 #else
05783   /* If rounding needed, allocate extra space
05784      to ensure we have TRAMPOLINE_SIZE bytes left after rounding up.  */
05785 #define TRAMPOLINE_REAL_SIZE \
05786   (TRAMPOLINE_SIZE + (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT) - 1)
05787   tramp = assign_stack_local_1 (BLKmode, TRAMPOLINE_REAL_SIZE, 0,
05788         fp ? fp : cfun);
05789 #endif
05790 
05791   /* Record the trampoline for reuse and note it for later initialization
05792      by expand_function_end.  */
05793   if (fp != 0)
05794     {
05795       rtlexp = make_node (RTL_EXPR);
05796       RTL_EXPR_RTL (rtlexp) = tramp;
05797       fp->x_trampoline_list = tree_cons (function, rtlexp,
05798            fp->x_trampoline_list);
05799     }
05800   else
05801     {
05802       /* Make the RTL_EXPR node temporary, not momentary, so that the
05803    trampoline_list doesn't become garbage.  */
05804       rtlexp = make_node (RTL_EXPR);
05805 
05806       RTL_EXPR_RTL (rtlexp) = tramp;
05807       trampoline_list = tree_cons (function, rtlexp, trampoline_list);
05808     }
05809 
05810   tramp = fix_lexical_addr (XEXP (tramp, 0), function);
05811   return adjust_trampoline_addr (tramp);
05812 }
05813 
05814 /* Given a trampoline address,
05815    round it to multiple of TRAMPOLINE_ALIGNMENT.  */
05816 
05817 static rtx
05818 round_trampoline_addr (tramp)
05819      rtx tramp;
05820 {
05821   /* Round address up to desired boundary.  */
05822   rtx temp = gen_reg_rtx (Pmode);
05823   rtx addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
05824   rtx mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
05825 
05826   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
05827              temp, 0, OPTAB_LIB_WIDEN);
05828   tramp = expand_simple_binop (Pmode, AND, temp, mask,
05829              temp, 0, OPTAB_LIB_WIDEN);
05830 
05831   return tramp;
05832 }
05833 
05834 /* Given a trampoline address, round it then apply any
05835    platform-specific adjustments so that the result can be used for a
05836    function call .  */
05837 
05838 static rtx
05839 adjust_trampoline_addr (tramp)
05840      rtx tramp;
05841 {
05842   tramp = round_trampoline_addr (tramp);
05843 #ifdef TRAMPOLINE_ADJUST_ADDRESS
05844   TRAMPOLINE_ADJUST_ADDRESS (tramp);
05845 #endif
05846   return tramp;
05847 }
05848 
05849 /* Put all this function's BLOCK nodes including those that are chained
05850    onto the first block into a vector, and return it.
05851    Also store in each NOTE for the beginning or end of a block
05852    the index of that block in the vector.
05853    The arguments are BLOCK, the chain of top-level blocks of the function,
05854    and INSNS, the insn chain of the function.  */
05855 
05856 void
05857 identify_blocks ()
05858 {
05859   int n_blocks;
05860   tree *block_vector, *last_block_vector;
05861   tree *block_stack;
05862   tree block = DECL_INITIAL (current_function_decl);
05863 
05864   if (block == 0)
05865     return;
05866 
05867   /* Fill the BLOCK_VECTOR with all of the BLOCKs in this function, in
05868      depth-first order.  */
05869   block_vector = get_block_vector (block, &n_blocks);
05870   block_stack = (tree *) xmalloc (n_blocks * sizeof (tree));
05871 
05872   last_block_vector = identify_blocks_1 (get_insns (),
05873            block_vector + 1,
05874            block_vector + n_blocks,
05875            block_stack);
05876 
05877   /* If we didn't use all of the subblocks, we've misplaced block notes.  */
05878   /* ??? This appears to happen all the time.  Latent bugs elsewhere?  */
05879   if (0 && last_block_vector != block_vector + n_blocks)
05880     abort ();
05881 
05882   free (block_vector);
05883   free (block_stack);
05884 }
05885 
05886 /* Subroutine of identify_blocks.  Do the block substitution on the
05887    insn chain beginning with INSNS.  Recurse for CALL_PLACEHOLDER chains.
05888 
05889    BLOCK_STACK is pushed and popped for each BLOCK_BEGIN/BLOCK_END pair.
05890    BLOCK_VECTOR is incremented for each block seen.  */
05891 
05892 static tree *
05893 identify_blocks_1 (insns, block_vector, end_block_vector, orig_block_stack)
05894      rtx insns;
05895      tree *block_vector;
05896      tree *end_block_vector;
05897      tree *orig_block_stack;
05898 {
05899   rtx insn;
05900   tree *block_stack = orig_block_stack;
05901 
05902   for (insn = insns; insn; insn = NEXT_INSN (insn))
05903     {
05904       if (GET_CODE (insn) == NOTE)
05905   {
05906     if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
05907       {
05908         tree b;
05909 
05910         /* If there are more block notes than BLOCKs, something
05911      is badly wrong.  */
05912         if (block_vector == end_block_vector)
05913     abort ();
05914 
05915         b = *block_vector++;
05916         NOTE_BLOCK (insn) = b;
05917         *block_stack++ = b;
05918       }
05919     else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
05920       {
05921         /* If there are more NOTE_INSN_BLOCK_ENDs than
05922      NOTE_INSN_BLOCK_BEGs, something is badly wrong.  */
05923         if (block_stack == orig_block_stack)
05924     abort ();
05925 
05926         NOTE_BLOCK (insn) = *--block_stack;
05927       }
05928   }
05929       else if (GET_CODE (insn) == CALL_INSN
05930          && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
05931   {
05932     rtx cp = PATTERN (insn);
05933 
05934     block_vector = identify_blocks_1 (XEXP (cp, 0), block_vector,
05935               end_block_vector, block_stack);
05936     if (XEXP (cp, 1))
05937       block_vector = identify_blocks_1 (XEXP (cp, 1), block_vector,
05938                 end_block_vector, block_stack);
05939     if (XEXP (cp, 2))
05940       block_vector = identify_blocks_1 (XEXP (cp, 2), block_vector,
05941                 end_block_vector, block_stack);
05942   }
05943     }
05944 
05945   /* If there are more NOTE_INSN_BLOCK_BEGINs than NOTE_INSN_BLOCK_ENDs,
05946      something is badly wrong.  */
05947   if (block_stack != orig_block_stack)
05948     abort ();
05949 
05950   return block_vector;
05951 }
05952 
05953 /* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
05954    and create duplicate blocks.  */
05955 /* ??? Need an option to either create block fragments or to create
05956    abstract origin duplicates of a source block.  It really depends
05957    on what optimization has been performed.  */
05958 
05959 void
05960 reorder_blocks ()
05961 {
05962   tree block = DECL_INITIAL (current_function_decl);
05963   varray_type block_stack;
05964 
05965   if (block == NULL_TREE)
05966     return;
05967 
05968   VARRAY_TREE_INIT (block_stack, 10, "block_stack");
05969 
05970   /* Reset the TREE_ASM_WRITTEN bit for all blocks.  */
05971   reorder_blocks_0 (block);
05972 
05973   /* Prune the old trees away, so that they don't get in the way.  */
05974   BLOCK_SUBBLOCKS (block) = NULL_TREE;
05975   BLOCK_CHAIN (block) = NULL_TREE;
05976 
05977   /* Recreate the block tree from the note nesting.  */
05978   reorder_blocks_1 (get_insns (), block, &block_stack);
05979   BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block));
05980 
05981   /* Remove deleted blocks from the block fragment chains.  */
05982   reorder_fix_fragments (block);
05983 }
05984 
05985 /* Helper function for reorder_blocks.  Reset TREE_ASM_WRITTEN.  */
05986 
05987 static void
05988 reorder_blocks_0 (block)
05989      tree block;
05990 {
05991   while (block)
05992     {
05993       TREE_ASM_WRITTEN (block) = 0;
05994       reorder_blocks_0 (BLOCK_SUBBLOCKS (block));
05995       block = BLOCK_CHAIN (block);
05996     }
05997 }
05998 
05999 static void
06000 reorder_blocks_1 (insns, current_block, p_block_stack)
06001      rtx insns;
06002      tree current_block;
06003      varray_type *p_block_stack;
06004 {
06005   rtx insn;
06006 
06007   for (insn = insns; insn; insn = NEXT_INSN (insn))
06008     {
06009       if (GET_CODE (insn) == NOTE)
06010   {
06011     if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
06012       {
06013         tree block = NOTE_BLOCK (insn);
06014 
06015         /* If we have seen this block before, that means it now
06016      spans multiple address regions.  Create a new fragment.  */
06017         if (TREE_ASM_WRITTEN (block))
06018     {
06019       tree new_block = copy_node (block);
06020       tree origin;
06021 
06022       origin = (BLOCK_FRAGMENT_ORIGIN (block)
06023           ? BLOCK_FRAGMENT_ORIGIN (block)
06024           : block);
06025       BLOCK_FRAGMENT_ORIGIN (new_block) = origin;
06026       BLOCK_FRAGMENT_CHAIN (new_block)
06027         = BLOCK_FRAGMENT_CHAIN (origin);
06028       BLOCK_FRAGMENT_CHAIN (origin) = new_block;
06029 
06030       NOTE_BLOCK (insn) = new_block;
06031       block = new_block;
06032     }
06033 
06034         BLOCK_SUBBLOCKS (block) = 0;
06035         TREE_ASM_WRITTEN (block) = 1;
06036         BLOCK_SUPERCONTEXT (block) = current_block;
06037         BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
06038         BLOCK_SUBBLOCKS (current_block) = block;
06039         current_block = block;
06040         VARRAY_PUSH_TREE (*p_block_stack, block);
06041       }
06042     else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
06043       {
06044         NOTE_BLOCK (insn) = VARRAY_TOP_TREE (*p_block_stack);
06045         VARRAY_POP (*p_block_stack);
06046         BLOCK_SUBBLOCKS (current_block)
06047     = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
06048         current_block = BLOCK_SUPERCONTEXT (current_block);
06049       }
06050   }
06051       else if (GET_CODE (insn) == CALL_INSN
06052          && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
06053   {
06054     rtx cp = PATTERN (insn);
06055     reorder_blocks_1 (XEXP (cp, 0), current_block, p_block_stack);
06056     if (XEXP (cp, 1))
06057       reorder_blocks_1 (XEXP (cp, 1), current_block, p_block_stack);
06058     if (XEXP (cp, 2))
06059       reorder_blocks_1 (XEXP (cp, 2), current_block, p_block_stack);
06060   }
06061     }
06062 }
06063 
06064 /* Rationalize BLOCK_FRAGMENT_ORIGIN.  If an origin block no longer
06065    appears in the block tree, select one of the fragments to become
06066    the new origin block.  */
06067 
06068 static void
06069 reorder_fix_fragments (block)
06070      tree block;
06071 {
06072   while (block)
06073     {
06074       tree dup_origin = BLOCK_FRAGMENT_ORIGIN (block);
06075       tree new_origin = NULL_TREE;
06076 
06077       if (dup_origin)
06078   {
06079     if (! TREE_ASM_WRITTEN (dup_origin))
06080       {
06081         new_origin = BLOCK_FRAGMENT_CHAIN (dup_origin);
06082 
06083         /* Find the first of the remaining fragments.  There must
06084      be at least one -- the current block.  */
06085         while (! TREE_ASM_WRITTEN (new_origin))
06086     new_origin = BLOCK_FRAGMENT_CHAIN (new_origin);
06087         BLOCK_FRAGMENT_ORIGIN (new_origin) = NULL_TREE;
06088       }
06089   }
06090       else if (! dup_origin)
06091   new_origin = block;
06092 
06093       /* Re-root the rest of the fragments to the new origin.  In the
06094    case that DUP_ORIGIN was null, that means BLOCK was the origin
06095    of a chain of fragments and we want to remove those fragments
06096    that didn't make it to the output.  */
06097       if (new_origin)
06098   {
06099     tree *pp = &BLOCK_FRAGMENT_CHAIN (new_origin);
06100     tree chain = *pp;
06101 
06102     while (chain)
06103       {
06104         if (TREE_ASM_WRITTEN (chain))
06105     {
06106       BLOCK_FRAGMENT_ORIGIN (chain) = new_origin;
06107       *pp = chain;
06108       pp = &BLOCK_FRAGMENT_CHAIN (chain);
06109     }
06110         chain = BLOCK_FRAGMENT_CHAIN (chain);
06111       }
06112     *pp = NULL_TREE;
06113   }
06114 
06115       reorder_fix_fragments (BLOCK_SUBBLOCKS (block));
06116       block = BLOCK_CHAIN (block);
06117     }
06118 }
06119 
06120 /* Reverse the order of elements in the chain T of blocks,
06121    and return the new head of the chain (old last element).  */
06122 
06123 static tree
06124 blocks_nreverse (t)
06125      tree t;
06126 {
06127   tree prev = 0, decl, next;
06128   for (decl = t; decl; decl = next)
06129     {
06130       next = BLOCK_CHAIN (decl);
06131       BLOCK_CHAIN (decl) = prev;
06132       prev = decl;
06133     }
06134   return prev;
06135 }
06136 
06137 /* Count the subblocks of the list starting with BLOCK.  If VECTOR is
06138    non-NULL, list them all into VECTOR, in a depth-first preorder
06139    traversal of the block tree.  Also clear TREE_ASM_WRITTEN in all
06140    blocks.  */
06141 
06142 static int
06143 all_blocks (block, vector)
06144      tree block;
06145      tree *vector;
06146 {
06147   int n_blocks = 0;
06148 
06149   while (block)
06150     {
06151       TREE_ASM_WRITTEN (block) = 0;
06152 
06153       /* Record this block.  */
06154       if (vector)
06155   vector[n_blocks] = block;
06156 
06157       ++n_blocks;
06158 
06159       /* Record the subblocks, and their subblocks...  */
06160       n_blocks += all_blocks (BLOCK_SUBBLOCKS (block),
06161             vector ? vector + n_blocks : 0);
06162       block = BLOCK_CHAIN (block);
06163     }
06164 
06165   return n_blocks;
06166 }
06167 
06168 /* Return a vector containing all the blocks rooted at BLOCK.  The
06169    number of elements in the vector is stored in N_BLOCKS_P.  The
06170    vector is dynamically allocated; it is the caller's responsibility
06171    to call `free' on the pointer returned.  */
06172 
06173 static tree *
06174 get_block_vector (block, n_blocks_p)
06175      tree block;
06176      int *n_blocks_p;
06177 {
06178   tree *block_vector;
06179 
06180   *n_blocks_p = all_blocks (block, NULL);
06181   block_vector = (tree *) xmalloc (*n_blocks_p * sizeof (tree));
06182   all_blocks (block, block_vector);
06183 
06184   return block_vector;
06185 }
06186 
06187 static int next_block_index = 2;
06188 
06189 /* Set BLOCK_NUMBER for all the blocks in FN.  */
06190 
06191 void
06192 number_blocks (fn)
06193      tree fn;
06194 {
06195   int i;
06196   int n_blocks;
06197   tree *block_vector;
06198 
06199   /* For SDB and XCOFF debugging output, we start numbering the blocks
06200      from 1 within each function, rather than keeping a running
06201      count.  */
06202 #if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
06203   if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG)
06204     next_block_index = 1;
06205 #endif
06206 
06207   block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks);
06208 
06209   /* The top-level BLOCK isn't numbered at all.  */
06210   for (i = 1; i < n_blocks; ++i)
06211     /* We number the blocks from two.  */
06212     BLOCK_NUMBER (block_vector[i]) = next_block_index++;
06213 
06214   free (block_vector);
06215 
06216   return;
06217 }
06218 
06219 /* If VAR is present in a subblock of BLOCK, return the subblock.  */
06220 
06221 tree
06222 debug_find_var_in_block_tree (var, block)
06223      tree var;
06224      tree block;
06225 {
06226   tree t;
06227 
06228   for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
06229     if (t == var)
06230       return block;
06231 
06232   for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
06233     {
06234       tree ret = debug_find_var_in_block_tree (var, t);
06235       if (ret)
06236   return ret;
06237     }
06238 
06239   return NULL_TREE;
06240 }
06241 
06242 /* Allocate a function structure and reset its contents to the defaults.  */
06243 
06244 static void
06245 prepare_function_start ()
06246 {
06247   cfun = (struct function *) ggc_alloc_cleared (sizeof (struct function));
06248 
06249   init_stmt_for_function ();
06250   init_eh_for_function ();
06251 
06252   cse_not_expected = ! optimize;
06253 
06254   /* Caller save not needed yet.  */
06255   caller_save_needed = 0;
06256 
06257   /* No stack slots have been made yet.  */
06258   stack_slot_list = 0;
06259 
06260   current_function_has_nonlocal_label = 0;
06261   current_function_has_nonlocal_goto = 0;
06262 
06263   /* There is no stack slot for handling nonlocal gotos.  */
06264   nonlocal_goto_handler_slots = 0;
06265   nonlocal_goto_stack_level = 0;
06266 
06267   /* No labels have been declared for nonlocal use.  */
06268   nonlocal_labels = 0;
06269   nonlocal_goto_handler_labels = 0;
06270 
06271   /* No function calls so far in this function.  */
06272   function_call_count = 0;
06273 
06274   /* No parm regs have been allocated.
06275      (This is important for output_inline_function.)  */
06276   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
06277 
06278   /* Initialize the RTL mechanism.  */
06279   init_emit ();
06280 
06281   /* Initialize the queue of pending postincrement and postdecrements,
06282      and some other info in expr.c.  */
06283   init_expr ();
06284 
06285   /* We haven't done register allocation yet.  */
06286   reg_renumber = 0;
06287 
06288   init_varasm_status (cfun);
06289 
06290   /* Clear out data used for inlining.  */
06291   cfun->inlinable = 0;
06292   cfun->original_decl_initial = 0;
06293   cfun->original_arg_vector = 0;
06294 
06295   cfun->stack_alignment_needed = STACK_BOUNDARY;
06296   cfun->preferred_stack_boundary = STACK_BOUNDARY;
06297 
06298   /* Set if a call to setjmp is seen.  */
06299   current_function_calls_setjmp = 0;
06300 
06301   /* Set if a call to longjmp is seen.  */
06302   current_function_calls_longjmp = 0;
06303 
06304   current_function_calls_alloca = 0;
06305   current_function_contains_functions = 0;
06306   current_function_is_leaf = 0;
06307   current_function_nothrow = 0;
06308   current_function_sp_is_unchanging = 0;
06309   current_function_uses_only_leaf_regs = 0;
06310   current_function_has_computed_jump = 0;
06311   current_function_is_thunk = 0;
06312 
06313   current_function_returns_pcc_struct = 0;
06314   current_function_returns_struct = 0;
06315   current_function_epilogue_delay_list = 0;
06316   current_function_uses_const_pool = 0;
06317   current_function_uses_pic_offset_table = 0;
06318   current_function_cannot_inline = 0;
06319 
06320   /* We have not yet needed to make a label to jump to for tail-recursion.  */
06321   tail_recursion_label = 0;
06322 
06323   /* We haven't had a need to make a save area for ap yet.  */
06324   arg_pointer_save_area = 0;
06325 
06326   /* No stack slots allocated yet.  */
06327   frame_offset = 0;
06328 
06329   /* No SAVE_EXPRs in this function yet.  */
06330   save_expr_regs = 0;
06331 
06332   /* No RTL_EXPRs in this function yet.  */
06333   rtl_expr_chain = 0;
06334 
06335   /* Set up to allocate temporaries.  */
06336   init_temp_slots ();
06337 
06338   /* Indicate that we need to distinguish between the return value of the
06339      present function and the return value of a function being called.  */
06340   rtx_equal_function_value_matters = 1;
06341 
06342   /* Indicate that we have not instantiated virtual registers yet.  */
06343   virtuals_instantiated = 0;
06344 
06345   /* Indicate that we want CONCATs now.  */
06346   generating_concat_p = 1;
06347 
06348   /* Indicate we have no need of a frame pointer yet.  */
06349   frame_pointer_needed = 0;
06350 
06351   /* By default assume not stdarg.  */
06352   current_function_stdarg = 0;
06353 
06354   /* We haven't made any trampolines for this function yet.  */
06355   trampoline_list = 0;
06356 
06357   init_pending_stack_adjust ();
06358   inhibit_defer_pop = 0;
06359 
06360   current_function_outgoing_args_size = 0;
06361 
06362   current_function_funcdef_no = funcdef_no++;
06363 
06364   cfun->arc_profile = profile_arc_flag || flag_test_coverage;
06365 
06366   cfun->arc_profile = profile_arc_flag || flag_test_coverage;
06367 
06368   cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
06369 
06370   cfun->max_jumptable_ents = 0;
06371 
06372   (*lang_hooks.function.init) (cfun);
06373   if (init_machine_status)
06374     cfun->machine = (*init_machine_status) ();
06375 }
06376 
06377 /* Initialize the rtl expansion mechanism so that we can do simple things
06378    like generate sequences.  This is used to provide a context during global
06379    initialization of some passes.  */
06380 void
06381 init_dummy_function_start ()
06382 {
06383   prepare_function_start ();
06384 }
06385 
06386 /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
06387    and initialize static variables for generating RTL for the statements
06388    of the function.  */
06389 
06390 void
06391 init_function_start (subr, filename, line)
06392      tree subr;
06393      const char *filename;
06394      int line;
06395 {
06396   prepare_function_start ();
06397 
06398   current_function_name = (*lang_hooks.decl_printable_name) (subr, 2);
06399   cfun->decl = subr;
06400 
06401   /* Nonzero if this is a nested function that uses a static chain.  */
06402 
06403   current_function_needs_context
06404     = (decl_function_context (current_function_decl) != 0
06405        && ! DECL_NO_STATIC_CHAIN (current_function_decl));
06406 
06407   /* Within function body, compute a type's size as soon it is laid out.  */
06408   immediate_size_expand++;
06409 
06410   /* Prevent ever trying to delete the first instruction of a function.
06411      Also tell final how to output a linenum before the function prologue.
06412      Note linenums could be missing, e.g. when compiling a Java .class file.  */
06413   if (line > 0)
06414     emit_line_note (filename, line);
06415 
06416   /* Make sure first insn is a note even if we don't want linenums.
06417      This makes sure the first insn will never be deleted.
06418      Also, final expects a note to appear there.  */
06419   emit_note (NULL, NOTE_INSN_DELETED);
06420 
06421   /* Set flags used by final.c.  */
06422   if (aggregate_value_p (DECL_RESULT (subr)))
06423     {
06424 #ifdef PCC_STATIC_STRUCT_RETURN
06425       current_function_returns_pcc_struct = 1;
06426 #endif
06427       current_function_returns_struct = 1;
06428     }
06429 
06430   /* Warn if this value is an aggregate type,
06431      regardless of which calling convention we are using for it.  */
06432   if (warn_aggregate_return
06433       && AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
06434     warning ("function returns an aggregate");
06435 
06436   current_function_returns_pointer
06437     = POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
06438 }
06439 
06440 /* Make sure all values used by the optimization passes have sane
06441    defaults.  */
06442 void
06443 init_function_for_compilation ()
06444 {
06445   reg_renumber = 0;
06446 
06447   /* No prologue/epilogue insns yet.  */
06448   VARRAY_GROW (prologue, 0);
06449   VARRAY_GROW (epilogue, 0);
06450   VARRAY_GROW (sibcall_epilogue, 0);
06451 }
06452 
06453 /* Expand a call to __main at the beginning of a possible main function.  */
06454 
06455 #if defined(INIT_SECTION_ASM_OP) && !defined(INVOKE__main)
06456 #undef HAS_INIT_SECTION
06457 #define HAS_INIT_SECTION
06458 #endif
06459 
06460 void
06461 expand_main_function ()
06462 {
06463 #ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
06464   if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN)
06465     {
06466       int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
06467       rtx tmp, seq;
06468 
06469       start_sequence ();
06470       /* Forcibly align the stack.  */
06471 #ifdef STACK_GROWS_DOWNWARD
06472       tmp = expand_simple_binop (Pmode, AND, stack_pointer_rtx, GEN_INT(-align),
06473          stack_pointer_rtx, 1, OPTAB_WIDEN);
06474 #else
06475       tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
06476          GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN);
06477       tmp = expand_simple_binop (Pmode, AND, tmp, GEN_INT (-align),
06478          stack_pointer_rtx, 1, OPTAB_WIDEN);
06479 #endif
06480       if (tmp != stack_pointer_rtx)
06481   emit_move_insn (stack_pointer_rtx, tmp);
06482 
06483       /* Enlist allocate_dynamic_stack_space to pick up the pieces.  */
06484       tmp = force_reg (Pmode, const0_rtx);
06485       allocate_dynamic_stack_space (tmp, NULL_RTX, BIGGEST_ALIGNMENT);
06486       seq = get_insns ();
06487       end_sequence ();
06488 
06489       for (tmp = get_last_insn (); tmp; tmp = PREV_INSN (tmp))
06490   if (NOTE_P (tmp) && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_FUNCTION_BEG)
06491     break;
06492       if (tmp)
06493   emit_insn_before (seq, tmp);
06494       else
06495   emit_insn (seq);
06496     }
06497 #endif
06498 
06499 #ifndef HAS_INIT_SECTION
06500   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, NAME__MAIN), LCT_NORMAL,
06501          VOIDmode, 0);
06502 #endif
06503 }
06504 
06505 /* The PENDING_SIZES represent the sizes of variable-sized types.
06506    Create RTL for the various sizes now (using temporary variables),
06507    so that we can refer to the sizes from the RTL we are generating
06508    for the current function.  The PENDING_SIZES are a TREE_LIST.  The
06509    TREE_VALUE of each node is a SAVE_EXPR.  */
06510 
06511 void
06512 expand_pending_sizes (pending_sizes)
06513      tree pending_sizes;
06514 {
06515   tree tem;
06516 
06517   /* Evaluate now the sizes of any types declared among the arguments.  */
06518   for (tem = pending_sizes; tem; tem = TREE_CHAIN (tem))
06519     {
06520       expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode, 0);
06521       /* Flush the queue in case this parameter declaration has
06522    side-effects.  */
06523       emit_queue ();
06524     }
06525 }
06526 
06527 /* Start the RTL for a new function, and set variables used for
06528    emitting RTL.
06529    SUBR is the FUNCTION_DECL node.
06530    PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
06531    the function's parameters, which must be run at any return statement.  */
06532 
06533 void
06534 expand_function_start (subr, parms_have_cleanups)
06535      tree subr;
06536      int parms_have_cleanups;
06537 {
06538   tree tem;
06539   rtx last_ptr = NULL_RTX;
06540 
06541   /* Make sure volatile mem refs aren't considered
06542      valid operands of arithmetic insns.  */
06543   init_recog_no_volatile ();
06544 
06545   current_function_instrument_entry_exit
06546     = (flag_instrument_function_entry_exit
06547        && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
06548 
06549   current_function_profile
06550     = (profile_flag
06551        && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr));
06552 
06553   current_function_limit_stack
06554     = (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr));
06555 
06556   /* If function gets a static chain arg, store it in the stack frame.
06557      Do this first, so it gets the first stack slot offset.  */
06558   if (current_function_needs_context)
06559     {
06560       last_ptr = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
06561 
06562       /* Delay copying static chain if it is not a register to avoid
06563    conflicts with regs used for parameters.  */
06564       if (! SMALL_REGISTER_CLASSES
06565     || GET_CODE (static_chain_incoming_rtx) == REG)
06566   emit_move_insn (last_ptr, static_chain_incoming_rtx);
06567     }
06568 
06569   /* If the parameters of this function need cleaning up, get a label
06570      for the beginning of the code which executes those cleanups.  This must
06571      be done before doing anything with return_label.  */
06572   if (parms_have_cleanups)
06573     cleanup_label = gen_label_rtx ();
06574   else
06575     cleanup_label = 0;
06576 
06577   /* Make the label for return statements to jump to.  Do not special
06578      case machines with special return instructions -- they will be
06579      handled later during jump, ifcvt, or epilogue creation.  */
06580   return_label = gen_label_rtx ();
06581 
06582   /* Initialize rtx used to return the value.  */
06583   /* Do this before assign_parms so that we copy the struct value address
06584      before any library calls that assign parms might generate.  */
06585 
06586   /* Decide whether to return the value in memory or in a register.  */
06587   if (aggregate_value_p (DECL_RESULT (subr)))
06588     {
06589       /* Returning something that won't go in a register.  */
06590       rtx value_address = 0;
06591 
06592 #ifdef PCC_STATIC_STRUCT_RETURN
06593       if (current_function_returns_pcc_struct)
06594   {
06595     int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
06596     value_address = assemble_static_space (size);
06597   }
06598       else
06599 #endif
06600   {
06601     /* Expect to be passed the address of a place to store the value.
06602        If it is passed as an argument, assign_parms will take care of
06603        it.  */
06604     if (struct_value_incoming_rtx)
06605       {
06606         value_address = gen_reg_rtx (Pmode);
06607         emit_move_insn (value_address, struct_value_incoming_rtx);
06608       }
06609   }
06610       if (value_address)
06611   {
06612     rtx x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), value_address);
06613     set_mem_attributes (x, DECL_RESULT (subr), 1);
06614     SET_DECL_RTL (DECL_RESULT (subr), x);
06615   }
06616     }
06617   else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
06618     /* If return mode is void, this decl rtl should not be used.  */
06619     SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX);
06620   else
06621     {
06622       /* Compute the return values into a pseudo reg, which we will copy
06623    into the true return register after the cleanups are done.  */
06624 
06625       /* In order to figure out what mode to use for the pseudo, we
06626    figure out what the mode of the eventual return register will
06627    actually be, and use that.  */
06628       rtx hard_reg
06629   = hard_function_value (TREE_TYPE (DECL_RESULT (subr)),
06630              subr, 1);
06631 
06632       /* Structures that are returned in registers are not aggregate_value_p,
06633    so we may see a PARALLEL or a REG.  */
06634       if (REG_P (hard_reg))
06635   SET_DECL_RTL (DECL_RESULT (subr), gen_reg_rtx (GET_MODE (hard_reg)));
06636       else if (GET_CODE (hard_reg) == PARALLEL)
06637   SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg));
06638       else
06639   abort ();
06640 
06641       /* Set DECL_REGISTER flag so that expand_function_end will copy the
06642    result to the real return register(s).  */
06643       DECL_REGISTER (DECL_RESULT (subr)) = 1;
06644     }
06645 
06646   /* Initialize rtx for parameters and local variables.
06647      In some cases this requires emitting insns.  */
06648 
06649   assign_parms (subr);
06650 
06651   /* Copy the static chain now if it wasn't a register.  The delay is to
06652      avoid conflicts with the parameter passing registers.  */
06653 
06654   if (SMALL_REGISTER_CLASSES && current_function_needs_context)
06655     if (GET_CODE (static_chain_incoming_rtx) != REG)
06656       emit_move_insn (last_ptr, static_chain_incoming_rtx);
06657 
06658   /* The following was moved from init_function_start.
06659      The move is supposed to make sdb output more accurate.  */
06660   /* Indicate the beginning of the function body,
06661      as opposed to parm setup.  */
06662   emit_note (NULL, NOTE_INSN_FUNCTION_BEG);
06663 
06664   if (GET_CODE (get_last_insn ()) != NOTE)
06665     emit_note (NULL, NOTE_INSN_DELETED);
06666   parm_birth_insn = get_last_insn ();
06667 
06668   context_display = 0;
06669   if (current_function_needs_context)
06670     {
06671       /* Fetch static chain values for containing functions.  */
06672       tem = decl_function_context (current_function_decl);
06673       /* Copy the static chain pointer into a pseudo.  If we have
06674    small register classes, copy the value from memory if
06675    static_chain_incoming_rtx is a REG.  */
06676       if (tem)
06677   {
06678     /* If the static chain originally came in a register, put it back
06679        there, then move it out in the next insn.  The reason for
06680        this peculiar code is to satisfy function integration.  */
06681     if (SMALL_REGISTER_CLASSES
06682         && GET_CODE (static_chain_incoming_rtx) == REG)
06683       emit_move_insn (static_chain_incoming_rtx, last_ptr);
06684     last_ptr = copy_to_reg (static_chain_incoming_rtx);
06685   }
06686 
06687       while (tem)
06688   {
06689     tree rtlexp = make_node (RTL_EXPR);
06690 
06691     RTL_EXPR_RTL (rtlexp) = last_ptr;
06692     context_display = tree_cons (tem, rtlexp, context_display);
06693     tem = decl_function_context (tem);
06694     if (tem == 0)
06695       break;
06696     /* Chain thru stack frames, assuming pointer to next lexical frame
06697        is found at the place we always store it.  */
06698 #ifdef FRAME_GROWS_DOWNWARD
06699     last_ptr = plus_constant (last_ptr,
06700             -(HOST_WIDE_INT) GET_MODE_SIZE (Pmode));
06701 #endif
06702     last_ptr = gen_rtx_MEM (Pmode, memory_address (Pmode, last_ptr));
06703     set_mem_alias_set (last_ptr, get_frame_alias_set ());
06704     last_ptr = copy_to_reg (last_ptr);
06705 
06706     /* If we are not optimizing, ensure that we know that this
06707        piece of context is live over the entire function.  */
06708     if (! optimize)
06709       save_expr_regs = gen_rtx_EXPR_LIST (VOIDmode, last_ptr,
06710             save_expr_regs);
06711   }
06712     }
06713 
06714   if (current_function_instrument_entry_exit)
06715     {
06716       rtx fun = DECL_RTL (current_function_decl);
06717       if (GET_CODE (fun) == MEM)
06718   fun = XEXP (fun, 0);
06719       else
06720   abort ();
06721       emit_library_call (profile_function_entry_libfunc, LCT_NORMAL, VOIDmode,
06722        2, fun, Pmode,
06723        expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
06724                  0,
06725                  hard_frame_pointer_rtx),
06726        Pmode);
06727     }
06728 
06729   if (current_function_profile)
06730     {
06731 #ifdef PROFILE_HOOK
06732       PROFILE_HOOK (current_function_funcdef_no);
06733 #endif
06734     }
06735 
06736   /* After the display initializations is where the tail-recursion label
06737      should go, if we end up needing one.   Ensure we have a NOTE here
06738      since some things (like trampolines) get placed before this.  */
06739   tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED);
06740 
06741   /* Evaluate now the sizes of any types declared among the arguments.  */
06742   expand_pending_sizes (nreverse (get_pending_sizes ()));
06743 
06744   /* Make sure there is a line number after the function entry setup code.  */
06745   force_next_line_note ();
06746 }
06747 
06748 /* Undo the effects of init_dummy_function_start.  */
06749 void
06750 expand_dummy_function_end ()
06751 {
06752   /* End any sequences that failed to be closed due to syntax errors.  */
06753   while (in_sequence_p ())
06754     end_sequence ();
06755 
06756   /* Outside function body, can't compute type's actual size
06757      until next function's body starts.  */
06758 
06759   free_after_parsing (cfun);
06760   free_after_compilation (cfun);
06761   cfun = 0;
06762 }
06763 
06764 /* Call DOIT for each hard register used as a return value from
06765    the current function.  */
06766 
06767 void
06768 diddle_return_value (doit, arg)
06769      void (*doit) PARAMS ((rtx, void *));
06770      void *arg;
06771 {
06772   rtx outgoing = current_function_return_rtx;
06773 
06774   if (! outgoing)
06775     return;
06776 
06777   if (GET_CODE (outgoing) == REG)
06778     (*doit) (outgoing, arg);
06779   else if (GET_CODE (outgoing) == PARALLEL)
06780     {
06781       int i;
06782 
06783       for (i = 0; i < XVECLEN (outgoing, 0); i++)
06784   {
06785     rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);
06786 
06787     if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
06788       (*doit) (x, arg);
06789   }
06790     }
06791 }
06792 
06793 static void
06794 do_clobber_return_reg (reg, arg)
06795      rtx reg;
06796      void *arg ATTRIBUTE_UNUSED;
06797 {
06798   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg));
06799 }
06800 
06801 void
06802 clobber_return_register ()
06803 {
06804   diddle_return_value (do_clobber_return_reg, NULL);
06805 
06806   /* In case we do use pseudo to return value, clobber it too.  */
06807   if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
06808     {
06809       tree decl_result = DECL_RESULT (current_function_decl);
06810       rtx decl_rtl = DECL_RTL (decl_result);
06811       if (REG_P (decl_rtl) && REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER)
06812   {
06813     do_clobber_return_reg (decl_rtl, NULL);
06814   }
06815     }
06816 }
06817 
06818 static void
06819 do_use_return_reg (reg, arg)
06820      rtx reg;
06821      void *arg ATTRIBUTE_UNUSED;
06822 {
06823   emit_insn (gen_rtx_USE (VOIDmode, reg));
06824 }
06825 
06826 void
06827 use_return_register ()
06828 {
06829   diddle_return_value (do_use_return_reg, NULL);
06830 }
06831 
06832 static GTY(()) rtx initial_trampoline;
06833 
06834 /* Generate RTL for the end of the current function.
06835    FILENAME and LINE are the current position in the source file.
06836 
06837    It is up to language-specific callers to do cleanups for parameters--
06838    or else, supply 1 for END_BINDINGS and we will call expand_end_bindings.  */
06839 
06840 void
06841 expand_function_end (filename, line, end_bindings)
06842      const char *filename;
06843      int line;
06844      int end_bindings;
06845 {
06846   tree link;
06847   rtx clobber_after;
06848 
06849 #ifdef SGI_MONGOOSE
06850 #ifdef KEY
06851   /* Fix for bug 592. */
06852   /* Outside function body, can't compute type's actual size
06853      until next function's body starts.  */
06854   immediate_size_expand--;
06855 #endif
06856 
06857   return;
06858 #endif /* SGI_MONGOOSE */
06859 
06860   finish_expr_for_function ();
06861 
06862   /* If arg_pointer_save_area was referenced only from a nested
06863      function, we will not have initialized it yet.  Do that now.  */
06864   if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init)
06865     get_arg_pointer_save_area (cfun);
06866 
06867 #ifdef NON_SAVING_SETJMP
06868   /* Don't put any variables in registers if we call setjmp
06869      on a machine that fails to restore the registers.  */
06870   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
06871     {
06872       if (DECL_INITIAL (current_function_decl) != error_mark_node)
06873   setjmp_protect (DECL_INITIAL (current_function_decl));
06874 
06875       setjmp_protect_args ();
06876     }
06877 #endif
06878 
06879   /* Initialize any trampolines required by this function.  */
06880   for (link = trampoline_list; link; link = TREE_CHAIN (link))
06881     {
06882       tree function = TREE_PURPOSE (link);
06883       rtx context ATTRIBUTE_UNUSED = lookup_static_chain (function);
06884       rtx tramp = RTL_EXPR_RTL (TREE_VALUE (link));
06885 #ifdef TRAMPOLINE_TEMPLATE
06886       rtx blktramp;
06887 #endif
06888       rtx seq;
06889 
06890 #ifdef TRAMPOLINE_TEMPLATE
06891       /* First make sure this compilation has a template for
06892    initializing trampolines.  */
06893       if (initial_trampoline == 0)
06894   {
06895     initial_trampoline
06896       = gen_rtx_MEM (BLKmode, assemble_trampoline_template ());
06897     set_mem_align (initial_trampoline, TRAMPOLINE_ALIGNMENT);
06898   }
06899 #endif
06900 
06901       /* Generate insns to initialize the trampoline.  */
06902       start_sequence ();
06903       tramp = round_trampoline_addr (XEXP (tramp, 0));
06904 #ifdef TRAMPOLINE_TEMPLATE
06905       blktramp = replace_equiv_address (initial_trampoline, tramp);
06906       emit_block_move (blktramp, initial_trampoline,
06907            GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
06908 #endif
06909       trampolines_created = 1;
06910       INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
06911       seq = get_insns ();
06912       end_sequence ();
06913 
06914       /* Put those insns at entry to the containing function (this one).  */
06915       emit_insn_before (seq, tail_recursion_reentry);
06916     }
06917 
06918   /* If we are doing stack checking and this function makes calls,
06919      do a stack probe at the start of the function to ensure we have enough
06920      space for another stack frame.  */
06921   if (flag_stack_check && ! STACK_CHECK_BUILTIN)
06922     {
06923       rtx insn, seq;
06924 
06925       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
06926   if (GET_CODE (insn) == CALL_INSN)
06927     {
06928       start_sequence ();
06929       probe_stack_range (STACK_CHECK_PROTECT,
06930              GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
06931       seq = get_insns ();
06932       end_sequence ();
06933       emit_insn_before (seq, tail_recursion_reentry);
06934       break;
06935     }
06936     }
06937 
06938   /* Warn about unused parms if extra warnings were specified.  */
06939   /* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this
06940      warning.  WARN_UNUSED_PARAMETER is negative when set by
06941      -Wunused.  */
06942   if (warn_unused_parameter > 0
06943       || (warn_unused_parameter < 0 && extra_warnings))
06944     {
06945       tree decl;
06946 
06947       for (decl = DECL_ARGUMENTS (current_function_decl);
06948      decl; decl = TREE_CHAIN (decl))
06949   if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
06950       && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
06951     warning_with_decl (decl, "unused parameter `%s'");
06952     }
06953 
06954   /* Delete handlers for nonlocal gotos if nothing uses them.  */
06955   if (nonlocal_goto_handler_slots != 0
06956       && ! current_function_has_nonlocal_label)
06957     delete_handlers ();
06958 
06959   /* End any sequences that failed to be closed due to syntax errors.  */
06960   while (in_sequence_p ())
06961     end_sequence ();
06962 
06963   /* Outside function body, can't compute type's actual size
06964      until next function's body starts.  */
06965   immediate_size_expand--;
06966 
06967   clear_pending_stack_adjust ();
06968   do_pending_stack_adjust ();
06969 
06970   /* Mark the end of the function body.
06971      If control reaches this insn, the function can drop through
06972      without returning a value.  */
06973   emit_note (NULL, NOTE_INSN_FUNCTION_END);
06974 
06975   /* Must mark the last line number note in the function, so that the test
06976      coverage code can avoid counting the last line twice.  This just tells
06977      the code to ignore the immediately following line note, since there
06978      already exists a copy of this note somewhere above.  This line number
06979      note is still needed for debugging though, so we can't delete it.  */
06980   if (flag_test_coverage)
06981     emit_note (NULL, NOTE_INSN_REPEATED_LINE_NUMBER);
06982 
06983   /* Output a linenumber for the end of the function.
06984      SDB depends on this.  */
06985   emit_line_note_force (filename, line);
06986 
06987   /* Before the return label (if any), clobber the return
06988      registers so that they are not propagated live to the rest of
06989      the function.  This can only happen with functions that drop
06990      through; if there had been a return statement, there would
06991      have either been a return rtx, or a jump to the return label.
06992 
06993      We delay actual code generation after the current_function_value_rtx
06994      is computed.  */
06995   clobber_after = get_last_insn ();
06996 
06997   /* Output the label for the actual return from the function,
06998      if one is expected.  This happens either because a function epilogue
06999      is used instead of a return instruction, or because a return was done
07000      with a goto in order to run local cleanups, or because of pcc-style
07001      structure returning.  */
07002   if (return_label)
07003     emit_label (return_label);
07004 
07005   /* C++ uses this.  */
07006   if (end_bindings)
07007     expand_end_bindings (0, 0, 0);
07008 
07009   if (current_function_instrument_entry_exit)
07010     {
07011       rtx fun = DECL_RTL (current_function_decl);
07012       if (GET_CODE (fun) == MEM)
07013   fun = XEXP (fun, 0);
07014       else
07015   abort ();
07016       emit_library_call (profile_function_exit_libfunc, LCT_NORMAL, VOIDmode,
07017        2, fun, Pmode,
07018        expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
07019                  0,
07020                  hard_frame_pointer_rtx),
07021        Pmode);
07022     }
07023 
07024   /* Let except.c know where it should emit the call to unregister
07025      the function context for sjlj exceptions.  */
07026   if (flag_exceptions && USING_SJLJ_EXCEPTIONS)
07027     sjlj_emit_function_exit_after (get_last_insn ());
07028 
07029   /* If we had calls to alloca, and this machine needs
07030      an accurate stack pointer to exit the function,
07031      insert some code to save and restore the stack pointer.  */
07032 #ifdef EXIT_IGNORE_STACK
07033   if (! EXIT_IGNORE_STACK)
07034 #endif
07035     if (current_function_calls_alloca)
07036       {
07037   rtx tem = 0;
07038 
07039   emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
07040   emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
07041       }
07042 
07043   /* If scalar return value was computed in a pseudo-reg, or was a named
07044      return value that got dumped to the stack, copy that to the hard
07045      return register.  */
07046   if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl)))
07047     {
07048       tree decl_result = DECL_RESULT (current_function_decl);
07049       rtx decl_rtl = DECL_RTL (decl_result);
07050 
07051       if (REG_P (decl_rtl)
07052     ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
07053     : DECL_REGISTER (decl_result))
07054   {
07055     rtx real_decl_rtl = current_function_return_rtx;
07056 
07057     /* This should be set in assign_parms.  */
07058     if (! REG_FUNCTION_VALUE_P (real_decl_rtl))
07059       abort ();
07060 
07061     /* If this is a BLKmode structure being returned in registers,
07062        then use the mode computed in expand_return.  Note that if
07063        decl_rtl is memory, then its mode may have been changed,
07064        but that current_function_return_rtx has not.  */
07065     if (GET_MODE (real_decl_rtl) == BLKmode)
07066       PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl));
07067 
07068     /* If a named return value dumped decl_return to memory, then
07069        we may need to re-do the PROMOTE_MODE signed/unsigned
07070        extension.  */
07071     if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl))
07072       {
07073         int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
07074 
07075 #ifdef PROMOTE_FUNCTION_RETURN
07076         promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
07077           &unsignedp, 1);
07078 #endif
07079 
07080         convert_move (real_decl_rtl, decl_rtl, unsignedp);
07081       }
07082     else if (GET_CODE (real_decl_rtl) == PARALLEL)
07083       {
07084         /* If expand_function_start has created a PARALLEL for decl_rtl,
07085      move the result to the real return registers.  Otherwise, do
07086      a group load from decl_rtl for a named return.  */
07087         if (GET_CODE (decl_rtl) == PARALLEL)
07088     emit_group_move (real_decl_rtl, decl_rtl);
07089         else
07090     emit_group_load (real_decl_rtl, decl_rtl,
07091          int_size_in_bytes (TREE_TYPE (decl_result)));
07092       }
07093     else
07094       emit_move_insn (real_decl_rtl, decl_rtl);
07095   }
07096     }
07097 
07098   /* If returning a structure, arrange to return the address of the value
07099      in a place where debuggers expect to find it.
07100 
07101      If returning a structure PCC style,
07102      the caller also depends on this value.
07103      And current_function_returns_pcc_struct is not necessarily set.  */
07104   if (current_function_returns_struct
07105       || current_function_returns_pcc_struct)
07106     {
07107       rtx value_address
07108   = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
07109       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
07110 #ifdef FUNCTION_OUTGOING_VALUE
07111       rtx outgoing
07112   = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
07113            current_function_decl);
07114 #else
07115       rtx outgoing
07116   = FUNCTION_VALUE (build_pointer_type (type), current_function_decl);
07117 #endif
07118 
07119       /* Mark this as a function return value so integrate will delete the
07120    assignment and USE below when inlining this function.  */
07121       REG_FUNCTION_VALUE_P (outgoing) = 1;
07122 
07123 #ifdef POINTERS_EXTEND_UNSIGNED
07124       /* The address may be ptr_mode and OUTGOING may be Pmode.  */
07125       if (GET_MODE (outgoing) != GET_MODE (value_address))
07126   value_address = convert_memory_address (GET_MODE (outgoing),
07127             value_address);
07128 #endif
07129 
07130       emit_move_insn (outgoing, value_address);
07131 
07132       /* Show return register used to hold result (in this case the address
07133    of the result.  */
07134       current_function_return_rtx = outgoing;
07135     }
07136 
07137   /* If this is an implementation of throw, do what's necessary to
07138      communicate between __builtin_eh_return and the epilogue.  */
07139   expand_eh_return ();
07140 
07141   /* Emit the actual code to clobber return register.  */
07142   {
07143     rtx seq, after;
07144 
07145     start_sequence ();
07146     clobber_return_register ();
07147     seq = get_insns ();
07148     end_sequence ();
07149 
07150     after = emit_insn_after (seq, clobber_after);
07151 
07152     if (clobber_after != after)
07153       cfun->x_clobber_return_insn = after;
07154   }
07155 
07156   /* ??? This should no longer be necessary since stupid is no longer with
07157      us, but there are some parts of the compiler (eg reload_combine, and
07158      sh mach_dep_reorg) that still try and compute their own lifetime info
07159      instead of using the general framework.  */
07160   use_return_register ();
07161 
07162   /* Fix up any gotos that jumped out to the outermost
07163      binding level of the function.
07164      Must follow emitting RETURN_LABEL.  */
07165 
07166   /* If you have any cleanups to do at this point,
07167      and they need to create temporary variables,
07168      then you will lose.  */
07169   expand_fixups (get_insns ());
07170 }
07171 
07172 rtx
07173 get_arg_pointer_save_area (f)
07174      struct function *f;
07175 {
07176   rtx ret = f->x_arg_pointer_save_area;
07177 
07178   if (! ret)
07179     {
07180       ret = assign_stack_local_1 (Pmode, GET_MODE_SIZE (Pmode), 0, f);
07181       f->x_arg_pointer_save_area = ret;
07182     }
07183 
07184   if (f == cfun && ! f->arg_pointer_save_area_init)
07185     {
07186       rtx seq;
07187 
07188       /* Save the arg pointer at the beginning of the function.  The
07189    generated stack slot may not be a valid memory address, so we
07190    have to check it and fix it if necessary.  */
07191       start_sequence ();
07192       emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx);
07193       seq = get_insns ();
07194       end_sequence ();
07195 
07196       push_topmost_sequence ();
07197       emit_insn_after (seq, get_insns ());
07198       pop_topmost_sequence ();
07199     }
07200 
07201   return ret;
07202 }
07203 
07204 /* Extend a vector that records the INSN_UIDs of INSNS
07205    (a list of one or more insns).  */
07206 
07207 static void
07208 record_insns (insns, vecp)
07209      rtx insns;
07210      varray_type *vecp;
07211 {
07212   int i, len;
07213   rtx tmp;
07214 
07215   tmp = insns;
07216   len = 0;
07217   while (tmp != NULL_RTX)
07218     {
07219       len++;
07220       tmp = NEXT_INSN (tmp);
07221     }
07222 
07223   i = VARRAY_SIZE (*vecp);
07224   VARRAY_GROW (*vecp, i + len);
07225   tmp = insns;
07226   while (tmp != NULL_RTX)
07227     {
07228       VARRAY_INT (*vecp, i) = INSN_UID (tmp);
07229       i++;
07230       tmp = NEXT_INSN (tmp);
07231     }
07232 }
07233 
07234 /* Determine how many INSN_UIDs in VEC are part of INSN.  Because we can
07235    be running after reorg, SEQUENCE rtl is possible.  */
07236 
07237 static int
07238 contains (insn, vec)
07239      rtx insn;
07240      varray_type vec;
07241 {
07242   int i, j;
07243 
07244   if (GET_CODE (insn) == INSN
07245       && GET_CODE (PATTERN (insn)) == SEQUENCE)
07246     {
07247       int count = 0;
07248       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
07249   for (j = VARRAY_SIZE (vec) - 1; j >= 0; --j)
07250     if (INSN_UID (XVECEXP (PATTERN (insn), 0, i)) == VARRAY_INT (vec, j))
07251       count++;
07252       return count;
07253     }
07254   else
07255     {
07256       for (j = VARRAY_SIZE (vec) - 1; j >= 0; --j)
07257   if (INSN_UID (insn) == VARRAY_INT (vec, j))
07258     return 1;
07259     }
07260   return 0;
07261 }
07262 
07263 int
07264 prologue_epilogue_contains (insn)
07265      rtx insn;
07266 {
07267   if (contains (insn, prologue))
07268     return 1;
07269   if (contains (insn, epilogue))
07270     return 1;
07271   return 0;
07272 }
07273 
07274 int
07275 sibcall_epilogue_contains (insn)
07276      rtx insn;
07277 {
07278   if (sibcall_epilogue)
07279     return contains (insn, sibcall_epilogue);
07280   return 0;
07281 }
07282 
07283 #ifdef HAVE_return
07284 /* Insert gen_return at the end of block BB.  This also means updating
07285    block_for_insn appropriately.  */
07286 
07287 static void
07288 emit_return_into_block (bb, line_note)
07289      basic_block bb;
07290      rtx line_note;
07291 {
07292   rtx p, end;
07293 
07294   p = NEXT_INSN (bb->end);
07295   end = emit_jump_insn_after (gen_return (), bb->end);
07296   if (line_note)
07297     emit_line_note_after (NOTE_SOURCE_FILE (line_note),
07298         NOTE_LINE_NUMBER (line_note), PREV_INSN (bb->end));
07299 }
07300 #endif /* HAVE_return */
07301 
07302 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
07303 
07304 /* These functions convert the epilogue into a variant that does not modify the
07305    stack pointer.  This is used in cases where a function returns an object
07306    whose size is not known until it is computed.  The called function leaves the
07307    object on the stack, leaves the stack depressed, and returns a pointer to
07308    the object.
07309 
07310    What we need to do is track all modifications and references to the stack
07311    pointer, deleting the modifications and changing the references to point to
07312    the location the stack pointer would have pointed to had the modifications
07313    taken place.
07314 
07315    These functions need to be portable so we need to make as few assumptions
07316    about the epilogue as we can.  However, the epilogue basically contains
07317    three things: instructions to reset the stack pointer, instructions to
07318    reload registers, possibly including the frame pointer, and an
07319    instruction to return to the caller.
07320 
07321    If we can't be sure of what a relevant epilogue insn is doing, we abort.
07322    We also make no attempt to validate the insns we make since if they are
07323    invalid, we probably can't do anything valid.  The intent is that these
07324    routines get "smarter" as more and more machines start to use them and
07325    they try operating on different epilogues.
07326 
07327    We use the following structure to track what the part of the epilogue that
07328    we've already processed has done.  We keep two copies of the SP equivalence,
07329    one for use during the insn we are processing and one for use in the next
07330    insn.  The difference is because one part of a PARALLEL may adjust SP
07331    and the other may use it.  */
07332 
07333 struct epi_info
07334 {
07335   rtx sp_equiv_reg;   /* REG that SP is set from, perhaps SP.  */
07336   HOST_WIDE_INT sp_offset;  /* Offset from SP_EQUIV_REG of present SP.  */
07337   rtx new_sp_equiv_reg;   /* REG to be used at end of insn.  */
07338   HOST_WIDE_INT new_sp_offset;  /* Offset to be used at end of insn.  */
07339   rtx equiv_reg_src;    /* If nonzero, the value that SP_EQUIV_REG
07340            should be set to once we no longer need
07341            its value.  */
07342 };
07343 
07344 static void handle_epilogue_set PARAMS ((rtx, struct epi_info *));
07345 static void emit_equiv_load PARAMS ((struct epi_info *));
07346 
07347 /* Modify INSN, a list of one or more insns that is part of the epilogue, to
07348    no modifications to the stack pointer.  Return the new list of insns.  */
07349 
07350 static rtx
07351 keep_stack_depressed (insns)
07352      rtx insns;
07353 {
07354   int j;
07355   struct epi_info info;
07356   rtx insn, next;
07357 
07358   /* If the epilogue is just a single instruction, it ust be OK as is.  */
07359 
07360   if (NEXT_INSN (insns) == NULL_RTX)
07361     return insns;
07362 
07363   /* Otherwise, start a sequence, initialize the information we have, and
07364      process all the insns we were given.  */
07365   start_sequence ();
07366 
07367   info.sp_equiv_reg = stack_pointer_rtx;
07368   info.sp_offset = 0;
07369   info.equiv_reg_src = 0;
07370 
07371   insn = insns;
07372   next = NULL_RTX;
07373   while (insn != NULL_RTX)
07374     {
07375       next = NEXT_INSN (insn);
07376 
07377       if (!INSN_P (insn))
07378   {
07379     add_insn (insn);
07380     insn = next;
07381     continue;
07382   }
07383 
07384       /* If this insn references the register that SP is equivalent to and
07385    we have a pending load to that register, we must force out the load
07386    first and then indicate we no longer know what SP's equivalent is.  */
07387       if (info.equiv_reg_src != 0
07388     && reg_referenced_p (info.sp_equiv_reg, PATTERN (insn)))
07389   {
07390     emit_equiv_load (&info);
07391     info.sp_equiv_reg = 0;
07392   }
07393 
07394       info.new_sp_equiv_reg = info.sp_equiv_reg;
07395       info.new_sp_offset = info.sp_offset;
07396 
07397       /* If this is a (RETURN) and the return address is on the stack,
07398    update the address and change to an indirect jump.  */
07399       if (GET_CODE (PATTERN (insn)) == RETURN
07400     || (GET_CODE (PATTERN (insn)) == PARALLEL
07401         && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == RETURN))
07402   {
07403     rtx retaddr = INCOMING_RETURN_ADDR_RTX;
07404     rtx base = 0;
07405     HOST_WIDE_INT offset = 0;
07406     rtx jump_insn, jump_set;
07407 
07408     /* If the return address is in a register, we can emit the insn
07409        unchanged.  Otherwise, it must be a MEM and we see what the
07410        base register and offset are.  In any case, we have to emit any
07411        pending load to the equivalent reg of SP, if any.  */
07412     if (GET_CODE (retaddr) == REG)
07413       {
07414         emit_equiv_load (&info);
07415         add_insn (insn);
07416         insn = next;
07417         continue;
07418       }
07419     else if (GET_CODE (retaddr) == MEM
07420        && GET_CODE (XEXP (retaddr, 0)) == REG)
07421       base = gen_rtx_REG (Pmode, REGNO (XEXP (retaddr, 0))), offset = 0;
07422     else if (GET_CODE (retaddr) == MEM
07423        && GET_CODE (XEXP (retaddr, 0)) == PLUS
07424        && GET_CODE (XEXP (XEXP (retaddr, 0), 0)) == REG
07425        && GET_CODE (XEXP (XEXP (retaddr, 0), 1)) == CONST_INT)
07426       {
07427         base = gen_rtx_REG (Pmode, REGNO (XEXP (XEXP (retaddr, 0), 0)));
07428         offset = INTVAL (XEXP (XEXP (retaddr, 0), 1));
07429       }
07430     else
07431       abort ();
07432 
07433     /* If the base of the location containing the return pointer
07434        is SP, we must update it with the replacement address.  Otherwise,
07435        just build the necessary MEM.  */
07436     retaddr = plus_constant (base, offset);
07437     if (base == stack_pointer_rtx)
07438       retaddr = simplify_replace_rtx (retaddr, stack_pointer_rtx,
07439               plus_constant (info.sp_equiv_reg,
07440                  info.sp_offset));
07441 
07442     retaddr = gen_rtx_MEM (Pmode, retaddr);
07443 
07444     /* If there is a pending load to the equivalent register for SP
07445        and we reference that register, we must load our address into
07446        a scratch register and then do that load.  */
07447     if (info.equiv_reg_src
07448         && reg_overlap_mentioned_p (info.equiv_reg_src, retaddr))
07449       {
07450         unsigned int regno;
07451         rtx reg;
07452 
07453         for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
07454     if (HARD_REGNO_MODE_OK (regno, Pmode)
07455         && !fixed_regs[regno]
07456         && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno)
07457         && !REGNO_REG_SET_P (EXIT_BLOCK_PTR->global_live_at_start,
07458            regno)
07459         && !refers_to_regno_p (regno,
07460              regno + HARD_REGNO_NREGS (regno,
07461                      Pmode),
07462              info.equiv_reg_src, NULL))
07463       break;
07464 
07465         if (regno == FIRST_PSEUDO_REGISTER)
07466     abort ();
07467 
07468         reg = gen_rtx_REG (Pmode, regno);
07469         emit_move_insn (reg, retaddr);
07470         retaddr = reg;
07471       }
07472 
07473     emit_equiv_load (&info);
07474     jump_insn = emit_jump_insn (gen_indirect_jump (retaddr));
07475 
07476     /* Show the SET in the above insn is a RETURN.  */
07477     jump_set = single_set (jump_insn);
07478     if (jump_set == 0)
07479       abort ();
07480     else
07481       SET_IS_RETURN_P (jump_set) = 1;
07482   }
07483 
07484       /* If SP is not mentioned in the pattern and its equivalent register, if
07485    any, is not modified, just emit it.  Otherwise, if neither is set,
07486    replace the reference to SP and emit the insn.  If none of those are
07487    true, handle each SET individually.  */
07488       else if (!reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))
07489          && (info.sp_equiv_reg == stack_pointer_rtx
07490        || !reg_set_p (info.sp_equiv_reg, insn)))
07491   add_insn (insn);
07492       else if (! reg_set_p (stack_pointer_rtx, insn)
07493          && (info.sp_equiv_reg == stack_pointer_rtx
07494        || !reg_set_p (info.sp_equiv_reg, insn)))
07495   {
07496     if (! validate_replace_rtx (stack_pointer_rtx,
07497               plus_constant (info.sp_equiv_reg,
07498                  info.sp_offset),
07499               insn))
07500       abort ();
07501 
07502     add_insn (insn);
07503   }
07504       else if (GET_CODE (PATTERN (insn)) == SET)
07505   handle_epilogue_set (PATTERN (insn), &info);
07506       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
07507   {
07508     for (j = 0; j < XVECLEN (PATTERN (insn), 0); j++)
07509       if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET)
07510         handle_epilogue_set (XVECEXP (PATTERN (insn), 0, j), &info);
07511   }
07512       else
07513   add_insn (insn);
07514 
07515       info.sp_equiv_reg = info.new_sp_equiv_reg;
07516       info.sp_offset = info.new_sp_offset;
07517 
07518       insn = next;
07519     }
07520 
07521   insns = get_insns ();
07522   end_sequence ();
07523   return insns;
07524 }
07525 
07526 /* SET is a SET from an insn in the epilogue.  P is a pointer to the epi_info
07527    structure that contains information about what we've seen so far.  We
07528    process this SET by either updating that data or by emitting one or
07529    more insns.  */
07530 
07531 static void
07532 handle_epilogue_set (set, p)
07533      rtx set;
07534      struct epi_info *p;
07535 {
07536   /* First handle the case where we are setting SP.  Record what it is being
07537      set from.  If unknown, abort.  */
07538   if (reg_set_p (stack_pointer_rtx, set))
07539     {
07540       if (SET_DEST (set) != stack_pointer_rtx)
07541   abort ();
07542 
07543       if (GET_CODE (SET_SRC (set)) == PLUS
07544     && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
07545   {
07546     p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
07547     p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
07548   }
07549       else
07550   p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0;
07551 
07552       /* If we are adjusting SP, we adjust from the old data.  */
07553       if (p->new_sp_equiv_reg == stack_pointer_rtx)
07554   {
07555     p->new_sp_equiv_reg = p->sp_equiv_reg;
07556     p->new_sp_offset += p->sp_offset;
07557   }
07558 
07559       if (p->new_sp_equiv_reg == 0 || GET_CODE (p->new_sp_equiv_reg) != REG)
07560   abort ();
07561 
07562       return;
07563     }
07564 
07565   /* Next handle the case where we are setting SP's equivalent register.
07566      If we already have a value to set it to, abort.  We could update, but
07567      there seems little point in handling that case.  Note that we have
07568      to allow for the case where we are setting the register set in
07569      the previous part of a PARALLEL inside a single insn.  But use the
07570      old offset for any updates within this insn.  */
07571   else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
07572     {
07573       if (!rtx_equal_p (p->new_sp_equiv_reg, SET_DEST (set))
07574     || p->equiv_reg_src != 0)
07575   abort ();
07576       else
07577   p->equiv_reg_src
07578     = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
07579           plus_constant (p->sp_equiv_reg,
07580              p->sp_offset));
07581     }
07582 
07583   /* Otherwise, replace any references to SP in the insn to its new value
07584      and emit the insn.  */
07585   else
07586     {
07587       SET_SRC (set) = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx,
07588               plus_constant (p->sp_equiv_reg,
07589                  p->sp_offset));
07590       SET_DEST (set) = simplify_replace_rtx (SET_DEST (set), stack_pointer_rtx,
07591                plus_constant (p->sp_equiv_reg,
07592                   p->sp_offset));
07593       emit_insn (set);
07594     }
07595 }
07596 
07597 /* Emit an insn to do the load shown in p->equiv_reg_src, if needed.  */
07598 
07599 static void
07600 emit_equiv_load (p)
07601      struct epi_info *p;
07602 {
07603   if (p->equiv_reg_src != 0)
07604     emit_move_insn (p->sp_equiv_reg, p->equiv_reg_src);
07605 
07606   p->equiv_reg_src = 0;
07607 }
07608 #endif
07609 
07610 /* Generate the prologue and epilogue RTL if the machine supports it.  Thread
07611    this into place with notes indicating where the prologue ends and where
07612    the epilogue begins.  Update the basic block information when possible.  */
07613 
07614 void
07615 thread_prologue_and_epilogue_insns (f)
07616      rtx f ATTRIBUTE_UNUSED;
07617 {
07618   int inserted = 0;
07619   edge e;
07620 #if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)
07621   rtx seq;
07622 #endif
07623 #ifdef HAVE_prologue
07624   rtx prologue_end = NULL_RTX;
07625 #endif
07626 #if defined (HAVE_epilogue) || defined(HAVE_return)
07627   rtx epilogue_end = NULL_RTX;
07628 #endif
07629 
07630 #ifdef HAVE_prologue
07631   if (HAVE_prologue)
07632     {
07633       start_sequence ();
07634       seq = gen_prologue ();
07635       emit_insn (seq);
07636 
07637       /* Retain a map of the prologue insns.  */
07638       record_insns (seq, &prologue);
07639       prologue_end = emit_note (NULL, NOTE_INSN_PROLOGUE_END);
07640 
07641       seq = get_insns ();
07642       end_sequence ();
07643 
07644       /* Can't deal with multiple successors of the entry block
07645          at the moment.  Function should always have at least one
07646          entry point.  */
07647       if (!ENTRY_BLOCK_PTR->succ || ENTRY_BLOCK_PTR->succ->succ_next)
07648   abort ();
07649 
07650       insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
07651       inserted = 1;
07652     }
07653 #endif
07654 
07655   /* If the exit block has no non-fake predecessors, we don't need
07656      an epilogue.  */
07657   for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
07658     if ((e->flags & EDGE_FAKE) == 0)
07659       break;
07660   if (e == NULL)
07661     goto epilogue_done;
07662 
07663 #ifdef HAVE_return
07664   if (optimize && HAVE_return)
07665     {
07666       /* If we're allowed to generate a simple return instruction,
07667    then by definition we don't need a full epilogue.  Examine
07668    the block that falls through to EXIT.   If it does not
07669    contain any code, examine its predecessors and try to
07670    emit (conditional) return instructions.  */
07671 
07672       basic_block last;
07673       edge e_next;
07674       rtx label;
07675 
07676       for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
07677   if (e->flags & EDGE_FALLTHRU)
07678     break;
07679       if (e == NULL)
07680   goto epilogue_done;
07681       last = e->src;
07682 
07683       /* Verify that there are no active instructions in the last block.  */
07684       label = last->end;
07685       while (label && GET_CODE (label) != CODE_LABEL)
07686   {
07687     if (active_insn_p (label))
07688       break;
07689     label = PREV_INSN (label);
07690   }
07691 
07692       if (last->head == label && GET_CODE (label) == CODE_LABEL)
07693   {
07694     rtx epilogue_line_note = NULL_RTX;
07695 
07696     /* Locate the line number associated with the closing brace,
07697        if we can find one.  */
07698     for (seq = get_last_insn ();
07699          seq && ! active_insn_p (seq);
07700          seq = PREV_INSN (seq))
07701       if (GET_CODE (seq) == NOTE && NOTE_LINE_NUMBER (seq) > 0)
07702         {
07703     epilogue_line_note = seq;
07704     break;
07705         }
07706 
07707     for (e = last->pred; e; e = e_next)
07708       {
07709         basic_block bb = e->src;
07710         rtx jump;
07711 
07712         e_next = e->pred_next;
07713         if (bb == ENTRY_BLOCK_PTR)
07714     continue;
07715 
07716         jump = bb->end;
07717         if ((GET_CODE (jump) != JUMP_INSN) || JUMP_LABEL (jump) != label)
07718     continue;
07719 
07720         /* If we have an unconditional jump, we can replace that
07721      with a simple return instruction.  */
07722         if (simplejump_p (jump))
07723     {
07724       emit_return_into_block (bb, epilogue_line_note);
07725       delete_insn (jump);
07726     }
07727 
07728         /* If we have a conditional jump, we can try to replace
07729      that with a conditional return instruction.  */
07730         else if (condjump_p (jump))
07731     {
07732       if (! redirect_jump (jump, 0, 0))
07733         continue;
07734 
07735       /* If this block has only one successor, it both jumps
07736          and falls through to the fallthru block, so we can't
07737          delete the edge.  */
07738       if (bb->succ->