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