Annotation of gcc/function.c, revision 1.1.1.8

1.1       root        1: /* Expands front end tree to back end RTL for GNU C-Compiler
1.1.1.8 ! root        2:    Copyright (C) 1987, 88, 89, 91-94, 1995 Free Software Foundation, Inc.
1.1       root        3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.8 ! root       18: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            19: Boston, MA 02111-1307, USA.  */
1.1       root       20: 
                     21: 
                     22: /* This file handles the generation of rtl code from tree structure
                     23:    at the level of the function as a whole.
                     24:    It creates the rtl expressions for parameters and auto variables
                     25:    and has full responsibility for allocating stack slots.
                     26: 
                     27:    `expand_function_start' is called at the beginning of a function,
                     28:    before the function body is parsed, and `expand_function_end' is
                     29:    called after parsing the body.
                     30: 
                     31:    Call `assign_stack_local' to allocate a stack slot for a local variable.
                     32:    This is usually done during the RTL generation for the function body,
                     33:    but it can also be done in the reload pass when a pseudo-register does
                     34:    not get a hard register.
                     35: 
                     36:    Call `put_var_into_stack' when you learn, belatedly, that a variable
                     37:    previously given a pseudo-register must in fact go in the stack.
                     38:    This function changes the DECL_RTL to be a stack slot instead of a reg
                     39:    then scans all the RTL instructions so far generated to correct them.  */
                     40: 
                     41: #include "config.h"
                     42: 
                     43: #include <stdio.h>
                     44: 
                     45: #include "rtl.h"
                     46: #include "tree.h"
                     47: #include "flags.h"
                     48: #include "function.h"
                     49: #include "insn-flags.h"
                     50: #include "expr.h"
                     51: #include "insn-codes.h"
                     52: #include "regs.h"
                     53: #include "hard-reg-set.h"
                     54: #include "insn-config.h"
                     55: #include "recog.h"
                     56: #include "output.h"
1.1.1.4   root       57: #include "basic-block.h"
1.1.1.6   root       58: #include "obstack.h"
                     59: #include "bytecode.h"
                     60: 
                     61: /* Some systems use __main in a way incompatible with its use in gcc, in these
                     62:    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
                     63:    give the same symbol without quotes for an alternative entry point.  You
1.1.1.8 ! root       64:    must define both, or neither. */
1.1.1.6   root       65: #ifndef NAME__MAIN
                     66: #define NAME__MAIN "__main"
                     67: #define SYMBOL__MAIN __main
                     68: #endif
1.1       root       69: 
                     70: /* Round a value to the lowest integer less than it that is a multiple of
                     71:    the required alignment.  Avoid using division in case the value is
                     72:    negative.  Assume the alignment is a power of two.  */
                     73: #define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))
                     74: 
                     75: /* Similar, but round to the next highest integer that meets the
                     76:    alignment.  */
                     77: #define CEIL_ROUND(VALUE,ALIGN)        (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
                     78: 
                     79: /* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp
                     80:    during rtl generation.  If they are different register numbers, this is
                     81:    always true.  It may also be true if
                     82:    FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl
                     83:    generation.  See fix_lexical_addr for details.  */
                     84: 
                     85: #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
                     86: #define NEED_SEPARATE_AP
                     87: #endif
                     88: 
                     89: /* Number of bytes of args popped by function being compiled on its return.
                     90:    Zero if no bytes are to be popped.
                     91:    May affect compilation of return insn or of function epilogue.  */
                     92: 
                     93: int current_function_pops_args;
                     94: 
                     95: /* Nonzero if function being compiled needs to be given an address
                     96:    where the value should be stored.  */
                     97: 
                     98: int current_function_returns_struct;
                     99: 
                    100: /* Nonzero if function being compiled needs to
                    101:    return the address of where it has put a structure value.  */
                    102: 
                    103: int current_function_returns_pcc_struct;
                    104: 
                    105: /* Nonzero if function being compiled needs to be passed a static chain.  */
                    106: 
                    107: int current_function_needs_context;
                    108: 
                    109: /* Nonzero if function being compiled can call setjmp.  */
                    110: 
                    111: int current_function_calls_setjmp;
                    112: 
                    113: /* Nonzero if function being compiled can call longjmp.  */
                    114: 
                    115: int current_function_calls_longjmp;
                    116: 
                    117: /* Nonzero if function being compiled receives nonlocal gotos
                    118:    from nested functions.  */
                    119: 
                    120: int current_function_has_nonlocal_label;
                    121: 
1.1.1.6   root      122: /* Nonzero if function being compiled has nonlocal gotos to parent
                    123:    function.  */
                    124: 
                    125: int current_function_has_nonlocal_goto;
                    126: 
1.1       root      127: /* Nonzero if function being compiled contains nested functions.  */
                    128: 
                    129: int current_function_contains_functions;
                    130: 
                    131: /* Nonzero if function being compiled can call alloca,
                    132:    either as a subroutine or builtin.  */
                    133: 
                    134: int current_function_calls_alloca;
                    135: 
                    136: /* Nonzero if the current function returns a pointer type */
                    137: 
                    138: int current_function_returns_pointer;
                    139: 
                    140: /* If some insns can be deferred to the delay slots of the epilogue, the
                    141:    delay list for them is recorded here.  */
                    142: 
                    143: rtx current_function_epilogue_delay_list;
                    144: 
                    145: /* If function's args have a fixed size, this is that size, in bytes.
                    146:    Otherwise, it is -1.
                    147:    May affect compilation of return insn or of function epilogue.  */
                    148: 
                    149: int current_function_args_size;
                    150: 
                    151: /* # bytes the prologue should push and pretend that the caller pushed them.
                    152:    The prologue must do this, but only if parms can be passed in registers.  */
                    153: 
                    154: int current_function_pretend_args_size;
                    155: 
1.1.1.7   root      156: /* # of bytes of outgoing arguments.  If ACCUMULATE_OUTGOING_ARGS is
                    157:    defined, the needed space is pushed by the prologue. */
1.1       root      158: 
                    159: int current_function_outgoing_args_size;
                    160: 
                    161: /* This is the offset from the arg pointer to the place where the first
                    162:    anonymous arg can be found, if there is one.  */
                    163: 
                    164: rtx current_function_arg_offset_rtx;
                    165: 
                    166: /* Nonzero if current function uses varargs.h or equivalent.
                    167:    Zero for functions that use stdarg.h.  */
                    168: 
                    169: int current_function_varargs;
                    170: 
1.1.1.8 ! root      171: /* Nonzero if current function uses stdarg.h or equivalent.
        !           172:    Zero for functions that use varargs.h.  */
        !           173: 
        !           174: int current_function_stdarg;
        !           175: 
1.1       root      176: /* Quantities of various kinds of registers
                    177:    used for the current function's args.  */
                    178: 
                    179: CUMULATIVE_ARGS current_function_args_info;
                    180: 
                    181: /* Name of function now being compiled.  */
                    182: 
                    183: char *current_function_name;
                    184: 
                    185: /* If non-zero, an RTL expression for that location at which the current
                    186:    function returns its result.  Always equal to
                    187:    DECL_RTL (DECL_RESULT (current_function_decl)), but provided
                    188:    independently of the tree structures.  */
                    189: 
                    190: rtx current_function_return_rtx;
                    191: 
                    192: /* Nonzero if the current function uses the constant pool.  */
                    193: 
                    194: int current_function_uses_const_pool;
                    195: 
                    196: /* Nonzero if the current function uses pic_offset_table_rtx.  */
                    197: int current_function_uses_pic_offset_table;
                    198: 
                    199: /* The arg pointer hard register, or the pseudo into which it was copied.  */
                    200: rtx current_function_internal_arg_pointer;
                    201: 
                    202: /* The FUNCTION_DECL for an inline function currently being expanded.  */
                    203: tree inline_function_decl;
                    204: 
                    205: /* Number of function calls seen so far in current function.  */
                    206: 
                    207: int function_call_count;
                    208: 
                    209: /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
                    210:    (labels to which there can be nonlocal gotos from nested functions)
                    211:    in this function.  */
                    212: 
                    213: tree nonlocal_labels;
                    214: 
                    215: /* RTX for stack slot that holds the current handler for nonlocal gotos.
                    216:    Zero when function does not have nonlocal labels.  */
                    217: 
                    218: rtx nonlocal_goto_handler_slot;
                    219: 
                    220: /* RTX for stack slot that holds the stack pointer value to restore
                    221:    for a nonlocal goto.
                    222:    Zero when function does not have nonlocal labels.  */
                    223: 
                    224: rtx nonlocal_goto_stack_level;
                    225: 
                    226: /* Label that will go on parm cleanup code, if any.
                    227:    Jumping to this label runs cleanup code for parameters, if
                    228:    such code must be run.  Following this code is the logical return label.  */
                    229: 
                    230: rtx cleanup_label;
                    231: 
                    232: /* Label that will go on function epilogue.
                    233:    Jumping to this label serves as a "return" instruction
                    234:    on machines which require execution of the epilogue on all returns.  */
                    235: 
                    236: rtx return_label;
                    237: 
                    238: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
                    239:    So we can mark them all live at the end of the function, if nonopt.  */
                    240: rtx save_expr_regs;
                    241: 
                    242: /* List (chain of EXPR_LISTs) of all stack slots in this function.
                    243:    Made for the sake of unshare_all_rtl.  */
                    244: rtx stack_slot_list;
                    245: 
                    246: /* Chain of all RTL_EXPRs that have insns in them.  */
                    247: tree rtl_expr_chain;
                    248: 
                    249: /* Label to jump back to for tail recursion, or 0 if we have
                    250:    not yet needed one for this function.  */
                    251: rtx tail_recursion_label;
                    252: 
                    253: /* Place after which to insert the tail_recursion_label if we need one.  */
                    254: rtx tail_recursion_reentry;
                    255: 
                    256: /* Location at which to save the argument pointer if it will need to be
                    257:    referenced.  There are two cases where this is done: if nonlocal gotos
                    258:    exist, or if vars stored at an offset from the argument pointer will be
                    259:    needed by inner routines.  */
                    260: 
                    261: rtx arg_pointer_save_area;
                    262: 
                    263: /* Offset to end of allocated area of stack frame.
                    264:    If stack grows down, this is the address of the last stack slot allocated.
                    265:    If stack grows up, this is the address for the next slot.  */
                    266: int frame_offset;
                    267: 
                    268: /* List (chain of TREE_LISTs) of static chains for containing functions.
                    269:    Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
                    270:    in an RTL_EXPR in the TREE_VALUE.  */
                    271: static tree context_display;
                    272: 
                    273: /* List (chain of TREE_LISTs) of trampolines for nested functions.
                    274:    The trampoline sets up the static chain and jumps to the function.
                    275:    We supply the trampoline's address when the function's address is requested.
                    276: 
                    277:    Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
                    278:    in an RTL_EXPR in the TREE_VALUE.  */
                    279: static tree trampoline_list;
                    280: 
                    281: /* Insn after which register parms and SAVE_EXPRs are born, if nonopt.  */
                    282: static rtx parm_birth_insn;
                    283: 
                    284: #if 0
                    285: /* Nonzero if a stack slot has been generated whose address is not
                    286:    actually valid.  It means that the generated rtl must all be scanned
                    287:    to detect and correct the invalid addresses where they occur.  */
                    288: static int invalid_stack_slot;
                    289: #endif
                    290: 
                    291: /* Last insn of those whose job was to put parms into their nominal homes.  */
                    292: static rtx last_parm_insn;
                    293: 
                    294: /* 1 + last pseudo register number used for loading a copy
                    295:    of a parameter of this function.  */
                    296: static int max_parm_reg;
                    297: 
                    298: /* Vector indexed by REGNO, containing location on stack in which
                    299:    to put the parm which is nominally in pseudo register REGNO,
                    300:    if we discover that that parm must go in the stack.  */
                    301: static rtx *parm_reg_stack_loc;
                    302: 
                    303: #if 0  /* Turned off because 0 seems to work just as well.  */
                    304: /* Cleanup lists are required for binding levels regardless of whether
                    305:    that binding level has cleanups or not.  This node serves as the
                    306:    cleanup list whenever an empty list is required.  */
                    307: static tree empty_cleanup_list;
                    308: #endif
                    309: 
                    310: /* Nonzero once virtual register instantiation has been done.
                    311:    assign_stack_local uses frame_pointer_rtx when this is nonzero.  */
                    312: static int virtuals_instantiated;
                    313: 
1.1.1.6   root      314: /* These variables hold pointers to functions to
                    315:    save and restore machine-specific data,
                    316:    in push_function_context and pop_function_context.  */
                    317: void (*save_machine_status) ();
                    318: void (*restore_machine_status) ();
                    319: 
1.1       root      320: /* Nonzero if we need to distinguish between the return value of this function
                    321:    and the return value of a function called by this function.  This helps
                    322:    integrate.c  */
                    323: 
                    324: extern int rtx_equal_function_value_matters;
1.1.1.6   root      325: extern tree sequence_rtl_expr;
                    326: extern tree bc_runtime_type_code ();
                    327: extern rtx bc_build_calldesc ();
                    328: extern char *bc_emit_trampoline ();
                    329: extern char *bc_end_function ();
1.1       root      330: 
                    331: /* In order to evaluate some expressions, such as function calls returning
                    332:    structures in memory, we need to temporarily allocate stack locations.
                    333:    We record each allocated temporary in the following structure.
                    334: 
                    335:    Associated with each temporary slot is a nesting level.  When we pop up
                    336:    one level, all temporaries associated with the previous level are freed.
                    337:    Normally, all temporaries are freed after the execution of the statement
                    338:    in which they were created.  However, if we are inside a ({...}) grouping,
                    339:    the result may be in a temporary and hence must be preserved.  If the
                    340:    result could be in a temporary, we preserve it if we can determine which
                    341:    one it is in.  If we cannot determine which temporary may contain the
                    342:    result, all temporaries are preserved.  A temporary is preserved by
                    343:    pretending it was allocated at the previous nesting level.
                    344: 
                    345:    Automatic variables are also assigned temporary slots, at the nesting
                    346:    level where they are defined.  They are marked a "kept" so that
                    347:    free_temp_slots will not free them.  */
                    348: 
                    349: struct temp_slot
                    350: {
                    351:   /* Points to next temporary slot.  */
                    352:   struct temp_slot *next;
                    353:   /* The rtx to used to reference the slot. */
                    354:   rtx slot;
1.1.1.7   root      355:   /* The rtx used to represent the address if not the address of the
                    356:      slot above.  May be an EXPR_LIST if multiple addresses exist.  */
                    357:   rtx address;
1.1       root      358:   /* The size, in units, of the slot.  */
                    359:   int size;
1.1.1.6   root      360:   /* The value of `sequence_rtl_expr' when this temporary is allocated.  */
                    361:   tree rtl_expr;
1.1       root      362:   /* Non-zero if this temporary is currently in use.  */
                    363:   char in_use;
1.1.1.7   root      364:   /* Non-zero if this temporary has its address taken.  */
                    365:   char addr_taken;
1.1       root      366:   /* Nesting level at which this slot is being used.  */
                    367:   int level;
                    368:   /* Non-zero if this should survive a call to free_temp_slots.  */
                    369:   int keep;
1.1.1.8 ! root      370:   /* The offset of the slot from the frame_pointer, including extra space
        !           371:      for alignment.  This info is for combine_temp_slots.  */
        !           372:   int base_offset;
        !           373:   /* The size of the slot, including extra space for alignment.  This
        !           374:      info is for combine_temp_slots.  */
        !           375:   int full_size;
1.1       root      376: };
                    377: 
                    378: /* List of all temporaries allocated, both available and in use.  */
                    379: 
                    380: struct temp_slot *temp_slots;
                    381: 
                    382: /* Current nesting level for temporaries.  */
                    383: 
                    384: int temp_slot_level;
                    385: 
1.1.1.6   root      386: /* The FUNCTION_DECL node for the current function.  */
                    387: static tree this_function_decl;
                    388: 
                    389: /* Callinfo pointer for the current function.  */
                    390: static rtx this_function_callinfo;
                    391: 
                    392: /* The label in the bytecode file of this function's actual bytecode.
                    393:    Not an rtx.  */
                    394: static char *this_function_bytecode;
                    395: 
                    396: /* The call description vector for the current function.  */
                    397: static rtx this_function_calldesc;
                    398: 
                    399: /* Size of the local variables allocated for the current function.  */
                    400: int local_vars_size;
                    401: 
                    402: /* Current depth of the bytecode evaluation stack.  */
                    403: int stack_depth;
                    404: 
                    405: /* Maximum depth of the evaluation stack in this function.  */
                    406: int max_stack_depth;
                    407: 
                    408: /* Current depth in statement expressions.  */
                    409: static int stmt_expr_depth;
1.1.1.7   root      410: 
                    411: /* This structure is used to record MEMs or pseudos used to replace VAR, any
                    412:    SUBREGs of VAR, and any MEMs containing VAR as an address.  We need to
                    413:    maintain this list in case two operands of an insn were required to match;
                    414:    in that case we must ensure we use the same replacement.  */
                    415: 
                    416: struct fixup_replacement
                    417: {
                    418:   rtx old;
                    419:   rtx new;
                    420:   struct fixup_replacement *next;
                    421: };
                    422:    
                    423: /* Forward declarations.  */
                    424: 
                    425: static struct temp_slot *find_temp_slot_from_address  PROTO((rtx));
                    426: static void put_reg_into_stack PROTO((struct function *, rtx, tree,
1.1.1.8 ! root      427:                                       enum machine_mode, enum machine_mode,
        !           428:                                       int));
1.1.1.7   root      429: static void fixup_var_refs     PROTO((rtx, enum machine_mode, int));
                    430: static struct fixup_replacement
                    431:   *find_fixup_replacement      PROTO((struct fixup_replacement **, rtx));
                    432: static void fixup_var_refs_insns PROTO((rtx, enum machine_mode, int,
                    433:                                        rtx, int));
                    434: static void fixup_var_refs_1   PROTO((rtx, enum machine_mode, rtx *, rtx,
                    435:                                       struct fixup_replacement **));
                    436: static rtx fixup_memory_subreg PROTO((rtx, rtx, int));
                    437: static rtx walk_fixup_memory_subreg  PROTO((rtx, rtx, int));
                    438: static rtx fixup_stack_1       PROTO((rtx, rtx));
                    439: static void optimize_bit_field PROTO((rtx, rtx, rtx *));
                    440: static void instantiate_decls  PROTO((tree, int));
                    441: static void instantiate_decls_1        PROTO((tree, int));
                    442: static void instantiate_decl   PROTO((rtx, int, int));
                    443: static int instantiate_virtual_regs_1 PROTO((rtx *, rtx, int));
                    444: static void delete_handlers    PROTO((void));
                    445: static void pad_to_arg_alignment PROTO((struct args_size *, int));
                    446: static void pad_below          PROTO((struct args_size *, enum  machine_mode,
                    447:                                       tree));
                    448: static tree round_down         PROTO((tree, int));
                    449: static rtx round_trampoline_addr PROTO((rtx));
                    450: static tree blocks_nreverse    PROTO((tree));
                    451: static int all_blocks          PROTO((tree, tree *));
                    452: static int *record_insns       PROTO((rtx));
                    453: static int contains            PROTO((rtx, int *));
1.1.1.6   root      454: 
1.1       root      455: /* Pointer to chain of `struct function' for containing functions.  */
                    456: struct function *outer_function_chain;
                    457: 
                    458: /* Given a function decl for a containing function,
                    459:    return the `struct function' for it.  */
                    460: 
                    461: struct function *
                    462: find_function_data (decl)
                    463:      tree decl;
                    464: {
                    465:   struct function *p;
                    466:   for (p = outer_function_chain; p; p = p->next)
                    467:     if (p->decl == decl)
                    468:       return p;
                    469:   abort ();
                    470: }
                    471: 
                    472: /* Save the current context for compilation of a nested function.
                    473:    This is called from language-specific code.
                    474:    The caller is responsible for saving any language-specific status,
1.1.1.3   root      475:    since this function knows only about language-independent variables.  */
1.1       root      476: 
                    477: void
1.1.1.8 ! root      478: push_function_context_to (context)
        !           479:      tree context;
1.1       root      480: {
                    481:   struct function *p = (struct function *) xmalloc (sizeof (struct function));
                    482: 
                    483:   p->next = outer_function_chain;
                    484:   outer_function_chain = p;
                    485: 
                    486:   p->name = current_function_name;
                    487:   p->decl = current_function_decl;
                    488:   p->pops_args = current_function_pops_args;
                    489:   p->returns_struct = current_function_returns_struct;
                    490:   p->returns_pcc_struct = current_function_returns_pcc_struct;
                    491:   p->needs_context = current_function_needs_context;
                    492:   p->calls_setjmp = current_function_calls_setjmp;
                    493:   p->calls_longjmp = current_function_calls_longjmp;
                    494:   p->calls_alloca = current_function_calls_alloca;
                    495:   p->has_nonlocal_label = current_function_has_nonlocal_label;
1.1.1.6   root      496:   p->has_nonlocal_goto = current_function_has_nonlocal_goto;
1.1.1.8 ! root      497:   p->contains_functions = current_function_contains_functions;
1.1       root      498:   p->args_size = current_function_args_size;
                    499:   p->pretend_args_size = current_function_pretend_args_size;
                    500:   p->arg_offset_rtx = current_function_arg_offset_rtx;
1.1.1.7   root      501:   p->varargs = current_function_varargs;
1.1.1.8 ! root      502:   p->stdarg = current_function_stdarg;
1.1       root      503:   p->uses_const_pool = current_function_uses_const_pool;
                    504:   p->uses_pic_offset_table = current_function_uses_pic_offset_table;
                    505:   p->internal_arg_pointer = current_function_internal_arg_pointer;
                    506:   p->max_parm_reg = max_parm_reg;
                    507:   p->parm_reg_stack_loc = parm_reg_stack_loc;
                    508:   p->outgoing_args_size = current_function_outgoing_args_size;
                    509:   p->return_rtx = current_function_return_rtx;
                    510:   p->nonlocal_goto_handler_slot = nonlocal_goto_handler_slot;
                    511:   p->nonlocal_goto_stack_level = nonlocal_goto_stack_level;
                    512:   p->nonlocal_labels = nonlocal_labels;
                    513:   p->cleanup_label = cleanup_label;
                    514:   p->return_label = return_label;
                    515:   p->save_expr_regs = save_expr_regs;
                    516:   p->stack_slot_list = stack_slot_list;
                    517:   p->parm_birth_insn = parm_birth_insn;
                    518:   p->frame_offset = frame_offset;
                    519:   p->tail_recursion_label = tail_recursion_label;
                    520:   p->tail_recursion_reentry = tail_recursion_reentry;
                    521:   p->arg_pointer_save_area = arg_pointer_save_area;
                    522:   p->rtl_expr_chain = rtl_expr_chain;
                    523:   p->last_parm_insn = last_parm_insn;
                    524:   p->context_display = context_display;
                    525:   p->trampoline_list = trampoline_list;
                    526:   p->function_call_count = function_call_count;
                    527:   p->temp_slots = temp_slots;
                    528:   p->temp_slot_level = temp_slot_level;
                    529:   p->fixup_var_refs_queue = 0;
1.1.1.4   root      530:   p->epilogue_delay_list = current_function_epilogue_delay_list;
1.1       root      531: 
1.1.1.8 ! root      532:   save_tree_status (p, context);
1.1       root      533:   save_storage_status (p);
                    534:   save_emit_status (p);
                    535:   init_emit ();
                    536:   save_expr_status (p);
                    537:   save_stmt_status (p);
1.1.1.4   root      538:   save_varasm_status (p);
1.1.1.6   root      539: 
                    540:   if (save_machine_status)
                    541:     (*save_machine_status) (p);
1.1       root      542: }
                    543: 
1.1.1.7   root      544: void
                    545: push_function_context ()
                    546: {
1.1.1.8 ! root      547:   push_function_context_to (current_function_decl);
1.1.1.7   root      548: }
                    549: 
1.1       root      550: /* Restore the last saved context, at the end of a nested function.
                    551:    This function is called from language-specific code.  */
                    552: 
                    553: void
1.1.1.8 ! root      554: pop_function_context_from (context)
        !           555:      tree context;
1.1       root      556: {
                    557:   struct function *p = outer_function_chain;
                    558: 
                    559:   outer_function_chain = p->next;
                    560: 
1.1.1.8 ! root      561:   current_function_contains_functions
        !           562:     = p->contains_functions || p->inline_obstacks
        !           563:       || context == current_function_decl;
1.1       root      564:   current_function_name = p->name;
                    565:   current_function_decl = p->decl;
                    566:   current_function_pops_args = p->pops_args;
                    567:   current_function_returns_struct = p->returns_struct;
                    568:   current_function_returns_pcc_struct = p->returns_pcc_struct;
                    569:   current_function_needs_context = p->needs_context;
                    570:   current_function_calls_setjmp = p->calls_setjmp;
                    571:   current_function_calls_longjmp = p->calls_longjmp;
                    572:   current_function_calls_alloca = p->calls_alloca;
                    573:   current_function_has_nonlocal_label = p->has_nonlocal_label;
1.1.1.6   root      574:   current_function_has_nonlocal_goto = p->has_nonlocal_goto;
1.1       root      575:   current_function_args_size = p->args_size;
                    576:   current_function_pretend_args_size = p->pretend_args_size;
                    577:   current_function_arg_offset_rtx = p->arg_offset_rtx;
1.1.1.7   root      578:   current_function_varargs = p->varargs;
1.1.1.8 ! root      579:   current_function_stdarg = p->stdarg;
1.1       root      580:   current_function_uses_const_pool = p->uses_const_pool;
                    581:   current_function_uses_pic_offset_table = p->uses_pic_offset_table;
                    582:   current_function_internal_arg_pointer = p->internal_arg_pointer;
                    583:   max_parm_reg = p->max_parm_reg;
                    584:   parm_reg_stack_loc = p->parm_reg_stack_loc;
                    585:   current_function_outgoing_args_size = p->outgoing_args_size;
                    586:   current_function_return_rtx = p->return_rtx;
                    587:   nonlocal_goto_handler_slot = p->nonlocal_goto_handler_slot;
                    588:   nonlocal_goto_stack_level = p->nonlocal_goto_stack_level;
                    589:   nonlocal_labels = p->nonlocal_labels;
                    590:   cleanup_label = p->cleanup_label;
                    591:   return_label = p->return_label;
                    592:   save_expr_regs = p->save_expr_regs;
                    593:   stack_slot_list = p->stack_slot_list;
                    594:   parm_birth_insn = p->parm_birth_insn;
                    595:   frame_offset = p->frame_offset;
                    596:   tail_recursion_label = p->tail_recursion_label;
                    597:   tail_recursion_reentry = p->tail_recursion_reentry;
                    598:   arg_pointer_save_area = p->arg_pointer_save_area;
                    599:   rtl_expr_chain = p->rtl_expr_chain;
                    600:   last_parm_insn = p->last_parm_insn;
                    601:   context_display = p->context_display;
                    602:   trampoline_list = p->trampoline_list;
                    603:   function_call_count = p->function_call_count;
                    604:   temp_slots = p->temp_slots;
                    605:   temp_slot_level = p->temp_slot_level;
1.1.1.4   root      606:   current_function_epilogue_delay_list = p->epilogue_delay_list;
1.1.1.7   root      607:   reg_renumber = 0;
1.1       root      608: 
1.1.1.8 ! root      609:   restore_tree_status (p);
1.1       root      610:   restore_storage_status (p);
                    611:   restore_expr_status (p);
                    612:   restore_emit_status (p);
                    613:   restore_stmt_status (p);
1.1.1.4   root      614:   restore_varasm_status (p);
1.1       root      615: 
1.1.1.6   root      616:   if (restore_machine_status)
                    617:     (*restore_machine_status) (p);
                    618: 
1.1       root      619:   /* Finish doing put_var_into_stack for any of our variables
                    620:      which became addressable during the nested function.  */
                    621:   {
                    622:     struct var_refs_queue *queue = p->fixup_var_refs_queue;
                    623:     for (; queue; queue = queue->next)
1.1.1.4   root      624:       fixup_var_refs (queue->modified, queue->promoted_mode, queue->unsignedp);
1.1       root      625:   }
                    626: 
                    627:   free (p);
                    628: 
                    629:   /* Reset variables that have known state during rtx generation.  */
                    630:   rtx_equal_function_value_matters = 1;
                    631:   virtuals_instantiated = 0;
                    632: }
1.1.1.7   root      633: 
                    634: void pop_function_context ()
                    635: {
1.1.1.8 ! root      636:   pop_function_context_from (current_function_decl);
1.1.1.7   root      637: }
1.1       root      638: 
                    639: /* Allocate fixed slots in the stack frame of the current function.  */
                    640: 
                    641: /* Return size needed for stack frame based on slots so far allocated.
                    642:    This size counts from zero.  It is not rounded to STACK_BOUNDARY;
                    643:    the caller may have to do that.  */
                    644: 
                    645: int
                    646: get_frame_size ()
                    647: {
                    648: #ifdef FRAME_GROWS_DOWNWARD
                    649:   return -frame_offset;
                    650: #else
                    651:   return frame_offset;
                    652: #endif
                    653: }
                    654: 
                    655: /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
                    656:    with machine mode MODE.
                    657:    
                    658:    ALIGN controls the amount of alignment for the address of the slot:
                    659:    0 means according to MODE,
                    660:    -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
                    661:    positive specifies alignment boundary in bits.
                    662: 
                    663:    We do not round to stack_boundary here.  */
                    664: 
                    665: rtx
                    666: assign_stack_local (mode, size, align)
                    667:      enum machine_mode mode;
                    668:      int size;
                    669:      int align;
                    670: {
                    671:   register rtx x, addr;
                    672:   int bigend_correction = 0;
                    673:   int alignment;
                    674: 
                    675:   if (align == 0)
                    676:     {
                    677:       alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
                    678:       if (mode == BLKmode)
                    679:        alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
                    680:     }
                    681:   else if (align == -1)
                    682:     {
                    683:       alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
                    684:       size = CEIL_ROUND (size, alignment);
                    685:     }
                    686:   else
                    687:     alignment = align / BITS_PER_UNIT;
                    688: 
                    689:   /* Round frame offset to that alignment.
                    690:      We must be careful here, since FRAME_OFFSET might be negative and
                    691:      division with a negative dividend isn't as well defined as we might
                    692:      like.  So we instead assume that ALIGNMENT is a power of two and
                    693:      use logical operations which are unambiguous.  */
                    694: #ifdef FRAME_GROWS_DOWNWARD
                    695:   frame_offset = FLOOR_ROUND (frame_offset, alignment);
                    696: #else
                    697:   frame_offset = CEIL_ROUND (frame_offset, alignment);
                    698: #endif
                    699: 
                    700:   /* On a big-endian machine, if we are allocating more space than we will use,
                    701:      use the least significant bytes of those that are allocated.  */
1.1.1.8 ! root      702:   if (BYTES_BIG_ENDIAN && mode != BLKmode)
1.1       root      703:     bigend_correction = size - GET_MODE_SIZE (mode);
                    704: 
                    705: #ifdef FRAME_GROWS_DOWNWARD
                    706:   frame_offset -= size;
                    707: #endif
                    708: 
                    709:   /* If we have already instantiated virtual registers, return the actual
                    710:      address relative to the frame pointer.  */
                    711:   if (virtuals_instantiated)
                    712:     addr = plus_constant (frame_pointer_rtx,
                    713:                          (frame_offset + bigend_correction
                    714:                           + STARTING_FRAME_OFFSET));
                    715:   else
                    716:     addr = plus_constant (virtual_stack_vars_rtx,
                    717:                          frame_offset + bigend_correction);
                    718: 
                    719: #ifndef FRAME_GROWS_DOWNWARD
                    720:   frame_offset += size;
                    721: #endif
                    722: 
                    723:   x = gen_rtx (MEM, mode, addr);
                    724: 
                    725:   stack_slot_list = gen_rtx (EXPR_LIST, VOIDmode, x, stack_slot_list);
                    726: 
                    727:   return x;
                    728: }
                    729: 
                    730: /* Assign a stack slot in a containing function.
                    731:    First three arguments are same as in preceding function.
                    732:    The last argument specifies the function to allocate in.  */
                    733: 
                    734: rtx
                    735: assign_outer_stack_local (mode, size, align, function)
                    736:      enum machine_mode mode;
                    737:      int size;
                    738:      int align;
                    739:      struct function *function;
                    740: {
                    741:   register rtx x, addr;
                    742:   int bigend_correction = 0;
                    743:   int alignment;
                    744: 
                    745:   /* Allocate in the memory associated with the function in whose frame
                    746:      we are assigning.  */
                    747:   push_obstacks (function->function_obstack,
                    748:                 function->function_maybepermanent_obstack);
                    749: 
                    750:   if (align == 0)
                    751:     {
                    752:       alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
                    753:       if (mode == BLKmode)
                    754:        alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
                    755:     }
                    756:   else if (align == -1)
                    757:     {
                    758:       alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
                    759:       size = CEIL_ROUND (size, alignment);
                    760:     }
                    761:   else
                    762:     alignment = align / BITS_PER_UNIT;
                    763: 
                    764:   /* Round frame offset to that alignment.  */
                    765: #ifdef FRAME_GROWS_DOWNWARD
1.1.1.4   root      766:   function->frame_offset = FLOOR_ROUND (function->frame_offset, alignment);
1.1       root      767: #else
1.1.1.4   root      768:   function->frame_offset = CEIL_ROUND (function->frame_offset, alignment);
1.1       root      769: #endif
                    770: 
                    771:   /* On a big-endian machine, if we are allocating more space than we will use,
                    772:      use the least significant bytes of those that are allocated.  */
1.1.1.8 ! root      773:   if (BYTES_BIG_ENDIAN && mode != BLKmode)
1.1       root      774:     bigend_correction = size - GET_MODE_SIZE (mode);
                    775: 
                    776: #ifdef FRAME_GROWS_DOWNWARD
                    777:   function->frame_offset -= size;
                    778: #endif
                    779:   addr = plus_constant (virtual_stack_vars_rtx,
                    780:                        function->frame_offset + bigend_correction);
                    781: #ifndef FRAME_GROWS_DOWNWARD
                    782:   function->frame_offset += size;
                    783: #endif
                    784: 
                    785:   x = gen_rtx (MEM, mode, addr);
                    786: 
                    787:   function->stack_slot_list
                    788:     = gen_rtx (EXPR_LIST, VOIDmode, x, function->stack_slot_list);
                    789: 
                    790:   pop_obstacks ();
                    791: 
                    792:   return x;
                    793: }
                    794: 
                    795: /* Allocate a temporary stack slot and record it for possible later
                    796:    reuse.
                    797: 
                    798:    MODE is the machine mode to be given to the returned rtx.
                    799: 
                    800:    SIZE is the size in units of the space required.  We do no rounding here
                    801:    since assign_stack_local will do any required rounding.
                    802: 
1.1.1.7   root      803:    KEEP is 1 if this slot is to be retained after a call to
                    804:    free_temp_slots.  Automatic variables for a block are allocated
                    805:    with this flag.  KEEP is 2, if we allocate a longer term temporary,
                    806:    whose lifetime is controlled by CLEANUP_POINT_EXPRs.  */
1.1       root      807: 
                    808: rtx
                    809: assign_stack_temp (mode, size, keep)
                    810:      enum machine_mode mode;
                    811:      int size;
                    812:      int keep;
                    813: {
                    814:   struct temp_slot *p, *best_p = 0;
                    815: 
1.1.1.7   root      816:   /* If SIZE is -1 it means that somebody tried to allocate a temporary
                    817:      of a variable size.  */
                    818:   if (size == -1)
                    819:     abort ();
                    820: 
1.1       root      821:   /* First try to find an available, already-allocated temporary that is the
                    822:      exact size we require.  */
                    823:   for (p = temp_slots; p; p = p->next)
                    824:     if (p->size == size && GET_MODE (p->slot) == mode && ! p->in_use)
                    825:       break;
                    826: 
                    827:   /* If we didn't find, one, try one that is larger than what we want.  We
                    828:      find the smallest such.  */
                    829:   if (p == 0)
                    830:     for (p = temp_slots; p; p = p->next)
                    831:       if (p->size > size && GET_MODE (p->slot) == mode && ! p->in_use
                    832:          && (best_p == 0 || best_p->size > p->size))
                    833:        best_p = p;
                    834: 
                    835:   /* Make our best, if any, the one to use.  */
                    836:   if (best_p)
1.1.1.6   root      837:     {
                    838:       /* If there are enough aligned bytes left over, make them into a new
                    839:         temp_slot so that the extra bytes don't get wasted.  Do this only
                    840:         for BLKmode slots, so that we can be sure of the alignment.  */
                    841:       if (GET_MODE (best_p->slot) == BLKmode)
                    842:        {
                    843:          int alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
                    844:          int rounded_size = CEIL_ROUND (size, alignment);
                    845: 
                    846:          if (best_p->size - rounded_size >= alignment)
                    847:            {
                    848:              p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
1.1.1.7   root      849:              p->in_use = p->addr_taken = 0;
1.1.1.6   root      850:              p->size = best_p->size - rounded_size;
1.1.1.8 ! root      851:              p->base_offset = best_p->base_offset + rounded_size;
        !           852:              p->full_size = best_p->full_size - rounded_size;
1.1.1.6   root      853:              p->slot = gen_rtx (MEM, BLKmode,
                    854:                                 plus_constant (XEXP (best_p->slot, 0),
                    855:                                                rounded_size));
1.1.1.7   root      856:              p->address = 0;
                    857:              p->rtl_expr = 0;
1.1.1.6   root      858:              p->next = temp_slots;
                    859:              temp_slots = p;
                    860: 
                    861:              stack_slot_list = gen_rtx (EXPR_LIST, VOIDmode, p->slot,
                    862:                                         stack_slot_list);
                    863: 
                    864:              best_p->size = rounded_size;
1.1.1.8 ! root      865:              best_p->full_size = rounded_size;
1.1.1.6   root      866:            }
                    867:        }
                    868: 
                    869:       p = best_p;
                    870:     }
                    871:              
1.1       root      872:   /* If we still didn't find one, make a new temporary.  */
                    873:   if (p == 0)
                    874:     {
1.1.1.8 ! root      875:       int frame_offset_old = frame_offset;
1.1       root      876:       p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
                    877:       /* If the temp slot mode doesn't indicate the alignment,
                    878:         use the largest possible, so no one will be disappointed.  */
1.1.1.7   root      879:       p->slot = assign_stack_local (mode, size, mode == BLKmode ? -1 : 0);
1.1.1.8 ! root      880:       /* The following slot size computation is necessary because we don't
        !           881:         know the actual size of the temporary slot until assign_stack_local
        !           882:         has performed all the frame alignment and size rounding for the
        !           883:         requested temporary.  Note that extra space added for alignment
        !           884:         can be either above or below this stack slot depending on which
        !           885:         way the frame grows.  We include the extra space if and only if it
        !           886:         is above this slot.  */
        !           887: #ifdef FRAME_GROWS_DOWNWARD
        !           888:       p->size = frame_offset_old - frame_offset;
        !           889: #else
        !           890:       p->size = size;
        !           891: #endif
        !           892:       /* Now define the fields used by combine_temp_slots.  */
        !           893: #ifdef FRAME_GROWS_DOWNWARD
        !           894:       p->base_offset = frame_offset;
        !           895:       p->full_size = frame_offset_old - frame_offset;
        !           896: #else
        !           897:       p->base_offset = frame_offset_old;
        !           898:       p->full_size = frame_offset - frame_offset_old;
        !           899: #endif
1.1.1.7   root      900:       p->address = 0;
1.1       root      901:       p->next = temp_slots;
                    902:       temp_slots = p;
                    903:     }
                    904: 
                    905:   p->in_use = 1;
1.1.1.7   root      906:   p->addr_taken = 0;
1.1.1.6   root      907:   p->rtl_expr = sequence_rtl_expr;
1.1.1.7   root      908: 
                    909:   if (keep == 2)
                    910:     {
                    911:       p->level = target_temp_slot_level;
                    912:       p->keep = 0;
                    913:     }
                    914:   else
                    915:     {
                    916:       p->level = temp_slot_level;
                    917:       p->keep = keep;
                    918:     }
1.1       root      919:   return p->slot;
                    920: }
1.1.1.6   root      921: 
                    922: /* Combine temporary stack slots which are adjacent on the stack.
                    923: 
                    924:    This allows for better use of already allocated stack space.  This is only
                    925:    done for BLKmode slots because we can be sure that we won't have alignment
                    926:    problems in this case.  */
                    927: 
                    928: void
                    929: combine_temp_slots ()
                    930: {
                    931:   struct temp_slot *p, *q;
                    932:   struct temp_slot *prev_p, *prev_q;
                    933:   /* Determine where to free back to after this function.  */
                    934:   rtx free_pointer = rtx_alloc (CONST_INT);
                    935: 
                    936:   for (p = temp_slots, prev_p = 0; p; p = prev_p ? prev_p->next : temp_slots)
                    937:     {
                    938:       int delete_p = 0;
                    939:       if (! p->in_use && GET_MODE (p->slot) == BLKmode)
                    940:        for (q = p->next, prev_q = p; q; q = prev_q->next)
                    941:          {
                    942:            int delete_q = 0;
                    943:            if (! q->in_use && GET_MODE (q->slot) == BLKmode)
                    944:              {
1.1.1.8 ! root      945:                if (p->base_offset + p->full_size == q->base_offset)
1.1.1.6   root      946:                  {
                    947:                    /* Q comes after P; combine Q into P.  */
                    948:                    p->size += q->size;
1.1.1.8 ! root      949:                    p->full_size += q->full_size;
1.1.1.6   root      950:                    delete_q = 1;
                    951:                  }
1.1.1.8 ! root      952:                else if (q->base_offset + q->full_size == p->base_offset)
1.1.1.6   root      953:                  {
                    954:                    /* P comes after Q; combine P into Q.  */
                    955:                    q->size += p->size;
1.1.1.8 ! root      956:                    q->full_size += p->full_size;
1.1.1.6   root      957:                    delete_p = 1;
                    958:                    break;
                    959:                  }
                    960:              }
                    961:            /* Either delete Q or advance past it.  */
                    962:            if (delete_q)
                    963:              prev_q->next = q->next;
                    964:            else
                    965:              prev_q = q;
                    966:          }
                    967:       /* Either delete P or advance past it.  */
                    968:       if (delete_p)
                    969:        {
                    970:          if (prev_p)
                    971:            prev_p->next = p->next;
                    972:          else
                    973:            temp_slots = p->next;
                    974:        }
                    975:       else
                    976:        prev_p = p;
                    977:     }
                    978: 
                    979:   /* Free all the RTL made by plus_constant.  */ 
                    980:   rtx_free (free_pointer);
                    981: }
1.1       root      982: 
1.1.1.7   root      983: /* Find the temp slot corresponding to the object at address X.  */
                    984: 
                    985: static struct temp_slot *
                    986: find_temp_slot_from_address (x)
                    987:      rtx x;
                    988: {
                    989:   struct temp_slot *p;
                    990:   rtx next;
                    991: 
                    992:   for (p = temp_slots; p; p = p->next)
                    993:     {
                    994:       if (! p->in_use)
                    995:        continue;
                    996:       else if (XEXP (p->slot, 0) == x
                    997:               || p->address == x)
                    998:        return p;
                    999: 
                   1000:       else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST)
                   1001:        for (next = p->address; next; next = XEXP (next, 1))
                   1002:          if (XEXP (next, 0) == x)
                   1003:            return p;
                   1004:     }
                   1005: 
                   1006:   return 0;
                   1007: }
                   1008:       
1.1.1.8 ! root     1009: /* Indicate that NEW is an alternate way of referring to the temp slot
1.1.1.7   root     1010:    that previous was known by OLD.  */
                   1011: 
                   1012: void
                   1013: update_temp_slot_address (old, new)
                   1014:      rtx old, new;
                   1015: {
                   1016:   struct temp_slot *p = find_temp_slot_from_address (old);
                   1017: 
                   1018:   /* If none, return.  Else add NEW as an alias.  */
                   1019:   if (p == 0)
                   1020:     return;
                   1021:   else if (p->address == 0)
                   1022:     p->address = new;
                   1023:   else
                   1024:     {
                   1025:       if (GET_CODE (p->address) != EXPR_LIST)
                   1026:        p->address = gen_rtx (EXPR_LIST, VOIDmode, p->address, NULL_RTX);
                   1027: 
                   1028:       p->address = gen_rtx (EXPR_LIST, VOIDmode, new, p->address);
                   1029:     }
                   1030: }
                   1031: 
                   1032: /* If X could be a reference to a temporary slot, mark the fact that its
1.1.1.8 ! root     1033:    address was taken.  */
1.1.1.7   root     1034: 
                   1035: void
                   1036: mark_temp_addr_taken (x)
                   1037:      rtx x;
                   1038: {
                   1039:   struct temp_slot *p;
                   1040: 
                   1041:   if (x == 0)
                   1042:     return;
                   1043: 
                   1044:   /* If X is not in memory or is at a constant address, it cannot be in
                   1045:      a temporary slot.  */
                   1046:   if (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
                   1047:     return;
                   1048: 
                   1049:   p = find_temp_slot_from_address (XEXP (x, 0));
                   1050:   if (p != 0)
                   1051:     p->addr_taken = 1;
                   1052: }
                   1053: 
1.1       root     1054: /* If X could be a reference to a temporary slot, mark that slot as belonging
                   1055:    to the to one level higher.  If X matched one of our slots, just mark that
                   1056:    one.  Otherwise, we can't easily predict which it is, so upgrade all of
                   1057:    them.  Kept slots need not be touched.
                   1058: 
                   1059:    This is called when an ({...}) construct occurs and a statement
                   1060:    returns a value in memory.  */
                   1061: 
                   1062: void
                   1063: preserve_temp_slots (x)
                   1064:      rtx x;
                   1065: {
1.1.1.7   root     1066:   struct temp_slot *p = 0;
                   1067: 
                   1068:   /* If there is no result, we still might have some objects whose address
                   1069:      were taken, so we need to make sure they stay around.  */
                   1070:   if (x == 0)
                   1071:     {
                   1072:       for (p = temp_slots; p; p = p->next)
                   1073:        if (p->in_use && p->level == temp_slot_level && p->addr_taken)
                   1074:          p->level--;
                   1075: 
                   1076:       return;
                   1077:     }
                   1078: 
                   1079:   /* If X is a register that is being used as a pointer, see if we have
                   1080:      a temporary slot we know it points to.  To be consistent with
                   1081:      the code below, we really should preserve all non-kept slots
                   1082:      if we can't find a match, but that seems to be much too costly.  */
                   1083:   if (GET_CODE (x) == REG && REGNO_POINTER_FLAG (REGNO (x)))
                   1084:     p = find_temp_slot_from_address (x);
1.1       root     1085: 
                   1086:   /* If X is not in memory or is at a constant address, it cannot be in
1.1.1.7   root     1087:      a temporary slot, but it can contain something whose address was
                   1088:      taken.  */
                   1089:   if (p == 0 && (GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0))))
                   1090:     {
                   1091:       for (p = temp_slots; p; p = p->next)
                   1092:        if (p->in_use && p->level == temp_slot_level && p->addr_taken)
                   1093:          p->level--;
                   1094: 
                   1095:       return;
                   1096:     }
1.1       root     1097: 
                   1098:   /* First see if we can find a match.  */
1.1.1.7   root     1099:   if (p == 0)
                   1100:     p = find_temp_slot_from_address (XEXP (x, 0));
                   1101: 
                   1102:   if (p != 0)
                   1103:     {
                   1104:       /* Move everything at our level whose address was taken to our new
                   1105:         level in case we used its address.  */
                   1106:       struct temp_slot *q;
                   1107: 
                   1108:       for (q = temp_slots; q; q = q->next)
                   1109:        if (q != p && q->addr_taken && q->level == p->level)
                   1110:          q->level--;
                   1111: 
                   1112:       p->level--;
1.1.1.8 ! root     1113:       p->addr_taken = 0;
1.1.1.7   root     1114:       return;
                   1115:     }
1.1       root     1116: 
                   1117:   /* Otherwise, preserve all non-kept slots at this level.  */
                   1118:   for (p = temp_slots; p; p = p->next)
                   1119:     if (p->in_use && p->level == temp_slot_level && ! p->keep)
                   1120:       p->level--;
                   1121: }
                   1122: 
1.1.1.6   root     1123: /* X is the result of an RTL_EXPR.  If it is a temporary slot associated
                   1124:    with that RTL_EXPR, promote it into a temporary slot at the present
                   1125:    level so it will not be freed when we free slots made in the
                   1126:    RTL_EXPR.  */
                   1127: 
                   1128: void
                   1129: preserve_rtl_expr_result (x)
                   1130:      rtx x;
                   1131: {
                   1132:   struct temp_slot *p;
                   1133: 
                   1134:   /* If X is not in memory or is at a constant address, it cannot be in
                   1135:      a temporary slot.  */
                   1136:   if (x == 0 || GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
                   1137:     return;
                   1138: 
1.1.1.7   root     1139:   /* If we can find a match, move it to our level unless it is already at
                   1140:      an upper level.  */
                   1141:   p = find_temp_slot_from_address (XEXP (x, 0));
                   1142:   if (p != 0)
                   1143:     {
                   1144:       p->level = MIN (p->level, temp_slot_level);
                   1145:       p->rtl_expr = 0;
                   1146:     }
1.1.1.6   root     1147: 
                   1148:   return;
                   1149: }
                   1150: 
1.1       root     1151: /* Free all temporaries used so far.  This is normally called at the end
1.1.1.6   root     1152:    of generating code for a statement.  Don't free any temporaries
                   1153:    currently in use for an RTL_EXPR that hasn't yet been emitted.
                   1154:    We could eventually do better than this since it can be reused while
                   1155:    generating the same RTL_EXPR, but this is complex and probably not
                   1156:    worthwhile.  */
1.1       root     1157: 
                   1158: void
                   1159: free_temp_slots ()
                   1160: {
                   1161:   struct temp_slot *p;
                   1162: 
                   1163:   for (p = temp_slots; p; p = p->next)
1.1.1.6   root     1164:     if (p->in_use && p->level == temp_slot_level && ! p->keep
                   1165:        && p->rtl_expr == 0)
1.1       root     1166:       p->in_use = 0;
1.1.1.6   root     1167: 
                   1168:   combine_temp_slots ();
                   1169: }
                   1170: 
                   1171: /* Free all temporary slots used in T, an RTL_EXPR node.  */
                   1172: 
                   1173: void
                   1174: free_temps_for_rtl_expr (t)
                   1175:      tree t;
                   1176: {
                   1177:   struct temp_slot *p;
                   1178: 
                   1179:   for (p = temp_slots; p; p = p->next)
                   1180:     if (p->rtl_expr == t)
                   1181:       p->in_use = 0;
                   1182: 
                   1183:   combine_temp_slots ();
1.1       root     1184: }
                   1185: 
                   1186: /* Push deeper into the nesting level for stack temporaries.  */
                   1187: 
                   1188: void
                   1189: push_temp_slots ()
                   1190: {
                   1191:   temp_slot_level++;
                   1192: }
                   1193: 
                   1194: /* Pop a temporary nesting level.  All slots in use in the current level
                   1195:    are freed.  */
                   1196: 
                   1197: void
                   1198: pop_temp_slots ()
                   1199: {
                   1200:   struct temp_slot *p;
                   1201: 
                   1202:   for (p = temp_slots; p; p = p->next)
1.1.1.6   root     1203:     if (p->in_use && p->level == temp_slot_level && p->rtl_expr == 0)
1.1       root     1204:       p->in_use = 0;
                   1205: 
1.1.1.6   root     1206:   combine_temp_slots ();
                   1207: 
1.1       root     1208:   temp_slot_level--;
                   1209: }
                   1210: 
                   1211: /* Retroactively move an auto variable from a register to a stack slot.
                   1212:    This is done when an address-reference to the variable is seen.  */
                   1213: 
                   1214: void
                   1215: put_var_into_stack (decl)
                   1216:      tree decl;
                   1217: {
                   1218:   register rtx reg;
1.1.1.4   root     1219:   enum machine_mode promoted_mode, decl_mode;
1.1       root     1220:   struct function *function = 0;
1.1.1.6   root     1221:   tree context;
                   1222: 
                   1223:   if (output_bytecode)
                   1224:     return;
                   1225:   
                   1226:   context = decl_function_context (decl);
1.1       root     1227: 
1.1.1.4   root     1228:   /* Get the current rtl used for this object and it's original mode.  */
1.1       root     1229:   reg = TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl) : DECL_RTL (decl);
                   1230: 
1.1.1.4   root     1231:   /* No need to do anything if decl has no rtx yet
                   1232:      since in that case caller is setting TREE_ADDRESSABLE
                   1233:      and a stack slot will be assigned when the rtl is made.  */
                   1234:   if (reg == 0)
                   1235:     return;
                   1236: 
                   1237:   /* Get the declared mode for this object.  */
                   1238:   decl_mode = (TREE_CODE (decl) == SAVE_EXPR ? TYPE_MODE (TREE_TYPE (decl))
                   1239:               : DECL_MODE (decl));
                   1240:   /* Get the mode it's actually stored in.  */
                   1241:   promoted_mode = GET_MODE (reg);
                   1242: 
1.1       root     1243:   /* If this variable comes from an outer function,
                   1244:      find that function's saved context.  */
                   1245:   if (context != current_function_decl)
                   1246:     for (function = outer_function_chain; function; function = function->next)
                   1247:       if (function->decl == context)
                   1248:        break;
                   1249: 
                   1250:   /* If this is a variable-size object with a pseudo to address it,
                   1251:      put that pseudo into the stack, if the var is nonlocal.  */
1.1.1.4   root     1252:   if (DECL_NONLOCAL (decl)
1.1       root     1253:       && GET_CODE (reg) == MEM
                   1254:       && GET_CODE (XEXP (reg, 0)) == REG
                   1255:       && REGNO (XEXP (reg, 0)) > LAST_VIRTUAL_REGISTER)
1.1.1.4   root     1256:     {
                   1257:       reg = XEXP (reg, 0);
                   1258:       decl_mode = promoted_mode = GET_MODE (reg);
                   1259:     }
1.1.1.5   root     1260: 
1.1.1.6   root     1261:   /* Now we should have a value that resides in one or more pseudo regs.  */
                   1262: 
                   1263:   if (GET_CODE (reg) == REG)
                   1264:     put_reg_into_stack (function, reg, TREE_TYPE (decl),
1.1.1.8 ! root     1265:                        promoted_mode, decl_mode, TREE_SIDE_EFFECTS (decl));
1.1.1.6   root     1266:   else if (GET_CODE (reg) == CONCAT)
                   1267:     {
                   1268:       /* A CONCAT contains two pseudos; put them both in the stack.
                   1269:         We do it so they end up consecutive.  */
                   1270:       enum machine_mode part_mode = GET_MODE (XEXP (reg, 0));
                   1271:       tree part_type = TREE_TYPE (TREE_TYPE (decl));
1.1.1.8 ! root     1272: #ifdef FRAME_GROWS_DOWNWARD
1.1.1.6   root     1273:       /* Since part 0 should have a lower address, do it second.  */
1.1.1.8 ! root     1274:       put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
        !          1275:                          part_mode, TREE_SIDE_EFFECTS (decl));
        !          1276:       put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
        !          1277:                          part_mode, TREE_SIDE_EFFECTS (decl));
1.1.1.6   root     1278: #else
1.1.1.8 ! root     1279:       put_reg_into_stack (function, XEXP (reg, 0), part_type, part_mode,
        !          1280:                          part_mode, TREE_SIDE_EFFECTS (decl));
        !          1281:       put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
        !          1282:                          part_mode, TREE_SIDE_EFFECTS (decl));
1.1.1.6   root     1283: #endif
                   1284: 
                   1285:       /* Change the CONCAT into a combined MEM for both parts.  */
                   1286:       PUT_CODE (reg, MEM);
1.1.1.8 ! root     1287:       MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (XEXP (reg, 0));
        !          1288: 
1.1.1.6   root     1289:       /* The two parts are in memory order already.
                   1290:         Use the lower parts address as ours.  */
                   1291:       XEXP (reg, 0) = XEXP (XEXP (reg, 0), 0);
                   1292:       /* Prevent sharing of rtl that might lose.  */
                   1293:       if (GET_CODE (XEXP (reg, 0)) == PLUS)
                   1294:        XEXP (reg, 0) = copy_rtx (XEXP (reg, 0));
                   1295:     }
                   1296: }
                   1297: 
                   1298: /* Subroutine of put_var_into_stack.  This puts a single pseudo reg REG
                   1299:    into the stack frame of FUNCTION (0 means the current function).
                   1300:    DECL_MODE is the machine mode of the user-level data type.
1.1.1.8 ! root     1301:    PROMOTED_MODE is the machine mode of the register.
        !          1302:    VOLATILE_P is nonzero if this is for a "volatile" decl.  */
1.1.1.6   root     1303: 
                   1304: static void
1.1.1.8 ! root     1305: put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p)
1.1.1.6   root     1306:      struct function *function;
                   1307:      rtx reg;
                   1308:      tree type;
                   1309:      enum machine_mode promoted_mode, decl_mode;
1.1.1.8 ! root     1310:      int volatile_p;
1.1.1.6   root     1311: {
                   1312:   rtx new = 0;
1.1       root     1313: 
                   1314:   if (function)
                   1315:     {
                   1316:       if (REGNO (reg) < function->max_parm_reg)
                   1317:        new = function->parm_reg_stack_loc[REGNO (reg)];
                   1318:       if (new == 0)
1.1.1.5   root     1319:        new = assign_outer_stack_local (decl_mode, GET_MODE_SIZE (decl_mode),
1.1       root     1320:                                        0, function);
                   1321:     }
                   1322:   else
                   1323:     {
                   1324:       if (REGNO (reg) < max_parm_reg)
                   1325:        new = parm_reg_stack_loc[REGNO (reg)];
                   1326:       if (new == 0)
1.1.1.5   root     1327:        new = assign_stack_local (decl_mode, GET_MODE_SIZE (decl_mode), 0);
1.1       root     1328:     }
                   1329: 
1.1.1.8 ! root     1330:   PUT_MODE (reg, decl_mode);
1.1       root     1331:   XEXP (reg, 0) = XEXP (new, 0);
                   1332:   /* `volatil' bit means one thing for MEMs, another entirely for REGs.  */
1.1.1.8 ! root     1333:   MEM_VOLATILE_P (reg) = volatile_p;
1.1       root     1334:   PUT_CODE (reg, MEM);
                   1335: 
                   1336:   /* If this is a memory ref that contains aggregate components,
                   1337:      mark it as such for cse and loop optimize.  */
1.1.1.7   root     1338:   MEM_IN_STRUCT_P (reg) = AGGREGATE_TYPE_P (type);
1.1       root     1339: 
                   1340:   /* Now make sure that all refs to the variable, previously made
                   1341:      when it was a register, are fixed up to be valid again.  */
                   1342:   if (function)
                   1343:     {
                   1344:       struct var_refs_queue *temp;
                   1345: 
                   1346:       /* Variable is inherited; fix it up when we get back to its function.  */
                   1347:       push_obstacks (function->function_obstack,
                   1348:                     function->function_maybepermanent_obstack);
1.1.1.6   root     1349: 
                   1350:       /* See comment in restore_tree_status in tree.c for why this needs to be
                   1351:         on saveable obstack.  */
1.1       root     1352:       temp
1.1.1.6   root     1353:        = (struct var_refs_queue *) savealloc (sizeof (struct var_refs_queue));
1.1       root     1354:       temp->modified = reg;
1.1.1.4   root     1355:       temp->promoted_mode = promoted_mode;
1.1.1.6   root     1356:       temp->unsignedp = TREE_UNSIGNED (type);
1.1       root     1357:       temp->next = function->fixup_var_refs_queue;
                   1358:       function->fixup_var_refs_queue = temp;
                   1359:       pop_obstacks ();
                   1360:     }
                   1361:   else
                   1362:     /* Variable is local; fix it up now.  */
1.1.1.6   root     1363:     fixup_var_refs (reg, promoted_mode, TREE_UNSIGNED (type));
1.1       root     1364: }
                   1365: 
                   1366: static void
1.1.1.4   root     1367: fixup_var_refs (var, promoted_mode, unsignedp)
1.1       root     1368:      rtx var;
1.1.1.4   root     1369:      enum machine_mode promoted_mode;
                   1370:      int unsignedp;
1.1       root     1371: {
                   1372:   tree pending;
                   1373:   rtx first_insn = get_insns ();
                   1374:   struct sequence_stack *stack = sequence_stack;
                   1375:   tree rtl_exps = rtl_expr_chain;
                   1376: 
                   1377:   /* Must scan all insns for stack-refs that exceed the limit.  */
1.1.1.4   root     1378:   fixup_var_refs_insns (var, promoted_mode, unsignedp, first_insn, stack == 0);
1.1       root     1379: 
                   1380:   /* Scan all pending sequences too.  */
                   1381:   for (; stack; stack = stack->next)
                   1382:     {
                   1383:       push_to_sequence (stack->first);
1.1.1.4   root     1384:       fixup_var_refs_insns (var, promoted_mode, unsignedp,
                   1385:                            stack->first, stack->next != 0);
1.1       root     1386:       /* Update remembered end of sequence
                   1387:         in case we added an insn at the end.  */
                   1388:       stack->last = get_last_insn ();
                   1389:       end_sequence ();
                   1390:     }
                   1391: 
                   1392:   /* Scan all waiting RTL_EXPRs too.  */
                   1393:   for (pending = rtl_exps; pending; pending = TREE_CHAIN (pending))
                   1394:     {
                   1395:       rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
                   1396:       if (seq != const0_rtx && seq != 0)
                   1397:        {
                   1398:          push_to_sequence (seq);
1.1.1.4   root     1399:          fixup_var_refs_insns (var, promoted_mode, unsignedp, seq, 0);
1.1       root     1400:          end_sequence ();
                   1401:        }
                   1402:     }
                   1403: }
                   1404: 
1.1.1.7   root     1405: /* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
1.1       root     1406:    some part of an insn.  Return a struct fixup_replacement whose OLD
                   1407:    value is equal to X.  Allocate a new structure if no such entry exists. */
                   1408: 
                   1409: static struct fixup_replacement *
1.1.1.4   root     1410: find_fixup_replacement (replacements, x)
1.1       root     1411:      struct fixup_replacement **replacements;
                   1412:      rtx x;
                   1413: {
                   1414:   struct fixup_replacement *p;
                   1415: 
                   1416:   /* See if we have already replaced this.  */
                   1417:   for (p = *replacements; p && p->old != x; p = p->next)
                   1418:     ;
                   1419: 
                   1420:   if (p == 0)
                   1421:     {
                   1422:       p = (struct fixup_replacement *) oballoc (sizeof (struct fixup_replacement));
                   1423:       p->old = x;
                   1424:       p->new = 0;
                   1425:       p->next = *replacements;
                   1426:       *replacements = p;
                   1427:     }
                   1428: 
                   1429:   return p;
                   1430: }
                   1431: 
                   1432: /* Scan the insn-chain starting with INSN for refs to VAR
                   1433:    and fix them up.  TOPLEVEL is nonzero if this chain is the
                   1434:    main chain of insns for the current function.  */
                   1435: 
                   1436: static void
1.1.1.4   root     1437: fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel)
1.1       root     1438:      rtx var;
1.1.1.4   root     1439:      enum machine_mode promoted_mode;
                   1440:      int unsignedp;
1.1       root     1441:      rtx insn;
                   1442:      int toplevel;
                   1443: {
1.1.1.5   root     1444:   rtx call_dest = 0;
                   1445: 
1.1       root     1446:   while (insn)
                   1447:     {
                   1448:       rtx next = NEXT_INSN (insn);
                   1449:       rtx note;
1.1.1.5   root     1450:       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
1.1       root     1451:        {
1.1.1.7   root     1452:          /* If this is a CLOBBER of VAR, delete it.
                   1453: 
                   1454:             If it has a REG_LIBCALL note, delete the REG_LIBCALL
                   1455:             and REG_RETVAL notes too.  */
1.1.1.8 ! root     1456:          if (GET_CODE (PATTERN (insn)) == CLOBBER
1.1.1.7   root     1457:              && XEXP (PATTERN (insn), 0) == var)
                   1458:            {
                   1459:              if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0)
                   1460:                /* The REG_LIBCALL note will go away since we are going to
                   1461:                   turn INSN into a NOTE, so just delete the
                   1462:                   corresponding REG_RETVAL note.  */
                   1463:                remove_note (XEXP (note, 0),
                   1464:                             find_reg_note (XEXP (note, 0), REG_RETVAL,
                   1465:                                            NULL_RTX));
                   1466: 
                   1467:              /* In unoptimized compilation, we shouldn't call delete_insn
                   1468:                 except in jump.c doing warnings.  */
                   1469:              PUT_CODE (insn, NOTE);
                   1470:              NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
                   1471:              NOTE_SOURCE_FILE (insn) = 0;
                   1472:            }
                   1473: 
1.1       root     1474:          /* The insn to load VAR from a home in the arglist
                   1475:             is now a no-op.  When we see it, just delete it.  */
1.1.1.7   root     1476:          else if (toplevel
                   1477:                   && GET_CODE (PATTERN (insn)) == SET
                   1478:                   && SET_DEST (PATTERN (insn)) == var
                   1479:                   /* If this represents the result of an insn group,
                   1480:                      don't delete the insn.  */
                   1481:                   && find_reg_note (insn, REG_RETVAL, NULL_RTX) == 0
                   1482:                   && rtx_equal_p (SET_SRC (PATTERN (insn)), var))
1.1       root     1483:            {
1.1.1.4   root     1484:              /* In unoptimized compilation, we shouldn't call delete_insn
                   1485:                 except in jump.c doing warnings.  */
                   1486:              PUT_CODE (insn, NOTE);
                   1487:              NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
                   1488:              NOTE_SOURCE_FILE (insn) = 0;
1.1       root     1489:              if (insn == last_parm_insn)
                   1490:                last_parm_insn = PREV_INSN (next);
                   1491:            }
                   1492:          else
                   1493:            {
1.1.1.5   root     1494:              struct fixup_replacement *replacements = 0;
                   1495:              rtx next_insn = NEXT_INSN (insn);
                   1496: 
                   1497: #ifdef SMALL_REGISTER_CLASSES
                   1498:              /* If the insn that copies the results of a CALL_INSN
                   1499:                 into a pseudo now references VAR, we have to use an
                   1500:                 intermediate pseudo since we want the life of the
                   1501:                 return value register to be only a single insn.
                   1502: 
                   1503:                 If we don't use an intermediate pseudo, such things as
                   1504:                 address computations to make the address of VAR valid
1.1.1.8 ! root     1505:                 if it is not can be placed between the CALL_INSN and INSN.
1.1.1.5   root     1506: 
                   1507:                 To make sure this doesn't happen, we record the destination
                   1508:                 of the CALL_INSN and see if the next insn uses both that
                   1509:                 and VAR.  */
                   1510: 
                   1511:              if (call_dest != 0 && GET_CODE (insn) == INSN
                   1512:                  && reg_mentioned_p (var, PATTERN (insn))
                   1513:                  && reg_mentioned_p (call_dest, PATTERN (insn)))
                   1514:                {
                   1515:                  rtx temp = gen_reg_rtx (GET_MODE (call_dest));
                   1516: 
                   1517:                  emit_insn_before (gen_move_insn (temp, call_dest), insn);
                   1518: 
                   1519:                  PATTERN (insn) = replace_rtx (PATTERN (insn),
                   1520:                                                call_dest, temp);
                   1521:                }
                   1522:              
                   1523:              if (GET_CODE (insn) == CALL_INSN
                   1524:                  && GET_CODE (PATTERN (insn)) == SET)
                   1525:                call_dest = SET_DEST (PATTERN (insn));
                   1526:              else if (GET_CODE (insn) == CALL_INSN
                   1527:                       && GET_CODE (PATTERN (insn)) == PARALLEL
                   1528:                       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
                   1529:                call_dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
                   1530:              else
                   1531:                call_dest = 0;
                   1532: #endif
                   1533: 
1.1       root     1534:              /* See if we have to do anything to INSN now that VAR is in
                   1535:                 memory.  If it needs to be loaded into a pseudo, use a single
                   1536:                 pseudo for the entire insn in case there is a MATCH_DUP
                   1537:                 between two operands.  We pass a pointer to the head of
                   1538:                 a list of struct fixup_replacements.  If fixup_var_refs_1
                   1539:                 needs to allocate pseudos or replacement MEMs (for SUBREGs),
                   1540:                 it will record them in this list.
                   1541:                 
                   1542:                 If it allocated a pseudo for any replacement, we copy into
                   1543:                 it here.  */
                   1544: 
1.1.1.4   root     1545:              fixup_var_refs_1 (var, promoted_mode, &PATTERN (insn), insn,
                   1546:                                &replacements);
1.1       root     1547: 
1.1.1.5   root     1548:              /* If this is last_parm_insn, and any instructions were output
                   1549:                 after it to fix it up, then we must set last_parm_insn to
                   1550:                 the last such instruction emitted.  */
                   1551:              if (insn == last_parm_insn)
                   1552:                last_parm_insn = PREV_INSN (next_insn);
                   1553: 
1.1       root     1554:              while (replacements)
                   1555:                {
                   1556:                  if (GET_CODE (replacements->new) == REG)
                   1557:                    {
                   1558:                      rtx insert_before;
1.1.1.4   root     1559:                      rtx seq;
1.1       root     1560: 
                   1561:                      /* OLD might be a (subreg (mem)).  */
                   1562:                      if (GET_CODE (replacements->old) == SUBREG)
                   1563:                        replacements->old
                   1564:                          = fixup_memory_subreg (replacements->old, insn, 0);
                   1565:                      else
                   1566:                        replacements->old
                   1567:                          = fixup_stack_1 (replacements->old, insn);
                   1568: 
1.1.1.7   root     1569:                      insert_before = insn;
1.1       root     1570: 
1.1.1.4   root     1571:                      /* If we are changing the mode, do a conversion.
                   1572:                         This might be wasteful, but combine.c will
                   1573:                         eliminate much of the waste.  */
                   1574: 
                   1575:                      if (GET_MODE (replacements->new)
                   1576:                          != GET_MODE (replacements->old))
                   1577:                        {
                   1578:                          start_sequence ();
                   1579:                          convert_move (replacements->new,
                   1580:                                        replacements->old, unsignedp);
                   1581:                          seq = gen_sequence ();
                   1582:                          end_sequence ();
                   1583:                        }
                   1584:                      else
                   1585:                        seq = gen_move_insn (replacements->new,
                   1586:                                             replacements->old);
                   1587: 
                   1588:                      emit_insn_before (seq, insert_before);
1.1       root     1589:                    }
                   1590: 
                   1591:                  replacements = replacements->next;
                   1592:                }
                   1593:            }
                   1594: 
                   1595:          /* Also fix up any invalid exprs in the REG_NOTES of this insn.
                   1596:             But don't touch other insns referred to by reg-notes;
                   1597:             we will get them elsewhere.  */
                   1598:          for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
                   1599:            if (GET_CODE (note) != INSN_LIST)
1.1.1.5   root     1600:              XEXP (note, 0)
                   1601:                = walk_fixup_memory_subreg (XEXP (note, 0), insn, 1);
1.1       root     1602:        }
                   1603:       insn = next;
                   1604:     }
                   1605: }
                   1606: 
1.1.1.4   root     1607: /* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
                   1608:    See if the rtx expression at *LOC in INSN needs to be changed.  
1.1       root     1609: 
                   1610:    REPLACEMENTS is a pointer to a list head that starts out zero, but may
                   1611:    contain a list of original rtx's and replacements. If we find that we need
                   1612:    to modify this insn by replacing a memory reference with a pseudo or by
                   1613:    making a new MEM to implement a SUBREG, we consult that list to see if
                   1614:    we have already chosen a replacement. If none has already been allocated,
                   1615:    we allocate it and update the list.  fixup_var_refs_insns will copy VAR
                   1616:    or the SUBREG, as appropriate, to the pseudo.  */
                   1617: 
                   1618: static void
1.1.1.4   root     1619: fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements)
1.1       root     1620:      register rtx var;
1.1.1.4   root     1621:      enum machine_mode promoted_mode;
1.1       root     1622:      register rtx *loc;
                   1623:      rtx insn;
                   1624:      struct fixup_replacement **replacements;
                   1625: {
                   1626:   register int i;
                   1627:   register rtx x = *loc;
                   1628:   RTX_CODE code = GET_CODE (x);
                   1629:   register char *fmt;
                   1630:   register rtx tem, tem1;
                   1631:   struct fixup_replacement *replacement;
                   1632: 
                   1633:   switch (code)
                   1634:     {
                   1635:     case MEM:
                   1636:       if (var == x)
                   1637:        {
                   1638:          /* If we already have a replacement, use it.  Otherwise, 
                   1639:             try to fix up this address in case it is invalid.  */
                   1640: 
1.1.1.4   root     1641:          replacement = find_fixup_replacement (replacements, var);
1.1       root     1642:          if (replacement->new)
                   1643:            {
                   1644:              *loc = replacement->new;
                   1645:              return;
                   1646:            }
                   1647: 
                   1648:          *loc = replacement->new = x = fixup_stack_1 (x, insn);
                   1649: 
1.1.1.4   root     1650:          /* Unless we are forcing memory to register or we changed the mode,
                   1651:             we can leave things the way they are if the insn is valid.  */
1.1       root     1652:             
                   1653:          INSN_CODE (insn) = -1;
1.1.1.4   root     1654:          if (! flag_force_mem && GET_MODE (x) == promoted_mode
                   1655:              && recog_memoized (insn) >= 0)
1.1       root     1656:            return;
                   1657: 
1.1.1.4   root     1658:          *loc = replacement->new = gen_reg_rtx (promoted_mode);
1.1       root     1659:          return;
                   1660:        }
                   1661: 
                   1662:       /* If X contains VAR, we need to unshare it here so that we update
                   1663:         each occurrence separately.  But all identical MEMs in one insn
                   1664:         must be replaced with the same rtx because of the possibility of
                   1665:         MATCH_DUPs.  */
                   1666: 
                   1667:       if (reg_mentioned_p (var, x))
                   1668:        {
1.1.1.4   root     1669:          replacement = find_fixup_replacement (replacements, x);
1.1       root     1670:          if (replacement->new == 0)
                   1671:            replacement->new = copy_most_rtx (x, var);
                   1672: 
                   1673:          *loc = x = replacement->new;
                   1674:        }
                   1675:       break;
                   1676: 
                   1677:     case REG:
                   1678:     case CC0:
                   1679:     case PC:
                   1680:     case CONST_INT:
                   1681:     case CONST:
                   1682:     case SYMBOL_REF:
                   1683:     case LABEL_REF:
                   1684:     case CONST_DOUBLE:
                   1685:       return;
                   1686: 
                   1687:     case SIGN_EXTRACT:
                   1688:     case ZERO_EXTRACT:
                   1689:       /* Note that in some cases those types of expressions are altered
                   1690:         by optimize_bit_field, and do not survive to get here.  */
                   1691:       if (XEXP (x, 0) == var
                   1692:          || (GET_CODE (XEXP (x, 0)) == SUBREG
                   1693:              && SUBREG_REG (XEXP (x, 0)) == var))
                   1694:        {
                   1695:          /* Get TEM as a valid MEM in the mode presently in the insn.
                   1696: 
                   1697:             We don't worry about the possibility of MATCH_DUP here; it
                   1698:             is highly unlikely and would be tricky to handle.  */
                   1699: 
                   1700:          tem = XEXP (x, 0);
                   1701:          if (GET_CODE (tem) == SUBREG)
                   1702:            tem = fixup_memory_subreg (tem, insn, 1);
                   1703:          tem = fixup_stack_1 (tem, insn);
                   1704: 
                   1705:          /* Unless we want to load from memory, get TEM into the proper mode
                   1706:             for an extract from memory.  This can only be done if the
                   1707:             extract is at a constant position and length.  */
                   1708: 
                   1709:          if (! flag_force_mem && GET_CODE (XEXP (x, 1)) == CONST_INT
                   1710:              && GET_CODE (XEXP (x, 2)) == CONST_INT
                   1711:              && ! mode_dependent_address_p (XEXP (tem, 0))
                   1712:              && ! MEM_VOLATILE_P (tem))
                   1713:            {
                   1714:              enum machine_mode wanted_mode = VOIDmode;
                   1715:              enum machine_mode is_mode = GET_MODE (tem);
                   1716:              int width = INTVAL (XEXP (x, 1));
                   1717:              int pos = INTVAL (XEXP (x, 2));
                   1718: 
                   1719: #ifdef HAVE_extzv
                   1720:              if (GET_CODE (x) == ZERO_EXTRACT)
                   1721:                wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
                   1722: #endif
                   1723: #ifdef HAVE_extv
                   1724:              if (GET_CODE (x) == SIGN_EXTRACT)
                   1725:                wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
                   1726: #endif
1.1.1.3   root     1727:              /* If we have a narrower mode, we can do something.  */
1.1       root     1728:              if (wanted_mode != VOIDmode
                   1729:                  && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
                   1730:                {
                   1731:                  int offset = pos / BITS_PER_UNIT;
                   1732:                  rtx old_pos = XEXP (x, 2);
                   1733:                  rtx newmem;
                   1734: 
                   1735:                  /* If the bytes and bits are counted differently, we
                   1736:                     must adjust the offset.  */
1.1.1.8 ! root     1737:                  if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
        !          1738:                    offset = (GET_MODE_SIZE (is_mode)
        !          1739:                              - GET_MODE_SIZE (wanted_mode) - offset);
1.1       root     1740: 
                   1741:                  pos %= GET_MODE_BITSIZE (wanted_mode);
                   1742: 
                   1743:                  newmem = gen_rtx (MEM, wanted_mode,
                   1744:                                    plus_constant (XEXP (tem, 0), offset));
                   1745:                  RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
                   1746:                  MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
                   1747:                  MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
                   1748: 
                   1749:                  /* Make the change and see if the insn remains valid.  */
                   1750:                  INSN_CODE (insn) = -1;
                   1751:                  XEXP (x, 0) = newmem;
1.1.1.4   root     1752:                  XEXP (x, 2) = GEN_INT (pos);
1.1       root     1753: 
                   1754:                  if (recog_memoized (insn) >= 0)
                   1755:                    return;
                   1756: 
                   1757:                  /* Otherwise, restore old position.  XEXP (x, 0) will be
                   1758:                     restored later.  */
                   1759:                  XEXP (x, 2) = old_pos;
                   1760:                }
                   1761:            }
                   1762: 
                   1763:          /* If we get here, the bitfield extract insn can't accept a memory
                   1764:             reference.  Copy the input into a register.  */
                   1765: 
                   1766:          tem1 = gen_reg_rtx (GET_MODE (tem));
                   1767:          emit_insn_before (gen_move_insn (tem1, tem), insn);
                   1768:          XEXP (x, 0) = tem1;
                   1769:          return;
                   1770:        }
                   1771:       break;
                   1772:              
                   1773:     case SUBREG:
                   1774:       if (SUBREG_REG (x) == var)
                   1775:        {
1.1.1.4   root     1776:          /* If this is a special SUBREG made because VAR was promoted
                   1777:             from a wider mode, replace it with VAR and call ourself
                   1778:             recursively, this time saying that the object previously
                   1779:             had its current mode (by virtue of the SUBREG).  */
                   1780: 
                   1781:          if (SUBREG_PROMOTED_VAR_P (x))
                   1782:            {
                   1783:              *loc = var;
                   1784:              fixup_var_refs_1 (var, GET_MODE (var), loc, insn, replacements);
                   1785:              return;
                   1786:            }
                   1787: 
1.1       root     1788:          /* If this SUBREG makes VAR wider, it has become a paradoxical
                   1789:             SUBREG with VAR in memory, but these aren't allowed at this 
                   1790:             stage of the compilation.  So load VAR into a pseudo and take
                   1791:             a SUBREG of that pseudo.  */
                   1792:          if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (var)))
                   1793:            {
1.1.1.4   root     1794:              replacement = find_fixup_replacement (replacements, var);
1.1       root     1795:              if (replacement->new == 0)
                   1796:                replacement->new = gen_reg_rtx (GET_MODE (var));
                   1797:              SUBREG_REG (x) = replacement->new;
                   1798:              return;
                   1799:            }
                   1800: 
                   1801:          /* See if we have already found a replacement for this SUBREG.
                   1802:             If so, use it.  Otherwise, make a MEM and see if the insn
                   1803:             is recognized.  If not, or if we should force MEM into a register,
                   1804:             make a pseudo for this SUBREG.  */
1.1.1.4   root     1805:          replacement = find_fixup_replacement (replacements, x);
1.1       root     1806:          if (replacement->new)
                   1807:            {
                   1808:              *loc = replacement->new;
                   1809:              return;
                   1810:            }
                   1811:          
                   1812:          replacement->new = *loc = fixup_memory_subreg (x, insn, 0);
                   1813: 
1.1.1.5   root     1814:          INSN_CODE (insn) = -1;
1.1       root     1815:          if (! flag_force_mem && recog_memoized (insn) >= 0)
                   1816:            return;
                   1817: 
                   1818:          *loc = replacement->new = gen_reg_rtx (GET_MODE (x));
                   1819:          return;
                   1820:        }
                   1821:       break;
                   1822: 
                   1823:     case SET:
                   1824:       /* First do special simplification of bit-field references.  */
                   1825:       if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
                   1826:          || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
                   1827:        optimize_bit_field (x, insn, 0);
                   1828:       if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
                   1829:          || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
1.1.1.4   root     1830:        optimize_bit_field (x, insn, NULL_PTR);
1.1       root     1831: 
                   1832:       /* If SET_DEST is now a paradoxical SUBREG, put the result of this
                   1833:         insn into a pseudo and store the low part of the pseudo into VAR. */
                   1834:       if (GET_CODE (SET_DEST (x)) == SUBREG
                   1835:          && SUBREG_REG (SET_DEST (x)) == var
                   1836:          && (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
                   1837:              > GET_MODE_SIZE (GET_MODE (var))))
                   1838:        {
                   1839:          SET_DEST (x) = tem = gen_reg_rtx (GET_MODE (SET_DEST (x)));
                   1840:          emit_insn_after (gen_move_insn (var, gen_lowpart (GET_MODE (var),
                   1841:                                                            tem)),
                   1842:                           insn);
                   1843:          break;
                   1844:        }
                   1845:          
                   1846:       {
                   1847:        rtx dest = SET_DEST (x);
                   1848:        rtx src = SET_SRC (x);
                   1849:        rtx outerdest = dest;
                   1850: 
                   1851:        while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
                   1852:               || GET_CODE (dest) == SIGN_EXTRACT
                   1853:               || GET_CODE (dest) == ZERO_EXTRACT)
                   1854:          dest = XEXP (dest, 0);
                   1855: 
                   1856:        if (GET_CODE (src) == SUBREG)
                   1857:          src = XEXP (src, 0);
                   1858: 
                   1859:        /* If VAR does not appear at the top level of the SET
                   1860:           just scan the lower levels of the tree.  */
                   1861: 
                   1862:         if (src != var && dest != var)
                   1863:          break;
                   1864: 
                   1865:        /* We will need to rerecognize this insn.  */
                   1866:        INSN_CODE (insn) = -1;
                   1867: 
                   1868: #ifdef HAVE_insv
                   1869:        if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var)
                   1870:          {
                   1871:            /* Since this case will return, ensure we fixup all the
                   1872:               operands here.  */
1.1.1.4   root     1873:            fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 1),
                   1874:                              insn, replacements);
                   1875:            fixup_var_refs_1 (var, promoted_mode, &XEXP (outerdest, 2),
                   1876:                              insn, replacements);
                   1877:            fixup_var_refs_1 (var, promoted_mode, &SET_SRC (x),
                   1878:                              insn, replacements);
1.1       root     1879: 
                   1880:            tem = XEXP (outerdest, 0);
                   1881: 
                   1882:            /* Clean up (SUBREG:SI (MEM:mode ...) 0)
                   1883:               that may appear inside a ZERO_EXTRACT.
                   1884:               This was legitimate when the MEM was a REG.  */
                   1885:            if (GET_CODE (tem) == SUBREG
                   1886:                && SUBREG_REG (tem) == var)
                   1887:              tem = fixup_memory_subreg (tem, insn, 1);
                   1888:            else
                   1889:              tem = fixup_stack_1 (tem, insn);
                   1890: 
                   1891:            if (GET_CODE (XEXP (outerdest, 1)) == CONST_INT
                   1892:                && GET_CODE (XEXP (outerdest, 2)) == CONST_INT
                   1893:                && ! mode_dependent_address_p (XEXP (tem, 0))
                   1894:                && ! MEM_VOLATILE_P (tem))
                   1895:              {
                   1896:                enum machine_mode wanted_mode
                   1897:                  = insn_operand_mode[(int) CODE_FOR_insv][0];
                   1898:                enum machine_mode is_mode = GET_MODE (tem);
                   1899:                int width = INTVAL (XEXP (outerdest, 1));
                   1900:                int pos = INTVAL (XEXP (outerdest, 2));
                   1901: 
1.1.1.3   root     1902:                /* If we have a narrower mode, we can do something.  */
1.1       root     1903:                if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
                   1904:                  {
                   1905:                    int offset = pos / BITS_PER_UNIT;
                   1906:                    rtx old_pos = XEXP (outerdest, 2);
                   1907:                    rtx newmem;
                   1908: 
1.1.1.8 ! root     1909:                    if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
        !          1910:                      offset = (GET_MODE_SIZE (is_mode)
        !          1911:                                - GET_MODE_SIZE (wanted_mode) - offset);
1.1       root     1912: 
                   1913:                    pos %= GET_MODE_BITSIZE (wanted_mode);
                   1914: 
                   1915:                    newmem = gen_rtx (MEM, wanted_mode,
                   1916:                                      plus_constant (XEXP (tem, 0), offset));
                   1917:                    RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
                   1918:                    MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
                   1919:                    MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
                   1920: 
                   1921:                    /* Make the change and see if the insn remains valid.  */
                   1922:                    INSN_CODE (insn) = -1;
                   1923:                    XEXP (outerdest, 0) = newmem;
1.1.1.4   root     1924:                    XEXP (outerdest, 2) = GEN_INT (pos);
1.1       root     1925:                    
                   1926:                    if (recog_memoized (insn) >= 0)
                   1927:                      return;
                   1928:                    
                   1929:                    /* Otherwise, restore old position.  XEXP (x, 0) will be
                   1930:                       restored later.  */
                   1931:                    XEXP (outerdest, 2) = old_pos;
                   1932:                  }
                   1933:              }
                   1934: 
                   1935:            /* If we get here, the bit-field store doesn't allow memory
                   1936:               or isn't located at a constant position.  Load the value into
                   1937:               a register, do the store, and put it back into memory.  */
                   1938: 
                   1939:            tem1 = gen_reg_rtx (GET_MODE (tem));
                   1940:            emit_insn_before (gen_move_insn (tem1, tem), insn);
                   1941:            emit_insn_after (gen_move_insn (tem, tem1), insn);
                   1942:            XEXP (outerdest, 0) = tem1;
                   1943:            return;
                   1944:          }
                   1945: #endif
                   1946: 
                   1947:        /* STRICT_LOW_PART is a no-op on memory references
                   1948:           and it can cause combinations to be unrecognizable,
                   1949:           so eliminate it.  */
                   1950: 
                   1951:        if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
                   1952:          SET_DEST (x) = XEXP (SET_DEST (x), 0);
                   1953: 
                   1954:        /* A valid insn to copy VAR into or out of a register
                   1955:           must be left alone, to avoid an infinite loop here.
                   1956:           If the reference to VAR is by a subreg, fix that up,
                   1957:           since SUBREG is not valid for a memref.
1.1.1.5   root     1958:           Also fix up the address of the stack slot.
                   1959: 
                   1960:           Note that we must not try to recognize the insn until
                   1961:           after we know that we have valid addresses and no
                   1962:           (subreg (mem ...) ...) constructs, since these interfere
                   1963:           with determining the validity of the insn.  */
1.1       root     1964: 
                   1965:        if ((SET_SRC (x) == var
                   1966:             || (GET_CODE (SET_SRC (x)) == SUBREG
                   1967:                 && SUBREG_REG (SET_SRC (x)) == var))
                   1968:            && (GET_CODE (SET_DEST (x)) == REG
                   1969:                || (GET_CODE (SET_DEST (x)) == SUBREG
                   1970:                    && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
1.1.1.5   root     1971:            && x == single_set (PATTERN (insn)))
1.1       root     1972:          {
1.1.1.5   root     1973:            rtx pat;
                   1974: 
1.1.1.4   root     1975:            replacement = find_fixup_replacement (replacements, SET_SRC (x));
1.1       root     1976:            if (replacement->new)
                   1977:              SET_SRC (x) = replacement->new;
                   1978:            else if (GET_CODE (SET_SRC (x)) == SUBREG)
                   1979:              SET_SRC (x) = replacement->new
                   1980:                = fixup_memory_subreg (SET_SRC (x), insn, 0);
                   1981:            else
                   1982:              SET_SRC (x) = replacement->new
                   1983:                = fixup_stack_1 (SET_SRC (x), insn);
1.1.1.5   root     1984: 
                   1985:            if (recog_memoized (insn) >= 0)
                   1986:              return;
                   1987: 
                   1988:            /* INSN is not valid, but we know that we want to
                   1989:               copy SET_SRC (x) to SET_DEST (x) in some way.  So
                   1990:               we generate the move and see whether it requires more
                   1991:               than one insn.  If it does, we emit those insns and
                   1992:               delete INSN.  Otherwise, we an just replace the pattern 
                   1993:               of INSN; we have already verified above that INSN has
                   1994:               no other function that to do X.  */
                   1995: 
                   1996:            pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
                   1997:            if (GET_CODE (pat) == SEQUENCE)
                   1998:              {
                   1999:                emit_insn_after (pat, insn);
                   2000:                PUT_CODE (insn, NOTE);
                   2001:                NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
                   2002:                NOTE_SOURCE_FILE (insn) = 0;
                   2003:              }
                   2004:            else
                   2005:              PATTERN (insn) = pat;
                   2006: 
1.1       root     2007:            return;
                   2008:          }
                   2009: 
                   2010:        if ((SET_DEST (x) == var
                   2011:             || (GET_CODE (SET_DEST (x)) == SUBREG
                   2012:                 && SUBREG_REG (SET_DEST (x)) == var))
                   2013:            && (GET_CODE (SET_SRC (x)) == REG
                   2014:                || (GET_CODE (SET_SRC (x)) == SUBREG
                   2015:                    && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG))
1.1.1.5   root     2016:            && x == single_set (PATTERN (insn)))
1.1       root     2017:          {
1.1.1.5   root     2018:            rtx pat;
                   2019: 
1.1       root     2020:            if (GET_CODE (SET_DEST (x)) == SUBREG)
                   2021:              SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn, 0);
                   2022:            else
                   2023:              SET_DEST (x) = fixup_stack_1 (SET_DEST (x), insn);
1.1.1.5   root     2024: 
                   2025:            if (recog_memoized (insn) >= 0)
                   2026:              return;
                   2027: 
                   2028:            pat = gen_move_insn (SET_DEST (x), SET_SRC (x));
                   2029:            if (GET_CODE (pat) == SEQUENCE)
                   2030:              {
                   2031:                emit_insn_after (pat, insn);
                   2032:                PUT_CODE (insn, NOTE);
                   2033:                NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
                   2034:                NOTE_SOURCE_FILE (insn) = 0;
                   2035:              }
                   2036:            else
                   2037:              PATTERN (insn) = pat;
                   2038: 
1.1       root     2039:            return;
                   2040:          }
                   2041: 
                   2042:        /* Otherwise, storing into VAR must be handled specially
                   2043:           by storing into a temporary and copying that into VAR
1.1.1.4   root     2044:           with a new insn after this one.  Note that this case
                   2045:           will be used when storing into a promoted scalar since
                   2046:           the insn will now have different modes on the input
                   2047:           and output and hence will be invalid (except for the case
                   2048:           of setting it to a constant, which does not need any
                   2049:           change if it is valid).  We generate extra code in that case,
                   2050:           but combine.c will eliminate it.  */
1.1       root     2051: 
                   2052:        if (dest == var)
                   2053:          {
                   2054:            rtx temp;
1.1.1.4   root     2055:            rtx fixeddest = SET_DEST (x);
                   2056: 
1.1       root     2057:            /* STRICT_LOW_PART can be discarded, around a MEM.  */
1.1.1.4   root     2058:            if (GET_CODE (fixeddest) == STRICT_LOW_PART)
                   2059:              fixeddest = XEXP (fixeddest, 0);
1.1       root     2060:            /* Convert (SUBREG (MEM)) to a MEM in a changed mode.  */
1.1.1.4   root     2061:            if (GET_CODE (fixeddest) == SUBREG)
1.1.1.8 ! root     2062:              {
        !          2063:                fixeddest = fixup_memory_subreg (fixeddest, insn, 0);
        !          2064:                promoted_mode = GET_MODE (fixeddest);
        !          2065:              }
1.1       root     2066:            else
1.1.1.4   root     2067:              fixeddest = fixup_stack_1 (fixeddest, insn);
                   2068: 
1.1.1.8 ! root     2069:            temp = gen_reg_rtx (promoted_mode);
1.1.1.4   root     2070: 
                   2071:            emit_insn_after (gen_move_insn (fixeddest,
                   2072:                                            gen_lowpart (GET_MODE (fixeddest),
                   2073:                                                         temp)),
                   2074:                             insn);
1.1       root     2075: 
                   2076:            SET_DEST (x) = temp;
                   2077:          }
                   2078:       }
                   2079:     }
                   2080: 
                   2081:   /* Nothing special about this RTX; fix its operands.  */
                   2082: 
                   2083:   fmt = GET_RTX_FORMAT (code);
                   2084:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   2085:     {
                   2086:       if (fmt[i] == 'e')
1.1.1.4   root     2087:        fixup_var_refs_1 (var, promoted_mode, &XEXP (x, i), insn, replacements);
1.1       root     2088:       if (fmt[i] == 'E')
                   2089:        {
                   2090:          register int j;
                   2091:          for (j = 0; j < XVECLEN (x, i); j++)
1.1.1.4   root     2092:            fixup_var_refs_1 (var, promoted_mode, &XVECEXP (x, i, j),
                   2093:                              insn, replacements);
1.1       root     2094:        }
                   2095:     }
                   2096: }
                   2097: 
                   2098: /* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
                   2099:    return an rtx (MEM:m1 newaddr) which is equivalent.
                   2100:    If any insns must be emitted to compute NEWADDR, put them before INSN.
                   2101: 
                   2102:    UNCRITICAL nonzero means accept paradoxical subregs.
1.1.1.5   root     2103:    This is used for subregs found inside of ZERO_EXTRACTs and in REG_NOTES. */
1.1       root     2104: 
                   2105: static rtx
                   2106: fixup_memory_subreg (x, insn, uncritical)
                   2107:      rtx x;
                   2108:      rtx insn;
                   2109:      int uncritical;
                   2110: {
                   2111:   int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
                   2112:   rtx addr = XEXP (SUBREG_REG (x), 0);
                   2113:   enum machine_mode mode = GET_MODE (x);
                   2114:   rtx saved, result;
                   2115: 
                   2116:   /* Paradoxical SUBREGs are usually invalid during RTL generation.  */
                   2117:   if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
                   2118:       && ! uncritical)
                   2119:     abort ();
                   2120: 
1.1.1.8 ! root     2121:   if (BYTES_BIG_ENDIAN)
        !          2122:     offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
        !          2123:               - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
1.1       root     2124:   addr = plus_constant (addr, offset);
                   2125:   if (!flag_force_addr && memory_address_p (mode, addr))
                   2126:     /* Shortcut if no insns need be emitted.  */
                   2127:     return change_address (SUBREG_REG (x), mode, addr);
                   2128:   start_sequence ();
                   2129:   result = change_address (SUBREG_REG (x), mode, addr);
                   2130:   emit_insn_before (gen_sequence (), insn);
                   2131:   end_sequence ();
                   2132:   return result;
                   2133: }
                   2134: 
                   2135: /* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
                   2136:    Replace subexpressions of X in place.
                   2137:    If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
                   2138:    Otherwise return X, with its contents possibly altered.
                   2139: 
1.1.1.5   root     2140:    If any insns must be emitted to compute NEWADDR, put them before INSN. 
                   2141: 
                   2142:    UNCRITICAL is as in fixup_memory_subreg.  */
1.1       root     2143: 
                   2144: static rtx
1.1.1.5   root     2145: walk_fixup_memory_subreg (x, insn, uncritical)
1.1       root     2146:      register rtx x;
                   2147:      rtx insn;
1.1.1.5   root     2148:      int uncritical;
1.1       root     2149: {
                   2150:   register enum rtx_code code;
                   2151:   register char *fmt;
                   2152:   register int i;
                   2153: 
                   2154:   if (x == 0)
                   2155:     return 0;
                   2156: 
                   2157:   code = GET_CODE (x);
                   2158: 
                   2159:   if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
1.1.1.5   root     2160:     return fixup_memory_subreg (x, insn, uncritical);
1.1       root     2161: 
                   2162:   /* Nothing special about this RTX; fix its operands.  */
                   2163: 
                   2164:   fmt = GET_RTX_FORMAT (code);
                   2165:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   2166:     {
                   2167:       if (fmt[i] == 'e')
1.1.1.5   root     2168:        XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn, uncritical);
1.1       root     2169:       if (fmt[i] == 'E')
                   2170:        {
                   2171:          register int j;
                   2172:          for (j = 0; j < XVECLEN (x, i); j++)
                   2173:            XVECEXP (x, i, j)
1.1.1.5   root     2174:              = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn, uncritical);
1.1       root     2175:        }
                   2176:     }
                   2177:   return x;
                   2178: }
                   2179: 
                   2180: /* For each memory ref within X, if it refers to a stack slot
                   2181:    with an out of range displacement, put the address in a temp register
                   2182:    (emitting new insns before INSN to load these registers)
                   2183:    and alter the memory ref to use that register.
                   2184:    Replace each such MEM rtx with a copy, to avoid clobberage.  */
                   2185: 
                   2186: static rtx
                   2187: fixup_stack_1 (x, insn)
                   2188:      rtx x;
                   2189:      rtx insn;
                   2190: {
                   2191:   register int i;
                   2192:   register RTX_CODE code = GET_CODE (x);
                   2193:   register char *fmt;
                   2194: 
                   2195:   if (code == MEM)
                   2196:     {
                   2197:       register rtx ad = XEXP (x, 0);
                   2198:       /* If we have address of a stack slot but it's not valid
                   2199:         (displacement is too large), compute the sum in a register.  */
                   2200:       if (GET_CODE (ad) == PLUS
                   2201:          && GET_CODE (XEXP (ad, 0)) == REG
1.1.1.6   root     2202:          && ((REGNO (XEXP (ad, 0)) >= FIRST_VIRTUAL_REGISTER
                   2203:               && REGNO (XEXP (ad, 0)) <= LAST_VIRTUAL_REGISTER)
                   2204:              || XEXP (ad, 0) == current_function_internal_arg_pointer)
1.1       root     2205:          && GET_CODE (XEXP (ad, 1)) == CONST_INT)
                   2206:        {
                   2207:          rtx temp, seq;
                   2208:          if (memory_address_p (GET_MODE (x), ad))
                   2209:            return x;
                   2210: 
                   2211:          start_sequence ();
                   2212:          temp = copy_to_reg (ad);
                   2213:          seq = gen_sequence ();
                   2214:          end_sequence ();
                   2215:          emit_insn_before (seq, insn);
                   2216:          return change_address (x, VOIDmode, temp);
                   2217:        }
                   2218:       return x;
                   2219:     }
                   2220: 
                   2221:   fmt = GET_RTX_FORMAT (code);
                   2222:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   2223:     {
                   2224:       if (fmt[i] == 'e')
                   2225:        XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
                   2226:       if (fmt[i] == 'E')
                   2227:        {
                   2228:          register int j;
                   2229:          for (j = 0; j < XVECLEN (x, i); j++)
                   2230:            XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
                   2231:        }
                   2232:     }
                   2233:   return x;
                   2234: }
                   2235: 
                   2236: /* Optimization: a bit-field instruction whose field
                   2237:    happens to be a byte or halfword in memory
                   2238:    can be changed to a move instruction.
                   2239: 
                   2240:    We call here when INSN is an insn to examine or store into a bit-field.
                   2241:    BODY is the SET-rtx to be altered.
                   2242: 
                   2243:    EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
                   2244:    (Currently this is called only from function.c, and EQUIV_MEM
                   2245:    is always 0.)  */
                   2246: 
                   2247: static void
                   2248: optimize_bit_field (body, insn, equiv_mem)
                   2249:      rtx body;
                   2250:      rtx insn;
                   2251:      rtx *equiv_mem;
                   2252: {
                   2253:   register rtx bitfield;
                   2254:   int destflag;
                   2255:   rtx seq = 0;
                   2256:   enum machine_mode mode;
                   2257: 
                   2258:   if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
                   2259:       || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
                   2260:     bitfield = SET_DEST (body), destflag = 1;
                   2261:   else
                   2262:     bitfield = SET_SRC (body), destflag = 0;
                   2263: 
                   2264:   /* First check that the field being stored has constant size and position
                   2265:      and is in fact a byte or halfword suitably aligned.  */
                   2266: 
                   2267:   if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
                   2268:       && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
                   2269:       && ((mode = mode_for_size (INTVAL (XEXP (bitfield, 1)), MODE_INT, 1))
                   2270:          != BLKmode)
                   2271:       && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
                   2272:     {
                   2273:       register rtx memref = 0;
                   2274: 
                   2275:       /* Now check that the containing word is memory, not a register,
                   2276:         and that it is safe to change the machine mode.  */
                   2277: 
                   2278:       if (GET_CODE (XEXP (bitfield, 0)) == MEM)
                   2279:        memref = XEXP (bitfield, 0);
                   2280:       else if (GET_CODE (XEXP (bitfield, 0)) == REG
                   2281:               && equiv_mem != 0)
                   2282:        memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
                   2283:       else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
                   2284:               && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
                   2285:        memref = SUBREG_REG (XEXP (bitfield, 0));
                   2286:       else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
                   2287:               && equiv_mem != 0
                   2288:               && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
                   2289:        memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];
                   2290: 
                   2291:       if (memref
                   2292:          && ! mode_dependent_address_p (XEXP (memref, 0))
                   2293:          && ! MEM_VOLATILE_P (memref))
                   2294:        {
                   2295:          /* Now adjust the address, first for any subreg'ing
                   2296:             that we are now getting rid of,
                   2297:             and then for which byte of the word is wanted.  */
                   2298: 
                   2299:          register int offset = INTVAL (XEXP (bitfield, 2));
1.1.1.7   root     2300:          rtx insns;
                   2301: 
1.1       root     2302:          /* Adjust OFFSET to count bits from low-address byte.  */
1.1.1.8 ! root     2303:          if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
        !          2304:            offset = (GET_MODE_BITSIZE (GET_MODE (XEXP (bitfield, 0)))
        !          2305:                      - offset - INTVAL (XEXP (bitfield, 1)));
        !          2306: 
1.1       root     2307:          /* Adjust OFFSET to count bytes from low-address byte.  */
                   2308:          offset /= BITS_PER_UNIT;
                   2309:          if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
                   2310:            {
                   2311:              offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
1.1.1.8 ! root     2312:              if (BYTES_BIG_ENDIAN)
        !          2313:                offset -= (MIN (UNITS_PER_WORD,
        !          2314:                                GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
        !          2315:                           - MIN (UNITS_PER_WORD,
        !          2316:                                  GET_MODE_SIZE (GET_MODE (memref))));
1.1       root     2317:            }
                   2318: 
1.1.1.7   root     2319:          start_sequence ();
                   2320:          memref = change_address (memref, mode,
1.1       root     2321:                                   plus_constant (XEXP (memref, 0), offset));
1.1.1.7   root     2322:          insns = get_insns ();
                   2323:          end_sequence ();
                   2324:          emit_insns_before (insns, insn);
1.1       root     2325: 
                   2326:          /* Store this memory reference where
                   2327:             we found the bit field reference.  */
                   2328: 
                   2329:          if (destflag)
                   2330:            {
                   2331:              validate_change (insn, &SET_DEST (body), memref, 1);
                   2332:              if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
                   2333:                {
                   2334:                  rtx src = SET_SRC (body);
                   2335:                  while (GET_CODE (src) == SUBREG
                   2336:                         && SUBREG_WORD (src) == 0)
                   2337:                    src = SUBREG_REG (src);
                   2338:                  if (GET_MODE (src) != GET_MODE (memref))
                   2339:                    src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
                   2340:                  validate_change (insn, &SET_SRC (body), src, 1);
                   2341:                }
                   2342:              else if (GET_MODE (SET_SRC (body)) != VOIDmode
                   2343:                       && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
                   2344:                /* This shouldn't happen because anything that didn't have
                   2345:                   one of these modes should have got converted explicitly
                   2346:                   and then referenced through a subreg.
                   2347:                   This is so because the original bit-field was
                   2348:                   handled by agg_mode and so its tree structure had
                   2349:                   the same mode that memref now has.  */
                   2350:                abort ();
                   2351:            }
                   2352:          else
                   2353:            {
                   2354:              rtx dest = SET_DEST (body);
                   2355: 
                   2356:              while (GET_CODE (dest) == SUBREG
1.1.1.8 ! root     2357:                     && SUBREG_WORD (dest) == 0
        !          2358:                     && (GET_MODE_CLASS (GET_MODE (dest))
        !          2359:                         == GET_MODE_CLASS (GET_MODE (SUBREG_REG (dest)))))
1.1       root     2360:                dest = SUBREG_REG (dest);
                   2361: 
                   2362:              validate_change (insn, &SET_DEST (body), dest, 1);
                   2363: 
                   2364:              if (GET_MODE (dest) == GET_MODE (memref))
                   2365:                validate_change (insn, &SET_SRC (body), memref, 1);
                   2366:              else
                   2367:                {
                   2368:                  /* Convert the mem ref to the destination mode.  */
                   2369:                  rtx newreg = gen_reg_rtx (GET_MODE (dest));
                   2370: 
                   2371:                  start_sequence ();
                   2372:                  convert_move (newreg, memref,
                   2373:                                GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
                   2374:                  seq = get_insns ();
                   2375:                  end_sequence ();
                   2376: 
                   2377:                  validate_change (insn, &SET_SRC (body), newreg, 1);
                   2378:                }
                   2379:            }
                   2380: 
                   2381:          /* See if we can convert this extraction or insertion into
                   2382:             a simple move insn.  We might not be able to do so if this
                   2383:             was, for example, part of a PARALLEL.
                   2384: 
                   2385:             If we succeed, write out any needed conversions.  If we fail,
                   2386:             it is hard to guess why we failed, so don't do anything
                   2387:             special; just let the optimization be suppressed.  */
                   2388: 
                   2389:          if (apply_change_group () && seq)
                   2390:            emit_insns_before (seq, insn);
                   2391:        }
                   2392:     }
                   2393: }
                   2394: 
                   2395: /* These routines are responsible for converting virtual register references
                   2396:    to the actual hard register references once RTL generation is complete.
                   2397: 
                   2398:    The following four variables are used for communication between the
                   2399:    routines.  They contain the offsets of the virtual registers from their
                   2400:    respective hard registers.  */
                   2401: 
                   2402: static int in_arg_offset;
                   2403: static int var_offset;
                   2404: static int dynamic_offset;
                   2405: static int out_arg_offset;
                   2406: 
                   2407: /* In most machines, the stack pointer register is equivalent to the bottom
                   2408:    of the stack.  */
                   2409: 
                   2410: #ifndef STACK_POINTER_OFFSET
                   2411: #define STACK_POINTER_OFFSET   0
                   2412: #endif
                   2413: 
                   2414: /* If not defined, pick an appropriate default for the offset of dynamically
                   2415:    allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
                   2416:    REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE.  */
                   2417: 
                   2418: #ifndef STACK_DYNAMIC_OFFSET
                   2419: 
                   2420: #ifdef ACCUMULATE_OUTGOING_ARGS
                   2421: /* The bottom of the stack points to the actual arguments.  If
                   2422:    REG_PARM_STACK_SPACE is defined, this includes the space for the register
                   2423:    parameters.  However, if OUTGOING_REG_PARM_STACK space is not defined,
                   2424:    stack space for register parameters is not pushed by the caller, but 
                   2425:    rather part of the fixed stack areas and hence not included in
                   2426:    `current_function_outgoing_args_size'.  Nevertheless, we must allow
                   2427:    for it when allocating stack dynamic objects.  */
                   2428: 
                   2429: #if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
                   2430: #define STACK_DYNAMIC_OFFSET(FNDECL)   \
                   2431: (current_function_outgoing_args_size   \
                   2432:  + REG_PARM_STACK_SPACE (FNDECL) + (STACK_POINTER_OFFSET))
                   2433: 
                   2434: #else
                   2435: #define STACK_DYNAMIC_OFFSET(FNDECL)   \
                   2436: (current_function_outgoing_args_size + (STACK_POINTER_OFFSET))
                   2437: #endif
                   2438: 
                   2439: #else
                   2440: #define STACK_DYNAMIC_OFFSET(FNDECL) STACK_POINTER_OFFSET
                   2441: #endif
                   2442: #endif
                   2443: 
                   2444: /* Pass through the INSNS of function FNDECL and convert virtual register
                   2445:    references to hard register references.  */
                   2446: 
                   2447: void
                   2448: instantiate_virtual_regs (fndecl, insns)
                   2449:      tree fndecl;
                   2450:      rtx insns;
                   2451: {
                   2452:   rtx insn;
                   2453: 
                   2454:   /* Compute the offsets to use for this function.  */
                   2455:   in_arg_offset = FIRST_PARM_OFFSET (fndecl);
                   2456:   var_offset = STARTING_FRAME_OFFSET;
                   2457:   dynamic_offset = STACK_DYNAMIC_OFFSET (fndecl);
                   2458:   out_arg_offset = STACK_POINTER_OFFSET;
                   2459: 
                   2460:   /* Scan all variables and parameters of this function.  For each that is
                   2461:      in memory, instantiate all virtual registers if the result is a valid
                   2462:      address.  If not, we do it later.  That will handle most uses of virtual
                   2463:      regs on many machines.  */
                   2464:   instantiate_decls (fndecl, 1);
                   2465: 
                   2466:   /* Initialize recognition, indicating that volatile is OK.  */
                   2467:   init_recog ();
                   2468: 
                   2469:   /* Scan through all the insns, instantiating every virtual register still
                   2470:      present.  */
                   2471:   for (insn = insns; insn; insn = NEXT_INSN (insn))
                   2472:     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
                   2473:        || GET_CODE (insn) == CALL_INSN)
                   2474:       {
                   2475:        instantiate_virtual_regs_1 (&PATTERN (insn), insn, 1);
1.1.1.4   root     2476:        instantiate_virtual_regs_1 (&REG_NOTES (insn), NULL_RTX, 0);
1.1       root     2477:       }
                   2478: 
                   2479:   /* Now instantiate the remaining register equivalences for debugging info.
                   2480:      These will not be valid addresses.  */
                   2481:   instantiate_decls (fndecl, 0);
                   2482: 
                   2483:   /* Indicate that, from now on, assign_stack_local should use
                   2484:      frame_pointer_rtx.  */
                   2485:   virtuals_instantiated = 1;
                   2486: }
                   2487: 
                   2488: /* Scan all decls in FNDECL (both variables and parameters) and instantiate
                   2489:    all virtual registers in their DECL_RTL's.
                   2490: 
                   2491:    If VALID_ONLY, do this only if the resulting address is still valid.
                   2492:    Otherwise, always do it.  */
                   2493: 
                   2494: static void
                   2495: instantiate_decls (fndecl, valid_only)
                   2496:      tree fndecl;
                   2497:      int valid_only;
                   2498: {
                   2499:   tree decl;
                   2500: 
1.1.1.8 ! root     2501:   if (DECL_INLINE (fndecl) || DECL_DEFER_OUTPUT (fndecl))
1.1       root     2502:     /* When compiling an inline function, the obstack used for
                   2503:        rtl allocation is the maybepermanent_obstack.  Calling
                   2504:        `resume_temporary_allocation' switches us back to that
                   2505:        obstack while we process this function's parameters.  */
                   2506:     resume_temporary_allocation ();
                   2507: 
                   2508:   /* Process all parameters of the function.  */
                   2509:   for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
                   2510:     {
1.1.1.4   root     2511:       instantiate_decl (DECL_RTL (decl), int_size_in_bytes (TREE_TYPE (decl)),
                   2512:                        valid_only);    
                   2513:       instantiate_decl (DECL_INCOMING_RTL (decl),
                   2514:                        int_size_in_bytes (TREE_TYPE (decl)), valid_only);
1.1       root     2515:     }
                   2516: 
                   2517:   /* Now process all variables defined in the function or its subblocks. */
                   2518:   instantiate_decls_1 (DECL_INITIAL (fndecl), valid_only);
                   2519: 
1.1.1.8 ! root     2520:   if (DECL_INLINE (fndecl) || DECL_DEFER_OUTPUT (fndecl))
1.1       root     2521:     {
                   2522:       /* Save all rtl allocated for this function by raising the
                   2523:         high-water mark on the maybepermanent_obstack.  */
                   2524:       preserve_data ();
                   2525:       /* All further rtl allocation is now done in the current_obstack.  */
                   2526:       rtl_in_current_obstack ();
                   2527:     }
                   2528: }
                   2529: 
                   2530: /* Subroutine of instantiate_decls: Process all decls in the given
                   2531:    BLOCK node and all its subblocks.  */
                   2532: 
                   2533: static void
                   2534: instantiate_decls_1 (let, valid_only)
                   2535:      tree let;
                   2536:      int valid_only;
                   2537: {
                   2538:   tree t;
                   2539: 
                   2540:   for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
1.1.1.4   root     2541:     instantiate_decl (DECL_RTL (t), int_size_in_bytes (TREE_TYPE (t)),
                   2542:                      valid_only);
1.1       root     2543: 
                   2544:   /* Process all subblocks.  */
                   2545:   for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
                   2546:     instantiate_decls_1 (t, valid_only);
                   2547: }
1.1.1.4   root     2548: 
1.1.1.5   root     2549: /* Subroutine of the preceding procedures: Given RTL representing a
1.1.1.4   root     2550:    decl and the size of the object, do any instantiation required.
                   2551: 
                   2552:    If VALID_ONLY is non-zero, it means that the RTL should only be
                   2553:    changed if the new address is valid.  */
                   2554: 
                   2555: static void
                   2556: instantiate_decl (x, size, valid_only)
                   2557:      rtx x;
                   2558:      int size;
                   2559:      int valid_only;
                   2560: {
                   2561:   enum machine_mode mode;
                   2562:   rtx addr;
                   2563: 
                   2564:   /* If this is not a MEM, no need to do anything.  Similarly if the
                   2565:      address is a constant or a register that is not a virtual register.  */
                   2566: 
                   2567:   if (x == 0 || GET_CODE (x) != MEM)
                   2568:     return;
                   2569: 
                   2570:   addr = XEXP (x, 0);
                   2571:   if (CONSTANT_P (addr)
                   2572:       || (GET_CODE (addr) == REG
                   2573:          && (REGNO (addr) < FIRST_VIRTUAL_REGISTER
                   2574:              || REGNO (addr) > LAST_VIRTUAL_REGISTER)))
                   2575:     return;
                   2576: 
                   2577:   /* If we should only do this if the address is valid, copy the address.
                   2578:      We need to do this so we can undo any changes that might make the
                   2579:      address invalid.  This copy is unfortunate, but probably can't be
                   2580:      avoided.  */
                   2581: 
                   2582:   if (valid_only)
                   2583:     addr = copy_rtx (addr);
                   2584: 
                   2585:   instantiate_virtual_regs_1 (&addr, NULL_RTX, 0);
                   2586: 
                   2587:   if (! valid_only)
                   2588:     return;
                   2589: 
                   2590:   /* Now verify that the resulting address is valid for every integer or
                   2591:      floating-point mode up to and including SIZE bytes long.  We do this
                   2592:      since the object might be accessed in any mode and frame addresses
                   2593:      are shared.  */
                   2594: 
                   2595:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
                   2596:        mode != VOIDmode && GET_MODE_SIZE (mode) <= size;
                   2597:        mode = GET_MODE_WIDER_MODE (mode))
                   2598:     if (! memory_address_p (mode, addr))
                   2599:       return;
                   2600: 
                   2601:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
                   2602:        mode != VOIDmode && GET_MODE_SIZE (mode) <= size;
                   2603:        mode = GET_MODE_WIDER_MODE (mode))
                   2604:     if (! memory_address_p (mode, addr))
                   2605:       return;
                   2606: 
                   2607:   /* Otherwise, put back the address, now that we have updated it and we
                   2608:      know it is valid.  */
                   2609: 
                   2610:   XEXP (x, 0) = addr;
                   2611: }
1.1       root     2612: 
                   2613: /* Given a pointer to a piece of rtx and an optional pointer to the
                   2614:    containing object, instantiate any virtual registers present in it.
                   2615: 
                   2616:    If EXTRA_INSNS, we always do the replacement and generate
                   2617:    any extra insns before OBJECT.  If it zero, we do nothing if replacement
                   2618:    is not valid.
                   2619: 
                   2620:    Return 1 if we either had nothing to do or if we were able to do the
                   2621:    needed replacement.  Return 0 otherwise; we only return zero if 
                   2622:    EXTRA_INSNS is zero.
                   2623: 
                   2624:    We first try some simple transformations to avoid the creation of extra
                   2625:    pseudos.  */
                   2626: 
                   2627: static int
                   2628: instantiate_virtual_regs_1 (loc, object, extra_insns)
                   2629:      rtx *loc;
                   2630:      rtx object;
                   2631:      int extra_insns;
                   2632: {
                   2633:   rtx x;
                   2634:   RTX_CODE code;
                   2635:   rtx new = 0;
                   2636:   int offset;
                   2637:   rtx temp;
                   2638:   rtx seq;
                   2639:   int i, j;
                   2640:   char *fmt;
                   2641: 
                   2642:   /* Re-start here to avoid recursion in common cases.  */
                   2643:  restart:
                   2644: 
                   2645:   x = *loc;
                   2646:   if (x == 0)
                   2647:     return 1;
                   2648: 
                   2649:   code = GET_CODE (x);
                   2650: 
                   2651:   /* Check for some special cases.  */
                   2652:   switch (code)
                   2653:     {
                   2654:     case CONST_INT:
                   2655:     case CONST_DOUBLE:
                   2656:     case CONST:
                   2657:     case SYMBOL_REF:
                   2658:     case CODE_LABEL:
                   2659:     case PC:
                   2660:     case CC0:
                   2661:     case ASM_INPUT:
                   2662:     case ADDR_VEC:
                   2663:     case ADDR_DIFF_VEC:
                   2664:     case RETURN:
                   2665:       return 1;
                   2666: 
                   2667:     case SET:
                   2668:       /* We are allowed to set the virtual registers.  This means that
                   2669:         that the actual register should receive the source minus the
                   2670:         appropriate offset.  This is used, for example, in the handling
                   2671:         of non-local gotos.  */
                   2672:       if (SET_DEST (x) == virtual_incoming_args_rtx)
                   2673:        new = arg_pointer_rtx, offset = - in_arg_offset;
                   2674:       else if (SET_DEST (x) == virtual_stack_vars_rtx)
                   2675:        new = frame_pointer_rtx, offset = - var_offset;
                   2676:       else if (SET_DEST (x) == virtual_stack_dynamic_rtx)
                   2677:        new = stack_pointer_rtx, offset = - dynamic_offset;
                   2678:       else if (SET_DEST (x) == virtual_outgoing_args_rtx)
                   2679:        new = stack_pointer_rtx, offset = - out_arg_offset;
                   2680: 
                   2681:       if (new)
                   2682:        {
                   2683:          /* The only valid sources here are PLUS or REG.  Just do
                   2684:             the simplest possible thing to handle them.  */
                   2685:          if (GET_CODE (SET_SRC (x)) != REG
                   2686:              && GET_CODE (SET_SRC (x)) != PLUS)
                   2687:            abort ();
                   2688: 
                   2689:          start_sequence ();
                   2690:          if (GET_CODE (SET_SRC (x)) != REG)
1.1.1.4   root     2691:            temp = force_operand (SET_SRC (x), NULL_RTX);
1.1       root     2692:          else
                   2693:            temp = SET_SRC (x);
1.1.1.4   root     2694:          temp = force_operand (plus_constant (temp, offset), NULL_RTX);
1.1       root     2695:          seq = get_insns ();
                   2696:          end_sequence ();
                   2697: 
                   2698:          emit_insns_before (seq, object);
                   2699:          SET_DEST (x) = new;
                   2700: 
                   2701:          if (!validate_change (object, &SET_SRC (x), temp, 0)
                   2702:              || ! extra_insns)
                   2703:            abort ();
                   2704: 
                   2705:          return 1;
                   2706:        }
                   2707: 
                   2708:       instantiate_virtual_regs_1 (&SET_DEST (x), object, extra_insns);
                   2709:       loc = &SET_SRC (x);
                   2710:       goto restart;
                   2711: 
                   2712:     case PLUS:
                   2713:       /* Handle special case of virtual register plus constant.  */
                   2714:       if (CONSTANT_P (XEXP (x, 1)))
                   2715:        {
1.1.1.8 ! root     2716:          rtx old, new_offset;
1.1       root     2717: 
                   2718:          /* Check for (plus (plus VIRT foo) (const_int)) first.  */
                   2719:          if (GET_CODE (XEXP (x, 0)) == PLUS)
                   2720:            {
                   2721:              rtx inner = XEXP (XEXP (x, 0), 0);
                   2722: 
                   2723:              if (inner == virtual_incoming_args_rtx)
                   2724:                new = arg_pointer_rtx, offset = in_arg_offset;
                   2725:              else if (inner == virtual_stack_vars_rtx)
                   2726:                new = frame_pointer_rtx, offset = var_offset;
                   2727:              else if (inner == virtual_stack_dynamic_rtx)
                   2728:                new = stack_pointer_rtx, offset = dynamic_offset;
                   2729:              else if (inner == virtual_outgoing_args_rtx)
                   2730:                new = stack_pointer_rtx, offset = out_arg_offset;
                   2731:              else
                   2732:                {
                   2733:                  loc = &XEXP (x, 0);
                   2734:                  goto restart;
                   2735:                }
                   2736: 
                   2737:              instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 1), object,
                   2738:                                          extra_insns);
                   2739:              new = gen_rtx (PLUS, Pmode, new, XEXP (XEXP (x, 0), 1));
                   2740:            }
                   2741: 
                   2742:          else if (XEXP (x, 0) == virtual_incoming_args_rtx)
                   2743:            new = arg_pointer_rtx, offset = in_arg_offset;
                   2744:          else if (XEXP (x, 0) == virtual_stack_vars_rtx)
                   2745:            new = frame_pointer_rtx, offset = var_offset;
                   2746:          else if (XEXP (x, 0) == virtual_stack_dynamic_rtx)
                   2747:            new = stack_pointer_rtx, offset = dynamic_offset;
                   2748:          else if (XEXP (x, 0) == virtual_outgoing_args_rtx)
                   2749:            new = stack_pointer_rtx, offset = out_arg_offset;
                   2750:          else
                   2751:            {
                   2752:              /* We know the second operand is a constant.  Unless the
                   2753:                 first operand is a REG (which has been already checked),
                   2754:                 it needs to be checked.  */
                   2755:              if (GET_CODE (XEXP (x, 0)) != REG)
                   2756:                {
                   2757:                  loc = &XEXP (x, 0);
                   2758:                  goto restart;
                   2759:                }
                   2760:              return 1;
                   2761:            }
                   2762: 
1.1.1.8 ! root     2763:          new_offset = plus_constant (XEXP (x, 1), offset);
1.1       root     2764: 
1.1.1.8 ! root     2765:          /* If the new constant is zero, try to replace the sum with just
        !          2766:             the register.  */
        !          2767:          if (new_offset == const0_rtx
        !          2768:              && validate_change (object, loc, new, 0))
1.1       root     2769:            return 1;
                   2770: 
1.1.1.8 ! root     2771:          /* Next try to replace the register and new offset.
        !          2772:             There are two changes to validate here and we can't assume that
        !          2773:             in the case of old offset equals new just changing the register
        !          2774:             will yield a valid insn.  In the interests of a little efficiency,
        !          2775:             however, we only call validate change once (we don't queue up the
        !          2776:             changes and then call apply_change_group). */
        !          2777: 
        !          2778:          old = XEXP (x, 0);
        !          2779:          if (offset == 0
        !          2780:              ? ! validate_change (object, &XEXP (x, 0), new, 0)
        !          2781:              : (XEXP (x, 0) = new,
        !          2782:                 ! validate_change (object, &XEXP (x, 1), new_offset, 0)))
1.1       root     2783:            {
                   2784:              if (! extra_insns)
                   2785:                {
                   2786:                  XEXP (x, 0) = old;
                   2787:                  return 0;
                   2788:                }
                   2789: 
                   2790:              /* Otherwise copy the new constant into a register and replace
                   2791:                 constant with that register.  */
                   2792:              temp = gen_reg_rtx (Pmode);
1.1.1.8 ! root     2793:              XEXP (x, 0) = new;
1.1       root     2794:              if (validate_change (object, &XEXP (x, 1), temp, 0))
1.1.1.8 ! root     2795:                emit_insn_before (gen_move_insn (temp, new_offset), object);
1.1       root     2796:              else
                   2797:                {
                   2798:                  /* If that didn't work, replace this expression with a
                   2799:                     register containing the sum.  */
                   2800: 
                   2801:                  XEXP (x, 0) = old;
1.1.1.8 ! root     2802:                  new = gen_rtx (PLUS, Pmode, new, new_offset);
1.1       root     2803: 
                   2804:                  start_sequence ();
1.1.1.4   root     2805:                  temp = force_operand (new, NULL_RTX);
1.1       root     2806:                  seq = get_insns ();
                   2807:                  end_sequence ();
                   2808: 
                   2809:                  emit_insns_before (seq, object);
                   2810:                  if (! validate_change (object, loc, temp, 0)
                   2811:                      && ! validate_replace_rtx (x, temp, object))
                   2812:                    abort ();
                   2813:                }
                   2814:            }
                   2815: 
                   2816:          return 1;
                   2817:        }
                   2818: 
                   2819:       /* Fall through to generic two-operand expression case.  */
                   2820:     case EXPR_LIST:
                   2821:     case CALL:
                   2822:     case COMPARE:
                   2823:     case MINUS:
                   2824:     case MULT:
                   2825:     case DIV:      case UDIV:
                   2826:     case MOD:      case UMOD:
                   2827:     case AND:      case IOR:      case XOR:
1.1.1.7   root     2828:     case ROTATERT: case ROTATE:
                   2829:     case ASHIFTRT: case LSHIFTRT: case ASHIFT:
1.1       root     2830:     case NE:       case EQ:
                   2831:     case GE:       case GT:       case GEU:    case GTU:
                   2832:     case LE:       case LT:       case LEU:    case LTU:
                   2833:       if (XEXP (x, 1) && ! CONSTANT_P (XEXP (x, 1)))
                   2834:        instantiate_virtual_regs_1 (&XEXP (x, 1), object, extra_insns);
                   2835:       loc = &XEXP (x, 0);
                   2836:       goto restart;
                   2837: 
                   2838:     case MEM:
                   2839:       /* Most cases of MEM that convert to valid addresses have already been
                   2840:         handled by our scan of regno_reg_rtx.  The only special handling we
                   2841:         need here is to make a copy of the rtx to ensure it isn't being
1.1.1.2   root     2842:         shared if we have to change it to a pseudo. 
1.1       root     2843: 
                   2844:         If the rtx is a simple reference to an address via a virtual register,
                   2845:         it can potentially be shared.  In such cases, first try to make it
                   2846:         a valid address, which can also be shared.  Otherwise, copy it and
                   2847:         proceed normally. 
                   2848: 
                   2849:         First check for common cases that need no processing.  These are
                   2850:         usually due to instantiation already being done on a previous instance
                   2851:         of a shared rtx.  */
                   2852: 
                   2853:       temp = XEXP (x, 0);
                   2854:       if (CONSTANT_ADDRESS_P (temp)
                   2855: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
                   2856:          || temp == arg_pointer_rtx
                   2857: #endif
1.1.1.6   root     2858: #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
                   2859:          || temp == hard_frame_pointer_rtx
                   2860: #endif
1.1       root     2861:          || temp == frame_pointer_rtx)
                   2862:        return 1;
                   2863: 
                   2864:       if (GET_CODE (temp) == PLUS
                   2865:          && CONSTANT_ADDRESS_P (XEXP (temp, 1))
                   2866:          && (XEXP (temp, 0) == frame_pointer_rtx
1.1.1.6   root     2867: #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
                   2868:              || XEXP (temp, 0) == hard_frame_pointer_rtx
                   2869: #endif
1.1       root     2870: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
                   2871:              || XEXP (temp, 0) == arg_pointer_rtx
                   2872: #endif
                   2873:              ))
                   2874:        return 1;
                   2875: 
                   2876:       if (temp == virtual_stack_vars_rtx
                   2877:          || temp == virtual_incoming_args_rtx
                   2878:          || (GET_CODE (temp) == PLUS
                   2879:              && CONSTANT_ADDRESS_P (XEXP (temp, 1))
                   2880:              && (XEXP (temp, 0) == virtual_stack_vars_rtx
                   2881:                  || XEXP (temp, 0) == virtual_incoming_args_rtx)))
                   2882:        {
                   2883:          /* This MEM may be shared.  If the substitution can be done without
                   2884:             the need to generate new pseudos, we want to do it in place
                   2885:             so all copies of the shared rtx benefit.  The call below will
                   2886:             only make substitutions if the resulting address is still
                   2887:             valid.
                   2888: 
                   2889:             Note that we cannot pass X as the object in the recursive call
                   2890:             since the insn being processed may not allow all valid
1.1.1.2   root     2891:             addresses.  However, if we were not passed on object, we can
                   2892:             only modify X without copying it if X will have a valid
                   2893:             address.
                   2894: 
                   2895:             ??? Also note that this can still lose if OBJECT is an insn that
                   2896:             has less restrictions on an address that some other insn.
                   2897:             In that case, we will modify the shared address.  This case
                   2898:             doesn't seem very likely, though.  */
1.1       root     2899: 
1.1.1.2   root     2900:          if (instantiate_virtual_regs_1 (&XEXP (x, 0),
                   2901:                                          object ? object : x, 0))
1.1       root     2902:            return 1;
                   2903: 
                   2904:          /* Otherwise make a copy and process that copy.  We copy the entire
                   2905:             RTL expression since it might be a PLUS which could also be
                   2906:             shared.  */
                   2907:          *loc = x = copy_rtx (x);
                   2908:        }
                   2909: 
                   2910:       /* Fall through to generic unary operation case.  */
                   2911:     case USE:
                   2912:     case CLOBBER:
                   2913:     case SUBREG:
                   2914:     case STRICT_LOW_PART:
                   2915:     case NEG:          case NOT:
                   2916:     case PRE_DEC:      case PRE_INC:      case POST_DEC:    case POST_INC:
                   2917:     case SIGN_EXTEND:  case ZERO_EXTEND:
                   2918:     case TRUNCATE:     case FLOAT_EXTEND: case FLOAT_TRUNCATE:
                   2919:     case FLOAT:        case FIX:
                   2920:     case UNSIGNED_FIX: case UNSIGNED_FLOAT:
                   2921:     case ABS:
                   2922:     case SQRT:
                   2923:     case FFS:
                   2924:       /* These case either have just one operand or we know that we need not
                   2925:         check the rest of the operands.  */
                   2926:       loc = &XEXP (x, 0);
                   2927:       goto restart;
                   2928: 
                   2929:     case REG:
                   2930:       /* Try to replace with a PLUS.  If that doesn't work, compute the sum
                   2931:         in front of this insn and substitute the temporary.  */
                   2932:       if (x == virtual_incoming_args_rtx)
                   2933:        new = arg_pointer_rtx, offset = in_arg_offset;
                   2934:       else if (x == virtual_stack_vars_rtx)
                   2935:        new = frame_pointer_rtx, offset = var_offset;
                   2936:       else if (x == virtual_stack_dynamic_rtx)
                   2937:        new = stack_pointer_rtx, offset = dynamic_offset;
                   2938:       else if (x == virtual_outgoing_args_rtx)
                   2939:        new = stack_pointer_rtx, offset = out_arg_offset;
                   2940: 
                   2941:       if (new)
                   2942:        {
                   2943:          temp = plus_constant (new, offset);
                   2944:          if (!validate_change (object, loc, temp, 0))
                   2945:            {
                   2946:              if (! extra_insns)
                   2947:                return 0;
                   2948: 
                   2949:              start_sequence ();
1.1.1.4   root     2950:              temp = force_operand (temp, NULL_RTX);
1.1       root     2951:              seq = get_insns ();
                   2952:              end_sequence ();
                   2953: 
                   2954:              emit_insns_before (seq, object);
                   2955:              if (! validate_change (object, loc, temp, 0)
                   2956:                  && ! validate_replace_rtx (x, temp, object))
                   2957:                abort ();
                   2958:            }
                   2959:        }
                   2960: 
                   2961:       return 1;
                   2962:     }
                   2963: 
                   2964:   /* Scan all subexpressions.  */
                   2965:   fmt = GET_RTX_FORMAT (code);
                   2966:   for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
                   2967:     if (*fmt == 'e')
                   2968:       {
                   2969:        if (!instantiate_virtual_regs_1 (&XEXP (x, i), object, extra_insns))
                   2970:          return 0;
                   2971:       }
                   2972:     else if (*fmt == 'E')
                   2973:       for (j = 0; j < XVECLEN (x, i); j++)
                   2974:        if (! instantiate_virtual_regs_1 (&XVECEXP (x, i, j), object,
                   2975:                                          extra_insns))
                   2976:          return 0;
                   2977: 
                   2978:   return 1;
                   2979: }
                   2980: 
                   2981: /* Optimization: assuming this function does not receive nonlocal gotos,
                   2982:    delete the handlers for such, as well as the insns to establish
                   2983:    and disestablish them.  */
                   2984: 
                   2985: static void
                   2986: delete_handlers ()
                   2987: {
                   2988:   rtx insn;
                   2989:   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
                   2990:     {
                   2991:       /* Delete the handler by turning off the flag that would
                   2992:         prevent jump_optimize from deleting it.
                   2993:         Also permit deletion of the nonlocal labels themselves
                   2994:         if nothing local refers to them.  */
                   2995:       if (GET_CODE (insn) == CODE_LABEL)
1.1.1.8 ! root     2996:        {
        !          2997:          tree t, last_t;
        !          2998: 
        !          2999:          LABEL_PRESERVE_P (insn) = 0;
        !          3000: 
        !          3001:          /* Remove it from the nonlocal_label list, to avoid confusing
        !          3002:             flow.  */
        !          3003:          for (t = nonlocal_labels, last_t = 0; t;
        !          3004:               last_t = t, t = TREE_CHAIN (t))
        !          3005:            if (DECL_RTL (TREE_VALUE (t)) == insn)
        !          3006:              break;
        !          3007:          if (t)
        !          3008:            {
        !          3009:              if (! last_t)
        !          3010:                nonlocal_labels = TREE_CHAIN (nonlocal_labels);
        !          3011:              else
        !          3012:                TREE_CHAIN (last_t) = TREE_CHAIN (t);
        !          3013:            }
        !          3014:        }
1.1       root     3015:       if (GET_CODE (insn) == INSN
1.1.1.3   root     3016:          && ((nonlocal_goto_handler_slot != 0
                   3017:               && reg_mentioned_p (nonlocal_goto_handler_slot, PATTERN (insn)))
                   3018:              || (nonlocal_goto_stack_level != 0
                   3019:                  && reg_mentioned_p (nonlocal_goto_stack_level,
                   3020:                                      PATTERN (insn)))))
1.1       root     3021:        delete_insn (insn);
                   3022:     }
                   3023: }
                   3024: 
                   3025: /* Return a list (chain of EXPR_LIST nodes) for the nonlocal labels
                   3026:    of the current function.  */
                   3027: 
                   3028: rtx
                   3029: nonlocal_label_rtx_list ()
                   3030: {
                   3031:   tree t;
                   3032:   rtx x = 0;
                   3033: 
                   3034:   for (t = nonlocal_labels; t; t = TREE_CHAIN (t))
                   3035:     x = gen_rtx (EXPR_LIST, VOIDmode, label_rtx (TREE_VALUE (t)), x);
                   3036: 
                   3037:   return x;
                   3038: }
                   3039: 
                   3040: /* Output a USE for any register use in RTL.
                   3041:    This is used with -noreg to mark the extent of lifespan
                   3042:    of any registers used in a user-visible variable's DECL_RTL.  */
                   3043: 
                   3044: void
                   3045: use_variable (rtl)
                   3046:      rtx rtl;
                   3047: {
                   3048:   if (GET_CODE (rtl) == REG)
                   3049:     /* This is a register variable.  */
                   3050:     emit_insn (gen_rtx (USE, VOIDmode, rtl));
                   3051:   else if (GET_CODE (rtl) == MEM
                   3052:           && GET_CODE (XEXP (rtl, 0)) == REG
                   3053:           && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
                   3054:               || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
                   3055:           && XEXP (rtl, 0) != current_function_internal_arg_pointer)
                   3056:     /* This is a variable-sized structure.  */
                   3057:     emit_insn (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)));
                   3058: }
                   3059: 
                   3060: /* Like use_variable except that it outputs the USEs after INSN
                   3061:    instead of at the end of the insn-chain.  */
                   3062: 
                   3063: void
                   3064: use_variable_after (rtl, insn)
                   3065:      rtx rtl, insn;
                   3066: {
                   3067:   if (GET_CODE (rtl) == REG)
                   3068:     /* This is a register variable.  */
                   3069:     emit_insn_after (gen_rtx (USE, VOIDmode, rtl), insn);
                   3070:   else if (GET_CODE (rtl) == MEM
                   3071:           && GET_CODE (XEXP (rtl, 0)) == REG
                   3072:           && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
                   3073:               || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
                   3074:           && XEXP (rtl, 0) != current_function_internal_arg_pointer)
                   3075:     /* This is a variable-sized structure.  */
                   3076:     emit_insn_after (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)), insn);
                   3077: }
                   3078: 
                   3079: int
                   3080: max_parm_reg_num ()
                   3081: {
                   3082:   return max_parm_reg;
                   3083: }
                   3084: 
                   3085: /* Return the first insn following those generated by `assign_parms'.  */
                   3086: 
                   3087: rtx
                   3088: get_first_nonparm_insn ()
                   3089: {
                   3090:   if (last_parm_insn)
                   3091:     return NEXT_INSN (last_parm_insn);
                   3092:   return get_insns ();
                   3093: }
                   3094: 
1.1.1.4   root     3095: /* Return the first NOTE_INSN_BLOCK_BEG note in the function.
                   3096:    Crash if there is none.  */
                   3097: 
                   3098: rtx
                   3099: get_first_block_beg ()
                   3100: {
                   3101:   register rtx searcher;
                   3102:   register rtx insn = get_first_nonparm_insn ();
                   3103: 
                   3104:   for (searcher = insn; searcher; searcher = NEXT_INSN (searcher))
                   3105:     if (GET_CODE (searcher) == NOTE
                   3106:        && NOTE_LINE_NUMBER (searcher) == NOTE_INSN_BLOCK_BEG)
                   3107:       return searcher;
                   3108: 
                   3109:   abort ();    /* Invalid call to this function.  (See comments above.)  */
                   3110:   return NULL_RTX;
                   3111: }
                   3112: 
1.1.1.6   root     3113: /* Return 1 if EXP is an aggregate type (or a value with aggregate type).
                   3114:    This means a type for which function calls must pass an address to the
                   3115:    function or get an address back from the function.
                   3116:    EXP may be a type node or an expression (whose type is tested).  */
1.1       root     3117: 
                   3118: int
                   3119: aggregate_value_p (exp)
                   3120:      tree exp;
                   3121: {
1.1.1.4   root     3122:   int i, regno, nregs;
                   3123:   rtx reg;
1.1.1.6   root     3124:   tree type;
                   3125:   if (TREE_CODE_CLASS (TREE_CODE (exp)) == 't')
                   3126:     type = exp;
                   3127:   else
                   3128:     type = TREE_TYPE (exp);
                   3129: 
                   3130:   if (RETURN_IN_MEMORY (type))
1.1       root     3131:     return 1;
1.1.1.7   root     3132:   if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type))
1.1       root     3133:     return 1;
1.1.1.4   root     3134:   /* Make sure we have suitable call-clobbered regs to return
                   3135:      the value in; if not, we must return it in memory.  */
1.1.1.6   root     3136:   reg = hard_function_value (type, 0);
1.1.1.4   root     3137:   regno = REGNO (reg);
1.1.1.6   root     3138:   nregs = HARD_REGNO_NREGS (regno, TYPE_MODE (type));
1.1.1.4   root     3139:   for (i = 0; i < nregs; i++)
                   3140:     if (! call_used_regs[regno + i])
                   3141:       return 1;
1.1       root     3142:   return 0;
                   3143: }
                   3144: 
                   3145: /* Assign RTL expressions to the function's parameters.
                   3146:    This may involve copying them into registers and using
                   3147:    those registers as the RTL for them.
                   3148: 
                   3149:    If SECOND_TIME is non-zero it means that this function is being
                   3150:    called a second time.  This is done by integrate.c when a function's
                   3151:    compilation is deferred.  We need to come back here in case the
                   3152:    FUNCTION_ARG macro computes items needed for the rest of the compilation
                   3153:    (such as changing which registers are fixed or caller-saved).  But suppress
                   3154:    writing any insns or setting DECL_RTL of anything in this case.  */
                   3155: 
                   3156: void
                   3157: assign_parms (fndecl, second_time)
                   3158:      tree fndecl;
                   3159:      int second_time;
                   3160: {
                   3161:   register tree parm;
                   3162:   register rtx entry_parm = 0;
                   3163:   register rtx stack_parm = 0;
                   3164:   CUMULATIVE_ARGS args_so_far;
1.1.1.8 ! root     3165:   enum machine_mode promoted_mode, passed_mode;
        !          3166:   enum machine_mode nominal_mode, promoted_nominal_mode;
1.1.1.4   root     3167:   int unsignedp;
1.1       root     3168:   /* Total space needed so far for args on the stack,
                   3169:      given as a constant and a tree-expression.  */
                   3170:   struct args_size stack_args_size;
                   3171:   tree fntype = TREE_TYPE (fndecl);
                   3172:   tree fnargs = DECL_ARGUMENTS (fndecl);
                   3173:   /* This is used for the arg pointer when referring to stack args.  */
                   3174:   rtx internal_arg_pointer;
                   3175:   /* This is a dummy PARM_DECL that we used for the function result if 
                   3176:      the function returns a structure.  */
                   3177:   tree function_result_decl = 0;
                   3178:   int nparmregs = list_length (fnargs) + LAST_VIRTUAL_REGISTER + 1;
                   3179:   int varargs_setup = 0;
1.1.1.5   root     3180:   rtx conversion_insns = 0;
                   3181:   /* FUNCTION_ARG may look at this variable.  Since this is not
                   3182:      expanding a call it will always be zero in this function.  */
                   3183:   int current_call_is_indirect = 0;
1.1       root     3184: 
                   3185:   /* Nonzero if the last arg is named `__builtin_va_alist',
                   3186:      which is used on some machines for old-fashioned non-ANSI varargs.h;
                   3187:      this should be stuck onto the stack as if it had arrived there.  */
1.1.1.7   root     3188:   int hide_last_arg
                   3189:     = (current_function_varargs
                   3190:        && fnargs
1.1       root     3191:        && (parm = tree_last (fnargs)) != 0
                   3192:        && DECL_NAME (parm)
                   3193:        && (! strcmp (IDENTIFIER_POINTER (DECL_NAME (parm)),
                   3194:                     "__builtin_va_alist")));
                   3195: 
                   3196:   /* Nonzero if function takes extra anonymous args.
                   3197:      This means the last named arg must be on the stack
                   3198:      right before the anonymous ones. */
                   3199:   int stdarg
                   3200:     = (TYPE_ARG_TYPES (fntype) != 0
                   3201:        && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
                   3202:           != void_type_node));
                   3203: 
1.1.1.8 ! root     3204:   current_function_stdarg = stdarg;
        !          3205: 
1.1       root     3206:   /* If the reg that the virtual arg pointer will be translated into is
                   3207:      not a fixed reg or is the stack pointer, make a copy of the virtual
                   3208:      arg pointer, and address parms via the copy.  The frame pointer is
                   3209:      considered fixed even though it is not marked as such.
                   3210: 
                   3211:      The second time through, simply use ap to avoid generating rtx.  */
                   3212: 
                   3213:   if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
                   3214:        || ! (fixed_regs[ARG_POINTER_REGNUM]
                   3215:             || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))
                   3216:       && ! second_time)
                   3217:     internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
                   3218:   else
                   3219:     internal_arg_pointer = virtual_incoming_args_rtx;
                   3220:   current_function_internal_arg_pointer = internal_arg_pointer;
                   3221: 
                   3222:   stack_args_size.constant = 0;
                   3223:   stack_args_size.var = 0;
                   3224: 
                   3225:   /* If struct value address is treated as the first argument, make it so.  */
                   3226:   if (aggregate_value_p (DECL_RESULT (fndecl))
                   3227:       && ! current_function_returns_pcc_struct
                   3228:       && struct_value_incoming_rtx == 0)
                   3229:     {
                   3230:       tree type = build_pointer_type (fntype);
                   3231: 
1.1.1.4   root     3232:       function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
1.1       root     3233: 
                   3234:       DECL_ARG_TYPE (function_result_decl) = type;
                   3235:       TREE_CHAIN (function_result_decl) = fnargs;
                   3236:       fnargs = function_result_decl;
                   3237:     }
                   3238:                               
                   3239:   parm_reg_stack_loc = (rtx *) oballoc (nparmregs * sizeof (rtx));
1.1.1.7   root     3240:   bzero ((char *) parm_reg_stack_loc, nparmregs * sizeof (rtx));
1.1       root     3241: 
                   3242: #ifdef INIT_CUMULATIVE_INCOMING_ARGS
1.1.1.5   root     3243:   INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
1.1       root     3244: #else
1.1.1.5   root     3245:   INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX);
1.1       root     3246: #endif
                   3247: 
                   3248:   /* We haven't yet found an argument that we must push and pretend the
                   3249:      caller did.  */
                   3250:   current_function_pretend_args_size = 0;
                   3251: 
                   3252:   for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
                   3253:     {
1.1.1.7   root     3254:       int aggregate = AGGREGATE_TYPE_P (TREE_TYPE (parm));
1.1       root     3255:       struct args_size stack_offset;
                   3256:       struct args_size arg_size;
                   3257:       int passed_pointer = 0;
1.1.1.8 ! root     3258:       int did_conversion = 0;
1.1       root     3259:       tree passed_type = DECL_ARG_TYPE (parm);
1.1.1.8 ! root     3260:       tree nominal_type = TREE_TYPE (parm);
1.1       root     3261: 
                   3262:       /* Set LAST_NAMED if this is last named arg before some
                   3263:         anonymous args.  We treat it as if it were anonymous too.  */
                   3264:       int last_named = ((TREE_CHAIN (parm) == 0
                   3265:                         || DECL_NAME (TREE_CHAIN (parm)) == 0)
1.1.1.7   root     3266:                        && (stdarg || current_function_varargs));
1.1       root     3267: 
                   3268:       if (TREE_TYPE (parm) == error_mark_node
                   3269:          /* This can happen after weird syntax errors
                   3270:             or if an enum type is defined among the parms.  */
                   3271:          || TREE_CODE (parm) != PARM_DECL
                   3272:          || passed_type == NULL)
                   3273:        {
1.1.1.4   root     3274:          DECL_INCOMING_RTL (parm) = DECL_RTL (parm) = gen_rtx (MEM, BLKmode,
                   3275:                                                                const0_rtx);
1.1       root     3276:          TREE_USED (parm) = 1;
                   3277:          continue;
                   3278:        }
                   3279: 
                   3280:       /* For varargs.h function, save info about regs and stack space
                   3281:         used by the individual args, not including the va_alist arg.  */
1.1.1.7   root     3282:       if (hide_last_arg && last_named)
1.1       root     3283:        current_function_args_info = args_so_far;
                   3284: 
                   3285:       /* Find mode of arg as it is passed, and mode of arg
                   3286:         as it should be during execution of this function.  */
                   3287:       passed_mode = TYPE_MODE (passed_type);
1.1.1.8 ! root     3288:       nominal_mode = TYPE_MODE (nominal_type);
1.1       root     3289: 
1.1.1.4   root     3290:       /* If the parm's mode is VOID, its value doesn't matter,
                   3291:         and avoid the usual things like emit_move_insn that could crash.  */
                   3292:       if (nominal_mode == VOIDmode)
                   3293:        {
                   3294:          DECL_INCOMING_RTL (parm) = DECL_RTL (parm) = const0_rtx;
                   3295:          continue;
                   3296:        }
                   3297: 
1.1.1.7   root     3298:       /* If the parm is to be passed as a transparent union, use the
                   3299:         type of the first field for the tests below.  We have already
                   3300:         verified that the modes are the same.  */
                   3301:       if (DECL_TRANSPARENT_UNION (parm)
                   3302:          || TYPE_TRANSPARENT_UNION (passed_type))
                   3303:        passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
                   3304: 
1.1.1.6   root     3305:       /* See if this arg was passed by invisible reference.  It is if
                   3306:         it is an object whose size depends on the contents of the
                   3307:         object itself or if the machine requires these objects be passed
                   3308:         that way.  */
                   3309: 
                   3310:       if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
                   3311:           && contains_placeholder_p (TYPE_SIZE (passed_type)))
1.1.1.8 ! root     3312:          || TREE_ADDRESSABLE (passed_type)
1.1       root     3313: #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
1.1.1.6   root     3314:          || FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
                   3315:                                              passed_type, ! last_named)
                   3316: #endif
                   3317:          )
1.1       root     3318:        {
1.1.1.8 ! root     3319:          passed_type = nominal_type = build_pointer_type (passed_type);
1.1       root     3320:          passed_pointer = 1;
                   3321:          passed_mode = nominal_mode = Pmode;
                   3322:        }
                   3323: 
1.1.1.4   root     3324:       promoted_mode = passed_mode;
                   3325: 
                   3326: #ifdef PROMOTE_FUNCTION_ARGS
                   3327:       /* Compute the mode in which the arg is actually extended to.  */
1.1.1.7   root     3328:       promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
1.1.1.4   root     3329: #endif
                   3330: 
1.1       root     3331:       /* Let machine desc say which reg (if any) the parm arrives in.
                   3332:         0 means it arrives on the stack.  */
                   3333: #ifdef FUNCTION_INCOMING_ARG
1.1.1.4   root     3334:       entry_parm = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
1.1       root     3335:                                          passed_type, ! last_named);
                   3336: #else
1.1.1.4   root     3337:       entry_parm = FUNCTION_ARG (args_so_far, promoted_mode,
1.1       root     3338:                                 passed_type, ! last_named);
                   3339: #endif
                   3340: 
1.1.1.8 ! root     3341:       if (entry_parm == 0)
        !          3342:        promoted_mode = passed_mode;
1.1.1.4   root     3343: 
1.1       root     3344: #ifdef SETUP_INCOMING_VARARGS
                   3345:       /* If this is the last named parameter, do any required setup for
                   3346:         varargs or stdargs.  We need to know about the case of this being an
                   3347:         addressable type, in which case we skip the registers it
                   3348:         would have arrived in.
                   3349: 
                   3350:         For stdargs, LAST_NAMED will be set for two parameters, the one that
                   3351:         is actually the last named, and the dummy parameter.  We only
                   3352:         want to do this action once.
                   3353: 
                   3354:         Also, indicate when RTL generation is to be suppressed.  */
                   3355:       if (last_named && !varargs_setup)
                   3356:        {
1.1.1.8 ! root     3357:          SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
1.1       root     3358:                                  current_function_pretend_args_size,
                   3359:                                  second_time);
                   3360:          varargs_setup = 1;
                   3361:        }
                   3362: #endif
                   3363: 
                   3364:       /* Determine parm's home in the stack,
                   3365:         in case it arrives in the stack or we should pretend it did.
                   3366: 
                   3367:         Compute the stack position and rtx where the argument arrives
                   3368:         and its size.
                   3369: 
                   3370:         There is one complexity here:  If this was a parameter that would
                   3371:         have been passed in registers, but wasn't only because it is
                   3372:         __builtin_va_alist, we want locate_and_pad_parm to treat it as if
                   3373:         it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
                   3374:         In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
                   3375:         0 as it was the previous time.  */
                   3376: 
1.1.1.8 ! root     3377:       locate_and_pad_parm (promoted_mode, passed_type,
1.1       root     3378: #ifdef STACK_PARMS_IN_REG_PARM_AREA
                   3379:                           1,
                   3380: #else
                   3381: #ifdef FUNCTION_INCOMING_ARG
1.1.1.8 ! root     3382:                           FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
1.1       root     3383:                                                  passed_type,
                   3384:                                                  (! last_named
                   3385:                                                   || varargs_setup)) != 0,
                   3386: #else
1.1.1.8 ! root     3387:                           FUNCTION_ARG (args_so_far, promoted_mode,
1.1       root     3388:                                         passed_type,
                   3389:                                         ! last_named || varargs_setup) != 0,
                   3390: #endif
                   3391: #endif
                   3392:                           fndecl, &stack_args_size, &stack_offset, &arg_size);
                   3393: 
                   3394:       if (! second_time)
                   3395:        {
                   3396:          rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
                   3397: 
                   3398:          if (offset_rtx == const0_rtx)
1.1.1.8 ! root     3399:            stack_parm = gen_rtx (MEM, promoted_mode, internal_arg_pointer);
1.1       root     3400:          else
1.1.1.8 ! root     3401:            stack_parm = gen_rtx (MEM, promoted_mode,
1.1       root     3402:                                  gen_rtx (PLUS, Pmode,
                   3403:                                           internal_arg_pointer, offset_rtx));
                   3404: 
                   3405:          /* If this is a memory ref that contains aggregate components,
                   3406:             mark it as such for cse and loop optimize.  */
                   3407:          MEM_IN_STRUCT_P (stack_parm) = aggregate;
                   3408:        }
                   3409: 
                   3410:       /* If this parameter was passed both in registers and in the stack,
                   3411:         use the copy on the stack.  */
1.1.1.8 ! root     3412:       if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
1.1       root     3413:        entry_parm = 0;
                   3414: 
1.1.1.5   root     3415: #ifdef FUNCTION_ARG_PARTIAL_NREGS
1.1       root     3416:       /* If this parm was passed part in regs and part in memory,
                   3417:         pretend it arrived entirely in memory
                   3418:         by pushing the register-part onto the stack.
                   3419: 
                   3420:         In the special case of a DImode or DFmode that is split,
                   3421:         we could put it together in a pseudoreg directly,
                   3422:         but for now that's not worth bothering with.  */
                   3423: 
                   3424:       if (entry_parm)
                   3425:        {
1.1.1.8 ! root     3426:          int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
1.1.1.5   root     3427:                                                  passed_type, ! last_named);
1.1       root     3428: 
                   3429:          if (nregs > 0)
                   3430:            {
                   3431:              current_function_pretend_args_size
                   3432:                = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
                   3433:                   / (PARM_BOUNDARY / BITS_PER_UNIT)
                   3434:                   * (PARM_BOUNDARY / BITS_PER_UNIT));
                   3435: 
                   3436:              if (! second_time)
                   3437:                move_block_from_reg (REGNO (entry_parm),
1.1.1.6   root     3438:                                     validize_mem (stack_parm), nregs,
                   3439:                                     int_size_in_bytes (TREE_TYPE (parm)));
1.1       root     3440:              entry_parm = stack_parm;
                   3441:            }
                   3442:        }
1.1.1.5   root     3443: #endif
1.1       root     3444: 
                   3445:       /* If we didn't decide this parm came in a register,
                   3446:         by default it came on the stack.  */
                   3447:       if (entry_parm == 0)
                   3448:        entry_parm = stack_parm;
                   3449: 
                   3450:       /* Record permanently how this parm was passed.  */
                   3451:       if (! second_time)
                   3452:        DECL_INCOMING_RTL (parm) = entry_parm;
                   3453: 
                   3454:       /* If there is actually space on the stack for this parm,
                   3455:         count it in stack_args_size; otherwise set stack_parm to 0
                   3456:         to indicate there is no preallocated stack slot for the parm.  */
                   3457: 
                   3458:       if (entry_parm == stack_parm
1.1.1.3   root     3459: #if defined (REG_PARM_STACK_SPACE) && ! defined (MAYBE_REG_PARM_STACK_SPACE)
1.1       root     3460:          /* On some machines, even if a parm value arrives in a register
1.1.1.3   root     3461:             there is still an (uninitialized) stack slot allocated for it.
                   3462: 
                   3463:             ??? When MAYBE_REG_PARM_STACK_SPACE is defined, we can't tell
                   3464:             whether this parameter already has a stack slot allocated,
                   3465:             because an arg block exists only if current_function_args_size
1.1.1.8 ! root     3466:             is larger than some threshold, and we haven't calculated that
1.1.1.3   root     3467:             yet.  So, for now, we just assume that stack slots never exist
                   3468:             in this case.  */
1.1       root     3469:          || REG_PARM_STACK_SPACE (fndecl) > 0
                   3470: #endif
                   3471:          )
                   3472:        {
                   3473:          stack_args_size.constant += arg_size.constant;
                   3474:          if (arg_size.var)
                   3475:            ADD_PARM_SIZE (stack_args_size, arg_size.var);
                   3476:        }
                   3477:       else
                   3478:        /* No stack slot was pushed for this parm.  */
                   3479:        stack_parm = 0;
                   3480: 
                   3481:       /* Update info on where next arg arrives in registers.  */
                   3482: 
1.1.1.8 ! root     3483:       FUNCTION_ARG_ADVANCE (args_so_far, promoted_mode,
1.1       root     3484:                            passed_type, ! last_named);
                   3485: 
                   3486:       /* If this is our second time through, we are done with this parm. */
                   3487:       if (second_time)
                   3488:        continue;
                   3489: 
1.1.1.3   root     3490:       /* If we can't trust the parm stack slot to be aligned enough
                   3491:         for its ultimate type, don't use that slot after entry.
                   3492:         We'll make another stack slot, if we need one.  */
                   3493:       {
                   3494:        int thisparm_boundary
1.1.1.8 ! root     3495:          = FUNCTION_ARG_BOUNDARY (promoted_mode, passed_type);
1.1.1.3   root     3496: 
                   3497:        if (GET_MODE_ALIGNMENT (nominal_mode) > thisparm_boundary)
                   3498:          stack_parm = 0;
                   3499:       }
                   3500: 
1.1.1.6   root     3501:       /* If parm was passed in memory, and we need to convert it on entry,
                   3502:         don't store it back in that same slot.  */
                   3503:       if (entry_parm != 0
                   3504:          && nominal_mode != BLKmode && nominal_mode != passed_mode)
                   3505:        stack_parm = 0;
                   3506: 
                   3507: #if 0
1.1       root     3508:       /* Now adjust STACK_PARM to the mode and precise location
                   3509:         where this parameter should live during execution,
                   3510:         if we discover that it must live in the stack during execution.
                   3511:         To make debuggers happier on big-endian machines, we store
                   3512:         the value in the last bytes of the space available.  */
                   3513: 
                   3514:       if (nominal_mode != BLKmode && nominal_mode != passed_mode
                   3515:          && stack_parm != 0)
                   3516:        {
                   3517:          rtx offset_rtx;
                   3518: 
1.1.1.8 ! root     3519:          if (BYTES_BIG_ENDIAN
        !          3520:              && GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
1.1       root     3521:            stack_offset.constant += (GET_MODE_SIZE (passed_mode)
                   3522:                                      - GET_MODE_SIZE (nominal_mode));
                   3523: 
                   3524:          offset_rtx = ARGS_SIZE_RTX (stack_offset);
                   3525:          if (offset_rtx == const0_rtx)
                   3526:            stack_parm = gen_rtx (MEM, nominal_mode, internal_arg_pointer);
                   3527:          else
                   3528:            stack_parm = gen_rtx (MEM, nominal_mode,
                   3529:                                  gen_rtx (PLUS, Pmode,
                   3530:                                           internal_arg_pointer, offset_rtx));
                   3531: 
                   3532:          /* If this is a memory ref that contains aggregate components,
                   3533:             mark it as such for cse and loop optimize.  */
                   3534:          MEM_IN_STRUCT_P (stack_parm) = aggregate;
                   3535:        }
1.1.1.6   root     3536: #endif /* 0 */
1.1       root     3537: 
1.1.1.8 ! root     3538: #ifdef STACK_REGS
        !          3539:       /* We need this "use" info, because the gcc-register->stack-register
        !          3540:         converter in reg-stack.c needs to know which registers are active
        !          3541:         at the start of the function call.  The actual parameter loading
        !          3542:         instructions are not always available then anymore, since they might
        !          3543:         have been optimised away.  */
        !          3544: 
        !          3545:       if (GET_CODE (entry_parm) == REG && !(hide_last_arg && last_named))
        !          3546:          emit_insn (gen_rtx (USE, GET_MODE (entry_parm), entry_parm));
        !          3547: #endif
        !          3548: 
1.1       root     3549:       /* ENTRY_PARM is an RTX for the parameter as it arrives,
                   3550:         in the mode in which it arrives.
                   3551:         STACK_PARM is an RTX for a stack slot where the parameter can live
                   3552:         during the function (in case we want to put it there).
                   3553:         STACK_PARM is 0 if no stack slot was pushed for it.
                   3554: 
                   3555:         Now output code if necessary to convert ENTRY_PARM to
                   3556:         the type in which this function declares it,
                   3557:         and store that result in an appropriate place,
                   3558:         which may be a pseudo reg, may be STACK_PARM,
                   3559:         or may be a local stack slot if STACK_PARM is 0.
                   3560: 
                   3561:         Set DECL_RTL to that place.  */
                   3562: 
                   3563:       if (nominal_mode == BLKmode)
                   3564:        {
                   3565:          /* If a BLKmode arrives in registers, copy it to a stack slot.  */
                   3566:          if (GET_CODE (entry_parm) == REG)
                   3567:            {
1.1.1.8 ! root     3568:              int size_stored
        !          3569:                = CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
        !          3570:                              UNITS_PER_WORD);
1.1       root     3571: 
                   3572:              /* Note that we will be storing an integral number of words.
                   3573:                 So we have to be careful to ensure that we allocate an
                   3574:                 integral number of words.  We do this below in the
                   3575:                 assign_stack_local if space was not allocated in the argument
                   3576:                 list.  If it was, this will not work if PARM_BOUNDARY is not
                   3577:                 a multiple of BITS_PER_WORD.  It isn't clear how to fix this
                   3578:                 if it becomes a problem.  */
                   3579: 
                   3580:              if (stack_parm == 0)
1.1.1.4   root     3581:                {
                   3582:                  stack_parm
1.1.1.8 ! root     3583:                    = assign_stack_local (GET_MODE (entry_parm),
        !          3584:                                          size_stored, 0);
        !          3585: 
        !          3586:                  /* If this is a memory ref that contains aggregate
        !          3587:                     components, mark it as such for cse and loop optimize.  */
1.1.1.4   root     3588:                  MEM_IN_STRUCT_P (stack_parm) = aggregate;
                   3589:                }
                   3590: 
1.1       root     3591:              else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
                   3592:                abort ();
                   3593: 
1.1.1.7   root     3594:              if (TREE_READONLY (parm))
                   3595:                RTX_UNCHANGING_P (stack_parm) = 1;
                   3596: 
1.1       root     3597:              move_block_from_reg (REGNO (entry_parm),
                   3598:                                   validize_mem (stack_parm),
1.1.1.6   root     3599:                                   size_stored / UNITS_PER_WORD,
                   3600:                                   int_size_in_bytes (TREE_TYPE (parm)));
1.1       root     3601:            }
                   3602:          DECL_RTL (parm) = stack_parm;
                   3603:        }
1.1.1.4   root     3604:       else if (! ((obey_regdecls && ! DECL_REGISTER (parm)
                   3605:                   && ! DECL_INLINE (fndecl))
1.1       root     3606:                  /* layout_decl may set this.  */
                   3607:                  || TREE_ADDRESSABLE (parm)
                   3608:                  || TREE_SIDE_EFFECTS (parm)
                   3609:                  /* If -ffloat-store specified, don't put explicit
                   3610:                     float variables into registers.  */
                   3611:                  || (flag_float_store
                   3612:                      && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))
                   3613:               /* Always assign pseudo to structure return or item passed
                   3614:                  by invisible reference.  */
                   3615:               || passed_pointer || parm == function_result_decl)
                   3616:        {
1.1.1.4   root     3617:          /* Store the parm in a pseudoregister during the function, but we
                   3618:             may need to do it in a wider mode.  */
                   3619: 
                   3620:          register rtx parmreg;
1.1.1.7   root     3621:          int regno, regnoi, regnor;
1.1.1.4   root     3622: 
                   3623:          unsignedp = TREE_UNSIGNED (TREE_TYPE (parm));
1.1       root     3624: 
1.1.1.8 ! root     3625:          promoted_nominal_mode
        !          3626:            = promote_mode (TREE_TYPE (parm), nominal_mode, &unsignedp, 0);
        !          3627: 
        !          3628:          parmreg = gen_reg_rtx (promoted_nominal_mode);
1.1       root     3629:          REG_USERVAR_P (parmreg) = 1;
                   3630: 
                   3631:          /* If this was an item that we received a pointer to, set DECL_RTL
                   3632:             appropriately.  */
                   3633:          if (passed_pointer)
                   3634:            {
1.1.1.8 ! root     3635:              DECL_RTL (parm)
        !          3636:                = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
1.1       root     3637:              MEM_IN_STRUCT_P (DECL_RTL (parm)) = aggregate;
                   3638:            }
                   3639:          else
                   3640:            DECL_RTL (parm) = parmreg;
                   3641: 
                   3642:          /* Copy the value into the register.  */
1.1.1.8 ! root     3643:          if (nominal_mode != passed_mode
        !          3644:              || promoted_nominal_mode != promoted_mode)
1.1.1.2   root     3645:            {
1.1.1.8 ! root     3646:              /* ENTRY_PARM has been converted to PROMOTED_MODE, its
        !          3647:                 mode, by the caller.  We now have to convert it to 
        !          3648:                 NOMINAL_MODE, if different.  However, PARMREG may be in
        !          3649:                 a diffent mode than NOMINAL_MODE if it is being stored
        !          3650:                 promoted.
        !          3651: 
        !          3652:                 If ENTRY_PARM is a hard register, it might be in a register
1.1.1.2   root     3653:                 not valid for operating in its mode (e.g., an odd-numbered
                   3654:                 register for a DFmode).  In that case, moves are the only
                   3655:                 thing valid, so we can't do a convert from there.  This
                   3656:                 occurs when the calling sequence allow such misaligned
1.1.1.5   root     3657:                 usages.
                   3658: 
                   3659:                 In addition, the conversion may involve a call, which could
                   3660:                 clobber parameters which haven't been copied to pseudo
                   3661:                 registers yet.  Therefore, we must first copy the parm to
                   3662:                 a pseudo reg here, and save the conversion until after all
                   3663:                 parameters have been moved.  */
                   3664: 
                   3665:              rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
                   3666: 
                   3667:              emit_move_insn (tempreg, validize_mem (entry_parm));
                   3668: 
                   3669:              push_to_sequence (conversion_insns);
1.1.1.8 ! root     3670:              tempreg = convert_to_mode (nominal_mode, tempreg, unsignedp);
        !          3671: 
        !          3672:              expand_assignment (parm,
        !          3673:                                 make_tree (nominal_type, tempreg), 0, 0);
1.1.1.5   root     3674:              conversion_insns = get_insns ();
1.1.1.8 ! root     3675:              did_conversion = 1;
1.1.1.5   root     3676:              end_sequence ();
1.1.1.2   root     3677:            }
1.1       root     3678:          else
                   3679:            emit_move_insn (parmreg, validize_mem (entry_parm));
                   3680: 
1.1.1.4   root     3681:          /* If we were passed a pointer but the actual value
                   3682:             can safely live in a register, put it in one.  */
                   3683:          if (passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
                   3684:              && ! ((obey_regdecls && ! DECL_REGISTER (parm)
                   3685:                     && ! DECL_INLINE (fndecl))
                   3686:                    /* layout_decl may set this.  */
                   3687:                    || TREE_ADDRESSABLE (parm)
                   3688:                    || TREE_SIDE_EFFECTS (parm)
                   3689:                    /* If -ffloat-store specified, don't put explicit
                   3690:                       float variables into registers.  */
                   3691:                    || (flag_float_store
                   3692:                        && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)))
                   3693:            {
                   3694:              /* We can't use nominal_mode, because it will have been set to
                   3695:                 Pmode above.  We must use the actual mode of the parm.  */
                   3696:              parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
1.1.1.7   root     3697:              REG_USERVAR_P (parmreg) = 1;
1.1.1.4   root     3698:              emit_move_insn (parmreg, DECL_RTL (parm));
                   3699:              DECL_RTL (parm) = parmreg;
1.1.1.6   root     3700:              /* STACK_PARM is the pointer, not the parm, and PARMREG is
                   3701:                 now the parm.  */
                   3702:              stack_parm = 0;
1.1.1.4   root     3703:            }
1.1.1.5   root     3704: #ifdef FUNCTION_ARG_CALLEE_COPIES
                   3705:          /* If we are passed an arg by reference and it is our responsibility
                   3706:             to make a copy, do it now.
                   3707:             PASSED_TYPE and PASSED mode now refer to the pointer, not the
                   3708:             original argument, so we must recreate them in the call to
                   3709:             FUNCTION_ARG_CALLEE_COPIES.  */
                   3710:          /* ??? Later add code to handle the case that if the argument isn't
                   3711:             modified, don't do the copy.  */
                   3712: 
                   3713:          else if (passed_pointer
                   3714:                   && FUNCTION_ARG_CALLEE_COPIES (args_so_far,
                   3715:                                                  TYPE_MODE (DECL_ARG_TYPE (parm)),
                   3716:                                                  DECL_ARG_TYPE (parm),
1.1.1.8 ! root     3717:                                                  ! last_named)
        !          3718:                   && ! TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))
1.1.1.5   root     3719:            {
                   3720:              rtx copy;
                   3721:              tree type = DECL_ARG_TYPE (parm);
                   3722: 
                   3723:              /* This sequence may involve a library call perhaps clobbering
                   3724:                 registers that haven't been copied to pseudos yet.  */
                   3725: 
                   3726:              push_to_sequence (conversion_insns);
                   3727: 
                   3728:              if (TYPE_SIZE (type) == 0
                   3729:                  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1.1.1.7   root     3730:                /* This is a variable sized object.  */
                   3731:                copy = gen_rtx (MEM, BLKmode,
                   3732:                                allocate_dynamic_stack_space
                   3733:                                (expr_size (parm), NULL_RTX,
                   3734:                                 TYPE_ALIGN (type)));
1.1.1.5   root     3735:              else
1.1.1.7   root     3736:                copy = assign_stack_temp (TYPE_MODE (type),
                   3737:                                          int_size_in_bytes (type), 1);
1.1.1.8 ! root     3738:              MEM_IN_STRUCT_P (copy) = AGGREGATE_TYPE_P (type);
1.1.1.5   root     3739: 
                   3740:              store_expr (parm, copy, 0);
                   3741:              emit_move_insn (parmreg, XEXP (copy, 0));
                   3742:              conversion_insns = get_insns ();
1.1.1.8 ! root     3743:              did_conversion = 1;
1.1.1.5   root     3744:              end_sequence ();
                   3745:            }
                   3746: #endif /* FUNCTION_ARG_CALLEE_COPIES */
1.1.1.4   root     3747: 
1.1       root     3748:          /* In any case, record the parm's desired stack location
1.1.1.6   root     3749:             in case we later discover it must live in the stack. 
                   3750: 
                   3751:             If it is a COMPLEX value, store the stack location for both
                   3752:             halves.  */
                   3753: 
                   3754:          if (GET_CODE (parmreg) == CONCAT)
                   3755:            regno = MAX (REGNO (XEXP (parmreg, 0)), REGNO (XEXP (parmreg, 1)));
                   3756:          else
                   3757:            regno = REGNO (parmreg);
                   3758: 
                   3759:          if (regno >= nparmregs)
1.1       root     3760:            {
                   3761:              rtx *new;
1.1.1.6   root     3762:              int old_nparmregs = nparmregs;
                   3763: 
                   3764:              nparmregs = regno + 5;
1.1       root     3765:              new = (rtx *) oballoc (nparmregs * sizeof (rtx));
1.1.1.7   root     3766:              bcopy ((char *) parm_reg_stack_loc, (char *) new,
                   3767:                     old_nparmregs * sizeof (rtx));
                   3768:              bzero ((char *) (new + old_nparmregs),
1.1.1.6   root     3769:                     (nparmregs - old_nparmregs) * sizeof (rtx));
1.1       root     3770:              parm_reg_stack_loc = new;
                   3771:            }
1.1.1.6   root     3772: 
                   3773:          if (GET_CODE (parmreg) == CONCAT)
                   3774:            {
                   3775:              enum machine_mode submode = GET_MODE (XEXP (parmreg, 0));
                   3776: 
1.1.1.7   root     3777:              regnor = REGNO (gen_realpart (submode, parmreg));
                   3778:              regnoi = REGNO (gen_imagpart (submode, parmreg));
                   3779: 
1.1.1.6   root     3780:              if (stack_parm != 0)
                   3781:                {
1.1.1.7   root     3782:                  parm_reg_stack_loc[regnor]
                   3783:                    = gen_realpart (submode, stack_parm);
                   3784:                  parm_reg_stack_loc[regnoi]
                   3785:                    = gen_imagpart (submode, stack_parm);
1.1.1.6   root     3786:                }
                   3787:              else
                   3788:                {
1.1.1.7   root     3789:                  parm_reg_stack_loc[regnor] = 0;
                   3790:                  parm_reg_stack_loc[regnoi] = 0;
1.1.1.6   root     3791:                }
                   3792:            }
                   3793:          else
                   3794:            parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
1.1       root     3795: 
                   3796:          /* Mark the register as eliminable if we did no conversion
                   3797:             and it was copied from memory at a fixed offset,
                   3798:             and the arg pointer was not copied to a pseudo-reg.
                   3799:             If the arg pointer is a pseudo reg or the offset formed
                   3800:             an invalid address, such memory-equivalences
                   3801:             as we make here would screw up life analysis for it.  */
                   3802:          if (nominal_mode == passed_mode
1.1.1.8 ! root     3803:              && ! did_conversion
1.1       root     3804:              && GET_CODE (entry_parm) == MEM
1.1.1.3   root     3805:              && entry_parm == stack_parm
1.1       root     3806:              && stack_offset.var == 0
                   3807:              && reg_mentioned_p (virtual_incoming_args_rtx,
                   3808:                                  XEXP (entry_parm, 0)))
1.1.1.7   root     3809:            {
                   3810:              rtx linsn = get_last_insn ();
                   3811: 
                   3812:              /* Mark complex types separately.  */
                   3813:              if (GET_CODE (parmreg) == CONCAT)
                   3814:                {
                   3815:                  REG_NOTES (linsn)
                   3816:                      = gen_rtx (EXPR_LIST, REG_EQUIV,
                   3817:                                 parm_reg_stack_loc[regnoi], REG_NOTES (linsn));
                   3818: 
                   3819:                  /* Now search backward for where we set the real part.  */
                   3820:                  for (; linsn != 0
                   3821:                       && ! reg_referenced_p (parm_reg_stack_loc[regnor],
                   3822:                                              PATTERN (linsn));
                   3823:                       linsn = prev_nonnote_insn (linsn))
                   3824:                    ;
                   3825: 
                   3826:                  REG_NOTES (linsn)
                   3827:                      = gen_rtx (EXPR_LIST, REG_EQUIV,
                   3828:                                 parm_reg_stack_loc[regnor], REG_NOTES (linsn));
                   3829:                }
                   3830:              else
                   3831:                REG_NOTES (linsn)
                   3832:                 = gen_rtx (EXPR_LIST, REG_EQUIV,
                   3833:                            entry_parm, REG_NOTES (linsn));
                   3834:            }
1.1       root     3835: 
                   3836:          /* For pointer data type, suggest pointer register.  */
                   3837:          if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
                   3838:            mark_reg_pointer (parmreg);
                   3839:        }
                   3840:       else
                   3841:        {
                   3842:          /* Value must be stored in the stack slot STACK_PARM
                   3843:             during function execution.  */
                   3844: 
1.1.1.8 ! root     3845:          if (promoted_mode != nominal_mode)
1.1.1.2   root     3846:            {
                   3847:              /* Conversion is required.   */
1.1.1.5   root     3848:              rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
1.1.1.2   root     3849: 
1.1.1.5   root     3850:              emit_move_insn (tempreg, validize_mem (entry_parm));
                   3851: 
                   3852:              push_to_sequence (conversion_insns);
                   3853:              entry_parm = convert_to_mode (nominal_mode, tempreg,
1.1.1.4   root     3854:                                            TREE_UNSIGNED (TREE_TYPE (parm)));
1.1.1.5   root     3855:              conversion_insns = get_insns ();
1.1.1.8 ! root     3856:              did_conversion = 1;
1.1.1.5   root     3857:              end_sequence ();
1.1.1.2   root     3858:            }
1.1       root     3859: 
                   3860:          if (entry_parm != stack_parm)
                   3861:            {
                   3862:              if (stack_parm == 0)
1.1.1.4   root     3863:                {
                   3864:                  stack_parm
                   3865:                    = assign_stack_local (GET_MODE (entry_parm),
                   3866:                                          GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
                   3867:                  /* If this is a memory ref that contains aggregate components,
                   3868:                     mark it as such for cse and loop optimize.  */
                   3869:                  MEM_IN_STRUCT_P (stack_parm) = aggregate;
                   3870:                }
                   3871: 
1.1.1.8 ! root     3872:              if (promoted_mode != nominal_mode)
1.1.1.5   root     3873:                {
                   3874:                  push_to_sequence (conversion_insns);
                   3875:                  emit_move_insn (validize_mem (stack_parm),
                   3876:                                  validize_mem (entry_parm));
                   3877:                  conversion_insns = get_insns ();
                   3878:                  end_sequence ();
                   3879:                }
                   3880:              else
                   3881:                emit_move_insn (validize_mem (stack_parm),
                   3882:                                validize_mem (entry_parm));
1.1       root     3883:            }
                   3884: 
                   3885:          DECL_RTL (parm) = stack_parm;
                   3886:        }
                   3887:       
                   3888:       /* If this "parameter" was the place where we are receiving the
                   3889:         function's incoming structure pointer, set up the result.  */
                   3890:       if (parm == function_result_decl)
1.1.1.7   root     3891:        {
                   3892:          tree result = DECL_RESULT (fndecl);
                   3893:          tree restype = TREE_TYPE (result);
                   3894: 
                   3895:          DECL_RTL (result)
                   3896:            = gen_rtx (MEM, DECL_MODE (result), DECL_RTL (parm));
                   3897: 
                   3898:          MEM_IN_STRUCT_P (DECL_RTL (result)) = AGGREGATE_TYPE_P (restype);
                   3899:        }
1.1       root     3900: 
                   3901:       if (TREE_THIS_VOLATILE (parm))
                   3902:        MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
                   3903:       if (TREE_READONLY (parm))
                   3904:        RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
                   3905:     }
                   3906: 
1.1.1.5   root     3907:   /* Output all parameter conversion instructions (possibly including calls)
                   3908:      now that all parameters have been copied out of hard registers.  */
                   3909:   emit_insns (conversion_insns);
                   3910: 
1.1       root     3911:   max_parm_reg = max_reg_num ();
                   3912:   last_parm_insn = get_last_insn ();
                   3913: 
                   3914:   current_function_args_size = stack_args_size.constant;
                   3915: 
                   3916:   /* Adjust function incoming argument size for alignment and
                   3917:      minimum length.  */
                   3918: 
                   3919: #ifdef REG_PARM_STACK_SPACE
1.1.1.3   root     3920: #ifndef MAYBE_REG_PARM_STACK_SPACE
1.1       root     3921:   current_function_args_size = MAX (current_function_args_size,
                   3922:                                    REG_PARM_STACK_SPACE (fndecl));
                   3923: #endif
1.1.1.3   root     3924: #endif
1.1       root     3925: 
                   3926: #ifdef STACK_BOUNDARY
                   3927: #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
                   3928: 
                   3929:   current_function_args_size
                   3930:     = ((current_function_args_size + STACK_BYTES - 1)
                   3931:        / STACK_BYTES) * STACK_BYTES;
                   3932: #endif  
                   3933: 
                   3934: #ifdef ARGS_GROW_DOWNWARD
                   3935:   current_function_arg_offset_rtx
1.1.1.4   root     3936:     = (stack_args_size.var == 0 ? GEN_INT (-stack_args_size.constant)
1.1       root     3937:        : expand_expr (size_binop (MINUS_EXPR, stack_args_size.var,     
                   3938:                                  size_int (-stack_args_size.constant)),   
1.1.1.4   root     3939:                      NULL_RTX, VOIDmode, 0));
1.1       root     3940: #else
                   3941:   current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
                   3942: #endif
                   3943: 
                   3944:   /* See how many bytes, if any, of its args a function should try to pop
                   3945:      on return.  */
                   3946: 
1.1.1.8 ! root     3947:   current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl),
1.1       root     3948:                                                 current_function_args_size);
                   3949: 
1.1.1.7   root     3950:   /* For stdarg.h function, save info about
                   3951:      regs and stack space used by the named args.  */
1.1       root     3952: 
1.1.1.7   root     3953:   if (!hide_last_arg)
1.1       root     3954:     current_function_args_info = args_so_far;
                   3955: 
                   3956:   /* Set the rtx used for the function return value.  Put this in its
                   3957:      own variable so any optimizers that need this information don't have
                   3958:      to include tree.h.  Do this here so it gets done when an inlined
                   3959:      function gets output.  */
                   3960: 
                   3961:   current_function_return_rtx = DECL_RTL (DECL_RESULT (fndecl));
                   3962: }
                   3963: 
1.1.1.5   root     3964: /* Indicate whether REGNO is an incoming argument to the current function
                   3965:    that was promoted to a wider mode.  If so, return the RTX for the
                   3966:    register (to get its mode).  PMODE and PUNSIGNEDP are set to the mode
                   3967:    that REGNO is promoted from and whether the promotion was signed or
                   3968:    unsigned.  */
                   3969: 
                   3970: #ifdef PROMOTE_FUNCTION_ARGS
                   3971: 
                   3972: rtx
                   3973: promoted_input_arg (regno, pmode, punsignedp)
                   3974:      int regno;
                   3975:      enum machine_mode *pmode;
                   3976:      int *punsignedp;
                   3977: {
                   3978:   tree arg;
                   3979: 
                   3980:   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
                   3981:        arg = TREE_CHAIN (arg))
                   3982:     if (GET_CODE (DECL_INCOMING_RTL (arg)) == REG
1.1.1.8 ! root     3983:        && REGNO (DECL_INCOMING_RTL (arg)) == regno
        !          3984:        && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg)))
1.1.1.5   root     3985:       {
                   3986:        enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
                   3987:        int unsignedp = TREE_UNSIGNED (TREE_TYPE (arg));
                   3988: 
1.1.1.7   root     3989:        mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1);
1.1.1.5   root     3990:        if (mode == GET_MODE (DECL_INCOMING_RTL (arg))
                   3991:            && mode != DECL_MODE (arg))
                   3992:          {
                   3993:            *pmode = DECL_MODE (arg);
                   3994:            *punsignedp = unsignedp;
                   3995:            return DECL_INCOMING_RTL (arg);
                   3996:          }
                   3997:       }
                   3998: 
                   3999:   return 0;
                   4000: }
                   4001: 
                   4002: #endif
                   4003: 
1.1       root     4004: /* Compute the size and offset from the start of the stacked arguments for a
                   4005:    parm passed in mode PASSED_MODE and with type TYPE.
                   4006: 
                   4007:    INITIAL_OFFSET_PTR points to the current offset into the stacked
                   4008:    arguments.
                   4009: 
                   4010:    The starting offset and size for this parm are returned in *OFFSET_PTR
                   4011:    and *ARG_SIZE_PTR, respectively.
                   4012: 
                   4013:    IN_REGS is non-zero if the argument will be passed in registers.  It will
                   4014:    never be set if REG_PARM_STACK_SPACE is not defined.
                   4015: 
                   4016:    FNDECL is the function in which the argument was defined.
                   4017: 
                   4018:    There are two types of rounding that are done.  The first, controlled by
                   4019:    FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
                   4020:    list to be aligned to the specific boundary (in bits).  This rounding
                   4021:    affects the initial and starting offsets, but not the argument size.
                   4022: 
                   4023:    The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
                   4024:    optionally rounds the size of the parm to PARM_BOUNDARY.  The
                   4025:    initial offset is not affected by this rounding, while the size always
                   4026:    is and the starting offset may be.  */
                   4027: 
                   4028: /*  offset_ptr will be negative for ARGS_GROW_DOWNWARD case; 
                   4029:     initial_offset_ptr is positive because locate_and_pad_parm's
                   4030:     callers pass in the total size of args so far as
                   4031:     initial_offset_ptr. arg_size_ptr is always positive.*/
                   4032: 
                   4033: void
                   4034: locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
                   4035:                     initial_offset_ptr, offset_ptr, arg_size_ptr)
                   4036:      enum machine_mode passed_mode;
                   4037:      tree type;
                   4038:      int in_regs;
                   4039:      tree fndecl;
                   4040:      struct args_size *initial_offset_ptr;
                   4041:      struct args_size *offset_ptr;
                   4042:      struct args_size *arg_size_ptr;
                   4043: {
                   4044:   tree sizetree
                   4045:     = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
                   4046:   enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
                   4047:   int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
                   4048:   int boundary_in_bytes = boundary / BITS_PER_UNIT;
                   4049:   int reg_parm_stack_space = 0;
                   4050: 
                   4051: #ifdef REG_PARM_STACK_SPACE
                   4052:   /* If we have found a stack parm before we reach the end of the
                   4053:      area reserved for registers, skip that area.  */
                   4054:   if (! in_regs)
                   4055:     {
1.1.1.3   root     4056: #ifdef MAYBE_REG_PARM_STACK_SPACE
                   4057:       reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
                   4058: #else
1.1       root     4059:       reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
1.1.1.3   root     4060: #endif
1.1       root     4061:       if (reg_parm_stack_space > 0)
                   4062:        {
                   4063:          if (initial_offset_ptr->var)
                   4064:            {
                   4065:              initial_offset_ptr->var
                   4066:                = size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
                   4067:                              size_int (reg_parm_stack_space));
                   4068:              initial_offset_ptr->constant = 0;
                   4069:            }
                   4070:          else if (initial_offset_ptr->constant < reg_parm_stack_space)
                   4071:            initial_offset_ptr->constant = reg_parm_stack_space;
                   4072:        }
                   4073:     }
                   4074: #endif /* REG_PARM_STACK_SPACE */
                   4075: 
                   4076:   arg_size_ptr->var = 0;
                   4077:   arg_size_ptr->constant = 0;
                   4078: 
                   4079: #ifdef ARGS_GROW_DOWNWARD
                   4080:   if (initial_offset_ptr->var)
                   4081:     {
                   4082:       offset_ptr->constant = 0;
                   4083:       offset_ptr->var = size_binop (MINUS_EXPR, integer_zero_node,
                   4084:                                    initial_offset_ptr->var);
                   4085:     }
                   4086:   else
                   4087:     {
                   4088:       offset_ptr->constant = - initial_offset_ptr->constant;
                   4089:       offset_ptr->var = 0;
                   4090:     }
1.1.1.7   root     4091:   if (where_pad != none
1.1       root     4092:       && (TREE_CODE (sizetree) != INTEGER_CST
                   4093:          || ((TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)))
                   4094:     sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
                   4095:   SUB_PARM_SIZE (*offset_ptr, sizetree);
1.1.1.4   root     4096:   if (where_pad != downward)
                   4097:     pad_to_arg_alignment (offset_ptr, boundary);
1.1       root     4098:   if (initial_offset_ptr->var)
                   4099:     {
                   4100:       arg_size_ptr->var = size_binop (MINUS_EXPR,
                   4101:                                      size_binop (MINUS_EXPR,
                   4102:                                                  integer_zero_node,
                   4103:                                                  initial_offset_ptr->var),
                   4104:                                      offset_ptr->var);
                   4105:     }
                   4106:   else
                   4107:     {
                   4108:       arg_size_ptr->constant = (- initial_offset_ptr->constant -
                   4109:                                offset_ptr->constant); 
                   4110:     }
                   4111: #else /* !ARGS_GROW_DOWNWARD */
                   4112:   pad_to_arg_alignment (initial_offset_ptr, boundary);
                   4113:   *offset_ptr = *initial_offset_ptr;
                   4114: 
                   4115: #ifdef PUSH_ROUNDING
                   4116:   if (passed_mode != BLKmode)
                   4117:     sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
                   4118: #endif
                   4119: 
1.1.1.8 ! root     4120:   /* Pad_below needs the pre-rounded size to know how much to pad below
        !          4121:      so this must be done before rounding up.  */
        !          4122:   if (where_pad == downward
        !          4123:     /* However, BLKmode args passed in regs have their padding done elsewhere.
        !          4124:        The stack slot must be able to hold the entire register.  */
        !          4125:       && !(in_regs && passed_mode == BLKmode))
        !          4126:     pad_below (offset_ptr, passed_mode, sizetree);
        !          4127: 
1.1       root     4128:   if (where_pad != none
                   4129:       && (TREE_CODE (sizetree) != INTEGER_CST
                   4130:          || ((TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)))
                   4131:     sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
                   4132: 
                   4133:   ADD_PARM_SIZE (*arg_size_ptr, sizetree);
                   4134: #endif /* ARGS_GROW_DOWNWARD */
                   4135: }
                   4136: 
1.1.1.3   root     4137: /* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
                   4138:    BOUNDARY is measured in bits, but must be a multiple of a storage unit.  */
                   4139: 
1.1       root     4140: static void
                   4141: pad_to_arg_alignment (offset_ptr, boundary)
                   4142:      struct args_size *offset_ptr;
                   4143:      int boundary;
                   4144: {
                   4145:   int boundary_in_bytes = boundary / BITS_PER_UNIT;
                   4146:   
                   4147:   if (boundary > BITS_PER_UNIT)
                   4148:     {
                   4149:       if (offset_ptr->var)
                   4150:        {
                   4151:          offset_ptr->var  =
                   4152: #ifdef ARGS_GROW_DOWNWARD
                   4153:            round_down 
                   4154: #else
                   4155:            round_up
                   4156: #endif
                   4157:              (ARGS_SIZE_TREE (*offset_ptr),
                   4158:               boundary / BITS_PER_UNIT);
                   4159:          offset_ptr->constant = 0; /*?*/
                   4160:        }
                   4161:       else
                   4162:        offset_ptr->constant =
                   4163: #ifdef ARGS_GROW_DOWNWARD
                   4164:          FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
                   4165: #else
                   4166:          CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
                   4167: #endif
                   4168:     }
                   4169: }
                   4170: 
                   4171: static void
                   4172: pad_below (offset_ptr, passed_mode, sizetree)
                   4173:      struct args_size *offset_ptr;
                   4174:      enum machine_mode passed_mode;
                   4175:      tree sizetree;
                   4176: {
                   4177:   if (passed_mode != BLKmode)
                   4178:     {
                   4179:       if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
                   4180:        offset_ptr->constant
                   4181:          += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
                   4182:               / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
                   4183:              - GET_MODE_SIZE (passed_mode));
                   4184:     }
                   4185:   else
                   4186:     {
                   4187:       if (TREE_CODE (sizetree) != INTEGER_CST
                   4188:          || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
                   4189:        {
                   4190:          /* Round the size up to multiple of PARM_BOUNDARY bits.  */
                   4191:          tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
                   4192:          /* Add it in.  */
                   4193:          ADD_PARM_SIZE (*offset_ptr, s2);
                   4194:          SUB_PARM_SIZE (*offset_ptr, sizetree);
                   4195:        }
                   4196:     }
                   4197: }
                   4198: 
                   4199: static tree
                   4200: round_down (value, divisor)
                   4201:      tree value;
                   4202:      int divisor;
                   4203: {
                   4204:   return size_binop (MULT_EXPR,
                   4205:                     size_binop (FLOOR_DIV_EXPR, value, size_int (divisor)),
                   4206:                     size_int (divisor));
                   4207: }
                   4208: 
                   4209: /* Walk the tree of blocks describing the binding levels within a function
                   4210:    and warn about uninitialized variables.
                   4211:    This is done after calling flow_analysis and before global_alloc
                   4212:    clobbers the pseudo-regs to hard regs.  */
                   4213: 
                   4214: void
                   4215: uninitialized_vars_warning (block)
                   4216:      tree block;
                   4217: {
                   4218:   register tree decl, sub;
                   4219:   for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
                   4220:     {
                   4221:       if (TREE_CODE (decl) == VAR_DECL
                   4222:          /* These warnings are unreliable for and aggregates
                   4223:             because assigning the fields one by one can fail to convince
                   4224:             flow.c that the entire aggregate was initialized.
                   4225:             Unions are troublesome because members may be shorter.  */
1.1.1.7   root     4226:          && ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
1.1       root     4227:          && DECL_RTL (decl) != 0
                   4228:          && GET_CODE (DECL_RTL (decl)) == REG
                   4229:          && regno_uninitialized (REGNO (DECL_RTL (decl))))
                   4230:        warning_with_decl (decl,
1.1.1.7   root     4231:                           "`%s' might be used uninitialized in this function");
1.1       root     4232:       if (TREE_CODE (decl) == VAR_DECL
                   4233:          && DECL_RTL (decl) != 0
                   4234:          && GET_CODE (DECL_RTL (decl)) == REG
                   4235:          && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
                   4236:        warning_with_decl (decl,
1.1.1.7   root     4237:                           "variable `%s' might be clobbered by `longjmp' or `vfork'");
1.1       root     4238:     }
                   4239:   for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
                   4240:     uninitialized_vars_warning (sub);
                   4241: }
                   4242: 
                   4243: /* Do the appropriate part of uninitialized_vars_warning
                   4244:    but for arguments instead of local variables.  */
                   4245: 
                   4246: void
1.1.1.8 ! root     4247: setjmp_args_warning ()
1.1       root     4248: {
                   4249:   register tree decl;
                   4250:   for (decl = DECL_ARGUMENTS (current_function_decl);
                   4251:        decl; decl = TREE_CHAIN (decl))
                   4252:     if (DECL_RTL (decl) != 0
                   4253:        && GET_CODE (DECL_RTL (decl)) == REG
                   4254:        && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
1.1.1.7   root     4255:       warning_with_decl (decl, "argument `%s' might be clobbered by `longjmp' or `vfork'");
1.1       root     4256: }
                   4257: 
                   4258: /* If this function call setjmp, put all vars into the stack
                   4259:    unless they were declared `register'.  */
                   4260: 
                   4261: void
                   4262: setjmp_protect (block)
                   4263:      tree block;
                   4264: {
                   4265:   register tree decl, sub;
                   4266:   for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
                   4267:     if ((TREE_CODE (decl) == VAR_DECL
                   4268:         || TREE_CODE (decl) == PARM_DECL)
                   4269:        && DECL_RTL (decl) != 0
                   4270:        && GET_CODE (DECL_RTL (decl)) == REG
1.1.1.2   root     4271:        /* If this variable came from an inline function, it must be
                   4272:           that it's life doesn't overlap the setjmp.  If there was a
                   4273:           setjmp in the function, it would already be in memory.  We
                   4274:           must exclude such variable because their DECL_RTL might be
                   4275:           set to strange things such as virtual_stack_vars_rtx.  */
                   4276:        && ! DECL_FROM_INLINE (decl)
1.1       root     4277:        && (
                   4278: #ifdef NON_SAVING_SETJMP
                   4279:            /* If longjmp doesn't restore the registers,
                   4280:               don't put anything in them.  */
                   4281:            NON_SAVING_SETJMP
                   4282:            ||
                   4283: #endif
1.1.1.4   root     4284:            ! DECL_REGISTER (decl)))
1.1       root     4285:       put_var_into_stack (decl);
                   4286:   for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
                   4287:     setjmp_protect (sub);
                   4288: }
                   4289: 
                   4290: /* Like the previous function, but for args instead of local variables.  */
                   4291: 
                   4292: void
                   4293: setjmp_protect_args ()
                   4294: {
                   4295:   register tree decl, sub;
                   4296:   for (decl = DECL_ARGUMENTS (current_function_decl);
                   4297:        decl; decl = TREE_CHAIN (decl))
                   4298:     if ((TREE_CODE (decl) == VAR_DECL
                   4299:         || TREE_CODE (decl) == PARM_DECL)
                   4300:        && DECL_RTL (decl) != 0
                   4301:        && GET_CODE (DECL_RTL (decl)) == REG
                   4302:        && (
                   4303:            /* If longjmp doesn't restore the registers,
                   4304:               don't put anything in them.  */
                   4305: #ifdef NON_SAVING_SETJMP
                   4306:            NON_SAVING_SETJMP
                   4307:            ||
                   4308: #endif
1.1.1.4   root     4309:            ! DECL_REGISTER (decl)))
1.1       root     4310:       put_var_into_stack (decl);
                   4311: }
                   4312: 
                   4313: /* Return the context-pointer register corresponding to DECL,
                   4314:    or 0 if it does not need one.  */
                   4315: 
                   4316: rtx
                   4317: lookup_static_chain (decl)
                   4318:      tree decl;
                   4319: {
                   4320:   tree context = decl_function_context (decl);
                   4321:   tree link;
                   4322: 
                   4323:   if (context == 0)
                   4324:     return 0;
                   4325:   
                   4326:   /* We treat inline_function_decl as an alias for the current function
                   4327:      because that is the inline function whose vars, types, etc.
                   4328:      are being merged into the current function.
                   4329:      See expand_inline_function.  */
                   4330:   if (context == current_function_decl || context == inline_function_decl)
                   4331:     return virtual_stack_vars_rtx;
                   4332: 
                   4333:   for (link = context_display; link; link = TREE_CHAIN (link))
                   4334:     if (TREE_PURPOSE (link) == context)
                   4335:       return RTL_EXPR_RTL (TREE_VALUE (link));
                   4336: 
                   4337:   abort ();
                   4338: }
                   4339: 
                   4340: /* Convert a stack slot address ADDR for variable VAR
                   4341:    (from a containing function)
                   4342:    into an address valid in this function (using a static chain).  */
                   4343: 
                   4344: rtx
                   4345: fix_lexical_addr (addr, var)
                   4346:      rtx addr;
                   4347:      tree var;
                   4348: {
                   4349:   rtx basereg;
                   4350:   int displacement;
                   4351:   tree context = decl_function_context (var);
                   4352:   struct function *fp;
                   4353:   rtx base = 0;
                   4354: 
                   4355:   /* If this is the present function, we need not do anything.  */
                   4356:   if (context == current_function_decl || context == inline_function_decl)
                   4357:     return addr;
                   4358: 
                   4359:   for (fp = outer_function_chain; fp; fp = fp->next)
                   4360:     if (fp->decl == context)
                   4361:       break;
                   4362: 
                   4363:   if (fp == 0)
                   4364:     abort ();
                   4365: 
                   4366:   /* Decode given address as base reg plus displacement.  */
                   4367:   if (GET_CODE (addr) == REG)
                   4368:     basereg = addr, displacement = 0;
                   4369:   else if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
                   4370:     basereg = XEXP (addr, 0), displacement = INTVAL (XEXP (addr, 1));
                   4371:   else
                   4372:     abort ();
                   4373: 
                   4374:   /* We accept vars reached via the containing function's
                   4375:      incoming arg pointer and via its stack variables pointer.  */
                   4376:   if (basereg == fp->internal_arg_pointer)
                   4377:     {
                   4378:       /* If reached via arg pointer, get the arg pointer value
                   4379:         out of that function's stack frame.
                   4380: 
                   4381:         There are two cases:  If a separate ap is needed, allocate a
                   4382:         slot in the outer function for it and dereference it that way.
                   4383:         This is correct even if the real ap is actually a pseudo.
                   4384:         Otherwise, just adjust the offset from the frame pointer to
                   4385:         compensate.  */
                   4386: 
                   4387: #ifdef NEED_SEPARATE_AP
                   4388:       rtx addr;
                   4389: 
                   4390:       if (fp->arg_pointer_save_area == 0)
                   4391:        fp->arg_pointer_save_area
                   4392:          = assign_outer_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0, fp);
                   4393: 
                   4394:       addr = fix_lexical_addr (XEXP (fp->arg_pointer_save_area, 0), var);
                   4395:       addr = memory_address (Pmode, addr);
                   4396: 
                   4397:       base = copy_to_reg (gen_rtx (MEM, Pmode, addr));
                   4398: #else
                   4399:       displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
1.1.1.2   root     4400:       base = lookup_static_chain (var);
1.1       root     4401: #endif
                   4402:     }
                   4403: 
                   4404:   else if (basereg == virtual_stack_vars_rtx)
                   4405:     {
                   4406:       /* This is the same code as lookup_static_chain, duplicated here to
                   4407:         avoid an extra call to decl_function_context.  */
                   4408:       tree link;
                   4409: 
                   4410:       for (link = context_display; link; link = TREE_CHAIN (link))
                   4411:        if (TREE_PURPOSE (link) == context)
                   4412:          {
                   4413:            base = RTL_EXPR_RTL (TREE_VALUE (link));
                   4414:            break;
                   4415:          }
                   4416:     }
                   4417: 
                   4418:   if (base == 0)
                   4419:     abort ();
                   4420: 
                   4421:   /* Use same offset, relative to appropriate static chain or argument
                   4422:      pointer.  */
                   4423:   return plus_constant (base, displacement);
                   4424: }
                   4425: 
                   4426: /* Return the address of the trampoline for entering nested fn FUNCTION.
                   4427:    If necessary, allocate a trampoline (in the stack frame)
                   4428:    and emit rtl to initialize its contents (at entry to this function).  */
                   4429: 
                   4430: rtx
                   4431: trampoline_address (function)
                   4432:      tree function;
                   4433: {
                   4434:   tree link;
                   4435:   tree rtlexp;
                   4436:   rtx tramp;
                   4437:   struct function *fp;
                   4438:   tree fn_context;
                   4439: 
                   4440:   /* Find an existing trampoline and return it.  */
                   4441:   for (link = trampoline_list; link; link = TREE_CHAIN (link))
                   4442:     if (TREE_PURPOSE (link) == function)
1.1.1.7   root     4443:       return
                   4444:        round_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));
                   4445: 
1.1       root     4446:   for (fp = outer_function_chain; fp; fp = fp->next)
                   4447:     for (link = fp->trampoline_list; link; link = TREE_CHAIN (link))
                   4448:       if (TREE_PURPOSE (link) == function)
                   4449:        {
                   4450:          tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
                   4451:                                    function);
                   4452:          return round_trampoline_addr (tramp);
                   4453:        }
                   4454: 
                   4455:   /* None exists; we must make one.  */
                   4456: 
                   4457:   /* Find the `struct function' for the function containing FUNCTION.  */
                   4458:   fp = 0;
                   4459:   fn_context = decl_function_context (function);
                   4460:   if (fn_context != current_function_decl)
                   4461:     for (fp = outer_function_chain; fp; fp = fp->next)
                   4462:       if (fp->decl == fn_context)
                   4463:        break;
                   4464: 
                   4465:   /* Allocate run-time space for this trampoline
                   4466:      (usually in the defining function's stack frame).  */
                   4467: #ifdef ALLOCATE_TRAMPOLINE
                   4468:   tramp = ALLOCATE_TRAMPOLINE (fp);
                   4469: #else
                   4470:   /* If rounding needed, allocate extra space
                   4471:      to ensure we have TRAMPOLINE_SIZE bytes left after rounding up.  */
                   4472: #ifdef TRAMPOLINE_ALIGNMENT
                   4473: #define TRAMPOLINE_REAL_SIZE (TRAMPOLINE_SIZE + TRAMPOLINE_ALIGNMENT - 1)
                   4474: #else
                   4475: #define TRAMPOLINE_REAL_SIZE (TRAMPOLINE_SIZE)
                   4476: #endif
                   4477:   if (fp != 0)
                   4478:     tramp = assign_outer_stack_local (BLKmode, TRAMPOLINE_REAL_SIZE, 0, fp);
                   4479:   else
                   4480:     tramp = assign_stack_local (BLKmode, TRAMPOLINE_REAL_SIZE, 0);
                   4481: #endif
                   4482: 
                   4483:   /* Record the trampoline for reuse and note it for later initialization
                   4484:      by expand_function_end.  */
                   4485:   if (fp != 0)
                   4486:     {
1.1.1.6   root     4487:       push_obstacks (fp->function_maybepermanent_obstack,
                   4488:                     fp->function_maybepermanent_obstack);
1.1       root     4489:       rtlexp = make_node (RTL_EXPR);
                   4490:       RTL_EXPR_RTL (rtlexp) = tramp;
                   4491:       fp->trampoline_list = tree_cons (function, rtlexp, fp->trampoline_list);
                   4492:       pop_obstacks ();
                   4493:     }
                   4494:   else
                   4495:     {
                   4496:       /* Make the RTL_EXPR node temporary, not momentary, so that the
                   4497:         trampoline_list doesn't become garbage.  */
                   4498:       int momentary = suspend_momentary ();
                   4499:       rtlexp = make_node (RTL_EXPR);
                   4500:       resume_momentary (momentary);
                   4501: 
                   4502:       RTL_EXPR_RTL (rtlexp) = tramp;
                   4503:       trampoline_list = tree_cons (function, rtlexp, trampoline_list);
                   4504:     }
                   4505: 
                   4506:   tramp = fix_lexical_addr (XEXP (tramp, 0), function);
                   4507:   return round_trampoline_addr (tramp);
                   4508: }
                   4509: 
                   4510: /* Given a trampoline address,
                   4511:    round it to multiple of TRAMPOLINE_ALIGNMENT.  */
                   4512: 
                   4513: static rtx
                   4514: round_trampoline_addr (tramp)
                   4515:      rtx tramp;
                   4516: {
                   4517: #ifdef TRAMPOLINE_ALIGNMENT
                   4518:   /* Round address up to desired boundary.  */
                   4519:   rtx temp = gen_reg_rtx (Pmode);
                   4520:   temp = expand_binop (Pmode, add_optab, tramp,
1.1.1.4   root     4521:                       GEN_INT (TRAMPOLINE_ALIGNMENT - 1),
1.1       root     4522:                       temp, 0, OPTAB_LIB_WIDEN);
                   4523:   tramp = expand_binop (Pmode, and_optab, temp,
1.1.1.4   root     4524:                        GEN_INT (- TRAMPOLINE_ALIGNMENT),
1.1       root     4525:                        temp, 0, OPTAB_LIB_WIDEN);
                   4526: #endif
                   4527:   return tramp;
                   4528: }
                   4529: 
1.1.1.4   root     4530: /* The functions identify_blocks and reorder_blocks provide a way to
                   4531:    reorder the tree of BLOCK nodes, for optimizers that reshuffle or
                   4532:    duplicate portions of the RTL code.  Call identify_blocks before
                   4533:    changing the RTL, and call reorder_blocks after.  */
                   4534: 
                   4535: /* Put all this function's BLOCK nodes into a vector, and return it.
                   4536:    Also store in each NOTE for the beginning or end of a block
                   4537:    the index of that block in the vector.
                   4538:    The arguments are TOP_BLOCK, the top-level block of the function,
                   4539:    and INSNS, the insn chain of the function.  */
                   4540: 
                   4541: tree *
                   4542: identify_blocks (top_block, insns)
                   4543:      tree top_block;
                   4544:      rtx insns;
                   4545: {
                   4546:   int n_blocks;
                   4547:   tree *block_vector;
                   4548:   int *block_stack;
                   4549:   int depth = 0;
                   4550:   int next_block_number = 0;
                   4551:   int current_block_number = 0;
                   4552:   rtx insn;
                   4553: 
                   4554:   if (top_block == 0)
                   4555:     return 0;
                   4556: 
                   4557:   n_blocks = all_blocks (top_block, 0);
                   4558:   block_vector = (tree *) xmalloc (n_blocks * sizeof (tree));
                   4559:   block_stack = (int *) alloca (n_blocks * sizeof (int));
                   4560: 
                   4561:   all_blocks (top_block, block_vector);
                   4562: 
                   4563:   for (insn = insns; insn; insn = NEXT_INSN (insn))
                   4564:     if (GET_CODE (insn) == NOTE)
                   4565:       {
                   4566:        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
                   4567:          {
                   4568:            block_stack[depth++] = current_block_number;
                   4569:            current_block_number = next_block_number;
                   4570:            NOTE_BLOCK_NUMBER (insn) =  next_block_number++;
                   4571:          }
                   4572:        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
                   4573:          {
                   4574:            current_block_number = block_stack[--depth];
                   4575:            NOTE_BLOCK_NUMBER (insn) = current_block_number;
                   4576:          }
                   4577:       }
                   4578: 
                   4579:   return block_vector;
                   4580: }
                   4581: 
                   4582: /* Given BLOCK_VECTOR which was returned by identify_blocks,
                   4583:    and a revised instruction chain, rebuild the tree structure
                   4584:    of BLOCK nodes to correspond to the new order of RTL.
                   4585:    The new block tree is inserted below TOP_BLOCK.
                   4586:    Returns the current top-level block.  */
                   4587: 
                   4588: tree
                   4589: reorder_blocks (block_vector, top_block, insns)
                   4590:      tree *block_vector;
                   4591:      tree top_block;
                   4592:      rtx insns;
                   4593: {
                   4594:   tree current_block = top_block;
                   4595:   rtx insn;
                   4596: 
                   4597:   if (block_vector == 0)
                   4598:     return top_block;
                   4599: 
                   4600:   /* Prune the old tree away, so that it doesn't get in the way.  */
                   4601:   BLOCK_SUBBLOCKS (current_block) = 0;
                   4602: 
                   4603:   for (insn = insns; insn; insn = NEXT_INSN (insn))
                   4604:     if (GET_CODE (insn) == NOTE)
                   4605:       {
                   4606:        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG)
                   4607:          {
                   4608:            tree block = block_vector[NOTE_BLOCK_NUMBER (insn)];
                   4609:            /* If we have seen this block before, copy it.  */
                   4610:            if (TREE_ASM_WRITTEN (block))
                   4611:              block = copy_node (block);
                   4612:            BLOCK_SUBBLOCKS (block) = 0;
                   4613:            TREE_ASM_WRITTEN (block) = 1;
                   4614:            BLOCK_SUPERCONTEXT (block) = current_block; 
                   4615:            BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
                   4616:            BLOCK_SUBBLOCKS (current_block) = block;
                   4617:            current_block = block;
                   4618:            NOTE_SOURCE_FILE (insn) = 0;
                   4619:          }
                   4620:        if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
                   4621:          {
                   4622:            BLOCK_SUBBLOCKS (current_block)
                   4623:              = blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
                   4624:            current_block = BLOCK_SUPERCONTEXT (current_block);
                   4625:            NOTE_SOURCE_FILE (insn) = 0;
                   4626:          }
                   4627:       }
                   4628: 
                   4629:   return current_block;
                   4630: }
                   4631: 
                   4632: /* Reverse the order of elements in the chain T of blocks,
                   4633:    and return the new head of the chain (old last element).  */
                   4634: 
                   4635: static tree
                   4636: blocks_nreverse (t)
                   4637:      tree t;
                   4638: {
                   4639:   register tree prev = 0, decl, next;
                   4640:   for (decl = t; decl; decl = next)
                   4641:     {
                   4642:       next = BLOCK_CHAIN (decl);
                   4643:       BLOCK_CHAIN (decl) = prev;
                   4644:       prev = decl;
                   4645:     }
                   4646:   return prev;
                   4647: }
                   4648: 
                   4649: /* Count the subblocks of BLOCK, and list them all into the vector VECTOR.
                   4650:    Also clear TREE_ASM_WRITTEN in all blocks.  */
                   4651: 
                   4652: static int
                   4653: all_blocks (block, vector)
                   4654:      tree block;
                   4655:      tree *vector;
                   4656: {
                   4657:   int n_blocks = 1;
                   4658:   tree subblocks; 
                   4659: 
                   4660:   TREE_ASM_WRITTEN (block) = 0;
                   4661:   /* Record this block.  */
                   4662:   if (vector)
                   4663:     vector[0] = block;
                   4664: 
                   4665:   /* Record the subblocks, and their subblocks.  */
                   4666:   for (subblocks = BLOCK_SUBBLOCKS (block);
                   4667:        subblocks; subblocks = BLOCK_CHAIN (subblocks))
                   4668:     n_blocks += all_blocks (subblocks, vector ? vector + n_blocks : 0);
                   4669: 
                   4670:   return n_blocks;
                   4671: }
                   4672: 
1.1.1.6   root     4673: /* Build bytecode call descriptor for function SUBR. */
1.1.1.7   root     4674: 
1.1.1.6   root     4675: rtx
                   4676: bc_build_calldesc (subr)
                   4677:   tree subr;
                   4678: {
                   4679:   tree calldesc = 0, arg;
                   4680:   int nargs = 0;
                   4681: 
                   4682:   /* Build the argument description vector in reverse order.  */
                   4683:   DECL_ARGUMENTS (subr) = nreverse (DECL_ARGUMENTS (subr));
                   4684:   nargs = 0;
                   4685: 
                   4686:   for (arg = DECL_ARGUMENTS (subr); arg; arg = TREE_CHAIN (arg))
                   4687:     {
                   4688:       ++nargs;
                   4689: 
                   4690:       calldesc = tree_cons ((tree) 0, size_in_bytes (TREE_TYPE (arg)), calldesc);
                   4691:       calldesc = tree_cons ((tree) 0, bc_runtime_type_code (TREE_TYPE (arg)), calldesc);
                   4692:     }
                   4693: 
                   4694:   DECL_ARGUMENTS (subr) = nreverse (DECL_ARGUMENTS (subr));
                   4695: 
                   4696:   /* Prepend the function's return type.  */
                   4697:   calldesc = tree_cons ((tree) 0,
                   4698:                        size_in_bytes (TREE_TYPE (TREE_TYPE (subr))),
                   4699:                        calldesc);
                   4700: 
                   4701:   calldesc = tree_cons ((tree) 0,
                   4702:                        bc_runtime_type_code (TREE_TYPE (TREE_TYPE (subr))),
                   4703:                        calldesc);
                   4704: 
                   4705:   /* Prepend the arg count.  */
                   4706:   calldesc = tree_cons ((tree) 0, build_int_2 (nargs, 0), calldesc);
                   4707: 
                   4708:   /* Output the call description vector and get its address.  */
                   4709:   calldesc = build_nt (CONSTRUCTOR, (tree) 0, calldesc);
                   4710:   TREE_TYPE (calldesc) = build_array_type (integer_type_node,
                   4711:                                           build_index_type (build_int_2 (nargs * 2, 0)));
                   4712: 
                   4713:   return output_constant_def (calldesc);
                   4714: }
                   4715: 
                   4716: 
1.1       root     4717: /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
                   4718:    and initialize static variables for generating RTL for the statements
                   4719:    of the function.  */
                   4720: 
                   4721: void
                   4722: init_function_start (subr, filename, line)
                   4723:      tree subr;
                   4724:      char *filename;
                   4725:      int line;
                   4726: {
                   4727:   char *junk;
                   4728: 
1.1.1.6   root     4729:   if (output_bytecode)
                   4730:     {
                   4731:       this_function_decl = subr;
                   4732:       this_function_calldesc = bc_build_calldesc (subr);
                   4733:       local_vars_size = 0;
                   4734:       stack_depth = 0;
                   4735:       max_stack_depth = 0;
                   4736:       stmt_expr_depth = 0;
                   4737:       return;
                   4738:     }
                   4739: 
1.1       root     4740:   init_stmt_for_function ();
                   4741: 
                   4742:   cse_not_expected = ! optimize;
                   4743: 
                   4744:   /* Caller save not needed yet.  */
                   4745:   caller_save_needed = 0;
                   4746: 
                   4747:   /* No stack slots have been made yet.  */
                   4748:   stack_slot_list = 0;
                   4749: 
                   4750:   /* There is no stack slot for handling nonlocal gotos.  */
                   4751:   nonlocal_goto_handler_slot = 0;
                   4752:   nonlocal_goto_stack_level = 0;
                   4753: 
                   4754:   /* No labels have been declared for nonlocal use.  */
                   4755:   nonlocal_labels = 0;
                   4756: 
                   4757:   /* No function calls so far in this function.  */
                   4758:   function_call_count = 0;
                   4759: 
                   4760:   /* No parm regs have been allocated.
                   4761:      (This is important for output_inline_function.)  */
                   4762:   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
                   4763: 
                   4764:   /* Initialize the RTL mechanism.  */
                   4765:   init_emit ();
                   4766: 
                   4767:   /* Initialize the queue of pending postincrement and postdecrements,
                   4768:      and some other info in expr.c.  */
                   4769:   init_expr ();
                   4770: 
                   4771:   /* We haven't done register allocation yet.  */
                   4772:   reg_renumber = 0;
                   4773: 
                   4774:   init_const_rtx_hash_table ();
                   4775: 
                   4776:   current_function_name = (*decl_printable_name) (subr, &junk);
                   4777: 
                   4778:   /* Nonzero if this is a nested function that uses a static chain.  */
                   4779: 
                   4780:   current_function_needs_context
                   4781:     = (decl_function_context (current_function_decl) != 0);
                   4782: 
                   4783:   /* Set if a call to setjmp is seen.  */
                   4784:   current_function_calls_setjmp = 0;
                   4785: 
                   4786:   /* Set if a call to longjmp is seen.  */
                   4787:   current_function_calls_longjmp = 0;
                   4788: 
                   4789:   current_function_calls_alloca = 0;
                   4790:   current_function_has_nonlocal_label = 0;
1.1.1.6   root     4791:   current_function_has_nonlocal_goto = 0;
1.1       root     4792:   current_function_contains_functions = 0;
                   4793: 
                   4794:   current_function_returns_pcc_struct = 0;
                   4795:   current_function_returns_struct = 0;
                   4796:   current_function_epilogue_delay_list = 0;
                   4797:   current_function_uses_const_pool = 0;
                   4798:   current_function_uses_pic_offset_table = 0;
                   4799: 
                   4800:   /* We have not yet needed to make a label to jump to for tail-recursion.  */
                   4801:   tail_recursion_label = 0;
                   4802: 
                   4803:   /* We haven't had a need to make a save area for ap yet.  */
                   4804: 
                   4805:   arg_pointer_save_area = 0;
                   4806: 
                   4807:   /* No stack slots allocated yet.  */
                   4808:   frame_offset = 0;
                   4809: 
                   4810:   /* No SAVE_EXPRs in this function yet.  */
                   4811:   save_expr_regs = 0;
                   4812: 
                   4813:   /* No RTL_EXPRs in this function yet.  */
                   4814:   rtl_expr_chain = 0;
                   4815: 
                   4816:   /* We have not allocated any temporaries yet.  */
                   4817:   temp_slots = 0;
                   4818:   temp_slot_level = 0;
1.1.1.7   root     4819:   target_temp_slot_level = 0;
1.1       root     4820: 
                   4821:   /* Within function body, compute a type's size as soon it is laid out.  */
                   4822:   immediate_size_expand++;
                   4823: 
1.1.1.6   root     4824:   /* We haven't made any trampolines for this function yet.  */
                   4825:   trampoline_list = 0;
                   4826: 
1.1       root     4827:   init_pending_stack_adjust ();
                   4828:   inhibit_defer_pop = 0;
                   4829: 
                   4830:   current_function_outgoing_args_size = 0;
                   4831: 
                   4832:   /* Prevent ever trying to delete the first instruction of a function.
                   4833:      Also tell final how to output a linenum before the function prologue.  */
                   4834:   emit_line_note (filename, line);
                   4835: 
                   4836:   /* Make sure first insn is a note even if we don't want linenums.
                   4837:      This makes sure the first insn will never be deleted.
                   4838:      Also, final expects a note to appear there.  */
1.1.1.4   root     4839:   emit_note (NULL_PTR, NOTE_INSN_DELETED);
1.1       root     4840: 
                   4841:   /* Set flags used by final.c.  */
                   4842:   if (aggregate_value_p (DECL_RESULT (subr)))
                   4843:     {
                   4844: #ifdef PCC_STATIC_STRUCT_RETURN
1.1.1.5   root     4845:       current_function_returns_pcc_struct = 1;
1.1       root     4846: #endif
1.1.1.5   root     4847:       current_function_returns_struct = 1;
1.1       root     4848:     }
                   4849: 
                   4850:   /* Warn if this value is an aggregate type,
                   4851:      regardless of which calling convention we are using for it.  */
                   4852:   if (warn_aggregate_return
1.1.1.7   root     4853:       && AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
1.1       root     4854:     warning ("function returns an aggregate");
                   4855: 
                   4856:   current_function_returns_pointer
1.1.1.8 ! root     4857:     = POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
1.1       root     4858: 
                   4859:   /* Indicate that we need to distinguish between the return value of the
                   4860:      present function and the return value of a function being called.  */
                   4861:   rtx_equal_function_value_matters = 1;
                   4862: 
                   4863:   /* Indicate that we have not instantiated virtual registers yet.  */
                   4864:   virtuals_instantiated = 0;
                   4865: 
                   4866:   /* Indicate we have no need of a frame pointer yet.  */
                   4867:   frame_pointer_needed = 0;
                   4868: 
1.1.1.8 ! root     4869:   /* By default assume not varargs or stdarg.  */
1.1       root     4870:   current_function_varargs = 0;
1.1.1.8 ! root     4871:   current_function_stdarg = 0;
1.1       root     4872: }
                   4873: 
                   4874: /* Indicate that the current function uses extra args
                   4875:    not explicitly mentioned in the argument list in any fashion.  */
                   4876: 
                   4877: void
                   4878: mark_varargs ()
                   4879: {
                   4880:   current_function_varargs = 1;
                   4881: }
                   4882: 
                   4883: /* Expand a call to __main at the beginning of a possible main function.  */
                   4884: 
1.1.1.7   root     4885: #if defined(INIT_SECTION_ASM_OP) && !defined(INVOKE__main)
                   4886: #undef HAS_INIT_SECTION
                   4887: #define HAS_INIT_SECTION
                   4888: #endif
                   4889: 
1.1       root     4890: void
                   4891: expand_main_function ()
                   4892: {
1.1.1.6   root     4893:   if (!output_bytecode)
                   4894:     {
                   4895:       /* The zero below avoids a possible parse error */
                   4896:       0;
1.1.1.7   root     4897: #if !defined (HAS_INIT_SECTION)
1.1.1.6   root     4898:       emit_library_call (gen_rtx (SYMBOL_REF, Pmode, NAME__MAIN), 0,
                   4899:                         VOIDmode, 0);
1.1.1.7   root     4900: #endif /* not HAS_INIT_SECTION */
1.1.1.6   root     4901:     }
1.1       root     4902: }
                   4903: 
1.1.1.6   root     4904: extern struct obstack permanent_obstack;
                   4905: 
                   4906: /* Expand start of bytecode function. See comment at
                   4907:    expand_function_start below for details. */
                   4908: 
                   4909: void
                   4910: bc_expand_function_start (subr, parms_have_cleanups)
                   4911:   tree subr;
                   4912:   int parms_have_cleanups;
                   4913: {
                   4914:   char label[20], *name;
                   4915:   static int nlab;
                   4916:   tree thisarg;
                   4917:   int argsz;
                   4918: 
                   4919:   if (TREE_PUBLIC (subr))
                   4920:     bc_globalize_label (IDENTIFIER_POINTER (DECL_NAME (subr)));
                   4921: 
                   4922: #ifdef DEBUG_PRINT_CODE
                   4923:   fprintf (stderr, "\n<func %s>\n", IDENTIFIER_POINTER (DECL_NAME (subr)));
                   4924: #endif
                   4925: 
                   4926:   for (argsz = 0, thisarg = DECL_ARGUMENTS (subr); thisarg; thisarg = TREE_CHAIN (thisarg))
                   4927:     {
                   4928:       if (DECL_RTL (thisarg))
                   4929:        abort ();               /* Should be NULL here I think.  */
                   4930:       else if (TREE_CONSTANT (DECL_SIZE (thisarg)))
                   4931:        {
                   4932:          DECL_RTL (thisarg) = bc_gen_rtx ((char *) 0, argsz, (struct bc_label *) 0);
                   4933:          argsz += TREE_INT_CST_LOW (DECL_SIZE (thisarg));
                   4934:        }
                   4935:       else
                   4936:        {
                   4937:          /* Variable-sized objects are pointers to their storage. */
                   4938:          DECL_RTL (thisarg) = bc_gen_rtx ((char *) 0, argsz, (struct bc_label *) 0);
                   4939:          argsz += POINTER_SIZE;
                   4940:        }
                   4941:     }
                   4942: 
                   4943:   bc_begin_function (bc_xstrdup (IDENTIFIER_POINTER (DECL_NAME (subr))));
                   4944: 
                   4945:   ASM_GENERATE_INTERNAL_LABEL (label, "LX", nlab);
                   4946: 
                   4947:   ++nlab;
                   4948:   name = (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
                   4949:   this_function_callinfo = bc_gen_rtx (name, 0, (struct bc_label *) 0);
                   4950:   this_function_bytecode =
                   4951:     bc_emit_trampoline (BYTECODE_LABEL (this_function_callinfo));
                   4952: }
                   4953: 
                   4954: 
                   4955: /* Expand end of bytecode function. See details the comment of
                   4956:    expand_function_end(), below. */
                   4957: 
                   4958: void
                   4959: bc_expand_function_end ()
                   4960: {
                   4961:   char *ptrconsts;
                   4962: 
                   4963:   expand_null_return ();
                   4964: 
                   4965:   /* Emit any fixup code. This must be done before the call to
                   4966:      to BC_END_FUNCTION (), since that will cause the bytecode
                   4967:      segment to be finished off and closed. */
                   4968: 
1.1.1.7   root     4969:   expand_fixups (NULL_RTX);
1.1.1.6   root     4970: 
                   4971:   ptrconsts = bc_end_function ();
                   4972: 
                   4973:   bc_align_const (2 /* INT_ALIGN */);
                   4974: 
                   4975:   /* If this changes also make sure to change bc-interp.h!  */
                   4976: 
                   4977:   bc_emit_const_labeldef (BYTECODE_LABEL (this_function_callinfo));
                   4978:   bc_emit_const ((char *) &max_stack_depth, sizeof max_stack_depth);
                   4979:   bc_emit_const ((char *) &local_vars_size, sizeof local_vars_size);
                   4980:   bc_emit_const_labelref (this_function_bytecode, 0);
                   4981:   bc_emit_const_labelref (ptrconsts, 0);
                   4982:   bc_emit_const_labelref (BYTECODE_LABEL (this_function_calldesc), 0);
                   4983: }
                   4984: 
                   4985: 
1.1       root     4986: /* Start the RTL for a new function, and set variables used for
                   4987:    emitting RTL.
                   4988:    SUBR is the FUNCTION_DECL node.
                   4989:    PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
                   4990:    the function's parameters, which must be run at any return statement.  */
                   4991: 
                   4992: void
                   4993: expand_function_start (subr, parms_have_cleanups)
                   4994:      tree subr;
                   4995:      int parms_have_cleanups;
                   4996: {
                   4997:   register int i;
                   4998:   tree tem;
                   4999:   rtx last_ptr;
                   5000: 
1.1.1.6   root     5001:   if (output_bytecode)
                   5002:     {
                   5003:       bc_expand_function_start (subr, parms_have_cleanups);
                   5004:       return;
                   5005:     }
                   5006: 
1.1       root     5007:   /* Make sure volatile mem refs aren't considered
                   5008:      valid operands of arithmetic insns.  */
                   5009:   init_recog_no_volatile ();
                   5010: 
                   5011:   /* If function gets a static chain arg, store it in the stack frame.
                   5012:      Do this first, so it gets the first stack slot offset.  */
                   5013:   if (current_function_needs_context)
1.1.1.4   root     5014:     {
                   5015:       last_ptr = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
1.1.1.7   root     5016: 
                   5017: #ifdef SMALL_REGISTER_CLASSES
                   5018:       /* Delay copying static chain if it is not a register to avoid
                   5019:         conflicts with regs used for parameters.  */
                   5020:       if (GET_CODE (static_chain_incoming_rtx) == REG)
                   5021: #endif
                   5022:         emit_move_insn (last_ptr, static_chain_incoming_rtx);
1.1.1.4   root     5023:     }
1.1       root     5024: 
                   5025:   /* If the parameters of this function need cleaning up, get a label
                   5026:      for the beginning of the code which executes those cleanups.  This must
                   5027:      be done before doing anything with return_label.  */
                   5028:   if (parms_have_cleanups)
                   5029:     cleanup_label = gen_label_rtx ();
                   5030:   else
                   5031:     cleanup_label = 0;
                   5032: 
                   5033:   /* Make the label for return statements to jump to, if this machine
                   5034:      does not have a one-instruction return and uses an epilogue,
                   5035:      or if it returns a structure, or if it has parm cleanups.  */
                   5036: #ifdef HAVE_return
                   5037:   if (cleanup_label == 0 && HAVE_return
                   5038:       && ! current_function_returns_pcc_struct
                   5039:       && ! (current_function_returns_struct && ! optimize))
                   5040:     return_label = 0;
                   5041:   else
                   5042:     return_label = gen_label_rtx ();
                   5043: #else
                   5044:   return_label = gen_label_rtx ();
                   5045: #endif
                   5046: 
                   5047:   /* Initialize rtx used to return the value.  */
                   5048:   /* Do this before assign_parms so that we copy the struct value address
                   5049:      before any library calls that assign parms might generate.  */
                   5050: 
                   5051:   /* Decide whether to return the value in memory or in a register.  */
                   5052:   if (aggregate_value_p (DECL_RESULT (subr)))
                   5053:     {
                   5054:       /* Returning something that won't go in a register.  */
1.1.1.7   root     5055:       register rtx value_address = 0;
1.1       root     5056: 
                   5057: #ifdef PCC_STATIC_STRUCT_RETURN
                   5058:       if (current_function_returns_pcc_struct)
                   5059:        {
                   5060:          int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
                   5061:          value_address = assemble_static_space (size);
                   5062:        }
                   5063:       else
                   5064: #endif
                   5065:        {
                   5066:          /* Expect to be passed the address of a place to store the value.
                   5067:             If it is passed as an argument, assign_parms will take care of
                   5068:             it.  */
                   5069:          if (struct_value_incoming_rtx)
                   5070:            {
                   5071:              value_address = gen_reg_rtx (Pmode);
                   5072:              emit_move_insn (value_address, struct_value_incoming_rtx);
                   5073:            }
                   5074:        }
                   5075:       if (value_address)
1.1.1.7   root     5076:        {
                   5077:          DECL_RTL (DECL_RESULT (subr))
                   5078:            = gen_rtx (MEM, DECL_MODE (DECL_RESULT (subr)), value_address);
                   5079:          MEM_IN_STRUCT_P (DECL_RTL (DECL_RESULT (subr)))
                   5080:            = AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
                   5081:        }
1.1       root     5082:     }
                   5083:   else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
                   5084:     /* If return mode is void, this decl rtl should not be used.  */
                   5085:     DECL_RTL (DECL_RESULT (subr)) = 0;
                   5086:   else if (parms_have_cleanups)
1.1.1.4   root     5087:     {
                   5088:       /* If function will end with cleanup code for parms,
                   5089:         compute the return values into a pseudo reg,
                   5090:         which we will copy into the true return register
                   5091:         after the cleanups are done.  */
                   5092: 
                   5093:       enum machine_mode mode = DECL_MODE (DECL_RESULT (subr));
1.1.1.7   root     5094: 
1.1.1.4   root     5095: #ifdef PROMOTE_FUNCTION_RETURN
                   5096:       tree type = TREE_TYPE (DECL_RESULT (subr));
                   5097:       int unsignedp = TREE_UNSIGNED (type);
                   5098: 
1.1.1.7   root     5099:       mode = promote_mode (type, mode, &unsignedp, 1);
1.1.1.4   root     5100: #endif
                   5101: 
                   5102:       DECL_RTL (DECL_RESULT (subr)) = gen_reg_rtx (mode);
                   5103:     }
1.1       root     5104:   else
                   5105:     /* Scalar, returned in a register.  */
                   5106:     {
                   5107: #ifdef FUNCTION_OUTGOING_VALUE
                   5108:       DECL_RTL (DECL_RESULT (subr))
                   5109:        = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
                   5110: #else
                   5111:       DECL_RTL (DECL_RESULT (subr))
                   5112:        = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
                   5113: #endif
                   5114: 
                   5115:       /* Mark this reg as the function's return value.  */
                   5116:       if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
                   5117:        {
                   5118:          REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
                   5119:          /* Needed because we may need to move this to memory
                   5120:             in case it's a named return value whose address is taken.  */
1.1.1.4   root     5121:          DECL_REGISTER (DECL_RESULT (subr)) = 1;
1.1       root     5122:        }
                   5123:     }
                   5124: 
                   5125:   /* Initialize rtx for parameters and local variables.
                   5126:      In some cases this requires emitting insns.  */
                   5127: 
                   5128:   assign_parms (subr, 0);
                   5129: 
1.1.1.7   root     5130: #ifdef SMALL_REGISTER_CLASSES
                   5131:   /* Copy the static chain now if it wasn't a register.  The delay is to
                   5132:      avoid conflicts with the parameter passing registers.  */
                   5133: 
                   5134:   if (current_function_needs_context)
                   5135:       if (GET_CODE (static_chain_incoming_rtx) != REG)
                   5136:         emit_move_insn (last_ptr, static_chain_incoming_rtx);
                   5137: #endif
                   5138: 
1.1       root     5139:   /* The following was moved from init_function_start.
                   5140:      The move is supposed to make sdb output more accurate.  */
                   5141:   /* Indicate the beginning of the function body,
                   5142:      as opposed to parm setup.  */
1.1.1.4   root     5143:   emit_note (NULL_PTR, NOTE_INSN_FUNCTION_BEG);
1.1       root     5144: 
                   5145:   /* If doing stupid allocation, mark parms as born here.  */
                   5146: 
                   5147:   if (GET_CODE (get_last_insn ()) != NOTE)
1.1.1.4   root     5148:     emit_note (NULL_PTR, NOTE_INSN_DELETED);
1.1       root     5149:   parm_birth_insn = get_last_insn ();
                   5150: 
                   5151:   if (obey_regdecls)
                   5152:     {
                   5153:       for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
                   5154:        use_variable (regno_reg_rtx[i]);
                   5155: 
                   5156:       if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
                   5157:        use_variable (current_function_internal_arg_pointer);
                   5158:     }
                   5159: 
                   5160:   /* Fetch static chain values for containing functions.  */
                   5161:   tem = decl_function_context (current_function_decl);
1.1.1.7   root     5162:   /* If not doing stupid register allocation copy the static chain
1.1.1.8 ! root     5163:      pointer into a pseudo.  If we have small register classes, copy the
1.1.1.7   root     5164:      value from memory if static_chain_incoming_rtx is a REG.  If we do
                   5165:      stupid register allocation, we use the stack address generated above.  */
1.1.1.4   root     5166:   if (tem && ! obey_regdecls)
1.1.1.7   root     5167:     {
                   5168: #ifdef SMALL_REGISTER_CLASSES
                   5169:       /* If the static chain originally came in a register, put it back
                   5170:         there, then move it out in the next insn.  The reason for
                   5171:         this peculiar code is to satisfy function integration.  */
                   5172:       if (GET_CODE (static_chain_incoming_rtx) == REG)
                   5173:        emit_move_insn (static_chain_incoming_rtx, last_ptr);
                   5174: #endif
                   5175: 
                   5176:       last_ptr = copy_to_reg (static_chain_incoming_rtx);
                   5177:     }
                   5178: 
1.1       root     5179:   context_display = 0;
                   5180:   while (tem)
                   5181:     {
                   5182:       tree rtlexp = make_node (RTL_EXPR);
                   5183: 
                   5184:       RTL_EXPR_RTL (rtlexp) = last_ptr;
                   5185:       context_display = tree_cons (tem, rtlexp, context_display);
                   5186:       tem = decl_function_context (tem);
                   5187:       if (tem == 0)
                   5188:        break;
                   5189:       /* Chain thru stack frames, assuming pointer to next lexical frame
                   5190:         is found at the place we always store it.  */
                   5191: #ifdef FRAME_GROWS_DOWNWARD
                   5192:       last_ptr = plus_constant (last_ptr, - GET_MODE_SIZE (Pmode));
                   5193: #endif
                   5194:       last_ptr = copy_to_reg (gen_rtx (MEM, Pmode,
                   5195:                                       memory_address (Pmode, last_ptr)));
1.1.1.6   root     5196: 
                   5197:       /* If we are not optimizing, ensure that we know that this
                   5198:         piece of context is live over the entire function.  */
                   5199:       if (! optimize)
                   5200:        save_expr_regs = gen_rtx (EXPR_LIST, VOIDmode, last_ptr,
                   5201:                                  save_expr_regs);
1.1       root     5202:     }
                   5203: 
                   5204:   /* After the display initializations is where the tail-recursion label
                   5205:      should go, if we end up needing one.   Ensure we have a NOTE here
                   5206:      since some things (like trampolines) get placed before this.  */
1.1.1.4   root     5207:   tail_recursion_reentry = emit_note (NULL_PTR, NOTE_INSN_DELETED);
1.1       root     5208: 
                   5209:   /* Evaluate now the sizes of any types declared among the arguments.  */
                   5210:   for (tem = nreverse (get_pending_sizes ()); tem; tem = TREE_CHAIN (tem))
1.1.1.5   root     5211:     expand_expr (TREE_VALUE (tem), const0_rtx, VOIDmode, 0);
1.1       root     5212: 
                   5213:   /* Make sure there is a line number after the function entry setup code.  */
                   5214:   force_next_line_note ();
                   5215: }
                   5216: 
                   5217: /* Generate RTL for the end of the current function.
1.1.1.6   root     5218:    FILENAME and LINE are the current position in the source file. 
1.1       root     5219: 
1.1.1.6   root     5220:    It is up to language-specific callers to do cleanups for parameters--
                   5221:    or else, supply 1 for END_BINDINGS and we will call expand_end_bindings.  */
1.1       root     5222: 
                   5223: void
1.1.1.6   root     5224: expand_function_end (filename, line, end_bindings)
1.1       root     5225:      char *filename;
                   5226:      int line;
1.1.1.6   root     5227:      int end_bindings;
1.1       root     5228: {
                   5229:   register int i;
                   5230:   tree link;
                   5231: 
                   5232:   static rtx initial_trampoline;
                   5233: 
1.1.1.6   root     5234:   if (output_bytecode)
                   5235:     {
                   5236:       bc_expand_function_end ();
                   5237:       return;
                   5238:     }
                   5239: 
1.1       root     5240: #ifdef NON_SAVING_SETJMP
                   5241:   /* Don't put any variables in registers if we call setjmp
                   5242:      on a machine that fails to restore the registers.  */
                   5243:   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
                   5244:     {
1.1.1.7   root     5245:       if (DECL_INITIAL (current_function_decl) != error_mark_node)
                   5246:        setjmp_protect (DECL_INITIAL (current_function_decl));
                   5247: 
1.1       root     5248:       setjmp_protect_args ();
                   5249:     }
                   5250: #endif
                   5251: 
                   5252:   /* Save the argument pointer if a save area was made for it.  */
                   5253:   if (arg_pointer_save_area)
                   5254:     {
                   5255:       rtx x = gen_move_insn (arg_pointer_save_area, virtual_incoming_args_rtx);
                   5256:       emit_insn_before (x, tail_recursion_reentry);
                   5257:     }
                   5258: 
                   5259:   /* Initialize any trampolines required by this function.  */
                   5260:   for (link = trampoline_list; link; link = TREE_CHAIN (link))
                   5261:     {
                   5262:       tree function = TREE_PURPOSE (link);
                   5263:       rtx context = lookup_static_chain (function);
                   5264:       rtx tramp = RTL_EXPR_RTL (TREE_VALUE (link));
                   5265:       rtx seq;
                   5266: 
                   5267:       /* First make sure this compilation has a template for
                   5268:         initializing trampolines.  */
                   5269:       if (initial_trampoline == 0)
1.1.1.2   root     5270:        {
                   5271:          end_temporary_allocation ();
                   5272:          initial_trampoline
                   5273:            = gen_rtx (MEM, BLKmode, assemble_trampoline_template ());
                   5274:          resume_temporary_allocation ();
                   5275:        }
1.1       root     5276: 
                   5277:       /* Generate insns to initialize the trampoline.  */
                   5278:       start_sequence ();
                   5279:       tramp = change_address (initial_trampoline, BLKmode,
                   5280:                              round_trampoline_addr (XEXP (tramp, 0)));
1.1.1.4   root     5281:       emit_block_move (tramp, initial_trampoline, GEN_INT (TRAMPOLINE_SIZE),
1.1       root     5282:                       FUNCTION_BOUNDARY / BITS_PER_UNIT);
                   5283:       INITIALIZE_TRAMPOLINE (XEXP (tramp, 0),
                   5284:                             XEXP (DECL_RTL (function), 0), context);
                   5285:       seq = get_insns ();
                   5286:       end_sequence ();
                   5287: 
                   5288:       /* Put those insns at entry to the containing function (this one).  */
                   5289:       emit_insns_before (seq, tail_recursion_reentry);
                   5290:     }
                   5291: 
1.1.1.8 ! root     5292:   /* Warn about unused parms if extra warnings were specified.  */
        !          5293:   if (warn_unused && extra_warnings)
1.1       root     5294:     {
1.1.1.8 ! root     5295:       tree decl;
1.1       root     5296: 
                   5297:       for (decl = DECL_ARGUMENTS (current_function_decl);
                   5298:           decl; decl = TREE_CHAIN (decl))
1.1.1.8 ! root     5299:        if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
        !          5300:            && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
1.1       root     5301:          warning_with_decl (decl, "unused parameter `%s'");
                   5302:     }
                   5303: 
                   5304:   /* Delete handlers for nonlocal gotos if nothing uses them.  */
                   5305:   if (nonlocal_goto_handler_slot != 0 && !current_function_has_nonlocal_label)
                   5306:     delete_handlers ();
                   5307: 
                   5308:   /* End any sequences that failed to be closed due to syntax errors.  */
                   5309:   while (in_sequence_p ())
1.1.1.4   root     5310:     end_sequence ();
1.1       root     5311: 
                   5312:   /* Outside function body, can't compute type's actual size
                   5313:      until next function's body starts.  */
                   5314:   immediate_size_expand--;
                   5315: 
                   5316:   /* If doing stupid register allocation,
                   5317:      mark register parms as dying here.  */
                   5318: 
                   5319:   if (obey_regdecls)
                   5320:     {
                   5321:       rtx tem;
                   5322:       for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
                   5323:        use_variable (regno_reg_rtx[i]);
                   5324: 
                   5325:       /* Likewise for the regs of all the SAVE_EXPRs in the function.  */
                   5326: 
                   5327:       for (tem = save_expr_regs; tem; tem = XEXP (tem, 1))
                   5328:        {
                   5329:          use_variable (XEXP (tem, 0));
                   5330:          use_variable_after (XEXP (tem, 0), parm_birth_insn);
                   5331:        }
                   5332: 
                   5333:       if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
                   5334:        use_variable (current_function_internal_arg_pointer);
                   5335:     }
                   5336: 
                   5337:   clear_pending_stack_adjust ();
                   5338:   do_pending_stack_adjust ();
                   5339: 
                   5340:   /* Mark the end of the function body.
                   5341:      If control reaches this insn, the function can drop through
                   5342:      without returning a value.  */
1.1.1.4   root     5343:   emit_note (NULL_PTR, NOTE_INSN_FUNCTION_END);
1.1       root     5344: 
                   5345:   /* Output a linenumber for the end of the function.
                   5346:      SDB depends on this.  */
                   5347:   emit_line_note_force (filename, line);
                   5348: 
                   5349:   /* Output the label for the actual return from the function,
                   5350:      if one is expected.  This happens either because a function epilogue
                   5351:      is used instead of a return instruction, or because a return was done
                   5352:      with a goto in order to run local cleanups, or because of pcc-style
                   5353:      structure returning.  */
                   5354: 
                   5355:   if (return_label)
                   5356:     emit_label (return_label);
                   5357: 
1.1.1.6   root     5358:   /* C++ uses this.  */
                   5359:   if (end_bindings)
                   5360:     expand_end_bindings (0, 0, 0);
                   5361: 
1.1       root     5362:   /* If we had calls to alloca, and this machine needs
                   5363:      an accurate stack pointer to exit the function,
                   5364:      insert some code to save and restore the stack pointer.  */
                   5365: #ifdef EXIT_IGNORE_STACK
                   5366:   if (! EXIT_IGNORE_STACK)
                   5367: #endif
                   5368:     if (current_function_calls_alloca)
                   5369:       {
1.1.1.3   root     5370:        rtx tem = 0;
                   5371: 
                   5372:        emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
1.1.1.4   root     5373:        emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
1.1       root     5374:       }
                   5375: 
                   5376:   /* If scalar return value was computed in a pseudo-reg,
                   5377:      copy that to the hard return register.  */
                   5378:   if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
                   5379:       && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
                   5380:       && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
                   5381:          >= FIRST_PSEUDO_REGISTER))
                   5382:     {
                   5383:       rtx real_decl_result;
                   5384: 
                   5385: #ifdef FUNCTION_OUTGOING_VALUE
                   5386:       real_decl_result
                   5387:        = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
                   5388:                                   current_function_decl);
                   5389: #else
                   5390:       real_decl_result
                   5391:        = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
                   5392:                          current_function_decl);
                   5393: #endif
                   5394:       REG_FUNCTION_VALUE_P (real_decl_result) = 1;
                   5395:       emit_move_insn (real_decl_result,
                   5396:                      DECL_RTL (DECL_RESULT (current_function_decl)));
                   5397:       emit_insn (gen_rtx (USE, VOIDmode, real_decl_result));
                   5398:     }
                   5399: 
                   5400:   /* If returning a structure, arrange to return the address of the value
                   5401:      in a place where debuggers expect to find it.
                   5402: 
                   5403:      If returning a structure PCC style,
                   5404:      the caller also depends on this value.
                   5405:      And current_function_returns_pcc_struct is not necessarily set.  */
                   5406:   if (current_function_returns_struct
                   5407:       || current_function_returns_pcc_struct)
                   5408:     {
                   5409:       rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
                   5410:       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
                   5411: #ifdef FUNCTION_OUTGOING_VALUE
                   5412:       rtx outgoing
                   5413:        = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
                   5414:                                   current_function_decl);
                   5415: #else
                   5416:       rtx outgoing
                   5417:        = FUNCTION_VALUE (build_pointer_type (type),
                   5418:                          current_function_decl);
                   5419: #endif
                   5420: 
                   5421:       /* Mark this as a function return value so integrate will delete the
                   5422:         assignment and USE below when inlining this function.  */
                   5423:       REG_FUNCTION_VALUE_P (outgoing) = 1;
                   5424: 
                   5425:       emit_move_insn (outgoing, value_address);
                   5426:       use_variable (outgoing);
                   5427:     }
                   5428: 
                   5429:   /* Output a return insn if we are using one.
                   5430:      Otherwise, let the rtl chain end here, to drop through
                   5431:      into the epilogue.  */
                   5432: 
                   5433: #ifdef HAVE_return
                   5434:   if (HAVE_return)
                   5435:     {
                   5436:       emit_jump_insn (gen_return ());
                   5437:       emit_barrier ();
                   5438:     }
                   5439: #endif
                   5440: 
                   5441:   /* Fix up any gotos that jumped out to the outermost
                   5442:      binding level of the function.
                   5443:      Must follow emitting RETURN_LABEL.  */
                   5444: 
                   5445:   /* If you have any cleanups to do at this point,
                   5446:      and they need to create temporary variables,
                   5447:      then you will lose.  */
1.1.1.7   root     5448:   expand_fixups (get_insns ());
1.1.1.4   root     5449: }
                   5450: 
                   5451: /* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
                   5452: 
                   5453: static int *prologue;
                   5454: static int *epilogue;
                   5455: 
                   5456: /* Create an array that records the INSN_UIDs of INSNS (either a sequence
                   5457:    or a single insn).  */
                   5458: 
                   5459: static int *
                   5460: record_insns (insns)
                   5461:      rtx insns;
                   5462: {
                   5463:   int *vec;
                   5464: 
                   5465:   if (GET_CODE (insns) == SEQUENCE)
                   5466:     {
                   5467:       int len = XVECLEN (insns, 0);
                   5468:       vec = (int *) oballoc ((len + 1) * sizeof (int));
                   5469:       vec[len] = 0;
                   5470:       while (--len >= 0)
                   5471:        vec[len] = INSN_UID (XVECEXP (insns, 0, len));
                   5472:     }
                   5473:   else
                   5474:     {
                   5475:       vec = (int *) oballoc (2 * sizeof (int));
                   5476:       vec[0] = INSN_UID (insns);
                   5477:       vec[1] = 0;
                   5478:     }
                   5479:   return vec;
                   5480: }
                   5481: 
                   5482: /* Determine how many INSN_UIDs in VEC are part of INSN.  */
                   5483: 
                   5484: static int
                   5485: contains (insn, vec)
                   5486:      rtx insn;
                   5487:      int *vec;
                   5488: {
                   5489:   register int i, j;
                   5490: 
                   5491:   if (GET_CODE (insn) == INSN
                   5492:       && GET_CODE (PATTERN (insn)) == SEQUENCE)
                   5493:     {
                   5494:       int count = 0;
                   5495:       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
                   5496:        for (j = 0; vec[j]; j++)
                   5497:          if (INSN_UID (XVECEXP (PATTERN (insn), 0, i)) == vec[j])
                   5498:            count++;
                   5499:       return count;
                   5500:     }
                   5501:   else
                   5502:     {
                   5503:       for (j = 0; vec[j]; j++)
                   5504:        if (INSN_UID (insn) == vec[j])
                   5505:          return 1;
                   5506:     }
                   5507:   return 0;
                   5508: }
                   5509: 
1.1.1.8 ! root     5510: /* Generate the prologue and epilogue RTL if the machine supports it.  Thread
1.1.1.4   root     5511:    this into place with notes indicating where the prologue ends and where
                   5512:    the epilogue begins.  Update the basic block information when possible.  */
                   5513: 
                   5514: void
                   5515: thread_prologue_and_epilogue_insns (f)
                   5516:      rtx f;
                   5517: {
                   5518: #ifdef HAVE_prologue
                   5519:   if (HAVE_prologue)
                   5520:     {
                   5521:       rtx head, seq, insn;
                   5522: 
                   5523:       /* The first insn (a NOTE_INSN_DELETED) is followed by zero or more
                   5524:         prologue insns and a NOTE_INSN_PROLOGUE_END.  */
                   5525:       emit_note_after (NOTE_INSN_PROLOGUE_END, f);
                   5526:       seq = gen_prologue ();
                   5527:       head = emit_insn_after (seq, f);
                   5528: 
                   5529:       /* Include the new prologue insns in the first block.  Ignore them
                   5530:         if they form a basic block unto themselves.  */
                   5531:       if (basic_block_head && n_basic_blocks
                   5532:          && GET_CODE (basic_block_head[0]) != CODE_LABEL)
                   5533:        basic_block_head[0] = NEXT_INSN (f);
                   5534: 
                   5535:       /* Retain a map of the prologue insns.  */
                   5536:       prologue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : head);
                   5537:     }
                   5538:   else
                   5539: #endif
                   5540:     prologue = 0;
                   5541: 
                   5542: #ifdef HAVE_epilogue
                   5543:   if (HAVE_epilogue)
                   5544:     {
                   5545:       rtx insn = get_last_insn ();
                   5546:       rtx prev = prev_nonnote_insn (insn);
                   5547: 
                   5548:       /* If we end with a BARRIER, we don't need an epilogue.  */
                   5549:       if (! (prev && GET_CODE (prev) == BARRIER))
                   5550:        {
1.1.1.6   root     5551:          rtx tail, seq, tem;
                   5552:          rtx first_use = 0;
                   5553:          rtx last_use = 0;
                   5554: 
                   5555:          /* The last basic block ends with a NOTE_INSN_EPILOGUE_BEG, the
                   5556:             epilogue insns, the USE insns at the end of a function,
                   5557:             the jump insn that returns, and then a BARRIER.  */
1.1.1.4   root     5558: 
1.1.1.6   root     5559:          /* Move the USE insns at the end of a function onto a list.  */
1.1.1.4   root     5560:          while (prev
                   5561:                 && GET_CODE (prev) == INSN
                   5562:                 && GET_CODE (PATTERN (prev)) == USE)
                   5563:            {
1.1.1.6   root     5564:              tem = prev;
1.1.1.4   root     5565:              prev = prev_nonnote_insn (prev);
1.1.1.6   root     5566: 
                   5567:              NEXT_INSN (PREV_INSN (tem)) = NEXT_INSN (tem);
                   5568:              PREV_INSN (NEXT_INSN (tem)) = PREV_INSN (tem);
                   5569:              if (first_use)
                   5570:                {
                   5571:                  NEXT_INSN (tem) = first_use;
                   5572:                  PREV_INSN (first_use) = tem;
                   5573:                }
                   5574:              first_use = tem;
                   5575:              if (!last_use)
                   5576:                last_use = tem;
1.1.1.4   root     5577:            }
                   5578: 
1.1.1.6   root     5579:          emit_barrier_after (insn);
                   5580: 
1.1.1.4   root     5581:          seq = gen_epilogue ();
                   5582:          tail = emit_jump_insn_after (seq, insn);
1.1.1.6   root     5583: 
                   5584:          /* Insert the USE insns immediately before the return insn, which
                   5585:             must be the first instruction before the final barrier.  */
                   5586:          if (first_use)
                   5587:            {
                   5588:              tem = prev_nonnote_insn (get_last_insn ());
                   5589:              NEXT_INSN (PREV_INSN (tem)) = first_use;
                   5590:              PREV_INSN (first_use) = PREV_INSN (tem);
                   5591:              PREV_INSN (tem) = last_use;
                   5592:              NEXT_INSN (last_use) = tem;
                   5593:            }
                   5594: 
1.1.1.4   root     5595:          emit_note_after (NOTE_INSN_EPILOGUE_BEG, insn);
                   5596: 
                   5597:          /* Include the new epilogue insns in the last block.  Ignore
                   5598:             them if they form a basic block unto themselves.  */
                   5599:          if (basic_block_end && n_basic_blocks
                   5600:              && GET_CODE (basic_block_end[n_basic_blocks - 1]) != JUMP_INSN)
                   5601:            basic_block_end[n_basic_blocks - 1] = tail;
                   5602: 
                   5603:          /* Retain a map of the epilogue insns.  */
                   5604:          epilogue = record_insns (GET_CODE (seq) == SEQUENCE ? seq : tail);
                   5605:          return;
                   5606:        }
                   5607:     }
                   5608: #endif
                   5609:   epilogue = 0;
                   5610: }
                   5611: 
                   5612: /* Reposition the prologue-end and epilogue-begin notes after instruction
                   5613:    scheduling and delayed branch scheduling.  */
                   5614: 
                   5615: void
                   5616: reposition_prologue_and_epilogue_notes (f)
                   5617:      rtx f;
                   5618: {
                   5619: #if defined (HAVE_prologue) || defined (HAVE_epilogue)
                   5620:   /* Reposition the prologue and epilogue notes.  */
                   5621:   if (n_basic_blocks)
                   5622:     {
                   5623:       rtx next, prev;
                   5624:       int len;
                   5625: 
                   5626:       if (prologue)
                   5627:        {
                   5628:          register rtx insn, note = 0;
                   5629: 
                   5630:          /* Scan from the beginning until we reach the last prologue insn.
                   5631:             We apparently can't depend on basic_block_{head,end} after
                   5632:             reorg has run.  */
                   5633:          for (len = 0; prologue[len]; len++)
                   5634:            ;
1.1.1.5   root     5635:          for (insn = f; len && insn; insn = NEXT_INSN (insn))
                   5636:            {
                   5637:              if (GET_CODE (insn) == NOTE)
                   5638:                {
                   5639:                  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
                   5640:                    note = insn;
                   5641:                }
                   5642:              else if ((len -= contains (insn, prologue)) == 0)
                   5643:                {
                   5644:                  /* Find the prologue-end note if we haven't already, and
                   5645:                     move it to just after the last prologue insn.  */
                   5646:                  if (note == 0)
                   5647:                    {
                   5648:                      for (note = insn; note = NEXT_INSN (note);)
                   5649:                        if (GET_CODE (note) == NOTE
                   5650:                            && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END)
                   5651:                          break;
                   5652:                    }
                   5653:                  next = NEXT_INSN (note);
                   5654:                  prev = PREV_INSN (note);
                   5655:                  if (prev)
                   5656:                    NEXT_INSN (prev) = next;
                   5657:                  if (next)
                   5658:                    PREV_INSN (next) = prev;
                   5659:                  add_insn_after (note, insn);
                   5660:                }
                   5661:            }
1.1.1.4   root     5662:        }
                   5663: 
                   5664:       if (epilogue)
                   5665:        {
                   5666:          register rtx insn, note = 0;
                   5667: 
                   5668:          /* Scan from the end until we reach the first epilogue insn.
                   5669:             We apparently can't depend on basic_block_{head,end} after
                   5670:             reorg has run.  */
                   5671:          for (len = 0; epilogue[len]; len++)
                   5672:            ;
1.1.1.5   root     5673:          for (insn = get_last_insn (); len && insn; insn = PREV_INSN (insn))
                   5674:            {
                   5675:              if (GET_CODE (insn) == NOTE)
                   5676:                {
                   5677:                  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG)
                   5678:                    note = insn;
                   5679:                }
                   5680:              else if ((len -= contains (insn, epilogue)) == 0)
                   5681:                {
                   5682:                  /* Find the epilogue-begin note if we haven't already, and
                   5683:                     move it to just before the first epilogue insn.  */
                   5684:                  if (note == 0)
                   5685:                    {
                   5686:                      for (note = insn; note = PREV_INSN (note);)
                   5687:                        if (GET_CODE (note) == NOTE
                   5688:                            && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG)
                   5689:                          break;
                   5690:                    }
                   5691:                  next = NEXT_INSN (note);
                   5692:                  prev = PREV_INSN (note);
                   5693:                  if (prev)
                   5694:                    NEXT_INSN (prev) = next;
                   5695:                  if (next)
                   5696:                    PREV_INSN (next) = prev;
                   5697:                  add_insn_after (note, PREV_INSN (insn));
                   5698:                }
                   5699:            }
1.1.1.4   root     5700:        }
                   5701:     }
                   5702: #endif /* HAVE_prologue or HAVE_epilogue */
1.1       root     5703: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.