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