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