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