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