|
|
1.1 root 1: /* Expands front end tree to back end RTL for GNU C-Compiler
1.1.1.15 root 2: Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
1.1.1.15 root 6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
1.1 root 11: GNU CC is distributed in the hope that it will be useful,
1.1.1.15 root 12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
1.1 root 19:
20:
21: /* This file handles the generation of rtl code from tree structure
1.1.1.2 root 22: above the level of expressions, using subroutines in exp*.c and emit-rtl.c.
1.1 root 23: It also creates the rtl expressions for parameters and auto variables
24: and has full responsibility for allocating stack slots.
25:
1.1.1.2 root 26: The functions whose names start with `expand_' are called by the
27: parser to generate RTL instructions for various kinds of constructs.
28:
29: Some control and binding constructs require calling several such
30: functions at different times. For example, a simple if-then
31: is expanded by calling `expand_start_cond' (with the condition-expression
32: as argument) before parsing the then-clause and calling `expand_end_cond'
33: after parsing the then-clause.
34:
1.1.1.10 root 35: `expand_function_start' is called at the beginning of a function,
36: before the function body is parsed, and `expand_function_end' is
1.1.1.2 root 37: called after parsing the body.
38:
39: Call `assign_stack_local' to allocate a stack slot for a local variable.
40: This is usually done during the RTL generation for the function body,
41: but it can also be done in the reload pass when a pseudo-register does
42: not get a hard register.
43:
44: Call `put_var_into_stack' when you learn, belatedly, that a variable
45: previously given a pseudo-register must in fact go in the stack.
46: This function changes the DECL_RTL to be a stack slot instead of a reg
47: then scans all the RTL instructions so far generated to correct them. */
1.1 root 48:
49: #include "config.h"
50:
51: #include <stdio.h>
52:
53: #include "rtl.h"
54: #include "tree.h"
1.1.1.2 root 55: #include "flags.h"
1.1 root 56: #include "insn-flags.h"
1.1.1.2 root 57: #include "insn-config.h"
1.1.1.18 root 58: #include "insn-codes.h"
1.1 root 59: #include "expr.h"
1.1.1.2 root 60: #include "regs.h"
1.1.1.17 root 61: #include "hard-reg-set.h"
1.1.1.18 root 62: #include "recog.h"
1.1 root 63:
64: #define MAX(x,y) (((x) > (y)) ? (x) : (y))
65: #define MIN(x,y) (((x) < (y)) ? (x) : (y))
66:
1.1.1.2 root 67: /* Nonzero if function being compiled pops its args on return.
68: May affect compilation of return insn or of function epilogue. */
69:
70: int current_function_pops_args;
71:
1.1.1.10 root 72: /* Nonzero if function being compiled needs to be given an address
73: where the value should be stored. */
74:
75: int current_function_returns_struct;
76:
1.1.1.15 root 77: /* Nonzero if function being compiled needs to
78: return the address of where it has put a structure value. */
79:
80: int current_function_returns_pcc_struct;
81:
1.1.1.10 root 82: /* Nonzero if function being compiled needs to be passed a static chain. */
83:
84: int current_function_needs_context;
85:
1.1.1.11 root 86: /* Nonzero if function being compiled can call setjmp. */
87:
88: int current_function_calls_setjmp;
89:
1.1.1.17 root 90: /* Nonzero if function being compiled can call alloca,
91: either as a subroutine or builtin. */
92:
93: int current_function_calls_alloca;
94:
95: /* Nonzero if the current function returns a pointer type */
96:
97: int current_function_returns_pointer;
98:
1.1.1.2 root 99: /* If function's args have a fixed size, this is that size, in bytes.
100: Otherwise, it is -1.
101: May affect compilation of return insn or of function epilogue. */
102:
103: int current_function_args_size;
104:
105: /* # bytes the prologue should push and pretend that the caller pushed them.
106: The prologue must do this, but only if parms can be passed in registers. */
107:
108: int current_function_pretend_args_size;
109:
1.1.1.19 root 110: /* This is the offset from the arg pointer to the place where the first
111: anonymous arg can be found, if there is one. */
112: rtx current_function_arg_offset_rtx;
113:
1.1.1.2 root 114: /* Name of function now being compiled. */
115:
116: char *current_function_name;
117:
1.1.1.17 root 118: /* Label that will go on parm cleanup code, if any.
119: Jumping to this label runs cleanup code for parameters, if
120: such code must be run. Following this code is the logical return label. */
121:
122: rtx cleanup_label;
123:
1.1 root 124: /* Label that will go on function epilogue.
125: Jumping to this label serves as a "return" instruction
126: on machines which require execution of the epilogue on all returns. */
127:
1.1.1.2 root 128: rtx return_label;
1.1 root 129:
1.1.1.5 root 130: /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
131: So we can mark them all live at the end of the function, if nonopt. */
132: rtx save_expr_regs;
133:
1.1.1.13 root 134: /* List (chain of EXPR_LISTs) of all stack slots in this function.
135: Made for the sake of unshare_all_rtl. */
136: rtx stack_slot_list;
137:
1.1.1.15 root 138: /* Filename and line number of last line-number note,
139: whether we actually emitted it or not. */
140: char *emit_filename;
141: int emit_lineno;
142:
1.1.1.5 root 143: /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */
144: static rtx parm_birth_insn;
145:
1.1 root 146: /* The FUNCTION_DECL node for the function being compiled. */
147:
148: static tree this_function;
149:
1.1.1.19 root 150: /* Number of binding contours started so far in this function. */
151:
152: static int block_start_count;
153:
1.1 root 154: /* Offset to end of allocated area of stack frame.
155: If stack grows down, this is the address of the last stack slot allocated.
156: If stack grows up, this is the address for the next slot. */
1.1.1.22! root 157: int frame_offset;
1.1 root 158:
1.1.1.2 root 159: /* Nonzero if a stack slot has been generated whose address is not
160: actually valid. It means that the generated rtl must all be scanned
161: to detect and correct the invalid addresses where they occur. */
162: static int invalid_stack_slot;
1.1 root 163:
164: /* Label to jump back to for tail recursion, or 0 if we have
165: not yet needed one for this function. */
166: static rtx tail_recursion_label;
167:
168: /* Place after which to insert the tail_recursion_label if we need one. */
169: static rtx tail_recursion_reentry;
170:
1.1.1.2 root 171: /* Each time we expand an expression-statement,
172: record the expr's type and its RTL value here. */
173:
174: static tree last_expr_type;
175: static rtx last_expr_value;
176:
1.1.1.10 root 177: /* Chain of all RTL_EXPRs that have insns in them. */
178: static tree rtl_expr_chain;
179:
1.1.1.8 root 180: /* Last insn of those whose job was to put parms into their nominal homes. */
181: static rtx last_parm_insn;
1.1 root 182:
1.1.1.13 root 183: /* Functions and data structures for expanding case statements. */
184:
185: /* Case label structure, used to hold info on labels within case
186: statements. We handle "range" labels; for a single-value label
187: as in C, the high and low limits are the same. */
188:
189: struct case_node
190: {
191: struct case_node *left;
192: struct case_node *right;
193: struct case_node *parent;
194: tree low;
195: tree high;
196: tree test_label;
197: tree code_label;
198: };
199:
200: typedef struct case_node case_node;
201: typedef struct case_node *case_node_ptr;
1.1.1.17 root 202:
203: static void balance_case_nodes ();
204: static void emit_case_nodes ();
205: static void group_case_nodes ();
206: static void emit_jump_if_reachable ();
1.1.1.13 root 207:
1.1.1.2 root 208: /* Stack of control and binding constructs we are currently inside.
1.1 root 209:
1.1.1.2 root 210: These constructs begin when you call `expand_start_WHATEVER'
211: and end when you call `expand_end_WHATEVER'. This stack records
212: info about how the construct began that tells the end-function
213: what to do. It also may provide information about the construct
214: to alter the behavior of other constructs within the body.
215: For example, they may affect the behavior of C `break' and `continue'.
216:
217: Each construct gets one `struct nesting' object.
218: All of these objects are chained through the `all' field.
219: `nesting_stack' points to the first object (innermost construct).
220: The position of an entry on `nesting_stack' is in its `depth' field.
221:
222: Each type of construct has its own individual stack.
223: For example, loops have `loop_stack'. Each object points to the
224: next object of the same type through the `next' field.
225:
226: Some constructs are visible to `break' exit-statements and others
227: are not. Which constructs are visible depends on the language.
228: Therefore, the data structure allows each construct to be visible
229: or not, according to the args given when the construct is started.
230: The construct is visible if the `exit_label' field is non-null.
231: In that case, the value should be a CODE_LABEL rtx. */
232:
233: struct nesting
1.1 root 234: {
1.1.1.2 root 235: struct nesting *all;
236: struct nesting *next;
237: int depth;
238: rtx exit_label;
239: union
240: {
241: /* For conds (if-then and if-then-else statements). */
242: struct
243: {
244: /* Label on the else-part, if any, else 0. */
245: rtx else_label;
246: /* Label at the end of the whole construct. */
247: rtx after_label;
248: } cond;
249: /* For loops. */
250: struct
251: {
252: /* Label at the top of the loop; place to loop back to. */
253: rtx start_label;
254: /* Label at the end of the whole construct. */
255: rtx end_label;
256: /* Label for `continue' statement to jump to;
257: this is in front of the stepper of the loop. */
258: rtx continue_label;
259: } loop;
260: /* For variable binding contours. */
261: struct
262: {
1.1.1.19 root 263: /* Sequence number of this binding contour within the function,
264: in order of entry. */
265: int block_start_count;
1.1.1.2 root 266: /* Nonzero => value to restore stack to on exit. */
267: rtx stack_level;
268: /* The NOTE that starts this contour.
269: Used by expand_goto to check whether the destination
270: is within each contour or not. */
271: rtx first_insn;
272: /* Innermost containing binding contour that has a stack level. */
273: struct nesting *innermost_stack_block;
1.1.1.7 root 274: /* List of cleanups to be run on exit from this contour.
275: This is a list of expressions to be evaluated.
276: The TREE_PURPOSE of each link is the ..._DECL node
277: which the cleanup pertains to. */
278: tree cleanups;
1.1.1.13 root 279: /* List of cleanup-lists of blocks containing this block,
280: as they were at the locus where this block appears.
281: There is an element for each containing block,
282: ordered innermost containing block first.
283: The element's TREE_VALUE is the cleanup-list of that block,
284: which may be null. */
285: tree outer_cleanups;
1.1.1.2 root 286: /* Chain of labels defined inside this binding contour.
1.1.1.8 root 287: For contours that have stack levels or cleanups. */
1.1.1.2 root 288: struct label_chain *label_chain;
289: } block;
290: /* For switch (C) or case (Pascal) statements,
291: and also for dummies (see `expand_start_case_dummy'). */
292: struct
293: {
294: /* The insn after which the case dispatch should finally
295: be emitted. Zero for a dummy. */
296: rtx start;
1.1.1.13 root 297: /* A list of case labels, kept in ascending order by value
298: as the list is built.
299: During expand_end_case, this list may be rearranged into a
300: nearly balanced binary tree. */
301: struct case_node *case_list;
302: /* Label to jump to if no case matches. */
303: tree default_label;
1.1.1.2 root 304: /* The expression to be dispatched on. */
305: tree index_expr;
306: /* Type that INDEX_EXPR should be converted to. */
307: tree nominal_type;
1.1.1.13 root 308: /* Number of range exprs in case statement. */
309: short num_ranges;
1.1.1.2 root 310: } case_stmt;
311: } data;
312: };
1.1 root 313:
1.1.1.2 root 314: /* Chain of all pending binding contours. */
315: struct nesting *block_stack;
1.1 root 316:
1.1.1.7 root 317: /* Chain of all pending binding contours that restore stack levels
318: or have cleanups. */
1.1.1.2 root 319: struct nesting *stack_block_stack;
1.1 root 320:
1.1.1.2 root 321: /* Chain of all pending conditional statements. */
322: struct nesting *cond_stack;
1.1 root 323:
1.1.1.2 root 324: /* Chain of all pending loops. */
325: struct nesting *loop_stack;
326:
327: /* Chain of all pending case or switch statements. */
328: struct nesting *case_stack;
329:
330: /* Separate chain including all of the above,
331: chained through the `all' field. */
332: struct nesting *nesting_stack;
333:
334: /* Number of entries on nesting_stack now. */
335: int nesting_depth;
336:
337: /* Pop one of the sub-stacks, such as `loop_stack' or `cond_stack';
338: and pop off `nesting_stack' down to the same level. */
339:
340: #define POPSTACK(STACK) \
341: do { int initial_depth = nesting_stack->depth; \
342: do { struct nesting *this = STACK; \
343: STACK = this->next; \
344: nesting_stack = this->all; \
345: nesting_depth = this->depth; \
346: free (this); } \
347: while (nesting_depth > initial_depth); } while (0)
348:
1.1.1.17 root 349: static int warn_if_unused_value ();
350: static void expand_goto_internal ();
351: static int expand_fixup ();
352: static void fixup_gotos ();
353: static void expand_cleanups ();
354: static void fixup_cleanups ();
355: static void expand_null_return_1 ();
356: static int tail_recursion_args ();
357: static void fixup_stack_slots ();
358: static rtx fixup_stack_1 ();
359: static rtx fixup_memory_subreg ();
360: static rtx walk_fixup_memory_subreg ();
361: static void fixup_var_refs ();
362: static void fixup_var_refs_insns ();
363: static rtx fixup_var_refs_1 ();
364: static rtx parm_stack_loc ();
365: static void optimize_bit_field ();
366: static void do_jump_if_equal ();
367:
368: /* Emit a no-op instruction. */
369:
370: rtx
371: emit_nop ()
372: {
373: rtx last_insn = get_last_insn ();
374: if (!optimize
375: && (GET_CODE (last_insn) == CODE_LABEL
376: || prev_real_insn (last_insn) == 0))
377: emit_insn (gen_nop ());
378: }
379:
1.1 root 380: /* Return the rtx-label that corresponds to a LABEL_DECL,
381: creating it if necessary. */
382:
383: static rtx
384: label_rtx (label)
385: tree label;
386: {
1.1.1.2 root 387: if (TREE_CODE (label) != LABEL_DECL)
388: abort ();
389:
1.1 root 390: if (DECL_RTL (label))
391: return DECL_RTL (label);
392:
393: return DECL_RTL (label) = gen_label_rtx ();
394: }
395:
396: /* Add an unconditional jump to LABEL as the next sequential instruction. */
397:
398: void
399: emit_jump (label)
400: rtx label;
401: {
402: do_pending_stack_adjust ();
403: emit_jump_insn (gen_jump (label));
404: emit_barrier ();
405: }
1.1.1.2 root 406:
407: /* Handle goto statements and the labels that they can go to. */
1.1 root 408:
1.1.1.2 root 409: /* In some cases it is impossible to generate code for a forward goto
410: until the label definition is seen. This happens when it may be necessary
411: for the goto to reset the stack pointer: we don't yet know how to do that.
412: So expand_goto puts an entry on this fixup list.
413: Each time a binding contour that resets the stack is exited,
414: we check each fixup.
415: If the target label has now been defined, we can insert the proper code. */
1.1 root 416:
1.1.1.2 root 417: struct goto_fixup
1.1 root 418: {
1.1.1.2 root 419: /* Points to following fixup. */
420: struct goto_fixup *next;
421: /* Points to the insn before the jump insn.
422: If more code must be inserted, it goes after this insn. */
423: rtx before_jump;
1.1.1.6 root 424: /* The LABEL_DECL that this jump is jumping to, or 0
425: for break, continue or return. */
1.1.1.2 root 426: tree target;
1.1.1.6 root 427: /* The CODE_LABEL rtx that this is jumping to. */
428: rtx target_rtl;
1.1.1.19 root 429: /* Number of binding contours started in current function
430: before the label reference. */
431: int block_start_count;
1.1.1.2 root 432: /* The outermost stack level that should be restored for this jump.
433: Each time a binding contour that resets the stack is exited,
434: if the target label is *not* yet defined, this slot is updated. */
435: rtx stack_level;
1.1.1.13 root 436: /* List of lists of cleanup expressions to be run by this goto.
437: There is one element for each block that this goto is within.
438: The TREE_VALUE contains the cleanup list of that block as of the
439: time this goto was seen.
440: The TREE_ADDRESSABLE flag is 1 for a block that has been exited. */
1.1.1.7 root 441: tree cleanup_list_list;
1.1.1.2 root 442: };
443:
444: static struct goto_fixup *goto_fixup_chain;
445:
446: /* Within any binding contour that must restore a stack level,
447: all labels are recorded with a chain of these structures. */
448:
449: struct label_chain
450: {
451: /* Points to following fixup. */
452: struct label_chain *next;
453: tree label;
454: };
455:
456: /* Specify the location in the RTL code of a label BODY,
457: which is a LABEL_DECL tree node.
458:
459: This is used for the kind of label that the user can jump to with a
460: goto statement, and for alternatives of a switch or case statement.
461: RTL labels generated for loops and conditionals don't go through here;
462: they are generated directly at the RTL level, by other functions below.
463:
464: Note that this has nothing to do with defining label *names*.
465: Languages vary in how they do that and what that even means. */
466:
467: void
468: expand_label (body)
469: tree body;
470: {
471: struct label_chain *p;
472:
473: do_pending_stack_adjust ();
474: emit_label (label_rtx (body));
475:
1.1.1.7 root 476: if (stack_block_stack != 0)
1.1.1.2 root 477: {
478: p = (struct label_chain *) oballoc (sizeof (struct label_chain));
479: p->next = stack_block_stack->data.block.label_chain;
480: stack_block_stack->data.block.label_chain = p;
481: p->label = body;
482: }
1.1 root 483: }
484:
1.1.1.2 root 485: /* Generate RTL code for a `goto' statement with target label BODY.
486: BODY should be a LABEL_DECL tree node that was or will later be
487: defined with `expand_label'. */
488:
489: void
490: expand_goto (body)
491: tree body;
1.1 root 492: {
1.1.1.8 root 493: expand_goto_internal (body, label_rtx (body), 0);
1.1.1.6 root 494: }
495:
1.1.1.8 root 496: /* Generate RTL code for a `goto' statement with target label BODY.
497: LABEL should be a LABEL_REF.
498: LAST_INSN, if non-0, is the rtx we should consider as the last
1.1.1.9 root 499: insn emitted (for the purposes of cleaning up a return). */
1.1.1.8 root 500:
1.1.1.6 root 501: static void
1.1.1.8 root 502: expand_goto_internal (body, label, last_insn)
1.1.1.6 root 503: tree body;
504: rtx label;
1.1.1.8 root 505: rtx last_insn;
1.1.1.6 root 506: {
1.1.1.2 root 507: struct nesting *block;
508: rtx stack_level = 0;
509:
510: if (GET_CODE (label) != CODE_LABEL)
511: abort ();
512:
513: /* If label has already been defined, we can tell now
514: whether and how we must alter the stack level. */
515:
1.1.1.6 root 516: if (PREV_INSN (label) != 0)
1.1.1.2 root 517: {
1.1.1.13 root 518: /* Find the innermost pending block that contains the label.
1.1.1.2 root 519: (Check containment by comparing insn-uids.)
1.1.1.13 root 520: Then restore the outermost stack level within that block,
521: and do cleanups of all blocks contained in it. */
1.1.1.2 root 522: for (block = block_stack; block; block = block->next)
523: {
524: if (INSN_UID (block->data.block.first_insn) < INSN_UID (label))
525: break;
526: if (block->data.block.stack_level != 0)
527: stack_level = block->data.block.stack_level;
1.1.1.7 root 528: /* Execute the cleanups for blocks we are exiting. */
529: if (block->data.block.cleanups != 0)
530: expand_cleanups (block->data.block.cleanups, 0);
1.1.1.2 root 531: }
532:
533: if (stack_level)
534: emit_move_insn (stack_pointer_rtx, stack_level);
535:
1.1.1.6 root 536: if (body != 0 && TREE_PACKED (body))
1.1.1.13 root 537: error ("jump to `%s' invalidly jumps into binding contour",
1.1.1.2 root 538: IDENTIFIER_POINTER (DECL_NAME (body)));
539: }
540: /* Label not yet defined: may need to put this goto
541: on the fixup list. */
1.1.1.8 root 542: else if (! expand_fixup (body, label, last_insn))
1.1.1.13 root 543: {
544: /* No fixup needed. Record that the label is the target
545: of at least one goto that has no fixup. */
546: if (body != 0)
547: TREE_ADDRESSABLE (body) = 1;
548: }
1.1.1.2 root 549:
1.1.1.6 root 550: emit_jump (label);
551: }
552:
553: /* Generate if necessary a fixup for a goto
554: whose target label in tree structure (if any) is TREE_LABEL
555: and whose target in rtl is RTL_LABEL.
556:
1.1.1.8 root 557: If LAST_INSN is nonzero, we pretend that the jump appears
558: after insn LAST_INSN instead of at the current point in the insn stream.
559:
1.1.1.6 root 560: The fixup will be used later to insert insns at this point
561: to restore the stack level as appropriate for the target label.
562:
563: Value is nonzero if a fixup is made. */
564:
565: static int
1.1.1.8 root 566: expand_fixup (tree_label, rtl_label, last_insn)
1.1.1.6 root 567: tree tree_label;
568: rtx rtl_label;
1.1.1.8 root 569: rtx last_insn;
1.1.1.6 root 570: {
1.1.1.13 root 571: struct nesting *block, *end_block;
572:
573: /* See if we can recognize which block the label will be output in.
574: This is possible in some very common cases.
575: If we succeed, set END_BLOCK to that block.
576: Otherwise, set it to 0. */
577:
578: if (cond_stack
579: && (rtl_label == cond_stack->data.cond.else_label
580: || rtl_label == cond_stack->data.cond.after_label))
581: end_block = cond_stack;
582: /* If we are in a loop, recognize certain labels which
583: are likely targets. This reduces the number of fixups
584: we need to create. */
585: else if (loop_stack
586: && (rtl_label == loop_stack->data.loop.start_label
587: || rtl_label == loop_stack->data.loop.end_label
588: || rtl_label == loop_stack->data.loop.continue_label))
589: end_block = loop_stack;
590: else
591: end_block = 0;
592:
593: /* Now set END_BLOCK to the binding level to which we will return. */
594:
595: if (end_block)
596: {
597: struct nesting *next_block = end_block->all;
598: block = block_stack;
599:
600: /* First see if the END_BLOCK is inside the innermost binding level.
601: If so, then no cleanups or stack levels are relevant. */
602: while (next_block && next_block != block)
603: next_block = next_block->all;
604:
605: if (next_block)
606: return 0;
607:
608: /* Otherwise, set END_BLOCK to the innermost binding level
609: which is outside the relevant control-structure nesting. */
610: next_block = block_stack->next;
611: for (block = block_stack; block != end_block; block = block->all)
612: if (block == next_block)
613: next_block = next_block->next;
614: end_block = next_block;
615: }
616:
1.1.1.7 root 617: /* Does any containing block have a stack level or cleanups?
1.1.1.6 root 618: If not, no fixup is needed, and that is the normal case
619: (the only case, for standard C). */
1.1.1.13 root 620: for (block = block_stack; block != end_block; block = block->next)
1.1.1.7 root 621: if (block->data.block.stack_level != 0
622: || block->data.block.cleanups != 0)
1.1.1.6 root 623: break;
624:
1.1.1.13 root 625: if (block != end_block)
1.1.1.6 root 626: {
627: /* Ok, a fixup is needed. Add a fixup to the list of such. */
628: struct goto_fixup *fixup
629: = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
630: /* In case an old stack level is restored, make sure that comes
631: after any pending stack adjust. */
632: do_pending_stack_adjust ();
1.1.1.8 root 633: fixup->before_jump = last_insn ? last_insn : get_last_insn ();
1.1.1.6 root 634: fixup->target = tree_label;
635: fixup->target_rtl = rtl_label;
1.1.1.19 root 636: fixup->block_start_count = block_start_count;
1.1.1.6 root 637: fixup->stack_level = 0;
1.1.1.13 root 638: fixup->cleanup_list_list
639: = (block->data.block.outer_cleanups || block->data.block.cleanups
640: ? tree_cons (0, block->data.block.cleanups,
641: block->data.block.outer_cleanups)
642: : 0);
1.1.1.6 root 643: fixup->next = goto_fixup_chain;
644: goto_fixup_chain = fixup;
1.1.1.2 root 645: }
646:
1.1.1.6 root 647: return block != 0;
1.1 root 648: }
649:
1.1.1.2 root 650: /* When exiting a binding contour, process all pending gotos requiring fixups.
1.1.1.13 root 651: THISBLOCK is the structure that describes the block being exited.
1.1.1.7 root 652: STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
1.1.1.13 root 653: CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
654: FIRST_INSN is the insn that began this contour.
1.1.1.7 root 655:
1.1.1.2 root 656: Gotos that jump out of this contour must restore the
1.1.1.7 root 657: stack level and do the cleanups before actually jumping.
1.1 root 658:
1.1.1.7 root 659: DONT_JUMP_IN nonzero means report error there is a jump into this
660: contour from before the beginning of the contour.
661: This is also done if STACK_LEVEL is nonzero. */
1.1 root 662:
1.1.1.2 root 663: static void
1.1.1.13 root 664: fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
665: struct nesting *thisblock;
1.1.1.2 root 666: rtx stack_level;
1.1.1.7 root 667: tree cleanup_list;
1.1.1.2 root 668: rtx first_insn;
1.1.1.7 root 669: int dont_jump_in;
1.1 root 670: {
1.1.1.13 root 671: register struct goto_fixup *f, *prev;
1.1 root 672:
1.1.1.13 root 673: /* F is the fixup we are considering; PREV is the previous one. */
674:
675: for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
1.1.1.2 root 676: {
677: /* Test for a fixup that is inactive because it is already handled. */
678: if (f->before_jump == 0)
1.1.1.13 root 679: {
680: /* Delete inactive fixup from the chain, if that is easy to do. */
681: if (prev != 0)
682: prev->next = f->next;
683: }
1.1.1.2 root 684: /* Has this fixup's target label been defined?
685: If so, we can finalize it. */
1.1.1.6 root 686: else if (PREV_INSN (f->target_rtl) != 0)
1.1.1.2 root 687: {
1.1.1.21 root 688: rtx after_label = f->target_rtl;
689: while (after_label != 0 && GET_CODE (after_label) == CODE_LABEL)
690: after_label = NEXT_INSN (after_label);
691:
1.1.1.2 root 692: /* If this fixup jumped into this contour from before the beginning
693: of this contour, report an error. */
1.1.1.13 root 694: /* ??? Bug: this does not detect jumping in through intermediate
695: blocks that have stack levels or cleanups.
696: It detects only a problem with the innermost block
697: around the label. */
1.1.1.6 root 698: if (f->target != 0
1.1.1.13 root 699: && (dont_jump_in || stack_level || cleanup_list)
1.1.1.21 root 700: /* If AFTER_LABEL is 0, it means the jump goes to the end
701: of the rtl, which means it jumps into this scope. */
702: && (after_label == 0
703: || INSN_UID (first_insn) < INSN_UID (after_label))
1.1.1.6 root 704: && INSN_UID (first_insn) > INSN_UID (f->before_jump)
1.1.1.21 root 705: && ! TREE_REGDECL (f->target))
1.1.1.2 root 706: {
1.1.1.13 root 707: error_with_decl (f->target,
708: "label `%s' used before containing binding contour");
1.1.1.2 root 709: /* Prevent multiple errors for one label. */
1.1.1.21 root 710: TREE_REGDECL (f->target) = 1;
1.1.1.2 root 711: }
1.1 root 712:
1.1.1.7 root 713: /* Execute cleanups for blocks this jump exits. */
714: if (f->cleanup_list_list)
1.1.1.13 root 715: {
716: tree lists;
717: for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists))
718: /* Marked elements correspond to blocks that have been closed.
719: Do their cleanups. */
720: if (TREE_ADDRESSABLE (lists)
721: && TREE_VALUE (lists) != 0)
722: fixup_cleanups (TREE_VALUE (lists), &f->before_jump);
723: }
1.1.1.7 root 724:
1.1.1.2 root 725: /* Restore stack level for the biggest contour that this
726: jump jumps out of. */
727: if (f->stack_level)
728: emit_insn_after (gen_move_insn (stack_pointer_rtx, f->stack_level),
729: f->before_jump);
730: f->before_jump = 0;
731: }
732: /* Label has still not appeared. If we are exiting a block with
1.1.1.19 root 733: a stack level to restore, that started before the fixup,
734: mark this stack level as needing restoration
735: when the fixup is later finalized.
1.1.1.13 root 736: Also mark the cleanup_list_list element for F
737: that corresponds to this block, so that ultimately
738: this block's cleanups will be executed by the code above. */
1.1.1.15 root 739: /* Note: if THISBLOCK == 0 and we have a label that hasn't appeared,
740: it means the label is undefined. That's erroneous, but possible. */
1.1.1.19 root 741: else if (thisblock != 0
742: && (thisblock->data.block.block_start_count
743: < f->block_start_count))
1.1.1.7 root 744: {
1.1.1.13 root 745: tree lists = f->cleanup_list_list;
746: for (; lists; lists = TREE_CHAIN (lists))
747: /* If the following elt. corresponds to our containing block
748: then the elt. must be for this block. */
749: if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups)
750: TREE_ADDRESSABLE (lists) = 1;
751:
1.1.1.7 root 752: if (stack_level)
753: f->stack_level = stack_level;
754: }
1.1.1.2 root 755: }
756: }
757:
758: /* Generate RTL for an asm statement (explicit assembler code).
759: BODY is a STRING_CST node containing the assembler code text. */
760:
761: void
762: expand_asm (body)
763: tree body;
1.1 root 764: {
1.1.1.2 root 765: emit_insn (gen_rtx (ASM_INPUT, VOIDmode,
766: TREE_STRING_POINTER (body)));
767: last_expr_type = 0;
768: }
769:
770: /* Generate RTL for an asm statement with arguments.
771: STRING is the instruction template.
772: OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
773: Each output or input has an expression in the TREE_VALUE and
774: a constraint-string in the TREE_PURPOSE.
1.1.1.8 root 775: CLOBBERS is a list of STRING_CST nodes each naming a hard register
776: that is clobbered by this insn.
1.1.1.2 root 777:
778: Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
779: Some elements of OUTPUTS may be replaced with trees representing temporary
780: values. The caller should copy those temporary values to the originally
781: specified lvalues.
1.1 root 782:
1.1.1.2 root 783: VOL nonzero means the insn is volatile; don't optimize it. */
1.1 root 784:
1.1.1.2 root 785: void
1.1.1.13 root 786: expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
1.1.1.8 root 787: tree string, outputs, inputs, clobbers;
1.1.1.2 root 788: int vol;
1.1.1.13 root 789: char *filename;
790: int line;
1.1.1.2 root 791: {
792: rtvec argvec, constraints;
793: rtx body;
794: int ninputs = list_length (inputs);
795: int noutputs = list_length (outputs);
1.1.1.8 root 796: int nclobbers = list_length (clobbers);
1.1.1.2 root 797: tree tail;
1.1.1.13 root 798: register int i;
799: /* Vector of RTX's of evaluated output operands. */
800: rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
801: /* The insn we have emitted. */
802: rtx insn;
1.1.1.2 root 803:
1.1.1.4 root 804: last_expr_type = 0;
805:
1.1.1.2 root 806: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
807: {
808: tree val = TREE_VALUE (tail);
1.1.1.19 root 809: tree val1;
1.1.1.14 root 810: int j;
811: int found_equal;
1.1 root 812:
1.1.1.4 root 813: /* If there's an erroneous arg, emit no insn. */
814: if (TREE_TYPE (val) == error_mark_node)
815: return;
816:
1.1.1.14 root 817: /* Make sure constraint has `=' and does not have `+'. */
818:
819: found_equal = 0;
820: for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
821: {
822: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
823: {
1.1.1.17 root 824: error ("output operand constraint contains `+'");
1.1.1.14 root 825: return;
826: }
827: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '=')
828: found_equal = 1;
829: }
830: if (! found_equal)
831: {
832: error ("output operand constraint lacks `='");
833: return;
834: }
835:
1.1.1.2 root 836: /* If an output operand is not a variable or indirect ref,
1.1.1.19 root 837: or a part of one,
1.1.1.2 root 838: create a SAVE_EXPR which is a pseudo-reg
839: to act as an intermediate temporary.
840: Make the asm insn write into that, then copy it to
841: the real output operand. */
842:
1.1.1.19 root 843: val1 = val;
844: while (TREE_CODE (val1) == COMPONENT_REF
845: || TREE_CODE (val1) == ARRAY_REF)
846: val1 = TREE_OPERAND (val1, 0);
847:
848: if (TREE_CODE (val1) != VAR_DECL
849: && TREE_CODE (val1) != PARM_DECL
850: && TREE_CODE (val1) != INDIRECT_REF)
1.1.1.10 root 851: {
852: rtx reg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (val)));
853: /* `build' isn't safe; it really expects args to be trees. */
854: tree t = build_nt (SAVE_EXPR, val, reg);
855:
1.1.1.19 root 856: if (GET_MODE (reg) == BLKmode)
857: abort ();
858:
1.1.1.10 root 859: save_expr_regs = gen_rtx (EXPR_LIST, VOIDmode, reg, save_expr_regs);
860: TREE_VALUE (tail) = t;
861: TREE_TYPE (t) = TREE_TYPE (val);
862: }
1.1.1.13 root 863: output_rtx[i] = expand_expr (TREE_VALUE (tail), 0, VOIDmode, 0);
1.1.1.2 root 864: }
1.1 root 865:
1.1.1.8 root 866: if (ninputs + noutputs > MAX_RECOG_OPERANDS)
867: {
868: error ("more than %d operands in `asm'", MAX_RECOG_OPERANDS);
869: return;
870: }
871:
1.1.1.2 root 872: /* Make vectors for the expression-rtx and constraint strings. */
1.1 root 873:
1.1.1.4 root 874: argvec = rtvec_alloc (ninputs);
875: constraints = rtvec_alloc (ninputs);
1.1 root 876:
1.1.1.2 root 877: body = gen_rtx (ASM_OPERANDS, VOIDmode,
1.1.1.16 root 878: TREE_STRING_POINTER (string), "", 0, argvec, constraints,
879: filename, line);
1.1.1.10 root 880: MEM_VOLATILE_P (body) = vol;
1.1 root 881:
1.1.1.2 root 882: /* Eval the inputs and put them into ARGVEC.
883: Put their constraints into ASM_INPUTs and store in CONSTRAINTS. */
1.1 root 884:
1.1.1.2 root 885: i = 0;
886: for (tail = inputs; tail; tail = TREE_CHAIN (tail))
887: {
1.1.1.14 root 888: int j;
889:
1.1.1.4 root 890: /* If there's an erroneous arg, emit no insn,
891: because the ASM_INPUT would get VOIDmode
892: and that could cause a crash in reload. */
893: if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
894: return;
1.1.1.8 root 895: if (TREE_PURPOSE (tail) == NULL_TREE)
896: {
1.1.1.13 root 897: error ("hard register `%s' listed as input operand to `asm'",
1.1.1.8 root 898: TREE_STRING_POINTER (TREE_VALUE (tail)) );
899: return;
900: }
1.1.1.4 root 901:
1.1.1.14 root 902: /* Make sure constraint has neither `=' nor `+'. */
903:
904: for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
905: if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '='
906: || TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
907: {
908: error ("input operand constraint contains `%c'",
909: TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
910: return;
911: }
912:
1.1.1.2 root 913: XVECEXP (body, 3, i) /* argvec */
914: = expand_expr (TREE_VALUE (tail), 0, VOIDmode, 0);
915: XVECEXP (body, 4, i) /* constraints */
916: = gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
917: TREE_STRING_POINTER (TREE_PURPOSE (tail)));
918: i++;
919: }
1.1 root 920:
1.1.1.13 root 921: /* Protect all the operands from the queue,
922: now that they have all been evaluated. */
923:
924: for (i = 0; i < ninputs; i++)
925: XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0);
926:
927: for (i = 0; i < noutputs; i++)
928: output_rtx[i] = protect_from_queue (output_rtx[i], 1);
929:
1.1.1.2 root 930: /* Now, for each output, construct an rtx
931: (set OUTPUT (asm_operands INSN OUTPUTNUMBER OUTPUTCONSTRAINT
932: ARGVEC CONSTRAINTS))
933: If there is more than one, put them inside a PARALLEL. */
1.1 root 934:
1.1.1.8 root 935: if (noutputs == 1 && nclobbers == 0)
1.1.1.2 root 936: {
937: XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
1.1.1.13 root 938: insn = emit_insn (gen_rtx (SET, VOIDmode, output_rtx[0], body));
1.1.1.2 root 939: }
1.1.1.8 root 940: else if (noutputs == 0 && nclobbers == 0)
1.1.1.5 root 941: {
942: /* No output operands: put in a raw ASM_OPERANDS rtx. */
1.1.1.13 root 943: insn = emit_insn (body);
1.1.1.5 root 944: }
1.1.1.2 root 945: else
946: {
1.1.1.12 root 947: rtx obody = body;
948: int num = noutputs;
949: if (num == 0) num = 1;
950: body = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num + nclobbers));
1.1.1.8 root 951:
952: /* For each output operand, store a SET. */
1.1.1.2 root 953:
954: for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
1.1 root 955: {
1.1.1.2 root 956: XVECEXP (body, 0, i)
957: = gen_rtx (SET, VOIDmode,
1.1.1.13 root 958: output_rtx[i],
1.1.1.2 root 959: gen_rtx (ASM_OPERANDS, VOIDmode,
960: TREE_STRING_POINTER (string),
961: TREE_STRING_POINTER (TREE_PURPOSE (tail)),
1.1.1.16 root 962: i, argvec, constraints,
963: filename, line));
1.1.1.10 root 964: MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
1.1 root 965: }
966:
1.1.1.12 root 967: /* If there are no outputs (but there are some clobbers)
968: store the bare ASM_OPERANDS into the PARALLEL. */
969:
970: if (i == 0)
971: XVECEXP (body, 0, i++) = obody;
972:
1.1.1.8 root 973: /* Store (clobber REG) for each clobbered register specified. */
974:
975: for (tail = clobbers; tail; tail = TREE_CHAIN (tail), i++)
976: {
977: int j;
978: char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
979: extern char *reg_names[];
980:
981: for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
982: if (!strcmp (regname, reg_names[j]))
983: break;
984:
985: if (j == FIRST_PSEUDO_REGISTER)
986: {
1.1.1.13 root 987: error ("unknown register name `%s' in `asm'", regname);
1.1.1.8 root 988: return;
989: }
990:
1.1.1.12 root 991: /* Use QImode since that's guaranteed to clobber just one reg. */
1.1.1.8 root 992: XVECEXP (body, 0, i)
1.1.1.12 root 993: = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, QImode, j));
1.1.1.8 root 994: }
995:
1.1.1.13 root 996: insn = emit_insn (body);
1.1.1.2 root 997: }
1.1.1.13 root 998:
1.1.1.2 root 999: last_expr_type = 0;
1000: }
1.1 root 1001:
1.1.1.2 root 1002: /* Nonzero if within a ({...}) grouping, in which case we must
1003: always compute a value for each expr-stmt in case it is the last one. */
1.1 root 1004:
1.1.1.2 root 1005: int expr_stmts_for_value;
1.1 root 1006:
1.1.1.2 root 1007: /* Generate RTL to evaluate the expression EXP
1008: and remember it in case this is the VALUE in a ({... VALUE; }) constr. */
1.1 root 1009:
1.1.1.2 root 1010: void
1011: expand_expr_stmt (exp)
1012: tree exp;
1013: {
1.1.1.13 root 1014: /* If -W, warn about statements with no side effects,
1015: except inside a ({...}) where they may be useful. */
1.1.1.17 root 1016: if (expr_stmts_for_value == 0 && exp != error_mark_node)
1017: {
1018: if (! TREE_VOLATILE (exp) && (extra_warnings || warn_unused))
1019: warning_with_file_and_line (emit_filename, emit_lineno,
1020: "statement with no effect");
1021: else if (warn_unused)
1022: warn_if_unused_value (exp);
1023: }
1.1.1.2 root 1024: last_expr_type = TREE_TYPE (exp);
1.1.1.13 root 1025: if (! flag_syntax_only)
1026: last_expr_value = expand_expr (exp, expr_stmts_for_value ? 0 : const0_rtx,
1027: VOIDmode, 0);
1.1.1.2 root 1028: emit_queue ();
1029: }
1.1 root 1030:
1.1.1.17 root 1031: /* Warn if EXP contains any computations whose results are not used.
1032: Return 1 if a warning is printed; 0 otherwise. */
1033:
1034: static int
1035: warn_if_unused_value (exp)
1036: tree exp;
1037: {
1038: switch (TREE_CODE (exp))
1039: {
1040: case PREINCREMENT_EXPR:
1041: case POSTINCREMENT_EXPR:
1042: case PREDECREMENT_EXPR:
1043: case POSTDECREMENT_EXPR:
1044: case MODIFY_EXPR:
1045: case INIT_EXPR:
1046: case NEW_EXPR:
1047: case DELETE_EXPR:
1048: case PUSH_EXPR:
1049: case POP_EXPR:
1050: case CALL_EXPR:
1051: case METHOD_CALL_EXPR:
1052: case RTL_EXPR:
1053: case WRAPPER_EXPR:
1054: case ANTI_WRAPPER_EXPR:
1055: case WITH_CLEANUP_EXPR:
1056: /* We don't warn about COND_EXPR because it may be a useful
1057: construct if either arm contains a side effect. */
1058: case COND_EXPR:
1059: return 0;
1060:
1061: case TRUTH_ORIF_EXPR:
1062: case TRUTH_ANDIF_EXPR:
1063: /* In && or ||, warn if 2nd operand has no side effect. */
1064: return warn_if_unused_value (TREE_OPERAND (exp, 1));
1065:
1066: case COMPOUND_EXPR:
1067: if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
1068: return 1;
1069: return warn_if_unused_value (TREE_OPERAND (exp, 1));
1070:
1071: case NOP_EXPR:
1072: case CONVERT_EXPR:
1073: /* Don't warn about values cast to void. */
1074: if (TREE_TYPE (exp) == void_type_node)
1075: return 0;
1076: /* Assignment to a cast results in a cast of a modify.
1077: Don't complain about that. */
1078: if (TREE_CODE (TREE_OPERAND (exp, 0)) == MODIFY_EXPR)
1079: return 0;
1080:
1081: default:
1082: warning_with_file_and_line (emit_filename, emit_lineno,
1083: "value computed is not used");
1084: return 1;
1085: }
1086: }
1087:
1.1.1.2 root 1088: /* Clear out the memory of the last expression evaluated. */
1.1 root 1089:
1.1.1.2 root 1090: void
1091: clear_last_expr ()
1092: {
1093: last_expr_type = 0;
1094: }
1.1 root 1095:
1.1.1.7 root 1096: /* Begin a statement which will return a value.
1.1.1.10 root 1097: Return the RTL_EXPR for this statement expr.
1098: The caller must save that value and pass it to expand_end_stmt_expr. */
1.1.1.7 root 1099:
1100: tree
1101: expand_start_stmt_expr ()
1102: {
1103: rtx save = start_sequence ();
1.1.1.10 root 1104: /* Make the RTL_EXPR node temporary, not momentary,
1105: so that rtl_expr_chain doesn't become garbage. */
1106: int momentary = suspend_momentary ();
1.1.1.7 root 1107: tree t = make_node (RTL_EXPR);
1.1.1.10 root 1108: resume_momentary (momentary);
1.1.1.7 root 1109: RTL_EXPR_RTL (t) = save;
1.1.1.17 root 1110: NO_DEFER_POP;
1.1.1.10 root 1111: expr_stmts_for_value++;
1.1.1.7 root 1112: return t;
1113: }
1114:
1115: /* Restore the previous state at the end of a statement that returns a value.
1116: Returns a tree node representing the statement's value and the
1117: insns to compute the value.
1118:
1.1.1.2 root 1119: The nodes of that expression have been freed by now, so we cannot use them.
1120: But we don't want to do that anyway; the expression has already been
1.1.1.10 root 1121: evaluated and now we just want to use the value. So generate a RTL_EXPR
1.1.1.2 root 1122: with the proper type and RTL value.
1.1 root 1123:
1.1.1.7 root 1124: If the last substatement was not an expression,
1.1.1.2 root 1125: return something with type `void'. */
1.1 root 1126:
1.1.1.2 root 1127: tree
1.1.1.7 root 1128: expand_end_stmt_expr (t)
1129: tree t;
1.1.1.2 root 1130: {
1.1.1.7 root 1131: rtx saved = RTL_EXPR_RTL (t);
1.1 root 1132:
1.1.1.22! root 1133: emit_queue ();
! 1134:
1.1.1.17 root 1135: OK_DEFER_POP;
1.1.1.16 root 1136:
1.1.1.2 root 1137: if (last_expr_type == 0)
1138: {
1139: last_expr_type = void_type_node;
1140: last_expr_value = const0_rtx;
1141: }
1.1.1.22! root 1142: else if (last_expr_value == 0)
! 1143: /* There are some cases where this can happen, such as when the
! 1144: statement is void type. */
! 1145: last_expr_value = const0_rtx;
! 1146: else
! 1147: last_expr_value = protect_from_queue (last_expr_value, 0);
! 1148:
1.1.1.7 root 1149: TREE_TYPE (t) = last_expr_type;
1.1.1.2 root 1150: RTL_EXPR_RTL (t) = last_expr_value;
1.1.1.10 root 1151: RTL_EXPR_SEQUENCE (t) = get_insns ();
1152:
1153: rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
1.1 root 1154:
1.1.1.7 root 1155: end_sequence (saved);
1.1.1.10 root 1156:
1157: /* Don't consider deleting this expr or containing exprs at tree level. */
1158: TREE_VOLATILE (t) = 1;
1159: /* Propagate volatility of the actual RTL expr. */
1160: TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
1161:
1162: last_expr_type = 0;
1.1.1.2 root 1163: expr_stmts_for_value--;
1.1.1.7 root 1164:
1165: return t;
1.1.1.2 root 1166: }
1167:
1168: /* Generate RTL for the start of an if-then. COND is the expression
1169: whose truth should be tested.
1.1 root 1170:
1.1.1.2 root 1171: If EXITFLAG is nonzero, this conditional is visible to
1172: `exit_something'. */
1.1 root 1173:
1.1.1.2 root 1174: void
1175: expand_start_cond (cond, exitflag)
1176: tree cond;
1177: int exitflag;
1178: {
1179: struct nesting *thiscond
1180: = (struct nesting *) xmalloc (sizeof (struct nesting));
1.1 root 1181:
1.1.1.2 root 1182: /* Make an entry on cond_stack for the cond we are entering. */
1.1 root 1183:
1.1.1.2 root 1184: thiscond->next = cond_stack;
1185: thiscond->all = nesting_stack;
1186: thiscond->depth = ++nesting_depth;
1187: thiscond->data.cond.after_label = 0;
1188: thiscond->data.cond.else_label = gen_label_rtx ();
1189: thiscond->exit_label = exitflag ? thiscond->data.cond.else_label : 0;
1190: cond_stack = thiscond;
1191: nesting_stack = thiscond;
1.1 root 1192:
1.1.1.2 root 1193: do_jump (cond, thiscond->data.cond.else_label, NULL);
1194: }
1.1 root 1195:
1.1.1.2 root 1196: /* Generate RTL for the end of an if-then with no else-clause.
1197: Pop the record for it off of cond_stack. */
1.1 root 1198:
1.1.1.2 root 1199: void
1200: expand_end_cond ()
1201: {
1202: struct nesting *thiscond = cond_stack;
1.1 root 1203:
1.1.1.2 root 1204: do_pending_stack_adjust ();
1205: emit_label (thiscond->data.cond.else_label);
1.1 root 1206:
1.1.1.2 root 1207: POPSTACK (cond_stack);
1208: last_expr_type = 0;
1209: }
1.1 root 1210:
1.1.1.2 root 1211: /* Generate RTL between the then-clause and the else-clause
1212: of an if-then-else. */
1.1 root 1213:
1.1.1.2 root 1214: void
1215: expand_start_else ()
1216: {
1217: cond_stack->data.cond.after_label = gen_label_rtx ();
1218: if (cond_stack->exit_label != 0)
1219: cond_stack->exit_label = cond_stack->data.cond.after_label;
1220: emit_jump (cond_stack->data.cond.after_label);
1221: if (cond_stack->data.cond.else_label)
1222: emit_label (cond_stack->data.cond.else_label);
1223: }
1.1 root 1224:
1.1.1.2 root 1225: /* Generate RTL for the end of an if-then-else.
1226: Pop the record for it off of cond_stack. */
1227:
1228: void
1229: expand_end_else ()
1230: {
1231: struct nesting *thiscond = cond_stack;
1232:
1233: do_pending_stack_adjust ();
1234: /* Note: a syntax error can cause this to be called
1235: without first calling `expand_start_else'. */
1236: if (thiscond->data.cond.after_label)
1237: emit_label (thiscond->data.cond.after_label);
1238:
1239: POPSTACK (cond_stack);
1240: last_expr_type = 0;
1241: }
1242:
1243: /* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this
1244: loop should be exited by `exit_something'. This is a loop for which
1245: `expand_continue' will jump to the top of the loop.
1246:
1247: Make an entry on loop_stack to record the labels associated with
1248: this loop. */
1249:
1250: void
1251: expand_start_loop (exit_flag)
1252: int exit_flag;
1253: {
1254: register struct nesting *thisloop
1255: = (struct nesting *) xmalloc (sizeof (struct nesting));
1256:
1257: /* Make an entry on loop_stack for the loop we are entering. */
1258:
1259: thisloop->next = loop_stack;
1260: thisloop->all = nesting_stack;
1261: thisloop->depth = ++nesting_depth;
1262: thisloop->data.loop.start_label = gen_label_rtx ();
1263: thisloop->data.loop.end_label = gen_label_rtx ();
1264: thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
1265: thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
1266: loop_stack = thisloop;
1267: nesting_stack = thisloop;
1268:
1269: do_pending_stack_adjust ();
1270: emit_queue ();
1271: emit_note (0, NOTE_INSN_LOOP_BEG);
1272: emit_label (thisloop->data.loop.start_label);
1273: }
1274:
1275: /* Like expand_start_loop but for a loop where the continuation point
1276: (for expand_continue_loop) will be specified explicitly. */
1.1 root 1277:
1.1.1.2 root 1278: void
1279: expand_start_loop_continue_elsewhere (exit_flag)
1280: int exit_flag;
1281: {
1282: expand_start_loop (exit_flag);
1283: loop_stack->data.loop.continue_label = gen_label_rtx ();
1284: }
1285:
1286: /* Specify the continuation point for a loop started with
1287: expand_start_loop_continue_elsewhere.
1288: Use this at the point in the code to which a continue statement
1289: should jump. */
1290:
1291: void
1292: expand_loop_continue_here ()
1293: {
1294: do_pending_stack_adjust ();
1.1.1.16 root 1295: emit_note (0, NOTE_INSN_LOOP_CONT);
1.1.1.2 root 1296: emit_label (loop_stack->data.loop.continue_label);
1297: }
1298:
1299: /* Finish a loop. Generate a jump back to the top and the loop-exit label.
1300: Pop the block off of loop_stack. */
1301:
1302: void
1303: expand_end_loop ()
1304: {
1305: register rtx insn = get_last_insn ();
1306: register rtx start_label = loop_stack->data.loop.start_label;
1307:
1308: do_pending_stack_adjust ();
1309:
1.1.1.21 root 1310: while (insn && GET_CODE (insn) == NOTE)
1311: insn = PREV_INSN (insn);
1312:
1.1.1.2 root 1313: /* If optimizing, perhaps reorder the loop. If the loop
1.1.1.21 root 1314: does not already end with a conditional branch, scan over the
1315: insns within the loop and try to find a conditional branch which
1316: is a loop exit. If such an insn is found, move that insn (and
1317: its predecessors) to the end of the loop so that the conditional
1318: exit and the jump back can perhaps be optimized into one insn. */
1319:
1320: if (optimize && insn != 0
1.1.1.2 root 1321: &&
1322: ! (GET_CODE (insn) == JUMP_INSN
1323: && GET_CODE (PATTERN (insn)) == SET
1324: && SET_DEST (PATTERN (insn)) == pc_rtx
1325: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))
1326: {
1327: /* Scan insns from the top of the loop looking for a qualified
1328: conditional exit. */
1329: for (insn = loop_stack->data.loop.start_label; insn; insn= NEXT_INSN (insn))
1330: if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET
1331: && SET_DEST (PATTERN (insn)) == pc_rtx
1332: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE
1333: &&
1334: ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF
1335: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
1336: == loop_stack->data.loop.end_label))
1337: ||
1338: (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
1339: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
1340: == loop_stack->data.loop.end_label))))
1341: break;
1342: if (insn != 0)
1343: {
1344: /* We found one. Move everything from there up
1345: to the end of the loop, and add a jump into the loop
1346: to jump to there. */
1347: register rtx newstart_label = gen_label_rtx ();
1348:
1349: emit_label_after (newstart_label, PREV_INSN (start_label));
1350: reorder_insns (start_label, insn, get_last_insn ());
1351: emit_jump_insn_after (gen_jump (start_label), PREV_INSN (newstart_label));
1352: emit_barrier_after (PREV_INSN (newstart_label));
1353: start_label = newstart_label;
1354: }
1355: }
1356:
1357: emit_jump (start_label);
1358: emit_note (0, NOTE_INSN_LOOP_END);
1359: emit_label (loop_stack->data.loop.end_label);
1360:
1361: POPSTACK (loop_stack);
1362:
1363: last_expr_type = 0;
1364: }
1365:
1366: /* Generate a jump to the current loop's continue-point.
1367: This is usually the top of the loop, but may be specified
1368: explicitly elsewhere. If not currently inside a loop,
1369: return 0 and do nothing; caller will print an error message. */
1370:
1371: int
1372: expand_continue_loop ()
1373: {
1374: last_expr_type = 0;
1375: if (loop_stack == 0)
1376: return 0;
1.1.1.8 root 1377: expand_goto_internal (0, loop_stack->data.loop.continue_label, 0);
1.1.1.2 root 1378: return 1;
1379: }
1380:
1381: /* Generate a jump to exit the current loop. If not currently inside a loop,
1382: return 0 and do nothing; caller will print an error message. */
1383:
1384: int
1385: expand_exit_loop ()
1386: {
1387: last_expr_type = 0;
1388: if (loop_stack == 0)
1389: return 0;
1.1.1.8 root 1390: expand_goto_internal (0, loop_stack->data.loop.end_label, 0);
1.1.1.2 root 1391: return 1;
1392: }
1393:
1394: /* Generate a conditional jump to exit the current loop if COND
1395: evaluates to zero. If not currently inside a loop,
1396: return 0 and do nothing; caller will print an error message. */
1397:
1398: int
1399: expand_exit_loop_if_false (cond)
1400: tree cond;
1401: {
1402: last_expr_type = 0;
1403: if (loop_stack == 0)
1404: return 0;
1405: do_jump (cond, loop_stack->data.loop.end_label, NULL);
1406: return 1;
1407: }
1408:
1.1.1.17 root 1409: /* Return non-zero if currently inside a loop. */
1410:
1411: int
1412: inside_loop ()
1413: {
1414: return loop_stack != 0;
1415: }
1416:
1.1.1.2 root 1417: /* Generate a jump to exit the current loop, conditional, binding contour
1418: or case statement. Not all such constructs are visible to this function,
1419: only those started with EXIT_FLAG nonzero. Individual languages use
1420: the EXIT_FLAG parameter to control which kinds of constructs you can
1421: exit this way.
1422:
1423: If not currently inside anything that can be exited,
1424: return 0 and do nothing; caller will print an error message. */
1425:
1426: int
1427: expand_exit_something ()
1428: {
1429: struct nesting *n;
1430: last_expr_type = 0;
1431: for (n = nesting_stack; n; n = n->all)
1.1.1.7 root 1432: if (n->exit_label != 0)
1433: {
1.1.1.8 root 1434: expand_goto_internal (0, n->exit_label, 0);
1.1.1.7 root 1435: return 1;
1436: }
1437:
1.1.1.2 root 1438: return 0;
1439: }
1440:
1441: /* Generate RTL to return from the current function, with no value.
1442: (That is, we do not do anything about returning any value.) */
1443:
1444: void
1445: expand_null_return ()
1446: {
1.1.1.17 root 1447: struct nesting *block = block_stack;
1448: rtx last_insn = 0;
1449:
1450: /* Does any pending block have cleanups? */
1451:
1452: while (block && block->data.block.cleanups == 0)
1453: block = block->next;
1454:
1455: /* If yes, use a goto to return, since that runs cleanups. */
1456:
1457: expand_null_return_1 (last_insn, block != 0);
1.1.1.8 root 1458: }
1459:
1460: /* Output a return with no value. If LAST_INSN is nonzero,
1.1.1.17 root 1461: pretend that the return takes place after LAST_INSN.
1462: If USE_GOTO is nonzero then don't use a return instruction;
1463: go to the return label instead. This causes any cleanups
1464: of pending blocks to be executed normally. */
1.1.1.8 root 1465:
1466: static void
1.1.1.17 root 1467: expand_null_return_1 (last_insn, use_goto)
1.1.1.8 root 1468: rtx last_insn;
1.1.1.17 root 1469: int use_goto;
1.1.1.8 root 1470: {
1.1.1.17 root 1471: rtx end_label = cleanup_label ? cleanup_label : return_label;
1472:
1.1.1.2 root 1473: clear_pending_stack_adjust ();
1.1.1.10 root 1474: do_pending_stack_adjust ();
1.1.1.16 root 1475: last_expr_type = 0;
1476:
1477: /* PCC-struct return always uses an epilogue. */
1.1.1.17 root 1478: if (current_function_returns_pcc_struct || use_goto)
1.1.1.16 root 1479: {
1.1.1.17 root 1480: if (end_label == 0)
1481: end_label = return_label = gen_label_rtx ();
1482: expand_goto_internal (0, end_label, last_insn);
1.1.1.16 root 1483: return;
1484: }
1485:
1.1.1.17 root 1486: /* Otherwise output a simple return-insn if one is available,
1487: unless it won't do the job. */
1.1.1.8 root 1488: #ifdef HAVE_return
1.1.1.17 root 1489: if (HAVE_return && cleanup_label == 0)
1.1.1.8 root 1490: {
1491: emit_jump_insn (gen_return ());
1492: emit_barrier ();
1.1.1.16 root 1493: return;
1.1.1.8 root 1494: }
1495: #endif
1.1.1.16 root 1496:
1497: /* Otherwise jump to the epilogue. */
1.1.1.17 root 1498: expand_goto_internal (0, end_label, last_insn);
1.1.1.2 root 1499: }
1.1 root 1500:
1.1.1.2 root 1501: /* Generate RTL to evaluate the expression RETVAL and return it
1502: from the current function. */
1.1 root 1503:
1.1.1.2 root 1504: void
1505: expand_return (retval)
1506: tree retval;
1507: {
1.1.1.17 root 1508: /* If there are any cleanups to be performed, then they will
1509: be inserted following LAST_INSN. It is desirable
1510: that the last_insn, for such purposes, should be the
1511: last insn before computing the return value. Otherwise, cleanups
1512: which call functions can clobber the return value. */
1513: /* ??? rms: I think that is erroneous, because in C++ it would
1514: run destructors on variables that might be used in the subsequent
1515: computation of the return value. */
1516: rtx last_insn = 0;
1.1.1.2 root 1517: register rtx val = 0;
1518: register rtx op0;
1.1.1.7 root 1519: tree retval_rhs;
1.1.1.15 root 1520: int cleanups;
1521: struct nesting *block;
1522:
1523: /* Are any cleanups needed? E.g. C++ destructors to be run? */
1524: cleanups = 0;
1525: for (block = block_stack; block; block = block->next)
1526: if (block->data.block.cleanups != 0)
1527: {
1528: cleanups = 1;
1529: break;
1530: }
1.1.1.7 root 1531:
1532: if (TREE_CODE (retval) == RESULT_DECL)
1533: retval_rhs = retval;
1534: else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
1535: && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
1536: retval_rhs = TREE_OPERAND (retval, 1);
1.1.1.14 root 1537: else if (TREE_TYPE (retval) == void_type_node)
1538: /* Recognize tail-recursive call to void function. */
1539: retval_rhs = retval;
1.1.1.7 root 1540: else
1541: retval_rhs = NULL_TREE;
1.1.1.2 root 1542:
1.1.1.17 root 1543: /* Only use `last_insn' if there are cleanups which must be run. */
1544: if (cleanups || cleanup_label != 0)
1545: last_insn = get_last_insn ();
1546:
1.1.1.2 root 1547: /* For tail-recursive call to current function,
1548: just jump back to the beginning.
1549: It's unsafe if any auto variable in this function
1550: has its address taken; for simplicity,
1551: require stack frame to be empty. */
1.1.1.7 root 1552: if (optimize && retval_rhs != 0
1.1.1.3 root 1553: && frame_offset == STARTING_FRAME_OFFSET
1.1.1.7 root 1554: && TREE_CODE (retval_rhs) == CALL_EXPR
1555: && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
1556: && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == this_function
1.1.1.2 root 1557: /* Finish checking validity, and if valid emit code
1558: to set the argument variables for the new call. */
1.1.1.8 root 1559: && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
1.1.1.2 root 1560: DECL_ARGUMENTS (this_function)))
1561: {
1562: if (tail_recursion_label == 0)
1563: {
1564: tail_recursion_label = gen_label_rtx ();
1565: emit_label_after (tail_recursion_label,
1566: tail_recursion_reentry);
1567: }
1.1.1.22! root 1568: emit_queue ();
1.1.1.17 root 1569: expand_goto_internal (0, tail_recursion_label, last_insn);
1.1.1.2 root 1570: emit_barrier ();
1571: return;
1572: }
1.1.1.8 root 1573: #ifdef HAVE_return
1.1.1.17 root 1574: /* This optimization is safe if there are local cleanups
1575: because expand_null_return takes care of them.
1576: ??? I think it should also be safe when there is a cleanup label,
1577: because expand_null_return takes care of them, too.
1578: Any reason why not? */
1579: if (HAVE_return && cleanup_label == 0
1.1.1.15 root 1580: && ! current_function_returns_pcc_struct)
1.1.1.8 root 1581: {
1582: /* If this is return x == y; then generate
1583: if (x == y) return 1; else return 0;
1584: if we can do it with explicit return insns. */
1585: if (retval_rhs)
1586: switch (TREE_CODE (retval_rhs))
1587: {
1588: case EQ_EXPR:
1589: case NE_EXPR:
1590: case GT_EXPR:
1591: case GE_EXPR:
1592: case LT_EXPR:
1593: case LE_EXPR:
1594: case TRUTH_ANDIF_EXPR:
1595: case TRUTH_ORIF_EXPR:
1.1.1.10 root 1596: case TRUTH_AND_EXPR:
1597: case TRUTH_OR_EXPR:
1.1.1.8 root 1598: case TRUTH_NOT_EXPR:
1599: op0 = gen_label_rtx ();
1600: val = DECL_RTL (DECL_RESULT (this_function));
1601: jumpifnot (retval_rhs, op0);
1602: emit_move_insn (val, const1_rtx);
1603: emit_insn (gen_rtx (USE, VOIDmode, val));
1604: expand_null_return ();
1605: emit_label (op0);
1606: emit_move_insn (val, const0_rtx);
1607: emit_insn (gen_rtx (USE, VOIDmode, val));
1608: expand_null_return ();
1609: return;
1610: }
1611: }
1612: #endif /* HAVE_return */
1.1.1.2 root 1613:
1.1.1.16 root 1614: if (cleanups
1615: && retval_rhs != 0
1616: && TREE_TYPE (retval_rhs) != void_type_node
1617: && GET_CODE (DECL_RTL (DECL_RESULT (this_function))) == REG)
1.1.1.15 root 1618: {
1619: rtx last_insn;
1620: /* Calculate the return value into a pseudo reg. */
1621: val = expand_expr (retval_rhs, 0, VOIDmode, 0);
1622: emit_queue ();
1623: /* Put the cleanups here. */
1624: last_insn = get_last_insn ();
1625: /* Copy the value into hard return reg. */
1626: emit_move_insn (DECL_RTL (DECL_RESULT (this_function)), val);
1627: val = DECL_RTL (DECL_RESULT (this_function));
1628:
1629: if (GET_CODE (val) == REG)
1630: emit_insn (gen_rtx (USE, VOIDmode, val));
1.1.1.17 root 1631: expand_null_return_1 (last_insn, cleanups);
1.1.1.15 root 1632: }
1633: else
1634: {
1635: /* No cleanups or no hard reg used;
1636: calculate value into hard return reg
1637: and let cleanups come after. */
1638: val = expand_expr (retval, 0, VOIDmode, 0);
1639: emit_queue ();
1.1.1.2 root 1640:
1.1.1.15 root 1641: val = DECL_RTL (DECL_RESULT (this_function));
1.1.1.17 root 1642: if (val && GET_CODE (val) == REG)
1.1.1.15 root 1643: emit_insn (gen_rtx (USE, VOIDmode, val));
1644: expand_null_return ();
1645: }
1.1.1.2 root 1646: }
1647:
1648: /* Return 1 if the end of the generated RTX is not a barrier.
1649: This means code already compiled can drop through. */
1650:
1651: int
1652: drop_through_at_end_p ()
1653: {
1654: rtx insn = get_last_insn ();
1655: while (insn && GET_CODE (insn) == NOTE)
1656: insn = PREV_INSN (insn);
1657: return insn && GET_CODE (insn) != BARRIER;
1.1 root 1658: }
1659:
1660: /* Emit code to alter this function's formal parms for a tail-recursive call.
1661: ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
1662: FORMALS is the chain of decls of formals.
1663: Return 1 if this can be done;
1664: otherwise return 0 and do not emit any code. */
1665:
1666: static int
1667: tail_recursion_args (actuals, formals)
1668: tree actuals, formals;
1669: {
1670: register tree a = actuals, f = formals;
1671: register int i;
1672: register rtx *argvec;
1673:
1674: /* Check that number and types of actuals are compatible
1675: with the formals. This is not always true in valid C code.
1676: Also check that no formal needs to be addressable
1677: and that all formals are scalars. */
1678:
1679: /* Also count the args. */
1680:
1681: for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
1682: {
1683: if (TREE_TYPE (TREE_VALUE (a)) != TREE_TYPE (f))
1684: return 0;
1685: if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
1686: return 0;
1687: }
1688: if (a != 0 || f != 0)
1689: return 0;
1690:
1691: /* Compute all the actuals. */
1692:
1693: argvec = (rtx *) alloca (i * sizeof (rtx));
1694:
1695: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1696: argvec[i] = expand_expr (TREE_VALUE (a), 0, VOIDmode, 0);
1697:
1698: /* Find which actual values refer to current values of previous formals.
1699: Copy each of them now, before any formal is changed. */
1700:
1701: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1702: {
1703: int copy = 0;
1704: register int j;
1705: for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
1706: if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
1707: { copy = 1; break; }
1708: if (copy)
1709: argvec[i] = copy_to_reg (argvec[i]);
1710: }
1711:
1712: /* Store the values of the actuals into the formals. */
1713:
1.1.1.2 root 1714: for (f = formals, a = actuals, i = 0; f;
1715: f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
1.1 root 1716: {
1717: if (DECL_MODE (f) == GET_MODE (argvec[i]))
1718: emit_move_insn (DECL_RTL (f), argvec[i]);
1719: else
1.1.1.2 root 1720: convert_move (DECL_RTL (f), argvec[i],
1721: TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
1.1 root 1722: }
1723:
1724: return 1;
1725: }
1726:
1.1.1.2 root 1727: /* Generate the RTL code for entering a binding contour.
1728: The variables are declared one by one, by calls to `expand_decl'.
1.1 root 1729:
1.1.1.2 root 1730: EXIT_FLAG is nonzero if this construct should be visible to
1731: `exit_something'. */
1732:
1733: void
1734: expand_start_bindings (exit_flag)
1735: int exit_flag;
1.1 root 1736: {
1.1.1.2 root 1737: struct nesting *thisblock
1738: = (struct nesting *) xmalloc (sizeof (struct nesting));
1739:
1740: rtx note = emit_note (0, NOTE_INSN_BLOCK_BEG);
1741:
1742: /* Make an entry on block_stack for the block we are entering. */
1743:
1744: thisblock->next = block_stack;
1745: thisblock->all = nesting_stack;
1746: thisblock->depth = ++nesting_depth;
1747: thisblock->data.block.stack_level = 0;
1.1.1.7 root 1748: thisblock->data.block.cleanups = 0;
1.1.1.13 root 1749: /* We build this even if the cleanups lists are empty
1750: because we rely on having an element in the chain
1751: for each block that is pending. */
1752: thisblock->data.block.outer_cleanups
1753: = (block_stack
1754: ? tree_cons (NULL_TREE, block_stack->data.block.cleanups,
1755: block_stack->data.block.outer_cleanups)
1756: : 0);
1.1.1.2 root 1757: thisblock->data.block.label_chain = 0;
1758: thisblock->data.block.innermost_stack_block = stack_block_stack;
1759: thisblock->data.block.first_insn = note;
1.1.1.19 root 1760: thisblock->data.block.block_start_count = ++block_start_count;
1.1.1.2 root 1761: thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
1.1.1.19 root 1762:
1.1.1.2 root 1763: block_stack = thisblock;
1764: nesting_stack = thisblock;
1765: }
1766:
1.1.1.3 root 1767: /* Output a USE for any register use in RTL.
1768: This is used with -noreg to mark the extent of lifespan
1769: of any registers used in a user-visible variable's DECL_RTL. */
1770:
1.1.1.13 root 1771: void
1.1.1.3 root 1772: use_variable (rtl)
1773: rtx rtl;
1774: {
1775: if (GET_CODE (rtl) == REG)
1776: /* This is a register variable. */
1777: emit_insn (gen_rtx (USE, VOIDmode, rtl));
1.1.1.21 root 1778: else if (GET_CODE (rtl) == SUBREG)
1779: use_variable (SUBREG_REG (rtl));
1.1.1.3 root 1780: else if (GET_CODE (rtl) == MEM
1781: && GET_CODE (XEXP (rtl, 0)) == REG
1782: && XEXP (rtl, 0) != frame_pointer_rtx
1783: && XEXP (rtl, 0) != arg_pointer_rtx)
1784: /* This is a variable-sized structure. */
1785: emit_insn (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)));
1786: }
1787:
1.1.1.13 root 1788: /* Like use_variable except that it outputs the USEs after INSN
1789: instead of at the end of the insn-chain. */
1790:
1791: static void
1792: use_variable_after (rtl, insn)
1793: rtx rtl, insn;
1794: {
1795: if (GET_CODE (rtl) == REG)
1796: /* This is a register variable. */
1797: emit_insn_after (gen_rtx (USE, VOIDmode, rtl), insn);
1.1.1.21 root 1798: else if (GET_CODE (rtl) == SUBREG)
1799: use_variable_after (SUBREG_REG (rtl), insn);
1.1.1.13 root 1800: else if (GET_CODE (rtl) == MEM
1801: && GET_CODE (XEXP (rtl, 0)) == REG
1802: && XEXP (rtl, 0) != frame_pointer_rtx
1803: && XEXP (rtl, 0) != arg_pointer_rtx)
1804: /* This is a variable-sized structure. */
1805: emit_insn_after (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)), insn);
1806: }
1807:
1.1.1.2 root 1808: /* Generate RTL code to terminate a binding contour.
1809: VARS is the chain of VAR_DECL nodes
1810: for the variables bound in this contour.
1.1.1.7 root 1811: MARK_ENDS is nonzero if we should put a note at the beginning
1812: and end of this binding contour.
1813:
1814: DONT_JUMP_IN is nonzero if it is not valid to jump into this contour.
1815: (That is true automatically if the contour has a saved stack level.) */
1.1.1.2 root 1816:
1817: void
1.1.1.7 root 1818: expand_end_bindings (vars, mark_ends, dont_jump_in)
1.1.1.2 root 1819: tree vars;
1820: int mark_ends;
1.1.1.7 root 1821: int dont_jump_in;
1.1.1.2 root 1822: {
1823: register struct nesting *thisblock = block_stack;
1824: register tree decl;
1825:
1.1.1.10 root 1826: if (warn_unused)
1827: for (decl = vars; decl; decl = TREE_CHAIN (decl))
1828: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
1829: warning_with_decl (decl, "unused variable `%s'");
1830:
1.1.1.2 root 1831: /* Mark the beginning and end of the scope if requested. */
1832:
1833: if (mark_ends)
1834: emit_note (0, NOTE_INSN_BLOCK_END);
1835: else
1836: /* Get rid of the beginning-mark if we don't make an end-mark. */
1837: NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
1838:
1839: if (thisblock->exit_label)
1840: {
1841: do_pending_stack_adjust ();
1842: emit_label (thisblock->exit_label);
1843: }
1844:
1.1.1.13 root 1845: if (dont_jump_in
1846: || thisblock->data.block.stack_level != 0
1847: || thisblock->data.block.cleanups != 0)
1.1.1.2 root 1848: {
1849: struct label_chain *chain;
1850:
1851: /* Any labels in this block are no longer valid to go to.
1852: Mark them to cause an error message. */
1853: for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
1854: {
1855: TREE_PACKED (chain->label) = 1;
1856: /* If any goto without a fixup came to this label,
1857: that must be an error, because gotos without fixups
1.1.1.13 root 1858: come from outside all saved stack-levels and all cleanups. */
1.1.1.2 root 1859: if (TREE_ADDRESSABLE (chain->label))
1.1.1.13 root 1860: error_with_decl (chain->label,
1861: "label `%s' used before containing binding contour");
1.1.1.2 root 1862: }
1.1.1.7 root 1863: }
1864:
1865: /* Restore stack level in effect before the block
1866: (only if variable-size objects allocated). */
1867:
1868: if (thisblock->data.block.stack_level != 0
1869: || thisblock->data.block.cleanups != 0)
1870: {
1871: /* Perform any cleanups associated with the block. */
1872:
1873: expand_cleanups (thisblock->data.block.cleanups, 0);
1874:
1875: /* Restore the stack level. */
1876:
1877: if (thisblock->data.block.stack_level != 0)
1878: {
1879: do_pending_stack_adjust ();
1880: emit_move_insn (stack_pointer_rtx,
1881: thisblock->data.block.stack_level);
1882: }
1.1.1.2 root 1883:
1.1.1.7 root 1884: /* Any gotos out of this block must also do these things.
1.1.1.2 root 1885: Also report any gotos with fixups that came to labels in this level. */
1.1.1.13 root 1886: fixup_gotos (thisblock,
1887: thisblock->data.block.stack_level,
1.1.1.7 root 1888: thisblock->data.block.cleanups,
1889: thisblock->data.block.first_insn,
1890: dont_jump_in);
1.1.1.2 root 1891: }
1892:
1893: /* If doing stupid register allocation, make sure lives of all
1894: register variables declared here extend thru end of scope. */
1895:
1896: if (obey_regdecls)
1897: for (decl = vars; decl; decl = TREE_CHAIN (decl))
1898: {
1.1.1.3 root 1899: rtx rtl = DECL_RTL (decl);
1900: if (TREE_CODE (decl) == VAR_DECL && rtl != 0)
1901: use_variable (rtl);
1.1.1.2 root 1902: }
1903:
1904: /* Restore block_stack level for containing block. */
1905:
1906: stack_block_stack = thisblock->data.block.innermost_stack_block;
1907: POPSTACK (block_stack);
1908: }
1909:
1910: /* Generate RTL for the automatic variable declaration DECL.
1.1.1.7 root 1911: (Other kinds of declarations are simply ignored if seen here.)
1912: CLEANUP is an expression to be executed at exit from this binding contour;
1913: for example, in C++, it might call the destructor for this variable.
1914:
1915: If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
1916: either before or after calling `expand_decl' but before compiling
1917: any subsequent expressions. This is because CLEANUP may be expanded
1918: more than once, on different branches of execution.
1919: For the same reason, CLEANUP may not contain a CALL_EXPR
1920: except as its topmost node--else `preexpand_calls' would get confused.
1921:
1.1.1.13 root 1922: If CLEANUP is nonzero and DECL is zero, we record a cleanup
1923: that is not associated with any particular variable.
1924:
1.1.1.7 root 1925: There is no special support here for C++ constructors.
1926: They should be handled by the proper code in DECL_INITIAL. */
1.1.1.2 root 1927:
1928: void
1.1.1.7 root 1929: expand_decl (decl, cleanup)
1.1.1.2 root 1930: register tree decl;
1.1.1.7 root 1931: tree cleanup;
1.1.1.2 root 1932: {
1933: struct nesting *thisblock = block_stack;
1.1.1.13 root 1934: tree type;
1935:
1936: /* Record the cleanup if there is one. */
1937:
1938: if (cleanup != 0)
1939: {
1940: thisblock->data.block.cleanups
1941: = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
1942: /* If this block has a cleanup, it belongs in stack_block_stack. */
1943: stack_block_stack = thisblock;
1944: }
1945:
1946: if (decl == NULL_TREE)
1947: {
1948: /* This was a cleanup with no variable. */
1949: if (cleanup == 0)
1950: abort ();
1951: return;
1952: }
1953:
1954: type = TREE_TYPE (decl);
1.1.1.2 root 1955:
1956: /* Aside from that, only automatic variables need any expansion done.
1.1.1.14 root 1957: Static and external variables, and external functions,
1958: will be handled by `assemble_variable' (called from finish_decl).
1959: TYPE_DECL and CONST_DECL require nothing.
1.1.1.2 root 1960: PARM_DECLs are handled in `assign_parms'. */
1961:
1962: if (TREE_CODE (decl) != VAR_DECL)
1963: return;
1964: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
1965: return;
1966:
1967: /* Create the RTL representation for the variable. */
1968:
1969: if (type == error_mark_node)
1970: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx);
1.1.1.14 root 1971: else if (DECL_SIZE (decl) == 0)
1972: /* Variable with incomplete type. */
1973: {
1974: if (DECL_INITIAL (decl) == 0)
1975: /* Error message was already done; now avoid a crash. */
1976: DECL_RTL (decl) = assign_stack_local (DECL_MODE (decl), 0);
1977: else
1978: /* An initializer is going to decide the size of this array.
1979: Until we know the size, represent its address with a reg. */
1980: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, gen_reg_rtx (Pmode));
1981: }
1.1.1.2 root 1982: else if (DECL_MODE (decl) != BLKmode
1983: /* If -ffloat-store, don't put explicit float vars
1984: into regs. */
1985: && !(flag_float_store
1986: && TREE_CODE (type) == REAL_TYPE)
1987: && ! TREE_VOLATILE (decl)
1988: && ! TREE_ADDRESSABLE (decl)
1989: && (TREE_REGDECL (decl) || ! obey_regdecls))
1990: {
1991: /* Automatic variable that can go in a register. */
1992: DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
1993: if (TREE_CODE (type) == POINTER_TYPE)
1994: mark_reg_pointer (DECL_RTL (decl));
1.1.1.10 root 1995: REG_USERVAR_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 1996: }
1997: else if (TREE_LITERAL (DECL_SIZE (decl)))
1998: {
1.1.1.14 root 1999: rtx oldaddr = 0;
2000: rtx addr;
2001:
2002: /* If we previously made RTL for this decl, it must be an array
2003: whose size was determined by the initializer.
2004: The old address was a register; set that register now
2005: to the proper address. */
2006: if (DECL_RTL (decl) != 0)
2007: {
2008: if (GET_CODE (DECL_RTL (decl)) != MEM
2009: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != REG)
2010: abort ();
2011: oldaddr = XEXP (DECL_RTL (decl), 0);
2012: }
2013:
1.1.1.2 root 2014: /* Variable of fixed size that goes on the stack. */
2015: DECL_RTL (decl)
2016: = assign_stack_local (DECL_MODE (decl),
2017: (TREE_INT_CST_LOW (DECL_SIZE (decl))
2018: * DECL_SIZE_UNIT (decl)
2019: + BITS_PER_UNIT - 1)
2020: / BITS_PER_UNIT);
1.1.1.14 root 2021: if (oldaddr)
2022: {
2023: addr = force_operand (XEXP (DECL_RTL (decl), 0), oldaddr);
2024: emit_move_insn (oldaddr, addr);
2025: }
2026:
1.1.1.2 root 2027: /* If this is a memory ref that contains aggregate components,
2028: mark it as such for cse and loop optimize. */
1.1.1.10 root 2029: MEM_IN_STRUCT_P (DECL_RTL (decl))
1.1.1.2 root 2030: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2031: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
2032: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
1.1.1.8 root 2033: #if 0
2034: /* If this is in memory because of -ffloat-store,
2035: set the volatile bit, to prevent optimizations from
2036: undoing the effects. */
2037: if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
1.1.1.10 root 2038: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.8 root 2039: #endif
1.1.1.2 root 2040: }
2041: else
2042: /* Dynamic-size object: must push space on the stack. */
2043: {
2044: rtx address, size;
2045:
2046: frame_pointer_needed = 1;
2047:
2048: /* Record the stack pointer on entry to block, if have
2049: not already done so. */
2050: if (thisblock->data.block.stack_level == 0)
2051: {
2052: do_pending_stack_adjust ();
2053: thisblock->data.block.stack_level
2054: = copy_to_reg (stack_pointer_rtx);
2055: stack_block_stack = thisblock;
2056: }
2057:
2058: /* Compute the variable's size, in bytes. */
2059: size = expand_expr (convert_units (DECL_SIZE (decl),
2060: DECL_SIZE_UNIT (decl),
2061: BITS_PER_UNIT),
2062: 0, VOIDmode, 0);
2063:
2064: /* Round it up to this machine's required stack boundary. */
2065: #ifdef STACK_BOUNDARY
2066: /* Avoid extra code if we can prove it's a multiple already. */
2067: if (DECL_SIZE_UNIT (decl) % STACK_BOUNDARY)
1.1.1.16 root 2068: {
2069: #ifdef STACK_POINTER_OFFSET
2070: /* Avoid extra code if we can prove that adding STACK_POINTER_OFFSET
2071: will not give this address invalid alignment. */
2072: if (DECL_ALIGN (decl) > ((STACK_POINTER_OFFSET * BITS_PER_UNIT) % STACK_BOUNDARY))
2073: size = plus_constant (size,
2074: STACK_POINTER_OFFSET % (STACK_BOUNDARY / BITS_PER_UNIT));
1.1.1.2 root 2075: #endif
1.1.1.16 root 2076: size = round_push (size);
2077: }
2078: #endif /* STACK_BOUNDARY */
1.1.1.2 root 2079:
2080: /* Make space on the stack, and get an rtx for the address of it. */
2081: #ifdef STACK_GROWS_DOWNWARD
2082: anti_adjust_stack (size);
2083: #endif
2084: address = copy_to_reg (stack_pointer_rtx);
1.1.1.4 root 2085: #ifdef STACK_POINTER_OFFSET
1.1.1.16 root 2086: {
2087: /* If the contents of the stack pointer reg are offset from the
2088: actual top-of-stack address, add the offset here. */
2089: rtx sp_offset = gen_rtx (CONST_INT, VOIDmode, STACK_POINTER_OFFSET);
2090: #ifdef STACK_BOUNDARY
2091: #ifdef STACK_GROWS_DOWNWARD
2092: int direction = 1;
2093: #else /* not STACK_GROWS_DOWNWARD */
2094: int direction = 0;
2095: #endif /* not STACK_GROWS_DOWNWARD */
2096: if (DECL_ALIGN (decl) > ((STACK_POINTER_OFFSET * BITS_PER_UNIT) % STACK_BOUNDARY))
2097: sp_offset = plus_constant (sp_offset,
2098: (STACK_POINTER_OFFSET
2099: % (STACK_BOUNDARY / BITS_PER_UNIT)
2100: * direction));
2101: #endif /* STACK_BOUNDARY */
2102: emit_insn (gen_add2_insn (address, sp_offset));
2103: }
2104: #endif /* STACK_POINTER_OFFSET */
1.1.1.2 root 2105: #ifndef STACK_GROWS_DOWNWARD
2106: anti_adjust_stack (size);
2107: #endif
2108:
1.1.1.17 root 2109: /* Some systems require a particular insn to refer to the stack
2110: to make the pages exist. */
2111: #ifdef HAVE_probe
2112: if (HAVE_probe)
2113: emit_insn (gen_probe ());
2114: #endif
2115:
1.1.1.2 root 2116: /* Reference the variable indirect through that rtx. */
2117: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
2118: }
2119:
2120: if (TREE_VOLATILE (decl))
1.1.1.10 root 2121: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 2122: if (TREE_READONLY (decl))
1.1.1.10 root 2123: RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 2124:
2125: /* If doing stupid register allocation, make sure life of any
2126: register variable starts here, at the start of its scope. */
2127:
1.1.1.14 root 2128: if (obey_regdecls)
1.1.1.3 root 2129: use_variable (DECL_RTL (decl));
1.1.1.14 root 2130: }
2131:
2132: /* Emit code to perform the initialization of a declaration DECL. */
2133:
2134: void
2135: expand_decl_init (decl)
2136: tree decl;
2137: {
2138: if (TREE_STATIC (decl))
2139: return;
1.1.1.2 root 2140:
2141: /* Compute and store the initial value now. */
2142:
1.1.1.3 root 2143: if (DECL_INITIAL (decl) == error_mark_node)
2144: {
2145: enum tree_code code = TREE_CODE (TREE_TYPE (decl));
2146: if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
2147: || code == POINTER_TYPE)
2148: expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
2149: 0, 0);
2150: emit_queue ();
2151: }
1.1.1.7 root 2152: else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
1.1.1.2 root 2153: {
1.1.1.12 root 2154: emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1.1.1.2 root 2155: expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
2156: emit_queue ();
2157: }
2158: }
1.1.1.13 root 2159:
2160: /* DECL is an anonymous union. CLEANUP is a cleanup for DECL.
2161: DECL_ELTS is the list of elements that belong to DECL's type.
2162: In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup. */
2163:
2164: void
2165: expand_anon_union_decl (decl, cleanup, decl_elts)
2166: tree decl, cleanup, decl_elts;
2167: {
2168: struct nesting *thisblock = block_stack;
2169: rtx x;
2170:
2171: expand_decl (decl, cleanup);
2172: x = DECL_RTL (decl);
2173:
2174: while (decl_elts)
2175: {
2176: tree decl_elt = TREE_VALUE (decl_elts);
2177: tree cleanup_elt = TREE_PURPOSE (decl_elts);
2178:
2179: DECL_RTL (decl_elt)
2180: = (GET_MODE (x) != BLKmode
2181: /*
2182: #error broken
2183: /* ??? This is incorrect if X is a MEM.
2184: (SUBREG (MEM)) is not allowed at rtl generation time. */
2185: ? gen_rtx (SUBREG, TYPE_MODE (TREE_TYPE (decl_elt)), x, 0)
2186: : x);
2187:
2188: /* Record the cleanup if there is one. */
2189:
2190: if (cleanup != 0)
2191: thisblock->data.block.cleanups
2192: = temp_tree_cons (decl_elt, cleanup_elt,
2193: thisblock->data.block.cleanups);
2194:
2195: decl_elts = TREE_CHAIN (decl_elts);
2196: }
2197: }
1.1.1.2 root 2198:
1.1.1.7 root 2199: /* Expand a list of cleanups LIST.
2200: Elements may be expressions or may be nested lists.
2201:
2202: If DONT_DO is nonnull, then any list-element
2203: whose TREE_PURPOSE matches DONT_DO is omitted.
2204: This is sometimes used to avoid a cleanup associated with
2205: a value that is being returned out of the scope. */
2206:
2207: static void
2208: expand_cleanups (list, dont_do)
2209: tree list;
2210: tree dont_do;
2211: {
2212: tree tail;
2213: for (tail = list; tail; tail = TREE_CHAIN (tail))
2214: if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
2215: {
2216: if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
1.1.1.8 root 2217: expand_cleanups (TREE_VALUE (tail), dont_do);
1.1.1.7 root 2218: else
2219: expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
2220: }
2221: }
2222:
2223: /* Expand a list of cleanups for a goto fixup.
2224: The expansion is put into the insn chain after the insn *BEFORE_JUMP
2225: and *BEFORE_JUMP is set to the insn that now comes before the jump. */
2226:
2227: static void
2228: fixup_cleanups (list, before_jump)
2229: tree list;
2230: rtx *before_jump;
2231: {
2232: rtx beyond_jump = get_last_insn ();
2233: rtx new_before_jump;
2234:
2235: expand_cleanups (list, 0);
2236: new_before_jump = get_last_insn ();
2237:
2238: reorder_insns (NEXT_INSN (beyond_jump), new_before_jump, *before_jump);
2239: *before_jump = new_before_jump;
2240: }
1.1.1.8 root 2241:
2242: /* Move all cleanups from the current block_stack
2243: to the containing block_stack, where they are assumed to
2244: have been created. If anything can cause a temporary to
2245: be created, but not expanded for more than one level of
2246: block_stacks, then this code will have to change. */
2247:
2248: void
2249: move_cleanups_up ()
2250: {
2251: struct nesting *block = block_stack;
2252: struct nesting *outer = block->next;
2253:
2254: outer->data.block.cleanups
1.1.1.13 root 2255: = chainon (block->data.block.cleanups,
2256: outer->data.block.cleanups);
1.1.1.8 root 2257: block->data.block.cleanups = 0;
2258: }
1.1.1.17 root 2259:
2260: int
2261: this_contour_has_cleanups_p ()
2262: {
2263: return block_stack && block_stack->data.block.cleanups != 0;
2264: }
1.1.1.7 root 2265:
1.1.1.2 root 2266: /* Enter a case (Pascal) or switch (C) statement.
2267: Push a block onto case_stack and nesting_stack
2268: to accumulate the case-labels that are seen
2269: and to record the labels generated for the statement.
2270:
2271: EXIT_FLAG is nonzero if `exit_something' should exit this case stmt.
2272: Otherwise, this construct is transparent for `exit_something'.
2273:
2274: EXPR is the index-expression to be dispatched on.
2275: TYPE is its nominal type. We could simply convert EXPR to this type,
2276: but instead we take short cuts. */
2277:
2278: void
2279: expand_start_case (exit_flag, expr, type)
2280: int exit_flag;
2281: tree expr;
2282: tree type;
2283: {
2284: register struct nesting *thiscase
2285: = (struct nesting *) xmalloc (sizeof (struct nesting));
2286:
2287: /* Make an entry on case_stack for the case we are entering. */
2288:
2289: thiscase->next = case_stack;
2290: thiscase->all = nesting_stack;
2291: thiscase->depth = ++nesting_depth;
2292: thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
2293: thiscase->data.case_stmt.case_list = 0;
2294: thiscase->data.case_stmt.index_expr = expr;
2295: thiscase->data.case_stmt.nominal_type = type;
1.1.1.13 root 2296: thiscase->data.case_stmt.default_label = 0;
2297: thiscase->data.case_stmt.num_ranges = 0;
1.1.1.2 root 2298: case_stack = thiscase;
2299: nesting_stack = thiscase;
2300:
2301: do_pending_stack_adjust ();
2302:
1.1.1.6 root 2303: /* Make sure case_stmt.start points to something that won't
2304: need any transformation before expand_end_case. */
1.1.1.17 root 2305: emit_note (0, NOTE_INSN_DELETED);
1.1.1.6 root 2306:
1.1.1.2 root 2307: thiscase->data.case_stmt.start = get_last_insn ();
2308: }
2309:
2310: /* Start a "dummy case statement" within which case labels are invalid
2311: and are not connected to any larger real case statement.
2312: This can be used if you don't want to let a case statement jump
2313: into the middle of certain kinds of constructs. */
2314:
2315: void
2316: expand_start_case_dummy ()
2317: {
2318: register struct nesting *thiscase
2319: = (struct nesting *) xmalloc (sizeof (struct nesting));
2320:
2321: /* Make an entry on case_stack for the dummy. */
2322:
2323: thiscase->next = case_stack;
2324: thiscase->all = nesting_stack;
2325: thiscase->depth = ++nesting_depth;
2326: thiscase->exit_label = 0;
2327: thiscase->data.case_stmt.case_list = 0;
2328: thiscase->data.case_stmt.start = 0;
2329: thiscase->data.case_stmt.nominal_type = 0;
1.1.1.13 root 2330: thiscase->data.case_stmt.default_label = 0;
2331: thiscase->data.case_stmt.num_ranges = 0;
1.1.1.2 root 2332: case_stack = thiscase;
2333: nesting_stack = thiscase;
2334: }
2335:
2336: /* End a dummy case statement. */
2337:
2338: void
2339: expand_end_case_dummy ()
2340: {
2341: POPSTACK (case_stack);
2342: }
1.1.1.7 root 2343:
1.1.1.2 root 2344: /* Accumulate one case or default label inside a case or switch statement.
2345: VALUE is the value of the case (a null pointer, for a default label).
2346:
2347: If not currently inside a case or switch statement, return 1 and do
2348: nothing. The caller will print a language-specific error message.
1.1.1.7 root 2349: If VALUE is a duplicate or overlaps, return 2 and do nothing.
1.1.1.2 root 2350: If VALUE is out of range, return 3 and do nothing.
1.1.1.13 root 2351: Return 0 on success.
2352:
2353: Extended to handle range statements, should they ever
2354: be adopted. */
1.1.1.2 root 2355:
2356: int
2357: pushcase (value, label)
2358: register tree value;
2359: register tree label;
2360: {
1.1.1.13 root 2361: register struct case_node **l;
2362: register struct case_node *n;
1.1.1.2 root 2363: tree index_type;
2364: tree nominal_type;
2365:
2366: /* Fail if not inside a real case statement. */
2367: if (! (case_stack && case_stack->data.case_stmt.start))
2368: return 1;
2369:
2370: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
2371: nominal_type = case_stack->data.case_stmt.nominal_type;
2372:
2373: /* If the index is erroneous, avoid more problems: pretend to succeed. */
2374: if (index_type == error_mark_node)
2375: return 0;
2376:
2377: /* Convert VALUE to the type in which the comparisons are nominally done. */
2378: if (value != 0)
2379: value = convert (nominal_type, value);
2380:
1.1.1.7 root 2381: /* Fail if this value is out of range for the actual type of the index
2382: (which may be narrower than NOMINAL_TYPE). */
2383: if (value != 0 && ! int_fits_type_p (value, index_type))
2384: return 3;
2385:
2386: /* Fail if this is a duplicate or overlaps another entry. */
2387: if (value == 0)
1.1.1.2 root 2388: {
1.1.1.13 root 2389: if (case_stack->data.case_stmt.default_label != 0)
1.1.1.2 root 2390: return 2;
1.1.1.13 root 2391: case_stack->data.case_stmt.default_label = label;
1.1.1.2 root 2392: }
1.1.1.7 root 2393: else
2394: {
1.1.1.13 root 2395: /* Find the elt in the chain before which to insert the new value,
2396: to keep the chain sorted in increasing order.
2397: But report an error if this element is a duplicate. */
2398: for (l = &case_stack->data.case_stmt.case_list;
2399: /* Keep going past elements distinctly less than VALUE. */
1.1.1.14 root 2400: *l != 0 && tree_int_cst_lt ((*l)->high, value);
1.1.1.13 root 2401: l = &(*l)->right)
2402: ;
2403: if (*l)
1.1.1.7 root 2404: {
1.1.1.13 root 2405: /* Element we will insert before must be distinctly greater;
2406: overlap means error. */
2407: if (! tree_int_cst_lt (value, (*l)->low))
2408: return 2;
1.1.1.7 root 2409: }
1.1.1.13 root 2410:
2411: /* Add this label to the chain, and succeed.
2412: Copy VALUE so it is on temporary rather than momentary
2413: obstack and will thus survive till the end of the case statement. */
2414: n = (struct case_node *) oballoc (sizeof (struct case_node));
2415: n->left = 0;
2416: n->right = *l;
2417: n->high = n->low = copy_node (value);
2418: n->code_label = label;
2419: n->test_label = 0;
2420: *l = n;
1.1.1.7 root 2421: }
2422:
2423: expand_label (label);
2424: return 0;
2425: }
2426:
2427: /* Like pushcase but this case applies to all values
2428: between VALUE1 and VALUE2 (inclusive).
2429: The return value is the same as that of pushcase
2430: but there is one additional error code:
2431: 4 means the specified range was empty.
2432:
2433: Note that this does not currently work, since expand_end_case
2434: has yet to be extended to handle RANGE_EXPRs. */
2435:
2436: int
2437: pushcase_range (value1, value2, label)
2438: register tree value1, value2;
2439: register tree label;
2440: {
1.1.1.13 root 2441: register struct case_node **l;
2442: register struct case_node *n;
1.1.1.7 root 2443: tree index_type;
2444: tree nominal_type;
2445:
2446: /* Fail if not inside a real case statement. */
2447: if (! (case_stack && case_stack->data.case_stmt.start))
2448: return 1;
2449:
2450: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
2451: nominal_type = case_stack->data.case_stmt.nominal_type;
2452:
2453: /* If the index is erroneous, avoid more problems: pretend to succeed. */
2454: if (index_type == error_mark_node)
2455: return 0;
2456:
2457: /* Convert VALUEs to type in which the comparisons are nominally done. */
2458: if (value1 != 0)
2459: value1 = convert (nominal_type, value1);
2460: if (value2 != 0)
2461: value2 = convert (nominal_type, value2);
2462:
2463: /* Fail if these values are out of range. */
2464: if (value1 != 0 && ! int_fits_type_p (value1, index_type))
2465: return 3;
2466:
2467: if (value2 != 0 && ! int_fits_type_p (value2, index_type))
1.1.1.2 root 2468: return 3;
2469:
1.1.1.7 root 2470: /* Fail if the range is empty. */
2471: if (tree_int_cst_lt (value2, value1))
2472: return 4;
2473:
1.1.1.8 root 2474: /* If the bounds are equal, turn this into the one-value case. */
2475: if (tree_int_cst_equal (value1, value2))
2476: return pushcase (value1, label);
2477:
1.1.1.13 root 2478: /* Find the elt in the chain before which to insert the new value,
2479: to keep the chain sorted in increasing order.
2480: But report an error if this element is a duplicate. */
2481: for (l = &case_stack->data.case_stmt.case_list;
2482: /* Keep going past elements distinctly less than this range. */
1.1.1.14 root 2483: *l != 0 && tree_int_cst_lt ((*l)->high, value1);
1.1.1.13 root 2484: l = &(*l)->right)
2485: ;
2486: if (*l)
2487: {
2488: /* Element we will insert before must be distinctly greater;
2489: overlap means error. */
2490: if (! tree_int_cst_lt (value2, (*l)->low))
2491: return 2;
1.1.1.7 root 2492: }
2493:
1.1.1.13 root 2494: /* Add this label to the chain, and succeed.
2495: Copy VALUE1, VALUE2 so they are on temporary rather than momentary
2496: obstack and will thus survive till the end of the case statement. */
2497:
2498: n = (struct case_node *) oballoc (sizeof (struct case_node));
2499: n->left = 0;
2500: n->right = *l;
2501: n->low = copy_node (value1);
2502: n->high = copy_node (value2);
2503: n->code_label = label;
2504: n->test_label = 0;
2505: *l = n;
2506:
1.1.1.2 root 2507: expand_label (label);
1.1.1.7 root 2508:
1.1.1.13 root 2509: case_stack->data.case_stmt.num_ranges++;
2510:
1.1.1.2 root 2511: return 0;
2512: }
2513:
1.1.1.16 root 2514: /* Check that all enumeration literals are covered by the case
2515: expressions of a switch. Also, warn if there are any extra
2516: switch cases that are *not* elements of the enumerated type. */
2517:
1.1.1.18 root 2518: static void
2519: check_for_full_enumeration_handling (type)
2520: tree type;
1.1.1.16 root 2521: {
1.1.1.18 root 2522: register struct case_node *n;
2523: register tree chain;
1.1.1.16 root 2524:
1.1.1.18 root 2525: /* The time complexity of this loop is currently O(N * M), with
2526: N being the number of enumerals in the enumerated type, and
2527: M being the number of case expressions in the switch. */
1.1.1.16 root 2528:
1.1.1.18 root 2529: for (chain = TYPE_VALUES (type);
2530: chain;
2531: chain = TREE_CHAIN (chain))
2532: {
2533: /* Find a match between enumeral and case expression, if possible.
2534: Quit looking when we've gone too far (since case expressions
2535: are kept sorted in ascending order). Warn about enumerals not
2536: handled in the switch statement case expression list. */
2537:
2538: for (n = case_stack->data.case_stmt.case_list;
2539: n && tree_int_cst_lt (n->high, TREE_VALUE (chain));
2540: n = n->right)
2541: ;
2542:
2543: if (!(n && tree_int_cst_equal (n->low, TREE_VALUE (chain))))
2544: warning ("enumerated value `%s' not handled in switch",
2545: IDENTIFIER_POINTER (TREE_PURPOSE (chain)));
2546: }
2547:
2548: /* Now we go the other way around; we warn if there are case
2549: expressions that don't correspond to enumerals. This can
2550: occur since C and C++ don't enforce type-checking of
2551: assignments to enumeration variables. */
2552:
2553: for (n = case_stack->data.case_stmt.case_list; n; n = n->right)
2554: {
2555: for (chain = TYPE_VALUES (type);
2556: chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain));
2557: chain = TREE_CHAIN (chain))
2558: ;
2559:
2560: if (!chain)
2561: warning ("case value `%d' not in enumerated type `%s'",
2562: TREE_INT_CST_LOW (n->low),
2563: IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
2564: ? TYPE_NAME (type)
2565: : DECL_NAME (TYPE_NAME (type))));
1.1.1.16 root 2566: }
2567: }
2568:
1.1.1.2 root 2569: /* Terminate a case (Pascal) or switch (C) statement
2570: in which CASE_INDEX is the expression to be tested.
2571: Generate the code to test it and jump to the right place. */
2572:
2573: void
1.1.1.16 root 2574: expand_end_case (orig_index)
2575: tree orig_index;
1.1.1.2 root 2576: {
2577: tree minval, maxval, range;
2578: rtx default_label = 0;
1.1.1.13 root 2579: register struct case_node *n;
1.1.1.2 root 2580: int count;
2581: rtx index;
2582: rtx table_label = gen_label_rtx ();
2583: int ncases;
2584: rtx *labelvec;
2585: register int i;
2586: rtx before_case;
2587: register struct nesting *thiscase = case_stack;
2588: tree index_expr = thiscase->data.case_stmt.index_expr;
1.1.1.17 root 2589: int unsignedp = TREE_UNSIGNED (TREE_TYPE (index_expr));
1.1.1.2 root 2590:
2591: do_pending_stack_adjust ();
2592:
1.1.1.6 root 2593: /* An ERROR_MARK occurs for various reasons including invalid data type. */
2594: if (TREE_TYPE (index_expr) != error_mark_node)
1.1.1.2 root 2595: {
1.1.1.16 root 2596: /* If switch expression was an enumerated type, check that all
2597: enumeration literals are covered by the cases.
2598: No sense trying this if there's a default case, however. */
2599:
2600: if (!thiscase->data.case_stmt.default_label
2601: && TREE_CODE (TREE_TYPE (orig_index)) == ENUMERAL_TYPE
1.1.1.18 root 2602: && TREE_CODE (index_expr) != INTEGER_CST
1.1.1.16 root 2603: && warn_switch)
1.1.1.18 root 2604: check_for_full_enumeration_handling (TREE_TYPE (orig_index));
1.1.1.16 root 2605:
1.1.1.2 root 2606: /* If we don't have a default-label, create one here,
2607: after the body of the switch. */
1.1.1.13 root 2608: if (thiscase->data.case_stmt.default_label == 0)
2609: {
2610: thiscase->data.case_stmt.default_label
2611: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2612: expand_label (thiscase->data.case_stmt.default_label);
2613: }
2614: default_label = label_rtx (thiscase->data.case_stmt.default_label);
1.1.1.2 root 2615:
2616: before_case = get_last_insn ();
2617:
1.1.1.13 root 2618: /* Simplify the case-list before we count it. */
2619: group_case_nodes (thiscase->data.case_stmt.case_list);
2620:
1.1.1.2 root 2621: /* Get upper and lower bounds of case values.
2622: Also convert all the case values to the index expr's data type. */
2623:
1.1.1.13 root 2624: count = 0;
2625: for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
2626: {
2627: /* Check low and high label values are integers. */
2628: if (TREE_CODE (n->low) != INTEGER_CST)
2629: abort ();
2630: if (TREE_CODE (n->high) != INTEGER_CST)
2631: abort ();
2632:
2633: n->low = convert (TREE_TYPE (index_expr), n->low);
2634: n->high = convert (TREE_TYPE (index_expr), n->high);
2635:
2636: /* Count the elements and track the largest and smallest
2637: of them (treating them as signed even if they are not). */
2638: if (count++ == 0)
2639: {
2640: minval = n->low;
2641: maxval = n->high;
2642: }
2643: else
2644: {
2645: if (INT_CST_LT (n->low, minval))
2646: minval = n->low;
2647: if (INT_CST_LT (maxval, n->high))
2648: maxval = n->high;
2649: }
2650: /* A range counts double, since it requires two compares. */
2651: if (! tree_int_cst_equal (n->low, n->high))
2652: count++;
2653: }
1.1.1.2 root 2654:
2655: /* Compute span of values. */
2656: if (count != 0)
2657: range = combine (MINUS_EXPR, maxval, minval);
2658:
2659: if (count == 0 || TREE_CODE (TREE_TYPE (index_expr)) == ERROR_MARK)
2660: {
2661: expand_expr (index_expr, const0_rtx, VOIDmode, 0);
2662: emit_queue ();
2663: emit_jump (default_label);
2664: }
2665: /* If range of values is much bigger than number of values,
2666: make a sequence of conditional branches instead of a dispatch.
2667: If the switch-index is a constant, do it this way
2668: because we can optimize it. */
2669: else if (TREE_INT_CST_HIGH (range) != 0
1.1 root 2670: #ifdef HAVE_casesi
1.1.1.2 root 2671: || count < 4
1.1 root 2672: #else
1.1.1.2 root 2673: /* If machine does not have a case insn that compares the
2674: bounds, this means extra overhead for dispatch tables
2675: which raises the threshold for using them. */
2676: || count < 5
1.1 root 2677: #endif
1.1.1.2 root 2678: || (unsigned) (TREE_INT_CST_LOW (range)) > 10 * count
2679: || TREE_CODE (index_expr) == INTEGER_CST)
2680: {
2681: index = expand_expr (index_expr, 0, VOIDmode, 0);
1.1.1.17 root 2682:
2683: /* If the index is a short or char that we do not have
2684: an insn to handle comparisons directly, convert it to
2685: a full integer now, rather than letting each comparison
2686: generate the conversion. */
2687:
2688: if ((GET_MODE (index) == QImode || GET_MODE (index) == HImode)
2689: && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code
2690: == CODE_FOR_nothing))
2691: index = convert_to_mode (SImode, index, unsignedp);
2692:
1.1.1.2 root 2693: emit_queue ();
1.1.1.14 root 2694: do_pending_stack_adjust ();
1.1 root 2695:
1.1.1.2 root 2696: index = protect_from_queue (index, 0);
2697: if (GET_CODE (index) == MEM)
2698: index = copy_to_reg (index);
1.1.1.14 root 2699: if (GET_CODE (index) == CONST_INT
2700: || TREE_CODE (index_expr) == INTEGER_CST)
1.1.1.2 root 2701: {
1.1.1.14 root 2702: /* Make a tree node with the proper constant value
2703: if we don't already have one. */
2704: if (TREE_CODE (index_expr) != INTEGER_CST)
2705: {
1.1.1.17 root 2706: index_expr
2707: = build_int_2 (INTVAL (index),
2708: !unsignedp && INTVAL (index) >= 0 ? 0 : -1);
1.1.1.14 root 2709: index_expr = convert (TREE_TYPE (index_expr), index_expr);
2710: }
2711:
1.1.1.13 root 2712: /* For constant index expressions we need only
2713: issue a unconditional branch to the appropriate
2714: target code. The job of removing any unreachable
2715: code is left to the optimisation phase if the
2716: "-O" option is specified. */
2717: for (n = thiscase->data.case_stmt.case_list;
2718: n;
2719: n = n->right)
2720: {
2721: if (! tree_int_cst_lt (index_expr, n->low)
2722: && ! tree_int_cst_lt (n->high, index_expr))
2723: break;
2724: }
2725: if (n)
2726: emit_jump (label_rtx (n->code_label));
1.1.1.14 root 2727: else
2728: emit_jump (default_label);
1.1.1.13 root 2729: }
2730: else
2731: {
2732: /* If the index expression is not constant we generate
2733: a binary decision tree to select the appropriate
2734: target code. This is done as follows:
2735:
2736: The list of cases is rearranged into a binary tree,
2737: nearly optimal assuming equal probability for each case.
2738:
2739: The tree is transformed into RTL, eliminating
2740: redundant test conditions at the same time.
2741:
2742: If program flow could reach the end of the
2743: decision tree an unconditional jump to the
2744: default code is emitted. */
2745: balance_case_nodes (&thiscase->data.case_stmt.case_list, 0);
2746: emit_case_nodes (index, thiscase->data.case_stmt.case_list,
1.1.1.17 root 2747: default_label, unsignedp);
1.1.1.13 root 2748: emit_jump_if_reachable (default_label);
1.1.1.2 root 2749: }
2750: }
2751: else
2752: {
1.1 root 2753: #ifdef HAVE_casesi
1.1.1.3 root 2754: /* Convert the index to SImode. */
1.1.1.2 root 2755: if (TYPE_MODE (TREE_TYPE (index_expr)) == DImode)
2756: {
1.1.1.3 root 2757: index_expr = build (MINUS_EXPR, TREE_TYPE (index_expr),
2758: index_expr, minval);
1.1.1.2 root 2759: minval = integer_zero_node;
2760: }
1.1.1.3 root 2761: if (TYPE_MODE (TREE_TYPE (index_expr)) != SImode)
2762: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
2763: index_expr);
1.1.1.2 root 2764: index = expand_expr (index_expr, 0, VOIDmode, 0);
2765: emit_queue ();
2766: index = protect_from_queue (index, 0);
2767: do_pending_stack_adjust ();
2768:
2769: emit_jump_insn (gen_casesi (index, expand_expr (minval, 0, VOIDmode, 0),
2770: expand_expr (range, 0, VOIDmode, 0),
2771: table_label, default_label));
1.1 root 2772: #else
2773: #ifdef HAVE_tablejump
1.1.1.3 root 2774: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
1.1.1.2 root 2775: build (MINUS_EXPR, TREE_TYPE (index_expr),
2776: index_expr, minval));
2777: index = expand_expr (index_expr, 0, VOIDmode, 0);
2778: emit_queue ();
2779: index = protect_from_queue (index, 0);
2780: do_pending_stack_adjust ();
2781:
2782: do_tablejump (index,
2783: gen_rtx (CONST_INT, VOIDmode, TREE_INT_CST_LOW (range)),
2784: table_label, default_label);
1.1 root 2785: #else
1.1.1.2 root 2786: lossage;
2787: #endif /* not HAVE_tablejump */
2788: #endif /* not HAVE_casesi */
2789:
2790: /* Get table of labels to jump to, in order of case index. */
2791:
2792: ncases = TREE_INT_CST_LOW (range) + 1;
2793: labelvec = (rtx *) alloca (ncases * sizeof (rtx));
2794: bzero (labelvec, ncases * sizeof (rtx));
1.1 root 2795:
1.1.1.13 root 2796: for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
2797: {
2798: register int i
2799: = TREE_INT_CST_LOW (n->low) - TREE_INT_CST_LOW (minval);
2800:
1.1.1.22! root 2801: while (1)
! 2802: {
! 2803: labelvec[i]
! 2804: = gen_rtx (LABEL_REF, Pmode, label_rtx (n->code_label));
! 2805: if (i + TREE_INT_CST_LOW (minval)
! 2806: == TREE_INT_CST_LOW (n->high))
! 2807: break;
! 2808: i++;
! 2809: }
1.1.1.13 root 2810: }
1.1.1.2 root 2811:
2812: /* Fill in the gaps with the default. */
2813: for (i = 0; i < ncases; i++)
2814: if (labelvec[i] == 0)
2815: labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label);
2816:
2817: /* Output the table */
2818: emit_label (table_label);
1.1 root 2819:
2820: #ifdef CASE_VECTOR_PC_RELATIVE
1.1.1.2 root 2821: emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE,
2822: gen_rtx (LABEL_REF, Pmode, table_label),
2823: gen_rtvec_v (ncases, labelvec)));
1.1 root 2824: #else
1.1.1.2 root 2825: emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE,
2826: gen_rtvec_v (ncases, labelvec)));
1.1 root 2827: #endif
1.1.1.2 root 2828: /* If the case insn drops through the table,
2829: after the table we must jump to the default-label.
2830: Otherwise record no drop-through after the table. */
2831: #ifdef CASE_DROPS_THROUGH
2832: emit_jump (default_label);
2833: #else
2834: emit_barrier ();
2835: #endif
2836: }
2837:
2838: reorder_insns (NEXT_INSN (before_case), get_last_insn (),
2839: thiscase->data.case_stmt.start);
2840: }
2841: if (thiscase->exit_label)
2842: emit_label (thiscase->exit_label);
2843:
2844: POPSTACK (case_stack);
2845: }
2846:
2847: /* Generate code to jump to LABEL if OP1 and OP2 are equal. */
2848:
1.1.1.14 root 2849: static void
2850: do_jump_if_equal (op1, op2, label, unsignedp)
1.1.1.2 root 2851: rtx op1, op2, label;
1.1.1.14 root 2852: int unsignedp;
1.1.1.2 root 2853: {
2854: if (GET_CODE (op1) == CONST_INT
2855: && GET_CODE (op2) == CONST_INT)
2856: {
2857: if (INTVAL (op1) == INTVAL (op2))
2858: emit_jump (label);
2859: }
2860: else
2861: {
1.1.1.14 root 2862: emit_cmp_insn (op1, op2, 0, unsignedp, 0);
1.1.1.2 root 2863: emit_jump_insn (gen_beq (label));
2864: }
1.1 root 2865: }
2866:
1.1.1.13 root 2867: /* Scan an ordered list of case nodes
2868: combining those with consecutive values or ranges.
2869:
2870: Eg. three separate entries 1: 2: 3: become one entry 1..3: */
2871:
2872: static void
2873: group_case_nodes (head)
2874: case_node_ptr head;
2875: {
2876: case_node_ptr node = head;
2877:
2878: while (node)
2879: {
2880: rtx lb = next_real_insn (label_rtx (node->code_label));
2881: case_node_ptr np = node;
2882:
2883: /* Try to group the successors of NODE with NODE. */
2884: while (((np = np->right) != 0)
2885: /* Do they jump to the same place? */
2886: && next_real_insn (label_rtx (np->code_label)) == lb
2887: /* Are their ranges consecutive? */
2888: && tree_int_cst_equal (np->low,
2889: combine (PLUS_EXPR, node->high,
1.1.1.19 root 2890: build_int_2 (1, 0)))
2891: /* An overflow is not consecutive. */
2892: && tree_int_cst_lt (node->high,
2893: combine (PLUS_EXPR, node->high,
2894: build_int_2 (1, 0))))
1.1.1.13 root 2895: {
2896: node->high = np->high;
2897: }
2898: /* NP is the first node after NODE which can't be grouped with it.
2899: Delete the nodes in between, and move on to that node. */
2900: node->right = np;
2901: node = np;
2902: }
2903: }
2904:
2905: /* Take an ordered list of case nodes
2906: and transform them into a near optimal binary tree,
2907: on the assumtion that any target code selection value is as
2908: likely as any other.
2909:
2910: The transformation is performed by splitting the ordered
2911: list into two equal sections plus a pivot. The parts are
2912: then attached to the pivot as left and right branches. Each
2913: branch is is then transformed recursively. */
2914:
2915: static void
2916: balance_case_nodes (head, parent)
2917: case_node_ptr *head;
2918: case_node_ptr parent;
2919: {
2920: register case_node_ptr np;
2921:
2922: np = *head;
2923: if (np)
2924: {
2925: int i = 0;
2926: int ranges = 0;
2927: register case_node_ptr *npp;
2928: case_node_ptr left;
2929:
2930: /* Count the number of entries on branch.
2931: Also count the ranges. */
2932: while (np)
2933: {
2934: if (!tree_int_cst_equal (np->low, np->high))
2935: ranges++;
2936: i++;
2937: np = np->right;
2938: }
2939: if (i > 2)
2940: {
2941: /* Split this list if it is long enough for that to help. */
2942: npp = head;
2943: left = *npp;
2944: /* If there are just three nodes, split at the middle one. */
2945: if (i == 3)
2946: npp = &(*npp)->right;
2947: else
2948: {
2949: /* Find the place in the list that bisects the list's total cost,
2950: where ranges count as 2.
2951: Here I gets half the total cost. */
2952: i = (i + ranges + 1) / 2;
2953: while (1)
2954: {
2955: /* Skip nodes while their cost does not reach that amount. */
2956: if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
2957: i--;
2958: i--;
2959: if (i <= 0)
2960: break;
2961: npp = &(*npp)->right;
2962: }
2963: }
2964: *head = np = *npp;
2965: *npp = 0;
2966: np->parent = parent;
2967: np->left = left;
2968:
2969: /* Optimize each of the two split parts. */
2970: balance_case_nodes (&np->left, np);
2971: balance_case_nodes (&np->right, np);
2972: }
2973: else
2974: {
2975: /* Else leave this branch as one level,
2976: but fill in `parent' fields. */
2977: np = *head;
2978: np->parent = parent;
2979: for (; np->right; np = np->right)
2980: np->right->parent = np;
2981: }
2982: }
2983: }
2984:
2985: /* Search the parent sections of the case node tree
2986: to see if a test for the lower bound of NODE would be redundant.
2987:
2988: The instructions to synthesis the case decision tree are
2989: output in the same order as nodes are processed so it is
2990: known that if a parent node checks the range of the current
2991: node minus one that the current node is bounded at its lower
2992: span. Thus the test would be redundant. */
2993:
2994: static int
2995: node_has_low_bound (node)
2996: case_node_ptr node;
2997: {
2998: tree low_minus_one;
2999: case_node_ptr pnode;
3000:
3001: if (node->left)
3002: {
3003: low_minus_one = combine (MINUS_EXPR, node->low, build_int_2 (1, 0));
1.1.1.14 root 3004: /* Avoid the screw case of overflow where low_minus_one is > low. */
3005: if (tree_int_cst_lt (low_minus_one, node->low))
3006: for (pnode = node->parent; pnode; pnode = pnode->parent)
3007: {
3008: if (tree_int_cst_equal (low_minus_one, pnode->high))
3009: return 1;
3010: /* If a parent node has a left branch we know that none
3011: of its parents can have a high bound of our target
3012: minus one so we abort the search. */
3013: if (node->left)
3014: break;
3015: }
1.1.1.13 root 3016: }
3017: return 0;
3018: }
3019:
3020: /* Search the parent sections of the case node tree
3021: to see if a test for the upper bound of NODE would be redundant.
3022:
3023: The instructions to synthesis the case decision tree are
3024: output in the same order as nodes are processed so it is
3025: known that if a parent node checks the range of the current
3026: node plus one that the current node is bounded at its upper
3027: span. Thus the test would be redundant. */
3028:
3029: static int
3030: node_has_high_bound (node)
3031: case_node_ptr node;
3032: {
3033: tree high_plus_one;
3034: case_node_ptr pnode;
3035:
3036: if (node->right == 0)
3037: {
3038: high_plus_one = combine (PLUS_EXPR, node->high, build_int_2 (1, 0));
1.1.1.14 root 3039: /* Avoid the screw case of overflow where high_plus_one is > high. */
3040: if (tree_int_cst_lt (node->high, high_plus_one))
3041: for (pnode = node->parent; pnode; pnode = pnode->parent)
3042: {
3043: if (tree_int_cst_equal (high_plus_one, pnode->low))
3044: return 1;
3045: /* If a parent node has a right branch we know that none
3046: of its parents can have a low bound of our target
3047: plus one so we abort the search. */
3048: if (node->right)
3049: break;
3050: }
1.1.1.13 root 3051: }
3052: return 0;
3053: }
3054:
3055: /* Search the parent sections of the
3056: case node tree to see if both tests for the upper and lower
3057: bounds of NODE would be redundant. */
3058:
3059: static int
3060: node_is_bounded (node)
3061: case_node_ptr node;
3062: {
3063: if (node->left || node->right)
3064: return 0;
3065: return node_has_low_bound (node) && node_has_high_bound (node);
3066: }
3067:
3068: /* Emit an unconditional jump to LABEL unless it would be dead code. */
3069:
3070: static void
3071: emit_jump_if_reachable (label)
3072: rtx label;
3073: {
3074: rtx last_insn;
3075:
3076: if (GET_CODE (get_last_insn ()) != BARRIER)
3077: emit_jump (label);
3078: }
3079:
3080: /* Emit step-by-step code to select a case for the value of INDEX.
3081: The thus generated decision tree follows the form of the
3082: case-node binary tree NODE, whose nodes represent test conditions.
1.1.1.14 root 3083: UNSIGNEDP is nonzero if we should do unsigned comparisons.
1.1.1.13 root 3084:
3085: Care is taken to prune redundant tests from the decision tree
3086: by detecting any boundary conditions already checked by
3087: emitted rtx. (See node_has_high_bound, node_has_low_bound
3088: and node_is_bounded, above.)
3089:
3090: Where the test conditions can be shown to be redundant we emit
3091: an unconditional jump to the target code. As a further
3092: optimization, the subordinates of a tree node are examined to
3093: check for bounded nodes. In this case conditional and/or
3094: unconditional jumps as a result of the boundary check for the
3095: current node are arranged to target the subordinates associated
3096: code for out of bound conditions on the current node node. */
3097:
3098: static void
1.1.1.14 root 3099: emit_case_nodes (index, node, default_label, unsignedp)
3100: rtx index;
1.1.1.13 root 3101: case_node_ptr node;
1.1.1.16 root 3102: rtx default_label;
1.1.1.14 root 3103: int unsignedp;
1.1.1.13 root 3104: {
1.1.1.14 root 3105: /* If INDEX has an unsigned type, we must make unsigned branches. */
3106: typedef rtx rtx_function ();
3107: rtx_function *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt;
3108: rtx_function *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge;
3109: rtx_function *gen_blt_pat = unsignedp ? gen_bltu : gen_blt;
3110: rtx_function *gen_ble_pat = unsignedp ? gen_bleu : gen_ble;
3111:
1.1.1.13 root 3112: if (node->test_label)
3113: {
3114: /* If this test node requires a label it follows that
3115: it must be preceeded by an unconditional branch.
3116: If control can pass to this point we can assume that
3117: a "br default" is in order. */
3118: emit_jump_if_reachable (default_label);
3119: expand_label (node->test_label);
3120: }
3121: if (tree_int_cst_equal (node->low, node->high))
3122: {
3123: /* Node is single valued. */
3124: do_jump_if_equal (index, expand_expr (node->low, 0, VOIDmode, 0),
1.1.1.14 root 3125: label_rtx (node->code_label), unsignedp);
1.1.1.13 root 3126: if (node->right)
3127: {
3128: if (node->left)
3129: {
3130: /* This node has children on either side. */
1.1.1.17 root 3131: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
1.1.1.13 root 3132:
3133: if (node_is_bounded (node->right))
3134: {
1.1.1.17 root 3135: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
1.1.1.13 root 3136: if (node_is_bounded (node->left))
3137: emit_jump (label_rtx (node->left->code_label));
3138: else
1.1.1.14 root 3139: emit_case_nodes (index, node->left,
3140: default_label, unsignedp);
1.1.1.13 root 3141: }
3142: else
3143: {
3144: if (node_is_bounded (node->left))
1.1.1.17 root 3145: emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
1.1.1.13 root 3146: else
3147: {
3148: node->right->test_label =
3149: build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1.1.1.17 root 3150: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
1.1.1.14 root 3151: emit_case_nodes (index, node->left,
3152: default_label, unsignedp);
1.1.1.13 root 3153: }
1.1.1.14 root 3154: emit_case_nodes (index, node->right,
3155: default_label, unsignedp);
1.1.1.13 root 3156: }
3157: }
3158: else
3159: {
3160: /* Here we have a right child but no left
3161: so we issue conditional branch to default
3162: and process the right child. */
3163:
3164: /* Omit the conditional branch to default
3165: if we it avoid only one right child;
3166: it costs too much space to save so little time. */
3167: if (node->right->right && !node_has_low_bound (node))
1.1.1.14 root 3168: {
1.1.1.17 root 3169: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3170: emit_jump_insn ((*gen_blt_pat) (default_label));
1.1.1.14 root 3171: }
1.1.1.13 root 3172: if (node_is_bounded (node->right))
3173: emit_jump (label_rtx (node->right->code_label));
3174: else
1.1.1.14 root 3175: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3176: }
3177: }
3178: else if (node->left)
3179: {
3180: if (node_is_bounded (node->left))
3181: emit_jump (label_rtx (node->left->code_label));
3182: else
1.1.1.14 root 3183: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3184: }
3185: }
3186: else
3187: {
3188: /* Node is a range. */
3189: if (node->right)
3190: {
3191: if (node->left)
3192: {
1.1.1.17 root 3193: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
1.1.1.13 root 3194: if (node_is_bounded (node->right))
3195: {
3196: /* Right hand node is fully bounded so we can
3197: eliminate any testing and branch directly
3198: to the target code. */
1.1.1.17 root 3199: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
1.1.1.13 root 3200: }
3201: else
3202: {
3203: /* Right hand node requires testing so create
3204: a label to put on the cmp code. */
3205: node->right->test_label =
3206: build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1.1.1.17 root 3207: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
1.1.1.13 root 3208: }
1.1.1.17 root 3209: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3210: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3211: if (node_is_bounded (node->left))
3212: {
3213: /* Left hand node is fully bounded so we can
3214: eliminate any testing and branch directly
3215: to the target code. */
3216: emit_jump (label_rtx (node->left->code_label));
3217: }
3218: else
1.1.1.14 root 3219: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3220: /* If right node has been given a test label above
3221: we must process it now. */
3222: if (node->right->test_label)
1.1.1.14 root 3223: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3224: }
3225: else
3226: {
3227: if (!node_has_low_bound (node))
3228: {
1.1.1.17 root 3229: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3230: emit_jump_insn ((*gen_blt_pat) (default_label));
1.1.1.13 root 3231: }
1.1.1.17 root 3232: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3233: emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3234: if (node_is_bounded (node->right))
3235: {
3236: /* Right hand node is fully bounded so we can
3237: eliminate any testing and branch directly
3238: to the target code. */
3239: emit_jump (label_rtx (node->right->code_label));
3240: }
3241: else
1.1.1.14 root 3242: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3243: }
3244: }
3245: else if (node->left)
3246: {
3247: if (!node_has_high_bound (node))
3248: {
1.1.1.17 root 3249: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3250: emit_jump_insn ((*gen_bgt_pat) (default_label));
1.1.1.13 root 3251: }
1.1.1.17 root 3252: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3253: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3254: if (node_is_bounded (node->left))
3255: {
3256: /* Left hand node is fully bounded so we can
3257: eliminate any testing and branch directly
3258: to the target code. */
3259: emit_jump (label_rtx (node->left->code_label));
3260: }
3261: else
1.1.1.14 root 3262: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3263: }
3264: else
3265: {
3266: /* Node has no children so we check low and
3267: high bounds to remove redundant tests. In practice
3268: only one of the limits may be bounded or the parent
3269: node will have emmited a jump to our target code. */
3270: if (!node_has_high_bound (node))
3271: {
1.1.1.17 root 3272: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3273: emit_jump_insn ((*gen_bgt_pat) (default_label));
1.1.1.13 root 3274: }
3275: if (!node_has_low_bound (node))
3276: {
1.1.1.17 root 3277: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3278: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3279: }
3280: /* We allow the default case to drop through since
3281: it will picked up by calls to `jump_if_reachable'
3282: either on the next test label or at the end of
3283: the decision tree emission. */
3284: }
3285: }
3286: }
3287:
1.1.1.2 root 3288: /* Allocate fixed slots in the stack frame of the current function. */
1.1 root 3289:
3290: /* Return size needed for stack frame based on slots so far allocated. */
3291:
3292: int
3293: get_frame_size ()
3294: {
1.1.1.2 root 3295: #ifdef FRAME_GROWS_DOWNWARD
1.1.1.17 root 3296: return -frame_offset + STARTING_FRAME_OFFSET;
1.1.1.2 root 3297: #else
1.1.1.17 root 3298: return frame_offset - STARTING_FRAME_OFFSET;
1.1.1.2 root 3299: #endif
1.1 root 3300: }
3301:
3302: /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
3303: with machine mode MODE. */
3304:
3305: rtx
3306: assign_stack_local (mode, size)
3307: enum machine_mode mode;
3308: int size;
3309: {
1.1.1.2 root 3310: register rtx x, addr;
1.1.1.4 root 3311: int bigend_correction = 0;
1.1 root 3312:
1.1.1.2 root 3313: frame_pointer_needed = 1;
1.1 root 3314:
3315: /* Make each stack slot a multiple of the main allocation unit. */
3316: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
3317: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
3318: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
3319:
1.1.1.4 root 3320: /* On a big-endian machine, if we are allocating more space than we will use,
3321: use the least significant bytes of those that are allocated. */
3322: #ifdef BYTES_BIG_ENDIAN
3323: if (mode != BLKmode)
3324: bigend_correction = size - GET_MODE_SIZE (mode);
3325: #endif
3326:
1.1 root 3327: #ifdef FRAME_GROWS_DOWNWARD
3328: frame_offset -= size;
3329: #endif
1.1.1.2 root 3330: addr = gen_rtx (PLUS, Pmode, frame_pointer_rtx,
1.1.1.4 root 3331: gen_rtx (CONST_INT, VOIDmode,
3332: (frame_offset + bigend_correction)));
1.1 root 3333: #ifndef FRAME_GROWS_DOWNWARD
3334: frame_offset += size;
3335: #endif
3336:
1.1.1.2 root 3337: if (! memory_address_p (mode, addr))
3338: invalid_stack_slot = 1;
3339:
3340: x = gen_rtx (MEM, mode, addr);
3341:
1.1.1.13 root 3342: stack_slot_list = gen_rtx (EXPR_LIST, VOIDmode, x, stack_slot_list);
3343:
1.1.1.2 root 3344: return x;
1.1 root 3345: }
3346:
1.1.1.2 root 3347: /* Retroactively move an auto variable from a register to a stack slot.
3348: This is done when an address-reference to the variable is seen. */
1.1 root 3349:
1.1.1.2 root 3350: void
3351: put_var_into_stack (decl)
3352: tree decl;
3353: {
3354: register rtx reg = DECL_RTL (decl);
3355: register rtx new;
1.1 root 3356:
1.1.1.2 root 3357: /* No need to do anything if decl has no rtx yet
3358: since in that case caller is setting TREE_ADDRESSABLE
3359: and a stack slot will be assigned when the rtl is made. */
3360: if (reg == 0)
3361: return;
3362: if (GET_CODE (reg) != REG)
3363: return;
3364:
3365: new = parm_stack_loc (reg);
3366: if (new == 0)
3367: new = assign_stack_local (GET_MODE (reg), GET_MODE_SIZE (GET_MODE (reg)));
3368:
1.1.1.10 root 3369: XEXP (reg, 0) = XEXP (new, 0);
3370: /* `volatil' bit means one thing for MEMs, another entirely for REGs. */
3371: REG_USERVAR_P (reg) = 0;
3372: PUT_CODE (reg, MEM);
3373:
1.1.1.2 root 3374: /* If this is a memory ref that contains aggregate components,
3375: mark it as such for cse and loop optimize. */
1.1.1.10 root 3376: MEM_IN_STRUCT_P (reg)
1.1.1.2 root 3377: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
3378: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
3379: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
3380:
3381: fixup_var_refs (reg);
3382: }
3383:
1.1 root 3384: static void
1.1.1.2 root 3385: fixup_var_refs (var)
3386: rtx var;
1.1 root 3387: {
1.1.1.10 root 3388: extern rtx sequence_stack;
3389: rtx stack = sequence_stack;
3390: tree pending;
3391:
3392: stack = sequence_stack;
3393:
3394: /* Must scan all insns for stack-refs that exceed the limit. */
3395: fixup_var_refs_insns (var, get_insns (), stack == 0);
3396:
3397: /* Scan all pending sequences too. */
3398: for (; stack; stack = XEXP (XEXP (stack, 1), 1))
3399: {
3400: push_to_sequence (XEXP (stack, 0));
3401: fixup_var_refs_insns (var, XEXP (stack, 0),
3402: XEXP (XEXP (stack, 1), 1) == 0);
1.1.1.17 root 3403: /* Update remembered end of sequence
3404: in case we added an insn at the end. */
3405: XEXP (XEXP (stack, 1), 0) = get_last_insn ();
1.1.1.10 root 3406: end_sequence ();
3407: }
3408:
3409: /* Scan all waiting RTL_EXPRs too. */
3410: for (pending = rtl_expr_chain; pending; pending = TREE_CHAIN (pending))
3411: {
3412: rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
3413: if (seq != const0_rtx && seq != 0)
3414: {
3415: push_to_sequence (seq);
3416: fixup_var_refs_insns (var, seq, 0);
3417: end_sequence ();
3418: }
3419: }
3420: }
1.1.1.2 root 3421:
1.1.1.10 root 3422: /* Scan the insn-chain starting with INSN for refs to VAR
3423: and fix them up. TOPLEVEL is nonzero if this chain is the
3424: main chain of insns for the current function. */
3425:
3426: static void
3427: fixup_var_refs_insns (var, insn, toplevel)
3428: rtx var;
3429: rtx insn;
3430: int toplevel;
3431: {
3432: while (insn)
1.1.1.2 root 3433: {
3434: rtx next = NEXT_INSN (insn);
1.1.1.13 root 3435: rtx note;
1.1.1.2 root 3436: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
3437: || GET_CODE (insn) == JUMP_INSN)
3438: {
3439: /* The insn to load VAR from a home in the arglist
3440: is now a no-op. When we see it, just delete it. */
1.1.1.10 root 3441: if (toplevel
3442: && GET_CODE (PATTERN (insn)) == SET
1.1.1.2 root 3443: && SET_DEST (PATTERN (insn)) == var
3444: && rtx_equal_p (SET_SRC (PATTERN (insn)), var))
1.1.1.8 root 3445: {
3446: next = delete_insn (insn);
3447: if (insn == last_parm_insn)
3448: last_parm_insn = PREV_INSN (next);
3449: }
1.1.1.2 root 3450: else
3451: fixup_var_refs_1 (var, PATTERN (insn), insn);
1.1.1.13 root 3452: /* Also fix up any invalid exprs in the REG_NOTES of this insn.
3453: But don't touch other insns referred to by reg-notes;
3454: we will get them elsewhere. */
3455: for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
3456: if (GET_CODE (note) != INSN_LIST)
3457: XEXP (note, 0) = walk_fixup_memory_subreg (XEXP (note, 0), insn);
1.1.1.2 root 3458: }
3459: insn = next;
3460: }
3461: }
1.1.1.13 root 3462:
1.1.1.2 root 3463: static rtx
3464: fixup_var_refs_1 (var, x, insn)
3465: register rtx var;
3466: register rtx x;
3467: rtx insn;
3468: {
3469: register int i;
3470: RTX_CODE code = GET_CODE (x);
3471: register char *fmt;
3472: register rtx tem;
3473:
3474: switch (code)
3475: {
3476: case MEM:
3477: if (var == x)
3478: {
3479: x = fixup_stack_1 (x, insn);
3480: tem = gen_reg_rtx (GET_MODE (x));
1.1.1.18 root 3481: /* Put new insn before a CALL, before any USEs before it. */
3482: if (GET_CODE (insn) == CALL_INSN)
3483: while (PREV_INSN (insn) != 0 && GET_CODE (PREV_INSN (insn)) == INSN
3484: && GET_CODE (PATTERN (PREV_INSN (insn))) == USE)
3485: insn = PREV_INSN (insn);
1.1.1.2 root 3486: emit_insn_before (gen_move_insn (tem, x), insn);
3487: return tem;
3488: }
3489: break;
3490:
3491: case REG:
3492: case CC0:
3493: case PC:
3494: case CONST_INT:
3495: case CONST:
3496: case SYMBOL_REF:
3497: case LABEL_REF:
3498: case CONST_DOUBLE:
3499: return x;
3500:
3501: case SIGN_EXTRACT:
3502: case ZERO_EXTRACT:
3503: /* Note that in some cases those types of expressions are altered
3504: by optimize_bit_field, and do not survive to get here. */
3505: case SUBREG:
3506: tem = x;
3507: while (GET_CODE (tem) == SUBREG || GET_CODE (tem) == SIGN_EXTRACT
3508: || GET_CODE (tem) == ZERO_EXTRACT)
3509: tem = XEXP (tem, 0);
3510: if (tem == var)
3511: {
3512: x = fixup_stack_1 (x, insn);
3513: tem = gen_reg_rtx (GET_MODE (x));
1.1.1.7 root 3514: if (GET_CODE (x) == SUBREG)
1.1.1.13 root 3515: x = fixup_memory_subreg (x, insn);
1.1.1.2 root 3516: emit_insn_before (gen_move_insn (tem, x), insn);
3517: return tem;
3518: }
3519: break;
3520:
3521: case SET:
3522: /* First do special simplification of bit-field references. */
3523: if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
3524: || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
3525: optimize_bit_field (x, insn, 0);
3526: if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
3527: || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
3528: optimize_bit_field (x, insn, 0);
3529:
3530: {
3531: rtx dest = SET_DEST (x);
3532: rtx src = SET_SRC (x);
3533: rtx outerdest = dest;
3534: rtx outersrc = src;
3535:
3536: while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
3537: || GET_CODE (dest) == SIGN_EXTRACT
3538: || GET_CODE (dest) == ZERO_EXTRACT)
3539: dest = XEXP (dest, 0);
3540: while (GET_CODE (src) == SUBREG
3541: || GET_CODE (src) == SIGN_EXTRACT
3542: || GET_CODE (src) == ZERO_EXTRACT)
3543: src = XEXP (src, 0);
3544:
3545: /* If VAR does not appear at the top level of the SET
3546: just scan the lower levels of the tree. */
3547:
3548: if (src != var && dest != var)
3549: break;
3550:
3551: /* Clean up (SUBREG:SI (MEM:mode ...) 0)
3552: that may appear inside a SIGN_EXTRACT or ZERO_EXTRACT.
3553: This was legitimate when the MEM was a REG. */
3554:
3555: if ((GET_CODE (outerdest) == SIGN_EXTRACT
3556: || GET_CODE (outerdest) == ZERO_EXTRACT)
3557: && GET_CODE (XEXP (outerdest, 0)) == SUBREG
3558: && SUBREG_REG (XEXP (outerdest, 0)) == var)
1.1.1.13 root 3559: XEXP (outerdest, 0) = fixup_memory_subreg (XEXP (outerdest, 0), insn);
1.1.1.2 root 3560:
3561: if ((GET_CODE (outersrc) == SIGN_EXTRACT
3562: || GET_CODE (outersrc) == ZERO_EXTRACT)
3563: && GET_CODE (XEXP (outersrc, 0)) == SUBREG
3564: && SUBREG_REG (XEXP (outersrc, 0)) == var)
1.1.1.13 root 3565: XEXP (outersrc, 0) = fixup_memory_subreg (XEXP (outersrc, 0), insn);
1.1.1.2 root 3566:
1.1.1.18 root 3567: /* Make sure that the machine's SIGN_EXTRACT and ZERO_EXTRACT insns
3568: accept a memory operand. */
3569: #ifdef HAVE_extzv
3570: if (GET_CODE (outersrc) == ZERO_EXTRACT
3571: && ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
3572: (XEXP (outersrc, 0), VOIDmode)))
3573: XEXP (outersrc, 0) = src
3574: = fixup_var_refs_1 (var, XEXP (outersrc, 0), insn);
3575: #endif
3576: #ifdef HAVE_extv
3577: if (GET_CODE (outersrc) == SIGN_EXTRACT
3578: && ! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
3579: (XEXP (outersrc, 0), VOIDmode)))
3580: XEXP (outersrc, 0) = src
3581: = fixup_var_refs_1 (var, XEXP (outersrc, 0), insn);
3582: #endif
3583: #ifdef HAVE_insv
3584: if (GET_CODE (outerdest) == ZERO_EXTRACT
3585: && ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
3586: (XEXP (outerdest, 0), VOIDmode)))
3587: {
3588: rtx tem = gen_reg_rtx (GET_MODE (XEXP (outerdest, 0)));
3589:
3590: emit_insn_before (gen_move_insn (tem, XEXP (outerdest, 0)), insn);
3591: emit_insn_after (gen_move_insn (XEXP (outerdest, 0), tem), insn);
3592: dest = XEXP (outerdest, 0) = tem;
3593: }
3594: #endif
3595:
1.1.1.2 root 3596: /* Make sure a MEM inside a SIGN_EXTRACT has QImode
3597: since that's what bit-field insns want. */
3598:
3599: if ((GET_CODE (outerdest) == SIGN_EXTRACT
3600: || GET_CODE (outerdest) == ZERO_EXTRACT)
3601: && GET_CODE (XEXP (outerdest, 0)) == MEM
3602: && GET_MODE (XEXP (outerdest, 0)) != QImode)
3603: {
3604: XEXP (outerdest, 0) = copy_rtx (XEXP (outerdest, 0));
3605: PUT_MODE (XEXP (outerdest, 0), QImode);
1.1.1.17 root 3606: /* Adjust the address so the bit field starts within the byte
3607: addressed. This helps certain optimization patterns. */
3608: if (GET_CODE (XEXP (outerdest, 2)) == CONST_INT
3609: && offsettable_memref_p (XEXP (outerdest, 0)))
3610: {
3611: int count = INTVAL (XEXP (outerdest, 2));
3612: XEXP (outerdest, 0)
3613: = adj_offsettable_operand (XEXP (outerdest, 0),
3614: count / GET_MODE_BITSIZE (QImode));
3615: XEXP (outerdest, 2)
3616: = gen_rtx (CONST_INT, VOIDmode,
3617: count % GET_MODE_BITSIZE (QImode));
3618: }
1.1.1.2 root 3619: }
3620:
3621: if ((GET_CODE (outersrc) == SIGN_EXTRACT
3622: || GET_CODE (outersrc) == ZERO_EXTRACT)
3623: && GET_CODE (XEXP (outersrc, 0)) == MEM
3624: && GET_MODE (XEXP (outersrc, 0)) != QImode)
3625: {
3626: XEXP (outersrc, 0) = copy_rtx (XEXP (outersrc, 0));
3627: PUT_MODE (XEXP (outersrc, 0), QImode);
1.1.1.17 root 3628: /* Adjust the address so the bit field starts within the byte
3629: addressed. This helps certain optimization patterns. */
3630: if (GET_CODE (XEXP (outersrc, 2)) == CONST_INT
3631: && offsettable_memref_p (XEXP (outersrc, 0)))
3632: {
3633: int count = INTVAL (XEXP (outersrc, 2));
3634: XEXP (outersrc, 0)
3635: = adj_offsettable_operand (XEXP (outersrc, 0),
3636: count / GET_MODE_BITSIZE (QImode));
3637: XEXP (outersrc, 2)
3638: = gen_rtx (CONST_INT, VOIDmode,
3639: count % GET_MODE_BITSIZE (QImode));
3640: }
1.1.1.2 root 3641: }
3642:
3643: /* STRICT_LOW_PART is a no-op on memory references
3644: and it can cause combinations to be unrecognizable,
3645: so eliminate it. */
3646:
3647: if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
3648: SET_DEST (x) = XEXP (SET_DEST (x), 0);
3649:
3650: /* An insn to copy VAR into or out of a register
3651: must be left alone, to avoid an infinite loop here.
1.1.1.9 root 3652: But do fix up the address of VAR's stack slot if nec,
3653: and fix up SUBREGs containing VAR
3654: (since they are now memory subregs). */
3655:
3656: if (GET_CODE (SET_SRC (x)) == REG || GET_CODE (SET_DEST (x)) == REG
3657: || (GET_CODE (SET_SRC (x)) == SUBREG
3658: && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG)
1.1.1.2 root 3659: || (GET_CODE (SET_DEST (x)) == SUBREG
3660: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
1.1.1.9 root 3661: {
3662: if (src == var && GET_CODE (SET_SRC (x)) == SUBREG)
1.1.1.13 root 3663: SET_SRC (x) = fixup_memory_subreg (SET_SRC (x), insn);
1.1.1.9 root 3664: if (dest == var && GET_CODE (SET_DEST (x)) == SUBREG)
1.1.1.13 root 3665: SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn);
1.1.1.9 root 3666: return fixup_stack_1 (x, insn);
3667: }
1.1.1.2 root 3668:
3669: /* Otherwise, storing into VAR must be handled specially
3670: by storing into a temporary and copying that into VAR
3671: with a new insn after this one. */
3672:
3673: if (dest == var)
3674: {
3675: rtx temp;
3676: rtx fixeddest;
3677: tem = SET_DEST (x);
1.1.1.12 root 3678: /* STRICT_LOW_PART can be discarded, around a MEM. */
1.1.1.2 root 3679: if (GET_CODE (tem) == STRICT_LOW_PART)
3680: tem = XEXP (tem, 0);
1.1.1.12 root 3681: /* Convert (SUBREG (MEM)) to a MEM in a changed mode. */
3682: if (GET_CODE (tem) == SUBREG)
1.1.1.13 root 3683: tem = fixup_memory_subreg (tem, insn);
1.1.1.12 root 3684: fixeddest = fixup_stack_1 (tem, insn);
1.1.1.2 root 3685: temp = gen_reg_rtx (GET_MODE (tem));
3686: emit_insn_after (gen_move_insn (fixeddest, temp), insn);
3687: SET_DEST (x) = temp;
3688: }
3689: }
3690: }
3691:
3692: /* Nothing special about this RTX; fix its operands. */
3693:
3694: fmt = GET_RTX_FORMAT (code);
3695: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3696: {
3697: if (fmt[i] == 'e')
3698: XEXP (x, i) = fixup_var_refs_1 (var, XEXP (x, i), insn);
3699: if (fmt[i] == 'E')
3700: {
3701: register int j;
3702: for (j = 0; j < XVECLEN (x, i); j++)
3703: XVECEXP (x, i, j)
3704: = fixup_var_refs_1 (var, XVECEXP (x, i, j), insn);
3705: }
3706: }
3707: return x;
3708: }
1.1.1.13 root 3709:
1.1.1.2 root 3710: /* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
1.1.1.13 root 3711: return an rtx (MEM:m1 newaddr) which is equivalent.
3712: If any insns must be emitted to compute NEWADDR, put them before INSN. */
1.1.1.2 root 3713:
3714: static rtx
1.1.1.13 root 3715: fixup_memory_subreg (x, insn)
1.1.1.2 root 3716: rtx x;
1.1.1.13 root 3717: rtx insn;
1.1.1.2 root 3718: {
3719: int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
3720: rtx addr = XEXP (SUBREG_REG (x), 0);
1.1.1.7 root 3721: enum machine_mode mode = GET_MODE (x);
1.1.1.13 root 3722: rtx saved, result;
1.1.1.2 root 3723:
3724: #ifdef BYTES_BIG_ENDIAN
1.1.1.8 root 3725: offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1.1.1.15 root 3726: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
1.1.1.2 root 3727: #endif
1.1.1.13 root 3728: addr = plus_constant (addr, offset);
3729: if (memory_address_p (mode, addr))
3730: return change_address (SUBREG_REG (x), mode, addr);
3731: saved = start_sequence ();
3732: result = change_address (SUBREG_REG (x), mode, addr);
3733: emit_insn_before (gen_sequence (), insn);
3734: end_sequence (saved);
3735: return result;
3736: }
3737:
3738: /* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
3739: Replace subexpressions of X in place.
3740: If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
3741: Otherwise return X, with its contents possibly altered.
3742:
3743: If any insns must be emitted to compute NEWADDR, put them before INSN. */
3744:
3745: static rtx
3746: walk_fixup_memory_subreg (x, insn)
3747: register rtx x;
3748: rtx insn;
3749: {
3750: register enum rtx_code code;
3751: register char *fmt;
3752: register int i;
3753:
1.1.1.16 root 3754: if (x == 0)
3755: return 0;
3756:
1.1.1.13 root 3757: code = GET_CODE (x);
3758:
3759: if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
3760: return fixup_memory_subreg (x, insn);
3761:
3762: /* Nothing special about this RTX; fix its operands. */
3763:
3764: fmt = GET_RTX_FORMAT (code);
3765: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3766: {
3767: if (fmt[i] == 'e')
3768: XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn);
3769: if (fmt[i] == 'E')
3770: {
3771: register int j;
3772: for (j = 0; j < XVECLEN (x, i); j++)
3773: XVECEXP (x, i, j)
3774: = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn);
3775: }
3776: }
3777: return x;
1.1.1.2 root 3778: }
3779:
3780: #if 0
3781: /* Fix up any references to stack slots that are invalid memory addresses
3782: because they exceed the maximum range of a displacement. */
3783:
3784: void
3785: fixup_stack_slots ()
3786: {
3787: register rtx insn;
3788:
3789: /* Did we generate a stack slot that is out of range
3790: or otherwise has an invalid address? */
3791: if (invalid_stack_slot)
3792: {
3793: /* Yes. Must scan all insns for stack-refs that exceed the limit. */
3794: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3795: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
3796: || GET_CODE (insn) == JUMP_INSN)
3797: fixup_stack_1 (PATTERN (insn), insn);
3798: }
3799: }
3800: #endif
3801:
3802: /* For each memory ref within X, if it refers to a stack slot
3803: with an out of range displacement, put the address in a temp register
3804: (emitting new insns before INSN to load these registers)
3805: and alter the memory ref to use that register.
3806: Replace each such MEM rtx with a copy, to avoid clobberage. */
3807:
3808: static rtx
3809: fixup_stack_1 (x, insn)
3810: rtx x;
3811: rtx insn;
3812: {
3813: register int i;
3814: register RTX_CODE code = GET_CODE (x);
3815: register char *fmt;
3816:
3817: if (code == MEM)
3818: {
3819: register rtx ad = XEXP (x, 0);
3820: /* If we have address of a stack slot but it's not valid
3821: (displacement is too large), compute the sum in a register. */
3822: if (GET_CODE (ad) == PLUS
3823: && XEXP (ad, 0) == frame_pointer_rtx
3824: && GET_CODE (XEXP (ad, 1)) == CONST_INT)
3825: {
3826: rtx temp;
3827: if (memory_address_p (GET_MODE (x), ad))
3828: return x;
3829: temp = gen_reg_rtx (GET_MODE (ad));
3830: emit_insn_before (gen_move_insn (temp, ad), insn);
3831: return change_address (x, VOIDmode, temp);
3832: }
3833: return x;
3834: }
3835:
3836: fmt = GET_RTX_FORMAT (code);
3837: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3838: {
3839: if (fmt[i] == 'e')
3840: XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
3841: if (fmt[i] == 'E')
3842: {
3843: register int j;
3844: for (j = 0; j < XVECLEN (x, i); j++)
3845: XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
3846: }
3847: }
3848: return x;
1.1 root 3849: }
1.1.1.2 root 3850:
3851: /* Optimization: a bit-field instruction whose field
3852: happens to be a byte or halfword in memory
3853: can be changed to a move instruction.
1.1 root 3854:
1.1.1.2 root 3855: We call here when INSN is an insn to examine or store into a bit-field.
3856: BODY is the SET-rtx to be altered.
3857:
3858: EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
3859: (Currently this is called only from stmt.c, and EQUIV_MEM is always 0.) */
1.1 root 3860:
3861: static void
1.1.1.2 root 3862: optimize_bit_field (body, insn, equiv_mem)
3863: rtx body;
3864: rtx insn;
3865: rtx *equiv_mem;
1.1 root 3866: {
1.1.1.2 root 3867: register rtx bitfield;
3868: int destflag;
1.1 root 3869:
1.1.1.2 root 3870: if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
3871: || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
3872: bitfield = SET_DEST (body), destflag = 1;
3873: else
3874: bitfield = SET_SRC (body), destflag = 0;
3875:
3876: /* First check that the field being stored has constant size and position
3877: and is in fact a byte or halfword suitably aligned. */
3878:
3879: if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
3880: && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
3881: && (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
3882: || INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (HImode))
3883: && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
1.1 root 3884: {
1.1.1.2 root 3885: register rtx memref = 0;
3886:
1.1.1.10 root 3887: /* Now check that the containing word is memory, not a register,
1.1.1.2 root 3888: and that it is safe to change the machine mode and to
3889: add something to the address. */
3890:
3891: if (GET_CODE (XEXP (bitfield, 0)) == MEM)
3892: memref = XEXP (bitfield, 0);
3893: else if (GET_CODE (XEXP (bitfield, 0)) == REG
1.1.1.8 root 3894: && equiv_mem != 0)
3895: memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
1.1.1.2 root 3896: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
3897: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
3898: memref = SUBREG_REG (XEXP (bitfield, 0));
3899: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
3900: && equiv_mem != 0
1.1.1.8 root 3901: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
3902: memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];
1.1.1.2 root 3903:
3904: if (memref
3905: && ! mode_dependent_address_p (XEXP (memref, 0))
1.1.1.17 root 3906: && offsettable_address_p (0, GET_MODE (bitfield), XEXP (memref, 0)))
1.1 root 3907: {
1.1.1.2 root 3908: /* Now adjust the address, first for any subreg'ing
3909: that we are now getting rid of,
3910: and then for which byte of the word is wanted. */
3911:
3912: register int offset
3913: = INTVAL (XEXP (bitfield, 2)) / GET_MODE_BITSIZE (QImode);
3914: if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
3915: {
3916: offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
3917: #ifdef BYTES_BIG_ENDIAN
3918: offset -= (MIN (UNITS_PER_WORD,
3919: GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
3920: - MIN (UNITS_PER_WORD,
3921: GET_MODE_SIZE (GET_MODE (memref))));
3922: #endif
3923: }
1.1.1.8 root 3924:
1.1.1.2 root 3925: memref = gen_rtx (MEM,
3926: (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
3927: ? QImode : HImode),
3928: XEXP (memref, 0));
1.1 root 3929:
1.1.1.2 root 3930: /* Store this memory reference where
3931: we found the bit field reference. */
1.1 root 3932:
1.1.1.2 root 3933: if (destflag)
1.1 root 3934: {
1.1.1.2 root 3935: SET_DEST (body)
1.1.1.17 root 3936: = adj_offsettable_operand (memref, offset);
1.1.1.2 root 3937: if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
1.1 root 3938: {
1.1.1.2 root 3939: rtx src = SET_SRC (body);
3940: while (GET_CODE (src) == SUBREG
3941: && SUBREG_WORD (src) == 0)
3942: src = SUBREG_REG (src);
3943: if (GET_MODE (src) != GET_MODE (memref))
1.1.1.10 root 3944: src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
1.1.1.2 root 3945: SET_SRC (body) = src;
1.1 root 3946: }
1.1.1.2 root 3947: else if (GET_MODE (SET_SRC (body)) != VOIDmode
3948: && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
3949: /* This shouldn't happen because anything that didn't have
3950: one of these modes should have got converted explicitly
3951: and then referenced through a subreg.
3952: This is so because the original bit-field was
3953: handled by agg_mode and so its tree structure had
3954: the same mode that memref now has. */
3955: abort ();
3956: }
3957: else
3958: {
1.1.1.8 root 3959: rtx dest = SET_DEST (body);
3960:
3961: while (GET_CODE (dest) == SUBREG
3962: && SUBREG_WORD (dest) == 0)
3963: dest = SUBREG_REG (dest);
3964: SET_DEST (body) = dest;
3965:
1.1.1.17 root 3966: memref = adj_offsettable_operand (memref, offset);
1.1.1.8 root 3967: if (GET_MODE (dest) == GET_MODE (memref))
3968: SET_SRC (body) = memref;
3969: else
3970: {
1.1.1.10 root 3971: /* Convert the mem ref to the destination mode. */
3972: rtx last = get_last_insn ();
1.1.1.8 root 3973: rtx newreg = gen_reg_rtx (GET_MODE (dest));
1.1.1.10 root 3974: convert_move (newreg, memref,
3975: GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
3976: /* Put the conversion before the insn being fixed. */
3977: reorder_insns (NEXT_INSN (last), get_last_insn (),
3978: PREV_INSN (insn));
1.1.1.8 root 3979: SET_SRC (body) = newreg;
3980: }
1.1 root 3981: }
1.1.1.2 root 3982:
3983: /* Cause the insn to be re-recognized. */
3984:
3985: INSN_CODE (insn) = -1;
1.1 root 3986: }
3987: }
3988: }
3989:
3990: /* 1 + last pseudo register number used for loading a copy
3991: of a parameter of this function. */
3992:
3993: static int max_parm_reg;
3994:
1.1.1.2 root 3995: /* Vector indexed by REGNO, containing location on stack in which
3996: to put the parm which is nominally in pseudo register REGNO,
3997: if we discover that that parm must go in the stack. */
3998: static rtx *parm_reg_stack_loc;
3999:
4000: int
4001: max_parm_reg_num ()
4002: {
4003: return max_parm_reg;
4004: }
4005:
4006: /* Return the first insn following those generated by `assign_parms'. */
4007:
4008: rtx
4009: get_first_nonparm_insn ()
4010: {
4011: if (last_parm_insn)
4012: return NEXT_INSN (last_parm_insn);
4013: return get_insns ();
4014: }
4015:
4016: /* Get the stack home of a REG rtx that is one of this function's parameters.
4017: This is called rather than assign a new stack slot as a local.
4018: Return 0 if there is no existing stack home suitable for such use. */
4019:
4020: static rtx
4021: parm_stack_loc (reg)
4022: rtx reg;
4023: {
4024: if (REGNO (reg) < max_parm_reg)
4025: return parm_reg_stack_loc[REGNO (reg)];
4026: return 0;
4027: }
4028:
1.1.1.17 root 4029: /* Return 1 if EXP returns an aggregate value, for which an address
4030: must be passed to the function or returned by the function. */
4031:
4032: int
4033: aggregate_value_p (exp)
4034: tree exp;
4035: {
4036: if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
4037: return 1;
4038: if (RETURN_IN_MEMORY (TREE_TYPE (exp)))
4039: return 1;
4040: if (flag_pcc_struct_return
4041: && (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
4042: || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE))
4043: return 1;
4044: return 0;
4045: }
1.1.1.18 root 4046:
4047: /* Convert a mem ref into one with a valid memory address.
4048: Pass through anything else unchanged. */
4049:
4050: rtx
4051: validize_mem (ref)
4052: rtx ref;
4053: {
4054: if (GET_CODE (ref) != MEM)
4055: return ref;
4056: if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
4057: return ref;
1.1.1.19 root 4058: /* Don't alter REF itself, since that is probably a stack slot. */
4059: return gen_rtx (MEM, GET_MODE (ref),
4060: memory_address (GET_MODE (ref), XEXP (ref, 0)));
1.1.1.18 root 4061: }
1.1.1.17 root 4062:
1.1 root 4063: /* Assign RTL expressions to the function's parameters.
4064: This may involve copying them into registers and using
4065: those registers as the RTL for them. */
4066:
4067: static void
4068: assign_parms (fndecl)
4069: tree fndecl;
4070: {
4071: register tree parm;
1.1.1.2 root 4072: register rtx entry_parm;
4073: register rtx stack_parm;
4074: register CUMULATIVE_ARGS args_so_far;
4075: enum machine_mode passed_mode, nominal_mode;
4076: /* Total space needed so far for args on the stack,
4077: given as a constant and a tree-expression. */
4078: struct args_size stack_args_size;
1.1.1.8 root 4079: int first_parm_offset = FIRST_PARM_OFFSET (fndecl);
1.1.1.19 root 4080: int first_parm_caller_offset
4081: #ifdef FIRST_PARM_CALLER_OFFSET
4082: = FIRST_PARM_CALLER_OFFSET (fndecl);
4083: #else
4084: = first_parm_offset;
4085: #endif
1.1.1.13 root 4086: tree fntype = TREE_TYPE (fndecl);
1.1.1.17 root 4087: /* This is used for the arg pointer when referring to stack args. */
4088: rtx internal_arg_pointer;
1.1.1.2 root 4089:
4090: int nparmregs
4091: = list_length (DECL_ARGUMENTS (fndecl)) + FIRST_PSEUDO_REGISTER;
4092:
4093: /* Nonzero if function takes extra anonymous args.
4094: This means the last named arg must be on the stack
1.1.1.4 root 4095: right before the anonymous ones.
4096: Also nonzero if the first arg is named `__builtin_va_alist',
4097: which is used on some machines for old-fashioned non-ANSI varargs.h;
4098: this too should be stuck onto the stack as if it had arrived there. */
1.1.1.2 root 4099: int vararg
1.1.1.4 root 4100: = ((DECL_ARGUMENTS (fndecl) != 0
1.1.1.13 root 4101: && DECL_NAME (DECL_ARGUMENTS (fndecl))
1.1.1.4 root 4102: && (! strcmp (IDENTIFIER_POINTER (DECL_NAME (DECL_ARGUMENTS (fndecl))),
4103: "__builtin_va_alist")))
4104: ||
1.1.1.13 root 4105: (TYPE_ARG_TYPES (fntype) != 0
4106: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1.1.1.4 root 4107: != void_type_node)));
1.1.1.17 root 4108: int arg_pointer_copied = 0;
4109:
4110: #if ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM
4111: internal_arg_pointer = arg_pointer_rtx;
4112: #else
4113: /* If the arg pointer reg is not a fixed reg,
4114: make a copy of it, and address parms via the copy. */
4115: if (fixed_regs[ARG_POINTER_REGNUM])
4116: internal_arg_pointer = arg_pointer_rtx;
4117: else
4118: {
4119: internal_arg_pointer = copy_to_reg (arg_pointer_rtx);
4120: arg_pointer_copied = 1;
4121: }
4122: #endif
1.1.1.2 root 4123:
4124: stack_args_size.constant = 0;
4125: stack_args_size.var = 0;
4126:
1.1.1.6 root 4127: /* If struct value address comes on the stack, count it in size of args. */
1.1.1.17 root 4128: if (aggregate_value_p (DECL_RESULT (fndecl))
1.1.1.6 root 4129: && GET_CODE (struct_value_incoming_rtx) == MEM)
1.1.1.20 root 4130: {
4131: #ifdef FIRST_PARM_CALLER_OFFSET
4132: /* Make the right thing happen on the sparc
4133: in a function with a struct value and struct arg. */
4134: if (first_parm_caller_offset < 0)
4135: first_parm_offset += GET_MODE_SIZE (Pmode);
4136: else
4137: #endif
4138: stack_args_size.constant += GET_MODE_SIZE (Pmode);
4139: }
1.1.1.6 root 4140:
1.1.1.2 root 4141: parm_reg_stack_loc = (rtx *) oballoc (nparmregs * sizeof (rtx));
4142: bzero (parm_reg_stack_loc, nparmregs * sizeof (rtx));
4143:
1.1.1.13 root 4144: INIT_CUMULATIVE_ARGS (args_so_far, fntype);
1.1 root 4145:
1.1.1.2 root 4146: for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
1.1 root 4147: {
1.1.1.2 root 4148: int aggregate
4149: = (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
4150: || TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
4151: || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE);
4152: struct args_size stack_offset;
4153: rtx stack_offset_rtx;
1.1.1.6 root 4154: enum direction where_pad;
1.1.1.2 root 4155:
4156: DECL_OFFSET (parm) = -1;
4157:
1.1.1.8 root 4158: if (TREE_TYPE (parm) == error_mark_node
1.1.1.10 root 4159: /* This can happen after weird syntax errors
4160: or if an enum type is defined among the parms. */
1.1.1.8 root 4161: || TREE_CODE (parm) != PARM_DECL
4162: || DECL_ARG_TYPE (parm) == NULL)
1.1.1.2 root 4163: {
4164: DECL_RTL (parm) = gen_rtx (MEM, BLKmode, const0_rtx);
1.1.1.13 root 4165: TREE_USED (parm) = 1;
1.1.1.2 root 4166: continue;
4167: }
4168:
4169: /* Find mode of arg as it is passed, and mode of arg
4170: as it should be during execution of this function. */
4171: passed_mode = TYPE_MODE (DECL_ARG_TYPE (parm));
4172: nominal_mode = TYPE_MODE (TREE_TYPE (parm));
4173:
1.1.1.6 root 4174: /* Get this parm's offset as an rtx. */
4175: stack_offset = stack_args_size;
1.1.1.8 root 4176: stack_offset.constant += first_parm_offset;
1.1.1.6 root 4177:
1.1.1.16 root 4178: /* If this argument needs more than the usual parm alignment, do
4179: extrinsic padding to reach that alignment. */
4180:
4181: #ifdef MAX_PARM_BOUNDARY
4182: /* If MAX_PARM_BOUNDARY is not defined, it means that the usual
4183: alignment requirements are relaxed for parms, and that no parm
4184: needs more alignment than PARM_BOUNDARY, regardless of data type. */
4185:
1.1.1.17 root 4186: if (PARM_BOUNDARY < TYPE_ALIGN (DECL_ARG_TYPE (parm)))
1.1.1.16 root 4187: {
4188: int boundary = PARM_BOUNDARY;
4189:
4190: /* Determine the boundary to pad up to. */
1.1.1.17 root 4191: if (TYPE_ALIGN (DECL_ARG_TYPE (parm)) > boundary)
4192: boundary = TYPE_ALIGN (DECL_ARG_TYPE (parm));
1.1.1.16 root 4193: if (boundary > MAX_PARM_BOUNDARY)
4194: boundary = MAX_PARM_BOUNDARY;
4195:
4196: /* If the previous args don't reach such a boundary,
4197: advance to the next one. */
1.1.1.17 root 4198: boundary /= BITS_PER_UNIT;
1.1.1.16 root 4199: stack_offset.constant += boundary - 1;
1.1.1.17 root 4200: stack_offset.constant &= ~(boundary - 1);
4201: stack_args_size.constant += boundary - 1;
4202: stack_args_size.constant &= ~(boundary - 1);
1.1.1.16 root 4203:
4204: if (stack_offset.var != 0)
4205: abort (); /* This case not implemented yet */
4206: }
4207: #endif /* MAX_PARM_BOUNDARY */
4208:
4209: /* Find out if the parm needs intrinsic padding (up to PARM_BOUNDARY),
4210: and whether above or below. */
4211:
1.1.1.6 root 4212: where_pad
4213: = FUNCTION_ARG_PADDING (passed_mode,
4214: expand_expr (size_in_bytes (DECL_ARG_TYPE (parm)),
4215: 0, VOIDmode, 0));
4216:
1.1.1.16 root 4217: /* If arg should be padded below, adjust the stack address upward.
4218: This padding is considered part of the space occupied by the
4219: argument. It pads only up to PARM_BOUNDARY, and it does not
4220: depend on the previous arguments, since they are assumed to
4221: occupy a multiple of PARM_BOUNDARY. */
4222:
1.1.1.6 root 4223: if (where_pad == downward)
4224: {
4225: if (passed_mode != BLKmode)
4226: {
4227: if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
4228: stack_offset.constant
4229: += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
4230: / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
4231: - GET_MODE_SIZE (passed_mode));
4232: }
4233: else
4234: {
4235: tree sizetree = size_in_bytes (DECL_ARG_TYPE (parm));
4236: /* Round the size up to multiple of PARM_BOUNDARY bits. */
4237: tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
4238: tree s2 = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
4239: /* Add it in. */
4240: ADD_PARM_SIZE (stack_offset, s2);
4241: SUB_PARM_SIZE (stack_offset, sizetree);
4242: }
4243: }
4244:
1.1.1.2 root 4245: /* Let machine desc say which reg (if any) the parm arrives in.
4246: 0 means it arrives on the stack. */
4247: entry_parm = 0;
4248: /* Variable-size args, and args following such, are never in regs. */
4249: if (TREE_CODE (TYPE_SIZE (TREE_TYPE (parm))) == INTEGER_CST
4250: || stack_offset.var != 0)
4251: {
1.1.1.17 root 4252: /* Set LAST_NAMED if this is last named arg before some
4253: anonymous args. We treat it as if it were anonymous too. */
4254: int last_named = (TREE_CHAIN (parm) == 0 && vararg);
1.1.1.2 root 4255: #ifdef FUNCTION_INCOMING_ARG
4256: entry_parm
4257: = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
1.1.1.17 root 4258: DECL_ARG_TYPE (parm), ! last_named);
1.1.1.2 root 4259: #else
4260: entry_parm
1.1.1.17 root 4261: = FUNCTION_ARG (args_so_far, passed_mode, DECL_ARG_TYPE (parm),
4262: ! last_named);
1.1.1.2 root 4263: #endif
4264: }
1.1.1.17 root 4265:
1.1.1.19 root 4266: #ifdef REG_PARM_STACK_SPACE
4267: /* If we arrive at a stack parm while still counting space for reg parms,
4268: skip up to the offset for the first stack parm. */
4269: if (entry_parm == 0
4270: && stack_args_size.constant + first_parm_caller_offset < 0)
4271: {
4272: int adjustment
4273: = -(stack_args_size.constant + first_parm_caller_offset);
4274: stack_args_size.constant += adjustment;
4275: stack_offset.constant += adjustment;
4276: }
4277: #endif
4278:
4279: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
4280:
4281: /* Determine parm's home in the stack,
4282: in case it arrives in the stack or we should pretend it did. */
4283: /* Note that this is not necessarily a valid address.
4284: We make it valid later when it is used.
4285: It is necessary for the DECL_RTL to be an explicit stack slot,
4286: but not necessary for it to be valid. */
4287: stack_parm
4288: = gen_rtx (MEM, passed_mode,
4289: gen_rtx (PLUS, Pmode,
4290: internal_arg_pointer,
4291: stack_offset_rtx));
4292:
4293: /* If this is a memory ref that contains aggregate components,
4294: mark it as such for cse and loop optimize. */
4295: MEM_IN_STRUCT_P (stack_parm) = aggregate;
4296:
1.1.1.2 root 4297: /* If this parm was passed part in regs and part in memory,
4298: pretend it arrived entirely in memory
4299: by pushing the register-part onto the stack.
4300:
4301: In the special case of a DImode or DFmode that is split,
4302: we could put it together in a pseudoreg directly,
4303: but for now that's not worth bothering with. */
4304:
1.1.1.17 root 4305: if (entry_parm)
4306: {
4307: int nregs = 0;
4308: int i;
1.1.1.2 root 4309: #ifdef FUNCTION_ARG_PARTIAL_NREGS
1.1.1.17 root 4310: nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
4311: DECL_ARG_TYPE (parm), 1);
1.1.1.2 root 4312: #endif
4313:
1.1.1.17 root 4314: #if 0 /* Replaced by new calling convention
4315: which actually passes these args on the stack. */
4316: /* If this is the last named arg and anonymous args follow,
4317: likewise pretend this arg arrived on the stack
4318: so varargs can find the anonymous args following it. */
4319: if (TREE_CHAIN (parm) == 0 && vararg)
4320: {
4321: if (GET_MODE (entry_parm) == BLKmode)
4322: nregs = GET_MODE_SIZE (GET_MODE (entry_parm)) / UNITS_PER_WORD;
4323: else
4324: nregs = (int_size_in_bytes (DECL_ARG_TYPE (parm))
4325: / UNITS_PER_WORD);
4326: }
4327: #endif /* 0 */
4328:
4329: if (nregs > 0)
4330: {
1.1.1.19 root 4331: rtx valid_stack_parm = validize_mem (stack_parm);
1.1.1.17 root 4332: current_function_pretend_args_size
4333: = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
4334: / (PARM_BOUNDARY / BITS_PER_UNIT)
4335: * (PARM_BOUNDARY / BITS_PER_UNIT));
4336:
4337: i = nregs;
4338: while (--i >= 0)
4339: emit_move_insn (gen_rtx (MEM, SImode,
1.1.1.19 root 4340: plus_constant (XEXP (valid_stack_parm, 0),
1.1.1.17 root 4341: i * GET_MODE_SIZE (SImode))),
4342: gen_rtx (REG, SImode, REGNO (entry_parm) + i));
4343: entry_parm = stack_parm;
4344: }
4345: }
1.1.1.2 root 4346:
1.1.1.4 root 4347: /* If we didn't decide this parm came in a register,
4348: by default it came on the stack. */
1.1.1.2 root 4349: if (entry_parm == 0)
4350: entry_parm = stack_parm;
4351:
1.1.1.4 root 4352: /* For a stack parm, record in DECL_OFFSET the arglist offset
4353: of the parm at the time it is passed (before conversion). */
1.1.1.2 root 4354: if (entry_parm == stack_parm)
1.1.1.4 root 4355: DECL_OFFSET (parm) = stack_offset.constant * BITS_PER_UNIT;
4356:
4357: /* If there is actually space on the stack for this parm,
4358: count it in stack_args_size; otherwise set stack_parm to 0
4359: to indicate there is no preallocated stack slot for the parm. */
4360:
4361: if (entry_parm == stack_parm
4362: #ifdef REG_PARM_STACK_SPACE
4363: /* On some machines, even if a parm value arrives in a register
4364: there is still an (uninitialized) stack slot allocated for it. */
4365: || 1
4366: #endif
4367: )
1.1.1.2 root 4368: {
4369: tree sizetree = size_in_bytes (DECL_ARG_TYPE (parm));
1.1.1.19 root 4370: #ifdef PUSH_ROUNDING
4371: /* If this arg will be pushed with a push instruction,
4372: note how that will add to its size. */
4373: if (DECL_MODE (parm) != BLKmode)
4374: {
4375: int old_bytes = int_size_in_bytes (DECL_ARG_TYPE (parm));
4376: sizetree = build_int_2 (PUSH_ROUNDING (old_bytes), 0);
4377: }
4378: #endif
1.1.1.6 root 4379: if (where_pad != none)
4380: {
4381: /* Round the size up to multiple of PARM_BOUNDARY bits. */
4382: tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
4383: sizetree = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
4384: }
1.1.1.2 root 4385: /* Add it in. */
1.1.1.6 root 4386: ADD_PARM_SIZE (stack_args_size, sizetree);
1.1.1.2 root 4387: }
1.1.1.4 root 4388: else
4389: /* No stack slot was pushed for this parm. */
4390: stack_parm = 0;
1.1.1.2 root 4391:
1.1.1.4 root 4392: /* Now adjust STACK_PARM to the mode and precise location
1.1.1.2 root 4393: where this parameter should live during execution,
4394: if we discover that it must live in the stack during execution.
4395: To make debuggers happier on big-endian machines, we store
4396: the value in the last bytes of the space available. */
4397:
1.1.1.4 root 4398: if (nominal_mode != BLKmode && nominal_mode != passed_mode
4399: && stack_parm != 0)
1.1.1.2 root 4400: {
4401: #ifdef BYTES_BIG_ENDIAN
1.1.1.6 root 4402: if (GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
4403: {
4404: stack_offset.constant
4405: += GET_MODE_SIZE (passed_mode)
4406: - GET_MODE_SIZE (nominal_mode);
4407: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
4408: }
1.1.1.2 root 4409: #endif
4410:
4411: stack_parm
4412: = gen_rtx (MEM, nominal_mode,
1.1.1.19 root 4413: gen_rtx (PLUS, Pmode,
4414: arg_pointer_rtx,
4415: stack_offset_rtx));
1.1.1.2 root 4416:
4417: /* If this is a memory ref that contains aggregate components,
4418: mark it as such for cse and loop optimize. */
1.1.1.10 root 4419: MEM_IN_STRUCT_P (stack_parm) = aggregate;
1.1.1.2 root 4420: }
4421:
4422: /* ENTRY_PARM is an RTX for the parameter as it arrives,
4423: in the mode in which it arrives.
1.1.1.4 root 4424: STACK_PARM is an RTX for a stack slot where the parameter can live
4425: during the function (in case we want to put it there).
4426: STACK_PARM is 0 if no stack slot was pushed for it.
1.1 root 4427:
1.1.1.4 root 4428: Now output code if necessary to convert ENTRY_PARM to
1.1 root 4429: the type in which this function declares it,
1.1.1.4 root 4430: and store that result in an appropriate place,
4431: which may be a pseudo reg, may be STACK_PARM,
4432: or may be a local stack slot if STACK_PARM is 0.
4433:
4434: Set DECL_RTL to that place. */
1.1.1.2 root 4435:
4436: if (nominal_mode == BLKmode)
4437: {
4438: /* If a BLKmode arrives in registers, copy it to a stack slot. */
1.1.1.4 root 4439: if (GET_CODE (entry_parm) == REG)
1.1.1.2 root 4440: {
1.1.1.19 root 4441: #if 0 /* This was probably wrong, but save it just in case. */
4442: rtx unpadded_stack_parm;
4443:
4444: /* Determine parm's home in the stack. */
4445:
4446: if (stack_parm == 0)
4447: unpadded_stack_parm
4448: = assign_stack_local (GET_MODE (entry_parm),
4449: int_size_in_bytes (TREE_TYPE (parm)));
4450: else
4451: unpadded_stack_parm
4452: = gen_rtx (MEM, passed_mode,
4453: memory_address (passed_mode,
4454: gen_rtx (PLUS, Pmode,
4455: internal_arg_pointer,
4456: ARGS_SIZE_RTX (unpadded_stack_offset))));
4457:
4458: /* Here we use unpadded_stack_parm because we assume
4459: that downward padding is used on big-endian machines
4460: where we would want to make the real data in the reg
4461: (which is in the low bits) end up at the padded address. */
4462: #endif
1.1.1.4 root 4463: if (stack_parm == 0)
4464: stack_parm
4465: = assign_stack_local (GET_MODE (entry_parm),
4466: int_size_in_bytes (TREE_TYPE (parm)));
1.1.1.2 root 4467:
1.1.1.19 root 4468: move_block_from_reg (REGNO (entry_parm),
4469: validize_mem (stack_parm),
1.1.1.18 root 4470: ((int_size_in_bytes (TREE_TYPE (parm))
4471: + UNITS_PER_WORD - 1)
1.1.1.22! root 4472: / UNITS_PER_WORD),
! 4473: TYPE_ALIGN (TREE_TYPE (parm)));
1.1.1.2 root 4474: }
4475: DECL_RTL (parm) = stack_parm;
4476: }
1.1.1.10 root 4477: else if (! ((obey_regdecls && ! TREE_REGDECL (parm)
4478: && ! TREE_INLINE (fndecl))
1.1.1.14 root 4479: /* layout_decl may set this. */
4480: || TREE_ADDRESSABLE (parm)
1.1.1.15 root 4481: || TREE_VOLATILE (parm)
1.1.1.2 root 4482: /* If -ffloat-store specified, don't put explicit
4483: float variables into registers. */
4484: || (flag_float_store
4485: && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)))
1.1 root 4486: {
1.1.1.2 root 4487: /* Store the parm in a pseudoregister during the function. */
4488: register rtx parmreg = gen_reg_rtx (nominal_mode);
1.1 root 4489:
1.1.1.10 root 4490: REG_USERVAR_P (parmreg) = 1;
1.1 root 4491: DECL_RTL (parm) = parmreg;
4492:
4493: /* Copy the value into the register. */
1.1.1.2 root 4494: if (GET_MODE (parmreg) != GET_MODE (entry_parm))
1.1.1.18 root 4495: convert_move (parmreg, validize_mem (entry_parm), 0);
1.1 root 4496: else
1.1.1.18 root 4497: emit_move_insn (parmreg, validize_mem (entry_parm));
1.1.1.2 root 4498:
4499: /* In any case, record the parm's desired stack location
4500: in case we later discover it must live in the stack. */
4501: if (REGNO (parmreg) >= nparmregs)
4502: {
4503: rtx *new;
4504: nparmregs = REGNO (parmreg) + 5;
4505: new = (rtx *) oballoc (nparmregs * sizeof (rtx));
4506: bcopy (parm_reg_stack_loc, new, nparmregs * sizeof (rtx));
4507: parm_reg_stack_loc = new;
4508: }
4509: parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
1.1 root 4510:
1.1.1.2 root 4511: /* Mark the register as eliminable if we did no conversion
1.1.1.17 root 4512: and it was copied from memory at a fixed offset,
4513: and the arg pointer was not copied to a pseudo-reg.
4514: If the arg pointer is a pseudo reg, such memory-equivalences
4515: as we make here would screw up life analysis for it. */
1.1.1.2 root 4516: if (nominal_mode == passed_mode
4517: && GET_CODE (entry_parm) == MEM
1.1.1.17 root 4518: && stack_offset.var == 0
4519: && ! arg_pointer_copied)
1.1.1.10 root 4520: REG_NOTES (get_last_insn ())
4521: = gen_rtx (EXPR_LIST, REG_EQUIV,
4522: entry_parm, REG_NOTES (get_last_insn ()));
1.1 root 4523:
4524: /* For pointer data type, suggest pointer register. */
4525: if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
4526: mark_reg_pointer (parmreg);
4527: }
1.1.1.2 root 4528: else
1.1 root 4529: {
1.1.1.2 root 4530: /* Value must be stored in the stack slot STACK_PARM
4531: during function execution. */
4532:
4533: if (passed_mode != nominal_mode)
4534: /* Conversion is required. */
1.1.1.19 root 4535: entry_parm = convert_to_mode (nominal_mode,
4536: validize_mem (entry_parm), 0);
1.1.1.2 root 4537:
4538: if (entry_parm != stack_parm)
4539: {
4540: if (stack_parm == 0)
4541: stack_parm = assign_stack_local (GET_MODE (entry_parm),
4542: GET_MODE_SIZE (GET_MODE (entry_parm)));
1.1.1.18 root 4543: emit_move_insn (validize_mem (stack_parm),
4544: validize_mem (entry_parm));
1.1.1.2 root 4545: }
4546:
4547: DECL_RTL (parm) = stack_parm;
4548: frame_pointer_needed = 1;
1.1 root 4549: }
1.1.1.2 root 4550:
4551: if (TREE_VOLATILE (parm))
1.1.1.10 root 4552: MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
1.1.1.2 root 4553: if (TREE_READONLY (parm))
1.1.1.10 root 4554: RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
1.1.1.2 root 4555:
4556: /* Update info on where next arg arrives in registers. */
4557:
4558: FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, DECL_ARG_TYPE (parm), 1);
1.1 root 4559: }
1.1.1.4 root 4560:
1.1 root 4561: max_parm_reg = max_reg_num ();
1.1.1.2 root 4562: last_parm_insn = get_last_insn ();
4563:
4564: current_function_args_size = stack_args_size.constant;
1.1.1.19 root 4565:
4566: stack_args_size.constant += first_parm_offset;
4567: current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
1.1 root 4568: }
4569:
4570: /* Allocation of space for returned structure values.
4571: During the rtl generation pass, `get_structure_value_addr'
4572: is called from time to time to request the address of a block in our
4573: stack frame in which called functions will store the structures
4574: they are returning. The same space is used for all of these blocks.
4575:
1.1.1.2 root 4576: We allocate these blocks like stack locals. We keep reusing
4577: the same block until a bigger one is needed. */
4578:
4579: /* Length in bytes of largest structure value returned by
4580: any function called so far in this function. */
4581: static int max_structure_value_size;
1.1 root 4582:
1.1.1.2 root 4583: /* An rtx for the addr we are currently using for structure values.
4584: This is typically (PLUS (REG:SI stackptr) (CONST_INT...)). */
4585: static rtx structure_value;
1.1 root 4586:
4587: rtx
4588: get_structure_value_addr (sizex)
4589: rtx sizex;
4590: {
4591: register int size;
4592: if (GET_CODE (sizex) != CONST_INT)
4593: abort ();
4594: size = INTVAL (sizex);
4595:
4596: /* Round up to a multiple of the main allocation unit. */
4597: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
4598: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
4599: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
4600:
1.1.1.2 root 4601: /* If this size is bigger than space we know to use,
4602: get a bigger piece of space. */
1.1 root 4603: if (size > max_structure_value_size)
4604: {
4605: max_structure_value_size = size;
1.1.1.2 root 4606: structure_value = assign_stack_local (BLKmode, size);
4607: if (GET_CODE (structure_value) == MEM)
4608: structure_value = XEXP (structure_value, 0);
1.1 root 4609: }
1.1.1.2 root 4610:
4611: return structure_value;
1.1 root 4612: }
1.1.1.19 root 4613:
4614: /* Push and pop the current structure value block. */
4615:
4616: void
4617: push_structure_value (rtx_ptr, size_ptr)
4618: rtx *rtx_ptr;
4619: int *size_ptr;
4620: {
4621: *rtx_ptr = structure_value;
4622: *size_ptr = max_structure_value_size;
4623: max_structure_value_size = 0;
4624: structure_value = 0;
4625: }
4626:
4627: void
4628: pop_structure_value (rtx_value, size)
4629: rtx rtx_value;
4630: int size;
4631: {
4632: structure_value = rtx_value;
4633: max_structure_value_size = size;
4634: }
4635:
1.1.1.2 root 4636:
4637: /* Walk the tree of LET_STMTs describing the binding levels within a function
4638: and warn about uninitialized variables.
4639: This is done after calling flow_analysis and before global_alloc
4640: clobbers the pseudo-regs to hard regs. */
1.1 root 4641:
1.1.1.2 root 4642: void
4643: uninitialized_vars_warning (block)
4644: tree block;
1.1 root 4645: {
1.1.1.2 root 4646: register tree decl, sub;
4647: for (decl = STMT_VARS (block); decl; decl = TREE_CHAIN (decl))
4648: {
4649: if (TREE_CODE (decl) == VAR_DECL
4650: /* These warnings are unreliable for and aggregates
4651: because assigning the fields one by one can fail to convince
4652: flow.c that the entire aggregate was initialized.
4653: Unions are troublesome because members may be shorter. */
4654: && TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE
4655: && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE
4656: && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
1.1.1.17 root 4657: && DECL_RTL (decl) != 0
1.1.1.2 root 4658: && GET_CODE (DECL_RTL (decl)) == REG
4659: && regno_uninitialized (REGNO (DECL_RTL (decl))))
4660: warning_with_decl (decl,
1.1.1.15 root 4661: "`%s' may be used uninitialized in this function");
1.1.1.2 root 4662: if (TREE_CODE (decl) == VAR_DECL
1.1.1.17 root 4663: && DECL_RTL (decl) != 0
1.1.1.2 root 4664: && GET_CODE (DECL_RTL (decl)) == REG
4665: && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
4666: warning_with_decl (decl,
4667: "variable `%s' may be clobbered by `longjmp'");
4668: }
1.1.1.17 root 4669: for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
1.1.1.2 root 4670: uninitialized_vars_warning (sub);
1.1 root 4671: }
1.1.1.11 root 4672:
4673: /* If this function call setjmp, put all vars into the stack
4674: unless they were declared `register'. */
4675:
4676: void
4677: setjmp_protect (block)
4678: tree block;
4679: {
4680: register tree decl, sub;
4681: for (decl = STMT_VARS (block); decl; decl = TREE_CHAIN (decl))
4682: if ((TREE_CODE (decl) == VAR_DECL
4683: || TREE_CODE (decl) == PARM_DECL)
4684: && DECL_RTL (decl) != 0
4685: && GET_CODE (DECL_RTL (decl)) == REG
4686: && ! TREE_REGDECL (decl))
4687: put_var_into_stack (decl);
1.1.1.17 root 4688: for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
1.1.1.11 root 4689: setjmp_protect (sub);
4690: }
1.1 root 4691:
1.1.1.17 root 4692: /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
1.1.1.2 root 4693: and initialize static variables for generating RTL for the statements
4694: of the function. */
1.1 root 4695:
1.1.1.2 root 4696: void
1.1.1.19 root 4697: init_function_start (subr, filename, line)
1.1 root 4698: tree subr;
1.1.1.19 root 4699: char *filename;
4700: int line;
1.1 root 4701: {
4702: this_function = subr;
1.1.1.2 root 4703: cse_not_expected = ! optimize;
4704:
4705: /* We have not yet found a reason why a frame pointer cannot
4706: be omitted for this function in particular, but maybe we know
4707: a priori that it is required.
4708: `flag_omit_frame_pointer' has its main effect here. */
4709: frame_pointer_needed = FRAME_POINTER_REQUIRED || ! flag_omit_frame_pointer;
1.1 root 4710:
1.1.1.17 root 4711: /* Caller save not needed yet. */
4712: caller_save_needed = 0;
4713:
1.1.1.2 root 4714: /* No gotos have been expanded yet. */
4715: goto_fixup_chain = 0;
1.1 root 4716:
1.1.1.13 root 4717: /* No stack slots have been made yet. */
4718: stack_slot_list = 0;
4719:
1.1.1.2 root 4720: /* No invalid stack slots have been made yet. */
4721: invalid_stack_slot = 0;
4722:
1.1.1.18 root 4723: /* No parm regs have been allocated.
4724: (This is important for output_inline_function.) */
4725: max_parm_reg = FIRST_PSEUDO_REGISTER;
4726:
1.1.1.2 root 4727: /* Initialize the RTL mechanism. */
4728: init_emit (write_symbols);
4729:
4730: /* Initialize the queue of pending postincrement and postdecrements,
4731: and some other info in expr.c. */
4732: init_expr ();
4733:
4734: init_const_rtx_hash_table ();
4735:
4736: /* Decide whether function should try to pop its args on return. */
4737:
4738: current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (subr));
4739:
1.1.1.17 root 4740: current_function_name = DECL_PRINT_NAME (subr);
1.1.1.2 root 4741:
1.1.1.10 root 4742: /* Nonzero if this is a nested function that uses a static chain. */
4743:
1.1.1.13 root 4744: current_function_needs_context
4745: = (DECL_CONTEXT (current_function_decl) != 0
4746: && TREE_CODE (DECL_CONTEXT (current_function_decl)) == LET_STMT);
1.1.1.10 root 4747:
1.1.1.11 root 4748: /* Set if a call to setjmp is seen. */
4749:
4750: current_function_calls_setjmp = 0;
1.1.1.17 root 4751: current_function_calls_alloca = 0;
1.1.1.11 root 4752:
1.1.1.15 root 4753: current_function_returns_pcc_struct = 0;
4754: current_function_returns_struct = 0;
1.1.1.10 root 4755:
1.1.1.2 root 4756: /* No space assigned yet for structure values. */
1.1.1.19 root 4757: max_structure_value_size = -1;
1.1.1.2 root 4758: structure_value = 0;
1.1 root 4759:
1.1.1.2 root 4760: /* We are not currently within any block, conditional, loop or case. */
1.1 root 4761: block_stack = 0;
1.1.1.2 root 4762: loop_stack = 0;
4763: case_stack = 0;
4764: cond_stack = 0;
4765: nesting_stack = 0;
4766: nesting_depth = 0;
4767:
1.1.1.19 root 4768: block_start_count = 0;
4769:
1.1.1.2 root 4770: /* We have not yet needed to make a label to jump to for tail-recursion. */
1.1 root 4771: tail_recursion_label = 0;
4772:
1.1.1.2 root 4773: /* No stack slots allocated yet. */
4774: frame_offset = STARTING_FRAME_OFFSET;
4775:
1.1.1.5 root 4776: /* No SAVE_EXPRs in this function yet. */
4777: save_expr_regs = 0;
4778:
1.1.1.10 root 4779: /* No RTL_EXPRs in this function yet. */
4780: rtl_expr_chain = 0;
4781:
1.1.1.4 root 4782: /* Within function body, compute a type's size as soon it is laid out. */
4783: immediate_size_expand++;
4784:
1.1.1.2 root 4785: init_pending_stack_adjust ();
1.1.1.17 root 4786: inhibit_defer_pop = 0;
1.1.1.7 root 4787: current_function_pretend_args_size = 0;
1.1 root 4788:
4789: /* Prevent ever trying to delete the first instruction of a function.
4790: Also tell final how to output a linenum before the function prologue. */
1.1.1.19 root 4791: emit_line_note (filename, line);
1.1 root 4792: /* Make sure first insn is a note even if we don't want linenums.
4793: This makes sure the first insn will never be deleted.
4794: Also, final expects a note to appear there. */
4795: emit_note (0, NOTE_INSN_DELETED);
1.1.1.17 root 4796: /* Indicate the beginning of the function body,
4797: as opposed to parm setup. */
4798: emit_note (0, NOTE_INSN_FUNCTION_BEG);
1.1 root 4799:
1.1.1.17 root 4800: /* Set flags used by final.c. */
4801: if (aggregate_value_p (DECL_RESULT (subr)))
4802: {
4803: #ifdef PCC_STATIC_STRUCT_RETURN
4804: if (flag_pcc_struct_return)
4805: current_function_returns_pcc_struct = 1;
4806: else
4807: #endif
4808: current_function_returns_struct = 1;
4809: }
4810: }
1.1 root 4811:
1.1.1.17 root 4812: /* Start the RTL for a new function, and set variables used for
4813: emitting RTL.
4814: SUBR is the FUNCTION_DECL node.
4815: PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
4816: the function's parameters, which must be run at any return statement. */
4817:
4818: void
4819: expand_function_start (subr, parms_have_cleanups)
4820: tree subr;
4821: int parms_have_cleanups;
4822: {
4823: register int i;
4824: tree tem;
4825:
1.1.1.18 root 4826: /* Make sure volatile mem refs aren't considered
4827: valid operands of arithmetic insns. */
4828: init_recog ();
4829:
1.1.1.17 root 4830: /* If the parameters of this function need cleaning up, get a label
4831: for the beginning of the code which executes those cleanups. This must
4832: be done before doing anything with return_label. */
4833: if (parms_have_cleanups)
4834: cleanup_label = gen_label_rtx ();
4835: else
4836: cleanup_label = 0;
4837:
4838: /* Make the label for return statements to jump to, if this machine
4839: does not have a one-instruction return and uses an epilogue,
4840: or if it returns a structure, or if it has parm cleanups. */
4841: #ifdef HAVE_return
4842: if (cleanup_label == 0 && HAVE_return
4843: && ! current_function_returns_pcc_struct
4844: && ! (current_function_returns_struct && ! optimize))
4845: return_label = 0;
4846: else
4847: return_label = gen_label_rtx ();
4848: #else
4849: return_label = gen_label_rtx ();
4850: #endif
1.1.1.2 root 4851:
1.1 root 4852: /* Initialize rtx used to return the value. */
1.1.1.17 root 4853: /* Do this before assign_parms so that we copy the struct value address
4854: before any library calls that assign parms might generate. */
1.1 root 4855:
1.1.1.15 root 4856: /* Decide whether to return the value in memory or in a register. */
1.1.1.17 root 4857: if (aggregate_value_p (DECL_RESULT (subr)))
1.1 root 4858: {
4859: /* Returning something that won't go in a register. */
4860: register rtx value_address;
4861:
1.1.1.15 root 4862: #ifdef PCC_STATIC_STRUCT_RETURN
4863: if (flag_pcc_struct_return)
4864: {
4865: int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
4866: value_address = assemble_static_space (size);
4867: current_function_returns_pcc_struct = 1;
4868: }
4869: else
4870: #endif
4871: {
4872: /* Expect to be passed the address of a place to store the value. */
4873: value_address = gen_reg_rtx (Pmode);
4874: emit_move_insn (value_address, struct_value_incoming_rtx);
4875: current_function_returns_struct = 1;
4876: }
1.1 root 4877: DECL_RTL (DECL_RESULT (subr))
4878: = gen_rtx (MEM, DECL_MODE (DECL_RESULT (subr)),
4879: value_address);
4880: }
1.1.1.17 root 4881: else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
4882: /* If return mode is void, this decl rtl should not be used. */
4883: DECL_RTL (DECL_RESULT (subr)) = 0;
4884: else if (parms_have_cleanups)
4885: /* If function will end with cleanup code for parms,
4886: compute the return values into a pseudo reg,
4887: which we will copy into the true return register
4888: after the cleanups are done. */
4889: DECL_RTL (DECL_RESULT (subr))
4890: = gen_reg_rtx (DECL_MODE (DECL_RESULT (subr)));
1.1 root 4891: else
1.1.1.15 root 4892: /* Scalar, returned in a register. */
1.1.1.17 root 4893: {
1.1.1.2 root 4894: #ifdef FUNCTION_OUTGOING_VALUE
1.1.1.17 root 4895: DECL_RTL (DECL_RESULT (subr))
4896: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
1.1.1.2 root 4897: #else
1.1.1.17 root 4898: DECL_RTL (DECL_RESULT (subr))
4899: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
1.1.1.2 root 4900: #endif
1.1.1.6 root 4901:
1.1.1.17 root 4902: current_function_returns_pointer
4903: = (TREE_CODE (DECL_RESULT_TYPE (subr)) == POINTER_TYPE);
1.1.1.8 root 4904:
1.1.1.17 root 4905: /* Mark this reg as the function's return value. */
4906: if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
4907: REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
4908: }
4909:
4910: /* Initialize rtx for parameters and local variables.
4911: In some cases this requires emitting insns. */
4912:
4913: assign_parms (subr);
1.1.1.16 root 4914:
1.1.1.10 root 4915: /* If doing stupid allocation, mark parms as born here. */
4916:
1.1.1.17 root 4917: if (GET_CODE (get_last_insn ()) != NOTE)
4918: emit_note (0, NOTE_INSN_DELETED);
4919: parm_birth_insn = get_last_insn ();
4920:
1.1.1.10 root 4921: if (obey_regdecls)
4922: {
4923: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
4924: use_variable (regno_reg_rtx[i]);
4925: }
4926:
1.1.1.8 root 4927: /* After the parm initializations is where the tail-recursion label
4928: should go, if we end up needing one. */
4929: tail_recursion_reentry = get_last_insn ();
4930:
4931: /* Evaluate now the sizes of any types declared among the arguments. */
4932: for (tem = get_pending_sizes (); tem; tem = TREE_CHAIN (tem))
4933: expand_expr (TREE_VALUE (tem), 0, VOIDmode, 0);
1.1.1.17 root 4934:
4935: /* Make sure there is a line number after the function entry setup code.
4936: There normally is one anyway, from the following statement,
4937: but there could fail to be one if there is no newline here. */
4938: force_next_line_note ();
1.1.1.2 root 4939: }
1.1 root 4940:
1.1.1.6 root 4941: /* Generate RTL for the end of the current function.
1.1.1.13 root 4942: FILENAME and LINE are the current position in the source file. */
1.1 root 4943:
1.1.1.17 root 4944: /* ??? Nobody seems to emit the cleanup_label and the cleanups themselves. */
4945:
1.1.1.2 root 4946: void
1.1.1.6 root 4947: expand_function_end (filename, line)
4948: char *filename;
4949: int line;
1.1.1.2 root 4950: {
4951: register int i;
1.1.1.17 root 4952: rtx decl;
1.1.1.13 root 4953: extern rtx sequence_stack;
4954:
1.1.1.17 root 4955: #if 0 /* I think unused parms are legitimate enough. */
4956: /* Warn about unused parms. */
4957: if (warn_unused)
4958: for (decl = DECL_ARGUMENTS (current_function_decl);
4959: decl; decl = TREE_CHAIN (decl))
4960: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
4961: warning_with_decl (decl, "unused parameter `%s'");
4962: #endif
4963:
1.1.1.13 root 4964: /* End any sequences that failed to be closed due to syntax errors. */
4965: while (sequence_stack)
4966: end_sequence (0);
1.1 root 4967:
1.1.1.4 root 4968: /* Outside function body, can't compute type's actual size
4969: until next function's body starts. */
4970: immediate_size_expand--;
4971:
1.1 root 4972: /* If doing stupid register allocation,
1.1.1.2 root 4973: mark register parms as dying here. */
4974:
1.1 root 4975: if (obey_regdecls)
1.1.1.5 root 4976: {
4977: rtx tem;
4978: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
4979: use_variable (regno_reg_rtx[i]);
4980:
4981: /* Likewise for the regs of all the SAVE_EXPRs in the function. */
4982:
4983: for (tem = save_expr_regs; tem; tem = XEXP (tem, 1))
1.1.1.13 root 4984: {
4985: /* ??? Tiemann thinks this does not work. */
4986: use_variable (XEXP (tem, 0));
4987: use_variable_after (XEXP (tem, 0), parm_birth_insn);
4988: }
1.1.1.5 root 4989: }
1.1 root 4990:
4991: clear_pending_stack_adjust ();
1.1.1.2 root 4992: do_pending_stack_adjust ();
1.1 root 4993:
1.1.1.2 root 4994: /* Mark the end of the function body.
4995: If control reaches this insn, the function can drop through
4996: without returning a value. */
4997: emit_note (0, NOTE_INSN_FUNCTION_END);
4998:
1.1.1.6 root 4999: /* Output a linenumber for the end of the function.
5000: SDB depends on this. */
1.1.1.13 root 5001: emit_line_note_force (filename, line);
1.1.1.6 root 5002:
1.1.1.17 root 5003: /* Output the label for the actual return from the function,
5004: if one is expected. This happens either because a function epilogue
5005: is used instead of a return instruction, or because a return was done
5006: with a goto in order to run local cleanups, or because of pcc-style
5007: structure returning. */
5008:
5009: if (return_label)
1.1.1.8 root 5010: emit_label (return_label);
1.1.1.6 root 5011:
1.1.1.17 root 5012: /* If we had calls to alloca, and this machine needs
5013: an accurate stack pointer to exit the function,
5014: insert some code to save and restore the stack pointer. */
5015: #ifdef EXIT_IGNORE_STACK
5016: if (! EXIT_IGNORE_STACK)
5017: #endif
5018: if (current_function_calls_alloca)
5019: {
5020: rtx tem = gen_reg_rtx (Pmode);
5021: emit_insn_after (gen_rtx (SET, VOIDmode, tem, stack_pointer_rtx),
5022: parm_birth_insn);
5023: emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx, tem));
5024: }
5025:
5026: /* If scalar return value was computed in a pseudo-reg,
5027: copy that to the hard return register. */
5028: if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
5029: && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
5030: && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
5031: >= FIRST_PSEUDO_REGISTER))
5032: {
5033: rtx real_decl_result;
5034:
5035: #ifdef FUNCTION_OUTGOING_VALUE
5036: real_decl_result
5037: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
5038: current_function_decl);
5039: #else
5040: real_decl_result
5041: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
5042: current_function_decl);
5043: #endif
5044: REG_FUNCTION_VALUE_P (real_decl_result) = 1;
5045: emit_move_insn (real_decl_result,
5046: DECL_RTL (DECL_RESULT (current_function_decl)));
5047: emit_insn (gen_rtx (USE, VOIDmode, real_decl_result));
5048: }
5049:
5050: /* If returning a structure, arrange to return the address of the value
5051: in a place where debuggers expect to find it. */
1.1.1.15 root 5052: /* If returning a structure PCC style,
1.1.1.17 root 5053: the caller also depends on this value.
5054: And current_function_returns_pcc_struct is not necessarily set. */
5055: if (current_function_returns_struct
5056: || current_function_returns_pcc_struct)
1.1.1.15 root 5057: {
5058: rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5059: tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
1.1.1.18 root 5060: #ifdef FUNCTION_OUTGOING_VALUE
5061: rtx outgoing
5062: = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
5063: current_function_decl);
5064: #else
1.1.1.15 root 5065: rtx outgoing
5066: = hard_function_value (build_pointer_type (type),
5067: current_function_decl);
1.1.1.18 root 5068: #endif
1.1.1.15 root 5069:
1.1.1.17 root 5070: REG_FUNCTION_VALUE_P (outgoing) = 1;
1.1.1.15 root 5071: emit_move_insn (outgoing, value_address);
5072: use_variable (outgoing);
1.1.1.17 root 5073: }
5074:
5075: /* Output a return insn if we are using one.
5076: Otherwise, let the rtl chain end here, to drop through
5077: into the epilogue. */
1.1.1.16 root 5078:
5079: #ifdef HAVE_return
1.1.1.17 root 5080: if (HAVE_return)
5081: emit_jump_insn (gen_return ());
1.1.1.16 root 5082: #endif
1.1.1.15 root 5083:
1.1.1.6 root 5084: /* Fix up any gotos that jumped out to the outermost
5085: binding level of the function.
5086: Must follow emitting RETURN_LABEL. */
1.1.1.8 root 5087:
5088: /* If you have any cleanups to do at this point,
5089: and they need to create temporary variables,
5090: then you will lose. */
1.1.1.14 root 5091: fixup_gotos (0, 0, 0, get_insns (), 0);
1.1 root 5092: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.