|
|
1.1 root 1: /* Expands front end tree to back end RTL for GNU C-Compiler
2: Copyright (C) 1987, 1988, 1989, 1991 Free Software Foundation, Inc.
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"
56:
57: /* Round a value to the lowest integer less than it that is a multiple of
58: the required alignment. Avoid using division in case the value is
59: negative. Assume the alignment is a power of two. */
60: #define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))
61:
62: /* Similar, but round to the next highest integer that meets the
63: alignment. */
64: #define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
65:
66: /* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp
67: during rtl generation. If they are different register numbers, this is
68: always true. It may also be true if
69: FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl
70: generation. See fix_lexical_addr for details. */
71:
72: #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
73: #define NEED_SEPARATE_AP
74: #endif
75:
76: /* Number of bytes of args popped by function being compiled on its return.
77: Zero if no bytes are to be popped.
78: May affect compilation of return insn or of function epilogue. */
79:
80: int current_function_pops_args;
81:
82: /* Nonzero if function being compiled needs to be given an address
83: where the value should be stored. */
84:
85: int current_function_returns_struct;
86:
87: /* Nonzero if function being compiled needs to
88: return the address of where it has put a structure value. */
89:
90: int current_function_returns_pcc_struct;
91:
92: /* Nonzero if function being compiled needs to be passed a static chain. */
93:
94: int current_function_needs_context;
95:
96: /* Nonzero if function being compiled can call setjmp. */
97:
98: int current_function_calls_setjmp;
99:
100: /* Nonzero if function being compiled can call longjmp. */
101:
102: int current_function_calls_longjmp;
103:
104: /* Nonzero if function being compiled receives nonlocal gotos
105: from nested functions. */
106:
107: int current_function_has_nonlocal_label;
108:
109: /* Nonzero if function being compiled contains nested functions. */
110:
111: int current_function_contains_functions;
112:
113: /* Nonzero if function being compiled can call alloca,
114: either as a subroutine or builtin. */
115:
116: int current_function_calls_alloca;
117:
118: /* Nonzero if the current function returns a pointer type */
119:
120: int current_function_returns_pointer;
121:
122: /* If some insns can be deferred to the delay slots of the epilogue, the
123: delay list for them is recorded here. */
124:
125: rtx current_function_epilogue_delay_list;
126:
127: /* If function's args have a fixed size, this is that size, in bytes.
128: Otherwise, it is -1.
129: May affect compilation of return insn or of function epilogue. */
130:
131: int current_function_args_size;
132:
133: /* # bytes the prologue should push and pretend that the caller pushed them.
134: The prologue must do this, but only if parms can be passed in registers. */
135:
136: int current_function_pretend_args_size;
137:
138: /* # of bytes of outgoing arguments required to be pushed by the prologue.
139: If this is non-zero, it means that ACCUMULATE_OUTGOING_ARGS was defined
140: and no stack adjusts will be done on function calls. */
141:
142: int current_function_outgoing_args_size;
143:
144: /* This is the offset from the arg pointer to the place where the first
145: anonymous arg can be found, if there is one. */
146:
147: rtx current_function_arg_offset_rtx;
148:
149: /* Nonzero if current function uses varargs.h or equivalent.
150: Zero for functions that use stdarg.h. */
151:
152: int current_function_varargs;
153:
154: /* Quantities of various kinds of registers
155: used for the current function's args. */
156:
157: CUMULATIVE_ARGS current_function_args_info;
158:
159: /* Name of function now being compiled. */
160:
161: char *current_function_name;
162:
163: /* If non-zero, an RTL expression for that location at which the current
164: function returns its result. Always equal to
165: DECL_RTL (DECL_RESULT (current_function_decl)), but provided
166: independently of the tree structures. */
167:
168: rtx current_function_return_rtx;
169:
170: /* Nonzero if the current function uses the constant pool. */
171:
172: int current_function_uses_const_pool;
173:
174: /* Nonzero if the current function uses pic_offset_table_rtx. */
175: int current_function_uses_pic_offset_table;
176:
177: /* The arg pointer hard register, or the pseudo into which it was copied. */
178: rtx current_function_internal_arg_pointer;
179:
180: /* The FUNCTION_DECL for an inline function currently being expanded. */
181: tree inline_function_decl;
182:
183: /* Number of function calls seen so far in current function. */
184:
185: int function_call_count;
186:
187: /* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels
188: (labels to which there can be nonlocal gotos from nested functions)
189: in this function. */
190:
191: tree nonlocal_labels;
192:
193: /* RTX for stack slot that holds the current handler for nonlocal gotos.
194: Zero when function does not have nonlocal labels. */
195:
196: rtx nonlocal_goto_handler_slot;
197:
198: /* RTX for stack slot that holds the stack pointer value to restore
199: for a nonlocal goto.
200: Zero when function does not have nonlocal labels. */
201:
202: rtx nonlocal_goto_stack_level;
203:
204: /* Label that will go on parm cleanup code, if any.
205: Jumping to this label runs cleanup code for parameters, if
206: such code must be run. Following this code is the logical return label. */
207:
208: rtx cleanup_label;
209:
210: /* Label that will go on function epilogue.
211: Jumping to this label serves as a "return" instruction
212: on machines which require execution of the epilogue on all returns. */
213:
214: rtx return_label;
215:
216: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
217: So we can mark them all live at the end of the function, if nonopt. */
218: rtx save_expr_regs;
219:
220: /* List (chain of EXPR_LISTs) of all stack slots in this function.
221: Made for the sake of unshare_all_rtl. */
222: rtx stack_slot_list;
223:
224: /* Chain of all RTL_EXPRs that have insns in them. */
225: tree rtl_expr_chain;
226:
227: /* Label to jump back to for tail recursion, or 0 if we have
228: not yet needed one for this function. */
229: rtx tail_recursion_label;
230:
231: /* Place after which to insert the tail_recursion_label if we need one. */
232: rtx tail_recursion_reentry;
233:
234: /* Location at which to save the argument pointer if it will need to be
235: referenced. There are two cases where this is done: if nonlocal gotos
236: exist, or if vars stored at an offset from the argument pointer will be
237: needed by inner routines. */
238:
239: rtx arg_pointer_save_area;
240:
241: /* Offset to end of allocated area of stack frame.
242: If stack grows down, this is the address of the last stack slot allocated.
243: If stack grows up, this is the address for the next slot. */
244: int frame_offset;
245:
246: /* List (chain of TREE_LISTs) of static chains for containing functions.
247: Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
248: in an RTL_EXPR in the TREE_VALUE. */
249: static tree context_display;
250:
251: /* List (chain of TREE_LISTs) of trampolines for nested functions.
252: The trampoline sets up the static chain and jumps to the function.
253: We supply the trampoline's address when the function's address is requested.
254:
255: Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx
256: in an RTL_EXPR in the TREE_VALUE. */
257: static tree trampoline_list;
258:
259: /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
260: static rtx parm_birth_insn;
261:
262: #if 0
263: /* Nonzero if a stack slot has been generated whose address is not
264: actually valid. It means that the generated rtl must all be scanned
265: to detect and correct the invalid addresses where they occur. */
266: static int invalid_stack_slot;
267: #endif
268:
269: /* Last insn of those whose job was to put parms into their nominal homes. */
270: static rtx last_parm_insn;
271:
272: /* 1 + last pseudo register number used for loading a copy
273: of a parameter of this function. */
274: static int max_parm_reg;
275:
276: /* Vector indexed by REGNO, containing location on stack in which
277: to put the parm which is nominally in pseudo register REGNO,
278: if we discover that that parm must go in the stack. */
279: static rtx *parm_reg_stack_loc;
280:
281: #if 0 /* Turned off because 0 seems to work just as well. */
282: /* Cleanup lists are required for binding levels regardless of whether
283: that binding level has cleanups or not. This node serves as the
284: cleanup list whenever an empty list is required. */
285: static tree empty_cleanup_list;
286: #endif
287:
288: /* Nonzero once virtual register instantiation has been done.
289: assign_stack_local uses frame_pointer_rtx when this is nonzero. */
290: static int virtuals_instantiated;
291:
292: /* Nonzero if we need to distinguish between the return value of this function
293: and the return value of a function called by this function. This helps
294: integrate.c */
295:
296: extern int rtx_equal_function_value_matters;
297:
298: void fixup_gotos ();
299:
300: static tree round_down ();
301: static rtx round_trampoline_addr ();
302: static rtx fixup_stack_1 ();
303: static void fixup_var_refs ();
304: static void fixup_var_refs_insns ();
305: static void fixup_var_refs_1 ();
306: static void optimize_bit_field ();
307: static void instantiate_decls ();
308: static void instantiate_decls_1 ();
309: static int instantiate_virtual_regs_1 ();
310: static rtx fixup_memory_subreg ();
311: static rtx walk_fixup_memory_subreg ();
312:
313: /* In order to evaluate some expressions, such as function calls returning
314: structures in memory, we need to temporarily allocate stack locations.
315: We record each allocated temporary in the following structure.
316:
317: Associated with each temporary slot is a nesting level. When we pop up
318: one level, all temporaries associated with the previous level are freed.
319: Normally, all temporaries are freed after the execution of the statement
320: in which they were created. However, if we are inside a ({...}) grouping,
321: the result may be in a temporary and hence must be preserved. If the
322: result could be in a temporary, we preserve it if we can determine which
323: one it is in. If we cannot determine which temporary may contain the
324: result, all temporaries are preserved. A temporary is preserved by
325: pretending it was allocated at the previous nesting level.
326:
327: Automatic variables are also assigned temporary slots, at the nesting
328: level where they are defined. They are marked a "kept" so that
329: free_temp_slots will not free them. */
330:
331: struct temp_slot
332: {
333: /* Points to next temporary slot. */
334: struct temp_slot *next;
335: /* The rtx to used to reference the slot. */
336: rtx slot;
337: /* The size, in units, of the slot. */
338: int size;
339: /* Non-zero if this temporary is currently in use. */
340: char in_use;
341: /* Nesting level at which this slot is being used. */
342: int level;
343: /* Non-zero if this should survive a call to free_temp_slots. */
344: int keep;
345: };
346:
347: /* List of all temporaries allocated, both available and in use. */
348:
349: struct temp_slot *temp_slots;
350:
351: /* Current nesting level for temporaries. */
352:
353: int temp_slot_level;
354:
355: /* Pointer to chain of `struct function' for containing functions. */
356: struct function *outer_function_chain;
357:
358: /* Given a function decl for a containing function,
359: return the `struct function' for it. */
360:
361: struct function *
362: find_function_data (decl)
363: tree decl;
364: {
365: struct function *p;
366: for (p = outer_function_chain; p; p = p->next)
367: if (p->decl == decl)
368: return p;
369: abort ();
370: }
371:
372: /* Save the current context for compilation of a nested function.
373: This is called from language-specific code.
374: The caller is responsible for saving any language-specific status,
375: since this function knows only about language-indepedent variables. */
376:
377: void
378: push_function_context ()
379: {
380: struct function *p = (struct function *) xmalloc (sizeof (struct function));
381:
382: p->next = outer_function_chain;
383: outer_function_chain = p;
384:
385: p->name = current_function_name;
386: p->decl = current_function_decl;
387: p->pops_args = current_function_pops_args;
388: p->returns_struct = current_function_returns_struct;
389: p->returns_pcc_struct = current_function_returns_pcc_struct;
390: p->needs_context = current_function_needs_context;
391: p->calls_setjmp = current_function_calls_setjmp;
392: p->calls_longjmp = current_function_calls_longjmp;
393: p->calls_alloca = current_function_calls_alloca;
394: p->has_nonlocal_label = current_function_has_nonlocal_label;
395: p->args_size = current_function_args_size;
396: p->pretend_args_size = current_function_pretend_args_size;
397: p->arg_offset_rtx = current_function_arg_offset_rtx;
398: p->uses_const_pool = current_function_uses_const_pool;
399: p->uses_pic_offset_table = current_function_uses_pic_offset_table;
400: p->internal_arg_pointer = current_function_internal_arg_pointer;
401: p->max_parm_reg = max_parm_reg;
402: p->parm_reg_stack_loc = parm_reg_stack_loc;
403: p->outgoing_args_size = current_function_outgoing_args_size;
404: p->return_rtx = current_function_return_rtx;
405: p->nonlocal_goto_handler_slot = nonlocal_goto_handler_slot;
406: p->nonlocal_goto_stack_level = nonlocal_goto_stack_level;
407: p->nonlocal_labels = nonlocal_labels;
408: p->cleanup_label = cleanup_label;
409: p->return_label = return_label;
410: p->save_expr_regs = save_expr_regs;
411: p->stack_slot_list = stack_slot_list;
412: p->parm_birth_insn = parm_birth_insn;
413: p->frame_offset = frame_offset;
414: p->tail_recursion_label = tail_recursion_label;
415: p->tail_recursion_reentry = tail_recursion_reentry;
416: p->arg_pointer_save_area = arg_pointer_save_area;
417: p->rtl_expr_chain = rtl_expr_chain;
418: p->last_parm_insn = last_parm_insn;
419: p->context_display = context_display;
420: p->trampoline_list = trampoline_list;
421: p->function_call_count = function_call_count;
422: p->temp_slots = temp_slots;
423: p->temp_slot_level = temp_slot_level;
424: p->fixup_var_refs_queue = 0;
425:
426: save_tree_status (p);
427: save_storage_status (p);
428: save_emit_status (p);
429: init_emit ();
430: save_expr_status (p);
431: save_stmt_status (p);
432: }
433:
434: /* Restore the last saved context, at the end of a nested function.
435: This function is called from language-specific code. */
436:
437: void
438: pop_function_context ()
439: {
440: struct function *p = outer_function_chain;
441:
442: outer_function_chain = p->next;
443:
444: current_function_name = p->name;
445: current_function_decl = p->decl;
446: current_function_pops_args = p->pops_args;
447: current_function_returns_struct = p->returns_struct;
448: current_function_returns_pcc_struct = p->returns_pcc_struct;
449: current_function_needs_context = p->needs_context;
450: current_function_calls_setjmp = p->calls_setjmp;
451: current_function_calls_longjmp = p->calls_longjmp;
452: current_function_calls_alloca = p->calls_alloca;
453: current_function_has_nonlocal_label = p->has_nonlocal_label;
454: current_function_contains_functions = 1;
455: current_function_args_size = p->args_size;
456: current_function_pretend_args_size = p->pretend_args_size;
457: current_function_arg_offset_rtx = p->arg_offset_rtx;
458: current_function_uses_const_pool = p->uses_const_pool;
459: current_function_uses_pic_offset_table = p->uses_pic_offset_table;
460: current_function_internal_arg_pointer = p->internal_arg_pointer;
461: max_parm_reg = p->max_parm_reg;
462: parm_reg_stack_loc = p->parm_reg_stack_loc;
463: current_function_outgoing_args_size = p->outgoing_args_size;
464: current_function_return_rtx = p->return_rtx;
465: nonlocal_goto_handler_slot = p->nonlocal_goto_handler_slot;
466: nonlocal_goto_stack_level = p->nonlocal_goto_stack_level;
467: nonlocal_labels = p->nonlocal_labels;
468: cleanup_label = p->cleanup_label;
469: return_label = p->return_label;
470: save_expr_regs = p->save_expr_regs;
471: stack_slot_list = p->stack_slot_list;
472: parm_birth_insn = p->parm_birth_insn;
473: frame_offset = p->frame_offset;
474: tail_recursion_label = p->tail_recursion_label;
475: tail_recursion_reentry = p->tail_recursion_reentry;
476: arg_pointer_save_area = p->arg_pointer_save_area;
477: rtl_expr_chain = p->rtl_expr_chain;
478: last_parm_insn = p->last_parm_insn;
479: context_display = p->context_display;
480: trampoline_list = p->trampoline_list;
481: function_call_count = p->function_call_count;
482: temp_slots = p->temp_slots;
483: temp_slot_level = p->temp_slot_level;
484:
485: restore_tree_status (p);
486: restore_storage_status (p);
487: restore_expr_status (p);
488: restore_emit_status (p);
489: restore_stmt_status (p);
490:
491: /* Finish doing put_var_into_stack for any of our variables
492: which became addressable during the nested function. */
493: {
494: struct var_refs_queue *queue = p->fixup_var_refs_queue;
495: for (; queue; queue = queue->next)
496: fixup_var_refs (queue->modified);
497: }
498:
499: free (p);
500:
501: /* Reset variables that have known state during rtx generation. */
502: rtx_equal_function_value_matters = 1;
503: virtuals_instantiated = 0;
504: }
505:
506: /* Allocate fixed slots in the stack frame of the current function. */
507:
508: /* Return size needed for stack frame based on slots so far allocated.
509: This size counts from zero. It is not rounded to STACK_BOUNDARY;
510: the caller may have to do that. */
511:
512: int
513: get_frame_size ()
514: {
515: #ifdef FRAME_GROWS_DOWNWARD
516: return -frame_offset;
517: #else
518: return frame_offset;
519: #endif
520: }
521:
522: /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
523: with machine mode MODE.
524:
525: ALIGN controls the amount of alignment for the address of the slot:
526: 0 means according to MODE,
527: -1 means use BIGGEST_ALIGNMENT and round size to multiple of that,
528: positive specifies alignment boundary in bits.
529:
530: We do not round to stack_boundary here. */
531:
532: rtx
533: assign_stack_local (mode, size, align)
534: enum machine_mode mode;
535: int size;
536: int align;
537: {
538: register rtx x, addr;
539: int bigend_correction = 0;
540: int alignment;
541:
542: if (align == 0)
543: {
544: alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
545: if (mode == BLKmode)
546: alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
547: }
548: else if (align == -1)
549: {
550: alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
551: size = CEIL_ROUND (size, alignment);
552: }
553: else
554: alignment = align / BITS_PER_UNIT;
555:
556: #if 0 /* Let's see if this is really needed--rms. */
557: #ifdef STRICT_ALIGNMENT
558: /* Supposedly sub-word sized units may later be accessed
559: with word intructions. It's not certain this is really true. */
560: if (mode != BLKmode && align == 0 && alignment < UNITS_PER_WORD)
561: alignment = UNITS_PER_WORD;
562:
563: /* This is in case we just made the alignment bigger than the size. */
564: size = CEIL_ROUND (size, alignment);
565: #endif
566: #endif
567:
568: /* Round frame offset to that alignment.
569: We must be careful here, since FRAME_OFFSET might be negative and
570: division with a negative dividend isn't as well defined as we might
571: like. So we instead assume that ALIGNMENT is a power of two and
572: use logical operations which are unambiguous. */
573: #ifdef FRAME_GROWS_DOWNWARD
574: frame_offset = FLOOR_ROUND (frame_offset, alignment);
575: #else
576: frame_offset = CEIL_ROUND (frame_offset, alignment);
577: #endif
578:
579: /* On a big-endian machine, if we are allocating more space than we will use,
580: use the least significant bytes of those that are allocated. */
581: #if BYTES_BIG_ENDIAN
582: if (mode != BLKmode)
583: bigend_correction = size - GET_MODE_SIZE (mode);
584: #endif
585:
586: #ifdef FRAME_GROWS_DOWNWARD
587: frame_offset -= size;
588: #endif
589:
590: /* If we have already instantiated virtual registers, return the actual
591: address relative to the frame pointer. */
592: if (virtuals_instantiated)
593: addr = plus_constant (frame_pointer_rtx,
594: (frame_offset + bigend_correction
595: + STARTING_FRAME_OFFSET));
596: else
597: addr = plus_constant (virtual_stack_vars_rtx,
598: frame_offset + bigend_correction);
599:
600: #ifndef FRAME_GROWS_DOWNWARD
601: frame_offset += size;
602: #endif
603:
604: x = gen_rtx (MEM, mode, addr);
605:
606: stack_slot_list = gen_rtx (EXPR_LIST, VOIDmode, x, stack_slot_list);
607:
608: return x;
609: }
610:
611: /* Assign a stack slot in a containing function.
612: First three arguments are same as in preceding function.
613: The last argument specifies the function to allocate in. */
614:
615: rtx
616: assign_outer_stack_local (mode, size, align, function)
617: enum machine_mode mode;
618: int size;
619: int align;
620: struct function *function;
621: {
622: register rtx x, addr;
623: int bigend_correction = 0;
624: int alignment;
625:
626: /* Allocate in the memory associated with the function in whose frame
627: we are assigning. */
628: push_obstacks (function->function_obstack,
629: function->function_maybepermanent_obstack);
630:
631: if (align == 0)
632: {
633: alignment = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
634: if (mode == BLKmode)
635: alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
636: }
637: else if (align == -1)
638: {
639: alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
640: size = CEIL_ROUND (size, alignment);
641: }
642: else
643: alignment = align / BITS_PER_UNIT;
644:
645: #if 0 /* Let's see if this is really needed--rms. */
646: #ifdef STRICT_ALIGNMENT
647: /* Sub-word sized units may later be accessed with word intructions.
648: This results from (SUBREG (MEM ...) ...). */
649: if (mode != BLKmode && align == 0 && alignment < UNITS_PER_WORD)
650: alignment = UNITS_PER_WORD;
651:
652: /* This is in case we just made the alignment bigger than the size. */
653: size = CEIL_ROUND (size, alignment);
654: #endif
655: #endif
656:
657: /* Round frame offset to that alignment. */
658: #ifdef FRAME_GROWS_DOWNWARD
659: frame_offset = FLOOR_ROUND (frame_offset, alignment);
660: #else
661: frame_offset = CEIL_ROUND (frame_offset, alignment);
662: #endif
663:
664: /* On a big-endian machine, if we are allocating more space than we will use,
665: use the least significant bytes of those that are allocated. */
666: #if BYTES_BIG_ENDIAN
667: if (mode != BLKmode)
668: bigend_correction = size - GET_MODE_SIZE (mode);
669: #endif
670:
671: #ifdef FRAME_GROWS_DOWNWARD
672: function->frame_offset -= size;
673: #endif
674: addr = plus_constant (virtual_stack_vars_rtx,
675: function->frame_offset + bigend_correction);
676: #ifndef FRAME_GROWS_DOWNWARD
677: function->frame_offset += size;
678: #endif
679:
680: x = gen_rtx (MEM, mode, addr);
681:
682: function->stack_slot_list
683: = gen_rtx (EXPR_LIST, VOIDmode, x, function->stack_slot_list);
684:
685: pop_obstacks ();
686:
687: return x;
688: }
689:
690: /* Allocate a temporary stack slot and record it for possible later
691: reuse.
692:
693: MODE is the machine mode to be given to the returned rtx.
694:
695: SIZE is the size in units of the space required. We do no rounding here
696: since assign_stack_local will do any required rounding.
697:
698: KEEP is non-zero if this slot is to be retained after a call to
699: free_temp_slots. Automatic variables for a block are allocated with this
700: flag. */
701:
702: rtx
703: assign_stack_temp (mode, size, keep)
704: enum machine_mode mode;
705: int size;
706: int keep;
707: {
708: struct temp_slot *p, *best_p = 0;
709:
710: /* First try to find an available, already-allocated temporary that is the
711: exact size we require. */
712: for (p = temp_slots; p; p = p->next)
713: if (p->size == size && GET_MODE (p->slot) == mode && ! p->in_use)
714: break;
715:
716: /* If we didn't find, one, try one that is larger than what we want. We
717: find the smallest such. */
718: if (p == 0)
719: for (p = temp_slots; p; p = p->next)
720: if (p->size > size && GET_MODE (p->slot) == mode && ! p->in_use
721: && (best_p == 0 || best_p->size > p->size))
722: best_p = p;
723:
724: /* Make our best, if any, the one to use. */
725: if (best_p)
726: p = best_p;
727:
728: /* If we still didn't find one, make a new temporary. */
729: if (p == 0)
730: {
731: p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
732: p->size = size;
733: /* If the temp slot mode doesn't indicate the alignment,
734: use the largest possible, so no one will be disappointed. */
735: p->slot = assign_stack_local (mode, size, mode == BLKmode ? -1 : 0);
736: p->next = temp_slots;
737: temp_slots = p;
738: }
739:
740: p->in_use = 1;
741: p->level = temp_slot_level;
742: p->keep = keep;
743: return p->slot;
744: }
745:
746: /* If X could be a reference to a temporary slot, mark that slot as belonging
747: to the to one level higher. If X matched one of our slots, just mark that
748: one. Otherwise, we can't easily predict which it is, so upgrade all of
749: them. Kept slots need not be touched.
750:
751: This is called when an ({...}) construct occurs and a statement
752: returns a value in memory. */
753:
754: void
755: preserve_temp_slots (x)
756: rtx x;
757: {
758: struct temp_slot *p;
759:
760: /* If X is not in memory or is at a constant address, it cannot be in
761: a temporary slot. */
762: if (x == 0 || GET_CODE (x) != MEM || CONSTANT_P (XEXP (x, 0)))
763: return;
764:
765: /* First see if we can find a match. */
766: for (p = temp_slots; p; p = p->next)
767: if (p->in_use && x == p->slot)
768: {
769: p->level--;
770: return;
771: }
772:
773: /* Otherwise, preserve all non-kept slots at this level. */
774: for (p = temp_slots; p; p = p->next)
775: if (p->in_use && p->level == temp_slot_level && ! p->keep)
776: p->level--;
777: }
778:
779: /* Free all temporaries used so far. This is normally called at the end
780: of generating code for a statement. */
781:
782: void
783: free_temp_slots ()
784: {
785: struct temp_slot *p;
786:
787: for (p = temp_slots; p; p = p->next)
788: if (p->in_use && p->level == temp_slot_level && ! p->keep)
789: p->in_use = 0;
790: }
791:
792: /* Push deeper into the nesting level for stack temporaries. */
793:
794: void
795: push_temp_slots ()
796: {
797: /* For GNU C++, we must allow a sequence to be emitted anywhere in
798: the level where the sequence was started. By not changing levels
799: when the compiler is inside a sequence, the temporaries for the
800: sequence and the temporaries will not unwittingly conflict with
801: the temporaries for other sequences and/or code at that level. */
802: if (in_sequence_p ())
803: return;
804:
805: temp_slot_level++;
806: }
807:
808: /* Pop a temporary nesting level. All slots in use in the current level
809: are freed. */
810:
811: void
812: pop_temp_slots ()
813: {
814: struct temp_slot *p;
815:
816: /* See comment in push_temp_slots about why we don't change levels
817: in sequences. */
818: if (in_sequence_p ())
819: return;
820:
821: for (p = temp_slots; p; p = p->next)
822: if (p->in_use && p->level == temp_slot_level)
823: p->in_use = 0;
824:
825: temp_slot_level--;
826: }
827:
828: /* Retroactively move an auto variable from a register to a stack slot.
829: This is done when an address-reference to the variable is seen. */
830:
831: void
832: put_var_into_stack (decl)
833: tree decl;
834: {
835: register rtx reg;
836: register rtx new = 0;
837: struct function *function = 0;
838: tree context = decl_function_context (decl);
839:
840: /* Get the current rtl used for this object. */
841: reg = TREE_CODE (decl) == SAVE_EXPR ? SAVE_EXPR_RTL (decl) : DECL_RTL (decl);
842:
843: /* If this variable comes from an outer function,
844: find that function's saved context. */
845: if (context != current_function_decl)
846: for (function = outer_function_chain; function; function = function->next)
847: if (function->decl == context)
848: break;
849:
850: /* No need to do anything if decl has no rtx yet
851: since in that case caller is setting TREE_ADDRESSABLE
852: and a stack slot will be assigned when the rtl is made. */
853: if (reg == 0)
854: return;
855:
856: /* If this is a variable-size object with a pseudo to address it,
857: put that pseudo into the stack, if the var is nonlocal. */
858: if (TREE_NONLOCAL (decl)
859: && GET_CODE (reg) == MEM
860: && GET_CODE (XEXP (reg, 0)) == REG
861: && REGNO (XEXP (reg, 0)) > LAST_VIRTUAL_REGISTER)
862: reg = XEXP (reg, 0);
863: if (GET_CODE (reg) != REG)
864: return;
865:
866: if (function)
867: {
868: if (REGNO (reg) < function->max_parm_reg)
869: new = function->parm_reg_stack_loc[REGNO (reg)];
870: if (new == 0)
871: new = assign_outer_stack_local (GET_MODE (reg),
872: GET_MODE_SIZE (GET_MODE (reg)),
873: 0, function);
874: }
875: else
876: {
877: if (REGNO (reg) < max_parm_reg)
878: new = parm_reg_stack_loc[REGNO (reg)];
879: if (new == 0)
880: new = assign_stack_local (GET_MODE (reg),
881: GET_MODE_SIZE (GET_MODE (reg)),
882: 0);
883: }
884:
885: XEXP (reg, 0) = XEXP (new, 0);
886: /* `volatil' bit means one thing for MEMs, another entirely for REGs. */
887: REG_USERVAR_P (reg) = 0;
888: PUT_CODE (reg, MEM);
889:
890: /* If this is a memory ref that contains aggregate components,
891: mark it as such for cse and loop optimize. */
892: MEM_IN_STRUCT_P (reg)
893: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
894: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
895: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
896:
897: /* Now make sure that all refs to the variable, previously made
898: when it was a register, are fixed up to be valid again. */
899: if (function)
900: {
901: struct var_refs_queue *temp;
902:
903: /* Variable is inherited; fix it up when we get back to its function. */
904: push_obstacks (function->function_obstack,
905: function->function_maybepermanent_obstack);
906: temp
907: = (struct var_refs_queue *) oballoc (sizeof (struct var_refs_queue));
908: temp->modified = reg;
909: temp->next = function->fixup_var_refs_queue;
910: function->fixup_var_refs_queue = temp;
911: pop_obstacks ();
912: }
913: else
914: /* Variable is local; fix it up now. */
915: fixup_var_refs (reg);
916: }
917:
918: static void
919: fixup_var_refs (var)
920: rtx var;
921: {
922: tree pending;
923: rtx first_insn = get_insns ();
924: struct sequence_stack *stack = sequence_stack;
925: tree rtl_exps = rtl_expr_chain;
926:
927: /* Must scan all insns for stack-refs that exceed the limit. */
928: fixup_var_refs_insns (var, first_insn, stack == 0);
929:
930: /* Scan all pending sequences too. */
931: for (; stack; stack = stack->next)
932: {
933: push_to_sequence (stack->first);
934: fixup_var_refs_insns (var, stack->first, stack->next != 0);
935: /* Update remembered end of sequence
936: in case we added an insn at the end. */
937: stack->last = get_last_insn ();
938: end_sequence ();
939: }
940:
941: /* Scan all waiting RTL_EXPRs too. */
942: for (pending = rtl_exps; pending; pending = TREE_CHAIN (pending))
943: {
944: rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
945: if (seq != const0_rtx && seq != 0)
946: {
947: push_to_sequence (seq);
948: fixup_var_refs_insns (var, seq, 0);
949: end_sequence ();
950: }
951: }
952: }
953:
954: /* This structure is used by the following two functions to record MEMs or
955: pseudos used to replace VAR, any SUBREGs of VAR, and any MEMs containing
956: VAR as an address. We need to maintain this list in case two operands of
957: an insn were required to match; in that case we must ensure we use the
958: same replacement. */
959:
960: struct fixup_replacement
961: {
962: rtx old;
963: rtx new;
964: struct fixup_replacement *next;
965: };
966:
967: /* REPLACEMENTS is a pointer to a list of the above structures and X is
968: some part of an insn. Return a struct fixup_replacement whose OLD
969: value is equal to X. Allocate a new structure if no such entry exists. */
970:
971: static struct fixup_replacement *
972: find_replacement (replacements, x)
973: struct fixup_replacement **replacements;
974: rtx x;
975: {
976: struct fixup_replacement *p;
977:
978: /* See if we have already replaced this. */
979: for (p = *replacements; p && p->old != x; p = p->next)
980: ;
981:
982: if (p == 0)
983: {
984: p = (struct fixup_replacement *) oballoc (sizeof (struct fixup_replacement));
985: p->old = x;
986: p->new = 0;
987: p->next = *replacements;
988: *replacements = p;
989: }
990:
991: return p;
992: }
993:
994: /* Scan the insn-chain starting with INSN for refs to VAR
995: and fix them up. TOPLEVEL is nonzero if this chain is the
996: main chain of insns for the current function. */
997:
998: static void
999: fixup_var_refs_insns (var, insn, toplevel)
1000: rtx var;
1001: rtx insn;
1002: int toplevel;
1003: {
1004: while (insn)
1005: {
1006: rtx next = NEXT_INSN (insn);
1007: rtx note;
1008: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
1009: || GET_CODE (insn) == JUMP_INSN)
1010: {
1011: /* The insn to load VAR from a home in the arglist
1012: is now a no-op. When we see it, just delete it. */
1013: if (toplevel
1014: && GET_CODE (PATTERN (insn)) == SET
1015: && SET_DEST (PATTERN (insn)) == var
1016: && rtx_equal_p (SET_SRC (PATTERN (insn)), var))
1017: {
1018: next = delete_insn (insn);
1019: if (insn == last_parm_insn)
1020: last_parm_insn = PREV_INSN (next);
1021: }
1022: else
1023: {
1024: /* See if we have to do anything to INSN now that VAR is in
1025: memory. If it needs to be loaded into a pseudo, use a single
1026: pseudo for the entire insn in case there is a MATCH_DUP
1027: between two operands. We pass a pointer to the head of
1028: a list of struct fixup_replacements. If fixup_var_refs_1
1029: needs to allocate pseudos or replacement MEMs (for SUBREGs),
1030: it will record them in this list.
1031:
1032: If it allocated a pseudo for any replacement, we copy into
1033: it here. */
1034:
1035: struct fixup_replacement *replacements = 0;
1036:
1037: fixup_var_refs_1 (var, &PATTERN (insn), insn, &replacements);
1038:
1039: while (replacements)
1040: {
1041: if (GET_CODE (replacements->new) == REG)
1042: {
1043: rtx insert_before;
1044:
1045: /* OLD might be a (subreg (mem)). */
1046: if (GET_CODE (replacements->old) == SUBREG)
1047: replacements->old
1048: = fixup_memory_subreg (replacements->old, insn, 0);
1049: else
1050: replacements->old
1051: = fixup_stack_1 (replacements->old, insn);
1052:
1053: /* We can not separate USE insns from the CALL_INSN
1054: that they belong to. If this is a CALL_INSN, insert
1055: the move insn before the USE insns preceeding it
1056: instead of immediately before the insn. */
1057: if (GET_CODE (insn) == CALL_INSN)
1058: {
1059: insert_before = insn;
1060: while (GET_CODE (PREV_INSN (insert_before)) == INSN
1061: && GET_CODE (PATTERN (PREV_INSN (insert_before))) == USE)
1062: insert_before = PREV_INSN (insert_before);
1063: }
1064: else
1065: insert_before = insn;
1066:
1067: emit_insn_before (gen_move_insn (replacements->new,
1068: replacements->old),
1069: insert_before);
1070: }
1071:
1072: replacements = replacements->next;
1073: }
1074: }
1075:
1076: /* Also fix up any invalid exprs in the REG_NOTES of this insn.
1077: But don't touch other insns referred to by reg-notes;
1078: we will get them elsewhere. */
1079: for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1080: if (GET_CODE (note) != INSN_LIST)
1081: XEXP (note, 0) = walk_fixup_memory_subreg (XEXP (note, 0), insn);
1082: }
1083: insn = next;
1084: }
1085: }
1086:
1087: /* VAR is a MEM that used to be a pseudo register. See if the rtx expression
1088: at *LOC in INSN needs to be changed.
1089:
1090: REPLACEMENTS is a pointer to a list head that starts out zero, but may
1091: contain a list of original rtx's and replacements. If we find that we need
1092: to modify this insn by replacing a memory reference with a pseudo or by
1093: making a new MEM to implement a SUBREG, we consult that list to see if
1094: we have already chosen a replacement. If none has already been allocated,
1095: we allocate it and update the list. fixup_var_refs_insns will copy VAR
1096: or the SUBREG, as appropriate, to the pseudo. */
1097:
1098: static void
1099: fixup_var_refs_1 (var, loc, insn, replacements)
1100: register rtx var;
1101: register rtx *loc;
1102: rtx insn;
1103: struct fixup_replacement **replacements;
1104: {
1105: register int i;
1106: register rtx x = *loc;
1107: RTX_CODE code = GET_CODE (x);
1108: register char *fmt;
1109: register rtx tem, tem1;
1110: struct fixup_replacement *replacement;
1111:
1112: switch (code)
1113: {
1114: case MEM:
1115: if (var == x)
1116: {
1117: /* If we already have a replacement, use it. Otherwise,
1118: try to fix up this address in case it is invalid. */
1119:
1120: replacement = find_replacement (replacements, var);
1121: if (replacement->new)
1122: {
1123: *loc = replacement->new;
1124: return;
1125: }
1126:
1127: *loc = replacement->new = x = fixup_stack_1 (x, insn);
1128:
1129: /* Unless we are forcing memory to register, we can leave things
1130: the way they are if the insn is valid. */
1131:
1132: INSN_CODE (insn) = -1;
1133: if (! flag_force_mem && recog_memoized (insn) >= 0)
1134: return;
1135:
1136: *loc = replacement->new = gen_reg_rtx (GET_MODE (x));
1137: return;
1138: }
1139:
1140: /* If X contains VAR, we need to unshare it here so that we update
1141: each occurrence separately. But all identical MEMs in one insn
1142: must be replaced with the same rtx because of the possibility of
1143: MATCH_DUPs. */
1144:
1145: if (reg_mentioned_p (var, x))
1146: {
1147: replacement = find_replacement (replacements, x);
1148: if (replacement->new == 0)
1149: replacement->new = copy_most_rtx (x, var);
1150:
1151: *loc = x = replacement->new;
1152: }
1153: break;
1154:
1155: case REG:
1156: case CC0:
1157: case PC:
1158: case CONST_INT:
1159: case CONST:
1160: case SYMBOL_REF:
1161: case LABEL_REF:
1162: case CONST_DOUBLE:
1163: return;
1164:
1165: case SIGN_EXTRACT:
1166: case ZERO_EXTRACT:
1167: /* Note that in some cases those types of expressions are altered
1168: by optimize_bit_field, and do not survive to get here. */
1169: if (XEXP (x, 0) == var
1170: || (GET_CODE (XEXP (x, 0)) == SUBREG
1171: && SUBREG_REG (XEXP (x, 0)) == var))
1172: {
1173: /* Get TEM as a valid MEM in the mode presently in the insn.
1174:
1175: We don't worry about the possibility of MATCH_DUP here; it
1176: is highly unlikely and would be tricky to handle. */
1177:
1178: tem = XEXP (x, 0);
1179: if (GET_CODE (tem) == SUBREG)
1180: tem = fixup_memory_subreg (tem, insn, 1);
1181: tem = fixup_stack_1 (tem, insn);
1182:
1183: /* Unless we want to load from memory, get TEM into the proper mode
1184: for an extract from memory. This can only be done if the
1185: extract is at a constant position and length. */
1186:
1187: if (! flag_force_mem && GET_CODE (XEXP (x, 1)) == CONST_INT
1188: && GET_CODE (XEXP (x, 2)) == CONST_INT
1189: && ! mode_dependent_address_p (XEXP (tem, 0))
1190: && ! MEM_VOLATILE_P (tem))
1191: {
1192: enum machine_mode wanted_mode = VOIDmode;
1193: enum machine_mode is_mode = GET_MODE (tem);
1194: int width = INTVAL (XEXP (x, 1));
1195: int pos = INTVAL (XEXP (x, 2));
1196:
1197: #ifdef HAVE_extzv
1198: if (GET_CODE (x) == ZERO_EXTRACT)
1199: wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
1200: #endif
1201: #ifdef HAVE_extv
1202: if (GET_CODE (x) == SIGN_EXTRACT)
1203: wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
1204: #endif
1205: /* If we have a narrower mode, we can do someting. */
1206: if (wanted_mode != VOIDmode
1207: && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
1208: {
1209: int offset = pos / BITS_PER_UNIT;
1210: rtx old_pos = XEXP (x, 2);
1211: rtx newmem;
1212:
1213: /* If the bytes and bits are counted differently, we
1214: must adjust the offset. */
1215: #if BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
1216: offset = (GET_MODE_SIZE (is_mode)
1217: - GET_MODE_SIZE (wanted_mode) - offset);
1218: #endif
1219:
1220: pos %= GET_MODE_BITSIZE (wanted_mode);
1221:
1222: newmem = gen_rtx (MEM, wanted_mode,
1223: plus_constant (XEXP (tem, 0), offset));
1224: RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
1225: MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
1226: MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
1227:
1228: /* Make the change and see if the insn remains valid. */
1229: INSN_CODE (insn) = -1;
1230: XEXP (x, 0) = newmem;
1231: XEXP (x, 2) = gen_rtx (CONST_INT, VOIDmode, pos);
1232:
1233: if (recog_memoized (insn) >= 0)
1234: return;
1235:
1236: /* Otherwise, restore old position. XEXP (x, 0) will be
1237: restored later. */
1238: XEXP (x, 2) = old_pos;
1239: }
1240: }
1241:
1242: /* If we get here, the bitfield extract insn can't accept a memory
1243: reference. Copy the input into a register. */
1244:
1245: tem1 = gen_reg_rtx (GET_MODE (tem));
1246: emit_insn_before (gen_move_insn (tem1, tem), insn);
1247: XEXP (x, 0) = tem1;
1248: return;
1249: }
1250: break;
1251:
1252: case SUBREG:
1253: if (SUBREG_REG (x) == var)
1254: {
1255: /* If this SUBREG makes VAR wider, it has become a paradoxical
1256: SUBREG with VAR in memory, but these aren't allowed at this
1257: stage of the compilation. So load VAR into a pseudo and take
1258: a SUBREG of that pseudo. */
1259: if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (var)))
1260: {
1261: replacement = find_replacement (replacements, var);
1262: if (replacement->new == 0)
1263: replacement->new = gen_reg_rtx (GET_MODE (var));
1264: SUBREG_REG (x) = replacement->new;
1265: return;
1266: }
1267:
1268: /* See if we have already found a replacement for this SUBREG.
1269: If so, use it. Otherwise, make a MEM and see if the insn
1270: is recognized. If not, or if we should force MEM into a register,
1271: make a pseudo for this SUBREG. */
1272: replacement = find_replacement (replacements, x);
1273: if (replacement->new)
1274: {
1275: *loc = replacement->new;
1276: return;
1277: }
1278:
1279: replacement->new = *loc = fixup_memory_subreg (x, insn, 0);
1280:
1281: if (! flag_force_mem && recog_memoized (insn) >= 0)
1282: return;
1283:
1284: *loc = replacement->new = gen_reg_rtx (GET_MODE (x));
1285: return;
1286: }
1287: break;
1288:
1289: case SET:
1290: /* First do special simplification of bit-field references. */
1291: if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
1292: || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
1293: optimize_bit_field (x, insn, 0);
1294: if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
1295: || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
1296: optimize_bit_field (x, insn, 0);
1297:
1298: /* If SET_DEST is now a paradoxical SUBREG, put the result of this
1299: insn into a pseudo and store the low part of the pseudo into VAR. */
1300: if (GET_CODE (SET_DEST (x)) == SUBREG
1301: && SUBREG_REG (SET_DEST (x)) == var
1302: && (GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
1303: > GET_MODE_SIZE (GET_MODE (var))))
1304: {
1305: SET_DEST (x) = tem = gen_reg_rtx (GET_MODE (SET_DEST (x)));
1306: emit_insn_after (gen_move_insn (var, gen_lowpart (GET_MODE (var),
1307: tem)),
1308: insn);
1309: break;
1310: }
1311:
1312: {
1313: rtx dest = SET_DEST (x);
1314: rtx src = SET_SRC (x);
1315: rtx outerdest = dest;
1316:
1317: while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
1318: || GET_CODE (dest) == SIGN_EXTRACT
1319: || GET_CODE (dest) == ZERO_EXTRACT)
1320: dest = XEXP (dest, 0);
1321:
1322: if (GET_CODE (src) == SUBREG)
1323: src = XEXP (src, 0);
1324:
1325: /* If VAR does not appear at the top level of the SET
1326: just scan the lower levels of the tree. */
1327:
1328: if (src != var && dest != var)
1329: break;
1330:
1331: /* We will need to rerecognize this insn. */
1332: INSN_CODE (insn) = -1;
1333:
1334: #ifdef HAVE_insv
1335: if (GET_CODE (outerdest) == ZERO_EXTRACT && dest == var)
1336: {
1337: /* Since this case will return, ensure we fixup all the
1338: operands here. */
1339: fixup_var_refs_1 (var, &XEXP (outerdest, 1), insn, replacements);
1340: fixup_var_refs_1 (var, &XEXP (outerdest, 2), insn, replacements);
1341: fixup_var_refs_1 (var, &SET_SRC (x), insn, replacements);
1342:
1343: tem = XEXP (outerdest, 0);
1344:
1345: /* Clean up (SUBREG:SI (MEM:mode ...) 0)
1346: that may appear inside a ZERO_EXTRACT.
1347: This was legitimate when the MEM was a REG. */
1348: if (GET_CODE (tem) == SUBREG
1349: && SUBREG_REG (tem) == var)
1350: tem = fixup_memory_subreg (tem, insn, 1);
1351: else
1352: tem = fixup_stack_1 (tem, insn);
1353:
1354: if (GET_CODE (XEXP (outerdest, 1)) == CONST_INT
1355: && GET_CODE (XEXP (outerdest, 2)) == CONST_INT
1356: && ! mode_dependent_address_p (XEXP (tem, 0))
1357: && ! MEM_VOLATILE_P (tem))
1358: {
1359: enum machine_mode wanted_mode
1360: = insn_operand_mode[(int) CODE_FOR_insv][0];
1361: enum machine_mode is_mode = GET_MODE (tem);
1362: int width = INTVAL (XEXP (outerdest, 1));
1363: int pos = INTVAL (XEXP (outerdest, 2));
1364:
1365: /* If we have a narrower mode, we can do someting. */
1366: if (GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
1367: {
1368: int offset = pos / BITS_PER_UNIT;
1369: rtx old_pos = XEXP (outerdest, 2);
1370: rtx newmem;
1371:
1372: #if BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
1373: offset = (GET_MODE_SIZE (is_mode)
1374: - GET_MODE_SIZE (wanted_mode) - offset);
1375: #endif
1376:
1377: pos %= GET_MODE_BITSIZE (wanted_mode);
1378:
1379: newmem = gen_rtx (MEM, wanted_mode,
1380: plus_constant (XEXP (tem, 0), offset));
1381: RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (tem);
1382: MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (tem);
1383: MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (tem);
1384:
1385: /* Make the change and see if the insn remains valid. */
1386: INSN_CODE (insn) = -1;
1387: XEXP (outerdest, 0) = newmem;
1388: XEXP (outerdest, 2) = gen_rtx (CONST_INT, VOIDmode, pos);
1389:
1390: if (recog_memoized (insn) >= 0)
1391: return;
1392:
1393: /* Otherwise, restore old position. XEXP (x, 0) will be
1394: restored later. */
1395: XEXP (outerdest, 2) = old_pos;
1396: }
1397: }
1398:
1399: /* If we get here, the bit-field store doesn't allow memory
1400: or isn't located at a constant position. Load the value into
1401: a register, do the store, and put it back into memory. */
1402:
1403: tem1 = gen_reg_rtx (GET_MODE (tem));
1404: emit_insn_before (gen_move_insn (tem1, tem), insn);
1405: emit_insn_after (gen_move_insn (tem, tem1), insn);
1406: XEXP (outerdest, 0) = tem1;
1407: return;
1408: }
1409: #endif
1410:
1411: /* STRICT_LOW_PART is a no-op on memory references
1412: and it can cause combinations to be unrecognizable,
1413: so eliminate it. */
1414:
1415: if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
1416: SET_DEST (x) = XEXP (SET_DEST (x), 0);
1417:
1418: /* A valid insn to copy VAR into or out of a register
1419: must be left alone, to avoid an infinite loop here.
1420: If the reference to VAR is by a subreg, fix that up,
1421: since SUBREG is not valid for a memref.
1422: Also fix up the address of the stack slot. */
1423:
1424: if ((SET_SRC (x) == var
1425: || (GET_CODE (SET_SRC (x)) == SUBREG
1426: && SUBREG_REG (SET_SRC (x)) == var))
1427: && (GET_CODE (SET_DEST (x)) == REG
1428: || (GET_CODE (SET_DEST (x)) == SUBREG
1429: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
1430: && recog_memoized (insn) >= 0)
1431: {
1432: replacement = find_replacement (replacements, SET_SRC (x));
1433: if (replacement->new)
1434: {
1435: SET_SRC (x) = replacement->new;
1436: return;
1437: }
1438: else if (GET_CODE (SET_SRC (x)) == SUBREG)
1439: SET_SRC (x) = replacement->new
1440: = fixup_memory_subreg (SET_SRC (x), insn, 0);
1441: else
1442: SET_SRC (x) = replacement->new
1443: = fixup_stack_1 (SET_SRC (x), insn);
1444: return;
1445: }
1446:
1447: if ((SET_DEST (x) == var
1448: || (GET_CODE (SET_DEST (x)) == SUBREG
1449: && SUBREG_REG (SET_DEST (x)) == var))
1450: && (GET_CODE (SET_SRC (x)) == REG
1451: || (GET_CODE (SET_SRC (x)) == SUBREG
1452: && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG))
1453: && recog_memoized (insn) >= 0)
1454: {
1455: if (GET_CODE (SET_DEST (x)) == SUBREG)
1456: SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn, 0);
1457: else
1458: SET_DEST (x) = fixup_stack_1 (SET_DEST (x), insn);
1459: return;
1460: }
1461:
1462: /* Otherwise, storing into VAR must be handled specially
1463: by storing into a temporary and copying that into VAR
1464: with a new insn after this one. */
1465:
1466: if (dest == var)
1467: {
1468: rtx temp;
1469: rtx fixeddest;
1470: tem = SET_DEST (x);
1471: /* STRICT_LOW_PART can be discarded, around a MEM. */
1472: if (GET_CODE (tem) == STRICT_LOW_PART)
1473: tem = XEXP (tem, 0);
1474: /* Convert (SUBREG (MEM)) to a MEM in a changed mode. */
1475: if (GET_CODE (tem) == SUBREG)
1476: fixeddest = fixup_memory_subreg (tem, insn, 0);
1477: else
1478: fixeddest = fixup_stack_1 (tem, insn);
1479:
1480: temp = gen_reg_rtx (GET_MODE (tem));
1481: emit_insn_after (gen_move_insn (fixeddest, temp), insn);
1482: SET_DEST (x) = temp;
1483: }
1484: }
1485: }
1486:
1487: /* Nothing special about this RTX; fix its operands. */
1488:
1489: fmt = GET_RTX_FORMAT (code);
1490: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1491: {
1492: if (fmt[i] == 'e')
1493: fixup_var_refs_1 (var, &XEXP (x, i), insn, replacements);
1494: if (fmt[i] == 'E')
1495: {
1496: register int j;
1497: for (j = 0; j < XVECLEN (x, i); j++)
1498: fixup_var_refs_1 (var, &XVECEXP (x, i, j), insn, replacements);
1499: }
1500: }
1501: }
1502:
1503: /* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
1504: return an rtx (MEM:m1 newaddr) which is equivalent.
1505: If any insns must be emitted to compute NEWADDR, put them before INSN.
1506:
1507: UNCRITICAL nonzero means accept paradoxical subregs.
1508: This is used for subregs found inside of ZERO_EXTRACTs. */
1509:
1510: static rtx
1511: fixup_memory_subreg (x, insn, uncritical)
1512: rtx x;
1513: rtx insn;
1514: int uncritical;
1515: {
1516: int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
1517: rtx addr = XEXP (SUBREG_REG (x), 0);
1518: enum machine_mode mode = GET_MODE (x);
1519: rtx saved, result;
1520:
1521: /* Paradoxical SUBREGs are usually invalid during RTL generation. */
1522: if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
1523: && ! uncritical)
1524: abort ();
1525:
1526: #if BYTES_BIG_ENDIAN
1527: offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1528: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
1529: #endif
1530: addr = plus_constant (addr, offset);
1531: if (!flag_force_addr && memory_address_p (mode, addr))
1532: /* Shortcut if no insns need be emitted. */
1533: return change_address (SUBREG_REG (x), mode, addr);
1534: start_sequence ();
1535: result = change_address (SUBREG_REG (x), mode, addr);
1536: emit_insn_before (gen_sequence (), insn);
1537: end_sequence ();
1538: return result;
1539: }
1540:
1541: /* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
1542: Replace subexpressions of X in place.
1543: If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
1544: Otherwise return X, with its contents possibly altered.
1545:
1546: If any insns must be emitted to compute NEWADDR, put them before INSN. */
1547:
1548: static rtx
1549: walk_fixup_memory_subreg (x, insn)
1550: register rtx x;
1551: rtx insn;
1552: {
1553: register enum rtx_code code;
1554: register char *fmt;
1555: register int i;
1556:
1557: if (x == 0)
1558: return 0;
1559:
1560: code = GET_CODE (x);
1561:
1562: if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
1563: return fixup_memory_subreg (x, insn, 0);
1564:
1565: /* Nothing special about this RTX; fix its operands. */
1566:
1567: fmt = GET_RTX_FORMAT (code);
1568: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1569: {
1570: if (fmt[i] == 'e')
1571: XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn);
1572: if (fmt[i] == 'E')
1573: {
1574: register int j;
1575: for (j = 0; j < XVECLEN (x, i); j++)
1576: XVECEXP (x, i, j)
1577: = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn);
1578: }
1579: }
1580: return x;
1581: }
1582:
1583: #if 0
1584: /* Fix up any references to stack slots that are invalid memory addresses
1585: because they exceed the maximum range of a displacement. */
1586:
1587: void
1588: fixup_stack_slots ()
1589: {
1590: register rtx insn;
1591:
1592: /* Did we generate a stack slot that is out of range
1593: or otherwise has an invalid address? */
1594: if (invalid_stack_slot)
1595: {
1596: /* Yes. Must scan all insns for stack-refs that exceed the limit. */
1597: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1598: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
1599: || GET_CODE (insn) == JUMP_INSN)
1600: fixup_stack_1 (PATTERN (insn), insn);
1601: }
1602: }
1603: #endif
1604:
1605: /* For each memory ref within X, if it refers to a stack slot
1606: with an out of range displacement, put the address in a temp register
1607: (emitting new insns before INSN to load these registers)
1608: and alter the memory ref to use that register.
1609: Replace each such MEM rtx with a copy, to avoid clobberage. */
1610:
1611: static rtx
1612: fixup_stack_1 (x, insn)
1613: rtx x;
1614: rtx insn;
1615: {
1616: register int i;
1617: register RTX_CODE code = GET_CODE (x);
1618: register char *fmt;
1619:
1620: if (code == MEM)
1621: {
1622: register rtx ad = XEXP (x, 0);
1623: /* If we have address of a stack slot but it's not valid
1624: (displacement is too large), compute the sum in a register. */
1625: if (GET_CODE (ad) == PLUS
1626: && GET_CODE (XEXP (ad, 0)) == REG
1627: && REGNO (XEXP (ad, 0)) >= FIRST_VIRTUAL_REGISTER
1628: && REGNO (XEXP (ad, 0)) <= LAST_VIRTUAL_REGISTER
1629: && GET_CODE (XEXP (ad, 1)) == CONST_INT)
1630: {
1631: rtx temp, seq;
1632: if (memory_address_p (GET_MODE (x), ad))
1633: return x;
1634:
1635: start_sequence ();
1636: temp = copy_to_reg (ad);
1637: seq = gen_sequence ();
1638: end_sequence ();
1639: emit_insn_before (seq, insn);
1640: return change_address (x, VOIDmode, temp);
1641: }
1642: return x;
1643: }
1644:
1645: fmt = GET_RTX_FORMAT (code);
1646: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1647: {
1648: if (fmt[i] == 'e')
1649: XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
1650: if (fmt[i] == 'E')
1651: {
1652: register int j;
1653: for (j = 0; j < XVECLEN (x, i); j++)
1654: XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
1655: }
1656: }
1657: return x;
1658: }
1659:
1660: /* Optimization: a bit-field instruction whose field
1661: happens to be a byte or halfword in memory
1662: can be changed to a move instruction.
1663:
1664: We call here when INSN is an insn to examine or store into a bit-field.
1665: BODY is the SET-rtx to be altered.
1666:
1667: EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
1668: (Currently this is called only from function.c, and EQUIV_MEM
1669: is always 0.) */
1670:
1671: static void
1672: optimize_bit_field (body, insn, equiv_mem)
1673: rtx body;
1674: rtx insn;
1675: rtx *equiv_mem;
1676: {
1677: register rtx bitfield;
1678: int destflag;
1679: rtx seq = 0;
1680: enum machine_mode mode;
1681:
1682: if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
1683: || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
1684: bitfield = SET_DEST (body), destflag = 1;
1685: else
1686: bitfield = SET_SRC (body), destflag = 0;
1687:
1688: /* First check that the field being stored has constant size and position
1689: and is in fact a byte or halfword suitably aligned. */
1690:
1691: if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
1692: && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
1693: && ((mode = mode_for_size (INTVAL (XEXP (bitfield, 1)), MODE_INT, 1))
1694: != BLKmode)
1695: && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
1696: {
1697: register rtx memref = 0;
1698:
1699: /* Now check that the containing word is memory, not a register,
1700: and that it is safe to change the machine mode. */
1701:
1702: if (GET_CODE (XEXP (bitfield, 0)) == MEM)
1703: memref = XEXP (bitfield, 0);
1704: else if (GET_CODE (XEXP (bitfield, 0)) == REG
1705: && equiv_mem != 0)
1706: memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
1707: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
1708: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
1709: memref = SUBREG_REG (XEXP (bitfield, 0));
1710: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
1711: && equiv_mem != 0
1712: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
1713: memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];
1714:
1715: if (memref
1716: && ! mode_dependent_address_p (XEXP (memref, 0))
1717: && ! MEM_VOLATILE_P (memref))
1718: {
1719: /* Now adjust the address, first for any subreg'ing
1720: that we are now getting rid of,
1721: and then for which byte of the word is wanted. */
1722:
1723: register int offset = INTVAL (XEXP (bitfield, 2));
1724: /* Adjust OFFSET to count bits from low-address byte. */
1725: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
1726: offset = (GET_MODE_BITSIZE (GET_MODE (XEXP (bitfield, 0)))
1727: - offset - INTVAL (XEXP (bitfield, 1)));
1728: #endif
1729: /* Adjust OFFSET to count bytes from low-address byte. */
1730: offset /= BITS_PER_UNIT;
1731: if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
1732: {
1733: offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
1734: #if BYTES_BIG_ENDIAN
1735: offset -= (MIN (UNITS_PER_WORD,
1736: GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
1737: - MIN (UNITS_PER_WORD,
1738: GET_MODE_SIZE (GET_MODE (memref))));
1739: #endif
1740: }
1741:
1742: memref = change_address (memref, mode,
1743: plus_constant (XEXP (memref, 0), offset));
1744:
1745: /* Store this memory reference where
1746: we found the bit field reference. */
1747:
1748: if (destflag)
1749: {
1750: validate_change (insn, &SET_DEST (body), memref, 1);
1751: if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
1752: {
1753: rtx src = SET_SRC (body);
1754: while (GET_CODE (src) == SUBREG
1755: && SUBREG_WORD (src) == 0)
1756: src = SUBREG_REG (src);
1757: if (GET_MODE (src) != GET_MODE (memref))
1758: src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
1759: validate_change (insn, &SET_SRC (body), src, 1);
1760: }
1761: else if (GET_MODE (SET_SRC (body)) != VOIDmode
1762: && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
1763: /* This shouldn't happen because anything that didn't have
1764: one of these modes should have got converted explicitly
1765: and then referenced through a subreg.
1766: This is so because the original bit-field was
1767: handled by agg_mode and so its tree structure had
1768: the same mode that memref now has. */
1769: abort ();
1770: }
1771: else
1772: {
1773: rtx dest = SET_DEST (body);
1774:
1775: while (GET_CODE (dest) == SUBREG
1776: && SUBREG_WORD (dest) == 0)
1777: dest = SUBREG_REG (dest);
1778:
1779: validate_change (insn, &SET_DEST (body), dest, 1);
1780:
1781: if (GET_MODE (dest) == GET_MODE (memref))
1782: validate_change (insn, &SET_SRC (body), memref, 1);
1783: else
1784: {
1785: /* Convert the mem ref to the destination mode. */
1786: rtx newreg = gen_reg_rtx (GET_MODE (dest));
1787:
1788: start_sequence ();
1789: convert_move (newreg, memref,
1790: GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
1791: seq = get_insns ();
1792: end_sequence ();
1793:
1794: validate_change (insn, &SET_SRC (body), newreg, 1);
1795: }
1796: }
1797:
1798: /* See if we can convert this extraction or insertion into
1799: a simple move insn. We might not be able to do so if this
1800: was, for example, part of a PARALLEL.
1801:
1802: If we succeed, write out any needed conversions. If we fail,
1803: it is hard to guess why we failed, so don't do anything
1804: special; just let the optimization be suppressed. */
1805:
1806: if (apply_change_group () && seq)
1807: emit_insns_before (seq, insn);
1808: }
1809: }
1810: }
1811:
1812: /* These routines are responsible for converting virtual register references
1813: to the actual hard register references once RTL generation is complete.
1814:
1815: The following four variables are used for communication between the
1816: routines. They contain the offsets of the virtual registers from their
1817: respective hard registers. */
1818:
1819: static int in_arg_offset;
1820: static int var_offset;
1821: static int dynamic_offset;
1822: static int out_arg_offset;
1823:
1824: /* In most machines, the stack pointer register is equivalent to the bottom
1825: of the stack. */
1826:
1827: #ifndef STACK_POINTER_OFFSET
1828: #define STACK_POINTER_OFFSET 0
1829: #endif
1830:
1831: /* If not defined, pick an appropriate default for the offset of dynamically
1832: allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS,
1833: REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE. */
1834:
1835: #ifndef STACK_DYNAMIC_OFFSET
1836:
1837: #ifdef ACCUMULATE_OUTGOING_ARGS
1838: /* The bottom of the stack points to the actual arguments. If
1839: REG_PARM_STACK_SPACE is defined, this includes the space for the register
1840: parameters. However, if OUTGOING_REG_PARM_STACK space is not defined,
1841: stack space for register parameters is not pushed by the caller, but
1842: rather part of the fixed stack areas and hence not included in
1843: `current_function_outgoing_args_size'. Nevertheless, we must allow
1844: for it when allocating stack dynamic objects. */
1845:
1846: #if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
1847: #define STACK_DYNAMIC_OFFSET(FNDECL) \
1848: (current_function_outgoing_args_size \
1849: + REG_PARM_STACK_SPACE (FNDECL) + (STACK_POINTER_OFFSET))
1850:
1851: #else
1852: #define STACK_DYNAMIC_OFFSET(FNDECL) \
1853: (current_function_outgoing_args_size + (STACK_POINTER_OFFSET))
1854: #endif
1855:
1856: #else
1857: #define STACK_DYNAMIC_OFFSET(FNDECL) STACK_POINTER_OFFSET
1858: #endif
1859: #endif
1860:
1861: /* Pass through the INSNS of function FNDECL and convert virtual register
1862: references to hard register references. */
1863:
1864: void
1865: instantiate_virtual_regs (fndecl, insns)
1866: tree fndecl;
1867: rtx insns;
1868: {
1869: rtx insn;
1870:
1871: /* Compute the offsets to use for this function. */
1872: in_arg_offset = FIRST_PARM_OFFSET (fndecl);
1873: var_offset = STARTING_FRAME_OFFSET;
1874: dynamic_offset = STACK_DYNAMIC_OFFSET (fndecl);
1875: out_arg_offset = STACK_POINTER_OFFSET;
1876:
1877: /* Scan all variables and parameters of this function. For each that is
1878: in memory, instantiate all virtual registers if the result is a valid
1879: address. If not, we do it later. That will handle most uses of virtual
1880: regs on many machines. */
1881: instantiate_decls (fndecl, 1);
1882:
1883: /* Initialize recognition, indicating that volatile is OK. */
1884: init_recog ();
1885:
1886: /* Scan through all the insns, instantiating every virtual register still
1887: present. */
1888: for (insn = insns; insn; insn = NEXT_INSN (insn))
1889: if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
1890: || GET_CODE (insn) == CALL_INSN)
1891: {
1892: instantiate_virtual_regs_1 (&PATTERN (insn), insn, 1);
1893: instantiate_virtual_regs_1 (®_NOTES (insn), 0, 0);
1894: }
1895:
1896: /* Now instantiate the remaining register equivalences for debugging info.
1897: These will not be valid addresses. */
1898: instantiate_decls (fndecl, 0);
1899:
1900: /* Indicate that, from now on, assign_stack_local should use
1901: frame_pointer_rtx. */
1902: virtuals_instantiated = 1;
1903: }
1904:
1905: /* Scan all decls in FNDECL (both variables and parameters) and instantiate
1906: all virtual registers in their DECL_RTL's.
1907:
1908: If VALID_ONLY, do this only if the resulting address is still valid.
1909: Otherwise, always do it. */
1910:
1911: static void
1912: instantiate_decls (fndecl, valid_only)
1913: tree fndecl;
1914: int valid_only;
1915: {
1916: tree decl;
1917:
1918: if (TREE_INLINE (fndecl))
1919: /* When compiling an inline function, the obstack used for
1920: rtl allocation is the maybepermanent_obstack. Calling
1921: `resume_temporary_allocation' switches us back to that
1922: obstack while we process this function's parameters. */
1923: resume_temporary_allocation ();
1924:
1925: /* Process all parameters of the function. */
1926: for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
1927: {
1928: if (DECL_RTL (decl) && GET_CODE (DECL_RTL (decl)) == MEM)
1929: instantiate_virtual_regs_1 (&XEXP (DECL_RTL (decl), 0),
1930: valid_only ? DECL_RTL (decl) : 0, 0);
1931: #if 0 /* This is probably correct, but it seems to require fixes
1932: elsewhere in order to work. Let's fix them in 2.1. */
1933: if (DECL_INCOMING_RTL (decl)
1934: && GET_CODE (DECL_INCOMING_RTL (decl)) == MEM)
1935: instantiate_virtual_regs_1 (&XEXP (DECL_INCOMING_RTL (decl), 0),
1936: valid_only ? DECL_INCOMING_RTL (decl) : 0,
1937: 0);
1938: #endif
1939: }
1940:
1941: /* Now process all variables defined in the function or its subblocks. */
1942: instantiate_decls_1 (DECL_INITIAL (fndecl), valid_only);
1943:
1944: if (TREE_INLINE (fndecl))
1945: {
1946: /* Save all rtl allocated for this function by raising the
1947: high-water mark on the maybepermanent_obstack. */
1948: preserve_data ();
1949: /* All further rtl allocation is now done in the current_obstack. */
1950: rtl_in_current_obstack ();
1951: }
1952: }
1953:
1954: /* Subroutine of instantiate_decls: Process all decls in the given
1955: BLOCK node and all its subblocks. */
1956:
1957: static void
1958: instantiate_decls_1 (let, valid_only)
1959: tree let;
1960: int valid_only;
1961: {
1962: tree t;
1963:
1964: for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
1965: if (DECL_RTL (t) && GET_CODE (DECL_RTL (t)) == MEM)
1966: instantiate_virtual_regs_1 (& XEXP (DECL_RTL (t), 0),
1967: valid_only ? DECL_RTL (t) : 0, 0);
1968:
1969: /* Process all subblocks. */
1970: for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
1971: instantiate_decls_1 (t, valid_only);
1972: }
1973:
1974: /* Given a pointer to a piece of rtx and an optional pointer to the
1975: containing object, instantiate any virtual registers present in it.
1976:
1977: If EXTRA_INSNS, we always do the replacement and generate
1978: any extra insns before OBJECT. If it zero, we do nothing if replacement
1979: is not valid.
1980:
1981: Return 1 if we either had nothing to do or if we were able to do the
1982: needed replacement. Return 0 otherwise; we only return zero if
1983: EXTRA_INSNS is zero.
1984:
1985: We first try some simple transformations to avoid the creation of extra
1986: pseudos. */
1987:
1988: static int
1989: instantiate_virtual_regs_1 (loc, object, extra_insns)
1990: rtx *loc;
1991: rtx object;
1992: int extra_insns;
1993: {
1994: rtx x;
1995: RTX_CODE code;
1996: rtx new = 0;
1997: int offset;
1998: rtx temp;
1999: rtx seq;
2000: int i, j;
2001: char *fmt;
2002:
2003: /* Re-start here to avoid recursion in common cases. */
2004: restart:
2005:
2006: x = *loc;
2007: if (x == 0)
2008: return 1;
2009:
2010: code = GET_CODE (x);
2011:
2012: /* Check for some special cases. */
2013: switch (code)
2014: {
2015: case CONST_INT:
2016: case CONST_DOUBLE:
2017: case CONST:
2018: case SYMBOL_REF:
2019: case CODE_LABEL:
2020: case PC:
2021: case CC0:
2022: case ASM_INPUT:
2023: case ADDR_VEC:
2024: case ADDR_DIFF_VEC:
2025: case RETURN:
2026: return 1;
2027:
2028: case SET:
2029: /* We are allowed to set the virtual registers. This means that
2030: that the actual register should receive the source minus the
2031: appropriate offset. This is used, for example, in the handling
2032: of non-local gotos. */
2033: if (SET_DEST (x) == virtual_incoming_args_rtx)
2034: new = arg_pointer_rtx, offset = - in_arg_offset;
2035: else if (SET_DEST (x) == virtual_stack_vars_rtx)
2036: new = frame_pointer_rtx, offset = - var_offset;
2037: else if (SET_DEST (x) == virtual_stack_dynamic_rtx)
2038: new = stack_pointer_rtx, offset = - dynamic_offset;
2039: else if (SET_DEST (x) == virtual_outgoing_args_rtx)
2040: new = stack_pointer_rtx, offset = - out_arg_offset;
2041:
2042: if (new)
2043: {
2044: /* The only valid sources here are PLUS or REG. Just do
2045: the simplest possible thing to handle them. */
2046: if (GET_CODE (SET_SRC (x)) != REG
2047: && GET_CODE (SET_SRC (x)) != PLUS)
2048: abort ();
2049:
2050: start_sequence ();
2051: if (GET_CODE (SET_SRC (x)) != REG)
2052: temp = force_operand (SET_SRC (x), 0);
2053: else
2054: temp = SET_SRC (x);
2055: temp = force_operand (plus_constant (temp, offset), 0);
2056: seq = get_insns ();
2057: end_sequence ();
2058:
2059: emit_insns_before (seq, object);
2060: SET_DEST (x) = new;
2061:
2062: if (!validate_change (object, &SET_SRC (x), temp, 0)
2063: || ! extra_insns)
2064: abort ();
2065:
2066: return 1;
2067: }
2068:
2069: instantiate_virtual_regs_1 (&SET_DEST (x), object, extra_insns);
2070: loc = &SET_SRC (x);
2071: goto restart;
2072:
2073: case PLUS:
2074: /* Handle special case of virtual register plus constant. */
2075: if (CONSTANT_P (XEXP (x, 1)))
2076: {
2077: rtx old;
2078:
2079: /* Check for (plus (plus VIRT foo) (const_int)) first. */
2080: if (GET_CODE (XEXP (x, 0)) == PLUS)
2081: {
2082: rtx inner = XEXP (XEXP (x, 0), 0);
2083:
2084: if (inner == virtual_incoming_args_rtx)
2085: new = arg_pointer_rtx, offset = in_arg_offset;
2086: else if (inner == virtual_stack_vars_rtx)
2087: new = frame_pointer_rtx, offset = var_offset;
2088: else if (inner == virtual_stack_dynamic_rtx)
2089: new = stack_pointer_rtx, offset = dynamic_offset;
2090: else if (inner == virtual_outgoing_args_rtx)
2091: new = stack_pointer_rtx, offset = out_arg_offset;
2092: else
2093: {
2094: loc = &XEXP (x, 0);
2095: goto restart;
2096: }
2097:
2098: instantiate_virtual_regs_1 (&XEXP (XEXP (x, 0), 1), object,
2099: extra_insns);
2100: new = gen_rtx (PLUS, Pmode, new, XEXP (XEXP (x, 0), 1));
2101: }
2102:
2103: else if (XEXP (x, 0) == virtual_incoming_args_rtx)
2104: new = arg_pointer_rtx, offset = in_arg_offset;
2105: else if (XEXP (x, 0) == virtual_stack_vars_rtx)
2106: new = frame_pointer_rtx, offset = var_offset;
2107: else if (XEXP (x, 0) == virtual_stack_dynamic_rtx)
2108: new = stack_pointer_rtx, offset = dynamic_offset;
2109: else if (XEXP (x, 0) == virtual_outgoing_args_rtx)
2110: new = stack_pointer_rtx, offset = out_arg_offset;
2111: else
2112: {
2113: /* We know the second operand is a constant. Unless the
2114: first operand is a REG (which has been already checked),
2115: it needs to be checked. */
2116: if (GET_CODE (XEXP (x, 0)) != REG)
2117: {
2118: loc = &XEXP (x, 0);
2119: goto restart;
2120: }
2121: return 1;
2122: }
2123:
2124: old = XEXP (x, 0);
2125: XEXP (x, 0) = new;
2126: new = plus_constant (XEXP (x, 1), offset);
2127:
2128: /* If the new constant is zero, try to replace the sum with its
2129: first operand. */
2130: if (new == const0_rtx
2131: && validate_change (object, loc, XEXP (x, 0), 0))
2132: return 1;
2133:
2134: /* Next try to replace constant with new one. */
2135: if (!validate_change (object, &XEXP (x, 1), new, 0))
2136: {
2137: if (! extra_insns)
2138: {
2139: XEXP (x, 0) = old;
2140: return 0;
2141: }
2142:
2143: /* Otherwise copy the new constant into a register and replace
2144: constant with that register. */
2145: temp = gen_reg_rtx (Pmode);
2146: if (validate_change (object, &XEXP (x, 1), temp, 0))
2147: emit_insn_before (gen_move_insn (temp, new), object);
2148: else
2149: {
2150: /* If that didn't work, replace this expression with a
2151: register containing the sum. */
2152:
2153: new = gen_rtx (PLUS, Pmode, XEXP (x, 0), new);
2154: XEXP (x, 0) = old;
2155:
2156: start_sequence ();
2157: temp = force_operand (new, 0);
2158: seq = get_insns ();
2159: end_sequence ();
2160:
2161: emit_insns_before (seq, object);
2162: if (! validate_change (object, loc, temp, 0)
2163: && ! validate_replace_rtx (x, temp, object))
2164: abort ();
2165: }
2166: }
2167:
2168: return 1;
2169: }
2170:
2171: /* Fall through to generic two-operand expression case. */
2172: case EXPR_LIST:
2173: case CALL:
2174: case COMPARE:
2175: case MINUS:
2176: case MULT:
2177: case DIV: case UDIV:
2178: case MOD: case UMOD:
2179: case AND: case IOR: case XOR:
2180: case LSHIFT: case ASHIFT: case ROTATE:
2181: case ASHIFTRT: case LSHIFTRT: case ROTATERT:
2182: case NE: case EQ:
2183: case GE: case GT: case GEU: case GTU:
2184: case LE: case LT: case LEU: case LTU:
2185: if (XEXP (x, 1) && ! CONSTANT_P (XEXP (x, 1)))
2186: instantiate_virtual_regs_1 (&XEXP (x, 1), object, extra_insns);
2187: loc = &XEXP (x, 0);
2188: goto restart;
2189:
2190: case MEM:
2191: /* Most cases of MEM that convert to valid addresses have already been
2192: handled by our scan of regno_reg_rtx. The only special handling we
2193: need here is to make a copy of the rtx to ensure it isn't being
2194: shared if we have to change it to a psuedo.
2195:
2196: If the rtx is a simple reference to an address via a virtual register,
2197: it can potentially be shared. In such cases, first try to make it
2198: a valid address, which can also be shared. Otherwise, copy it and
2199: proceed normally.
2200:
2201: First check for common cases that need no processing. These are
2202: usually due to instantiation already being done on a previous instance
2203: of a shared rtx. */
2204:
2205: temp = XEXP (x, 0);
2206: if (CONSTANT_ADDRESS_P (temp)
2207: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2208: || temp == arg_pointer_rtx
2209: #endif
2210: || temp == frame_pointer_rtx)
2211: return 1;
2212:
2213: if (GET_CODE (temp) == PLUS
2214: && CONSTANT_ADDRESS_P (XEXP (temp, 1))
2215: && (XEXP (temp, 0) == frame_pointer_rtx
2216: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
2217: || XEXP (temp, 0) == arg_pointer_rtx
2218: #endif
2219: ))
2220: return 1;
2221:
2222: if (temp == virtual_stack_vars_rtx
2223: || temp == virtual_incoming_args_rtx
2224: || (GET_CODE (temp) == PLUS
2225: && CONSTANT_ADDRESS_P (XEXP (temp, 1))
2226: && (XEXP (temp, 0) == virtual_stack_vars_rtx
2227: || XEXP (temp, 0) == virtual_incoming_args_rtx)))
2228: {
2229: /* This MEM may be shared. If the substitution can be done without
2230: the need to generate new pseudos, we want to do it in place
2231: so all copies of the shared rtx benefit. The call below will
2232: only make substitutions if the resulting address is still
2233: valid.
2234:
2235: Note that we cannot pass X as the object in the recursive call
2236: since the insn being processed may not allow all valid
2237: addresses. */
2238:
2239: if (instantiate_virtual_regs_1 (&XEXP (x, 0), object, 0))
2240: return 1;
2241:
2242: /* Otherwise make a copy and process that copy. We copy the entire
2243: RTL expression since it might be a PLUS which could also be
2244: shared. */
2245: *loc = x = copy_rtx (x);
2246: }
2247:
2248: /* Fall through to generic unary operation case. */
2249: case USE:
2250: case CLOBBER:
2251: case SUBREG:
2252: case STRICT_LOW_PART:
2253: case NEG: case NOT:
2254: case PRE_DEC: case PRE_INC: case POST_DEC: case POST_INC:
2255: case SIGN_EXTEND: case ZERO_EXTEND:
2256: case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
2257: case FLOAT: case FIX:
2258: case UNSIGNED_FIX: case UNSIGNED_FLOAT:
2259: case ABS:
2260: case SQRT:
2261: case FFS:
2262: /* These case either have just one operand or we know that we need not
2263: check the rest of the operands. */
2264: loc = &XEXP (x, 0);
2265: goto restart;
2266:
2267: case REG:
2268: /* Try to replace with a PLUS. If that doesn't work, compute the sum
2269: in front of this insn and substitute the temporary. */
2270: if (x == virtual_incoming_args_rtx)
2271: new = arg_pointer_rtx, offset = in_arg_offset;
2272: else if (x == virtual_stack_vars_rtx)
2273: new = frame_pointer_rtx, offset = var_offset;
2274: else if (x == virtual_stack_dynamic_rtx)
2275: new = stack_pointer_rtx, offset = dynamic_offset;
2276: else if (x == virtual_outgoing_args_rtx)
2277: new = stack_pointer_rtx, offset = out_arg_offset;
2278:
2279: if (new)
2280: {
2281: temp = plus_constant (new, offset);
2282: if (!validate_change (object, loc, temp, 0))
2283: {
2284: if (! extra_insns)
2285: return 0;
2286:
2287: start_sequence ();
2288: temp = force_operand (temp, 0);
2289: seq = get_insns ();
2290: end_sequence ();
2291:
2292: emit_insns_before (seq, object);
2293: if (! validate_change (object, loc, temp, 0)
2294: && ! validate_replace_rtx (x, temp, object))
2295: abort ();
2296: }
2297: }
2298:
2299: return 1;
2300: }
2301:
2302: /* Scan all subexpressions. */
2303: fmt = GET_RTX_FORMAT (code);
2304: for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
2305: if (*fmt == 'e')
2306: {
2307: if (!instantiate_virtual_regs_1 (&XEXP (x, i), object, extra_insns))
2308: return 0;
2309: }
2310: else if (*fmt == 'E')
2311: for (j = 0; j < XVECLEN (x, i); j++)
2312: if (! instantiate_virtual_regs_1 (&XVECEXP (x, i, j), object,
2313: extra_insns))
2314: return 0;
2315:
2316: return 1;
2317: }
2318:
2319: /* Optimization: assuming this function does not receive nonlocal gotos,
2320: delete the handlers for such, as well as the insns to establish
2321: and disestablish them. */
2322:
2323: static void
2324: delete_handlers ()
2325: {
2326: rtx insn;
2327: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2328: {
2329: /* Delete the handler by turning off the flag that would
2330: prevent jump_optimize from deleting it.
2331: Also permit deletion of the nonlocal labels themselves
2332: if nothing local refers to them. */
2333: if (GET_CODE (insn) == CODE_LABEL)
2334: LABEL_PRESERVE_P (insn) = 0;
2335: if (GET_CODE (insn) == INSN
2336: && GET_CODE (PATTERN (insn)) == SET
2337: && (SET_DEST (PATTERN (insn)) == nonlocal_goto_handler_slot
2338: || SET_SRC (PATTERN (insn)) == nonlocal_goto_handler_slot
2339: || SET_DEST (PATTERN (insn)) == nonlocal_goto_stack_level
2340: || SET_SRC (PATTERN (insn)) == nonlocal_goto_stack_level))
2341: delete_insn (insn);
2342: }
2343: }
2344:
2345: /* Return a list (chain of EXPR_LIST nodes) for the nonlocal labels
2346: of the current function. */
2347:
2348: rtx
2349: nonlocal_label_rtx_list ()
2350: {
2351: tree t;
2352: rtx x = 0;
2353:
2354: for (t = nonlocal_labels; t; t = TREE_CHAIN (t))
2355: x = gen_rtx (EXPR_LIST, VOIDmode, label_rtx (TREE_VALUE (t)), x);
2356:
2357: return x;
2358: }
2359:
2360: /* Output a USE for any register use in RTL.
2361: This is used with -noreg to mark the extent of lifespan
2362: of any registers used in a user-visible variable's DECL_RTL. */
2363:
2364: void
2365: use_variable (rtl)
2366: rtx rtl;
2367: {
2368: if (GET_CODE (rtl) == REG)
2369: /* This is a register variable. */
2370: emit_insn (gen_rtx (USE, VOIDmode, rtl));
2371: else if (GET_CODE (rtl) == MEM
2372: && GET_CODE (XEXP (rtl, 0)) == REG
2373: && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
2374: || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
2375: && XEXP (rtl, 0) != current_function_internal_arg_pointer)
2376: /* This is a variable-sized structure. */
2377: emit_insn (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)));
2378: }
2379:
2380: /* Like use_variable except that it outputs the USEs after INSN
2381: instead of at the end of the insn-chain. */
2382:
2383: void
2384: use_variable_after (rtl, insn)
2385: rtx rtl, insn;
2386: {
2387: if (GET_CODE (rtl) == REG)
2388: /* This is a register variable. */
2389: emit_insn_after (gen_rtx (USE, VOIDmode, rtl), insn);
2390: else if (GET_CODE (rtl) == MEM
2391: && GET_CODE (XEXP (rtl, 0)) == REG
2392: && (REGNO (XEXP (rtl, 0)) < FIRST_VIRTUAL_REGISTER
2393: || REGNO (XEXP (rtl, 0)) > LAST_VIRTUAL_REGISTER)
2394: && XEXP (rtl, 0) != current_function_internal_arg_pointer)
2395: /* This is a variable-sized structure. */
2396: emit_insn_after (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)), insn);
2397: }
2398:
2399: int
2400: max_parm_reg_num ()
2401: {
2402: return max_parm_reg;
2403: }
2404:
2405: /* Return the first insn following those generated by `assign_parms'. */
2406:
2407: rtx
2408: get_first_nonparm_insn ()
2409: {
2410: if (last_parm_insn)
2411: return NEXT_INSN (last_parm_insn);
2412: return get_insns ();
2413: }
2414:
2415: /* Return 1 if EXP returns an aggregate value, for which an address
2416: must be passed to the function or returned by the function. */
2417:
2418: int
2419: aggregate_value_p (exp)
2420: tree exp;
2421: {
2422: if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
2423: return 1;
2424: if (RETURN_IN_MEMORY (TREE_TYPE (exp)))
2425: return 1;
2426: if (flag_pcc_struct_return
2427: && (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
2428: || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE))
2429: return 1;
2430: return 0;
2431: }
2432:
2433: /* Assign RTL expressions to the function's parameters.
2434: This may involve copying them into registers and using
2435: those registers as the RTL for them.
2436:
2437: If SECOND_TIME is non-zero it means that this function is being
2438: called a second time. This is done by integrate.c when a function's
2439: compilation is deferred. We need to come back here in case the
2440: FUNCTION_ARG macro computes items needed for the rest of the compilation
2441: (such as changing which registers are fixed or caller-saved). But suppress
2442: writing any insns or setting DECL_RTL of anything in this case. */
2443:
2444: void
2445: assign_parms (fndecl, second_time)
2446: tree fndecl;
2447: int second_time;
2448: {
2449: register tree parm;
2450: register rtx entry_parm = 0;
2451: register rtx stack_parm = 0;
2452: CUMULATIVE_ARGS args_so_far;
2453: enum machine_mode passed_mode, nominal_mode;
2454: /* Total space needed so far for args on the stack,
2455: given as a constant and a tree-expression. */
2456: struct args_size stack_args_size;
2457: tree fntype = TREE_TYPE (fndecl);
2458: tree fnargs = DECL_ARGUMENTS (fndecl);
2459: /* This is used for the arg pointer when referring to stack args. */
2460: rtx internal_arg_pointer;
2461: /* This is a dummy PARM_DECL that we used for the function result if
2462: the function returns a structure. */
2463: tree function_result_decl = 0;
2464: int nparmregs = list_length (fnargs) + LAST_VIRTUAL_REGISTER + 1;
2465: int varargs_setup = 0;
2466:
2467: /* Nonzero if the last arg is named `__builtin_va_alist',
2468: which is used on some machines for old-fashioned non-ANSI varargs.h;
2469: this should be stuck onto the stack as if it had arrived there. */
2470: int vararg
2471: = (fnargs
2472: && (parm = tree_last (fnargs)) != 0
2473: && DECL_NAME (parm)
2474: && (! strcmp (IDENTIFIER_POINTER (DECL_NAME (parm)),
2475: "__builtin_va_alist")));
2476:
2477: /* Nonzero if function takes extra anonymous args.
2478: This means the last named arg must be on the stack
2479: right before the anonymous ones. */
2480: int stdarg
2481: = (TYPE_ARG_TYPES (fntype) != 0
2482: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2483: != void_type_node));
2484:
2485: /* If the reg that the virtual arg pointer will be translated into is
2486: not a fixed reg or is the stack pointer, make a copy of the virtual
2487: arg pointer, and address parms via the copy. The frame pointer is
2488: considered fixed even though it is not marked as such.
2489:
2490: The second time through, simply use ap to avoid generating rtx. */
2491:
2492: if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
2493: || ! (fixed_regs[ARG_POINTER_REGNUM]
2494: || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))
2495: && ! second_time)
2496: internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
2497: else
2498: internal_arg_pointer = virtual_incoming_args_rtx;
2499: current_function_internal_arg_pointer = internal_arg_pointer;
2500:
2501: stack_args_size.constant = 0;
2502: stack_args_size.var = 0;
2503:
2504: /* If struct value address is treated as the first argument, make it so. */
2505: if (aggregate_value_p (DECL_RESULT (fndecl))
2506: && ! current_function_returns_pcc_struct
2507: && struct_value_incoming_rtx == 0)
2508: {
2509: tree type = build_pointer_type (fntype);
2510:
2511: function_result_decl = build_decl (PARM_DECL, 0, type);
2512:
2513: DECL_ARG_TYPE (function_result_decl) = type;
2514: TREE_CHAIN (function_result_decl) = fnargs;
2515: fnargs = function_result_decl;
2516: }
2517:
2518: parm_reg_stack_loc = (rtx *) oballoc (nparmregs * sizeof (rtx));
2519: bzero (parm_reg_stack_loc, nparmregs * sizeof (rtx));
2520:
2521: #ifdef INIT_CUMULATIVE_INCOMING_ARGS
2522: INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, 0);
2523: #else
2524: INIT_CUMULATIVE_ARGS (args_so_far, fntype, 0);
2525: #endif
2526:
2527: /* We haven't yet found an argument that we must push and pretend the
2528: caller did. */
2529: current_function_pretend_args_size = 0;
2530:
2531: for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
2532: {
2533: int aggregate
2534: = (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
2535: || TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
2536: || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE);
2537: struct args_size stack_offset;
2538: struct args_size arg_size;
2539: int passed_pointer = 0;
2540: tree passed_type = DECL_ARG_TYPE (parm);
2541:
2542: /* Set LAST_NAMED if this is last named arg before some
2543: anonymous args. We treat it as if it were anonymous too. */
2544: int last_named = ((TREE_CHAIN (parm) == 0
2545: || DECL_NAME (TREE_CHAIN (parm)) == 0)
2546: && (vararg || stdarg));
2547:
2548: if (TREE_TYPE (parm) == error_mark_node
2549: /* This can happen after weird syntax errors
2550: or if an enum type is defined among the parms. */
2551: || TREE_CODE (parm) != PARM_DECL
2552: || passed_type == NULL)
2553: {
2554: DECL_RTL (parm) = gen_rtx (MEM, BLKmode, const0_rtx);
2555: TREE_USED (parm) = 1;
2556: continue;
2557: }
2558:
2559: /* For varargs.h function, save info about regs and stack space
2560: used by the individual args, not including the va_alist arg. */
2561: if (vararg && last_named)
2562: current_function_args_info = args_so_far;
2563:
2564: /* Find mode of arg as it is passed, and mode of arg
2565: as it should be during execution of this function. */
2566: passed_mode = TYPE_MODE (passed_type);
2567: nominal_mode = TYPE_MODE (TREE_TYPE (parm));
2568:
2569: #ifdef FUNCTION_ARG_PASS_BY_REFERENCE
2570: /* See if this arg was passed by invisible reference. */
2571: if (FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
2572: passed_type, ! last_named))
2573: {
2574: passed_type = build_pointer_type (passed_type);
2575: passed_pointer = 1;
2576: passed_mode = nominal_mode = Pmode;
2577: }
2578: #endif
2579:
2580: /* Let machine desc say which reg (if any) the parm arrives in.
2581: 0 means it arrives on the stack. */
2582: #ifdef FUNCTION_INCOMING_ARG
2583: entry_parm = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
2584: passed_type, ! last_named);
2585: #else
2586: entry_parm = FUNCTION_ARG (args_so_far, passed_mode,
2587: passed_type, ! last_named);
2588: #endif
2589:
2590: #ifdef SETUP_INCOMING_VARARGS
2591: /* If this is the last named parameter, do any required setup for
2592: varargs or stdargs. We need to know about the case of this being an
2593: addressable type, in which case we skip the registers it
2594: would have arrived in.
2595:
2596: For stdargs, LAST_NAMED will be set for two parameters, the one that
2597: is actually the last named, and the dummy parameter. We only
2598: want to do this action once.
2599:
2600: Also, indicate when RTL generation is to be suppressed. */
2601: if (last_named && !varargs_setup)
2602: {
2603: SETUP_INCOMING_VARARGS (args_so_far, passed_mode, passed_type,
2604: current_function_pretend_args_size,
2605: second_time);
2606: varargs_setup = 1;
2607: }
2608: #endif
2609:
2610: /* Determine parm's home in the stack,
2611: in case it arrives in the stack or we should pretend it did.
2612:
2613: Compute the stack position and rtx where the argument arrives
2614: and its size.
2615:
2616: There is one complexity here: If this was a parameter that would
2617: have been passed in registers, but wasn't only because it is
2618: __builtin_va_alist, we want locate_and_pad_parm to treat it as if
2619: it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
2620: In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
2621: 0 as it was the previous time. */
2622:
2623: locate_and_pad_parm (passed_mode, passed_type,
2624: #ifdef STACK_PARMS_IN_REG_PARM_AREA
2625: 1,
2626: #else
2627: #ifdef FUNCTION_INCOMING_ARG
2628: FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
2629: passed_type,
2630: (! last_named
2631: || varargs_setup)) != 0,
2632: #else
2633: FUNCTION_ARG (args_so_far, passed_mode,
2634: passed_type,
2635: ! last_named || varargs_setup) != 0,
2636: #endif
2637: #endif
2638: fndecl, &stack_args_size, &stack_offset, &arg_size);
2639:
2640: if (! second_time)
2641: {
2642: rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
2643:
2644: if (offset_rtx == const0_rtx)
2645: stack_parm = gen_rtx (MEM, passed_mode, internal_arg_pointer);
2646: else
2647: stack_parm = gen_rtx (MEM, passed_mode,
2648: gen_rtx (PLUS, Pmode,
2649: internal_arg_pointer, offset_rtx));
2650:
2651: /* If this is a memory ref that contains aggregate components,
2652: mark it as such for cse and loop optimize. */
2653: MEM_IN_STRUCT_P (stack_parm) = aggregate;
2654: }
2655:
2656: /* If this parameter was passed both in registers and in the stack,
2657: use the copy on the stack. */
2658: if (MUST_PASS_IN_STACK (passed_mode, passed_type))
2659: entry_parm = 0;
2660:
2661: /* If this parm was passed part in regs and part in memory,
2662: pretend it arrived entirely in memory
2663: by pushing the register-part onto the stack.
2664:
2665: In the special case of a DImode or DFmode that is split,
2666: we could put it together in a pseudoreg directly,
2667: but for now that's not worth bothering with. */
2668:
2669: if (entry_parm)
2670: {
2671: int nregs = 0;
2672: #ifdef FUNCTION_ARG_PARTIAL_NREGS
2673: nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
2674: passed_type, ! last_named);
2675: #endif
2676:
2677: if (nregs > 0)
2678: {
2679: current_function_pretend_args_size
2680: = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
2681: / (PARM_BOUNDARY / BITS_PER_UNIT)
2682: * (PARM_BOUNDARY / BITS_PER_UNIT));
2683:
2684: if (! second_time)
2685: move_block_from_reg (REGNO (entry_parm),
2686: validize_mem (stack_parm), nregs);
2687: entry_parm = stack_parm;
2688: }
2689: }
2690:
2691: /* If we didn't decide this parm came in a register,
2692: by default it came on the stack. */
2693: if (entry_parm == 0)
2694: entry_parm = stack_parm;
2695:
2696: /* Record permanently how this parm was passed. */
2697: if (! second_time)
2698: DECL_INCOMING_RTL (parm) = entry_parm;
2699:
2700: /* If there is actually space on the stack for this parm,
2701: count it in stack_args_size; otherwise set stack_parm to 0
2702: to indicate there is no preallocated stack slot for the parm. */
2703:
2704: if (entry_parm == stack_parm
2705: #ifdef REG_PARM_STACK_SPACE
2706: /* On some machines, even if a parm value arrives in a register
2707: there is still an (uninitialized) stack slot allocated for it. */
2708: || REG_PARM_STACK_SPACE (fndecl) > 0
2709: #endif
2710: )
2711: {
2712: stack_args_size.constant += arg_size.constant;
2713: if (arg_size.var)
2714: ADD_PARM_SIZE (stack_args_size, arg_size.var);
2715: }
2716: else
2717: /* No stack slot was pushed for this parm. */
2718: stack_parm = 0;
2719:
2720: /* Update info on where next arg arrives in registers. */
2721:
2722: FUNCTION_ARG_ADVANCE (args_so_far, passed_mode,
2723: passed_type, ! last_named);
2724:
2725: /* If this is our second time through, we are done with this parm. */
2726: if (second_time)
2727: continue;
2728:
2729: /* Now adjust STACK_PARM to the mode and precise location
2730: where this parameter should live during execution,
2731: if we discover that it must live in the stack during execution.
2732: To make debuggers happier on big-endian machines, we store
2733: the value in the last bytes of the space available. */
2734:
2735: if (nominal_mode != BLKmode && nominal_mode != passed_mode
2736: && stack_parm != 0)
2737: {
2738: rtx offset_rtx;
2739:
2740: #if BYTES_BIG_ENDIAN
2741: if (GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
2742: stack_offset.constant += (GET_MODE_SIZE (passed_mode)
2743: - GET_MODE_SIZE (nominal_mode));
2744: #endif
2745:
2746: offset_rtx = ARGS_SIZE_RTX (stack_offset);
2747: if (offset_rtx == const0_rtx)
2748: stack_parm = gen_rtx (MEM, nominal_mode, internal_arg_pointer);
2749: else
2750: stack_parm = gen_rtx (MEM, nominal_mode,
2751: gen_rtx (PLUS, Pmode,
2752: internal_arg_pointer, offset_rtx));
2753:
2754: /* If this is a memory ref that contains aggregate components,
2755: mark it as such for cse and loop optimize. */
2756: MEM_IN_STRUCT_P (stack_parm) = aggregate;
2757: }
2758:
2759: /* ENTRY_PARM is an RTX for the parameter as it arrives,
2760: in the mode in which it arrives.
2761: STACK_PARM is an RTX for a stack slot where the parameter can live
2762: during the function (in case we want to put it there).
2763: STACK_PARM is 0 if no stack slot was pushed for it.
2764:
2765: Now output code if necessary to convert ENTRY_PARM to
2766: the type in which this function declares it,
2767: and store that result in an appropriate place,
2768: which may be a pseudo reg, may be STACK_PARM,
2769: or may be a local stack slot if STACK_PARM is 0.
2770:
2771: Set DECL_RTL to that place. */
2772:
2773: if (nominal_mode == BLKmode)
2774: {
2775: /* If a BLKmode arrives in registers, copy it to a stack slot. */
2776: if (GET_CODE (entry_parm) == REG)
2777: {
2778: int size_stored = CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
2779: UNITS_PER_WORD);
2780:
2781: /* Note that we will be storing an integral number of words.
2782: So we have to be careful to ensure that we allocate an
2783: integral number of words. We do this below in the
2784: assign_stack_local if space was not allocated in the argument
2785: list. If it was, this will not work if PARM_BOUNDARY is not
2786: a multiple of BITS_PER_WORD. It isn't clear how to fix this
2787: if it becomes a problem. */
2788:
2789: if (stack_parm == 0)
2790: stack_parm
2791: = assign_stack_local (GET_MODE (entry_parm), size_stored, 0);
2792: else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
2793: abort ();
2794:
2795: move_block_from_reg (REGNO (entry_parm),
2796: validize_mem (stack_parm),
2797: size_stored / UNITS_PER_WORD);
2798: }
2799: DECL_RTL (parm) = stack_parm;
2800: }
2801: else if (! (
2802: #if 0 /* This change was turned off because it makes compilation bigger. */
2803: !optimize
2804: #else /* It's not clear why the following was replaced. */
2805: /* Obsoleted by preceeding line. */
2806: (obey_regdecls && ! TREE_REGDECL (parm)
2807: && ! TREE_INLINE (fndecl))
2808: #endif
2809: /* layout_decl may set this. */
2810: || TREE_ADDRESSABLE (parm)
2811: || TREE_SIDE_EFFECTS (parm)
2812: /* If -ffloat-store specified, don't put explicit
2813: float variables into registers. */
2814: || (flag_float_store
2815: && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE))
2816: /* Always assign pseudo to structure return or item passed
2817: by invisible reference. */
2818: || passed_pointer || parm == function_result_decl)
2819: {
2820: /* Store the parm in a pseudoregister during the function. */
2821: register rtx parmreg = gen_reg_rtx (nominal_mode);
2822:
2823: REG_USERVAR_P (parmreg) = 1;
2824:
2825: /* If this was an item that we received a pointer to, set DECL_RTL
2826: appropriately. */
2827: if (passed_pointer)
2828: {
2829: DECL_RTL (parm) = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (passed_type)), parmreg);
2830: MEM_IN_STRUCT_P (DECL_RTL (parm)) = aggregate;
2831: }
2832: else
2833: DECL_RTL (parm) = parmreg;
2834:
2835: /* Copy the value into the register. */
2836: if (GET_MODE (parmreg) != GET_MODE (entry_parm))
2837: convert_move (parmreg, validize_mem (entry_parm), 0);
2838: else
2839: emit_move_insn (parmreg, validize_mem (entry_parm));
2840:
2841: /* In any case, record the parm's desired stack location
2842: in case we later discover it must live in the stack. */
2843: if (REGNO (parmreg) >= nparmregs)
2844: {
2845: rtx *new;
2846: nparmregs = REGNO (parmreg) + 5;
2847: new = (rtx *) oballoc (nparmregs * sizeof (rtx));
2848: bcopy (parm_reg_stack_loc, new, nparmregs * sizeof (rtx));
2849: parm_reg_stack_loc = new;
2850: }
2851: parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
2852:
2853: /* Mark the register as eliminable if we did no conversion
2854: and it was copied from memory at a fixed offset,
2855: and the arg pointer was not copied to a pseudo-reg.
2856: If the arg pointer is a pseudo reg or the offset formed
2857: an invalid address, such memory-equivalences
2858: as we make here would screw up life analysis for it. */
2859: if (nominal_mode == passed_mode
2860: && GET_CODE (entry_parm) == MEM
2861: && stack_offset.var == 0
2862: && reg_mentioned_p (virtual_incoming_args_rtx,
2863: XEXP (entry_parm, 0)))
2864: REG_NOTES (get_last_insn ())
2865: = gen_rtx (EXPR_LIST, REG_EQUIV,
2866: entry_parm, REG_NOTES (get_last_insn ()));
2867:
2868: /* For pointer data type, suggest pointer register. */
2869: if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
2870: mark_reg_pointer (parmreg);
2871: }
2872: else
2873: {
2874: /* Value must be stored in the stack slot STACK_PARM
2875: during function execution. */
2876:
2877: if (passed_mode != nominal_mode)
2878: /* Conversion is required. */
2879: entry_parm = convert_to_mode (nominal_mode, entry_parm, 0);
2880:
2881: if (entry_parm != stack_parm)
2882: {
2883: if (stack_parm == 0)
2884: stack_parm = assign_stack_local (GET_MODE (entry_parm),
2885: GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
2886: emit_move_insn (validize_mem (stack_parm),
2887: validize_mem (entry_parm));
2888: }
2889:
2890: DECL_RTL (parm) = stack_parm;
2891: }
2892:
2893: /* If this "parameter" was the place where we are receiving the
2894: function's incoming structure pointer, set up the result. */
2895: if (parm == function_result_decl)
2896: DECL_RTL (DECL_RESULT (fndecl))
2897: = gen_rtx (MEM, DECL_MODE (DECL_RESULT (fndecl)), DECL_RTL (parm));
2898:
2899: if (TREE_THIS_VOLATILE (parm))
2900: MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
2901: if (TREE_READONLY (parm))
2902: RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
2903: }
2904:
2905: max_parm_reg = max_reg_num ();
2906: last_parm_insn = get_last_insn ();
2907:
2908: current_function_args_size = stack_args_size.constant;
2909:
2910: /* Adjust function incoming argument size for alignment and
2911: minimum length. */
2912:
2913: #ifdef REG_PARM_STACK_SPACE
2914: current_function_args_size = MAX (current_function_args_size,
2915: REG_PARM_STACK_SPACE (fndecl));
2916: #endif
2917:
2918: #ifdef STACK_BOUNDARY
2919: #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2920:
2921: current_function_args_size
2922: = ((current_function_args_size + STACK_BYTES - 1)
2923: / STACK_BYTES) * STACK_BYTES;
2924: #endif
2925:
2926: #ifdef ARGS_GROW_DOWNWARD
2927: current_function_arg_offset_rtx
2928: = (stack_args_size.var == 0 ? gen_rtx (CONST_INT, VOIDmode,
2929: -stack_args_size.constant)
2930: : expand_expr (size_binop (MINUS_EXPR, stack_args_size.var,
2931: size_int (-stack_args_size.constant)),
2932: 0, VOIDmode, 0));
2933: #else
2934: current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
2935: #endif
2936:
2937: /* See how many bytes, if any, of its args a function should try to pop
2938: on return. */
2939:
2940: current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (fndecl),
2941: current_function_args_size);
2942:
2943: /* For stdarg.h function, save info about regs and stack space
2944: used by the named args. */
2945:
2946: if (stdarg)
2947: current_function_args_info = args_so_far;
2948:
2949: /* Set the rtx used for the function return value. Put this in its
2950: own variable so any optimizers that need this information don't have
2951: to include tree.h. Do this here so it gets done when an inlined
2952: function gets output. */
2953:
2954: current_function_return_rtx = DECL_RTL (DECL_RESULT (fndecl));
2955: }
2956:
2957: /* Compute the size and offset from the start of the stacked arguments for a
2958: parm passed in mode PASSED_MODE and with type TYPE.
2959:
2960: INITIAL_OFFSET_PTR points to the current offset into the stacked
2961: arguments.
2962:
2963: The starting offset and size for this parm are returned in *OFFSET_PTR
2964: and *ARG_SIZE_PTR, respectively.
2965:
2966: IN_REGS is non-zero if the argument will be passed in registers. It will
2967: never be set if REG_PARM_STACK_SPACE is not defined.
2968:
2969: FNDECL is the function in which the argument was defined.
2970:
2971: There are two types of rounding that are done. The first, controlled by
2972: FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument
2973: list to be aligned to the specific boundary (in bits). This rounding
2974: affects the initial and starting offsets, but not the argument size.
2975:
2976: The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY,
2977: optionally rounds the size of the parm to PARM_BOUNDARY. The
2978: initial offset is not affected by this rounding, while the size always
2979: is and the starting offset may be. */
2980:
2981: /* offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
2982: initial_offset_ptr is positive because locate_and_pad_parm's
2983: callers pass in the total size of args so far as
2984: initial_offset_ptr. arg_size_ptr is always positive.*/
2985:
2986: static void pad_to_arg_alignment (), pad_below ();
2987:
2988: void
2989: locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
2990: initial_offset_ptr, offset_ptr, arg_size_ptr)
2991: enum machine_mode passed_mode;
2992: tree type;
2993: int in_regs;
2994: tree fndecl;
2995: struct args_size *initial_offset_ptr;
2996: struct args_size *offset_ptr;
2997: struct args_size *arg_size_ptr;
2998: {
2999: tree sizetree
3000: = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
3001: enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
3002: int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
3003: int boundary_in_bytes = boundary / BITS_PER_UNIT;
3004: int reg_parm_stack_space = 0;
3005:
3006: #ifdef REG_PARM_STACK_SPACE
3007: /* If we have found a stack parm before we reach the end of the
3008: area reserved for registers, skip that area. */
3009: if (! in_regs)
3010: {
3011: reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
3012: if (reg_parm_stack_space > 0)
3013: {
3014: if (initial_offset_ptr->var)
3015: {
3016: initial_offset_ptr->var
3017: = size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr),
3018: size_int (reg_parm_stack_space));
3019: initial_offset_ptr->constant = 0;
3020: }
3021: else if (initial_offset_ptr->constant < reg_parm_stack_space)
3022: initial_offset_ptr->constant = reg_parm_stack_space;
3023: }
3024: }
3025: #endif /* REG_PARM_STACK_SPACE */
3026:
3027: arg_size_ptr->var = 0;
3028: arg_size_ptr->constant = 0;
3029:
3030: #ifdef ARGS_GROW_DOWNWARD
3031: if (initial_offset_ptr->var)
3032: {
3033: offset_ptr->constant = 0;
3034: offset_ptr->var = size_binop (MINUS_EXPR, integer_zero_node,
3035: initial_offset_ptr->var);
3036: }
3037: else
3038: {
3039: offset_ptr->constant = - initial_offset_ptr->constant;
3040: offset_ptr->var = 0;
3041: }
3042: if (where_pad == upward
3043: && (TREE_CODE (sizetree) != INTEGER_CST
3044: || ((TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)))
3045: sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
3046: SUB_PARM_SIZE (*offset_ptr, sizetree);
3047: pad_to_arg_alignment (offset_ptr, boundary);
3048: if (initial_offset_ptr->var)
3049: {
3050: arg_size_ptr->var = size_binop (MINUS_EXPR,
3051: size_binop (MINUS_EXPR,
3052: integer_zero_node,
3053: initial_offset_ptr->var),
3054: offset_ptr->var);
3055: }
3056: else
3057: {
3058: arg_size_ptr->constant = (- initial_offset_ptr->constant -
3059: offset_ptr->constant);
3060: }
3061: /* ADD_PARM_SIZE (*arg_size_ptr, sizetree); */
3062: if (where_pad == downward)
3063: pad_below (arg_size_ptr, passed_mode, sizetree);
3064: #else /* !ARGS_GROW_DOWNWARD */
3065: pad_to_arg_alignment (initial_offset_ptr, boundary);
3066: *offset_ptr = *initial_offset_ptr;
3067: if (where_pad == downward)
3068: pad_below (offset_ptr, passed_mode, sizetree);
3069:
3070: #ifdef PUSH_ROUNDING
3071: if (passed_mode != BLKmode)
3072: sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree)));
3073: #endif
3074:
3075: if (where_pad != none
3076: && (TREE_CODE (sizetree) != INTEGER_CST
3077: || ((TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)))
3078: sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
3079:
3080: ADD_PARM_SIZE (*arg_size_ptr, sizetree);
3081: #endif /* ARGS_GROW_DOWNWARD */
3082: }
3083:
3084: static void
3085: pad_to_arg_alignment (offset_ptr, boundary)
3086: struct args_size *offset_ptr;
3087: int boundary;
3088: {
3089: int boundary_in_bytes = boundary / BITS_PER_UNIT;
3090:
3091: if (boundary > BITS_PER_UNIT)
3092: {
3093: if (offset_ptr->var)
3094: {
3095: offset_ptr->var =
3096: #ifdef ARGS_GROW_DOWNWARD
3097: round_down
3098: #else
3099: round_up
3100: #endif
3101: (ARGS_SIZE_TREE (*offset_ptr),
3102: boundary / BITS_PER_UNIT);
3103: offset_ptr->constant = 0; /*?*/
3104: }
3105: else
3106: offset_ptr->constant =
3107: #ifdef ARGS_GROW_DOWNWARD
3108: FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
3109: #else
3110: CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
3111: #endif
3112: }
3113: }
3114:
3115: static void
3116: pad_below (offset_ptr, passed_mode, sizetree)
3117: struct args_size *offset_ptr;
3118: enum machine_mode passed_mode;
3119: tree sizetree;
3120: {
3121: if (passed_mode != BLKmode)
3122: {
3123: if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
3124: offset_ptr->constant
3125: += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
3126: / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
3127: - GET_MODE_SIZE (passed_mode));
3128: }
3129: else
3130: {
3131: if (TREE_CODE (sizetree) != INTEGER_CST
3132: || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY)
3133: {
3134: /* Round the size up to multiple of PARM_BOUNDARY bits. */
3135: tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
3136: /* Add it in. */
3137: ADD_PARM_SIZE (*offset_ptr, s2);
3138: SUB_PARM_SIZE (*offset_ptr, sizetree);
3139: }
3140: }
3141: }
3142:
3143: static tree
3144: round_down (value, divisor)
3145: tree value;
3146: int divisor;
3147: {
3148: return size_binop (MULT_EXPR,
3149: size_binop (FLOOR_DIV_EXPR, value, size_int (divisor)),
3150: size_int (divisor));
3151: }
3152:
3153: /* Walk the tree of blocks describing the binding levels within a function
3154: and warn about uninitialized variables.
3155: This is done after calling flow_analysis and before global_alloc
3156: clobbers the pseudo-regs to hard regs. */
3157:
3158: void
3159: uninitialized_vars_warning (block)
3160: tree block;
3161: {
3162: register tree decl, sub;
3163: for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
3164: {
3165: if (TREE_CODE (decl) == VAR_DECL
3166: /* These warnings are unreliable for and aggregates
3167: because assigning the fields one by one can fail to convince
3168: flow.c that the entire aggregate was initialized.
3169: Unions are troublesome because members may be shorter. */
3170: && TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE
3171: && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE
3172: && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
3173: && DECL_RTL (decl) != 0
3174: && GET_CODE (DECL_RTL (decl)) == REG
3175: && regno_uninitialized (REGNO (DECL_RTL (decl))))
3176: warning_with_decl (decl,
3177: "`%s' may be used uninitialized in this function");
3178: if (TREE_CODE (decl) == VAR_DECL
3179: && DECL_RTL (decl) != 0
3180: && GET_CODE (DECL_RTL (decl)) == REG
3181: && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3182: warning_with_decl (decl,
3183: "variable `%s' may be clobbered by `longjmp'");
3184: }
3185: for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
3186: uninitialized_vars_warning (sub);
3187: }
3188:
3189: /* Do the appropriate part of uninitialized_vars_warning
3190: but for arguments instead of local variables. */
3191:
3192: void
3193: setjmp_args_warning (block)
3194: tree block;
3195: {
3196: register tree decl;
3197: for (decl = DECL_ARGUMENTS (current_function_decl);
3198: decl; decl = TREE_CHAIN (decl))
3199: if (DECL_RTL (decl) != 0
3200: && GET_CODE (DECL_RTL (decl)) == REG
3201: && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
3202: warning_with_decl (decl, "argument `%s' may be clobbered by `longjmp'");
3203: }
3204:
3205: /* If this function call setjmp, put all vars into the stack
3206: unless they were declared `register'. */
3207:
3208: void
3209: setjmp_protect (block)
3210: tree block;
3211: {
3212: register tree decl, sub;
3213: for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
3214: if ((TREE_CODE (decl) == VAR_DECL
3215: || TREE_CODE (decl) == PARM_DECL)
3216: && DECL_RTL (decl) != 0
3217: && GET_CODE (DECL_RTL (decl)) == REG
3218: && (
3219: #ifdef NON_SAVING_SETJMP
3220: /* If longjmp doesn't restore the registers,
3221: don't put anything in them. */
3222: NON_SAVING_SETJMP
3223: ||
3224: #endif
3225: ! TREE_REGDECL (decl)))
3226: put_var_into_stack (decl);
3227: for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
3228: setjmp_protect (sub);
3229: }
3230:
3231: /* Like the previous function, but for args instead of local variables. */
3232:
3233: void
3234: setjmp_protect_args ()
3235: {
3236: register tree decl, sub;
3237: for (decl = DECL_ARGUMENTS (current_function_decl);
3238: decl; decl = TREE_CHAIN (decl))
3239: if ((TREE_CODE (decl) == VAR_DECL
3240: || TREE_CODE (decl) == PARM_DECL)
3241: && DECL_RTL (decl) != 0
3242: && GET_CODE (DECL_RTL (decl)) == REG
3243: && (
3244: /* If longjmp doesn't restore the registers,
3245: don't put anything in them. */
3246: #ifdef NON_SAVING_SETJMP
3247: NON_SAVING_SETJMP
3248: ||
3249: #endif
3250: ! TREE_REGDECL (decl)))
3251: put_var_into_stack (decl);
3252: }
3253:
3254: /* Return the context-pointer register corresponding to DECL,
3255: or 0 if it does not need one. */
3256:
3257: rtx
3258: lookup_static_chain (decl)
3259: tree decl;
3260: {
3261: tree context = decl_function_context (decl);
3262: tree link;
3263:
3264: if (context == 0)
3265: return 0;
3266:
3267: /* We treat inline_function_decl as an alias for the current function
3268: because that is the inline function whose vars, types, etc.
3269: are being merged into the current function.
3270: See expand_inline_function. */
3271: if (context == current_function_decl || context == inline_function_decl)
3272: return virtual_stack_vars_rtx;
3273:
3274: for (link = context_display; link; link = TREE_CHAIN (link))
3275: if (TREE_PURPOSE (link) == context)
3276: return RTL_EXPR_RTL (TREE_VALUE (link));
3277:
3278: abort ();
3279: }
3280:
3281: /* Convert a stack slot address ADDR for variable VAR
3282: (from a containing function)
3283: into an address valid in this function (using a static chain). */
3284:
3285: rtx
3286: fix_lexical_addr (addr, var)
3287: rtx addr;
3288: tree var;
3289: {
3290: rtx basereg;
3291: int displacement;
3292: tree context = decl_function_context (var);
3293: struct function *fp;
3294: rtx base = 0;
3295:
3296: /* If this is the present function, we need not do anything. */
3297: if (context == current_function_decl || context == inline_function_decl)
3298: return addr;
3299:
3300: for (fp = outer_function_chain; fp; fp = fp->next)
3301: if (fp->decl == context)
3302: break;
3303:
3304: if (fp == 0)
3305: abort ();
3306:
3307: /* Decode given address as base reg plus displacement. */
3308: if (GET_CODE (addr) == REG)
3309: basereg = addr, displacement = 0;
3310: else if (GET_CODE (addr) == PLUS && GET_CODE (XEXP (addr, 1)) == CONST_INT)
3311: basereg = XEXP (addr, 0), displacement = INTVAL (XEXP (addr, 1));
3312: else
3313: abort ();
3314:
3315: /* We accept vars reached via the containing function's
3316: incoming arg pointer and via its stack variables pointer. */
3317: if (basereg == fp->internal_arg_pointer)
3318: {
3319: /* If reached via arg pointer, get the arg pointer value
3320: out of that function's stack frame.
3321:
3322: There are two cases: If a separate ap is needed, allocate a
3323: slot in the outer function for it and dereference it that way.
3324: This is correct even if the real ap is actually a pseudo.
3325: Otherwise, just adjust the offset from the frame pointer to
3326: compensate. */
3327:
3328: #ifdef NEED_SEPARATE_AP
3329: rtx addr;
3330:
3331: if (fp->arg_pointer_save_area == 0)
3332: fp->arg_pointer_save_area
3333: = assign_outer_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0, fp);
3334:
3335: addr = fix_lexical_addr (XEXP (fp->arg_pointer_save_area, 0), var);
3336: addr = memory_address (Pmode, addr);
3337:
3338: base = copy_to_reg (gen_rtx (MEM, Pmode, addr));
3339: #else
3340: displacement += (FIRST_PARM_OFFSET (context) - STARTING_FRAME_OFFSET);
3341: #endif
3342: }
3343:
3344: else if (basereg == virtual_stack_vars_rtx)
3345: {
3346: /* This is the same code as lookup_static_chain, duplicated here to
3347: avoid an extra call to decl_function_context. */
3348: tree link;
3349:
3350: for (link = context_display; link; link = TREE_CHAIN (link))
3351: if (TREE_PURPOSE (link) == context)
3352: {
3353: base = RTL_EXPR_RTL (TREE_VALUE (link));
3354: break;
3355: }
3356: }
3357:
3358: if (base == 0)
3359: abort ();
3360:
3361: /* Use same offset, relative to appropriate static chain or argument
3362: pointer. */
3363: return plus_constant (base, displacement);
3364: }
3365:
3366: /* Return the address of the trampoline for entering nested fn FUNCTION.
3367: If necessary, allocate a trampoline (in the stack frame)
3368: and emit rtl to initialize its contents (at entry to this function). */
3369:
3370: rtx
3371: trampoline_address (function)
3372: tree function;
3373: {
3374: tree link;
3375: tree rtlexp;
3376: rtx tramp;
3377: struct function *fp;
3378: tree fn_context;
3379:
3380: /* Find an existing trampoline and return it. */
3381: for (link = trampoline_list; link; link = TREE_CHAIN (link))
3382: if (TREE_PURPOSE (link) == function)
3383: return XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0);
3384: for (fp = outer_function_chain; fp; fp = fp->next)
3385: for (link = fp->trampoline_list; link; link = TREE_CHAIN (link))
3386: if (TREE_PURPOSE (link) == function)
3387: {
3388: tramp = fix_lexical_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0),
3389: function);
3390: return round_trampoline_addr (tramp);
3391: }
3392:
3393: /* None exists; we must make one. */
3394:
3395: /* Find the `struct function' for the function containing FUNCTION. */
3396: fp = 0;
3397: fn_context = decl_function_context (function);
3398: if (fn_context != current_function_decl)
3399: for (fp = outer_function_chain; fp; fp = fp->next)
3400: if (fp->decl == fn_context)
3401: break;
3402:
3403: /* Allocate run-time space for this trampoline
3404: (usually in the defining function's stack frame). */
3405: #ifdef ALLOCATE_TRAMPOLINE
3406: tramp = ALLOCATE_TRAMPOLINE (fp);
3407: #else
3408: /* If rounding needed, allocate extra space
3409: to ensure we have TRAMPOLINE_SIZE bytes left after rounding up. */
3410: #ifdef TRAMPOLINE_ALIGNMENT
3411: #define TRAMPOLINE_REAL_SIZE (TRAMPOLINE_SIZE + TRAMPOLINE_ALIGNMENT - 1)
3412: #else
3413: #define TRAMPOLINE_REAL_SIZE (TRAMPOLINE_SIZE)
3414: #endif
3415: if (fp != 0)
3416: tramp = assign_outer_stack_local (BLKmode, TRAMPOLINE_REAL_SIZE, 0, fp);
3417: else
3418: tramp = assign_stack_local (BLKmode, TRAMPOLINE_REAL_SIZE, 0);
3419: #endif
3420:
3421: /* Record the trampoline for reuse and note it for later initialization
3422: by expand_function_end. */
3423: if (fp != 0)
3424: {
3425: push_obstacks (fp->current_obstack, fp->function_maybepermanent_obstack);
3426: rtlexp = make_node (RTL_EXPR);
3427: RTL_EXPR_RTL (rtlexp) = tramp;
3428: fp->trampoline_list = tree_cons (function, rtlexp, fp->trampoline_list);
3429: pop_obstacks ();
3430: }
3431: else
3432: {
3433: /* Make the RTL_EXPR node temporary, not momentary, so that the
3434: trampoline_list doesn't become garbage. */
3435: int momentary = suspend_momentary ();
3436: rtlexp = make_node (RTL_EXPR);
3437: resume_momentary (momentary);
3438:
3439: RTL_EXPR_RTL (rtlexp) = tramp;
3440: trampoline_list = tree_cons (function, rtlexp, trampoline_list);
3441: }
3442:
3443: tramp = fix_lexical_addr (XEXP (tramp, 0), function);
3444: return round_trampoline_addr (tramp);
3445: }
3446:
3447: /* Given a trampoline address,
3448: round it to multiple of TRAMPOLINE_ALIGNMENT. */
3449:
3450: static rtx
3451: round_trampoline_addr (tramp)
3452: rtx tramp;
3453: {
3454: #ifdef TRAMPOLINE_ALIGNMENT
3455: /* Round address up to desired boundary. */
3456: rtx temp = gen_reg_rtx (Pmode);
3457: temp = expand_binop (Pmode, add_optab, tramp,
3458: gen_rtx (CONST_INT, VOIDmode, TRAMPOLINE_ALIGNMENT - 1),
3459: temp, 0, OPTAB_LIB_WIDEN);
3460: tramp = expand_binop (Pmode, and_optab, temp,
3461: gen_rtx (CONST_INT, VOIDmode, - TRAMPOLINE_ALIGNMENT),
3462: temp, 0, OPTAB_LIB_WIDEN);
3463: #endif
3464: return tramp;
3465: }
3466:
3467: /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
3468: and initialize static variables for generating RTL for the statements
3469: of the function. */
3470:
3471: void
3472: init_function_start (subr, filename, line)
3473: tree subr;
3474: char *filename;
3475: int line;
3476: {
3477: char *junk;
3478:
3479: init_stmt_for_function ();
3480:
3481: cse_not_expected = ! optimize;
3482:
3483: /* Caller save not needed yet. */
3484: caller_save_needed = 0;
3485:
3486: /* No stack slots have been made yet. */
3487: stack_slot_list = 0;
3488:
3489: /* There is no stack slot for handling nonlocal gotos. */
3490: nonlocal_goto_handler_slot = 0;
3491: nonlocal_goto_stack_level = 0;
3492:
3493: /* No labels have been declared for nonlocal use. */
3494: nonlocal_labels = 0;
3495:
3496: /* No function calls so far in this function. */
3497: function_call_count = 0;
3498:
3499: /* No parm regs have been allocated.
3500: (This is important for output_inline_function.) */
3501: max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
3502:
3503: /* Initialize the RTL mechanism. */
3504: init_emit ();
3505:
3506: /* Initialize the queue of pending postincrement and postdecrements,
3507: and some other info in expr.c. */
3508: init_expr ();
3509:
3510: /* We haven't done register allocation yet. */
3511: reg_renumber = 0;
3512:
3513: init_const_rtx_hash_table ();
3514:
3515: current_function_name = (*decl_printable_name) (subr, &junk);
3516:
3517: /* Nonzero if this is a nested function that uses a static chain. */
3518:
3519: current_function_needs_context
3520: = (decl_function_context (current_function_decl) != 0);
3521:
3522: /* Set if a call to setjmp is seen. */
3523: current_function_calls_setjmp = 0;
3524:
3525: /* Set if a call to longjmp is seen. */
3526: current_function_calls_longjmp = 0;
3527:
3528: current_function_calls_alloca = 0;
3529: current_function_has_nonlocal_label = 0;
3530: current_function_contains_functions = 0;
3531:
3532: current_function_returns_pcc_struct = 0;
3533: current_function_returns_struct = 0;
3534: current_function_epilogue_delay_list = 0;
3535: current_function_uses_const_pool = 0;
3536: current_function_uses_pic_offset_table = 0;
3537:
3538: /* We have not yet needed to make a label to jump to for tail-recursion. */
3539: tail_recursion_label = 0;
3540:
3541: /* We haven't had a need to make a save area for ap yet. */
3542:
3543: arg_pointer_save_area = 0;
3544:
3545: /* No stack slots allocated yet. */
3546: frame_offset = 0;
3547:
3548: /* No SAVE_EXPRs in this function yet. */
3549: save_expr_regs = 0;
3550:
3551: /* No RTL_EXPRs in this function yet. */
3552: rtl_expr_chain = 0;
3553:
3554: /* We have not allocated any temporaries yet. */
3555: temp_slots = 0;
3556: temp_slot_level = 0;
3557:
3558: /* Within function body, compute a type's size as soon it is laid out. */
3559: immediate_size_expand++;
3560:
3561: init_pending_stack_adjust ();
3562: inhibit_defer_pop = 0;
3563:
3564: current_function_outgoing_args_size = 0;
3565:
3566: /* Initialize the insn lengths. */
3567: init_insn_lengths ();
3568:
3569: /* Prevent ever trying to delete the first instruction of a function.
3570: Also tell final how to output a linenum before the function prologue. */
3571: emit_line_note (filename, line);
3572:
3573: /* Make sure first insn is a note even if we don't want linenums.
3574: This makes sure the first insn will never be deleted.
3575: Also, final expects a note to appear there. */
3576: emit_note (0, NOTE_INSN_DELETED);
3577:
3578: /* Set flags used by final.c. */
3579: if (aggregate_value_p (DECL_RESULT (subr)))
3580: {
3581: #ifdef PCC_STATIC_STRUCT_RETURN
3582: if (flag_pcc_struct_return)
3583: current_function_returns_pcc_struct = 1;
3584: else
3585: #endif
3586: current_function_returns_struct = 1;
3587: }
3588:
3589: /* Warn if this value is an aggregate type,
3590: regardless of which calling convention we are using for it. */
3591: if (warn_aggregate_return
3592: && (TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == RECORD_TYPE
3593: || TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == UNION_TYPE
3594: || TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == ARRAY_TYPE))
3595: warning ("function returns an aggregate");
3596:
3597: current_function_returns_pointer
3598: = (TREE_CODE (TREE_TYPE (DECL_RESULT (subr))) == POINTER_TYPE);
3599:
3600: /* Indicate that we need to distinguish between the return value of the
3601: present function and the return value of a function being called. */
3602: rtx_equal_function_value_matters = 1;
3603:
3604: /* Indicate that we have not instantiated virtual registers yet. */
3605: virtuals_instantiated = 0;
3606:
3607: /* Indicate we have no need of a frame pointer yet. */
3608: frame_pointer_needed = 0;
3609:
3610: /* By default assume not varargs. */
3611: current_function_varargs = 0;
3612: }
3613:
3614: /* Indicate that the current function uses extra args
3615: not explicitly mentioned in the argument list in any fashion. */
3616:
3617: void
3618: mark_varargs ()
3619: {
3620: current_function_varargs = 1;
3621: }
3622:
3623: /* Expand a call to __main at the beginning of a possible main function. */
3624:
3625: void
3626: expand_main_function ()
3627: {
3628: #ifndef INIT_SECTION_ASM_OP
3629: emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__main"), 0,
3630: VOIDmode, 0);
3631: #endif /* not INIT_SECTION_ASM_OP */
3632: }
3633:
3634: /* Start the RTL for a new function, and set variables used for
3635: emitting RTL.
3636: SUBR is the FUNCTION_DECL node.
3637: PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
3638: the function's parameters, which must be run at any return statement. */
3639:
3640: void
3641: expand_function_start (subr, parms_have_cleanups)
3642: tree subr;
3643: int parms_have_cleanups;
3644: {
3645: register int i;
3646: tree tem;
3647: rtx last_ptr;
3648:
3649: /* Make sure volatile mem refs aren't considered
3650: valid operands of arithmetic insns. */
3651: init_recog_no_volatile ();
3652:
3653: /* If function gets a static chain arg, store it in the stack frame.
3654: Do this first, so it gets the first stack slot offset. */
3655: if (current_function_needs_context)
3656: emit_move_insn (assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0),
3657: static_chain_incoming_rtx);
3658:
3659: /* If the parameters of this function need cleaning up, get a label
3660: for the beginning of the code which executes those cleanups. This must
3661: be done before doing anything with return_label. */
3662: if (parms_have_cleanups)
3663: cleanup_label = gen_label_rtx ();
3664: else
3665: cleanup_label = 0;
3666:
3667: /* Make the label for return statements to jump to, if this machine
3668: does not have a one-instruction return and uses an epilogue,
3669: or if it returns a structure, or if it has parm cleanups. */
3670: #ifdef HAVE_return
3671: if (cleanup_label == 0 && HAVE_return
3672: && ! current_function_returns_pcc_struct
3673: && ! (current_function_returns_struct && ! optimize))
3674: return_label = 0;
3675: else
3676: return_label = gen_label_rtx ();
3677: #else
3678: return_label = gen_label_rtx ();
3679: #endif
3680:
3681: /* Initialize rtx used to return the value. */
3682: /* Do this before assign_parms so that we copy the struct value address
3683: before any library calls that assign parms might generate. */
3684:
3685: /* Decide whether to return the value in memory or in a register. */
3686: if (aggregate_value_p (DECL_RESULT (subr)))
3687: {
3688: /* Returning something that won't go in a register. */
3689: register rtx value_address;
3690:
3691: #ifdef PCC_STATIC_STRUCT_RETURN
3692: if (current_function_returns_pcc_struct)
3693: {
3694: int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
3695: value_address = assemble_static_space (size);
3696: }
3697: else
3698: #endif
3699: {
3700: /* Expect to be passed the address of a place to store the value.
3701: If it is passed as an argument, assign_parms will take care of
3702: it. */
3703: if (struct_value_incoming_rtx)
3704: {
3705: value_address = gen_reg_rtx (Pmode);
3706: emit_move_insn (value_address, struct_value_incoming_rtx);
3707: }
3708: }
3709: if (value_address)
3710: DECL_RTL (DECL_RESULT (subr))
3711: = gen_rtx (MEM, DECL_MODE (DECL_RESULT (subr)),
3712: value_address);
3713: }
3714: else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
3715: /* If return mode is void, this decl rtl should not be used. */
3716: DECL_RTL (DECL_RESULT (subr)) = 0;
3717: else if (parms_have_cleanups)
3718: /* If function will end with cleanup code for parms,
3719: compute the return values into a pseudo reg,
3720: which we will copy into the true return register
3721: after the cleanups are done. */
3722: DECL_RTL (DECL_RESULT (subr))
3723: = gen_reg_rtx (DECL_MODE (DECL_RESULT (subr)));
3724: else
3725: /* Scalar, returned in a register. */
3726: {
3727: #ifdef FUNCTION_OUTGOING_VALUE
3728: DECL_RTL (DECL_RESULT (subr))
3729: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
3730: #else
3731: DECL_RTL (DECL_RESULT (subr))
3732: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
3733: #endif
3734:
3735: /* Mark this reg as the function's return value. */
3736: if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
3737: {
3738: REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
3739: /* Needed because we may need to move this to memory
3740: in case it's a named return value whose address is taken. */
3741: TREE_REGDECL (DECL_RESULT (subr)) = 1;
3742: }
3743: }
3744:
3745: /* Initialize rtx for parameters and local variables.
3746: In some cases this requires emitting insns. */
3747:
3748: assign_parms (subr, 0);
3749:
3750: /* The following was moved from init_function_start.
3751: The move is supposed to make sdb output more accurate. */
3752: /* Indicate the beginning of the function body,
3753: as opposed to parm setup. */
3754: emit_note (0, NOTE_INSN_FUNCTION_BEG);
3755:
3756: /* If doing stupid allocation, mark parms as born here. */
3757:
3758: if (GET_CODE (get_last_insn ()) != NOTE)
3759: emit_note (0, NOTE_INSN_DELETED);
3760: parm_birth_insn = get_last_insn ();
3761:
3762: if (obey_regdecls)
3763: {
3764: for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
3765: use_variable (regno_reg_rtx[i]);
3766:
3767: if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
3768: use_variable (current_function_internal_arg_pointer);
3769: }
3770:
3771: /* Fetch static chain values for containing functions. */
3772: tem = decl_function_context (current_function_decl);
3773: if (tem)
3774: last_ptr = copy_to_reg (static_chain_incoming_rtx);
3775: context_display = 0;
3776: while (tem)
3777: {
3778: tree rtlexp = make_node (RTL_EXPR);
3779:
3780: RTL_EXPR_RTL (rtlexp) = last_ptr;
3781: context_display = tree_cons (tem, rtlexp, context_display);
3782: tem = decl_function_context (tem);
3783: if (tem == 0)
3784: break;
3785: /* Chain thru stack frames, assuming pointer to next lexical frame
3786: is found at the place we always store it. */
3787: #ifdef FRAME_GROWS_DOWNWARD
3788: last_ptr = plus_constant (last_ptr, - GET_MODE_SIZE (Pmode));
3789: #endif
3790: last_ptr = copy_to_reg (gen_rtx (MEM, Pmode,
3791: memory_address (Pmode, last_ptr)));
3792: }
3793:
3794: /* After the display initializations is where the tail-recursion label
3795: should go, if we end up needing one. Ensure we have a NOTE here
3796: since some things (like trampolines) get placed before this. */
3797: tail_recursion_reentry = emit_note (0, NOTE_INSN_DELETED);
3798:
3799: /* Evaluate now the sizes of any types declared among the arguments. */
3800: for (tem = nreverse (get_pending_sizes ()); tem; tem = TREE_CHAIN (tem))
3801: expand_expr (TREE_VALUE (tem), 0, VOIDmode, 0);
3802:
3803: /* Make sure there is a line number after the function entry setup code. */
3804: force_next_line_note ();
3805: }
3806:
3807: /* Generate RTL for the end of the current function.
3808: FILENAME and LINE are the current position in the source file. */
3809:
3810: /* It is up to language-specific callers to do cleanups for parameters. */
3811:
3812: void
3813: expand_function_end (filename, line)
3814: char *filename;
3815: int line;
3816: {
3817: register int i;
3818: tree link;
3819:
3820: static rtx initial_trampoline;
3821:
3822: #ifdef NON_SAVING_SETJMP
3823: /* Don't put any variables in registers if we call setjmp
3824: on a machine that fails to restore the registers. */
3825: if (NON_SAVING_SETJMP && current_function_calls_setjmp)
3826: {
3827: setjmp_protect (DECL_INITIAL (current_function_decl));
3828: setjmp_protect_args ();
3829: }
3830: #endif
3831:
3832: /* Save the argument pointer if a save area was made for it. */
3833: if (arg_pointer_save_area)
3834: {
3835: rtx x = gen_move_insn (arg_pointer_save_area, virtual_incoming_args_rtx);
3836: emit_insn_before (x, tail_recursion_reentry);
3837: }
3838:
3839: /* Initialize any trampolines required by this function. */
3840: for (link = trampoline_list; link; link = TREE_CHAIN (link))
3841: {
3842: tree function = TREE_PURPOSE (link);
3843: rtx context = lookup_static_chain (function);
3844: rtx tramp = RTL_EXPR_RTL (TREE_VALUE (link));
3845: rtx seq;
3846:
3847: /* First make sure this compilation has a template for
3848: initializing trampolines. */
3849: if (initial_trampoline == 0)
3850: initial_trampoline
3851: = gen_rtx (MEM, BLKmode, assemble_trampoline_template ());
3852:
3853: /* Generate insns to initialize the trampoline. */
3854: start_sequence ();
3855: tramp = change_address (initial_trampoline, BLKmode,
3856: round_trampoline_addr (XEXP (tramp, 0)));
3857: emit_block_move (tramp, initial_trampoline,
3858: gen_rtx (CONST_INT, VOIDmode, TRAMPOLINE_SIZE),
3859: FUNCTION_BOUNDARY / BITS_PER_UNIT);
3860: INITIALIZE_TRAMPOLINE (XEXP (tramp, 0),
3861: XEXP (DECL_RTL (function), 0), context);
3862: seq = get_insns ();
3863: end_sequence ();
3864:
3865: /* Put those insns at entry to the containing function (this one). */
3866: emit_insns_before (seq, tail_recursion_reentry);
3867: }
3868: /* Clear the trampoline_list for the next function. */
3869: trampoline_list = 0;
3870:
3871: #if 0 /* I think unused parms are legitimate enough. */
3872: /* Warn about unused parms. */
3873: if (warn_unused)
3874: {
3875: rtx decl;
3876:
3877: for (decl = DECL_ARGUMENTS (current_function_decl);
3878: decl; decl = TREE_CHAIN (decl))
3879: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
3880: warning_with_decl (decl, "unused parameter `%s'");
3881: }
3882: #endif
3883:
3884: /* Delete handlers for nonlocal gotos if nothing uses them. */
3885: if (nonlocal_goto_handler_slot != 0 && !current_function_has_nonlocal_label)
3886: delete_handlers ();
3887:
3888: /* End any sequences that failed to be closed due to syntax errors. */
3889: while (in_sequence_p ())
3890: end_sequence (0);
3891:
3892: /* Outside function body, can't compute type's actual size
3893: until next function's body starts. */
3894: immediate_size_expand--;
3895:
3896: /* If doing stupid register allocation,
3897: mark register parms as dying here. */
3898:
3899: if (obey_regdecls)
3900: {
3901: rtx tem;
3902: for (i = LAST_VIRTUAL_REGISTER + 1; i < max_parm_reg; i++)
3903: use_variable (regno_reg_rtx[i]);
3904:
3905: /* Likewise for the regs of all the SAVE_EXPRs in the function. */
3906:
3907: for (tem = save_expr_regs; tem; tem = XEXP (tem, 1))
3908: {
3909: use_variable (XEXP (tem, 0));
3910: use_variable_after (XEXP (tem, 0), parm_birth_insn);
3911: }
3912:
3913: if (current_function_internal_arg_pointer != virtual_incoming_args_rtx)
3914: use_variable (current_function_internal_arg_pointer);
3915: }
3916:
3917: clear_pending_stack_adjust ();
3918: do_pending_stack_adjust ();
3919:
3920: /* Mark the end of the function body.
3921: If control reaches this insn, the function can drop through
3922: without returning a value. */
3923: emit_note (0, NOTE_INSN_FUNCTION_END);
3924:
3925: /* Output a linenumber for the end of the function.
3926: SDB depends on this. */
3927: emit_line_note_force (filename, line);
3928:
3929: /* Output the label for the actual return from the function,
3930: if one is expected. This happens either because a function epilogue
3931: is used instead of a return instruction, or because a return was done
3932: with a goto in order to run local cleanups, or because of pcc-style
3933: structure returning. */
3934:
3935: if (return_label)
3936: emit_label (return_label);
3937:
3938: /* If we had calls to alloca, and this machine needs
3939: an accurate stack pointer to exit the function,
3940: insert some code to save and restore the stack pointer. */
3941: #ifdef EXIT_IGNORE_STACK
3942: if (! EXIT_IGNORE_STACK)
3943: #endif
3944: if (current_function_calls_alloca)
3945: {
3946: rtx tem = gen_reg_rtx (Pmode);
3947: emit_insn_after (gen_rtx (SET, VOIDmode, tem, stack_pointer_rtx),
3948: parm_birth_insn);
3949: emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx, tem));
3950: }
3951:
3952: /* If scalar return value was computed in a pseudo-reg,
3953: copy that to the hard return register. */
3954: if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
3955: && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
3956: && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
3957: >= FIRST_PSEUDO_REGISTER))
3958: {
3959: rtx real_decl_result;
3960:
3961: #ifdef FUNCTION_OUTGOING_VALUE
3962: real_decl_result
3963: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
3964: current_function_decl);
3965: #else
3966: real_decl_result
3967: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
3968: current_function_decl);
3969: #endif
3970: REG_FUNCTION_VALUE_P (real_decl_result) = 1;
3971: emit_move_insn (real_decl_result,
3972: DECL_RTL (DECL_RESULT (current_function_decl)));
3973: emit_insn (gen_rtx (USE, VOIDmode, real_decl_result));
3974: }
3975:
3976: /* If returning a structure, arrange to return the address of the value
3977: in a place where debuggers expect to find it.
3978:
3979: If returning a structure PCC style,
3980: the caller also depends on this value.
3981: And current_function_returns_pcc_struct is not necessarily set. */
3982: if (current_function_returns_struct
3983: || current_function_returns_pcc_struct)
3984: {
3985: rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
3986: tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
3987: #ifdef FUNCTION_OUTGOING_VALUE
3988: rtx outgoing
3989: = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
3990: current_function_decl);
3991: #else
3992: rtx outgoing
3993: = FUNCTION_VALUE (build_pointer_type (type),
3994: current_function_decl);
3995: #endif
3996:
3997: /* Mark this as a function return value so integrate will delete the
3998: assignment and USE below when inlining this function. */
3999: REG_FUNCTION_VALUE_P (outgoing) = 1;
4000:
4001: emit_move_insn (outgoing, value_address);
4002: use_variable (outgoing);
4003: }
4004:
4005: /* Output a return insn if we are using one.
4006: Otherwise, let the rtl chain end here, to drop through
4007: into the epilogue. */
4008:
4009: #ifdef HAVE_return
4010: if (HAVE_return)
4011: {
4012: emit_jump_insn (gen_return ());
4013: emit_barrier ();
4014: }
4015: #endif
4016:
4017: /* Fix up any gotos that jumped out to the outermost
4018: binding level of the function.
4019: Must follow emitting RETURN_LABEL. */
4020:
4021: /* If you have any cleanups to do at this point,
4022: and they need to create temporary variables,
4023: then you will lose. */
4024: fixup_gotos (0, 0, 0, get_insns (), 0);
4025: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.