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