|
|
1.1 root 1: /* Expands front end tree to back end RTL for GNU C-Compiler
2: Copyright (C) 1987,1988 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* This file handles the generation of rtl code from tree structure
23: above the level of expressions, using subroutines in exp*.c and emit-rtl.c.
24: It also creates the rtl expressions for parameters and auto variables
25: and has full responsibility for allocating stack slots.
26:
27: The functions whose names start with `expand_' are called by the
28: parser to generate RTL instructions for various kinds of constructs.
29:
30: Some control and binding constructs require calling several such
31: functions at different times. For example, a simple if-then
32: is expanded by calling `expand_start_cond' (with the condition-expression
33: as argument) before parsing the then-clause and calling `expand_end_cond'
34: after parsing the then-clause.
35:
36: `expand_start_function' is called at the beginning of a function,
37: before the function body is parsed, and `expand_end_function' is
38: called after parsing the body.
39:
40: Call `assign_stack_local' to allocate a stack slot for a local variable.
41: This is usually done during the RTL generation for the function body,
42: but it can also be done in the reload pass when a pseudo-register does
43: not get a hard register.
44:
45: Call `put_var_into_stack' when you learn, belatedly, that a variable
46: previously given a pseudo-register must in fact go in the stack.
47: This function changes the DECL_RTL to be a stack slot instead of a reg
48: then scans all the RTL instructions so far generated to correct them. */
49:
50: #include "config.h"
51:
52: #include <stdio.h>
53:
54: #include "rtl.h"
55: #include "tree.h"
56: #include "flags.h"
57: #include "insn-flags.h"
58: #include "insn-config.h"
59: #include "expr.h"
60: #include "regs.h"
61:
62: #define MAX(x,y) (((x) > (y)) ? (x) : (y))
63: #define MIN(x,y) (((x) < (y)) ? (x) : (y))
64:
65: /* Nonzero if function being compiled pops its args on return.
66: May affect compilation of return insn or of function epilogue. */
67:
68: int current_function_pops_args;
69:
70: /* If function's args have a fixed size, this is that size, in bytes.
71: Otherwise, it is -1.
72: May affect compilation of return insn or of function epilogue. */
73:
74: int current_function_args_size;
75:
76: /* # bytes the prologue should push and pretend that the caller pushed them.
77: The prologue must do this, but only if parms can be passed in registers. */
78:
79: int current_function_pretend_args_size;
80:
81: /* Name of function now being compiled. */
82:
83: char *current_function_name;
84:
85: /* Label that will go on function epilogue.
86: Jumping to this label serves as a "return" instruction
87: on machines which require execution of the epilogue on all returns. */
88:
89: rtx return_label;
90:
91: /* The FUNCTION_DECL node for the function being compiled. */
92:
93: static tree this_function;
94:
95: /* Offset to end of allocated area of stack frame.
96: If stack grows down, this is the address of the last stack slot allocated.
97: If stack grows up, this is the address for the next slot. */
98: static int frame_offset;
99:
100: /* Nonzero if a stack slot has been generated whose address is not
101: actually valid. It means that the generated rtl must all be scanned
102: to detect and correct the invalid addresses where they occur. */
103: static int invalid_stack_slot;
104:
105: /* Label to jump back to for tail recursion, or 0 if we have
106: not yet needed one for this function. */
107: static rtx tail_recursion_label;
108:
109: /* Place after which to insert the tail_recursion_label if we need one. */
110: static rtx tail_recursion_reentry;
111:
112: /* Each time we expand an expression-statement,
113: record the expr's type and its RTL value here. */
114:
115: static tree last_expr_type;
116: static rtx last_expr_value;
117:
118: static void fixup_gotos ();
119: static int tail_recursion_args ();
120: void fixup_stack_slots ();
121: static rtx fixup_stack_1 ();
122: static rtx fixup_memory_subreg ();
123: static void fixup_var_refs ();
124: static rtx fixup_var_refs_1 ();
125: static rtx parm_stack_loc ();
126: static void optimize_bit_field ();
127: void do_jump_if_equal ();
128:
129: /* Stack of control and binding constructs we are currently inside.
130:
131: These constructs begin when you call `expand_start_WHATEVER'
132: and end when you call `expand_end_WHATEVER'. This stack records
133: info about how the construct began that tells the end-function
134: what to do. It also may provide information about the construct
135: to alter the behavior of other constructs within the body.
136: For example, they may affect the behavior of C `break' and `continue'.
137:
138: Each construct gets one `struct nesting' object.
139: All of these objects are chained through the `all' field.
140: `nesting_stack' points to the first object (innermost construct).
141: The position of an entry on `nesting_stack' is in its `depth' field.
142:
143: Each type of construct has its own individual stack.
144: For example, loops have `loop_stack'. Each object points to the
145: next object of the same type through the `next' field.
146:
147: Some constructs are visible to `break' exit-statements and others
148: are not. Which constructs are visible depends on the language.
149: Therefore, the data structure allows each construct to be visible
150: or not, according to the args given when the construct is started.
151: The construct is visible if the `exit_label' field is non-null.
152: In that case, the value should be a CODE_LABEL rtx. */
153:
154: struct nesting
155: {
156: struct nesting *all;
157: struct nesting *next;
158: int depth;
159: rtx exit_label;
160: union
161: {
162: /* For conds (if-then and if-then-else statements). */
163: struct
164: {
165: /* Label on the else-part, if any, else 0. */
166: rtx else_label;
167: /* Label at the end of the whole construct. */
168: rtx after_label;
169: } cond;
170: /* For loops. */
171: struct
172: {
173: /* Label at the top of the loop; place to loop back to. */
174: rtx start_label;
175: /* Label at the end of the whole construct. */
176: rtx end_label;
177: /* Label for `continue' statement to jump to;
178: this is in front of the stepper of the loop. */
179: rtx continue_label;
180: } loop;
181: /* For variable binding contours. */
182: struct
183: {
184: /* Nonzero => value to restore stack to on exit. */
185: rtx stack_level;
186: /* The NOTE that starts this contour.
187: Used by expand_goto to check whether the destination
188: is within each contour or not. */
189: rtx first_insn;
190: /* Innermost containing binding contour that has a stack level. */
191: struct nesting *innermost_stack_block;
192: /* Chain of labels defined inside this binding contour.
193: Only for contours that have stack levels. */
194: struct label_chain *label_chain;
195: } block;
196: /* For switch (C) or case (Pascal) statements,
197: and also for dummies (see `expand_start_case_dummy'). */
198: struct
199: {
200: /* The insn after which the case dispatch should finally
201: be emitted. Zero for a dummy. */
202: rtx start;
203: /* A list of the case-values and their labels.
204: A chain of TREE_LIST nodes with the value to test for
205: (a constant node) in the TREE_PURPOSE and the
206: label (a LABEL_DECL) in the TREE_VALUE. */
207: tree case_list;
208: /* The expression to be dispatched on. */
209: tree index_expr;
210: /* Type that INDEX_EXPR should be converted to. */
211: tree nominal_type;
212: } case_stmt;
213: } data;
214: };
215:
216: /* Chain of all pending binding contours. */
217: struct nesting *block_stack;
218:
219: /* Chain of all pending binding contours that restore stack levels. */
220: struct nesting *stack_block_stack;
221:
222: /* Chain of all pending conditional statements. */
223: struct nesting *cond_stack;
224:
225: /* Chain of all pending loops. */
226: struct nesting *loop_stack;
227:
228: /* Chain of all pending case or switch statements. */
229: struct nesting *case_stack;
230:
231: /* Separate chain including all of the above,
232: chained through the `all' field. */
233: struct nesting *nesting_stack;
234:
235: /* Number of entries on nesting_stack now. */
236: int nesting_depth;
237:
238: /* Pop one of the sub-stacks, such as `loop_stack' or `cond_stack';
239: and pop off `nesting_stack' down to the same level. */
240:
241: #define POPSTACK(STACK) \
242: do { int initial_depth = nesting_stack->depth; \
243: do { struct nesting *this = STACK; \
244: STACK = this->next; \
245: nesting_stack = this->all; \
246: nesting_depth = this->depth; \
247: free (this); } \
248: while (nesting_depth > initial_depth); } while (0)
249:
250: /* Return the rtx-label that corresponds to a LABEL_DECL,
251: creating it if necessary. */
252:
253: static rtx
254: label_rtx (label)
255: tree label;
256: {
257: if (TREE_CODE (label) != LABEL_DECL)
258: abort ();
259:
260: if (DECL_RTL (label))
261: return DECL_RTL (label);
262:
263: return DECL_RTL (label) = gen_label_rtx ();
264: }
265:
266: /* Add an unconditional jump to LABEL as the next sequential instruction. */
267:
268: void
269: emit_jump (label)
270: rtx label;
271: {
272: do_pending_stack_adjust ();
273: emit_jump_insn (gen_jump (label));
274: emit_barrier ();
275: }
276:
277: /* Handle goto statements and the labels that they can go to. */
278:
279: /* In some cases it is impossible to generate code for a forward goto
280: until the label definition is seen. This happens when it may be necessary
281: for the goto to reset the stack pointer: we don't yet know how to do that.
282: So expand_goto puts an entry on this fixup list.
283: Each time a binding contour that resets the stack is exited,
284: we check each fixup.
285: If the target label has now been defined, we can insert the proper code. */
286:
287: struct goto_fixup
288: {
289: /* Points to following fixup. */
290: struct goto_fixup *next;
291: /* Points to the insn before the jump insn.
292: If more code must be inserted, it goes after this insn. */
293: rtx before_jump;
294: /* The LABEL_DECL that this jump is jumping to. */
295: tree target;
296: /* The outermost stack level that should be restored for this jump.
297: Each time a binding contour that resets the stack is exited,
298: if the target label is *not* yet defined, this slot is updated. */
299: rtx stack_level;
300: };
301:
302: static struct goto_fixup *goto_fixup_chain;
303:
304: /* Within any binding contour that must restore a stack level,
305: all labels are recorded with a chain of these structures. */
306:
307: struct label_chain
308: {
309: /* Points to following fixup. */
310: struct label_chain *next;
311: tree label;
312: };
313:
314: /* Specify the location in the RTL code of a label BODY,
315: which is a LABEL_DECL tree node.
316:
317: This is used for the kind of label that the user can jump to with a
318: goto statement, and for alternatives of a switch or case statement.
319: RTL labels generated for loops and conditionals don't go through here;
320: they are generated directly at the RTL level, by other functions below.
321:
322: Note that this has nothing to do with defining label *names*.
323: Languages vary in how they do that and what that even means. */
324:
325: void
326: expand_label (body)
327: tree body;
328: {
329: struct label_chain *p;
330:
331: do_pending_stack_adjust ();
332: emit_label (label_rtx (body));
333:
334: if (stack_block_stack)
335: {
336: p = (struct label_chain *) oballoc (sizeof (struct label_chain));
337: p->next = stack_block_stack->data.block.label_chain;
338: stack_block_stack->data.block.label_chain = p;
339: p->label = body;
340: }
341: }
342:
343: /* Generate RTL code for a `goto' statement with target label BODY.
344: BODY should be a LABEL_DECL tree node that was or will later be
345: defined with `expand_label'. */
346:
347: void
348: expand_goto (body)
349: tree body;
350: {
351: struct nesting *block;
352: rtx stack_level = 0;
353: rtx label = label_rtx (body);
354:
355: if (GET_CODE (label) != CODE_LABEL)
356: abort ();
357:
358: /* If label has already been defined, we can tell now
359: whether and how we must alter the stack level. */
360:
361: if (DECL_SOURCE_LINE (body) != 0)
362: {
363: /* Find the outermost pending block that contains the label.
364: (Check containment by comparing insn-uids.)
365: Then restore the outermost stack level within that block. */
366: for (block = block_stack; block; block = block->next)
367: {
368: if (INSN_UID (block->data.block.first_insn) < INSN_UID (label))
369: break;
370: if (block->data.block.stack_level != 0)
371: stack_level = block->data.block.stack_level;
372: }
373:
374: if (stack_level)
375: emit_move_insn (stack_pointer_rtx, stack_level);
376:
377: if (TREE_PACKED (body))
378: error ("goto \"%s\" invalidly jumps into binding contour",
379: IDENTIFIER_POINTER (DECL_NAME (body)));
380: }
381: /* Label not yet defined: may need to put this goto
382: on the fixup list. */
383: else
384: {
385: /* Does any containing block have a stack level?
386: If not, no fixup is needed, and that is the normal case
387: (the only case, for standard C). */
388: for (block = block_stack; block; block = block->next)
389: if (block->data.block.stack_level != 0)
390: break;
391:
392: if (block)
393: {
394: /* Ok, a fixup is needed. Add a fixup to the list of such. */
395: struct goto_fixup *fixup
396: = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
397: /* In case an old stack level is restored, make sure that comes
398: after any pending stack adjust. */
399: do_pending_stack_adjust ();
400: fixup->before_jump = get_last_insn ();
401: fixup->target = body;
402: fixup->stack_level = 0;
403: fixup->next = goto_fixup_chain;
404: goto_fixup_chain = fixup;
405: }
406: else
407: /* No fixup needed. Record that the label is the target
408: of at least one goto that has no fixup. */
409: TREE_ADDRESSABLE (body) = 1;
410: }
411:
412: emit_jump (label);
413: }
414:
415: /* When exiting a binding contour, process all pending gotos requiring fixups.
416: STACK_LEVEL is the rtx for the stack level to restore on exit from
417: this contour. FIRST_INSN is the insn that begain this contour.
418: Gotos that jump out of this contour must restore the
419: stack level before actually jumping.
420:
421: Also print an error message if any fixup describes a jump into this
422: contour from before the beginning of the contour. */
423:
424: static void
425: fixup_gotos (stack_level, first_insn)
426: rtx stack_level;
427: rtx first_insn;
428: {
429: register struct goto_fixup *f;
430:
431: for (f = goto_fixup_chain; f; f = f->next)
432: {
433: /* Test for a fixup that is inactive because it is already handled. */
434: if (f->before_jump == 0)
435: ;
436: /* Has this fixup's target label been defined?
437: If so, we can finalize it. */
438: else if (DECL_SOURCE_LINE (f->target) != 0)
439: {
440: /* If this fixup jumped into this contour from before the beginning
441: of this contour, report an error. */
442: if (INSN_UID (first_insn) > INSN_UID (f->before_jump)
443: && ! TREE_ADDRESSABLE (f->target))
444: {
445: error_with_file_and_line (DECL_SOURCE_FILE (f->target),
446: DECL_SOURCE_LINE (f->target),
447: "label \"%s\" was used \
448: before containing binding contour",
449: IDENTIFIER_POINTER (DECL_NAME (f->target)));
450: /* Prevent multiple errors for one label. */
451: TREE_ADDRESSABLE (f->target) = 1;
452: }
453:
454: /* Restore stack level for the biggest contour that this
455: jump jumps out of. */
456: if (f->stack_level)
457: emit_insn_after (gen_move_insn (stack_pointer_rtx, f->stack_level),
458: f->before_jump);
459: f->before_jump = 0;
460: }
461: /* Label has still not appeared. If we are exiting a block with
462: a stack level to restore, mark this stack level as needing
463: restoration when the fixup is later finalized. */
464: else if (stack_level)
465: f->stack_level = stack_level;
466: }
467: }
468:
469: /* Generate RTL for an asm statement (explicit assembler code).
470: BODY is a STRING_CST node containing the assembler code text. */
471:
472: void
473: expand_asm (body)
474: tree body;
475: {
476: emit_insn (gen_rtx (ASM_INPUT, VOIDmode,
477: TREE_STRING_POINTER (body)));
478: last_expr_type = 0;
479: }
480:
481: /* Generate RTL for an asm statement with arguments.
482: STRING is the instruction template.
483: OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
484: Each output or input has an expression in the TREE_VALUE and
485: a constraint-string in the TREE_PURPOSE.
486:
487: Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
488: Some elements of OUTPUTS may be replaced with trees representing temporary
489: values. The caller should copy those temporary values to the originally
490: specified lvalues.
491:
492: VOL nonzero means the insn is volatile; don't optimize it. */
493:
494: void
495: expand_asm_operands (string, outputs, inputs, vol)
496: tree string, outputs, inputs;
497: int vol;
498: {
499: rtvec argvec, constraints;
500: rtx body;
501: int ninputs = list_length (inputs);
502: int noutputs = list_length (outputs);
503: int numargs = 0;
504: tree tail;
505: int i;
506:
507: if (ninputs + noutputs > MAX_RECOG_OPERANDS)
508: {
509: error ("more than %d operands in `asm'", MAX_RECOG_OPERANDS);
510: return;
511: }
512:
513: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
514: {
515: tree val = TREE_VALUE (tail);
516:
517: /* If an output operand is not a variable or indirect ref,
518: create a SAVE_EXPR which is a pseudo-reg
519: to act as an intermediate temporary.
520: Make the asm insn write into that, then copy it to
521: the real output operand. */
522:
523: if (TREE_CODE (val) != VAR_DECL
524: && TREE_CODE (val) != PARM_DECL
525: && TREE_CODE (val) != INDIRECT_REF)
526: TREE_VALUE (tail) = build (SAVE_EXPR, TREE_TYPE (val), val,
527: gen_reg_rtx (TYPE_MODE (TREE_TYPE (val))));
528: }
529:
530: /* Make vectors for the expression-rtx and constraint strings. */
531:
532: if (ninputs > 0)
533: {
534: argvec = rtvec_alloc (ninputs);
535: constraints = rtvec_alloc (ninputs);
536: }
537: else
538: argvec = constraints = 0;
539:
540: body = gen_rtx (ASM_OPERANDS, VOIDmode,
541: TREE_STRING_POINTER (string), "", 0, argvec, constraints);
542: body->volatil = vol;
543:
544: /* Eval the inputs and put them into ARGVEC.
545: Put their constraints into ASM_INPUTs and store in CONSTRAINTS. */
546:
547: i = 0;
548: for (tail = inputs; tail; tail = TREE_CHAIN (tail))
549: {
550: XVECEXP (body, 3, i) /* argvec */
551: = expand_expr (TREE_VALUE (tail), 0, VOIDmode, 0);
552: XVECEXP (body, 4, i) /* constraints */
553: = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
554: TREE_STRING_POINTER (TREE_PURPOSE (tail)));
555: i++;
556: }
557:
558: /* Now, for each output, construct an rtx
559: (set OUTPUT (asm_operands INSN OUTPUTNUMBER OUTPUTCONSTRAINT
560: ARGVEC CONSTRAINTS))
561: If there is more than one, put them inside a PARALLEL. */
562:
563: if (noutputs == 1)
564: {
565: tree val = TREE_VALUE (outputs);
566:
567: XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
568: emit_insn (gen_rtx (SET, VOIDmode,
569: expand_expr (val, 0, VOIDmode, 0),
570: body));
571: }
572: else
573: {
574: body = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (noutputs));
575:
576: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
577: {
578: tree val = TREE_VALUE (tail);
579:
580: XVECEXP (body, 0, i)
581: = gen_rtx (SET, VOIDmode,
582: expand_expr (val, 0, VOIDmode, 0),
583: gen_rtx (ASM_OPERANDS, VOIDmode,
584: TREE_STRING_POINTER (string),
585: TREE_STRING_POINTER (TREE_PURPOSE (tail)),
586: i, argvec, constraints));
587: SET_SRC (XVECEXP (body, 0, i))->volatil = vol;
588: }
589:
590: emit_insn (body);
591: }
592: last_expr_type = 0;
593: }
594:
595: /* Nonzero if within a ({...}) grouping, in which case we must
596: always compute a value for each expr-stmt in case it is the last one. */
597:
598: int expr_stmts_for_value;
599:
600: /* Generate RTL to evaluate the expression EXP
601: and remember it in case this is the VALUE in a ({... VALUE; }) constr. */
602:
603: void
604: expand_expr_stmt (exp)
605: tree exp;
606: {
607: last_expr_type = TREE_TYPE (exp);
608: last_expr_value = expand_expr (exp, expr_stmts_for_value ? 0 : const0_rtx,
609: VOIDmode, 0);
610: emit_queue ();
611: }
612:
613: /* Clear out the memory of the last expression evaluated. */
614:
615: void
616: clear_last_expr ()
617: {
618: last_expr_type = 0;
619: }
620:
621: /* Return a tree node that refers to the last expression evaluated.
622: The nodes of that expression have been freed by now, so we cannot use them.
623: But we don't want to do that anyway; the expression has already been
624: evaluated and now we just want to use the value. So generate a SAVE_EXPR
625: with the proper type and RTL value.
626:
627: If the last statement was not an expression,
628: return something with type `void'. */
629:
630: tree
631: get_last_expr ()
632: {
633: tree t;
634:
635: if (last_expr_type == 0)
636: {
637: last_expr_type = void_type_node;
638: last_expr_value = const0_rtx;
639: }
640: t = build (RTL_EXPR, last_expr_type, NULL, NULL);
641: RTL_EXPR_RTL (t) = last_expr_value;
642: RTL_EXPR_SEQUENCE (t) = gen_sequence ();
643: return t;
644: }
645:
646: void
647: expand_start_stmt_expr ()
648: {
649: extern int emit_to_sequence;
650: expr_stmts_for_value++;
651: emit_to_sequence++;
652: }
653:
654: void
655: expand_end_stmt_expr ()
656: {
657: extern int emit_to_sequence;
658: expr_stmts_for_value--;
659: emit_to_sequence--;
660: }
661:
662: /* Generate RTL for the start of an if-then. COND is the expression
663: whose truth should be tested.
664:
665: If EXITFLAG is nonzero, this conditional is visible to
666: `exit_something'. */
667:
668: void
669: expand_start_cond (cond, exitflag)
670: tree cond;
671: int exitflag;
672: {
673: struct nesting *thiscond
674: = (struct nesting *) xmalloc (sizeof (struct nesting));
675:
676: /* Make an entry on cond_stack for the cond we are entering. */
677:
678: thiscond->next = cond_stack;
679: thiscond->all = nesting_stack;
680: thiscond->depth = ++nesting_depth;
681: thiscond->data.cond.after_label = 0;
682: thiscond->data.cond.else_label = gen_label_rtx ();
683: thiscond->exit_label = exitflag ? thiscond->data.cond.else_label : 0;
684: cond_stack = thiscond;
685: nesting_stack = thiscond;
686:
687: do_jump (cond, thiscond->data.cond.else_label, NULL);
688: }
689:
690: /* Generate RTL for the end of an if-then with no else-clause.
691: Pop the record for it off of cond_stack. */
692:
693: void
694: expand_end_cond ()
695: {
696: struct nesting *thiscond = cond_stack;
697:
698: do_pending_stack_adjust ();
699: emit_label (thiscond->data.cond.else_label);
700:
701: POPSTACK (cond_stack);
702: last_expr_type = 0;
703: }
704:
705: /* Generate RTL between the then-clause and the else-clause
706: of an if-then-else. */
707:
708: void
709: expand_start_else ()
710: {
711: cond_stack->data.cond.after_label = gen_label_rtx ();
712: if (cond_stack->exit_label != 0)
713: cond_stack->exit_label = cond_stack->data.cond.after_label;
714: emit_jump (cond_stack->data.cond.after_label);
715: if (cond_stack->data.cond.else_label)
716: emit_label (cond_stack->data.cond.else_label);
717: }
718:
719: /* Generate RTL for the end of an if-then-else.
720: Pop the record for it off of cond_stack. */
721:
722: void
723: expand_end_else ()
724: {
725: struct nesting *thiscond = cond_stack;
726:
727: do_pending_stack_adjust ();
728: /* Note: a syntax error can cause this to be called
729: without first calling `expand_start_else'. */
730: if (thiscond->data.cond.after_label)
731: emit_label (thiscond->data.cond.after_label);
732:
733: POPSTACK (cond_stack);
734: last_expr_type = 0;
735: }
736:
737: /* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this
738: loop should be exited by `exit_something'. This is a loop for which
739: `expand_continue' will jump to the top of the loop.
740:
741: Make an entry on loop_stack to record the labels associated with
742: this loop. */
743:
744: void
745: expand_start_loop (exit_flag)
746: int exit_flag;
747: {
748: register struct nesting *thisloop
749: = (struct nesting *) xmalloc (sizeof (struct nesting));
750:
751: /* Make an entry on loop_stack for the loop we are entering. */
752:
753: thisloop->next = loop_stack;
754: thisloop->all = nesting_stack;
755: thisloop->depth = ++nesting_depth;
756: thisloop->data.loop.start_label = gen_label_rtx ();
757: thisloop->data.loop.end_label = gen_label_rtx ();
758: thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
759: thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
760: loop_stack = thisloop;
761: nesting_stack = thisloop;
762:
763: do_pending_stack_adjust ();
764: emit_queue ();
765: emit_note (0, NOTE_INSN_LOOP_BEG);
766: emit_label (thisloop->data.loop.start_label);
767: }
768:
769: /* Like expand_start_loop but for a loop where the continuation point
770: (for expand_continue_loop) will be specified explicitly. */
771:
772: void
773: expand_start_loop_continue_elsewhere (exit_flag)
774: int exit_flag;
775: {
776: expand_start_loop (exit_flag);
777: loop_stack->data.loop.continue_label = gen_label_rtx ();
778: }
779:
780: /* Specify the continuation point for a loop started with
781: expand_start_loop_continue_elsewhere.
782: Use this at the point in the code to which a continue statement
783: should jump. */
784:
785: void
786: expand_loop_continue_here ()
787: {
788: do_pending_stack_adjust ();
789: emit_label (loop_stack->data.loop.continue_label);
790: }
791:
792: /* Finish a loop. Generate a jump back to the top and the loop-exit label.
793: Pop the block off of loop_stack. */
794:
795: void
796: expand_end_loop ()
797: {
798: register struct nesting *thisloop = loop_stack;
799: register rtx insn = get_last_insn ();
800: register rtx start_label = loop_stack->data.loop.start_label;
801:
802: do_pending_stack_adjust ();
803:
804: /* If optimizing, perhaps reorder the loop. If the loop
805: starts with a conditional exit, roll that to the end
806: where it will optimize together with the jump back. */
807: if (optimize
808: &&
809: ! (GET_CODE (insn) == JUMP_INSN
810: && GET_CODE (PATTERN (insn)) == SET
811: && SET_DEST (PATTERN (insn)) == pc_rtx
812: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))
813: {
814: /* Scan insns from the top of the loop looking for a qualified
815: conditional exit. */
816: for (insn = loop_stack->data.loop.start_label; insn; insn= NEXT_INSN (insn))
817: if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET
818: && SET_DEST (PATTERN (insn)) == pc_rtx
819: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE
820: &&
821: ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF
822: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
823: == loop_stack->data.loop.end_label))
824: ||
825: (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
826: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
827: == loop_stack->data.loop.end_label))))
828: break;
829: if (insn != 0)
830: {
831: /* We found one. Move everything from there up
832: to the end of the loop, and add a jump into the loop
833: to jump to there. */
834: register rtx newstart_label = gen_label_rtx ();
835:
836: emit_label_after (newstart_label, PREV_INSN (start_label));
837: reorder_insns (start_label, insn, get_last_insn ());
838: emit_jump_insn_after (gen_jump (start_label), PREV_INSN (newstart_label));
839: emit_barrier_after (PREV_INSN (newstart_label));
840: start_label = newstart_label;
841: }
842: }
843:
844: emit_jump (start_label);
845: emit_note (0, NOTE_INSN_LOOP_END);
846: emit_label (loop_stack->data.loop.end_label);
847:
848: POPSTACK (loop_stack);
849:
850: last_expr_type = 0;
851: }
852:
853: /* Generate a jump to the current loop's continue-point.
854: This is usually the top of the loop, but may be specified
855: explicitly elsewhere. If not currently inside a loop,
856: return 0 and do nothing; caller will print an error message. */
857:
858: int
859: expand_continue_loop ()
860: {
861: last_expr_type = 0;
862: if (loop_stack == 0)
863: return 0;
864: emit_jump (loop_stack->data.loop.continue_label);
865: return 1;
866: }
867:
868: /* Generate a jump to exit the current loop. If not currently inside a loop,
869: return 0 and do nothing; caller will print an error message. */
870:
871: int
872: expand_exit_loop ()
873: {
874: last_expr_type = 0;
875: if (loop_stack == 0)
876: return 0;
877: emit_jump (loop_stack->data.loop.end_label);
878: return 1;
879: }
880:
881: /* Generate a conditional jump to exit the current loop if COND
882: evaluates to zero. If not currently inside a loop,
883: return 0 and do nothing; caller will print an error message. */
884:
885: int
886: expand_exit_loop_if_false (cond)
887: tree cond;
888: {
889: last_expr_type = 0;
890: if (loop_stack == 0)
891: return 0;
892: do_jump (cond, loop_stack->data.loop.end_label, NULL);
893: return 1;
894: }
895:
896: /* Generate a jump to exit the current loop, conditional, binding contour
897: or case statement. Not all such constructs are visible to this function,
898: only those started with EXIT_FLAG nonzero. Individual languages use
899: the EXIT_FLAG parameter to control which kinds of constructs you can
900: exit this way.
901:
902: If not currently inside anything that can be exited,
903: return 0 and do nothing; caller will print an error message. */
904:
905: int
906: expand_exit_something ()
907: {
908: struct nesting *n;
909: last_expr_type = 0;
910: for (n = nesting_stack; n; n = n->all)
911: {
912: if (n->exit_label != 0)
913: {
914: emit_jump (n->exit_label);
915: return 1;
916: }
917: }
918: return 0;
919: }
920:
921: /* Generate RTL to return from the current function, with no value.
922: (That is, we do not do anything about returning any value.) */
923:
924: void
925: expand_null_return ()
926: {
927: clear_pending_stack_adjust ();
928: #ifdef FUNCTION_EPILOGUE
929: emit_jump (return_label);
930: #else
931: emit_jump_insn (gen_return ());
932: emit_barrier ();
933: #endif
934: last_expr_type = 0;
935: }
936:
937: /* Generate RTL to evaluate the expression RETVAL and return it
938: from the current function. */
939:
940: void
941: expand_return (retval)
942: tree retval;
943: {
944: register rtx val = 0;
945: register rtx op0;
946: int really_for_value =
947: (TREE_CODE (retval) == MODIFY_EXPR
948: && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL);
949:
950: /* For tail-recursive call to current function,
951: just jump back to the beginning.
952: It's unsafe if any auto variable in this function
953: has its address taken; for simplicity,
954: require stack frame to be empty. */
955: if (optimize && really_for_value
956: && frame_offset == STARTING_FRAME_OFFSET
957: && TREE_CODE (TREE_OPERAND (retval, 1)) == CALL_EXPR
958: && TREE_CODE (TREE_OPERAND (TREE_OPERAND (retval, 1), 0)) == ADDR_EXPR
959: && TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (retval, 1), 0), 0) == this_function
960: /* Finish checking validity, and if valid emit code
961: to set the argument variables for the new call. */
962: && tail_recursion_args (TREE_OPERAND (TREE_OPERAND (retval, 1), 1),
963: DECL_ARGUMENTS (this_function)))
964: {
965: ;
966: if (tail_recursion_label == 0)
967: {
968: tail_recursion_label = gen_label_rtx ();
969: emit_label_after (tail_recursion_label,
970: tail_recursion_reentry);
971: }
972: emit_jump (tail_recursion_label);
973: emit_barrier ();
974: return;
975: }
976: #ifndef FUNCTION_EPILOGUE
977: /* If this is return x == y; then generate
978: if (x == y) return 1; else return 0;
979: if we can do it with explicit return insns. */
980: if (really_for_value)
981: switch (TREE_CODE (TREE_OPERAND (retval, 1)))
982: {
983: case EQ_EXPR:
984: case NE_EXPR:
985: case GT_EXPR:
986: case GE_EXPR:
987: case LT_EXPR:
988: case LE_EXPR:
989: case TRUTH_ANDIF_EXPR:
990: case TRUTH_ORIF_EXPR:
991: case TRUTH_NOT_EXPR:
992: op0 = gen_label_rtx ();
993: val = DECL_RTL (DECL_RESULT (this_function));
994: jumpifnot (TREE_OPERAND (retval, 1), op0);
995: emit_move_insn (val, const1_rtx);
996: emit_insn (gen_rtx (USE, VOIDmode, val));
997: expand_null_return ();
998: emit_label (op0);
999: emit_move_insn (val, const0_rtx);
1000: emit_insn (gen_rtx (USE, VOIDmode, val));
1001: expand_null_return ();
1002: return;
1003: }
1004: #endif
1005: val = expand_expr (retval, 0, VOIDmode, 0);
1006: emit_queue ();
1007:
1008: if (really_for_value && GET_CODE (val) == REG)
1009: emit_insn (gen_rtx (USE, VOIDmode, val));
1010:
1011: expand_null_return ();
1012: }
1013:
1014: /* Return 1 if the end of the generated RTX is not a barrier.
1015: This means code already compiled can drop through. */
1016:
1017: int
1018: drop_through_at_end_p ()
1019: {
1020: rtx insn = get_last_insn ();
1021: while (insn && GET_CODE (insn) == NOTE)
1022: insn = PREV_INSN (insn);
1023: return insn && GET_CODE (insn) != BARRIER;
1024: }
1025:
1026: /* Emit code to alter this function's formal parms for a tail-recursive call.
1027: ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
1028: FORMALS is the chain of decls of formals.
1029: Return 1 if this can be done;
1030: otherwise return 0 and do not emit any code. */
1031:
1032: static int
1033: tail_recursion_args (actuals, formals)
1034: tree actuals, formals;
1035: {
1036: register tree a = actuals, f = formals;
1037: register int i;
1038: register rtx *argvec;
1039:
1040: /* Check that number and types of actuals are compatible
1041: with the formals. This is not always true in valid C code.
1042: Also check that no formal needs to be addressable
1043: and that all formals are scalars. */
1044:
1045: /* Also count the args. */
1046:
1047: for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
1048: {
1049: if (TREE_TYPE (TREE_VALUE (a)) != TREE_TYPE (f))
1050: return 0;
1051: if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
1052: return 0;
1053: }
1054: if (a != 0 || f != 0)
1055: return 0;
1056:
1057: /* Compute all the actuals. */
1058:
1059: argvec = (rtx *) alloca (i * sizeof (rtx));
1060:
1061: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1062: argvec[i] = expand_expr (TREE_VALUE (a), 0, VOIDmode, 0);
1063:
1064: /* Find which actual values refer to current values of previous formals.
1065: Copy each of them now, before any formal is changed. */
1066:
1067: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1068: {
1069: int copy = 0;
1070: register int j;
1071: for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
1072: if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
1073: { copy = 1; break; }
1074: if (copy)
1075: argvec[i] = copy_to_reg (argvec[i]);
1076: }
1077:
1078: /* Store the values of the actuals into the formals. */
1079:
1080: for (f = formals, a = actuals, i = 0; f;
1081: f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
1082: {
1083: if (DECL_MODE (f) == GET_MODE (argvec[i]))
1084: emit_move_insn (DECL_RTL (f), argvec[i]);
1085: else
1086: convert_move (DECL_RTL (f), argvec[i],
1087: TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
1088: }
1089:
1090: return 1;
1091: }
1092:
1093: /* Generate the RTL code for entering a binding contour.
1094: The variables are declared one by one, by calls to `expand_decl'.
1095:
1096: EXIT_FLAG is nonzero if this construct should be visible to
1097: `exit_something'. */
1098:
1099: void
1100: expand_start_bindings (exit_flag)
1101: int exit_flag;
1102: {
1103: struct nesting *thisblock
1104: = (struct nesting *) xmalloc (sizeof (struct nesting));
1105:
1106: rtx note = emit_note (0, NOTE_INSN_BLOCK_BEG);
1107:
1108: /* Make an entry on block_stack for the block we are entering. */
1109:
1110: thisblock->next = block_stack;
1111: thisblock->all = nesting_stack;
1112: thisblock->depth = ++nesting_depth;
1113: thisblock->data.block.stack_level = 0;
1114: thisblock->data.block.label_chain = 0;
1115: thisblock->data.block.innermost_stack_block = stack_block_stack;
1116: thisblock->data.block.first_insn = note;
1117: thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
1118: block_stack = thisblock;
1119: nesting_stack = thisblock;
1120: }
1121:
1122: /* Output a USE for any register use in RTL.
1123: This is used with -noreg to mark the extent of lifespan
1124: of any registers used in a user-visible variable's DECL_RTL. */
1125:
1126: static void
1127: use_variable (rtl)
1128: rtx rtl;
1129: {
1130: if (GET_CODE (rtl) == REG)
1131: /* This is a register variable. */
1132: emit_insn (gen_rtx (USE, VOIDmode, rtl));
1133: else if (GET_CODE (rtl) == MEM
1134: && GET_CODE (XEXP (rtl, 0)) == REG
1135: && XEXP (rtl, 0) != frame_pointer_rtx
1136: && XEXP (rtl, 0) != arg_pointer_rtx)
1137: /* This is a variable-sized structure. */
1138: emit_insn (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)));
1139: }
1140:
1141: /* Generate RTL code to terminate a binding contour.
1142: VARS is the chain of VAR_DECL nodes
1143: for the variables bound in this contour.
1144: MARK_ENDs is nonzero if we should put a note at the beginning
1145: and end of this binding contour. */
1146:
1147: void
1148: expand_end_bindings (vars, mark_ends)
1149: tree vars;
1150: int mark_ends;
1151: {
1152: register struct nesting *thisblock = block_stack;
1153: register tree decl;
1154:
1155: /* Mark the beginning and end of the scope if requested. */
1156:
1157: if (mark_ends)
1158: emit_note (0, NOTE_INSN_BLOCK_END);
1159: else
1160: /* Get rid of the beginning-mark if we don't make an end-mark. */
1161: NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
1162:
1163: if (thisblock->exit_label)
1164: {
1165: do_pending_stack_adjust ();
1166: emit_label (thisblock->exit_label);
1167: }
1168:
1169: /* Restore stack level in effect before the block
1170: (only if variable-size objects allocated). */
1171:
1172: if (thisblock->data.block.stack_level != 0)
1173: {
1174: struct label_chain *chain;
1175:
1176: do_pending_stack_adjust ();
1177: emit_move_insn (stack_pointer_rtx,
1178: thisblock->data.block.stack_level);
1179:
1180: /* Any labels in this block are no longer valid to go to.
1181: Mark them to cause an error message. */
1182: for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
1183: {
1184: TREE_PACKED (chain->label) = 1;
1185: /* If any goto without a fixup came to this label,
1186: that must be an error, because gotos without fixups
1187: come from outside all saved stack-levels. */
1188: if (TREE_ADDRESSABLE (chain->label))
1189: error_with_file_and_line (DECL_SOURCE_FILE (chain->label),
1190: DECL_SOURCE_LINE (chain->label),
1191: "label \"%s\" was used \
1192: before containing binding contour",
1193: IDENTIFIER_POINTER (DECL_NAME (chain->label)));
1194: }
1195:
1196: /* Any gotos out of this block must also restore the stack level.
1197: Also report any gotos with fixups that came to labels in this level. */
1198: fixup_gotos (thisblock->data.block.stack_level,
1199: thisblock->data.block.first_insn);
1200: }
1201:
1202: /* If doing stupid register allocation, make sure lives of all
1203: register variables declared here extend thru end of scope. */
1204:
1205: if (obey_regdecls)
1206: for (decl = vars; decl; decl = TREE_CHAIN (decl))
1207: {
1208: rtx rtl = DECL_RTL (decl);
1209: if (TREE_CODE (decl) == VAR_DECL && rtl != 0)
1210: use_variable (rtl);
1211: }
1212:
1213: /* Restore block_stack level for containing block. */
1214:
1215: stack_block_stack = thisblock->data.block.innermost_stack_block;
1216: POPSTACK (block_stack);
1217: }
1218:
1219: /* Generate RTL for the automatic variable declaration DECL.
1220: (Other kinds of declarations are simply ignored.) */
1221:
1222: void
1223: expand_decl (decl)
1224: register tree decl;
1225: {
1226: struct nesting *thisblock = block_stack;
1227: tree type = TREE_TYPE (decl);
1228:
1229: /* External function declarations are supposed to have been
1230: handled in assemble_variable. Verify this. */
1231: if (TREE_CODE (decl) == FUNCTION_DECL)
1232: {
1233: if (DECL_RTL (decl) == 0)
1234: abort ();
1235: return;
1236: }
1237:
1238: /* Aside from that, only automatic variables need any expansion done.
1239: Static and external variables were handled by `assemble_variable'
1240: (called from finish_decl). TYPE_DECL and CONST_DECL require nothing;
1241: PARM_DECLs are handled in `assign_parms'. */
1242:
1243: if (TREE_CODE (decl) != VAR_DECL)
1244: return;
1245: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
1246: return;
1247:
1248: /* Create the RTL representation for the variable. */
1249:
1250: if (type == error_mark_node)
1251: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx);
1252: else if (DECL_MODE (decl) != BLKmode
1253: /* If -ffloat-store, don't put explicit float vars
1254: into regs. */
1255: && !(flag_float_store
1256: && TREE_CODE (type) == REAL_TYPE)
1257: && ! TREE_VOLATILE (decl)
1258: && ! TREE_ADDRESSABLE (decl)
1259: && (TREE_REGDECL (decl) || ! obey_regdecls))
1260: {
1261: /* Automatic variable that can go in a register. */
1262: DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
1263: if (TREE_CODE (type) == POINTER_TYPE)
1264: mark_reg_pointer (DECL_RTL (decl));
1265: DECL_RTL (decl)->volatil = 1;
1266: }
1267: else if (DECL_SIZE (decl) == 0)
1268: /* Variable with incomplete type. */
1269: /* Error message was already done; now avoid a crash. */
1270: DECL_RTL (decl) = assign_stack_local (DECL_MODE (decl), 0);
1271: else if (TREE_LITERAL (DECL_SIZE (decl)))
1272: {
1273: /* Variable of fixed size that goes on the stack. */
1274: DECL_RTL (decl)
1275: = assign_stack_local (DECL_MODE (decl),
1276: (TREE_INT_CST_LOW (DECL_SIZE (decl))
1277: * DECL_SIZE_UNIT (decl)
1278: + BITS_PER_UNIT - 1)
1279: / BITS_PER_UNIT);
1280: /* If this is a memory ref that contains aggregate components,
1281: mark it as such for cse and loop optimize. */
1282: DECL_RTL (decl)->in_struct
1283: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1284: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1285: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
1286: }
1287: else
1288: /* Dynamic-size object: must push space on the stack. */
1289: {
1290: rtx address, size;
1291:
1292: frame_pointer_needed = 1;
1293:
1294: /* Record the stack pointer on entry to block, if have
1295: not already done so. */
1296: if (thisblock->data.block.stack_level == 0)
1297: {
1298: do_pending_stack_adjust ();
1299: thisblock->data.block.stack_level
1300: = copy_to_reg (stack_pointer_rtx);
1301: stack_block_stack = thisblock;
1302: }
1303:
1304: /* Compute the variable's size, in bytes. */
1305: size = expand_expr (convert_units (DECL_SIZE (decl),
1306: DECL_SIZE_UNIT (decl),
1307: BITS_PER_UNIT),
1308: 0, VOIDmode, 0);
1309:
1310: /* Round it up to this machine's required stack boundary. */
1311: #ifdef STACK_BOUNDARY
1312: /* Avoid extra code if we can prove it's a multiple already. */
1313: if (DECL_SIZE_UNIT (decl) % STACK_BOUNDARY)
1314: size = round_push (size);
1315: #endif
1316:
1317: /* Make space on the stack, and get an rtx for the address of it. */
1318: #ifdef STACK_GROWS_DOWNWARD
1319: anti_adjust_stack (size);
1320: #endif
1321: address = copy_to_reg (stack_pointer_rtx);
1322: #ifndef STACK_GROWS_DOWNWARD
1323: anti_adjust_stack (size);
1324: #endif
1325:
1326: /* Reference the variable indirect through that rtx. */
1327: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
1328: }
1329:
1330: if (TREE_VOLATILE (decl))
1331: DECL_RTL (decl)->volatil = 1;
1332: if (TREE_READONLY (decl))
1333: DECL_RTL (decl)->unchanging = 1;
1334:
1335: /* If doing stupid register allocation, make sure life of any
1336: register variable starts here, at the start of its scope. */
1337:
1338: if (obey_regdecls
1339: && TREE_CODE (decl) == VAR_DECL
1340: && DECL_RTL (decl) != 0)
1341: use_variable (DECL_RTL (decl));
1342:
1343: /* Compute and store the initial value now. */
1344:
1345: if (DECL_INITIAL (decl) == error_mark_node)
1346: {
1347: enum tree_code code = TREE_CODE (TREE_TYPE (decl));
1348: if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
1349: || code == POINTER_TYPE)
1350: expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
1351: 0, 0);
1352: emit_queue ();
1353: }
1354: else if (DECL_INITIAL (decl))
1355: {
1356: emit_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1357: expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
1358: emit_queue ();
1359: }
1360: }
1361:
1362: /* Enter a case (Pascal) or switch (C) statement.
1363: Push a block onto case_stack and nesting_stack
1364: to accumulate the case-labels that are seen
1365: and to record the labels generated for the statement.
1366:
1367: EXIT_FLAG is nonzero if `exit_something' should exit this case stmt.
1368: Otherwise, this construct is transparent for `exit_something'.
1369:
1370: EXPR is the index-expression to be dispatched on.
1371: TYPE is its nominal type. We could simply convert EXPR to this type,
1372: but instead we take short cuts. */
1373:
1374: void
1375: expand_start_case (exit_flag, expr, type)
1376: int exit_flag;
1377: tree expr;
1378: tree type;
1379: {
1380: register struct nesting *thiscase
1381: = (struct nesting *) xmalloc (sizeof (struct nesting));
1382:
1383: /* Make an entry on case_stack for the case we are entering. */
1384:
1385: thiscase->next = case_stack;
1386: thiscase->all = nesting_stack;
1387: thiscase->depth = ++nesting_depth;
1388: thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
1389: thiscase->data.case_stmt.case_list = 0;
1390: thiscase->data.case_stmt.index_expr = expr;
1391: thiscase->data.case_stmt.nominal_type = type;
1392: case_stack = thiscase;
1393: nesting_stack = thiscase;
1394:
1395: do_pending_stack_adjust ();
1396:
1397: thiscase->data.case_stmt.start = get_last_insn ();
1398: }
1399:
1400: /* Start a "dummy case statement" within which case labels are invalid
1401: and are not connected to any larger real case statement.
1402: This can be used if you don't want to let a case statement jump
1403: into the middle of certain kinds of constructs. */
1404:
1405: void
1406: expand_start_case_dummy ()
1407: {
1408: register struct nesting *thiscase
1409: = (struct nesting *) xmalloc (sizeof (struct nesting));
1410:
1411: /* Make an entry on case_stack for the dummy. */
1412:
1413: thiscase->next = case_stack;
1414: thiscase->all = nesting_stack;
1415: thiscase->depth = ++nesting_depth;
1416: thiscase->exit_label = 0;
1417: thiscase->data.case_stmt.case_list = 0;
1418: thiscase->data.case_stmt.start = 0;
1419: thiscase->data.case_stmt.nominal_type = 0;
1420: case_stack = thiscase;
1421: nesting_stack = thiscase;
1422: }
1423:
1424: /* End a dummy case statement. */
1425:
1426: void
1427: expand_end_case_dummy ()
1428: {
1429: POPSTACK (case_stack);
1430: }
1431:
1432: /* Accumulate one case or default label inside a case or switch statement.
1433: VALUE is the value of the case (a null pointer, for a default label).
1434:
1435: If not currently inside a case or switch statement, return 1 and do
1436: nothing. The caller will print a language-specific error message.
1437: If VALUE is a duplicate, return 2 and do nothing.
1438: If VALUE is out of range, return 3 and do nothing.
1439: Return 0 on success. */
1440:
1441: int
1442: pushcase (value, label)
1443: register tree value;
1444: register tree label;
1445: {
1446: register tree l;
1447: tree index_type;
1448: tree nominal_type;
1449:
1450: /* Fail if not inside a real case statement. */
1451: if (! (case_stack && case_stack->data.case_stmt.start))
1452: return 1;
1453:
1454: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
1455: nominal_type = case_stack->data.case_stmt.nominal_type;
1456:
1457: /* If the index is erroneous, avoid more problems: pretend to succeed. */
1458: if (index_type == error_mark_node)
1459: return 0;
1460:
1461: /* Convert VALUE to the type in which the comparisons are nominally done. */
1462: if (value != 0)
1463: value = convert (nominal_type, value);
1464:
1465: /* Fail if this is a duplicate entry. */
1466: for (l = case_stack->data.case_stmt.case_list; l; l = TREE_CHAIN (l))
1467: {
1468: if (value == 0 && TREE_PURPOSE (l) == 0)
1469: return 2;
1470: if (value != 0 && TREE_PURPOSE (l)
1471: && (TREE_INT_CST_LOW (value)
1472: == TREE_INT_CST_LOW (TREE_PURPOSE (l)))
1473: && (TREE_INT_CST_HIGH (value)
1474: == TREE_INT_CST_HIGH (TREE_PURPOSE (l))))
1475: return 2;
1476: }
1477:
1478: /* Fail if this value is out of range for the actual type of the index
1479: (which may be narrower than NOMINAL_TYPE). */
1480: if (value != 0 && ! int_fits_type_p (value, index_type))
1481: return 3;
1482:
1483: /* Add this label to the list, and succeed.
1484: Copy VALUE so it is temporary rather than momentary. */
1485: case_stack->data.case_stmt.case_list
1486: = tree_cons (value ? copy_node (value) : 0, label,
1487: case_stack->data.case_stmt.case_list);
1488: expand_label (label);
1489: return 0;
1490: }
1491:
1492: /* Terminate a case (Pascal) or switch (C) statement
1493: in which CASE_INDEX is the expression to be tested.
1494: Generate the code to test it and jump to the right place. */
1495:
1496: void
1497: expand_end_case ()
1498: {
1499: tree minval, maxval, range;
1500: rtx default_label = 0;
1501: register tree elt;
1502: register tree c;
1503: int count;
1504: rtx index;
1505: rtx table_label = gen_label_rtx ();
1506: int ncases;
1507: rtx *labelvec;
1508: register int i;
1509: rtx before_case;
1510: register struct nesting *thiscase = case_stack;
1511: tree index_expr = thiscase->data.case_stmt.index_expr;
1512:
1513: do_pending_stack_adjust ();
1514:
1515: /* This happens for various reasons including invalid data type. */
1516: if (index_expr != error_mark_node)
1517: {
1518: /* If we don't have a default-label, create one here,
1519: after the body of the switch. */
1520: for (c = thiscase->data.case_stmt.case_list; c; c = TREE_CHAIN (c))
1521: if (TREE_PURPOSE (c) == 0)
1522: break;
1523: if (c == 0)
1524: pushcase (0, build_decl (LABEL_DECL, NULL_TREE, NULL_TREE));
1525:
1526: before_case = get_last_insn ();
1527:
1528: /* Get upper and lower bounds of case values.
1529: Also convert all the case values to the index expr's data type. */
1530: count = 0;
1531: for (c = thiscase->data.case_stmt.case_list; c; c = TREE_CHAIN (c))
1532: if (elt = TREE_PURPOSE (c))
1533: {
1534: /* Note that in Pascal it will be possible
1535: to have a RANGE_EXPR here as long as both
1536: ends of the range are constant.
1537: It will be necessary to extend this function
1538: to handle them. */
1539: if (TREE_CODE (elt) != INTEGER_CST)
1540: abort ();
1541:
1542: TREE_PURPOSE (c) = elt = convert (TREE_TYPE (index_expr), elt);
1543:
1544: /* Count the elements and track the largest and
1545: smallest of them
1546: (treating them as signed even if they are not). */
1547: if (count++ == 0)
1548: {
1549: minval = maxval = elt;
1550: }
1551: else
1552: {
1553: if (INT_CST_LT (elt, minval))
1554: minval = elt;
1555: if (INT_CST_LT (maxval, elt))
1556: maxval = elt;
1557: }
1558: }
1559: else
1560: default_label = label_rtx (TREE_VALUE (c));
1561:
1562: if (default_label == 0)
1563: abort ();
1564:
1565: /* Compute span of values. */
1566: if (count != 0)
1567: range = combine (MINUS_EXPR, maxval, minval);
1568:
1569: if (count == 0 || TREE_CODE (TREE_TYPE (index_expr)) == ERROR_MARK)
1570: {
1571: expand_expr (index_expr, const0_rtx, VOIDmode, 0);
1572: emit_queue ();
1573: emit_jump (default_label);
1574: }
1575: /* If range of values is much bigger than number of values,
1576: make a sequence of conditional branches instead of a dispatch.
1577: If the switch-index is a constant, do it this way
1578: because we can optimize it. */
1579: else if (TREE_INT_CST_HIGH (range) != 0
1580: #ifdef HAVE_casesi
1581: || count < 4
1582: #else
1583: /* If machine does not have a case insn that compares the
1584: bounds, this means extra overhead for dispatch tables
1585: which raises the threshold for using them. */
1586: || count < 5
1587: #endif
1588: || (unsigned) (TREE_INT_CST_LOW (range)) > 10 * count
1589: || TREE_CODE (index_expr) == INTEGER_CST)
1590: {
1591: index = expand_expr (index_expr, 0, VOIDmode, 0);
1592: emit_queue ();
1593:
1594: index = protect_from_queue (index, 0);
1595: if (GET_CODE (index) == MEM)
1596: index = copy_to_reg (index);
1597: do_pending_stack_adjust ();
1598:
1599: for (c = thiscase->data.case_stmt.case_list; c; c = TREE_CHAIN (c))
1600: {
1601: elt = TREE_PURPOSE (c);
1602: if (elt && TREE_VALUE (c))
1603: do_jump_if_equal (expand_expr (elt, 0, VOIDmode, 0), index,
1604: label_rtx (TREE_VALUE (c)));
1605: }
1606:
1607: emit_jump (default_label);
1608: }
1609: else
1610: {
1611: #ifdef HAVE_casesi
1612: /* Convert the index to SImode. */
1613: if (TYPE_MODE (TREE_TYPE (index_expr)) == DImode)
1614: {
1615: index_expr = build (MINUS_EXPR, TREE_TYPE (index_expr),
1616: index_expr, minval);
1617: minval = integer_zero_node;
1618: }
1619: if (TYPE_MODE (TREE_TYPE (index_expr)) != SImode)
1620: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
1621: index_expr);
1622: index = expand_expr (index_expr, 0, VOIDmode, 0);
1623: emit_queue ();
1624: index = protect_from_queue (index, 0);
1625: do_pending_stack_adjust ();
1626:
1627: emit_jump_insn (gen_casesi (index, expand_expr (minval, 0, VOIDmode, 0),
1628: expand_expr (range, 0, VOIDmode, 0),
1629: table_label, default_label));
1630: #else
1631: #ifdef HAVE_tablejump
1632: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
1633: build (MINUS_EXPR, TREE_TYPE (index_expr),
1634: index_expr, minval));
1635: index = expand_expr (index_expr, 0, VOIDmode, 0);
1636: emit_queue ();
1637: index = protect_from_queue (index, 0);
1638: do_pending_stack_adjust ();
1639:
1640: do_tablejump (index,
1641: gen_rtx (CONST_INT, VOIDmode, TREE_INT_CST_LOW (range)),
1642: table_label, default_label);
1643: #else
1644: lossage;
1645: #endif /* not HAVE_tablejump */
1646: #endif /* not HAVE_casesi */
1647:
1648: /* Get table of labels to jump to, in order of case index. */
1649:
1650: ncases = TREE_INT_CST_LOW (range) + 1;
1651: labelvec = (rtx *) alloca (ncases * sizeof (rtx));
1652: bzero (labelvec, ncases * sizeof (rtx));
1653:
1654: for (c = thiscase->data.case_stmt.case_list; c; c = TREE_CHAIN (c))
1655: if (TREE_VALUE (c) && (elt = TREE_PURPOSE (c)))
1656: {
1657: register int i
1658: = TREE_INT_CST_LOW (elt) - TREE_INT_CST_LOW (minval);
1659: labelvec[i]
1660: = gen_rtx (LABEL_REF, Pmode, label_rtx (TREE_VALUE (c)));
1661: }
1662:
1663: /* Fill in the gaps with the default. */
1664: for (i = 0; i < ncases; i++)
1665: if (labelvec[i] == 0)
1666: labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label);
1667:
1668: /* Output the table */
1669: emit_label (table_label);
1670:
1671: #ifdef CASE_VECTOR_PC_RELATIVE
1672: emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE,
1673: gen_rtx (LABEL_REF, Pmode, table_label),
1674: gen_rtvec_v (ncases, labelvec)));
1675: #else
1676: emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE,
1677: gen_rtvec_v (ncases, labelvec)));
1678: #endif
1679: /* If the case insn drops through the table,
1680: after the table we must jump to the default-label.
1681: Otherwise record no drop-through after the table. */
1682: #ifdef CASE_DROPS_THROUGH
1683: emit_jump (default_label);
1684: #else
1685: emit_barrier ();
1686: #endif
1687: }
1688:
1689: reorder_insns (NEXT_INSN (before_case), get_last_insn (),
1690: thiscase->data.case_stmt.start);
1691: }
1692: if (thiscase->exit_label)
1693: emit_label (thiscase->exit_label);
1694:
1695: POPSTACK (case_stack);
1696: }
1697:
1698: /* Generate code to jump to LABEL if OP1 and OP2 are equal. */
1699: /* ??? This may need an UNSIGNEDP argument to work properly ??? */
1700:
1701: void
1702: do_jump_if_equal (op1, op2, label)
1703: rtx op1, op2, label;
1704: {
1705: if (GET_CODE (op1) == CONST_INT
1706: && GET_CODE (op2) == CONST_INT)
1707: {
1708: if (INTVAL (op1) == INTVAL (op2))
1709: emit_jump (label);
1710: }
1711: else
1712: {
1713: emit_cmp_insn (op1, op2, 0, 0);
1714: emit_jump_insn (gen_beq (label));
1715: }
1716: }
1717:
1718: /* Allocate fixed slots in the stack frame of the current function. */
1719:
1720: /* Return size needed for stack frame based on slots so far allocated. */
1721:
1722: int
1723: get_frame_size ()
1724: {
1725: #ifdef FRAME_GROWS_DOWNWARD
1726: return -frame_offset;
1727: #else
1728: return frame_offset;
1729: #endif
1730: }
1731:
1732: /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
1733: with machine mode MODE. */
1734:
1735: rtx
1736: assign_stack_local (mode, size)
1737: enum machine_mode mode;
1738: int size;
1739: {
1740: register rtx x, addr;
1741:
1742: frame_pointer_needed = 1;
1743:
1744: /* Make each stack slot a multiple of the main allocation unit. */
1745: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
1746: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
1747: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
1748:
1749: #ifdef FRAME_GROWS_DOWNWARD
1750: frame_offset -= size;
1751: #endif
1752: addr = gen_rtx (PLUS, Pmode, frame_pointer_rtx,
1753: gen_rtx (CONST_INT, VOIDmode, frame_offset));
1754: #ifndef FRAME_GROWS_DOWNWARD
1755: frame_offset += size;
1756: #endif
1757:
1758: if (! memory_address_p (mode, addr))
1759: invalid_stack_slot = 1;
1760:
1761: x = gen_rtx (MEM, mode, addr);
1762:
1763: return x;
1764: }
1765:
1766: /* Retroactively move an auto variable from a register to a stack slot.
1767: This is done when an address-reference to the variable is seen. */
1768:
1769: void
1770: put_var_into_stack (decl)
1771: tree decl;
1772: {
1773: register rtx reg = DECL_RTL (decl);
1774: register rtx new;
1775:
1776: /* No need to do anything if decl has no rtx yet
1777: since in that case caller is setting TREE_ADDRESSABLE
1778: and a stack slot will be assigned when the rtl is made. */
1779: if (reg == 0)
1780: return;
1781: if (GET_CODE (reg) != REG)
1782: return;
1783:
1784: new = parm_stack_loc (reg);
1785: if (new == 0)
1786: new = assign_stack_local (GET_MODE (reg), GET_MODE_SIZE (GET_MODE (reg)));
1787:
1788: /* If this is a memory ref that contains aggregate components,
1789: mark it as such for cse and loop optimize. */
1790: reg->in_struct
1791: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1792: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
1793: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
1794:
1795: XEXP (reg, 0) = XEXP (new, 0);
1796: PUT_CODE (reg, MEM);
1797: /* `volatil' bit means one thing for MEMs, another entirely for REGs. */
1798: reg->volatil = 0;
1799:
1800: fixup_var_refs (reg);
1801: }
1802:
1803: static void
1804: fixup_var_refs (var)
1805: rtx var;
1806: {
1807: register rtx insn;
1808:
1809: /* Yes. Must scan all insns for stack-refs that exceed the limit. */
1810: for (insn = get_insns (); insn; )
1811: {
1812: rtx next = NEXT_INSN (insn);
1813: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
1814: || GET_CODE (insn) == JUMP_INSN)
1815: {
1816: /* The insn to load VAR from a home in the arglist
1817: is now a no-op. When we see it, just delete it. */
1818: if (GET_CODE (PATTERN (insn)) == SET
1819: && SET_DEST (PATTERN (insn)) == var
1820: && rtx_equal_p (SET_SRC (PATTERN (insn)), var))
1821: next = delete_insn (insn);
1822: else
1823: fixup_var_refs_1 (var, PATTERN (insn), insn);
1824: }
1825: insn = next;
1826: }
1827: }
1828:
1829: static rtx
1830: fixup_var_refs_1 (var, x, insn)
1831: register rtx var;
1832: register rtx x;
1833: rtx insn;
1834: {
1835: register int i;
1836: RTX_CODE code = GET_CODE (x);
1837: register char *fmt;
1838: register rtx tem;
1839:
1840: switch (code)
1841: {
1842: case MEM:
1843: if (var == x)
1844: {
1845: x = fixup_stack_1 (x, insn);
1846: tem = gen_reg_rtx (GET_MODE (x));
1847: emit_insn_before (gen_move_insn (tem, x), insn);
1848: return tem;
1849: }
1850: break;
1851:
1852: case REG:
1853: case CC0:
1854: case PC:
1855: case CONST_INT:
1856: case CONST:
1857: case SYMBOL_REF:
1858: case LABEL_REF:
1859: case CONST_DOUBLE:
1860: return x;
1861:
1862: case SIGN_EXTRACT:
1863: case ZERO_EXTRACT:
1864: /* Note that in some cases those types of expressions are altered
1865: by optimize_bit_field, and do not survive to get here. */
1866: case SUBREG:
1867: tem = x;
1868: while (GET_CODE (tem) == SUBREG || GET_CODE (tem) == SIGN_EXTRACT
1869: || GET_CODE (tem) == ZERO_EXTRACT)
1870: tem = XEXP (tem, 0);
1871: if (tem == var)
1872: {
1873: x = fixup_stack_1 (x, insn);
1874: tem = gen_reg_rtx (GET_MODE (x));
1875: emit_insn_before (gen_move_insn (tem, x), insn);
1876: return tem;
1877: }
1878: break;
1879:
1880: case SET:
1881: /* First do special simplification of bit-field references. */
1882: if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
1883: || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
1884: optimize_bit_field (x, insn, 0);
1885: if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
1886: || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
1887: optimize_bit_field (x, insn, 0);
1888:
1889: {
1890: rtx dest = SET_DEST (x);
1891: rtx src = SET_SRC (x);
1892: rtx outerdest = dest;
1893: rtx outersrc = src;
1894: int strictflag = GET_CODE (dest) == STRICT_LOW_PART;
1895:
1896: while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
1897: || GET_CODE (dest) == SIGN_EXTRACT
1898: || GET_CODE (dest) == ZERO_EXTRACT)
1899: dest = XEXP (dest, 0);
1900: while (GET_CODE (src) == SUBREG
1901: || GET_CODE (src) == SIGN_EXTRACT
1902: || GET_CODE (src) == ZERO_EXTRACT)
1903: src = XEXP (src, 0);
1904:
1905: /* If VAR does not appear at the top level of the SET
1906: just scan the lower levels of the tree. */
1907:
1908: if (src != var && dest != var)
1909: break;
1910:
1911: /* Clean up (SUBREG:SI (MEM:mode ...) 0)
1912: that may appear inside a SIGN_EXTRACT or ZERO_EXTRACT.
1913: This was legitimate when the MEM was a REG. */
1914:
1915: if ((GET_CODE (outerdest) == SIGN_EXTRACT
1916: || GET_CODE (outerdest) == ZERO_EXTRACT)
1917: && GET_CODE (XEXP (outerdest, 0)) == SUBREG
1918: && SUBREG_REG (XEXP (outerdest, 0)) == var)
1919: XEXP (outerdest, 0) = fixup_memory_subreg (XEXP (outerdest, 0));
1920:
1921: if ((GET_CODE (outersrc) == SIGN_EXTRACT
1922: || GET_CODE (outersrc) == ZERO_EXTRACT)
1923: && GET_CODE (XEXP (outersrc, 0)) == SUBREG
1924: && SUBREG_REG (XEXP (outersrc, 0)) == var)
1925: XEXP (outersrc, 0) = fixup_memory_subreg (XEXP (outersrc, 0));
1926:
1927: /* Make sure a MEM inside a SIGN_EXTRACT has QImode
1928: since that's what bit-field insns want. */
1929:
1930: if ((GET_CODE (outerdest) == SIGN_EXTRACT
1931: || GET_CODE (outerdest) == ZERO_EXTRACT)
1932: && GET_CODE (XEXP (outerdest, 0)) == MEM
1933: && GET_MODE (XEXP (outerdest, 0)) != QImode)
1934: {
1935: XEXP (outerdest, 0) = copy_rtx (XEXP (outerdest, 0));
1936: PUT_MODE (XEXP (outerdest, 0), QImode);
1937: }
1938:
1939: if ((GET_CODE (outersrc) == SIGN_EXTRACT
1940: || GET_CODE (outersrc) == ZERO_EXTRACT)
1941: && GET_CODE (XEXP (outersrc, 0)) == MEM
1942: && GET_MODE (XEXP (outersrc, 0)) != QImode)
1943: {
1944: XEXP (outersrc, 0) = copy_rtx (XEXP (outersrc, 0));
1945: PUT_MODE (XEXP (outersrc, 0), QImode);
1946: }
1947:
1948: /* STRICT_LOW_PART is a no-op on memory references
1949: and it can cause combinations to be unrecognizable,
1950: so eliminate it. */
1951:
1952: if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
1953: SET_DEST (x) = XEXP (SET_DEST (x), 0);
1954:
1955: /* An insn to copy VAR into or out of a register
1956: must be left alone, to avoid an infinite loop here.
1957: But do fix up the address of VAR's stack slot if nec. */
1958:
1959: if (GET_CODE (SET_SRC (x)) == REG || GET_CODE (SET_DEST (x)) == REG)
1960: return fixup_stack_1 (x, insn);
1961:
1962: if ((GET_CODE (SET_SRC (x)) == SUBREG
1963: && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG)
1964: || (GET_CODE (SET_DEST (x)) == SUBREG
1965: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
1966: return fixup_stack_1 (x, insn);
1967:
1968: /* Otherwise, storing into VAR must be handled specially
1969: by storing into a temporary and copying that into VAR
1970: with a new insn after this one. */
1971:
1972: if (dest == var)
1973: {
1974: rtx temp;
1975: rtx fixeddest;
1976: tem = SET_DEST (x);
1977: if (GET_CODE (tem) == STRICT_LOW_PART)
1978: tem = XEXP (tem, 0);
1979: temp = gen_reg_rtx (GET_MODE (tem));
1980: fixeddest = fixup_stack_1 (SET_DEST (x), insn);
1981: emit_insn_after (gen_move_insn (fixeddest, temp), insn);
1982: SET_DEST (x) = temp;
1983: }
1984: }
1985: }
1986:
1987: /* Nothing special about this RTX; fix its operands. */
1988:
1989: fmt = GET_RTX_FORMAT (code);
1990: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1991: {
1992: if (fmt[i] == 'e')
1993: XEXP (x, i) = fixup_var_refs_1 (var, XEXP (x, i), insn);
1994: if (fmt[i] == 'E')
1995: {
1996: register int j;
1997: for (j = 0; j < XVECLEN (x, i); j++)
1998: XVECEXP (x, i, j)
1999: = fixup_var_refs_1 (var, XVECEXP (x, i, j), insn);
2000: }
2001: }
2002: return x;
2003: }
2004:
2005: /* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
2006: return an rtx (MEM:m1 newaddr) which is equivalent. */
2007:
2008: static rtx
2009: fixup_memory_subreg (x)
2010: rtx x;
2011: {
2012: int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
2013: rtx addr = XEXP (SUBREG_REG (x), 0);
2014: enum machine_mode mode = GET_MODE (SUBREG_REG (x));
2015:
2016: #ifdef BYTES_BIG_ENDIAN
2017: offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
2018: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
2019: #endif
2020: return change_address (SUBREG_REG (x), mode,
2021: plus_constant (addr, offset));
2022: }
2023:
2024: #if 0
2025: /* Fix up any references to stack slots that are invalid memory addresses
2026: because they exceed the maximum range of a displacement. */
2027:
2028: void
2029: fixup_stack_slots ()
2030: {
2031: register rtx insn;
2032:
2033: /* Did we generate a stack slot that is out of range
2034: or otherwise has an invalid address? */
2035: if (invalid_stack_slot)
2036: {
2037: /* Yes. Must scan all insns for stack-refs that exceed the limit. */
2038: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2039: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
2040: || GET_CODE (insn) == JUMP_INSN)
2041: fixup_stack_1 (PATTERN (insn), insn);
2042: }
2043: }
2044: #endif
2045:
2046: /* For each memory ref within X, if it refers to a stack slot
2047: with an out of range displacement, put the address in a temp register
2048: (emitting new insns before INSN to load these registers)
2049: and alter the memory ref to use that register.
2050: Replace each such MEM rtx with a copy, to avoid clobberage. */
2051:
2052: static rtx
2053: fixup_stack_1 (x, insn)
2054: rtx x;
2055: rtx insn;
2056: {
2057: register int i;
2058: register RTX_CODE code = GET_CODE (x);
2059: register char *fmt;
2060:
2061: if (code == MEM)
2062: {
2063: register rtx ad = XEXP (x, 0);
2064: /* If we have address of a stack slot but it's not valid
2065: (displacement is too large), compute the sum in a register. */
2066: if (GET_CODE (ad) == PLUS
2067: && XEXP (ad, 0) == frame_pointer_rtx
2068: && GET_CODE (XEXP (ad, 1)) == CONST_INT)
2069: {
2070: rtx temp;
2071: if (memory_address_p (GET_MODE (x), ad))
2072: return x;
2073: temp = gen_reg_rtx (GET_MODE (ad));
2074: emit_insn_before (gen_move_insn (temp, ad), insn);
2075: return change_address (x, VOIDmode, temp);
2076: }
2077: return x;
2078: }
2079:
2080: fmt = GET_RTX_FORMAT (code);
2081: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2082: {
2083: if (fmt[i] == 'e')
2084: XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
2085: if (fmt[i] == 'E')
2086: {
2087: register int j;
2088: for (j = 0; j < XVECLEN (x, i); j++)
2089: XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
2090: }
2091: }
2092: return x;
2093: }
2094:
2095: /* Optimization: a bit-field instruction whose field
2096: happens to be a byte or halfword in memory
2097: can be changed to a move instruction.
2098:
2099: We call here when INSN is an insn to examine or store into a bit-field.
2100: BODY is the SET-rtx to be altered.
2101:
2102: EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
2103: (Currently this is called only from stmt.c, and EQUIV_MEM is always 0.) */
2104:
2105: static void
2106: optimize_bit_field (body, insn, equiv_mem)
2107: rtx body;
2108: rtx insn;
2109: rtx *equiv_mem;
2110: {
2111: register rtx bitfield;
2112: int destflag;
2113:
2114: if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
2115: || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
2116: bitfield = SET_DEST (body), destflag = 1;
2117: else
2118: bitfield = SET_SRC (body), destflag = 0;
2119:
2120: /* First check that the field being stored has constant size and position
2121: and is in fact a byte or halfword suitably aligned. */
2122:
2123: if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
2124: && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
2125: && (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
2126: || INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (HImode))
2127: && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
2128: {
2129: register rtx memref = 0;
2130:
2131: /* Now check that the contanting word is memory, not a register,
2132: and that it is safe to change the machine mode and to
2133: add something to the address. */
2134:
2135: if (GET_CODE (XEXP (bitfield, 0)) == MEM)
2136: memref = XEXP (bitfield, 0);
2137: else if (GET_CODE (XEXP (bitfield, 0)) == REG
2138: && equiv_mem != 0
2139: && (memref = equiv_mem[REGNO (XEXP (bitfield, 0))]) != 0)
2140: ;
2141: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
2142: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
2143: memref = SUBREG_REG (XEXP (bitfield, 0));
2144: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
2145: && equiv_mem != 0
2146: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG
2147: && (memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))]) != 0)
2148: ;
2149:
2150: if (memref
2151: && ! mode_dependent_address_p (XEXP (memref, 0))
2152: && offsetable_address_p (GET_MODE (bitfield), XEXP (memref, 0)))
2153: {
2154: /* Now adjust the address, first for any subreg'ing
2155: that we are now getting rid of,
2156: and then for which byte of the word is wanted. */
2157:
2158: register int offset
2159: = INTVAL (XEXP (bitfield, 2)) / GET_MODE_BITSIZE (QImode);
2160: if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
2161: {
2162: offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
2163: #ifdef BYTES_BIG_ENDIAN
2164: offset -= (MIN (UNITS_PER_WORD,
2165: GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
2166: - MIN (UNITS_PER_WORD,
2167: GET_MODE_SIZE (GET_MODE (memref))));
2168: #endif
2169: }
2170: memref = gen_rtx (MEM,
2171: (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
2172: ? QImode : HImode),
2173: XEXP (memref, 0));
2174:
2175: /* Store this memory reference where
2176: we found the bit field reference. */
2177:
2178: if (destflag)
2179: {
2180: SET_DEST (body)
2181: = adj_offsetable_operand (memref, offset);
2182: if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
2183: {
2184: rtx src = SET_SRC (body);
2185: while (GET_CODE (src) == SUBREG
2186: && SUBREG_WORD (src) == 0)
2187: src = SUBREG_REG (src);
2188: if (GET_MODE (src) != GET_MODE (memref))
2189: src = gen_rtx (SUBREG, GET_MODE (memref),
2190: SET_SRC (body), 0);
2191: SET_SRC (body) = src;
2192: }
2193: else if (GET_MODE (SET_SRC (body)) != VOIDmode
2194: && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
2195: /* This shouldn't happen because anything that didn't have
2196: one of these modes should have got converted explicitly
2197: and then referenced through a subreg.
2198: This is so because the original bit-field was
2199: handled by agg_mode and so its tree structure had
2200: the same mode that memref now has. */
2201: abort ();
2202: }
2203: else
2204: {
2205: rtx newreg = gen_reg_rtx (GET_MODE (SET_DEST (body)));
2206: emit_insn_before (gen_extend_insn (newreg, adj_offsetable_operand (memref, offset),
2207: GET_MODE (SET_DEST (body)),
2208: GET_MODE (memref),
2209: GET_CODE (SET_SRC (body)) == ZERO_EXTRACT),
2210: insn);
2211: SET_SRC (body) = newreg;
2212: }
2213:
2214: /* Cause the insn to be re-recognized. */
2215:
2216: INSN_CODE (insn) = -1;
2217: }
2218: }
2219: }
2220:
2221: /* 1 + last pseudo register number used for loading a copy
2222: of a parameter of this function. */
2223:
2224: static int max_parm_reg;
2225:
2226: /* Vector indexed by REGNO, containing location on stack in which
2227: to put the parm which is nominally in pseudo register REGNO,
2228: if we discover that that parm must go in the stack. */
2229: static rtx *parm_reg_stack_loc;
2230:
2231: /* Last insn of those whose job was to put parms into their nominal homes. */
2232: static rtx last_parm_insn;
2233:
2234: int
2235: max_parm_reg_num ()
2236: {
2237: return max_parm_reg;
2238: }
2239:
2240: /* Return the first insn following those generated by `assign_parms'. */
2241:
2242: rtx
2243: get_first_nonparm_insn ()
2244: {
2245: if (last_parm_insn)
2246: return NEXT_INSN (last_parm_insn);
2247: return get_insns ();
2248: }
2249:
2250: /* Get the stack home of a REG rtx that is one of this function's parameters.
2251: This is called rather than assign a new stack slot as a local.
2252: Return 0 if there is no existing stack home suitable for such use. */
2253:
2254: static rtx
2255: parm_stack_loc (reg)
2256: rtx reg;
2257: {
2258: if (REGNO (reg) < max_parm_reg)
2259: return parm_reg_stack_loc[REGNO (reg)];
2260: return 0;
2261: }
2262:
2263: /* Assign RTL expressions to the function's parameters.
2264: This may involve copying them into registers and using
2265: those registers as the RTL for them. */
2266:
2267: static void
2268: assign_parms (fndecl)
2269: tree fndecl;
2270: {
2271: register tree parm;
2272: register rtx entry_parm;
2273: register rtx stack_parm;
2274: register CUMULATIVE_ARGS args_so_far;
2275: enum machine_mode passed_mode, nominal_mode;
2276: /* Total space needed so far for args on the stack,
2277: given as a constant and a tree-expression. */
2278: struct args_size stack_args_size;
2279:
2280: int nparmregs
2281: = list_length (DECL_ARGUMENTS (fndecl)) + FIRST_PSEUDO_REGISTER;
2282:
2283: /* Nonzero if function takes extra anonymous args.
2284: This means the last named arg must be on the stack
2285: right before the anonymous ones. */
2286: int vararg
2287: = (TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
2288: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
2289: != void_type_node));
2290:
2291: stack_args_size.constant = 0;
2292: stack_args_size.var = 0;
2293:
2294: parm_reg_stack_loc = (rtx *) oballoc (nparmregs * sizeof (rtx));
2295: bzero (parm_reg_stack_loc, nparmregs * sizeof (rtx));
2296:
2297: INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fndecl));
2298:
2299: for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
2300: {
2301: int aggregate
2302: = (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
2303: || TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
2304: || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE);
2305: struct args_size stack_offset;
2306: rtx stack_offset_rtx;
2307:
2308: /* Get this parm's offset as an rtx. */
2309: stack_offset = stack_args_size;
2310: stack_offset.constant += FIRST_PARM_OFFSET;
2311: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
2312:
2313: DECL_OFFSET (parm) = -1;
2314:
2315: if (TREE_TYPE (parm) == error_mark_node)
2316: {
2317: DECL_RTL (parm) = gen_rtx (MEM, BLKmode, const0_rtx);
2318: continue;
2319: }
2320:
2321: /* Find mode of arg as it is passed, and mode of arg
2322: as it should be during execution of this function. */
2323: passed_mode = TYPE_MODE (DECL_ARG_TYPE (parm));
2324: nominal_mode = TYPE_MODE (TREE_TYPE (parm));
2325:
2326: /* Determine parm's home in the stack,
2327: in case it arrives in the stack or we should pretend it did. */
2328: stack_parm
2329: = gen_rtx (MEM, passed_mode,
2330: memory_address (passed_mode,
2331: gen_rtx (PLUS, Pmode,
2332: arg_pointer_rtx, stack_offset_rtx)));
2333:
2334: /* If this is a memory ref that contains aggregate components,
2335: mark it as such for cse and loop optimize. */
2336: stack_parm->in_struct = aggregate;
2337:
2338: /* Let machine desc say which reg (if any) the parm arrives in.
2339: 0 means it arrives on the stack. */
2340: entry_parm = 0;
2341: /* Variable-size args, and args following such, are never in regs. */
2342: if (TREE_CODE (TYPE_SIZE (TREE_TYPE (parm))) == INTEGER_CST
2343: || stack_offset.var != 0)
2344: {
2345: #ifdef FUNCTION_INCOMING_ARG
2346: entry_parm
2347: = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
2348: DECL_ARG_TYPE (parm), 1);
2349: #else
2350: entry_parm
2351: = FUNCTION_ARG (args_so_far, passed_mode, DECL_ARG_TYPE (parm), 1);
2352: #endif
2353: }
2354: /* If this parm was passed part in regs and part in memory,
2355: pretend it arrived entirely in memory
2356: by pushing the register-part onto the stack.
2357:
2358: In the special case of a DImode or DFmode that is split,
2359: we could put it together in a pseudoreg directly,
2360: but for now that's not worth bothering with. */
2361:
2362: /* If this is the last named arg and anonymous args follow,
2363: likewise pretend this arg arrived on the stack
2364: so varargs can find the anonymous args following it. */
2365: {
2366: int nregs = 0;
2367: int i;
2368: #ifdef FUNCTION_ARG_PARTIAL_NREGS
2369: nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
2370: DECL_ARG_TYPE (parm), 1);
2371: #endif
2372: if (TREE_CHAIN (parm) == 0 && vararg && entry_parm != 0)
2373: nregs = GET_MODE_SIZE (GET_MODE (entry_parm)) / UNITS_PER_WORD;
2374:
2375: if (nregs > 0)
2376: current_function_pretend_args_size
2377: = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
2378: / (PARM_BOUNDARY / BITS_PER_UNIT)
2379: * (PARM_BOUNDARY / BITS_PER_UNIT));
2380:
2381: i = nregs;
2382: while (--i >= 0)
2383: emit_move_insn (gen_rtx (MEM, SImode,
2384: plus_constant (XEXP (stack_parm, 0),
2385: i * GET_MODE_SIZE (SImode))),
2386: gen_rtx (REG, SImode, REGNO (entry_parm) + i));
2387: if (nregs > 0)
2388: entry_parm = stack_parm;
2389: }
2390:
2391: if (entry_parm == 0)
2392: entry_parm = stack_parm;
2393:
2394: /* Now ENTRY_PARM refers to the stack iff this parm uses stack space.
2395: In that case, count its size in STACK_ARGS_SIZE. */
2396:
2397: if (entry_parm == stack_parm)
2398: {
2399: tree sizetree = size_in_bytes (DECL_ARG_TYPE (parm));
2400: /* Round the size up to multiple of PARM_BOUNDARY bits. */
2401: tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
2402: tree s2 = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
2403: /* Add it in. */
2404: ADD_PARM_SIZE (stack_args_size, s2);
2405: }
2406:
2407: /* For a memory parm, record in DECL_OFFSET the arglist offset
2408: of the parm at the time it is passed (before conversion). */
2409: if (GET_CODE (entry_parm) != REG)
2410: DECL_OFFSET (parm) = stack_offset.constant * BITS_PER_UNIT;
2411:
2412: /* Now set STACK_PARM to the place in the stack
2413: where this parameter should live during execution,
2414: if we discover that it must live in the stack during execution.
2415: To make debuggers happier on big-endian machines, we store
2416: the value in the last bytes of the space available. */
2417:
2418: if (nominal_mode != BLKmode && nominal_mode != passed_mode)
2419: {
2420: #ifdef BYTES_BIG_ENDIAN
2421: stack_offset.constant
2422: += GET_MODE_SIZE (passed_mode)
2423: - GET_MODE_SIZE (nominal_mode);
2424: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
2425: #endif
2426:
2427: stack_parm
2428: = gen_rtx (MEM, nominal_mode,
2429: memory_address (nominal_mode,
2430: gen_rtx (PLUS, Pmode,
2431: arg_pointer_rtx,
2432: stack_offset_rtx)));
2433:
2434: /* If this is a memory ref that contains aggregate components,
2435: mark it as such for cse and loop optimize. */
2436: stack_parm->in_struct = aggregate;
2437: }
2438:
2439: /* If the parm arrived in a reg, we don't have an argument
2440: stack slot for it, so don't think that we do.
2441: If it needs to be addressable, it will get put into the stack
2442: like an ordinary automatic variable. */
2443:
2444: if (GET_CODE (entry_parm) == REG)
2445: stack_parm = 0;
2446:
2447: #if 0 /* Not needed now that `memory_address' is used above. */
2448: /* If either STACK_PARM or ENTRY_PARM is a MEM whose address
2449: is not really valid, arrange to correct all references later. */
2450:
2451: if ((GET_CODE (entry_parm) == MEM
2452: && ! memory_address_p (passed_mode, XEXP (entry_parm, 0)))
2453: || (stack_parm != entry_parm && stack_parm != 0
2454: && GET_CODE (stack_parm) == MEM
2455: && ! memory_address_p (nominal_mode, XEXP (stack_parm, 0))))
2456: invalid_stack_slot = 1;
2457: #endif /* 0 */
2458:
2459: /* ENTRY_PARM is an RTX for the parameter as it arrives,
2460: in the mode in which it arrives.
2461:
2462: Now output code if necessary to convert it to
2463: the type in which this function declares it,
2464: and store a reference to that value in DECL_RTL.
2465: This reference may be the same as STACK_PARM,
2466: or a similar stack reference in a different mode,
2467: or may be a pseudo register. */
2468:
2469: if (nominal_mode == BLKmode)
2470: {
2471: /* If a BLKmode arrives in registers, copy it to a stack slot. */
2472: if (stack_parm == 0)
2473: {
2474: stack_parm
2475: = assign_stack_local (GET_MODE (entry_parm),
2476: int_size_in_bytes (TREE_TYPE (parm)));
2477:
2478: move_block_from_reg (REGNO (entry_parm), stack_parm,
2479: int_size_in_bytes (TREE_TYPE (parm))
2480: / UNITS_PER_WORD);
2481: }
2482: DECL_RTL (parm) = stack_parm;
2483:
2484: }
2485: else if (! ((obey_regdecls && ! TREE_REGDECL (parm))
2486: /* If -ffloat-store specified, don't put explicit
2487: float variables into registers. */
2488: || (flag_float_store
2489: && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)))
2490: {
2491: /* Store the parm in a pseudoregister during the function. */
2492: register rtx parmreg = gen_reg_rtx (nominal_mode);
2493:
2494: parmreg->volatil = 1;
2495: DECL_RTL (parm) = parmreg;
2496:
2497: /* Copy the value into the register. */
2498: if (GET_MODE (parmreg) != GET_MODE (entry_parm))
2499: convert_move (parmreg, entry_parm, 0);
2500: else
2501: emit_move_insn (parmreg, entry_parm);
2502:
2503: /* In any case, record the parm's desired stack location
2504: in case we later discover it must live in the stack. */
2505: if (REGNO (parmreg) >= nparmregs)
2506: {
2507: rtx *new;
2508: nparmregs = REGNO (parmreg) + 5;
2509: new = (rtx *) oballoc (nparmregs * sizeof (rtx));
2510: bcopy (parm_reg_stack_loc, new, nparmregs * sizeof (rtx));
2511: parm_reg_stack_loc = new;
2512: }
2513: parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
2514:
2515: /* Mark the register as eliminable if we did no conversion
2516: and it was copied from memory at a fixed offset. */
2517: if (nominal_mode == passed_mode
2518: && GET_CODE (entry_parm) == MEM
2519: && stack_offset.var == 0)
2520: REG_NOTES (get_last_insn ()) = gen_rtx (EXPR_LIST, REG_EQUIV,
2521: entry_parm, 0);
2522:
2523: /* For pointer data type, suggest pointer register. */
2524: if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
2525: mark_reg_pointer (parmreg);
2526: }
2527: else
2528: {
2529: /* Value must be stored in the stack slot STACK_PARM
2530: during function execution. */
2531:
2532: if (passed_mode != nominal_mode)
2533: /* Conversion is required. */
2534: entry_parm = convert_to_mode (nominal_mode, entry_parm, 0);
2535:
2536: if (entry_parm != stack_parm)
2537: {
2538: if (stack_parm == 0)
2539: stack_parm = assign_stack_local (GET_MODE (entry_parm),
2540: GET_MODE_SIZE (GET_MODE (entry_parm)));
2541: emit_move_insn (stack_parm, entry_parm);
2542: }
2543:
2544: DECL_RTL (parm) = stack_parm;
2545: frame_pointer_needed = 1;
2546: }
2547:
2548: if (TREE_VOLATILE (parm))
2549: DECL_RTL (parm)->volatil = 1;
2550: if (TREE_READONLY (parm))
2551: DECL_RTL (parm)->unchanging = 1;
2552:
2553: /* Update info on where next arg arrives in registers. */
2554:
2555: FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, DECL_ARG_TYPE (parm), 1);
2556: }
2557: max_parm_reg = max_reg_num ();
2558: last_parm_insn = get_last_insn ();
2559:
2560: current_function_args_size = stack_args_size.constant;
2561: }
2562:
2563: /* Allocation of space for returned structure values.
2564: During the rtl generation pass, `get_structure_value_addr'
2565: is called from time to time to request the address of a block in our
2566: stack frame in which called functions will store the structures
2567: they are returning. The same space is used for all of these blocks.
2568:
2569: We allocate these blocks like stack locals. We keep reusing
2570: the same block until a bigger one is needed. */
2571:
2572: /* Length in bytes of largest structure value returned by
2573: any function called so far in this function. */
2574: static int max_structure_value_size;
2575:
2576: /* An rtx for the addr we are currently using for structure values.
2577: This is typically (PLUS (REG:SI stackptr) (CONST_INT...)). */
2578: static rtx structure_value;
2579:
2580: rtx
2581: get_structure_value_addr (sizex)
2582: rtx sizex;
2583: {
2584: register int size;
2585: if (GET_CODE (sizex) != CONST_INT)
2586: abort ();
2587: size = INTVAL (sizex);
2588:
2589: /* Round up to a multiple of the main allocation unit. */
2590: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
2591: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
2592: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
2593:
2594: /* If this size is bigger than space we know to use,
2595: get a bigger piece of space. */
2596: if (size > max_structure_value_size)
2597: {
2598: max_structure_value_size = size;
2599: structure_value = assign_stack_local (BLKmode, size);
2600: if (GET_CODE (structure_value) == MEM)
2601: structure_value = XEXP (structure_value, 0);
2602: }
2603:
2604: return structure_value;
2605: }
2606:
2607: /* Walk the tree of LET_STMTs describing the binding levels within a function
2608: and warn about uninitialized variables.
2609: This is done after calling flow_analysis and before global_alloc
2610: clobbers the pseudo-regs to hard regs. */
2611:
2612: void
2613: uninitialized_vars_warning (block)
2614: tree block;
2615: {
2616: register tree decl, sub;
2617: for (decl = STMT_VARS (block); decl; decl = TREE_CHAIN (decl))
2618: {
2619: if (TREE_CODE (decl) == VAR_DECL
2620: /* These warnings are unreliable for and aggregates
2621: because assigning the fields one by one can fail to convince
2622: flow.c that the entire aggregate was initialized.
2623: Unions are troublesome because members may be shorter. */
2624: && TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE
2625: && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE
2626: && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
2627: && GET_CODE (DECL_RTL (decl)) == REG
2628: && regno_uninitialized (REGNO (DECL_RTL (decl))))
2629: warning_with_decl (decl,
2630: "variable `%s' used uninitialized in this function");
2631: if (TREE_CODE (decl) == VAR_DECL
2632: && GET_CODE (DECL_RTL (decl)) == REG
2633: && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
2634: warning_with_decl (decl,
2635: "variable `%s' may be clobbered by `longjmp'");
2636: }
2637: for (sub = STMT_BODY (block); sub; sub = TREE_CHAIN (sub))
2638: uninitialized_vars_warning (sub);
2639: }
2640:
2641: /* Generate RTL for the start of the function FUNC (a FUNCTION_DECL tree node)
2642: and initialize static variables for generating RTL for the statements
2643: of the function. */
2644:
2645: void
2646: expand_function_start (subr)
2647: tree subr;
2648: {
2649: register int i;
2650: tree tem;
2651:
2652: this_function = subr;
2653: cse_not_expected = ! optimize;
2654:
2655: /* We have not yet found a reason why a frame pointer cannot
2656: be omitted for this function in particular, but maybe we know
2657: a priori that it is required.
2658: `flag_omit_frame_pointer' has its main effect here. */
2659: frame_pointer_needed = FRAME_POINTER_REQUIRED || ! flag_omit_frame_pointer;
2660:
2661: /* No gotos have been expanded yet. */
2662: goto_fixup_chain = 0;
2663:
2664: /* No invalid stack slots have been made yet. */
2665: invalid_stack_slot = 0;
2666:
2667: /* Initialize the RTL mechanism. */
2668: init_emit (write_symbols);
2669:
2670: /* Initialize the queue of pending postincrement and postdecrements,
2671: and some other info in expr.c. */
2672: init_expr ();
2673:
2674: init_const_rtx_hash_table ();
2675:
2676: /* Decide whether function should try to pop its args on return. */
2677:
2678: current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (subr));
2679:
2680: current_function_name = IDENTIFIER_POINTER (DECL_NAME (subr));
2681:
2682: /* Make the label for return statements to jump to, if this machine
2683: does not have a one-instruction return. */
2684: #ifdef FUNCTION_EPILOGUE
2685: return_label = gen_label_rtx ();
2686: #else
2687: return_label = 0;
2688: #endif
2689:
2690: /* No space assigned yet for structure values. */
2691: max_structure_value_size = 0;
2692: structure_value = 0;
2693:
2694: /* We are not currently within any block, conditional, loop or case. */
2695: block_stack = 0;
2696: loop_stack = 0;
2697: case_stack = 0;
2698: cond_stack = 0;
2699: nesting_stack = 0;
2700: nesting_depth = 0;
2701:
2702: /* We have not yet needed to make a label to jump to for tail-recursion. */
2703: tail_recursion_label = 0;
2704:
2705: /* No stack slots allocated yet. */
2706: frame_offset = STARTING_FRAME_OFFSET;
2707:
2708: init_pending_stack_adjust ();
2709: clear_current_args_size ();
2710:
2711: /* Prevent ever trying to delete the first instruction of a function.
2712: Also tell final how to output a linenum before the function prologue. */
2713: emit_note (DECL_SOURCE_FILE (subr), DECL_SOURCE_LINE (subr));
2714: /* Make sure first insn is a note even if we don't want linenums.
2715: This makes sure the first insn will never be deleted.
2716: Also, final expects a note to appear there. */
2717: emit_note (0, NOTE_INSN_DELETED);
2718:
2719: /* Initialize rtx for parameters and local variables.
2720: In some cases this requires emitting insns. */
2721:
2722: assign_parms (subr);
2723:
2724: /* If doing stupid allocation, mark parms as born here. */
2725:
2726: if (obey_regdecls)
2727: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
2728: use_variable (regno_reg_rtx[i]);
2729:
2730: /* After the parm initializations is where the tail-recursion label
2731: should go, if we end up needing one. */
2732: tail_recursion_reentry = get_last_insn ();
2733:
2734: /* Initialize rtx used to return the value. */
2735:
2736: if (DECL_MODE (DECL_RESULT (subr)) == BLKmode)
2737: {
2738: /* Returning something that won't go in a register. */
2739: register rtx value_address;
2740:
2741: /* Expect to be passed the address of a place to store the value. */
2742: value_address = gen_reg_rtx (Pmode);
2743: emit_move_insn (value_address, struct_value_incoming_rtx);
2744: DECL_RTL (DECL_RESULT (subr))
2745: = gen_rtx (MEM, DECL_MODE (DECL_RESULT (subr)),
2746: value_address);
2747: }
2748: else
2749: #ifdef FUNCTION_OUTGOING_VALUE
2750: DECL_RTL (DECL_RESULT (subr))
2751: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
2752: #else
2753: DECL_RTL (DECL_RESULT (subr))
2754: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
2755: #endif
2756: }
2757:
2758: /* Generate RTL for the end of the current function. */
2759:
2760: void
2761: expand_function_end ()
2762: {
2763: register int i;
2764:
2765: /* Fix up any gotos that jumped out to the outermost
2766: binding level of the function. */
2767: fixup_gotos (0, get_insns ());
2768:
2769: /* If doing stupid register allocation,
2770: mark register parms as dying here. */
2771:
2772: if (obey_regdecls)
2773: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
2774: use_variable (regno_reg_rtx[i]);
2775:
2776: clear_pending_stack_adjust ();
2777: do_pending_stack_adjust ();
2778:
2779: /* Mark the end of the function body.
2780: If control reaches this insn, the function can drop through
2781: without returning a value. */
2782: emit_note (0, NOTE_INSN_FUNCTION_END);
2783:
2784: /* If we require a true epilogue,
2785: put here the label that return statements jump to.
2786: If there will be no epilogue, write a return instruction. */
2787: #ifdef FUNCTION_EPILOGUE
2788: emit_label (return_label);
2789: #else
2790: emit_jump_insn (gen_return ());
2791: #endif
2792: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.