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