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