|
|
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. */
157: static int frame_offset;
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.17 root 1133: OK_DEFER_POP;
1.1.1.16 root 1134:
1.1.1.2 root 1135: if (last_expr_type == 0)
1136: {
1137: last_expr_type = void_type_node;
1138: last_expr_value = const0_rtx;
1139: }
1.1.1.7 root 1140: TREE_TYPE (t) = last_expr_type;
1.1.1.2 root 1141: RTL_EXPR_RTL (t) = last_expr_value;
1.1.1.10 root 1142: RTL_EXPR_SEQUENCE (t) = get_insns ();
1143:
1144: rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
1.1 root 1145:
1.1.1.7 root 1146: end_sequence (saved);
1.1.1.10 root 1147:
1148: /* Don't consider deleting this expr or containing exprs at tree level. */
1149: TREE_VOLATILE (t) = 1;
1150: /* Propagate volatility of the actual RTL expr. */
1151: TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
1152:
1153: last_expr_type = 0;
1.1.1.2 root 1154: expr_stmts_for_value--;
1.1.1.7 root 1155:
1156: return t;
1.1.1.2 root 1157: }
1158:
1159: /* Generate RTL for the start of an if-then. COND is the expression
1160: whose truth should be tested.
1.1 root 1161:
1.1.1.2 root 1162: If EXITFLAG is nonzero, this conditional is visible to
1163: `exit_something'. */
1.1 root 1164:
1.1.1.2 root 1165: void
1166: expand_start_cond (cond, exitflag)
1167: tree cond;
1168: int exitflag;
1169: {
1170: struct nesting *thiscond
1171: = (struct nesting *) xmalloc (sizeof (struct nesting));
1.1 root 1172:
1.1.1.2 root 1173: /* Make an entry on cond_stack for the cond we are entering. */
1.1 root 1174:
1.1.1.2 root 1175: thiscond->next = cond_stack;
1176: thiscond->all = nesting_stack;
1177: thiscond->depth = ++nesting_depth;
1178: thiscond->data.cond.after_label = 0;
1179: thiscond->data.cond.else_label = gen_label_rtx ();
1180: thiscond->exit_label = exitflag ? thiscond->data.cond.else_label : 0;
1181: cond_stack = thiscond;
1182: nesting_stack = thiscond;
1.1 root 1183:
1.1.1.2 root 1184: do_jump (cond, thiscond->data.cond.else_label, NULL);
1185: }
1.1 root 1186:
1.1.1.2 root 1187: /* Generate RTL for the end of an if-then with no else-clause.
1188: Pop the record for it off of cond_stack. */
1.1 root 1189:
1.1.1.2 root 1190: void
1191: expand_end_cond ()
1192: {
1193: struct nesting *thiscond = cond_stack;
1.1 root 1194:
1.1.1.2 root 1195: do_pending_stack_adjust ();
1196: emit_label (thiscond->data.cond.else_label);
1.1 root 1197:
1.1.1.2 root 1198: POPSTACK (cond_stack);
1199: last_expr_type = 0;
1200: }
1.1 root 1201:
1.1.1.2 root 1202: /* Generate RTL between the then-clause and the else-clause
1203: of an if-then-else. */
1.1 root 1204:
1.1.1.2 root 1205: void
1206: expand_start_else ()
1207: {
1208: cond_stack->data.cond.after_label = gen_label_rtx ();
1209: if (cond_stack->exit_label != 0)
1210: cond_stack->exit_label = cond_stack->data.cond.after_label;
1211: emit_jump (cond_stack->data.cond.after_label);
1212: if (cond_stack->data.cond.else_label)
1213: emit_label (cond_stack->data.cond.else_label);
1214: }
1.1 root 1215:
1.1.1.2 root 1216: /* Generate RTL for the end of an if-then-else.
1217: Pop the record for it off of cond_stack. */
1218:
1219: void
1220: expand_end_else ()
1221: {
1222: struct nesting *thiscond = cond_stack;
1223:
1224: do_pending_stack_adjust ();
1225: /* Note: a syntax error can cause this to be called
1226: without first calling `expand_start_else'. */
1227: if (thiscond->data.cond.after_label)
1228: emit_label (thiscond->data.cond.after_label);
1229:
1230: POPSTACK (cond_stack);
1231: last_expr_type = 0;
1232: }
1233:
1234: /* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this
1235: loop should be exited by `exit_something'. This is a loop for which
1236: `expand_continue' will jump to the top of the loop.
1237:
1238: Make an entry on loop_stack to record the labels associated with
1239: this loop. */
1240:
1241: void
1242: expand_start_loop (exit_flag)
1243: int exit_flag;
1244: {
1245: register struct nesting *thisloop
1246: = (struct nesting *) xmalloc (sizeof (struct nesting));
1247:
1248: /* Make an entry on loop_stack for the loop we are entering. */
1249:
1250: thisloop->next = loop_stack;
1251: thisloop->all = nesting_stack;
1252: thisloop->depth = ++nesting_depth;
1253: thisloop->data.loop.start_label = gen_label_rtx ();
1254: thisloop->data.loop.end_label = gen_label_rtx ();
1255: thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
1256: thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
1257: loop_stack = thisloop;
1258: nesting_stack = thisloop;
1259:
1260: do_pending_stack_adjust ();
1261: emit_queue ();
1262: emit_note (0, NOTE_INSN_LOOP_BEG);
1263: emit_label (thisloop->data.loop.start_label);
1264: }
1265:
1266: /* Like expand_start_loop but for a loop where the continuation point
1267: (for expand_continue_loop) will be specified explicitly. */
1.1 root 1268:
1.1.1.2 root 1269: void
1270: expand_start_loop_continue_elsewhere (exit_flag)
1271: int exit_flag;
1272: {
1273: expand_start_loop (exit_flag);
1274: loop_stack->data.loop.continue_label = gen_label_rtx ();
1275: }
1276:
1277: /* Specify the continuation point for a loop started with
1278: expand_start_loop_continue_elsewhere.
1279: Use this at the point in the code to which a continue statement
1280: should jump. */
1281:
1282: void
1283: expand_loop_continue_here ()
1284: {
1285: do_pending_stack_adjust ();
1.1.1.16 root 1286: emit_note (0, NOTE_INSN_LOOP_CONT);
1.1.1.2 root 1287: emit_label (loop_stack->data.loop.continue_label);
1288: }
1289:
1290: /* Finish a loop. Generate a jump back to the top and the loop-exit label.
1291: Pop the block off of loop_stack. */
1292:
1293: void
1294: expand_end_loop ()
1295: {
1296: register rtx insn = get_last_insn ();
1297: register rtx start_label = loop_stack->data.loop.start_label;
1298:
1299: do_pending_stack_adjust ();
1300:
1.1.1.21! root 1301: while (insn && GET_CODE (insn) == NOTE)
! 1302: insn = PREV_INSN (insn);
! 1303:
1.1.1.2 root 1304: /* If optimizing, perhaps reorder the loop. If the loop
1.1.1.21! root 1305: does not already end with a conditional branch, scan over the
! 1306: insns within the loop and try to find a conditional branch which
! 1307: is a loop exit. If such an insn is found, move that insn (and
! 1308: its predecessors) to the end of the loop so that the conditional
! 1309: exit and the jump back can perhaps be optimized into one insn. */
! 1310:
! 1311: if (optimize && insn != 0
1.1.1.2 root 1312: &&
1313: ! (GET_CODE (insn) == JUMP_INSN
1314: && GET_CODE (PATTERN (insn)) == SET
1315: && SET_DEST (PATTERN (insn)) == pc_rtx
1316: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))
1317: {
1318: /* Scan insns from the top of the loop looking for a qualified
1319: conditional exit. */
1320: for (insn = loop_stack->data.loop.start_label; insn; insn= NEXT_INSN (insn))
1321: if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET
1322: && SET_DEST (PATTERN (insn)) == pc_rtx
1323: && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE
1324: &&
1325: ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF
1326: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
1327: == loop_stack->data.loop.end_label))
1328: ||
1329: (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
1330: && (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
1331: == loop_stack->data.loop.end_label))))
1332: break;
1333: if (insn != 0)
1334: {
1335: /* We found one. Move everything from there up
1336: to the end of the loop, and add a jump into the loop
1337: to jump to there. */
1338: register rtx newstart_label = gen_label_rtx ();
1339:
1340: emit_label_after (newstart_label, PREV_INSN (start_label));
1341: reorder_insns (start_label, insn, get_last_insn ());
1342: emit_jump_insn_after (gen_jump (start_label), PREV_INSN (newstart_label));
1343: emit_barrier_after (PREV_INSN (newstart_label));
1344: start_label = newstart_label;
1345: }
1346: }
1347:
1348: emit_jump (start_label);
1349: emit_note (0, NOTE_INSN_LOOP_END);
1350: emit_label (loop_stack->data.loop.end_label);
1351:
1352: POPSTACK (loop_stack);
1353:
1354: last_expr_type = 0;
1355: }
1356:
1357: /* Generate a jump to the current loop's continue-point.
1358: This is usually the top of the loop, but may be specified
1359: explicitly elsewhere. If not currently inside a loop,
1360: return 0 and do nothing; caller will print an error message. */
1361:
1362: int
1363: expand_continue_loop ()
1364: {
1365: last_expr_type = 0;
1366: if (loop_stack == 0)
1367: return 0;
1.1.1.8 root 1368: expand_goto_internal (0, loop_stack->data.loop.continue_label, 0);
1.1.1.2 root 1369: return 1;
1370: }
1371:
1372: /* Generate a jump to exit the current loop. If not currently inside a loop,
1373: return 0 and do nothing; caller will print an error message. */
1374:
1375: int
1376: expand_exit_loop ()
1377: {
1378: last_expr_type = 0;
1379: if (loop_stack == 0)
1380: return 0;
1.1.1.8 root 1381: expand_goto_internal (0, loop_stack->data.loop.end_label, 0);
1.1.1.2 root 1382: return 1;
1383: }
1384:
1385: /* Generate a conditional jump to exit the current loop if COND
1386: evaluates to zero. If not currently inside a loop,
1387: return 0 and do nothing; caller will print an error message. */
1388:
1389: int
1390: expand_exit_loop_if_false (cond)
1391: tree cond;
1392: {
1393: last_expr_type = 0;
1394: if (loop_stack == 0)
1395: return 0;
1396: do_jump (cond, loop_stack->data.loop.end_label, NULL);
1397: return 1;
1398: }
1399:
1.1.1.17 root 1400: /* Return non-zero if currently inside a loop. */
1401:
1402: int
1403: inside_loop ()
1404: {
1405: return loop_stack != 0;
1406: }
1407:
1.1.1.2 root 1408: /* Generate a jump to exit the current loop, conditional, binding contour
1409: or case statement. Not all such constructs are visible to this function,
1410: only those started with EXIT_FLAG nonzero. Individual languages use
1411: the EXIT_FLAG parameter to control which kinds of constructs you can
1412: exit this way.
1413:
1414: If not currently inside anything that can be exited,
1415: return 0 and do nothing; caller will print an error message. */
1416:
1417: int
1418: expand_exit_something ()
1419: {
1420: struct nesting *n;
1421: last_expr_type = 0;
1422: for (n = nesting_stack; n; n = n->all)
1.1.1.7 root 1423: if (n->exit_label != 0)
1424: {
1.1.1.8 root 1425: expand_goto_internal (0, n->exit_label, 0);
1.1.1.7 root 1426: return 1;
1427: }
1428:
1.1.1.2 root 1429: return 0;
1430: }
1431:
1432: /* Generate RTL to return from the current function, with no value.
1433: (That is, we do not do anything about returning any value.) */
1434:
1435: void
1436: expand_null_return ()
1437: {
1.1.1.17 root 1438: struct nesting *block = block_stack;
1439: rtx last_insn = 0;
1440:
1441: /* Does any pending block have cleanups? */
1442:
1443: while (block && block->data.block.cleanups == 0)
1444: block = block->next;
1445:
1446: /* If yes, use a goto to return, since that runs cleanups. */
1447:
1448: expand_null_return_1 (last_insn, block != 0);
1.1.1.8 root 1449: }
1450:
1451: /* Output a return with no value. If LAST_INSN is nonzero,
1.1.1.17 root 1452: pretend that the return takes place after LAST_INSN.
1453: If USE_GOTO is nonzero then don't use a return instruction;
1454: go to the return label instead. This causes any cleanups
1455: of pending blocks to be executed normally. */
1.1.1.8 root 1456:
1457: static void
1.1.1.17 root 1458: expand_null_return_1 (last_insn, use_goto)
1.1.1.8 root 1459: rtx last_insn;
1.1.1.17 root 1460: int use_goto;
1.1.1.8 root 1461: {
1.1.1.17 root 1462: rtx end_label = cleanup_label ? cleanup_label : return_label;
1463:
1.1.1.2 root 1464: clear_pending_stack_adjust ();
1.1.1.10 root 1465: do_pending_stack_adjust ();
1.1.1.16 root 1466: last_expr_type = 0;
1467:
1468: /* PCC-struct return always uses an epilogue. */
1.1.1.17 root 1469: if (current_function_returns_pcc_struct || use_goto)
1.1.1.16 root 1470: {
1.1.1.17 root 1471: if (end_label == 0)
1472: end_label = return_label = gen_label_rtx ();
1473: expand_goto_internal (0, end_label, last_insn);
1.1.1.16 root 1474: return;
1475: }
1476:
1.1.1.17 root 1477: /* Otherwise output a simple return-insn if one is available,
1478: unless it won't do the job. */
1.1.1.8 root 1479: #ifdef HAVE_return
1.1.1.17 root 1480: if (HAVE_return && cleanup_label == 0)
1.1.1.8 root 1481: {
1482: emit_jump_insn (gen_return ());
1483: emit_barrier ();
1.1.1.16 root 1484: return;
1.1.1.8 root 1485: }
1486: #endif
1.1.1.16 root 1487:
1488: /* Otherwise jump to the epilogue. */
1.1.1.17 root 1489: expand_goto_internal (0, end_label, last_insn);
1.1.1.2 root 1490: }
1.1 root 1491:
1.1.1.2 root 1492: /* Generate RTL to evaluate the expression RETVAL and return it
1493: from the current function. */
1.1 root 1494:
1.1.1.2 root 1495: void
1496: expand_return (retval)
1497: tree retval;
1498: {
1.1.1.17 root 1499: /* If there are any cleanups to be performed, then they will
1500: be inserted following LAST_INSN. It is desirable
1501: that the last_insn, for such purposes, should be the
1502: last insn before computing the return value. Otherwise, cleanups
1503: which call functions can clobber the return value. */
1504: /* ??? rms: I think that is erroneous, because in C++ it would
1505: run destructors on variables that might be used in the subsequent
1506: computation of the return value. */
1507: rtx last_insn = 0;
1.1.1.2 root 1508: register rtx val = 0;
1509: register rtx op0;
1.1.1.7 root 1510: tree retval_rhs;
1.1.1.15 root 1511: int cleanups;
1512: struct nesting *block;
1513:
1514: /* Are any cleanups needed? E.g. C++ destructors to be run? */
1515: cleanups = 0;
1516: for (block = block_stack; block; block = block->next)
1517: if (block->data.block.cleanups != 0)
1518: {
1519: cleanups = 1;
1520: break;
1521: }
1.1.1.7 root 1522:
1523: if (TREE_CODE (retval) == RESULT_DECL)
1524: retval_rhs = retval;
1525: else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
1526: && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
1527: retval_rhs = TREE_OPERAND (retval, 1);
1.1.1.14 root 1528: else if (TREE_TYPE (retval) == void_type_node)
1529: /* Recognize tail-recursive call to void function. */
1530: retval_rhs = retval;
1.1.1.7 root 1531: else
1532: retval_rhs = NULL_TREE;
1.1.1.2 root 1533:
1.1.1.17 root 1534: /* Only use `last_insn' if there are cleanups which must be run. */
1535: if (cleanups || cleanup_label != 0)
1536: last_insn = get_last_insn ();
1537:
1.1.1.2 root 1538: /* For tail-recursive call to current function,
1539: just jump back to the beginning.
1540: It's unsafe if any auto variable in this function
1541: has its address taken; for simplicity,
1542: require stack frame to be empty. */
1.1.1.7 root 1543: if (optimize && retval_rhs != 0
1.1.1.3 root 1544: && frame_offset == STARTING_FRAME_OFFSET
1.1.1.7 root 1545: && TREE_CODE (retval_rhs) == CALL_EXPR
1546: && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
1547: && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == this_function
1.1.1.2 root 1548: /* Finish checking validity, and if valid emit code
1549: to set the argument variables for the new call. */
1.1.1.8 root 1550: && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
1.1.1.2 root 1551: DECL_ARGUMENTS (this_function)))
1552: {
1553: if (tail_recursion_label == 0)
1554: {
1555: tail_recursion_label = gen_label_rtx ();
1556: emit_label_after (tail_recursion_label,
1557: tail_recursion_reentry);
1558: }
1.1.1.17 root 1559: expand_goto_internal (0, tail_recursion_label, last_insn);
1.1.1.2 root 1560: emit_barrier ();
1561: return;
1562: }
1.1.1.8 root 1563: #ifdef HAVE_return
1.1.1.17 root 1564: /* This optimization is safe if there are local cleanups
1565: because expand_null_return takes care of them.
1566: ??? I think it should also be safe when there is a cleanup label,
1567: because expand_null_return takes care of them, too.
1568: Any reason why not? */
1569: if (HAVE_return && cleanup_label == 0
1.1.1.15 root 1570: && ! current_function_returns_pcc_struct)
1.1.1.8 root 1571: {
1572: /* If this is return x == y; then generate
1573: if (x == y) return 1; else return 0;
1574: if we can do it with explicit return insns. */
1575: if (retval_rhs)
1576: switch (TREE_CODE (retval_rhs))
1577: {
1578: case EQ_EXPR:
1579: case NE_EXPR:
1580: case GT_EXPR:
1581: case GE_EXPR:
1582: case LT_EXPR:
1583: case LE_EXPR:
1584: case TRUTH_ANDIF_EXPR:
1585: case TRUTH_ORIF_EXPR:
1.1.1.10 root 1586: case TRUTH_AND_EXPR:
1587: case TRUTH_OR_EXPR:
1.1.1.8 root 1588: case TRUTH_NOT_EXPR:
1589: op0 = gen_label_rtx ();
1590: val = DECL_RTL (DECL_RESULT (this_function));
1591: jumpifnot (retval_rhs, op0);
1592: emit_move_insn (val, const1_rtx);
1593: emit_insn (gen_rtx (USE, VOIDmode, val));
1594: expand_null_return ();
1595: emit_label (op0);
1596: emit_move_insn (val, const0_rtx);
1597: emit_insn (gen_rtx (USE, VOIDmode, val));
1598: expand_null_return ();
1599: return;
1600: }
1601: }
1602: #endif /* HAVE_return */
1.1.1.2 root 1603:
1.1.1.16 root 1604: if (cleanups
1605: && retval_rhs != 0
1606: && TREE_TYPE (retval_rhs) != void_type_node
1607: && GET_CODE (DECL_RTL (DECL_RESULT (this_function))) == REG)
1.1.1.15 root 1608: {
1609: rtx last_insn;
1610: /* Calculate the return value into a pseudo reg. */
1611: val = expand_expr (retval_rhs, 0, VOIDmode, 0);
1612: emit_queue ();
1613: /* Put the cleanups here. */
1614: last_insn = get_last_insn ();
1615: /* Copy the value into hard return reg. */
1616: emit_move_insn (DECL_RTL (DECL_RESULT (this_function)), val);
1617: val = DECL_RTL (DECL_RESULT (this_function));
1618:
1619: if (GET_CODE (val) == REG)
1620: emit_insn (gen_rtx (USE, VOIDmode, val));
1.1.1.17 root 1621: expand_null_return_1 (last_insn, cleanups);
1.1.1.15 root 1622: }
1623: else
1624: {
1625: /* No cleanups or no hard reg used;
1626: calculate value into hard return reg
1627: and let cleanups come after. */
1628: val = expand_expr (retval, 0, VOIDmode, 0);
1629: emit_queue ();
1.1.1.2 root 1630:
1.1.1.15 root 1631: val = DECL_RTL (DECL_RESULT (this_function));
1.1.1.17 root 1632: if (val && GET_CODE (val) == REG)
1.1.1.15 root 1633: emit_insn (gen_rtx (USE, VOIDmode, val));
1634: expand_null_return ();
1635: }
1.1.1.2 root 1636: }
1637:
1638: /* Return 1 if the end of the generated RTX is not a barrier.
1639: This means code already compiled can drop through. */
1640:
1641: int
1642: drop_through_at_end_p ()
1643: {
1644: rtx insn = get_last_insn ();
1645: while (insn && GET_CODE (insn) == NOTE)
1646: insn = PREV_INSN (insn);
1647: return insn && GET_CODE (insn) != BARRIER;
1.1 root 1648: }
1649:
1650: /* Emit code to alter this function's formal parms for a tail-recursive call.
1651: ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
1652: FORMALS is the chain of decls of formals.
1653: Return 1 if this can be done;
1654: otherwise return 0 and do not emit any code. */
1655:
1656: static int
1657: tail_recursion_args (actuals, formals)
1658: tree actuals, formals;
1659: {
1660: register tree a = actuals, f = formals;
1661: register int i;
1662: register rtx *argvec;
1663:
1664: /* Check that number and types of actuals are compatible
1665: with the formals. This is not always true in valid C code.
1666: Also check that no formal needs to be addressable
1667: and that all formals are scalars. */
1668:
1669: /* Also count the args. */
1670:
1671: for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
1672: {
1673: if (TREE_TYPE (TREE_VALUE (a)) != TREE_TYPE (f))
1674: return 0;
1675: if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
1676: return 0;
1677: }
1678: if (a != 0 || f != 0)
1679: return 0;
1680:
1681: /* Compute all the actuals. */
1682:
1683: argvec = (rtx *) alloca (i * sizeof (rtx));
1684:
1685: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1686: argvec[i] = expand_expr (TREE_VALUE (a), 0, VOIDmode, 0);
1687:
1688: /* Find which actual values refer to current values of previous formals.
1689: Copy each of them now, before any formal is changed. */
1690:
1691: for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
1692: {
1693: int copy = 0;
1694: register int j;
1695: for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
1696: if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
1697: { copy = 1; break; }
1698: if (copy)
1699: argvec[i] = copy_to_reg (argvec[i]);
1700: }
1701:
1702: /* Store the values of the actuals into the formals. */
1703:
1.1.1.2 root 1704: for (f = formals, a = actuals, i = 0; f;
1705: f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
1.1 root 1706: {
1707: if (DECL_MODE (f) == GET_MODE (argvec[i]))
1708: emit_move_insn (DECL_RTL (f), argvec[i]);
1709: else
1.1.1.2 root 1710: convert_move (DECL_RTL (f), argvec[i],
1711: TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
1.1 root 1712: }
1713:
1714: return 1;
1715: }
1716:
1.1.1.2 root 1717: /* Generate the RTL code for entering a binding contour.
1718: The variables are declared one by one, by calls to `expand_decl'.
1.1 root 1719:
1.1.1.2 root 1720: EXIT_FLAG is nonzero if this construct should be visible to
1721: `exit_something'. */
1722:
1723: void
1724: expand_start_bindings (exit_flag)
1725: int exit_flag;
1.1 root 1726: {
1.1.1.2 root 1727: struct nesting *thisblock
1728: = (struct nesting *) xmalloc (sizeof (struct nesting));
1729:
1730: rtx note = emit_note (0, NOTE_INSN_BLOCK_BEG);
1731:
1732: /* Make an entry on block_stack for the block we are entering. */
1733:
1734: thisblock->next = block_stack;
1735: thisblock->all = nesting_stack;
1736: thisblock->depth = ++nesting_depth;
1737: thisblock->data.block.stack_level = 0;
1.1.1.7 root 1738: thisblock->data.block.cleanups = 0;
1.1.1.13 root 1739: /* We build this even if the cleanups lists are empty
1740: because we rely on having an element in the chain
1741: for each block that is pending. */
1742: thisblock->data.block.outer_cleanups
1743: = (block_stack
1744: ? tree_cons (NULL_TREE, block_stack->data.block.cleanups,
1745: block_stack->data.block.outer_cleanups)
1746: : 0);
1.1.1.2 root 1747: thisblock->data.block.label_chain = 0;
1748: thisblock->data.block.innermost_stack_block = stack_block_stack;
1749: thisblock->data.block.first_insn = note;
1.1.1.19 root 1750: thisblock->data.block.block_start_count = ++block_start_count;
1.1.1.2 root 1751: thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
1.1.1.19 root 1752:
1.1.1.2 root 1753: block_stack = thisblock;
1754: nesting_stack = thisblock;
1755: }
1756:
1.1.1.3 root 1757: /* Output a USE for any register use in RTL.
1758: This is used with -noreg to mark the extent of lifespan
1759: of any registers used in a user-visible variable's DECL_RTL. */
1760:
1.1.1.13 root 1761: void
1.1.1.3 root 1762: use_variable (rtl)
1763: rtx rtl;
1764: {
1765: if (GET_CODE (rtl) == REG)
1766: /* This is a register variable. */
1767: emit_insn (gen_rtx (USE, VOIDmode, rtl));
1.1.1.21! root 1768: else if (GET_CODE (rtl) == SUBREG)
! 1769: use_variable (SUBREG_REG (rtl));
1.1.1.3 root 1770: else if (GET_CODE (rtl) == MEM
1771: && GET_CODE (XEXP (rtl, 0)) == REG
1772: && XEXP (rtl, 0) != frame_pointer_rtx
1773: && XEXP (rtl, 0) != arg_pointer_rtx)
1774: /* This is a variable-sized structure. */
1775: emit_insn (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)));
1776: }
1777:
1.1.1.13 root 1778: /* Like use_variable except that it outputs the USEs after INSN
1779: instead of at the end of the insn-chain. */
1780:
1781: static void
1782: use_variable_after (rtl, insn)
1783: rtx rtl, insn;
1784: {
1785: if (GET_CODE (rtl) == REG)
1786: /* This is a register variable. */
1787: emit_insn_after (gen_rtx (USE, VOIDmode, rtl), insn);
1.1.1.21! root 1788: else if (GET_CODE (rtl) == SUBREG)
! 1789: use_variable_after (SUBREG_REG (rtl), insn);
1.1.1.13 root 1790: else if (GET_CODE (rtl) == MEM
1791: && GET_CODE (XEXP (rtl, 0)) == REG
1792: && XEXP (rtl, 0) != frame_pointer_rtx
1793: && XEXP (rtl, 0) != arg_pointer_rtx)
1794: /* This is a variable-sized structure. */
1795: emit_insn_after (gen_rtx (USE, VOIDmode, XEXP (rtl, 0)), insn);
1796: }
1797:
1.1.1.2 root 1798: /* Generate RTL code to terminate a binding contour.
1799: VARS is the chain of VAR_DECL nodes
1800: for the variables bound in this contour.
1.1.1.7 root 1801: MARK_ENDS is nonzero if we should put a note at the beginning
1802: and end of this binding contour.
1803:
1804: DONT_JUMP_IN is nonzero if it is not valid to jump into this contour.
1805: (That is true automatically if the contour has a saved stack level.) */
1.1.1.2 root 1806:
1807: void
1.1.1.7 root 1808: expand_end_bindings (vars, mark_ends, dont_jump_in)
1.1.1.2 root 1809: tree vars;
1810: int mark_ends;
1.1.1.7 root 1811: int dont_jump_in;
1.1.1.2 root 1812: {
1813: register struct nesting *thisblock = block_stack;
1814: register tree decl;
1815:
1.1.1.10 root 1816: if (warn_unused)
1817: for (decl = vars; decl; decl = TREE_CHAIN (decl))
1818: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
1819: warning_with_decl (decl, "unused variable `%s'");
1820:
1.1.1.2 root 1821: /* Mark the beginning and end of the scope if requested. */
1822:
1823: if (mark_ends)
1824: emit_note (0, NOTE_INSN_BLOCK_END);
1825: else
1826: /* Get rid of the beginning-mark if we don't make an end-mark. */
1827: NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;
1828:
1829: if (thisblock->exit_label)
1830: {
1831: do_pending_stack_adjust ();
1832: emit_label (thisblock->exit_label);
1833: }
1834:
1.1.1.13 root 1835: if (dont_jump_in
1836: || thisblock->data.block.stack_level != 0
1837: || thisblock->data.block.cleanups != 0)
1.1.1.2 root 1838: {
1839: struct label_chain *chain;
1840:
1841: /* Any labels in this block are no longer valid to go to.
1842: Mark them to cause an error message. */
1843: for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
1844: {
1845: TREE_PACKED (chain->label) = 1;
1846: /* If any goto without a fixup came to this label,
1847: that must be an error, because gotos without fixups
1.1.1.13 root 1848: come from outside all saved stack-levels and all cleanups. */
1.1.1.2 root 1849: if (TREE_ADDRESSABLE (chain->label))
1.1.1.13 root 1850: error_with_decl (chain->label,
1851: "label `%s' used before containing binding contour");
1.1.1.2 root 1852: }
1.1.1.7 root 1853: }
1854:
1855: /* Restore stack level in effect before the block
1856: (only if variable-size objects allocated). */
1857:
1858: if (thisblock->data.block.stack_level != 0
1859: || thisblock->data.block.cleanups != 0)
1860: {
1861: /* Perform any cleanups associated with the block. */
1862:
1863: expand_cleanups (thisblock->data.block.cleanups, 0);
1864:
1865: /* Restore the stack level. */
1866:
1867: if (thisblock->data.block.stack_level != 0)
1868: {
1869: do_pending_stack_adjust ();
1870: emit_move_insn (stack_pointer_rtx,
1871: thisblock->data.block.stack_level);
1872: }
1.1.1.2 root 1873:
1.1.1.7 root 1874: /* Any gotos out of this block must also do these things.
1.1.1.2 root 1875: Also report any gotos with fixups that came to labels in this level. */
1.1.1.13 root 1876: fixup_gotos (thisblock,
1877: thisblock->data.block.stack_level,
1.1.1.7 root 1878: thisblock->data.block.cleanups,
1879: thisblock->data.block.first_insn,
1880: dont_jump_in);
1.1.1.2 root 1881: }
1882:
1883: /* If doing stupid register allocation, make sure lives of all
1884: register variables declared here extend thru end of scope. */
1885:
1886: if (obey_regdecls)
1887: for (decl = vars; decl; decl = TREE_CHAIN (decl))
1888: {
1.1.1.3 root 1889: rtx rtl = DECL_RTL (decl);
1890: if (TREE_CODE (decl) == VAR_DECL && rtl != 0)
1891: use_variable (rtl);
1.1.1.2 root 1892: }
1893:
1894: /* Restore block_stack level for containing block. */
1895:
1896: stack_block_stack = thisblock->data.block.innermost_stack_block;
1897: POPSTACK (block_stack);
1898: }
1899:
1900: /* Generate RTL for the automatic variable declaration DECL.
1.1.1.7 root 1901: (Other kinds of declarations are simply ignored if seen here.)
1902: CLEANUP is an expression to be executed at exit from this binding contour;
1903: for example, in C++, it might call the destructor for this variable.
1904:
1905: If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
1906: either before or after calling `expand_decl' but before compiling
1907: any subsequent expressions. This is because CLEANUP may be expanded
1908: more than once, on different branches of execution.
1909: For the same reason, CLEANUP may not contain a CALL_EXPR
1910: except as its topmost node--else `preexpand_calls' would get confused.
1911:
1.1.1.13 root 1912: If CLEANUP is nonzero and DECL is zero, we record a cleanup
1913: that is not associated with any particular variable.
1914:
1.1.1.7 root 1915: There is no special support here for C++ constructors.
1916: They should be handled by the proper code in DECL_INITIAL. */
1.1.1.2 root 1917:
1918: void
1.1.1.7 root 1919: expand_decl (decl, cleanup)
1.1.1.2 root 1920: register tree decl;
1.1.1.7 root 1921: tree cleanup;
1.1.1.2 root 1922: {
1923: struct nesting *thisblock = block_stack;
1.1.1.13 root 1924: tree type;
1925:
1926: /* Record the cleanup if there is one. */
1927:
1928: if (cleanup != 0)
1929: {
1930: thisblock->data.block.cleanups
1931: = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
1932: /* If this block has a cleanup, it belongs in stack_block_stack. */
1933: stack_block_stack = thisblock;
1934: }
1935:
1936: if (decl == NULL_TREE)
1937: {
1938: /* This was a cleanup with no variable. */
1939: if (cleanup == 0)
1940: abort ();
1941: return;
1942: }
1943:
1944: type = TREE_TYPE (decl);
1.1.1.2 root 1945:
1946: /* Aside from that, only automatic variables need any expansion done.
1.1.1.14 root 1947: Static and external variables, and external functions,
1948: will be handled by `assemble_variable' (called from finish_decl).
1949: TYPE_DECL and CONST_DECL require nothing.
1.1.1.2 root 1950: PARM_DECLs are handled in `assign_parms'. */
1951:
1952: if (TREE_CODE (decl) != VAR_DECL)
1953: return;
1954: if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))
1955: return;
1956:
1957: /* Create the RTL representation for the variable. */
1958:
1959: if (type == error_mark_node)
1960: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx);
1.1.1.14 root 1961: else if (DECL_SIZE (decl) == 0)
1962: /* Variable with incomplete type. */
1963: {
1964: if (DECL_INITIAL (decl) == 0)
1965: /* Error message was already done; now avoid a crash. */
1966: DECL_RTL (decl) = assign_stack_local (DECL_MODE (decl), 0);
1967: else
1968: /* An initializer is going to decide the size of this array.
1969: Until we know the size, represent its address with a reg. */
1970: DECL_RTL (decl) = gen_rtx (MEM, BLKmode, gen_reg_rtx (Pmode));
1971: }
1.1.1.2 root 1972: else if (DECL_MODE (decl) != BLKmode
1973: /* If -ffloat-store, don't put explicit float vars
1974: into regs. */
1975: && !(flag_float_store
1976: && TREE_CODE (type) == REAL_TYPE)
1977: && ! TREE_VOLATILE (decl)
1978: && ! TREE_ADDRESSABLE (decl)
1979: && (TREE_REGDECL (decl) || ! obey_regdecls))
1980: {
1981: /* Automatic variable that can go in a register. */
1982: DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl));
1983: if (TREE_CODE (type) == POINTER_TYPE)
1984: mark_reg_pointer (DECL_RTL (decl));
1.1.1.10 root 1985: REG_USERVAR_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 1986: }
1987: else if (TREE_LITERAL (DECL_SIZE (decl)))
1988: {
1.1.1.14 root 1989: rtx oldaddr = 0;
1990: rtx addr;
1991:
1992: /* If we previously made RTL for this decl, it must be an array
1993: whose size was determined by the initializer.
1994: The old address was a register; set that register now
1995: to the proper address. */
1996: if (DECL_RTL (decl) != 0)
1997: {
1998: if (GET_CODE (DECL_RTL (decl)) != MEM
1999: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != REG)
2000: abort ();
2001: oldaddr = XEXP (DECL_RTL (decl), 0);
2002: }
2003:
1.1.1.2 root 2004: /* Variable of fixed size that goes on the stack. */
2005: DECL_RTL (decl)
2006: = assign_stack_local (DECL_MODE (decl),
2007: (TREE_INT_CST_LOW (DECL_SIZE (decl))
2008: * DECL_SIZE_UNIT (decl)
2009: + BITS_PER_UNIT - 1)
2010: / BITS_PER_UNIT);
1.1.1.14 root 2011: if (oldaddr)
2012: {
2013: addr = force_operand (XEXP (DECL_RTL (decl), 0), oldaddr);
2014: emit_move_insn (oldaddr, addr);
2015: }
2016:
1.1.1.2 root 2017: /* If this is a memory ref that contains aggregate components,
2018: mark it as such for cse and loop optimize. */
1.1.1.10 root 2019: MEM_IN_STRUCT_P (DECL_RTL (decl))
1.1.1.2 root 2020: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
2021: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
2022: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
1.1.1.8 root 2023: #if 0
2024: /* If this is in memory because of -ffloat-store,
2025: set the volatile bit, to prevent optimizations from
2026: undoing the effects. */
2027: if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
1.1.1.10 root 2028: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.8 root 2029: #endif
1.1.1.2 root 2030: }
2031: else
2032: /* Dynamic-size object: must push space on the stack. */
2033: {
2034: rtx address, size;
2035:
2036: frame_pointer_needed = 1;
2037:
2038: /* Record the stack pointer on entry to block, if have
2039: not already done so. */
2040: if (thisblock->data.block.stack_level == 0)
2041: {
2042: do_pending_stack_adjust ();
2043: thisblock->data.block.stack_level
2044: = copy_to_reg (stack_pointer_rtx);
2045: stack_block_stack = thisblock;
2046: }
2047:
2048: /* Compute the variable's size, in bytes. */
2049: size = expand_expr (convert_units (DECL_SIZE (decl),
2050: DECL_SIZE_UNIT (decl),
2051: BITS_PER_UNIT),
2052: 0, VOIDmode, 0);
2053:
2054: /* Round it up to this machine's required stack boundary. */
2055: #ifdef STACK_BOUNDARY
2056: /* Avoid extra code if we can prove it's a multiple already. */
2057: if (DECL_SIZE_UNIT (decl) % STACK_BOUNDARY)
1.1.1.16 root 2058: {
2059: #ifdef STACK_POINTER_OFFSET
2060: /* Avoid extra code if we can prove that adding STACK_POINTER_OFFSET
2061: will not give this address invalid alignment. */
2062: if (DECL_ALIGN (decl) > ((STACK_POINTER_OFFSET * BITS_PER_UNIT) % STACK_BOUNDARY))
2063: size = plus_constant (size,
2064: STACK_POINTER_OFFSET % (STACK_BOUNDARY / BITS_PER_UNIT));
1.1.1.2 root 2065: #endif
1.1.1.16 root 2066: size = round_push (size);
2067: }
2068: #endif /* STACK_BOUNDARY */
1.1.1.2 root 2069:
2070: /* Make space on the stack, and get an rtx for the address of it. */
2071: #ifdef STACK_GROWS_DOWNWARD
2072: anti_adjust_stack (size);
2073: #endif
2074: address = copy_to_reg (stack_pointer_rtx);
1.1.1.4 root 2075: #ifdef STACK_POINTER_OFFSET
1.1.1.16 root 2076: {
2077: /* If the contents of the stack pointer reg are offset from the
2078: actual top-of-stack address, add the offset here. */
2079: rtx sp_offset = gen_rtx (CONST_INT, VOIDmode, STACK_POINTER_OFFSET);
2080: #ifdef STACK_BOUNDARY
2081: #ifdef STACK_GROWS_DOWNWARD
2082: int direction = 1;
2083: #else /* not STACK_GROWS_DOWNWARD */
2084: int direction = 0;
2085: #endif /* not STACK_GROWS_DOWNWARD */
2086: if (DECL_ALIGN (decl) > ((STACK_POINTER_OFFSET * BITS_PER_UNIT) % STACK_BOUNDARY))
2087: sp_offset = plus_constant (sp_offset,
2088: (STACK_POINTER_OFFSET
2089: % (STACK_BOUNDARY / BITS_PER_UNIT)
2090: * direction));
2091: #endif /* STACK_BOUNDARY */
2092: emit_insn (gen_add2_insn (address, sp_offset));
2093: }
2094: #endif /* STACK_POINTER_OFFSET */
1.1.1.2 root 2095: #ifndef STACK_GROWS_DOWNWARD
2096: anti_adjust_stack (size);
2097: #endif
2098:
1.1.1.17 root 2099: /* Some systems require a particular insn to refer to the stack
2100: to make the pages exist. */
2101: #ifdef HAVE_probe
2102: if (HAVE_probe)
2103: emit_insn (gen_probe ());
2104: #endif
2105:
1.1.1.2 root 2106: /* Reference the variable indirect through that rtx. */
2107: DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);
2108: }
2109:
2110: if (TREE_VOLATILE (decl))
1.1.1.10 root 2111: MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 2112: if (TREE_READONLY (decl))
1.1.1.10 root 2113: RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
1.1.1.2 root 2114:
2115: /* If doing stupid register allocation, make sure life of any
2116: register variable starts here, at the start of its scope. */
2117:
1.1.1.14 root 2118: if (obey_regdecls)
1.1.1.3 root 2119: use_variable (DECL_RTL (decl));
1.1.1.14 root 2120: }
2121:
2122: /* Emit code to perform the initialization of a declaration DECL. */
2123:
2124: void
2125: expand_decl_init (decl)
2126: tree decl;
2127: {
2128: if (TREE_STATIC (decl))
2129: return;
1.1.1.2 root 2130:
2131: /* Compute and store the initial value now. */
2132:
1.1.1.3 root 2133: if (DECL_INITIAL (decl) == error_mark_node)
2134: {
2135: enum tree_code code = TREE_CODE (TREE_TYPE (decl));
2136: if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
2137: || code == POINTER_TYPE)
2138: expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
2139: 0, 0);
2140: emit_queue ();
2141: }
1.1.1.7 root 2142: else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
1.1.1.2 root 2143: {
1.1.1.12 root 2144: emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1.1.1.2 root 2145: expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
2146: emit_queue ();
2147: }
2148: }
1.1.1.13 root 2149:
2150: /* DECL is an anonymous union. CLEANUP is a cleanup for DECL.
2151: DECL_ELTS is the list of elements that belong to DECL's type.
2152: In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup. */
2153:
2154: void
2155: expand_anon_union_decl (decl, cleanup, decl_elts)
2156: tree decl, cleanup, decl_elts;
2157: {
2158: struct nesting *thisblock = block_stack;
2159: rtx x;
2160:
2161: expand_decl (decl, cleanup);
2162: x = DECL_RTL (decl);
2163:
2164: while (decl_elts)
2165: {
2166: tree decl_elt = TREE_VALUE (decl_elts);
2167: tree cleanup_elt = TREE_PURPOSE (decl_elts);
2168:
2169: DECL_RTL (decl_elt)
2170: = (GET_MODE (x) != BLKmode
2171: /*
2172: #error broken
2173: /* ??? This is incorrect if X is a MEM.
2174: (SUBREG (MEM)) is not allowed at rtl generation time. */
2175: ? gen_rtx (SUBREG, TYPE_MODE (TREE_TYPE (decl_elt)), x, 0)
2176: : x);
2177:
2178: /* Record the cleanup if there is one. */
2179:
2180: if (cleanup != 0)
2181: thisblock->data.block.cleanups
2182: = temp_tree_cons (decl_elt, cleanup_elt,
2183: thisblock->data.block.cleanups);
2184:
2185: decl_elts = TREE_CHAIN (decl_elts);
2186: }
2187: }
1.1.1.2 root 2188:
1.1.1.7 root 2189: /* Expand a list of cleanups LIST.
2190: Elements may be expressions or may be nested lists.
2191:
2192: If DONT_DO is nonnull, then any list-element
2193: whose TREE_PURPOSE matches DONT_DO is omitted.
2194: This is sometimes used to avoid a cleanup associated with
2195: a value that is being returned out of the scope. */
2196:
2197: static void
2198: expand_cleanups (list, dont_do)
2199: tree list;
2200: tree dont_do;
2201: {
2202: tree tail;
2203: for (tail = list; tail; tail = TREE_CHAIN (tail))
2204: if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
2205: {
2206: if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
1.1.1.8 root 2207: expand_cleanups (TREE_VALUE (tail), dont_do);
1.1.1.7 root 2208: else
2209: expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
2210: }
2211: }
2212:
2213: /* Expand a list of cleanups for a goto fixup.
2214: The expansion is put into the insn chain after the insn *BEFORE_JUMP
2215: and *BEFORE_JUMP is set to the insn that now comes before the jump. */
2216:
2217: static void
2218: fixup_cleanups (list, before_jump)
2219: tree list;
2220: rtx *before_jump;
2221: {
2222: rtx beyond_jump = get_last_insn ();
2223: rtx new_before_jump;
2224:
2225: expand_cleanups (list, 0);
2226: new_before_jump = get_last_insn ();
2227:
2228: reorder_insns (NEXT_INSN (beyond_jump), new_before_jump, *before_jump);
2229: *before_jump = new_before_jump;
2230: }
1.1.1.8 root 2231:
2232: /* Move all cleanups from the current block_stack
2233: to the containing block_stack, where they are assumed to
2234: have been created. If anything can cause a temporary to
2235: be created, but not expanded for more than one level of
2236: block_stacks, then this code will have to change. */
2237:
2238: void
2239: move_cleanups_up ()
2240: {
2241: struct nesting *block = block_stack;
2242: struct nesting *outer = block->next;
2243:
2244: outer->data.block.cleanups
1.1.1.13 root 2245: = chainon (block->data.block.cleanups,
2246: outer->data.block.cleanups);
1.1.1.8 root 2247: block->data.block.cleanups = 0;
2248: }
1.1.1.17 root 2249:
2250: int
2251: this_contour_has_cleanups_p ()
2252: {
2253: return block_stack && block_stack->data.block.cleanups != 0;
2254: }
1.1.1.7 root 2255:
1.1.1.2 root 2256: /* Enter a case (Pascal) or switch (C) statement.
2257: Push a block onto case_stack and nesting_stack
2258: to accumulate the case-labels that are seen
2259: and to record the labels generated for the statement.
2260:
2261: EXIT_FLAG is nonzero if `exit_something' should exit this case stmt.
2262: Otherwise, this construct is transparent for `exit_something'.
2263:
2264: EXPR is the index-expression to be dispatched on.
2265: TYPE is its nominal type. We could simply convert EXPR to this type,
2266: but instead we take short cuts. */
2267:
2268: void
2269: expand_start_case (exit_flag, expr, type)
2270: int exit_flag;
2271: tree expr;
2272: tree type;
2273: {
2274: register struct nesting *thiscase
2275: = (struct nesting *) xmalloc (sizeof (struct nesting));
2276:
2277: /* Make an entry on case_stack for the case we are entering. */
2278:
2279: thiscase->next = case_stack;
2280: thiscase->all = nesting_stack;
2281: thiscase->depth = ++nesting_depth;
2282: thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
2283: thiscase->data.case_stmt.case_list = 0;
2284: thiscase->data.case_stmt.index_expr = expr;
2285: thiscase->data.case_stmt.nominal_type = type;
1.1.1.13 root 2286: thiscase->data.case_stmt.default_label = 0;
2287: thiscase->data.case_stmt.num_ranges = 0;
1.1.1.2 root 2288: case_stack = thiscase;
2289: nesting_stack = thiscase;
2290:
2291: do_pending_stack_adjust ();
2292:
1.1.1.6 root 2293: /* Make sure case_stmt.start points to something that won't
2294: need any transformation before expand_end_case. */
1.1.1.17 root 2295: emit_note (0, NOTE_INSN_DELETED);
1.1.1.6 root 2296:
1.1.1.2 root 2297: thiscase->data.case_stmt.start = get_last_insn ();
2298: }
2299:
2300: /* Start a "dummy case statement" within which case labels are invalid
2301: and are not connected to any larger real case statement.
2302: This can be used if you don't want to let a case statement jump
2303: into the middle of certain kinds of constructs. */
2304:
2305: void
2306: expand_start_case_dummy ()
2307: {
2308: register struct nesting *thiscase
2309: = (struct nesting *) xmalloc (sizeof (struct nesting));
2310:
2311: /* Make an entry on case_stack for the dummy. */
2312:
2313: thiscase->next = case_stack;
2314: thiscase->all = nesting_stack;
2315: thiscase->depth = ++nesting_depth;
2316: thiscase->exit_label = 0;
2317: thiscase->data.case_stmt.case_list = 0;
2318: thiscase->data.case_stmt.start = 0;
2319: thiscase->data.case_stmt.nominal_type = 0;
1.1.1.13 root 2320: thiscase->data.case_stmt.default_label = 0;
2321: thiscase->data.case_stmt.num_ranges = 0;
1.1.1.2 root 2322: case_stack = thiscase;
2323: nesting_stack = thiscase;
2324: }
2325:
2326: /* End a dummy case statement. */
2327:
2328: void
2329: expand_end_case_dummy ()
2330: {
2331: POPSTACK (case_stack);
2332: }
1.1.1.7 root 2333:
1.1.1.2 root 2334: /* Accumulate one case or default label inside a case or switch statement.
2335: VALUE is the value of the case (a null pointer, for a default label).
2336:
2337: If not currently inside a case or switch statement, return 1 and do
2338: nothing. The caller will print a language-specific error message.
1.1.1.7 root 2339: If VALUE is a duplicate or overlaps, return 2 and do nothing.
1.1.1.2 root 2340: If VALUE is out of range, return 3 and do nothing.
1.1.1.13 root 2341: Return 0 on success.
2342:
2343: Extended to handle range statements, should they ever
2344: be adopted. */
1.1.1.2 root 2345:
2346: int
2347: pushcase (value, label)
2348: register tree value;
2349: register tree label;
2350: {
1.1.1.13 root 2351: register struct case_node **l;
2352: register struct case_node *n;
1.1.1.2 root 2353: tree index_type;
2354: tree nominal_type;
2355:
2356: /* Fail if not inside a real case statement. */
2357: if (! (case_stack && case_stack->data.case_stmt.start))
2358: return 1;
2359:
2360: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
2361: nominal_type = case_stack->data.case_stmt.nominal_type;
2362:
2363: /* If the index is erroneous, avoid more problems: pretend to succeed. */
2364: if (index_type == error_mark_node)
2365: return 0;
2366:
2367: /* Convert VALUE to the type in which the comparisons are nominally done. */
2368: if (value != 0)
2369: value = convert (nominal_type, value);
2370:
1.1.1.7 root 2371: /* Fail if this value is out of range for the actual type of the index
2372: (which may be narrower than NOMINAL_TYPE). */
2373: if (value != 0 && ! int_fits_type_p (value, index_type))
2374: return 3;
2375:
2376: /* Fail if this is a duplicate or overlaps another entry. */
2377: if (value == 0)
1.1.1.2 root 2378: {
1.1.1.13 root 2379: if (case_stack->data.case_stmt.default_label != 0)
1.1.1.2 root 2380: return 2;
1.1.1.13 root 2381: case_stack->data.case_stmt.default_label = label;
1.1.1.2 root 2382: }
1.1.1.7 root 2383: else
2384: {
1.1.1.13 root 2385: /* Find the elt in the chain before which to insert the new value,
2386: to keep the chain sorted in increasing order.
2387: But report an error if this element is a duplicate. */
2388: for (l = &case_stack->data.case_stmt.case_list;
2389: /* Keep going past elements distinctly less than VALUE. */
1.1.1.14 root 2390: *l != 0 && tree_int_cst_lt ((*l)->high, value);
1.1.1.13 root 2391: l = &(*l)->right)
2392: ;
2393: if (*l)
1.1.1.7 root 2394: {
1.1.1.13 root 2395: /* Element we will insert before must be distinctly greater;
2396: overlap means error. */
2397: if (! tree_int_cst_lt (value, (*l)->low))
2398: return 2;
1.1.1.7 root 2399: }
1.1.1.13 root 2400:
2401: /* Add this label to the chain, and succeed.
2402: Copy VALUE so it is on temporary rather than momentary
2403: obstack and will thus survive till the end of the case statement. */
2404: n = (struct case_node *) oballoc (sizeof (struct case_node));
2405: n->left = 0;
2406: n->right = *l;
2407: n->high = n->low = copy_node (value);
2408: n->code_label = label;
2409: n->test_label = 0;
2410: *l = n;
1.1.1.7 root 2411: }
2412:
2413: expand_label (label);
2414: return 0;
2415: }
2416:
2417: /* Like pushcase but this case applies to all values
2418: between VALUE1 and VALUE2 (inclusive).
2419: The return value is the same as that of pushcase
2420: but there is one additional error code:
2421: 4 means the specified range was empty.
2422:
2423: Note that this does not currently work, since expand_end_case
2424: has yet to be extended to handle RANGE_EXPRs. */
2425:
2426: int
2427: pushcase_range (value1, value2, label)
2428: register tree value1, value2;
2429: register tree label;
2430: {
1.1.1.13 root 2431: register struct case_node **l;
2432: register struct case_node *n;
1.1.1.7 root 2433: tree index_type;
2434: tree nominal_type;
2435:
2436: /* Fail if not inside a real case statement. */
2437: if (! (case_stack && case_stack->data.case_stmt.start))
2438: return 1;
2439:
2440: index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
2441: nominal_type = case_stack->data.case_stmt.nominal_type;
2442:
2443: /* If the index is erroneous, avoid more problems: pretend to succeed. */
2444: if (index_type == error_mark_node)
2445: return 0;
2446:
2447: /* Convert VALUEs to type in which the comparisons are nominally done. */
2448: if (value1 != 0)
2449: value1 = convert (nominal_type, value1);
2450: if (value2 != 0)
2451: value2 = convert (nominal_type, value2);
2452:
2453: /* Fail if these values are out of range. */
2454: if (value1 != 0 && ! int_fits_type_p (value1, index_type))
2455: return 3;
2456:
2457: if (value2 != 0 && ! int_fits_type_p (value2, index_type))
1.1.1.2 root 2458: return 3;
2459:
1.1.1.7 root 2460: /* Fail if the range is empty. */
2461: if (tree_int_cst_lt (value2, value1))
2462: return 4;
2463:
1.1.1.8 root 2464: /* If the bounds are equal, turn this into the one-value case. */
2465: if (tree_int_cst_equal (value1, value2))
2466: return pushcase (value1, label);
2467:
1.1.1.13 root 2468: /* Find the elt in the chain before which to insert the new value,
2469: to keep the chain sorted in increasing order.
2470: But report an error if this element is a duplicate. */
2471: for (l = &case_stack->data.case_stmt.case_list;
2472: /* Keep going past elements distinctly less than this range. */
1.1.1.14 root 2473: *l != 0 && tree_int_cst_lt ((*l)->high, value1);
1.1.1.13 root 2474: l = &(*l)->right)
2475: ;
2476: if (*l)
2477: {
2478: /* Element we will insert before must be distinctly greater;
2479: overlap means error. */
2480: if (! tree_int_cst_lt (value2, (*l)->low))
2481: return 2;
1.1.1.7 root 2482: }
2483:
1.1.1.13 root 2484: /* Add this label to the chain, and succeed.
2485: Copy VALUE1, VALUE2 so they are on temporary rather than momentary
2486: obstack and will thus survive till the end of the case statement. */
2487:
2488: n = (struct case_node *) oballoc (sizeof (struct case_node));
2489: n->left = 0;
2490: n->right = *l;
2491: n->low = copy_node (value1);
2492: n->high = copy_node (value2);
2493: n->code_label = label;
2494: n->test_label = 0;
2495: *l = n;
2496:
1.1.1.2 root 2497: expand_label (label);
1.1.1.7 root 2498:
1.1.1.13 root 2499: case_stack->data.case_stmt.num_ranges++;
2500:
1.1.1.2 root 2501: return 0;
2502: }
2503:
1.1.1.16 root 2504: /* Check that all enumeration literals are covered by the case
2505: expressions of a switch. Also, warn if there are any extra
2506: switch cases that are *not* elements of the enumerated type. */
2507:
1.1.1.18 root 2508: static void
2509: check_for_full_enumeration_handling (type)
2510: tree type;
1.1.1.16 root 2511: {
1.1.1.18 root 2512: register struct case_node *n;
2513: register tree chain;
1.1.1.16 root 2514:
1.1.1.18 root 2515: /* The time complexity of this loop is currently O(N * M), with
2516: N being the number of enumerals in the enumerated type, and
2517: M being the number of case expressions in the switch. */
1.1.1.16 root 2518:
1.1.1.18 root 2519: for (chain = TYPE_VALUES (type);
2520: chain;
2521: chain = TREE_CHAIN (chain))
2522: {
2523: /* Find a match between enumeral and case expression, if possible.
2524: Quit looking when we've gone too far (since case expressions
2525: are kept sorted in ascending order). Warn about enumerals not
2526: handled in the switch statement case expression list. */
2527:
2528: for (n = case_stack->data.case_stmt.case_list;
2529: n && tree_int_cst_lt (n->high, TREE_VALUE (chain));
2530: n = n->right)
2531: ;
2532:
2533: if (!(n && tree_int_cst_equal (n->low, TREE_VALUE (chain))))
2534: warning ("enumerated value `%s' not handled in switch",
2535: IDENTIFIER_POINTER (TREE_PURPOSE (chain)));
2536: }
2537:
2538: /* Now we go the other way around; we warn if there are case
2539: expressions that don't correspond to enumerals. This can
2540: occur since C and C++ don't enforce type-checking of
2541: assignments to enumeration variables. */
2542:
2543: for (n = case_stack->data.case_stmt.case_list; n; n = n->right)
2544: {
2545: for (chain = TYPE_VALUES (type);
2546: chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain));
2547: chain = TREE_CHAIN (chain))
2548: ;
2549:
2550: if (!chain)
2551: warning ("case value `%d' not in enumerated type `%s'",
2552: TREE_INT_CST_LOW (n->low),
2553: IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
2554: ? TYPE_NAME (type)
2555: : DECL_NAME (TYPE_NAME (type))));
1.1.1.16 root 2556: }
2557: }
2558:
1.1.1.2 root 2559: /* Terminate a case (Pascal) or switch (C) statement
2560: in which CASE_INDEX is the expression to be tested.
2561: Generate the code to test it and jump to the right place. */
2562:
2563: void
1.1.1.16 root 2564: expand_end_case (orig_index)
2565: tree orig_index;
1.1.1.2 root 2566: {
2567: tree minval, maxval, range;
2568: rtx default_label = 0;
1.1.1.13 root 2569: register struct case_node *n;
1.1.1.2 root 2570: int count;
2571: rtx index;
2572: rtx table_label = gen_label_rtx ();
2573: int ncases;
2574: rtx *labelvec;
2575: register int i;
2576: rtx before_case;
2577: register struct nesting *thiscase = case_stack;
2578: tree index_expr = thiscase->data.case_stmt.index_expr;
1.1.1.17 root 2579: int unsignedp = TREE_UNSIGNED (TREE_TYPE (index_expr));
1.1.1.2 root 2580:
2581: do_pending_stack_adjust ();
2582:
1.1.1.6 root 2583: /* An ERROR_MARK occurs for various reasons including invalid data type. */
2584: if (TREE_TYPE (index_expr) != error_mark_node)
1.1.1.2 root 2585: {
1.1.1.16 root 2586: /* If switch expression was an enumerated type, check that all
2587: enumeration literals are covered by the cases.
2588: No sense trying this if there's a default case, however. */
2589:
2590: if (!thiscase->data.case_stmt.default_label
2591: && TREE_CODE (TREE_TYPE (orig_index)) == ENUMERAL_TYPE
1.1.1.18 root 2592: && TREE_CODE (index_expr) != INTEGER_CST
1.1.1.16 root 2593: && warn_switch)
1.1.1.18 root 2594: check_for_full_enumeration_handling (TREE_TYPE (orig_index));
1.1.1.16 root 2595:
1.1.1.2 root 2596: /* If we don't have a default-label, create one here,
2597: after the body of the switch. */
1.1.1.13 root 2598: if (thiscase->data.case_stmt.default_label == 0)
2599: {
2600: thiscase->data.case_stmt.default_label
2601: = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
2602: expand_label (thiscase->data.case_stmt.default_label);
2603: }
2604: default_label = label_rtx (thiscase->data.case_stmt.default_label);
1.1.1.2 root 2605:
2606: before_case = get_last_insn ();
2607:
1.1.1.13 root 2608: /* Simplify the case-list before we count it. */
2609: group_case_nodes (thiscase->data.case_stmt.case_list);
2610:
1.1.1.2 root 2611: /* Get upper and lower bounds of case values.
2612: Also convert all the case values to the index expr's data type. */
2613:
1.1.1.13 root 2614: count = 0;
2615: for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
2616: {
2617: /* Check low and high label values are integers. */
2618: if (TREE_CODE (n->low) != INTEGER_CST)
2619: abort ();
2620: if (TREE_CODE (n->high) != INTEGER_CST)
2621: abort ();
2622:
2623: n->low = convert (TREE_TYPE (index_expr), n->low);
2624: n->high = convert (TREE_TYPE (index_expr), n->high);
2625:
2626: /* Count the elements and track the largest and smallest
2627: of them (treating them as signed even if they are not). */
2628: if (count++ == 0)
2629: {
2630: minval = n->low;
2631: maxval = n->high;
2632: }
2633: else
2634: {
2635: if (INT_CST_LT (n->low, minval))
2636: minval = n->low;
2637: if (INT_CST_LT (maxval, n->high))
2638: maxval = n->high;
2639: }
2640: /* A range counts double, since it requires two compares. */
2641: if (! tree_int_cst_equal (n->low, n->high))
2642: count++;
2643: }
1.1.1.2 root 2644:
2645: /* Compute span of values. */
2646: if (count != 0)
2647: range = combine (MINUS_EXPR, maxval, minval);
2648:
2649: if (count == 0 || TREE_CODE (TREE_TYPE (index_expr)) == ERROR_MARK)
2650: {
2651: expand_expr (index_expr, const0_rtx, VOIDmode, 0);
2652: emit_queue ();
2653: emit_jump (default_label);
2654: }
2655: /* If range of values is much bigger than number of values,
2656: make a sequence of conditional branches instead of a dispatch.
2657: If the switch-index is a constant, do it this way
2658: because we can optimize it. */
2659: else if (TREE_INT_CST_HIGH (range) != 0
1.1 root 2660: #ifdef HAVE_casesi
1.1.1.2 root 2661: || count < 4
1.1 root 2662: #else
1.1.1.2 root 2663: /* If machine does not have a case insn that compares the
2664: bounds, this means extra overhead for dispatch tables
2665: which raises the threshold for using them. */
2666: || count < 5
1.1 root 2667: #endif
1.1.1.2 root 2668: || (unsigned) (TREE_INT_CST_LOW (range)) > 10 * count
2669: || TREE_CODE (index_expr) == INTEGER_CST)
2670: {
2671: index = expand_expr (index_expr, 0, VOIDmode, 0);
1.1.1.17 root 2672:
2673: /* If the index is a short or char that we do not have
2674: an insn to handle comparisons directly, convert it to
2675: a full integer now, rather than letting each comparison
2676: generate the conversion. */
2677:
2678: if ((GET_MODE (index) == QImode || GET_MODE (index) == HImode)
2679: && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code
2680: == CODE_FOR_nothing))
2681: index = convert_to_mode (SImode, index, unsignedp);
2682:
1.1.1.2 root 2683: emit_queue ();
1.1.1.14 root 2684: do_pending_stack_adjust ();
1.1 root 2685:
1.1.1.2 root 2686: index = protect_from_queue (index, 0);
2687: if (GET_CODE (index) == MEM)
2688: index = copy_to_reg (index);
1.1.1.14 root 2689: if (GET_CODE (index) == CONST_INT
2690: || TREE_CODE (index_expr) == INTEGER_CST)
1.1.1.2 root 2691: {
1.1.1.14 root 2692: /* Make a tree node with the proper constant value
2693: if we don't already have one. */
2694: if (TREE_CODE (index_expr) != INTEGER_CST)
2695: {
1.1.1.17 root 2696: index_expr
2697: = build_int_2 (INTVAL (index),
2698: !unsignedp && INTVAL (index) >= 0 ? 0 : -1);
1.1.1.14 root 2699: index_expr = convert (TREE_TYPE (index_expr), index_expr);
2700: }
2701:
1.1.1.13 root 2702: /* For constant index expressions we need only
2703: issue a unconditional branch to the appropriate
2704: target code. The job of removing any unreachable
2705: code is left to the optimisation phase if the
2706: "-O" option is specified. */
2707: for (n = thiscase->data.case_stmt.case_list;
2708: n;
2709: n = n->right)
2710: {
2711: if (! tree_int_cst_lt (index_expr, n->low)
2712: && ! tree_int_cst_lt (n->high, index_expr))
2713: break;
2714: }
2715: if (n)
2716: emit_jump (label_rtx (n->code_label));
1.1.1.14 root 2717: else
2718: emit_jump (default_label);
1.1.1.13 root 2719: }
2720: else
2721: {
2722: /* If the index expression is not constant we generate
2723: a binary decision tree to select the appropriate
2724: target code. This is done as follows:
2725:
2726: The list of cases is rearranged into a binary tree,
2727: nearly optimal assuming equal probability for each case.
2728:
2729: The tree is transformed into RTL, eliminating
2730: redundant test conditions at the same time.
2731:
2732: If program flow could reach the end of the
2733: decision tree an unconditional jump to the
2734: default code is emitted. */
2735: balance_case_nodes (&thiscase->data.case_stmt.case_list, 0);
2736: emit_case_nodes (index, thiscase->data.case_stmt.case_list,
1.1.1.17 root 2737: default_label, unsignedp);
1.1.1.13 root 2738: emit_jump_if_reachable (default_label);
1.1.1.2 root 2739: }
2740: }
2741: else
2742: {
1.1 root 2743: #ifdef HAVE_casesi
1.1.1.3 root 2744: /* Convert the index to SImode. */
1.1.1.2 root 2745: if (TYPE_MODE (TREE_TYPE (index_expr)) == DImode)
2746: {
1.1.1.3 root 2747: index_expr = build (MINUS_EXPR, TREE_TYPE (index_expr),
2748: index_expr, minval);
1.1.1.2 root 2749: minval = integer_zero_node;
2750: }
1.1.1.3 root 2751: if (TYPE_MODE (TREE_TYPE (index_expr)) != SImode)
2752: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
2753: index_expr);
1.1.1.2 root 2754: index = expand_expr (index_expr, 0, VOIDmode, 0);
2755: emit_queue ();
2756: index = protect_from_queue (index, 0);
2757: do_pending_stack_adjust ();
2758:
2759: emit_jump_insn (gen_casesi (index, expand_expr (minval, 0, VOIDmode, 0),
2760: expand_expr (range, 0, VOIDmode, 0),
2761: table_label, default_label));
1.1 root 2762: #else
2763: #ifdef HAVE_tablejump
1.1.1.3 root 2764: index_expr = convert (type_for_size (GET_MODE_BITSIZE (SImode), 0),
1.1.1.2 root 2765: build (MINUS_EXPR, TREE_TYPE (index_expr),
2766: index_expr, minval));
2767: index = expand_expr (index_expr, 0, VOIDmode, 0);
2768: emit_queue ();
2769: index = protect_from_queue (index, 0);
2770: do_pending_stack_adjust ();
2771:
2772: do_tablejump (index,
2773: gen_rtx (CONST_INT, VOIDmode, TREE_INT_CST_LOW (range)),
2774: table_label, default_label);
1.1 root 2775: #else
1.1.1.2 root 2776: lossage;
2777: #endif /* not HAVE_tablejump */
2778: #endif /* not HAVE_casesi */
2779:
2780: /* Get table of labels to jump to, in order of case index. */
2781:
2782: ncases = TREE_INT_CST_LOW (range) + 1;
2783: labelvec = (rtx *) alloca (ncases * sizeof (rtx));
2784: bzero (labelvec, ncases * sizeof (rtx));
1.1 root 2785:
1.1.1.13 root 2786: for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
2787: {
2788: register int i
2789: = TREE_INT_CST_LOW (n->low) - TREE_INT_CST_LOW (minval);
2790:
2791: while (i + TREE_INT_CST_LOW (minval)
2792: <= TREE_INT_CST_LOW (n->high))
2793: labelvec[i++]
2794: = gen_rtx (LABEL_REF, Pmode, label_rtx (n->code_label));
2795: }
1.1.1.2 root 2796:
2797: /* Fill in the gaps with the default. */
2798: for (i = 0; i < ncases; i++)
2799: if (labelvec[i] == 0)
2800: labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label);
2801:
2802: /* Output the table */
2803: emit_label (table_label);
1.1 root 2804:
2805: #ifdef CASE_VECTOR_PC_RELATIVE
1.1.1.2 root 2806: emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE,
2807: gen_rtx (LABEL_REF, Pmode, table_label),
2808: gen_rtvec_v (ncases, labelvec)));
1.1 root 2809: #else
1.1.1.2 root 2810: emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE,
2811: gen_rtvec_v (ncases, labelvec)));
1.1 root 2812: #endif
1.1.1.2 root 2813: /* If the case insn drops through the table,
2814: after the table we must jump to the default-label.
2815: Otherwise record no drop-through after the table. */
2816: #ifdef CASE_DROPS_THROUGH
2817: emit_jump (default_label);
2818: #else
2819: emit_barrier ();
2820: #endif
2821: }
2822:
2823: reorder_insns (NEXT_INSN (before_case), get_last_insn (),
2824: thiscase->data.case_stmt.start);
2825: }
2826: if (thiscase->exit_label)
2827: emit_label (thiscase->exit_label);
2828:
2829: POPSTACK (case_stack);
2830: }
2831:
2832: /* Generate code to jump to LABEL if OP1 and OP2 are equal. */
2833:
1.1.1.14 root 2834: static void
2835: do_jump_if_equal (op1, op2, label, unsignedp)
1.1.1.2 root 2836: rtx op1, op2, label;
1.1.1.14 root 2837: int unsignedp;
1.1.1.2 root 2838: {
2839: if (GET_CODE (op1) == CONST_INT
2840: && GET_CODE (op2) == CONST_INT)
2841: {
2842: if (INTVAL (op1) == INTVAL (op2))
2843: emit_jump (label);
2844: }
2845: else
2846: {
1.1.1.14 root 2847: emit_cmp_insn (op1, op2, 0, unsignedp, 0);
1.1.1.2 root 2848: emit_jump_insn (gen_beq (label));
2849: }
1.1 root 2850: }
2851:
1.1.1.13 root 2852: /* Scan an ordered list of case nodes
2853: combining those with consecutive values or ranges.
2854:
2855: Eg. three separate entries 1: 2: 3: become one entry 1..3: */
2856:
2857: static void
2858: group_case_nodes (head)
2859: case_node_ptr head;
2860: {
2861: case_node_ptr node = head;
2862:
2863: while (node)
2864: {
2865: rtx lb = next_real_insn (label_rtx (node->code_label));
2866: case_node_ptr np = node;
2867:
2868: /* Try to group the successors of NODE with NODE. */
2869: while (((np = np->right) != 0)
2870: /* Do they jump to the same place? */
2871: && next_real_insn (label_rtx (np->code_label)) == lb
2872: /* Are their ranges consecutive? */
2873: && tree_int_cst_equal (np->low,
2874: combine (PLUS_EXPR, node->high,
1.1.1.19 root 2875: build_int_2 (1, 0)))
2876: /* An overflow is not consecutive. */
2877: && tree_int_cst_lt (node->high,
2878: combine (PLUS_EXPR, node->high,
2879: build_int_2 (1, 0))))
1.1.1.13 root 2880: {
2881: node->high = np->high;
2882: }
2883: /* NP is the first node after NODE which can't be grouped with it.
2884: Delete the nodes in between, and move on to that node. */
2885: node->right = np;
2886: node = np;
2887: }
2888: }
2889:
2890: /* Take an ordered list of case nodes
2891: and transform them into a near optimal binary tree,
2892: on the assumtion that any target code selection value is as
2893: likely as any other.
2894:
2895: The transformation is performed by splitting the ordered
2896: list into two equal sections plus a pivot. The parts are
2897: then attached to the pivot as left and right branches. Each
2898: branch is is then transformed recursively. */
2899:
2900: static void
2901: balance_case_nodes (head, parent)
2902: case_node_ptr *head;
2903: case_node_ptr parent;
2904: {
2905: register case_node_ptr np;
2906:
2907: np = *head;
2908: if (np)
2909: {
2910: int i = 0;
2911: int ranges = 0;
2912: register case_node_ptr *npp;
2913: case_node_ptr left;
2914:
2915: /* Count the number of entries on branch.
2916: Also count the ranges. */
2917: while (np)
2918: {
2919: if (!tree_int_cst_equal (np->low, np->high))
2920: ranges++;
2921: i++;
2922: np = np->right;
2923: }
2924: if (i > 2)
2925: {
2926: /* Split this list if it is long enough for that to help. */
2927: npp = head;
2928: left = *npp;
2929: /* If there are just three nodes, split at the middle one. */
2930: if (i == 3)
2931: npp = &(*npp)->right;
2932: else
2933: {
2934: /* Find the place in the list that bisects the list's total cost,
2935: where ranges count as 2.
2936: Here I gets half the total cost. */
2937: i = (i + ranges + 1) / 2;
2938: while (1)
2939: {
2940: /* Skip nodes while their cost does not reach that amount. */
2941: if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
2942: i--;
2943: i--;
2944: if (i <= 0)
2945: break;
2946: npp = &(*npp)->right;
2947: }
2948: }
2949: *head = np = *npp;
2950: *npp = 0;
2951: np->parent = parent;
2952: np->left = left;
2953:
2954: /* Optimize each of the two split parts. */
2955: balance_case_nodes (&np->left, np);
2956: balance_case_nodes (&np->right, np);
2957: }
2958: else
2959: {
2960: /* Else leave this branch as one level,
2961: but fill in `parent' fields. */
2962: np = *head;
2963: np->parent = parent;
2964: for (; np->right; np = np->right)
2965: np->right->parent = np;
2966: }
2967: }
2968: }
2969:
2970: /* Search the parent sections of the case node tree
2971: to see if a test for the lower bound of NODE would be redundant.
2972:
2973: The instructions to synthesis the case decision tree are
2974: output in the same order as nodes are processed so it is
2975: known that if a parent node checks the range of the current
2976: node minus one that the current node is bounded at its lower
2977: span. Thus the test would be redundant. */
2978:
2979: static int
2980: node_has_low_bound (node)
2981: case_node_ptr node;
2982: {
2983: tree low_minus_one;
2984: case_node_ptr pnode;
2985:
2986: if (node->left)
2987: {
2988: low_minus_one = combine (MINUS_EXPR, node->low, build_int_2 (1, 0));
1.1.1.14 root 2989: /* Avoid the screw case of overflow where low_minus_one is > low. */
2990: if (tree_int_cst_lt (low_minus_one, node->low))
2991: for (pnode = node->parent; pnode; pnode = pnode->parent)
2992: {
2993: if (tree_int_cst_equal (low_minus_one, pnode->high))
2994: return 1;
2995: /* If a parent node has a left branch we know that none
2996: of its parents can have a high bound of our target
2997: minus one so we abort the search. */
2998: if (node->left)
2999: break;
3000: }
1.1.1.13 root 3001: }
3002: return 0;
3003: }
3004:
3005: /* Search the parent sections of the case node tree
3006: to see if a test for the upper bound of NODE would be redundant.
3007:
3008: The instructions to synthesis the case decision tree are
3009: output in the same order as nodes are processed so it is
3010: known that if a parent node checks the range of the current
3011: node plus one that the current node is bounded at its upper
3012: span. Thus the test would be redundant. */
3013:
3014: static int
3015: node_has_high_bound (node)
3016: case_node_ptr node;
3017: {
3018: tree high_plus_one;
3019: case_node_ptr pnode;
3020:
3021: if (node->right == 0)
3022: {
3023: high_plus_one = combine (PLUS_EXPR, node->high, build_int_2 (1, 0));
1.1.1.14 root 3024: /* Avoid the screw case of overflow where high_plus_one is > high. */
3025: if (tree_int_cst_lt (node->high, high_plus_one))
3026: for (pnode = node->parent; pnode; pnode = pnode->parent)
3027: {
3028: if (tree_int_cst_equal (high_plus_one, pnode->low))
3029: return 1;
3030: /* If a parent node has a right branch we know that none
3031: of its parents can have a low bound of our target
3032: plus one so we abort the search. */
3033: if (node->right)
3034: break;
3035: }
1.1.1.13 root 3036: }
3037: return 0;
3038: }
3039:
3040: /* Search the parent sections of the
3041: case node tree to see if both tests for the upper and lower
3042: bounds of NODE would be redundant. */
3043:
3044: static int
3045: node_is_bounded (node)
3046: case_node_ptr node;
3047: {
3048: if (node->left || node->right)
3049: return 0;
3050: return node_has_low_bound (node) && node_has_high_bound (node);
3051: }
3052:
3053: /* Emit an unconditional jump to LABEL unless it would be dead code. */
3054:
3055: static void
3056: emit_jump_if_reachable (label)
3057: rtx label;
3058: {
3059: rtx last_insn;
3060:
3061: if (GET_CODE (get_last_insn ()) != BARRIER)
3062: emit_jump (label);
3063: }
3064:
3065: /* Emit step-by-step code to select a case for the value of INDEX.
3066: The thus generated decision tree follows the form of the
3067: case-node binary tree NODE, whose nodes represent test conditions.
1.1.1.14 root 3068: UNSIGNEDP is nonzero if we should do unsigned comparisons.
1.1.1.13 root 3069:
3070: Care is taken to prune redundant tests from the decision tree
3071: by detecting any boundary conditions already checked by
3072: emitted rtx. (See node_has_high_bound, node_has_low_bound
3073: and node_is_bounded, above.)
3074:
3075: Where the test conditions can be shown to be redundant we emit
3076: an unconditional jump to the target code. As a further
3077: optimization, the subordinates of a tree node are examined to
3078: check for bounded nodes. In this case conditional and/or
3079: unconditional jumps as a result of the boundary check for the
3080: current node are arranged to target the subordinates associated
3081: code for out of bound conditions on the current node node. */
3082:
3083: static void
1.1.1.14 root 3084: emit_case_nodes (index, node, default_label, unsignedp)
3085: rtx index;
1.1.1.13 root 3086: case_node_ptr node;
1.1.1.16 root 3087: rtx default_label;
1.1.1.14 root 3088: int unsignedp;
1.1.1.13 root 3089: {
1.1.1.14 root 3090: /* If INDEX has an unsigned type, we must make unsigned branches. */
3091: typedef rtx rtx_function ();
3092: rtx_function *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt;
3093: rtx_function *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge;
3094: rtx_function *gen_blt_pat = unsignedp ? gen_bltu : gen_blt;
3095: rtx_function *gen_ble_pat = unsignedp ? gen_bleu : gen_ble;
3096:
1.1.1.13 root 3097: if (node->test_label)
3098: {
3099: /* If this test node requires a label it follows that
3100: it must be preceeded by an unconditional branch.
3101: If control can pass to this point we can assume that
3102: a "br default" is in order. */
3103: emit_jump_if_reachable (default_label);
3104: expand_label (node->test_label);
3105: }
3106: if (tree_int_cst_equal (node->low, node->high))
3107: {
3108: /* Node is single valued. */
3109: do_jump_if_equal (index, expand_expr (node->low, 0, VOIDmode, 0),
1.1.1.14 root 3110: label_rtx (node->code_label), unsignedp);
1.1.1.13 root 3111: if (node->right)
3112: {
3113: if (node->left)
3114: {
3115: /* This node has children on either side. */
1.1.1.17 root 3116: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
1.1.1.13 root 3117:
3118: if (node_is_bounded (node->right))
3119: {
1.1.1.17 root 3120: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
1.1.1.13 root 3121: if (node_is_bounded (node->left))
3122: emit_jump (label_rtx (node->left->code_label));
3123: else
1.1.1.14 root 3124: emit_case_nodes (index, node->left,
3125: default_label, unsignedp);
1.1.1.13 root 3126: }
3127: else
3128: {
3129: if (node_is_bounded (node->left))
1.1.1.17 root 3130: emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
1.1.1.13 root 3131: else
3132: {
3133: node->right->test_label =
3134: build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1.1.1.17 root 3135: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
1.1.1.14 root 3136: emit_case_nodes (index, node->left,
3137: default_label, unsignedp);
1.1.1.13 root 3138: }
1.1.1.14 root 3139: emit_case_nodes (index, node->right,
3140: default_label, unsignedp);
1.1.1.13 root 3141: }
3142: }
3143: else
3144: {
3145: /* Here we have a right child but no left
3146: so we issue conditional branch to default
3147: and process the right child. */
3148:
3149: /* Omit the conditional branch to default
3150: if we it avoid only one right child;
3151: it costs too much space to save so little time. */
3152: if (node->right->right && !node_has_low_bound (node))
1.1.1.14 root 3153: {
1.1.1.17 root 3154: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3155: emit_jump_insn ((*gen_blt_pat) (default_label));
1.1.1.14 root 3156: }
1.1.1.13 root 3157: if (node_is_bounded (node->right))
3158: emit_jump (label_rtx (node->right->code_label));
3159: else
1.1.1.14 root 3160: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3161: }
3162: }
3163: else if (node->left)
3164: {
3165: if (node_is_bounded (node->left))
3166: emit_jump (label_rtx (node->left->code_label));
3167: else
1.1.1.14 root 3168: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3169: }
3170: }
3171: else
3172: {
3173: /* Node is a range. */
3174: if (node->right)
3175: {
3176: if (node->left)
3177: {
1.1.1.17 root 3178: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
1.1.1.13 root 3179: if (node_is_bounded (node->right))
3180: {
3181: /* Right hand node is fully bounded so we can
3182: eliminate any testing and branch directly
3183: to the target code. */
1.1.1.17 root 3184: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
1.1.1.13 root 3185: }
3186: else
3187: {
3188: /* Right hand node requires testing so create
3189: a label to put on the cmp code. */
3190: node->right->test_label =
3191: build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
1.1.1.17 root 3192: emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->test_label)));
1.1.1.13 root 3193: }
1.1.1.17 root 3194: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3195: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3196: if (node_is_bounded (node->left))
3197: {
3198: /* Left hand node is fully bounded so we can
3199: eliminate any testing and branch directly
3200: to the target code. */
3201: emit_jump (label_rtx (node->left->code_label));
3202: }
3203: else
1.1.1.14 root 3204: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3205: /* If right node has been given a test label above
3206: we must process it now. */
3207: if (node->right->test_label)
1.1.1.14 root 3208: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3209: }
3210: else
3211: {
3212: if (!node_has_low_bound (node))
3213: {
1.1.1.17 root 3214: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3215: emit_jump_insn ((*gen_blt_pat) (default_label));
1.1.1.13 root 3216: }
1.1.1.17 root 3217: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3218: emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3219: if (node_is_bounded (node->right))
3220: {
3221: /* Right hand node is fully bounded so we can
3222: eliminate any testing and branch directly
3223: to the target code. */
3224: emit_jump (label_rtx (node->right->code_label));
3225: }
3226: else
1.1.1.14 root 3227: emit_case_nodes (index, node->right, default_label, unsignedp);
1.1.1.13 root 3228: }
3229: }
3230: else if (node->left)
3231: {
3232: if (!node_has_high_bound (node))
3233: {
1.1.1.17 root 3234: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3235: emit_jump_insn ((*gen_bgt_pat) (default_label));
1.1.1.13 root 3236: }
1.1.1.17 root 3237: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3238: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3239: if (node_is_bounded (node->left))
3240: {
3241: /* Left hand node is fully bounded so we can
3242: eliminate any testing and branch directly
3243: to the target code. */
3244: emit_jump (label_rtx (node->left->code_label));
3245: }
3246: else
1.1.1.14 root 3247: emit_case_nodes (index, node->left, default_label, unsignedp);
1.1.1.13 root 3248: }
3249: else
3250: {
3251: /* Node has no children so we check low and
3252: high bounds to remove redundant tests. In practice
3253: only one of the limits may be bounded or the parent
3254: node will have emmited a jump to our target code. */
3255: if (!node_has_high_bound (node))
3256: {
1.1.1.17 root 3257: emit_cmp_insn (index, expand_expr (node->high, 0, VOIDmode, 0), 0, unsignedp, 0);
3258: emit_jump_insn ((*gen_bgt_pat) (default_label));
1.1.1.13 root 3259: }
3260: if (!node_has_low_bound (node))
3261: {
1.1.1.17 root 3262: emit_cmp_insn (index, expand_expr (node->low, 0, VOIDmode, 0), 0, unsignedp, 0);
3263: emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));
1.1.1.13 root 3264: }
3265: /* We allow the default case to drop through since
3266: it will picked up by calls to `jump_if_reachable'
3267: either on the next test label or at the end of
3268: the decision tree emission. */
3269: }
3270: }
3271: }
3272:
1.1.1.2 root 3273: /* Allocate fixed slots in the stack frame of the current function. */
1.1 root 3274:
3275: /* Return size needed for stack frame based on slots so far allocated. */
3276:
3277: int
3278: get_frame_size ()
3279: {
1.1.1.2 root 3280: #ifdef FRAME_GROWS_DOWNWARD
1.1.1.17 root 3281: return -frame_offset + STARTING_FRAME_OFFSET;
1.1.1.2 root 3282: #else
1.1.1.17 root 3283: return frame_offset - STARTING_FRAME_OFFSET;
1.1.1.2 root 3284: #endif
1.1 root 3285: }
3286:
3287: /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
3288: with machine mode MODE. */
3289:
3290: rtx
3291: assign_stack_local (mode, size)
3292: enum machine_mode mode;
3293: int size;
3294: {
1.1.1.2 root 3295: register rtx x, addr;
1.1.1.4 root 3296: int bigend_correction = 0;
1.1 root 3297:
1.1.1.2 root 3298: frame_pointer_needed = 1;
1.1 root 3299:
3300: /* Make each stack slot a multiple of the main allocation unit. */
3301: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
3302: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
3303: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
3304:
1.1.1.4 root 3305: /* On a big-endian machine, if we are allocating more space than we will use,
3306: use the least significant bytes of those that are allocated. */
3307: #ifdef BYTES_BIG_ENDIAN
3308: if (mode != BLKmode)
3309: bigend_correction = size - GET_MODE_SIZE (mode);
3310: #endif
3311:
1.1 root 3312: #ifdef FRAME_GROWS_DOWNWARD
3313: frame_offset -= size;
3314: #endif
1.1.1.2 root 3315: addr = gen_rtx (PLUS, Pmode, frame_pointer_rtx,
1.1.1.4 root 3316: gen_rtx (CONST_INT, VOIDmode,
3317: (frame_offset + bigend_correction)));
1.1 root 3318: #ifndef FRAME_GROWS_DOWNWARD
3319: frame_offset += size;
3320: #endif
3321:
1.1.1.2 root 3322: if (! memory_address_p (mode, addr))
3323: invalid_stack_slot = 1;
3324:
3325: x = gen_rtx (MEM, mode, addr);
3326:
1.1.1.13 root 3327: stack_slot_list = gen_rtx (EXPR_LIST, VOIDmode, x, stack_slot_list);
3328:
1.1.1.2 root 3329: return x;
1.1 root 3330: }
3331:
1.1.1.2 root 3332: /* Retroactively move an auto variable from a register to a stack slot.
3333: This is done when an address-reference to the variable is seen. */
1.1 root 3334:
1.1.1.2 root 3335: void
3336: put_var_into_stack (decl)
3337: tree decl;
3338: {
3339: register rtx reg = DECL_RTL (decl);
3340: register rtx new;
1.1 root 3341:
1.1.1.2 root 3342: /* No need to do anything if decl has no rtx yet
3343: since in that case caller is setting TREE_ADDRESSABLE
3344: and a stack slot will be assigned when the rtl is made. */
3345: if (reg == 0)
3346: return;
3347: if (GET_CODE (reg) != REG)
3348: return;
3349:
3350: new = parm_stack_loc (reg);
3351: if (new == 0)
3352: new = assign_stack_local (GET_MODE (reg), GET_MODE_SIZE (GET_MODE (reg)));
3353:
1.1.1.10 root 3354: XEXP (reg, 0) = XEXP (new, 0);
3355: /* `volatil' bit means one thing for MEMs, another entirely for REGs. */
3356: REG_USERVAR_P (reg) = 0;
3357: PUT_CODE (reg, MEM);
3358:
1.1.1.2 root 3359: /* If this is a memory ref that contains aggregate components,
3360: mark it as such for cse and loop optimize. */
1.1.1.10 root 3361: MEM_IN_STRUCT_P (reg)
1.1.1.2 root 3362: = (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
3363: || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
3364: || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE);
3365:
3366: fixup_var_refs (reg);
3367: }
3368:
1.1 root 3369: static void
1.1.1.2 root 3370: fixup_var_refs (var)
3371: rtx var;
1.1 root 3372: {
1.1.1.10 root 3373: extern rtx sequence_stack;
3374: rtx stack = sequence_stack;
3375: tree pending;
3376:
3377: stack = sequence_stack;
3378:
3379: /* Must scan all insns for stack-refs that exceed the limit. */
3380: fixup_var_refs_insns (var, get_insns (), stack == 0);
3381:
3382: /* Scan all pending sequences too. */
3383: for (; stack; stack = XEXP (XEXP (stack, 1), 1))
3384: {
3385: push_to_sequence (XEXP (stack, 0));
3386: fixup_var_refs_insns (var, XEXP (stack, 0),
3387: XEXP (XEXP (stack, 1), 1) == 0);
1.1.1.17 root 3388: /* Update remembered end of sequence
3389: in case we added an insn at the end. */
3390: XEXP (XEXP (stack, 1), 0) = get_last_insn ();
1.1.1.10 root 3391: end_sequence ();
3392: }
3393:
3394: /* Scan all waiting RTL_EXPRs too. */
3395: for (pending = rtl_expr_chain; pending; pending = TREE_CHAIN (pending))
3396: {
3397: rtx seq = RTL_EXPR_SEQUENCE (TREE_VALUE (pending));
3398: if (seq != const0_rtx && seq != 0)
3399: {
3400: push_to_sequence (seq);
3401: fixup_var_refs_insns (var, seq, 0);
3402: end_sequence ();
3403: }
3404: }
3405: }
1.1.1.2 root 3406:
1.1.1.10 root 3407: /* Scan the insn-chain starting with INSN for refs to VAR
3408: and fix them up. TOPLEVEL is nonzero if this chain is the
3409: main chain of insns for the current function. */
3410:
3411: static void
3412: fixup_var_refs_insns (var, insn, toplevel)
3413: rtx var;
3414: rtx insn;
3415: int toplevel;
3416: {
3417: while (insn)
1.1.1.2 root 3418: {
3419: rtx next = NEXT_INSN (insn);
1.1.1.13 root 3420: rtx note;
1.1.1.2 root 3421: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
3422: || GET_CODE (insn) == JUMP_INSN)
3423: {
3424: /* The insn to load VAR from a home in the arglist
3425: is now a no-op. When we see it, just delete it. */
1.1.1.10 root 3426: if (toplevel
3427: && GET_CODE (PATTERN (insn)) == SET
1.1.1.2 root 3428: && SET_DEST (PATTERN (insn)) == var
3429: && rtx_equal_p (SET_SRC (PATTERN (insn)), var))
1.1.1.8 root 3430: {
3431: next = delete_insn (insn);
3432: if (insn == last_parm_insn)
3433: last_parm_insn = PREV_INSN (next);
3434: }
1.1.1.2 root 3435: else
3436: fixup_var_refs_1 (var, PATTERN (insn), insn);
1.1.1.13 root 3437: /* Also fix up any invalid exprs in the REG_NOTES of this insn.
3438: But don't touch other insns referred to by reg-notes;
3439: we will get them elsewhere. */
3440: for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
3441: if (GET_CODE (note) != INSN_LIST)
3442: XEXP (note, 0) = walk_fixup_memory_subreg (XEXP (note, 0), insn);
1.1.1.2 root 3443: }
3444: insn = next;
3445: }
3446: }
1.1.1.13 root 3447:
1.1.1.2 root 3448: static rtx
3449: fixup_var_refs_1 (var, x, insn)
3450: register rtx var;
3451: register rtx x;
3452: rtx insn;
3453: {
3454: register int i;
3455: RTX_CODE code = GET_CODE (x);
3456: register char *fmt;
3457: register rtx tem;
3458:
3459: switch (code)
3460: {
3461: case MEM:
3462: if (var == x)
3463: {
3464: x = fixup_stack_1 (x, insn);
3465: tem = gen_reg_rtx (GET_MODE (x));
1.1.1.18 root 3466: /* Put new insn before a CALL, before any USEs before it. */
3467: if (GET_CODE (insn) == CALL_INSN)
3468: while (PREV_INSN (insn) != 0 && GET_CODE (PREV_INSN (insn)) == INSN
3469: && GET_CODE (PATTERN (PREV_INSN (insn))) == USE)
3470: insn = PREV_INSN (insn);
1.1.1.2 root 3471: emit_insn_before (gen_move_insn (tem, x), insn);
3472: return tem;
3473: }
3474: break;
3475:
3476: case REG:
3477: case CC0:
3478: case PC:
3479: case CONST_INT:
3480: case CONST:
3481: case SYMBOL_REF:
3482: case LABEL_REF:
3483: case CONST_DOUBLE:
3484: return x;
3485:
3486: case SIGN_EXTRACT:
3487: case ZERO_EXTRACT:
3488: /* Note that in some cases those types of expressions are altered
3489: by optimize_bit_field, and do not survive to get here. */
3490: case SUBREG:
3491: tem = x;
3492: while (GET_CODE (tem) == SUBREG || GET_CODE (tem) == SIGN_EXTRACT
3493: || GET_CODE (tem) == ZERO_EXTRACT)
3494: tem = XEXP (tem, 0);
3495: if (tem == var)
3496: {
3497: x = fixup_stack_1 (x, insn);
3498: tem = gen_reg_rtx (GET_MODE (x));
1.1.1.7 root 3499: if (GET_CODE (x) == SUBREG)
1.1.1.13 root 3500: x = fixup_memory_subreg (x, insn);
1.1.1.2 root 3501: emit_insn_before (gen_move_insn (tem, x), insn);
3502: return tem;
3503: }
3504: break;
3505:
3506: case SET:
3507: /* First do special simplification of bit-field references. */
3508: if (GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
3509: || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
3510: optimize_bit_field (x, insn, 0);
3511: if (GET_CODE (SET_SRC (x)) == SIGN_EXTRACT
3512: || GET_CODE (SET_SRC (x)) == ZERO_EXTRACT)
3513: optimize_bit_field (x, insn, 0);
3514:
3515: {
3516: rtx dest = SET_DEST (x);
3517: rtx src = SET_SRC (x);
3518: rtx outerdest = dest;
3519: rtx outersrc = src;
3520:
3521: while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
3522: || GET_CODE (dest) == SIGN_EXTRACT
3523: || GET_CODE (dest) == ZERO_EXTRACT)
3524: dest = XEXP (dest, 0);
3525: while (GET_CODE (src) == SUBREG
3526: || GET_CODE (src) == SIGN_EXTRACT
3527: || GET_CODE (src) == ZERO_EXTRACT)
3528: src = XEXP (src, 0);
3529:
3530: /* If VAR does not appear at the top level of the SET
3531: just scan the lower levels of the tree. */
3532:
3533: if (src != var && dest != var)
3534: break;
3535:
3536: /* Clean up (SUBREG:SI (MEM:mode ...) 0)
3537: that may appear inside a SIGN_EXTRACT or ZERO_EXTRACT.
3538: This was legitimate when the MEM was a REG. */
3539:
3540: if ((GET_CODE (outerdest) == SIGN_EXTRACT
3541: || GET_CODE (outerdest) == ZERO_EXTRACT)
3542: && GET_CODE (XEXP (outerdest, 0)) == SUBREG
3543: && SUBREG_REG (XEXP (outerdest, 0)) == var)
1.1.1.13 root 3544: XEXP (outerdest, 0) = fixup_memory_subreg (XEXP (outerdest, 0), insn);
1.1.1.2 root 3545:
3546: if ((GET_CODE (outersrc) == SIGN_EXTRACT
3547: || GET_CODE (outersrc) == ZERO_EXTRACT)
3548: && GET_CODE (XEXP (outersrc, 0)) == SUBREG
3549: && SUBREG_REG (XEXP (outersrc, 0)) == var)
1.1.1.13 root 3550: XEXP (outersrc, 0) = fixup_memory_subreg (XEXP (outersrc, 0), insn);
1.1.1.2 root 3551:
1.1.1.18 root 3552: /* Make sure that the machine's SIGN_EXTRACT and ZERO_EXTRACT insns
3553: accept a memory operand. */
3554: #ifdef HAVE_extzv
3555: if (GET_CODE (outersrc) == ZERO_EXTRACT
3556: && ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
3557: (XEXP (outersrc, 0), VOIDmode)))
3558: XEXP (outersrc, 0) = src
3559: = fixup_var_refs_1 (var, XEXP (outersrc, 0), insn);
3560: #endif
3561: #ifdef HAVE_extv
3562: if (GET_CODE (outersrc) == SIGN_EXTRACT
3563: && ! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
3564: (XEXP (outersrc, 0), VOIDmode)))
3565: XEXP (outersrc, 0) = src
3566: = fixup_var_refs_1 (var, XEXP (outersrc, 0), insn);
3567: #endif
3568: #ifdef HAVE_insv
3569: if (GET_CODE (outerdest) == ZERO_EXTRACT
3570: && ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
3571: (XEXP (outerdest, 0), VOIDmode)))
3572: {
3573: rtx tem = gen_reg_rtx (GET_MODE (XEXP (outerdest, 0)));
3574:
3575: emit_insn_before (gen_move_insn (tem, XEXP (outerdest, 0)), insn);
3576: emit_insn_after (gen_move_insn (XEXP (outerdest, 0), tem), insn);
3577: dest = XEXP (outerdest, 0) = tem;
3578: }
3579: #endif
3580:
1.1.1.2 root 3581: /* Make sure a MEM inside a SIGN_EXTRACT has QImode
3582: since that's what bit-field insns want. */
3583:
3584: if ((GET_CODE (outerdest) == SIGN_EXTRACT
3585: || GET_CODE (outerdest) == ZERO_EXTRACT)
3586: && GET_CODE (XEXP (outerdest, 0)) == MEM
3587: && GET_MODE (XEXP (outerdest, 0)) != QImode)
3588: {
3589: XEXP (outerdest, 0) = copy_rtx (XEXP (outerdest, 0));
3590: PUT_MODE (XEXP (outerdest, 0), QImode);
1.1.1.17 root 3591: /* Adjust the address so the bit field starts within the byte
3592: addressed. This helps certain optimization patterns. */
3593: if (GET_CODE (XEXP (outerdest, 2)) == CONST_INT
3594: && offsettable_memref_p (XEXP (outerdest, 0)))
3595: {
3596: int count = INTVAL (XEXP (outerdest, 2));
3597: XEXP (outerdest, 0)
3598: = adj_offsettable_operand (XEXP (outerdest, 0),
3599: count / GET_MODE_BITSIZE (QImode));
3600: XEXP (outerdest, 2)
3601: = gen_rtx (CONST_INT, VOIDmode,
3602: count % GET_MODE_BITSIZE (QImode));
3603: }
1.1.1.2 root 3604: }
3605:
3606: if ((GET_CODE (outersrc) == SIGN_EXTRACT
3607: || GET_CODE (outersrc) == ZERO_EXTRACT)
3608: && GET_CODE (XEXP (outersrc, 0)) == MEM
3609: && GET_MODE (XEXP (outersrc, 0)) != QImode)
3610: {
3611: XEXP (outersrc, 0) = copy_rtx (XEXP (outersrc, 0));
3612: PUT_MODE (XEXP (outersrc, 0), QImode);
1.1.1.17 root 3613: /* Adjust the address so the bit field starts within the byte
3614: addressed. This helps certain optimization patterns. */
3615: if (GET_CODE (XEXP (outersrc, 2)) == CONST_INT
3616: && offsettable_memref_p (XEXP (outersrc, 0)))
3617: {
3618: int count = INTVAL (XEXP (outersrc, 2));
3619: XEXP (outersrc, 0)
3620: = adj_offsettable_operand (XEXP (outersrc, 0),
3621: count / GET_MODE_BITSIZE (QImode));
3622: XEXP (outersrc, 2)
3623: = gen_rtx (CONST_INT, VOIDmode,
3624: count % GET_MODE_BITSIZE (QImode));
3625: }
1.1.1.2 root 3626: }
3627:
3628: /* STRICT_LOW_PART is a no-op on memory references
3629: and it can cause combinations to be unrecognizable,
3630: so eliminate it. */
3631:
3632: if (dest == var && GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
3633: SET_DEST (x) = XEXP (SET_DEST (x), 0);
3634:
3635: /* An insn to copy VAR into or out of a register
3636: must be left alone, to avoid an infinite loop here.
1.1.1.9 root 3637: But do fix up the address of VAR's stack slot if nec,
3638: and fix up SUBREGs containing VAR
3639: (since they are now memory subregs). */
3640:
3641: if (GET_CODE (SET_SRC (x)) == REG || GET_CODE (SET_DEST (x)) == REG
3642: || (GET_CODE (SET_SRC (x)) == SUBREG
3643: && GET_CODE (SUBREG_REG (SET_SRC (x))) == REG)
1.1.1.2 root 3644: || (GET_CODE (SET_DEST (x)) == SUBREG
3645: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG))
1.1.1.9 root 3646: {
3647: if (src == var && GET_CODE (SET_SRC (x)) == SUBREG)
1.1.1.13 root 3648: SET_SRC (x) = fixup_memory_subreg (SET_SRC (x), insn);
1.1.1.9 root 3649: if (dest == var && GET_CODE (SET_DEST (x)) == SUBREG)
1.1.1.13 root 3650: SET_DEST (x) = fixup_memory_subreg (SET_DEST (x), insn);
1.1.1.9 root 3651: return fixup_stack_1 (x, insn);
3652: }
1.1.1.2 root 3653:
3654: /* Otherwise, storing into VAR must be handled specially
3655: by storing into a temporary and copying that into VAR
3656: with a new insn after this one. */
3657:
3658: if (dest == var)
3659: {
3660: rtx temp;
3661: rtx fixeddest;
3662: tem = SET_DEST (x);
1.1.1.12 root 3663: /* STRICT_LOW_PART can be discarded, around a MEM. */
1.1.1.2 root 3664: if (GET_CODE (tem) == STRICT_LOW_PART)
3665: tem = XEXP (tem, 0);
1.1.1.12 root 3666: /* Convert (SUBREG (MEM)) to a MEM in a changed mode. */
3667: if (GET_CODE (tem) == SUBREG)
1.1.1.13 root 3668: tem = fixup_memory_subreg (tem, insn);
1.1.1.12 root 3669: fixeddest = fixup_stack_1 (tem, insn);
1.1.1.2 root 3670: temp = gen_reg_rtx (GET_MODE (tem));
3671: emit_insn_after (gen_move_insn (fixeddest, temp), insn);
3672: SET_DEST (x) = temp;
3673: }
3674: }
3675: }
3676:
3677: /* Nothing special about this RTX; fix its operands. */
3678:
3679: fmt = GET_RTX_FORMAT (code);
3680: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3681: {
3682: if (fmt[i] == 'e')
3683: XEXP (x, i) = fixup_var_refs_1 (var, XEXP (x, i), insn);
3684: if (fmt[i] == 'E')
3685: {
3686: register int j;
3687: for (j = 0; j < XVECLEN (x, i); j++)
3688: XVECEXP (x, i, j)
3689: = fixup_var_refs_1 (var, XVECEXP (x, i, j), insn);
3690: }
3691: }
3692: return x;
3693: }
1.1.1.13 root 3694:
1.1.1.2 root 3695: /* Given X, an rtx of the form (SUBREG:m1 (MEM:m2 addr)),
1.1.1.13 root 3696: return an rtx (MEM:m1 newaddr) which is equivalent.
3697: If any insns must be emitted to compute NEWADDR, put them before INSN. */
1.1.1.2 root 3698:
3699: static rtx
1.1.1.13 root 3700: fixup_memory_subreg (x, insn)
1.1.1.2 root 3701: rtx x;
1.1.1.13 root 3702: rtx insn;
1.1.1.2 root 3703: {
3704: int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
3705: rtx addr = XEXP (SUBREG_REG (x), 0);
1.1.1.7 root 3706: enum machine_mode mode = GET_MODE (x);
1.1.1.13 root 3707: rtx saved, result;
1.1.1.2 root 3708:
3709: #ifdef BYTES_BIG_ENDIAN
1.1.1.8 root 3710: offset += (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
1.1.1.15 root 3711: - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
1.1.1.2 root 3712: #endif
1.1.1.13 root 3713: addr = plus_constant (addr, offset);
3714: if (memory_address_p (mode, addr))
3715: return change_address (SUBREG_REG (x), mode, addr);
3716: saved = start_sequence ();
3717: result = change_address (SUBREG_REG (x), mode, addr);
3718: emit_insn_before (gen_sequence (), insn);
3719: end_sequence (saved);
3720: return result;
3721: }
3722:
3723: /* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
3724: Replace subexpressions of X in place.
3725: If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
3726: Otherwise return X, with its contents possibly altered.
3727:
3728: If any insns must be emitted to compute NEWADDR, put them before INSN. */
3729:
3730: static rtx
3731: walk_fixup_memory_subreg (x, insn)
3732: register rtx x;
3733: rtx insn;
3734: {
3735: register enum rtx_code code;
3736: register char *fmt;
3737: register int i;
3738:
1.1.1.16 root 3739: if (x == 0)
3740: return 0;
3741:
1.1.1.13 root 3742: code = GET_CODE (x);
3743:
3744: if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
3745: return fixup_memory_subreg (x, insn);
3746:
3747: /* Nothing special about this RTX; fix its operands. */
3748:
3749: fmt = GET_RTX_FORMAT (code);
3750: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3751: {
3752: if (fmt[i] == 'e')
3753: XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn);
3754: if (fmt[i] == 'E')
3755: {
3756: register int j;
3757: for (j = 0; j < XVECLEN (x, i); j++)
3758: XVECEXP (x, i, j)
3759: = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn);
3760: }
3761: }
3762: return x;
1.1.1.2 root 3763: }
3764:
3765: #if 0
3766: /* Fix up any references to stack slots that are invalid memory addresses
3767: because they exceed the maximum range of a displacement. */
3768:
3769: void
3770: fixup_stack_slots ()
3771: {
3772: register rtx insn;
3773:
3774: /* Did we generate a stack slot that is out of range
3775: or otherwise has an invalid address? */
3776: if (invalid_stack_slot)
3777: {
3778: /* Yes. Must scan all insns for stack-refs that exceed the limit. */
3779: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3780: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
3781: || GET_CODE (insn) == JUMP_INSN)
3782: fixup_stack_1 (PATTERN (insn), insn);
3783: }
3784: }
3785: #endif
3786:
3787: /* For each memory ref within X, if it refers to a stack slot
3788: with an out of range displacement, put the address in a temp register
3789: (emitting new insns before INSN to load these registers)
3790: and alter the memory ref to use that register.
3791: Replace each such MEM rtx with a copy, to avoid clobberage. */
3792:
3793: static rtx
3794: fixup_stack_1 (x, insn)
3795: rtx x;
3796: rtx insn;
3797: {
3798: register int i;
3799: register RTX_CODE code = GET_CODE (x);
3800: register char *fmt;
3801:
3802: if (code == MEM)
3803: {
3804: register rtx ad = XEXP (x, 0);
3805: /* If we have address of a stack slot but it's not valid
3806: (displacement is too large), compute the sum in a register. */
3807: if (GET_CODE (ad) == PLUS
3808: && XEXP (ad, 0) == frame_pointer_rtx
3809: && GET_CODE (XEXP (ad, 1)) == CONST_INT)
3810: {
3811: rtx temp;
3812: if (memory_address_p (GET_MODE (x), ad))
3813: return x;
3814: temp = gen_reg_rtx (GET_MODE (ad));
3815: emit_insn_before (gen_move_insn (temp, ad), insn);
3816: return change_address (x, VOIDmode, temp);
3817: }
3818: return x;
3819: }
3820:
3821: fmt = GET_RTX_FORMAT (code);
3822: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3823: {
3824: if (fmt[i] == 'e')
3825: XEXP (x, i) = fixup_stack_1 (XEXP (x, i), insn);
3826: if (fmt[i] == 'E')
3827: {
3828: register int j;
3829: for (j = 0; j < XVECLEN (x, i); j++)
3830: XVECEXP (x, i, j) = fixup_stack_1 (XVECEXP (x, i, j), insn);
3831: }
3832: }
3833: return x;
1.1 root 3834: }
1.1.1.2 root 3835:
3836: /* Optimization: a bit-field instruction whose field
3837: happens to be a byte or halfword in memory
3838: can be changed to a move instruction.
1.1 root 3839:
1.1.1.2 root 3840: We call here when INSN is an insn to examine or store into a bit-field.
3841: BODY is the SET-rtx to be altered.
3842:
3843: EQUIV_MEM is the table `reg_equiv_mem' if that is available; else 0.
3844: (Currently this is called only from stmt.c, and EQUIV_MEM is always 0.) */
1.1 root 3845:
3846: static void
1.1.1.2 root 3847: optimize_bit_field (body, insn, equiv_mem)
3848: rtx body;
3849: rtx insn;
3850: rtx *equiv_mem;
1.1 root 3851: {
1.1.1.2 root 3852: register rtx bitfield;
3853: int destflag;
1.1 root 3854:
1.1.1.2 root 3855: if (GET_CODE (SET_DEST (body)) == SIGN_EXTRACT
3856: || GET_CODE (SET_DEST (body)) == ZERO_EXTRACT)
3857: bitfield = SET_DEST (body), destflag = 1;
3858: else
3859: bitfield = SET_SRC (body), destflag = 0;
3860:
3861: /* First check that the field being stored has constant size and position
3862: and is in fact a byte or halfword suitably aligned. */
3863:
3864: if (GET_CODE (XEXP (bitfield, 1)) == CONST_INT
3865: && GET_CODE (XEXP (bitfield, 2)) == CONST_INT
3866: && (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
3867: || INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (HImode))
3868: && INTVAL (XEXP (bitfield, 2)) % INTVAL (XEXP (bitfield, 1)) == 0)
1.1 root 3869: {
1.1.1.2 root 3870: register rtx memref = 0;
3871:
1.1.1.10 root 3872: /* Now check that the containing word is memory, not a register,
1.1.1.2 root 3873: and that it is safe to change the machine mode and to
3874: add something to the address. */
3875:
3876: if (GET_CODE (XEXP (bitfield, 0)) == MEM)
3877: memref = XEXP (bitfield, 0);
3878: else if (GET_CODE (XEXP (bitfield, 0)) == REG
1.1.1.8 root 3879: && equiv_mem != 0)
3880: memref = equiv_mem[REGNO (XEXP (bitfield, 0))];
1.1.1.2 root 3881: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
3882: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == MEM)
3883: memref = SUBREG_REG (XEXP (bitfield, 0));
3884: else if (GET_CODE (XEXP (bitfield, 0)) == SUBREG
3885: && equiv_mem != 0
1.1.1.8 root 3886: && GET_CODE (SUBREG_REG (XEXP (bitfield, 0))) == REG)
3887: memref = equiv_mem[REGNO (SUBREG_REG (XEXP (bitfield, 0)))];
1.1.1.2 root 3888:
3889: if (memref
3890: && ! mode_dependent_address_p (XEXP (memref, 0))
1.1.1.17 root 3891: && offsettable_address_p (0, GET_MODE (bitfield), XEXP (memref, 0)))
1.1 root 3892: {
1.1.1.2 root 3893: /* Now adjust the address, first for any subreg'ing
3894: that we are now getting rid of,
3895: and then for which byte of the word is wanted. */
3896:
3897: register int offset
3898: = INTVAL (XEXP (bitfield, 2)) / GET_MODE_BITSIZE (QImode);
3899: if (GET_CODE (XEXP (bitfield, 0)) == SUBREG)
3900: {
3901: offset += SUBREG_WORD (XEXP (bitfield, 0)) * UNITS_PER_WORD;
3902: #ifdef BYTES_BIG_ENDIAN
3903: offset -= (MIN (UNITS_PER_WORD,
3904: GET_MODE_SIZE (GET_MODE (XEXP (bitfield, 0))))
3905: - MIN (UNITS_PER_WORD,
3906: GET_MODE_SIZE (GET_MODE (memref))));
3907: #endif
3908: }
1.1.1.8 root 3909:
1.1.1.2 root 3910: memref = gen_rtx (MEM,
3911: (INTVAL (XEXP (bitfield, 1)) == GET_MODE_BITSIZE (QImode)
3912: ? QImode : HImode),
3913: XEXP (memref, 0));
1.1 root 3914:
1.1.1.2 root 3915: /* Store this memory reference where
3916: we found the bit field reference. */
1.1 root 3917:
1.1.1.2 root 3918: if (destflag)
1.1 root 3919: {
1.1.1.2 root 3920: SET_DEST (body)
1.1.1.17 root 3921: = adj_offsettable_operand (memref, offset);
1.1.1.2 root 3922: if (! CONSTANT_ADDRESS_P (SET_SRC (body)))
1.1 root 3923: {
1.1.1.2 root 3924: rtx src = SET_SRC (body);
3925: while (GET_CODE (src) == SUBREG
3926: && SUBREG_WORD (src) == 0)
3927: src = SUBREG_REG (src);
3928: if (GET_MODE (src) != GET_MODE (memref))
1.1.1.10 root 3929: src = gen_lowpart (GET_MODE (memref), SET_SRC (body));
1.1.1.2 root 3930: SET_SRC (body) = src;
1.1 root 3931: }
1.1.1.2 root 3932: else if (GET_MODE (SET_SRC (body)) != VOIDmode
3933: && GET_MODE (SET_SRC (body)) != GET_MODE (memref))
3934: /* This shouldn't happen because anything that didn't have
3935: one of these modes should have got converted explicitly
3936: and then referenced through a subreg.
3937: This is so because the original bit-field was
3938: handled by agg_mode and so its tree structure had
3939: the same mode that memref now has. */
3940: abort ();
3941: }
3942: else
3943: {
1.1.1.8 root 3944: rtx dest = SET_DEST (body);
3945:
3946: while (GET_CODE (dest) == SUBREG
3947: && SUBREG_WORD (dest) == 0)
3948: dest = SUBREG_REG (dest);
3949: SET_DEST (body) = dest;
3950:
1.1.1.17 root 3951: memref = adj_offsettable_operand (memref, offset);
1.1.1.8 root 3952: if (GET_MODE (dest) == GET_MODE (memref))
3953: SET_SRC (body) = memref;
3954: else
3955: {
1.1.1.10 root 3956: /* Convert the mem ref to the destination mode. */
3957: rtx last = get_last_insn ();
1.1.1.8 root 3958: rtx newreg = gen_reg_rtx (GET_MODE (dest));
1.1.1.10 root 3959: convert_move (newreg, memref,
3960: GET_CODE (SET_SRC (body)) == ZERO_EXTRACT);
3961: /* Put the conversion before the insn being fixed. */
3962: reorder_insns (NEXT_INSN (last), get_last_insn (),
3963: PREV_INSN (insn));
1.1.1.8 root 3964: SET_SRC (body) = newreg;
3965: }
1.1 root 3966: }
1.1.1.2 root 3967:
3968: /* Cause the insn to be re-recognized. */
3969:
3970: INSN_CODE (insn) = -1;
1.1 root 3971: }
3972: }
3973: }
3974:
3975: /* 1 + last pseudo register number used for loading a copy
3976: of a parameter of this function. */
3977:
3978: static int max_parm_reg;
3979:
1.1.1.2 root 3980: /* Vector indexed by REGNO, containing location on stack in which
3981: to put the parm which is nominally in pseudo register REGNO,
3982: if we discover that that parm must go in the stack. */
3983: static rtx *parm_reg_stack_loc;
3984:
3985: int
3986: max_parm_reg_num ()
3987: {
3988: return max_parm_reg;
3989: }
3990:
3991: /* Return the first insn following those generated by `assign_parms'. */
3992:
3993: rtx
3994: get_first_nonparm_insn ()
3995: {
3996: if (last_parm_insn)
3997: return NEXT_INSN (last_parm_insn);
3998: return get_insns ();
3999: }
4000:
4001: /* Get the stack home of a REG rtx that is one of this function's parameters.
4002: This is called rather than assign a new stack slot as a local.
4003: Return 0 if there is no existing stack home suitable for such use. */
4004:
4005: static rtx
4006: parm_stack_loc (reg)
4007: rtx reg;
4008: {
4009: if (REGNO (reg) < max_parm_reg)
4010: return parm_reg_stack_loc[REGNO (reg)];
4011: return 0;
4012: }
4013:
1.1.1.17 root 4014: /* Return 1 if EXP returns an aggregate value, for which an address
4015: must be passed to the function or returned by the function. */
4016:
4017: int
4018: aggregate_value_p (exp)
4019: tree exp;
4020: {
4021: if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
4022: return 1;
4023: if (RETURN_IN_MEMORY (TREE_TYPE (exp)))
4024: return 1;
4025: if (flag_pcc_struct_return
4026: && (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
4027: || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE))
4028: return 1;
4029: return 0;
4030: }
1.1.1.18 root 4031:
4032: /* Convert a mem ref into one with a valid memory address.
4033: Pass through anything else unchanged. */
4034:
4035: rtx
4036: validize_mem (ref)
4037: rtx ref;
4038: {
4039: if (GET_CODE (ref) != MEM)
4040: return ref;
4041: if (memory_address_p (GET_MODE (ref), XEXP (ref, 0)))
4042: return ref;
1.1.1.19 root 4043: /* Don't alter REF itself, since that is probably a stack slot. */
4044: return gen_rtx (MEM, GET_MODE (ref),
4045: memory_address (GET_MODE (ref), XEXP (ref, 0)));
1.1.1.18 root 4046: }
1.1.1.17 root 4047:
1.1 root 4048: /* Assign RTL expressions to the function's parameters.
4049: This may involve copying them into registers and using
4050: those registers as the RTL for them. */
4051:
4052: static void
4053: assign_parms (fndecl)
4054: tree fndecl;
4055: {
4056: register tree parm;
1.1.1.2 root 4057: register rtx entry_parm;
4058: register rtx stack_parm;
4059: register CUMULATIVE_ARGS args_so_far;
4060: enum machine_mode passed_mode, nominal_mode;
4061: /* Total space needed so far for args on the stack,
4062: given as a constant and a tree-expression. */
4063: struct args_size stack_args_size;
1.1.1.8 root 4064: int first_parm_offset = FIRST_PARM_OFFSET (fndecl);
1.1.1.19 root 4065: int first_parm_caller_offset
4066: #ifdef FIRST_PARM_CALLER_OFFSET
4067: = FIRST_PARM_CALLER_OFFSET (fndecl);
4068: #else
4069: = first_parm_offset;
4070: #endif
1.1.1.13 root 4071: tree fntype = TREE_TYPE (fndecl);
1.1.1.17 root 4072: /* This is used for the arg pointer when referring to stack args. */
4073: rtx internal_arg_pointer;
1.1.1.2 root 4074:
4075: int nparmregs
4076: = list_length (DECL_ARGUMENTS (fndecl)) + FIRST_PSEUDO_REGISTER;
4077:
4078: /* Nonzero if function takes extra anonymous args.
4079: This means the last named arg must be on the stack
1.1.1.4 root 4080: right before the anonymous ones.
4081: Also nonzero if the first arg is named `__builtin_va_alist',
4082: which is used on some machines for old-fashioned non-ANSI varargs.h;
4083: this too should be stuck onto the stack as if it had arrived there. */
1.1.1.2 root 4084: int vararg
1.1.1.4 root 4085: = ((DECL_ARGUMENTS (fndecl) != 0
1.1.1.13 root 4086: && DECL_NAME (DECL_ARGUMENTS (fndecl))
1.1.1.4 root 4087: && (! strcmp (IDENTIFIER_POINTER (DECL_NAME (DECL_ARGUMENTS (fndecl))),
4088: "__builtin_va_alist")))
4089: ||
1.1.1.13 root 4090: (TYPE_ARG_TYPES (fntype) != 0
4091: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1.1.1.4 root 4092: != void_type_node)));
1.1.1.17 root 4093: int arg_pointer_copied = 0;
4094:
4095: #if ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM
4096: internal_arg_pointer = arg_pointer_rtx;
4097: #else
4098: /* If the arg pointer reg is not a fixed reg,
4099: make a copy of it, and address parms via the copy. */
4100: if (fixed_regs[ARG_POINTER_REGNUM])
4101: internal_arg_pointer = arg_pointer_rtx;
4102: else
4103: {
4104: internal_arg_pointer = copy_to_reg (arg_pointer_rtx);
4105: arg_pointer_copied = 1;
4106: }
4107: #endif
1.1.1.2 root 4108:
4109: stack_args_size.constant = 0;
4110: stack_args_size.var = 0;
4111:
1.1.1.6 root 4112: /* If struct value address comes on the stack, count it in size of args. */
1.1.1.17 root 4113: if (aggregate_value_p (DECL_RESULT (fndecl))
1.1.1.6 root 4114: && GET_CODE (struct_value_incoming_rtx) == MEM)
1.1.1.20 root 4115: {
4116: #ifdef FIRST_PARM_CALLER_OFFSET
4117: /* Make the right thing happen on the sparc
4118: in a function with a struct value and struct arg. */
4119: if (first_parm_caller_offset < 0)
4120: first_parm_offset += GET_MODE_SIZE (Pmode);
4121: else
4122: #endif
4123: stack_args_size.constant += GET_MODE_SIZE (Pmode);
4124: }
1.1.1.6 root 4125:
1.1.1.2 root 4126: parm_reg_stack_loc = (rtx *) oballoc (nparmregs * sizeof (rtx));
4127: bzero (parm_reg_stack_loc, nparmregs * sizeof (rtx));
4128:
1.1.1.13 root 4129: INIT_CUMULATIVE_ARGS (args_so_far, fntype);
1.1 root 4130:
1.1.1.2 root 4131: for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
1.1 root 4132: {
1.1.1.2 root 4133: int aggregate
4134: = (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
4135: || TREE_CODE (TREE_TYPE (parm)) == RECORD_TYPE
4136: || TREE_CODE (TREE_TYPE (parm)) == UNION_TYPE);
4137: struct args_size stack_offset;
4138: rtx stack_offset_rtx;
1.1.1.6 root 4139: enum direction where_pad;
1.1.1.2 root 4140:
4141: DECL_OFFSET (parm) = -1;
4142:
1.1.1.8 root 4143: if (TREE_TYPE (parm) == error_mark_node
1.1.1.10 root 4144: /* This can happen after weird syntax errors
4145: or if an enum type is defined among the parms. */
1.1.1.8 root 4146: || TREE_CODE (parm) != PARM_DECL
4147: || DECL_ARG_TYPE (parm) == NULL)
1.1.1.2 root 4148: {
4149: DECL_RTL (parm) = gen_rtx (MEM, BLKmode, const0_rtx);
1.1.1.13 root 4150: TREE_USED (parm) = 1;
1.1.1.2 root 4151: continue;
4152: }
4153:
4154: /* Find mode of arg as it is passed, and mode of arg
4155: as it should be during execution of this function. */
4156: passed_mode = TYPE_MODE (DECL_ARG_TYPE (parm));
4157: nominal_mode = TYPE_MODE (TREE_TYPE (parm));
4158:
1.1.1.6 root 4159: /* Get this parm's offset as an rtx. */
4160: stack_offset = stack_args_size;
1.1.1.8 root 4161: stack_offset.constant += first_parm_offset;
1.1.1.6 root 4162:
1.1.1.16 root 4163: /* If this argument needs more than the usual parm alignment, do
4164: extrinsic padding to reach that alignment. */
4165:
4166: #ifdef MAX_PARM_BOUNDARY
4167: /* If MAX_PARM_BOUNDARY is not defined, it means that the usual
4168: alignment requirements are relaxed for parms, and that no parm
4169: needs more alignment than PARM_BOUNDARY, regardless of data type. */
4170:
1.1.1.17 root 4171: if (PARM_BOUNDARY < TYPE_ALIGN (DECL_ARG_TYPE (parm)))
1.1.1.16 root 4172: {
4173: int boundary = PARM_BOUNDARY;
4174:
4175: /* Determine the boundary to pad up to. */
1.1.1.17 root 4176: if (TYPE_ALIGN (DECL_ARG_TYPE (parm)) > boundary)
4177: boundary = TYPE_ALIGN (DECL_ARG_TYPE (parm));
1.1.1.16 root 4178: if (boundary > MAX_PARM_BOUNDARY)
4179: boundary = MAX_PARM_BOUNDARY;
4180:
4181: /* If the previous args don't reach such a boundary,
4182: advance to the next one. */
1.1.1.17 root 4183: boundary /= BITS_PER_UNIT;
1.1.1.16 root 4184: stack_offset.constant += boundary - 1;
1.1.1.17 root 4185: stack_offset.constant &= ~(boundary - 1);
4186: stack_args_size.constant += boundary - 1;
4187: stack_args_size.constant &= ~(boundary - 1);
1.1.1.16 root 4188:
4189: if (stack_offset.var != 0)
4190: abort (); /* This case not implemented yet */
4191: }
4192: #endif /* MAX_PARM_BOUNDARY */
4193:
4194: /* Find out if the parm needs intrinsic padding (up to PARM_BOUNDARY),
4195: and whether above or below. */
4196:
1.1.1.6 root 4197: where_pad
4198: = FUNCTION_ARG_PADDING (passed_mode,
4199: expand_expr (size_in_bytes (DECL_ARG_TYPE (parm)),
4200: 0, VOIDmode, 0));
4201:
1.1.1.16 root 4202: /* If arg should be padded below, adjust the stack address upward.
4203: This padding is considered part of the space occupied by the
4204: argument. It pads only up to PARM_BOUNDARY, and it does not
4205: depend on the previous arguments, since they are assumed to
4206: occupy a multiple of PARM_BOUNDARY. */
4207:
1.1.1.6 root 4208: if (where_pad == downward)
4209: {
4210: if (passed_mode != BLKmode)
4211: {
4212: if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY)
4213: stack_offset.constant
4214: += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1)
4215: / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT)
4216: - GET_MODE_SIZE (passed_mode));
4217: }
4218: else
4219: {
4220: tree sizetree = size_in_bytes (DECL_ARG_TYPE (parm));
4221: /* Round the size up to multiple of PARM_BOUNDARY bits. */
4222: tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
4223: tree s2 = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
4224: /* Add it in. */
4225: ADD_PARM_SIZE (stack_offset, s2);
4226: SUB_PARM_SIZE (stack_offset, sizetree);
4227: }
4228: }
4229:
1.1.1.2 root 4230: /* Let machine desc say which reg (if any) the parm arrives in.
4231: 0 means it arrives on the stack. */
4232: entry_parm = 0;
4233: /* Variable-size args, and args following such, are never in regs. */
4234: if (TREE_CODE (TYPE_SIZE (TREE_TYPE (parm))) == INTEGER_CST
4235: || stack_offset.var != 0)
4236: {
1.1.1.17 root 4237: /* Set LAST_NAMED if this is last named arg before some
4238: anonymous args. We treat it as if it were anonymous too. */
4239: int last_named = (TREE_CHAIN (parm) == 0 && vararg);
1.1.1.2 root 4240: #ifdef FUNCTION_INCOMING_ARG
4241: entry_parm
4242: = FUNCTION_INCOMING_ARG (args_so_far, passed_mode,
1.1.1.17 root 4243: DECL_ARG_TYPE (parm), ! last_named);
1.1.1.2 root 4244: #else
4245: entry_parm
1.1.1.17 root 4246: = FUNCTION_ARG (args_so_far, passed_mode, DECL_ARG_TYPE (parm),
4247: ! last_named);
1.1.1.2 root 4248: #endif
4249: }
1.1.1.17 root 4250:
1.1.1.19 root 4251: #ifdef REG_PARM_STACK_SPACE
4252: /* If we arrive at a stack parm while still counting space for reg parms,
4253: skip up to the offset for the first stack parm. */
4254: if (entry_parm == 0
4255: && stack_args_size.constant + first_parm_caller_offset < 0)
4256: {
4257: int adjustment
4258: = -(stack_args_size.constant + first_parm_caller_offset);
4259: stack_args_size.constant += adjustment;
4260: stack_offset.constant += adjustment;
4261: }
4262: #endif
4263:
4264: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
4265:
4266: /* Determine parm's home in the stack,
4267: in case it arrives in the stack or we should pretend it did. */
4268: /* Note that this is not necessarily a valid address.
4269: We make it valid later when it is used.
4270: It is necessary for the DECL_RTL to be an explicit stack slot,
4271: but not necessary for it to be valid. */
4272: stack_parm
4273: = gen_rtx (MEM, passed_mode,
4274: gen_rtx (PLUS, Pmode,
4275: internal_arg_pointer,
4276: stack_offset_rtx));
4277:
4278: /* If this is a memory ref that contains aggregate components,
4279: mark it as such for cse and loop optimize. */
4280: MEM_IN_STRUCT_P (stack_parm) = aggregate;
4281:
1.1.1.2 root 4282: /* If this parm was passed part in regs and part in memory,
4283: pretend it arrived entirely in memory
4284: by pushing the register-part onto the stack.
4285:
4286: In the special case of a DImode or DFmode that is split,
4287: we could put it together in a pseudoreg directly,
4288: but for now that's not worth bothering with. */
4289:
1.1.1.17 root 4290: if (entry_parm)
4291: {
4292: int nregs = 0;
4293: int i;
1.1.1.2 root 4294: #ifdef FUNCTION_ARG_PARTIAL_NREGS
1.1.1.17 root 4295: nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, passed_mode,
4296: DECL_ARG_TYPE (parm), 1);
1.1.1.2 root 4297: #endif
4298:
1.1.1.17 root 4299: #if 0 /* Replaced by new calling convention
4300: which actually passes these args on the stack. */
4301: /* If this is the last named arg and anonymous args follow,
4302: likewise pretend this arg arrived on the stack
4303: so varargs can find the anonymous args following it. */
4304: if (TREE_CHAIN (parm) == 0 && vararg)
4305: {
4306: if (GET_MODE (entry_parm) == BLKmode)
4307: nregs = GET_MODE_SIZE (GET_MODE (entry_parm)) / UNITS_PER_WORD;
4308: else
4309: nregs = (int_size_in_bytes (DECL_ARG_TYPE (parm))
4310: / UNITS_PER_WORD);
4311: }
4312: #endif /* 0 */
4313:
4314: if (nregs > 0)
4315: {
1.1.1.19 root 4316: rtx valid_stack_parm = validize_mem (stack_parm);
1.1.1.17 root 4317: current_function_pretend_args_size
4318: = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
4319: / (PARM_BOUNDARY / BITS_PER_UNIT)
4320: * (PARM_BOUNDARY / BITS_PER_UNIT));
4321:
4322: i = nregs;
4323: while (--i >= 0)
4324: emit_move_insn (gen_rtx (MEM, SImode,
1.1.1.19 root 4325: plus_constant (XEXP (valid_stack_parm, 0),
1.1.1.17 root 4326: i * GET_MODE_SIZE (SImode))),
4327: gen_rtx (REG, SImode, REGNO (entry_parm) + i));
4328: entry_parm = stack_parm;
4329: }
4330: }
1.1.1.2 root 4331:
1.1.1.4 root 4332: /* If we didn't decide this parm came in a register,
4333: by default it came on the stack. */
1.1.1.2 root 4334: if (entry_parm == 0)
4335: entry_parm = stack_parm;
4336:
1.1.1.4 root 4337: /* For a stack parm, record in DECL_OFFSET the arglist offset
4338: of the parm at the time it is passed (before conversion). */
1.1.1.2 root 4339: if (entry_parm == stack_parm)
1.1.1.4 root 4340: DECL_OFFSET (parm) = stack_offset.constant * BITS_PER_UNIT;
4341:
4342: /* If there is actually space on the stack for this parm,
4343: count it in stack_args_size; otherwise set stack_parm to 0
4344: to indicate there is no preallocated stack slot for the parm. */
4345:
4346: if (entry_parm == stack_parm
4347: #ifdef REG_PARM_STACK_SPACE
4348: /* On some machines, even if a parm value arrives in a register
4349: there is still an (uninitialized) stack slot allocated for it. */
4350: || 1
4351: #endif
4352: )
1.1.1.2 root 4353: {
4354: tree sizetree = size_in_bytes (DECL_ARG_TYPE (parm));
1.1.1.19 root 4355: #ifdef PUSH_ROUNDING
4356: /* If this arg will be pushed with a push instruction,
4357: note how that will add to its size. */
4358: if (DECL_MODE (parm) != BLKmode)
4359: {
4360: int old_bytes = int_size_in_bytes (DECL_ARG_TYPE (parm));
4361: sizetree = build_int_2 (PUSH_ROUNDING (old_bytes), 0);
4362: }
4363: #endif
1.1.1.6 root 4364: if (where_pad != none)
4365: {
4366: /* Round the size up to multiple of PARM_BOUNDARY bits. */
4367: tree s1 = convert_units (sizetree, BITS_PER_UNIT, PARM_BOUNDARY);
4368: sizetree = convert_units (s1, PARM_BOUNDARY, BITS_PER_UNIT);
4369: }
1.1.1.2 root 4370: /* Add it in. */
1.1.1.6 root 4371: ADD_PARM_SIZE (stack_args_size, sizetree);
1.1.1.2 root 4372: }
1.1.1.4 root 4373: else
4374: /* No stack slot was pushed for this parm. */
4375: stack_parm = 0;
1.1.1.2 root 4376:
1.1.1.4 root 4377: /* Now adjust STACK_PARM to the mode and precise location
1.1.1.2 root 4378: where this parameter should live during execution,
4379: if we discover that it must live in the stack during execution.
4380: To make debuggers happier on big-endian machines, we store
4381: the value in the last bytes of the space available. */
4382:
1.1.1.4 root 4383: if (nominal_mode != BLKmode && nominal_mode != passed_mode
4384: && stack_parm != 0)
1.1.1.2 root 4385: {
4386: #ifdef BYTES_BIG_ENDIAN
1.1.1.6 root 4387: if (GET_MODE_SIZE (nominal_mode) < UNITS_PER_WORD)
4388: {
4389: stack_offset.constant
4390: += GET_MODE_SIZE (passed_mode)
4391: - GET_MODE_SIZE (nominal_mode);
4392: stack_offset_rtx = ARGS_SIZE_RTX (stack_offset);
4393: }
1.1.1.2 root 4394: #endif
4395:
4396: stack_parm
4397: = gen_rtx (MEM, nominal_mode,
1.1.1.19 root 4398: gen_rtx (PLUS, Pmode,
4399: arg_pointer_rtx,
4400: stack_offset_rtx));
1.1.1.2 root 4401:
4402: /* If this is a memory ref that contains aggregate components,
4403: mark it as such for cse and loop optimize. */
1.1.1.10 root 4404: MEM_IN_STRUCT_P (stack_parm) = aggregate;
1.1.1.2 root 4405: }
4406:
4407: /* ENTRY_PARM is an RTX for the parameter as it arrives,
4408: in the mode in which it arrives.
1.1.1.4 root 4409: STACK_PARM is an RTX for a stack slot where the parameter can live
4410: during the function (in case we want to put it there).
4411: STACK_PARM is 0 if no stack slot was pushed for it.
1.1 root 4412:
1.1.1.4 root 4413: Now output code if necessary to convert ENTRY_PARM to
1.1 root 4414: the type in which this function declares it,
1.1.1.4 root 4415: and store that result in an appropriate place,
4416: which may be a pseudo reg, may be STACK_PARM,
4417: or may be a local stack slot if STACK_PARM is 0.
4418:
4419: Set DECL_RTL to that place. */
1.1.1.2 root 4420:
4421: if (nominal_mode == BLKmode)
4422: {
4423: /* If a BLKmode arrives in registers, copy it to a stack slot. */
1.1.1.4 root 4424: if (GET_CODE (entry_parm) == REG)
1.1.1.2 root 4425: {
1.1.1.19 root 4426: #if 0 /* This was probably wrong, but save it just in case. */
4427: rtx unpadded_stack_parm;
4428:
4429: /* Determine parm's home in the stack. */
4430:
4431: if (stack_parm == 0)
4432: unpadded_stack_parm
4433: = assign_stack_local (GET_MODE (entry_parm),
4434: int_size_in_bytes (TREE_TYPE (parm)));
4435: else
4436: unpadded_stack_parm
4437: = gen_rtx (MEM, passed_mode,
4438: memory_address (passed_mode,
4439: gen_rtx (PLUS, Pmode,
4440: internal_arg_pointer,
4441: ARGS_SIZE_RTX (unpadded_stack_offset))));
4442:
4443: /* Here we use unpadded_stack_parm because we assume
4444: that downward padding is used on big-endian machines
4445: where we would want to make the real data in the reg
4446: (which is in the low bits) end up at the padded address. */
4447: #endif
1.1.1.4 root 4448: if (stack_parm == 0)
4449: stack_parm
4450: = assign_stack_local (GET_MODE (entry_parm),
4451: int_size_in_bytes (TREE_TYPE (parm)));
1.1.1.2 root 4452:
1.1.1.19 root 4453: move_block_from_reg (REGNO (entry_parm),
4454: validize_mem (stack_parm),
1.1.1.18 root 4455: ((int_size_in_bytes (TREE_TYPE (parm))
4456: + UNITS_PER_WORD - 1)
4457: / UNITS_PER_WORD));
1.1.1.2 root 4458: }
4459: DECL_RTL (parm) = stack_parm;
4460: }
1.1.1.10 root 4461: else if (! ((obey_regdecls && ! TREE_REGDECL (parm)
4462: && ! TREE_INLINE (fndecl))
1.1.1.14 root 4463: /* layout_decl may set this. */
4464: || TREE_ADDRESSABLE (parm)
1.1.1.15 root 4465: || TREE_VOLATILE (parm)
1.1.1.2 root 4466: /* If -ffloat-store specified, don't put explicit
4467: float variables into registers. */
4468: || (flag_float_store
4469: && TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE)))
1.1 root 4470: {
1.1.1.2 root 4471: /* Store the parm in a pseudoregister during the function. */
4472: register rtx parmreg = gen_reg_rtx (nominal_mode);
1.1 root 4473:
1.1.1.10 root 4474: REG_USERVAR_P (parmreg) = 1;
1.1 root 4475: DECL_RTL (parm) = parmreg;
4476:
4477: /* Copy the value into the register. */
1.1.1.2 root 4478: if (GET_MODE (parmreg) != GET_MODE (entry_parm))
1.1.1.18 root 4479: convert_move (parmreg, validize_mem (entry_parm), 0);
1.1 root 4480: else
1.1.1.18 root 4481: emit_move_insn (parmreg, validize_mem (entry_parm));
1.1.1.2 root 4482:
4483: /* In any case, record the parm's desired stack location
4484: in case we later discover it must live in the stack. */
4485: if (REGNO (parmreg) >= nparmregs)
4486: {
4487: rtx *new;
4488: nparmregs = REGNO (parmreg) + 5;
4489: new = (rtx *) oballoc (nparmregs * sizeof (rtx));
4490: bcopy (parm_reg_stack_loc, new, nparmregs * sizeof (rtx));
4491: parm_reg_stack_loc = new;
4492: }
4493: parm_reg_stack_loc[REGNO (parmreg)] = stack_parm;
1.1 root 4494:
1.1.1.2 root 4495: /* Mark the register as eliminable if we did no conversion
1.1.1.17 root 4496: and it was copied from memory at a fixed offset,
4497: and the arg pointer was not copied to a pseudo-reg.
4498: If the arg pointer is a pseudo reg, such memory-equivalences
4499: as we make here would screw up life analysis for it. */
1.1.1.2 root 4500: if (nominal_mode == passed_mode
4501: && GET_CODE (entry_parm) == MEM
1.1.1.17 root 4502: && stack_offset.var == 0
4503: && ! arg_pointer_copied)
1.1.1.10 root 4504: REG_NOTES (get_last_insn ())
4505: = gen_rtx (EXPR_LIST, REG_EQUIV,
4506: entry_parm, REG_NOTES (get_last_insn ()));
1.1 root 4507:
4508: /* For pointer data type, suggest pointer register. */
4509: if (TREE_CODE (TREE_TYPE (parm)) == POINTER_TYPE)
4510: mark_reg_pointer (parmreg);
4511: }
1.1.1.2 root 4512: else
1.1 root 4513: {
1.1.1.2 root 4514: /* Value must be stored in the stack slot STACK_PARM
4515: during function execution. */
4516:
4517: if (passed_mode != nominal_mode)
4518: /* Conversion is required. */
1.1.1.19 root 4519: entry_parm = convert_to_mode (nominal_mode,
4520: validize_mem (entry_parm), 0);
1.1.1.2 root 4521:
4522: if (entry_parm != stack_parm)
4523: {
4524: if (stack_parm == 0)
4525: stack_parm = assign_stack_local (GET_MODE (entry_parm),
4526: GET_MODE_SIZE (GET_MODE (entry_parm)));
1.1.1.18 root 4527: emit_move_insn (validize_mem (stack_parm),
4528: validize_mem (entry_parm));
1.1.1.2 root 4529: }
4530:
4531: DECL_RTL (parm) = stack_parm;
4532: frame_pointer_needed = 1;
1.1 root 4533: }
1.1.1.2 root 4534:
4535: if (TREE_VOLATILE (parm))
1.1.1.10 root 4536: MEM_VOLATILE_P (DECL_RTL (parm)) = 1;
1.1.1.2 root 4537: if (TREE_READONLY (parm))
1.1.1.10 root 4538: RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
1.1.1.2 root 4539:
4540: /* Update info on where next arg arrives in registers. */
4541:
4542: FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, DECL_ARG_TYPE (parm), 1);
1.1 root 4543: }
1.1.1.4 root 4544:
1.1 root 4545: max_parm_reg = max_reg_num ();
1.1.1.2 root 4546: last_parm_insn = get_last_insn ();
4547:
4548: current_function_args_size = stack_args_size.constant;
1.1.1.19 root 4549:
4550: stack_args_size.constant += first_parm_offset;
4551: current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size);
1.1 root 4552: }
4553:
4554: /* Allocation of space for returned structure values.
4555: During the rtl generation pass, `get_structure_value_addr'
4556: is called from time to time to request the address of a block in our
4557: stack frame in which called functions will store the structures
4558: they are returning. The same space is used for all of these blocks.
4559:
1.1.1.2 root 4560: We allocate these blocks like stack locals. We keep reusing
4561: the same block until a bigger one is needed. */
4562:
4563: /* Length in bytes of largest structure value returned by
4564: any function called so far in this function. */
4565: static int max_structure_value_size;
1.1 root 4566:
1.1.1.2 root 4567: /* An rtx for the addr we are currently using for structure values.
4568: This is typically (PLUS (REG:SI stackptr) (CONST_INT...)). */
4569: static rtx structure_value;
1.1 root 4570:
4571: rtx
4572: get_structure_value_addr (sizex)
4573: rtx sizex;
4574: {
4575: register int size;
4576: if (GET_CODE (sizex) != CONST_INT)
4577: abort ();
4578: size = INTVAL (sizex);
4579:
4580: /* Round up to a multiple of the main allocation unit. */
4581: size = (((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
4582: / (BIGGEST_ALIGNMENT / BITS_PER_UNIT))
4583: * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
4584:
1.1.1.2 root 4585: /* If this size is bigger than space we know to use,
4586: get a bigger piece of space. */
1.1 root 4587: if (size > max_structure_value_size)
4588: {
4589: max_structure_value_size = size;
1.1.1.2 root 4590: structure_value = assign_stack_local (BLKmode, size);
4591: if (GET_CODE (structure_value) == MEM)
4592: structure_value = XEXP (structure_value, 0);
1.1 root 4593: }
1.1.1.2 root 4594:
4595: return structure_value;
1.1 root 4596: }
1.1.1.19 root 4597:
4598: /* Push and pop the current structure value block. */
4599:
4600: void
4601: push_structure_value (rtx_ptr, size_ptr)
4602: rtx *rtx_ptr;
4603: int *size_ptr;
4604: {
4605: *rtx_ptr = structure_value;
4606: *size_ptr = max_structure_value_size;
4607: max_structure_value_size = 0;
4608: structure_value = 0;
4609: }
4610:
4611: void
4612: pop_structure_value (rtx_value, size)
4613: rtx rtx_value;
4614: int size;
4615: {
4616: structure_value = rtx_value;
4617: max_structure_value_size = size;
4618: }
4619:
1.1.1.2 root 4620:
4621: /* Walk the tree of LET_STMTs describing the binding levels within a function
4622: and warn about uninitialized variables.
4623: This is done after calling flow_analysis and before global_alloc
4624: clobbers the pseudo-regs to hard regs. */
1.1 root 4625:
1.1.1.2 root 4626: void
4627: uninitialized_vars_warning (block)
4628: tree block;
1.1 root 4629: {
1.1.1.2 root 4630: register tree decl, sub;
4631: for (decl = STMT_VARS (block); decl; decl = TREE_CHAIN (decl))
4632: {
4633: if (TREE_CODE (decl) == VAR_DECL
4634: /* These warnings are unreliable for and aggregates
4635: because assigning the fields one by one can fail to convince
4636: flow.c that the entire aggregate was initialized.
4637: Unions are troublesome because members may be shorter. */
4638: && TREE_CODE (TREE_TYPE (decl)) != RECORD_TYPE
4639: && TREE_CODE (TREE_TYPE (decl)) != UNION_TYPE
4640: && TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE
1.1.1.17 root 4641: && DECL_RTL (decl) != 0
1.1.1.2 root 4642: && GET_CODE (DECL_RTL (decl)) == REG
4643: && regno_uninitialized (REGNO (DECL_RTL (decl))))
4644: warning_with_decl (decl,
1.1.1.15 root 4645: "`%s' may be used uninitialized in this function");
1.1.1.2 root 4646: if (TREE_CODE (decl) == VAR_DECL
1.1.1.17 root 4647: && DECL_RTL (decl) != 0
1.1.1.2 root 4648: && GET_CODE (DECL_RTL (decl)) == REG
4649: && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
4650: warning_with_decl (decl,
4651: "variable `%s' may be clobbered by `longjmp'");
4652: }
1.1.1.17 root 4653: for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
1.1.1.2 root 4654: uninitialized_vars_warning (sub);
1.1 root 4655: }
1.1.1.11 root 4656:
4657: /* If this function call setjmp, put all vars into the stack
4658: unless they were declared `register'. */
4659:
4660: void
4661: setjmp_protect (block)
4662: tree block;
4663: {
4664: register tree decl, sub;
4665: for (decl = STMT_VARS (block); decl; decl = TREE_CHAIN (decl))
4666: if ((TREE_CODE (decl) == VAR_DECL
4667: || TREE_CODE (decl) == PARM_DECL)
4668: && DECL_RTL (decl) != 0
4669: && GET_CODE (DECL_RTL (decl)) == REG
4670: && ! TREE_REGDECL (decl))
4671: put_var_into_stack (decl);
1.1.1.17 root 4672: for (sub = STMT_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
1.1.1.11 root 4673: setjmp_protect (sub);
4674: }
1.1 root 4675:
1.1.1.17 root 4676: /* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
1.1.1.2 root 4677: and initialize static variables for generating RTL for the statements
4678: of the function. */
1.1 root 4679:
1.1.1.2 root 4680: void
1.1.1.19 root 4681: init_function_start (subr, filename, line)
1.1 root 4682: tree subr;
1.1.1.19 root 4683: char *filename;
4684: int line;
1.1 root 4685: {
4686: this_function = subr;
1.1.1.2 root 4687: cse_not_expected = ! optimize;
4688:
4689: /* We have not yet found a reason why a frame pointer cannot
4690: be omitted for this function in particular, but maybe we know
4691: a priori that it is required.
4692: `flag_omit_frame_pointer' has its main effect here. */
4693: frame_pointer_needed = FRAME_POINTER_REQUIRED || ! flag_omit_frame_pointer;
1.1 root 4694:
1.1.1.17 root 4695: /* Caller save not needed yet. */
4696: caller_save_needed = 0;
4697:
1.1.1.2 root 4698: /* No gotos have been expanded yet. */
4699: goto_fixup_chain = 0;
1.1 root 4700:
1.1.1.13 root 4701: /* No stack slots have been made yet. */
4702: stack_slot_list = 0;
4703:
1.1.1.2 root 4704: /* No invalid stack slots have been made yet. */
4705: invalid_stack_slot = 0;
4706:
1.1.1.18 root 4707: /* No parm regs have been allocated.
4708: (This is important for output_inline_function.) */
4709: max_parm_reg = FIRST_PSEUDO_REGISTER;
4710:
1.1.1.2 root 4711: /* Initialize the RTL mechanism. */
4712: init_emit (write_symbols);
4713:
4714: /* Initialize the queue of pending postincrement and postdecrements,
4715: and some other info in expr.c. */
4716: init_expr ();
4717:
4718: init_const_rtx_hash_table ();
4719:
4720: /* Decide whether function should try to pop its args on return. */
4721:
4722: current_function_pops_args = RETURN_POPS_ARGS (TREE_TYPE (subr));
4723:
1.1.1.17 root 4724: current_function_name = DECL_PRINT_NAME (subr);
1.1.1.2 root 4725:
1.1.1.10 root 4726: /* Nonzero if this is a nested function that uses a static chain. */
4727:
1.1.1.13 root 4728: current_function_needs_context
4729: = (DECL_CONTEXT (current_function_decl) != 0
4730: && TREE_CODE (DECL_CONTEXT (current_function_decl)) == LET_STMT);
1.1.1.10 root 4731:
1.1.1.11 root 4732: /* Set if a call to setjmp is seen. */
4733:
4734: current_function_calls_setjmp = 0;
1.1.1.17 root 4735: current_function_calls_alloca = 0;
1.1.1.11 root 4736:
1.1.1.15 root 4737: current_function_returns_pcc_struct = 0;
4738: current_function_returns_struct = 0;
1.1.1.10 root 4739:
1.1.1.2 root 4740: /* No space assigned yet for structure values. */
1.1.1.19 root 4741: max_structure_value_size = -1;
1.1.1.2 root 4742: structure_value = 0;
1.1 root 4743:
1.1.1.2 root 4744: /* We are not currently within any block, conditional, loop or case. */
1.1 root 4745: block_stack = 0;
1.1.1.2 root 4746: loop_stack = 0;
4747: case_stack = 0;
4748: cond_stack = 0;
4749: nesting_stack = 0;
4750: nesting_depth = 0;
4751:
1.1.1.19 root 4752: block_start_count = 0;
4753:
1.1.1.2 root 4754: /* We have not yet needed to make a label to jump to for tail-recursion. */
1.1 root 4755: tail_recursion_label = 0;
4756:
1.1.1.2 root 4757: /* No stack slots allocated yet. */
4758: frame_offset = STARTING_FRAME_OFFSET;
4759:
1.1.1.5 root 4760: /* No SAVE_EXPRs in this function yet. */
4761: save_expr_regs = 0;
4762:
1.1.1.10 root 4763: /* No RTL_EXPRs in this function yet. */
4764: rtl_expr_chain = 0;
4765:
1.1.1.4 root 4766: /* Within function body, compute a type's size as soon it is laid out. */
4767: immediate_size_expand++;
4768:
1.1.1.2 root 4769: init_pending_stack_adjust ();
1.1.1.17 root 4770: inhibit_defer_pop = 0;
1.1.1.7 root 4771: current_function_pretend_args_size = 0;
1.1 root 4772:
4773: /* Prevent ever trying to delete the first instruction of a function.
4774: Also tell final how to output a linenum before the function prologue. */
1.1.1.19 root 4775: emit_line_note (filename, line);
1.1 root 4776: /* Make sure first insn is a note even if we don't want linenums.
4777: This makes sure the first insn will never be deleted.
4778: Also, final expects a note to appear there. */
4779: emit_note (0, NOTE_INSN_DELETED);
1.1.1.17 root 4780: /* Indicate the beginning of the function body,
4781: as opposed to parm setup. */
4782: emit_note (0, NOTE_INSN_FUNCTION_BEG);
1.1 root 4783:
1.1.1.17 root 4784: /* Set flags used by final.c. */
4785: if (aggregate_value_p (DECL_RESULT (subr)))
4786: {
4787: #ifdef PCC_STATIC_STRUCT_RETURN
4788: if (flag_pcc_struct_return)
4789: current_function_returns_pcc_struct = 1;
4790: else
4791: #endif
4792: current_function_returns_struct = 1;
4793: }
4794: }
1.1 root 4795:
1.1.1.17 root 4796: /* Start the RTL for a new function, and set variables used for
4797: emitting RTL.
4798: SUBR is the FUNCTION_DECL node.
4799: PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with
4800: the function's parameters, which must be run at any return statement. */
4801:
4802: void
4803: expand_function_start (subr, parms_have_cleanups)
4804: tree subr;
4805: int parms_have_cleanups;
4806: {
4807: register int i;
4808: tree tem;
4809:
1.1.1.18 root 4810: /* Make sure volatile mem refs aren't considered
4811: valid operands of arithmetic insns. */
4812: init_recog ();
4813:
1.1.1.17 root 4814: /* If the parameters of this function need cleaning up, get a label
4815: for the beginning of the code which executes those cleanups. This must
4816: be done before doing anything with return_label. */
4817: if (parms_have_cleanups)
4818: cleanup_label = gen_label_rtx ();
4819: else
4820: cleanup_label = 0;
4821:
4822: /* Make the label for return statements to jump to, if this machine
4823: does not have a one-instruction return and uses an epilogue,
4824: or if it returns a structure, or if it has parm cleanups. */
4825: #ifdef HAVE_return
4826: if (cleanup_label == 0 && HAVE_return
4827: && ! current_function_returns_pcc_struct
4828: && ! (current_function_returns_struct && ! optimize))
4829: return_label = 0;
4830: else
4831: return_label = gen_label_rtx ();
4832: #else
4833: return_label = gen_label_rtx ();
4834: #endif
1.1.1.2 root 4835:
1.1 root 4836: /* Initialize rtx used to return the value. */
1.1.1.17 root 4837: /* Do this before assign_parms so that we copy the struct value address
4838: before any library calls that assign parms might generate. */
1.1 root 4839:
1.1.1.15 root 4840: /* Decide whether to return the value in memory or in a register. */
1.1.1.17 root 4841: if (aggregate_value_p (DECL_RESULT (subr)))
1.1 root 4842: {
4843: /* Returning something that won't go in a register. */
4844: register rtx value_address;
4845:
1.1.1.15 root 4846: #ifdef PCC_STATIC_STRUCT_RETURN
4847: if (flag_pcc_struct_return)
4848: {
4849: int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr)));
4850: value_address = assemble_static_space (size);
4851: current_function_returns_pcc_struct = 1;
4852: }
4853: else
4854: #endif
4855: {
4856: /* Expect to be passed the address of a place to store the value. */
4857: value_address = gen_reg_rtx (Pmode);
4858: emit_move_insn (value_address, struct_value_incoming_rtx);
4859: current_function_returns_struct = 1;
4860: }
1.1 root 4861: DECL_RTL (DECL_RESULT (subr))
4862: = gen_rtx (MEM, DECL_MODE (DECL_RESULT (subr)),
4863: value_address);
4864: }
1.1.1.17 root 4865: else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode)
4866: /* If return mode is void, this decl rtl should not be used. */
4867: DECL_RTL (DECL_RESULT (subr)) = 0;
4868: else if (parms_have_cleanups)
4869: /* If function will end with cleanup code for parms,
4870: compute the return values into a pseudo reg,
4871: which we will copy into the true return register
4872: after the cleanups are done. */
4873: DECL_RTL (DECL_RESULT (subr))
4874: = gen_reg_rtx (DECL_MODE (DECL_RESULT (subr)));
1.1 root 4875: else
1.1.1.15 root 4876: /* Scalar, returned in a register. */
1.1.1.17 root 4877: {
1.1.1.2 root 4878: #ifdef FUNCTION_OUTGOING_VALUE
1.1.1.17 root 4879: DECL_RTL (DECL_RESULT (subr))
4880: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
1.1.1.2 root 4881: #else
1.1.1.17 root 4882: DECL_RTL (DECL_RESULT (subr))
4883: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (subr)), subr);
1.1.1.2 root 4884: #endif
1.1.1.6 root 4885:
1.1.1.17 root 4886: current_function_returns_pointer
4887: = (TREE_CODE (DECL_RESULT_TYPE (subr)) == POINTER_TYPE);
1.1.1.8 root 4888:
1.1.1.17 root 4889: /* Mark this reg as the function's return value. */
4890: if (GET_CODE (DECL_RTL (DECL_RESULT (subr))) == REG)
4891: REG_FUNCTION_VALUE_P (DECL_RTL (DECL_RESULT (subr))) = 1;
4892: }
4893:
4894: /* Initialize rtx for parameters and local variables.
4895: In some cases this requires emitting insns. */
4896:
4897: assign_parms (subr);
1.1.1.16 root 4898:
1.1.1.10 root 4899: /* If doing stupid allocation, mark parms as born here. */
4900:
1.1.1.17 root 4901: if (GET_CODE (get_last_insn ()) != NOTE)
4902: emit_note (0, NOTE_INSN_DELETED);
4903: parm_birth_insn = get_last_insn ();
4904:
1.1.1.10 root 4905: if (obey_regdecls)
4906: {
4907: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
4908: use_variable (regno_reg_rtx[i]);
4909: }
4910:
1.1.1.8 root 4911: /* After the parm initializations is where the tail-recursion label
4912: should go, if we end up needing one. */
4913: tail_recursion_reentry = get_last_insn ();
4914:
4915: /* Evaluate now the sizes of any types declared among the arguments. */
4916: for (tem = get_pending_sizes (); tem; tem = TREE_CHAIN (tem))
4917: expand_expr (TREE_VALUE (tem), 0, VOIDmode, 0);
1.1.1.17 root 4918:
4919: /* Make sure there is a line number after the function entry setup code.
4920: There normally is one anyway, from the following statement,
4921: but there could fail to be one if there is no newline here. */
4922: force_next_line_note ();
1.1.1.2 root 4923: }
1.1 root 4924:
1.1.1.6 root 4925: /* Generate RTL for the end of the current function.
1.1.1.13 root 4926: FILENAME and LINE are the current position in the source file. */
1.1 root 4927:
1.1.1.17 root 4928: /* ??? Nobody seems to emit the cleanup_label and the cleanups themselves. */
4929:
1.1.1.2 root 4930: void
1.1.1.6 root 4931: expand_function_end (filename, line)
4932: char *filename;
4933: int line;
1.1.1.2 root 4934: {
4935: register int i;
1.1.1.17 root 4936: rtx decl;
1.1.1.13 root 4937: extern rtx sequence_stack;
4938:
1.1.1.17 root 4939: #if 0 /* I think unused parms are legitimate enough. */
4940: /* Warn about unused parms. */
4941: if (warn_unused)
4942: for (decl = DECL_ARGUMENTS (current_function_decl);
4943: decl; decl = TREE_CHAIN (decl))
4944: if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL)
4945: warning_with_decl (decl, "unused parameter `%s'");
4946: #endif
4947:
1.1.1.13 root 4948: /* End any sequences that failed to be closed due to syntax errors. */
4949: while (sequence_stack)
4950: end_sequence (0);
1.1 root 4951:
1.1.1.4 root 4952: /* Outside function body, can't compute type's actual size
4953: until next function's body starts. */
4954: immediate_size_expand--;
4955:
1.1 root 4956: /* If doing stupid register allocation,
1.1.1.2 root 4957: mark register parms as dying here. */
4958:
1.1 root 4959: if (obey_regdecls)
1.1.1.5 root 4960: {
4961: rtx tem;
4962: for (i = FIRST_PSEUDO_REGISTER; i < max_parm_reg; i++)
4963: use_variable (regno_reg_rtx[i]);
4964:
4965: /* Likewise for the regs of all the SAVE_EXPRs in the function. */
4966:
4967: for (tem = save_expr_regs; tem; tem = XEXP (tem, 1))
1.1.1.13 root 4968: {
4969: /* ??? Tiemann thinks this does not work. */
4970: use_variable (XEXP (tem, 0));
4971: use_variable_after (XEXP (tem, 0), parm_birth_insn);
4972: }
1.1.1.5 root 4973: }
1.1 root 4974:
4975: clear_pending_stack_adjust ();
1.1.1.2 root 4976: do_pending_stack_adjust ();
1.1 root 4977:
1.1.1.2 root 4978: /* Mark the end of the function body.
4979: If control reaches this insn, the function can drop through
4980: without returning a value. */
4981: emit_note (0, NOTE_INSN_FUNCTION_END);
4982:
1.1.1.6 root 4983: /* Output a linenumber for the end of the function.
4984: SDB depends on this. */
1.1.1.13 root 4985: emit_line_note_force (filename, line);
1.1.1.6 root 4986:
1.1.1.17 root 4987: /* Output the label for the actual return from the function,
4988: if one is expected. This happens either because a function epilogue
4989: is used instead of a return instruction, or because a return was done
4990: with a goto in order to run local cleanups, or because of pcc-style
4991: structure returning. */
4992:
4993: if (return_label)
1.1.1.8 root 4994: emit_label (return_label);
1.1.1.6 root 4995:
1.1.1.17 root 4996: /* If we had calls to alloca, and this machine needs
4997: an accurate stack pointer to exit the function,
4998: insert some code to save and restore the stack pointer. */
4999: #ifdef EXIT_IGNORE_STACK
5000: if (! EXIT_IGNORE_STACK)
5001: #endif
5002: if (current_function_calls_alloca)
5003: {
5004: rtx tem = gen_reg_rtx (Pmode);
5005: emit_insn_after (gen_rtx (SET, VOIDmode, tem, stack_pointer_rtx),
5006: parm_birth_insn);
5007: emit_insn (gen_rtx (SET, VOIDmode, stack_pointer_rtx, tem));
5008: }
5009:
5010: /* If scalar return value was computed in a pseudo-reg,
5011: copy that to the hard return register. */
5012: if (DECL_RTL (DECL_RESULT (current_function_decl)) != 0
5013: && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG
5014: && (REGNO (DECL_RTL (DECL_RESULT (current_function_decl)))
5015: >= FIRST_PSEUDO_REGISTER))
5016: {
5017: rtx real_decl_result;
5018:
5019: #ifdef FUNCTION_OUTGOING_VALUE
5020: real_decl_result
5021: = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
5022: current_function_decl);
5023: #else
5024: real_decl_result
5025: = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (current_function_decl)),
5026: current_function_decl);
5027: #endif
5028: REG_FUNCTION_VALUE_P (real_decl_result) = 1;
5029: emit_move_insn (real_decl_result,
5030: DECL_RTL (DECL_RESULT (current_function_decl)));
5031: emit_insn (gen_rtx (USE, VOIDmode, real_decl_result));
5032: }
5033:
5034: /* If returning a structure, arrange to return the address of the value
5035: in a place where debuggers expect to find it. */
1.1.1.15 root 5036: /* If returning a structure PCC style,
1.1.1.17 root 5037: the caller also depends on this value.
5038: And current_function_returns_pcc_struct is not necessarily set. */
5039: if (current_function_returns_struct
5040: || current_function_returns_pcc_struct)
1.1.1.15 root 5041: {
5042: rtx value_address = XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5043: tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
1.1.1.18 root 5044: #ifdef FUNCTION_OUTGOING_VALUE
5045: rtx outgoing
5046: = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
5047: current_function_decl);
5048: #else
1.1.1.15 root 5049: rtx outgoing
5050: = hard_function_value (build_pointer_type (type),
5051: current_function_decl);
1.1.1.18 root 5052: #endif
1.1.1.15 root 5053:
1.1.1.17 root 5054: REG_FUNCTION_VALUE_P (outgoing) = 1;
1.1.1.15 root 5055: emit_move_insn (outgoing, value_address);
5056: use_variable (outgoing);
1.1.1.17 root 5057: }
5058:
5059: /* Output a return insn if we are using one.
5060: Otherwise, let the rtl chain end here, to drop through
5061: into the epilogue. */
1.1.1.16 root 5062:
5063: #ifdef HAVE_return
1.1.1.17 root 5064: if (HAVE_return)
5065: emit_jump_insn (gen_return ());
1.1.1.16 root 5066: #endif
1.1.1.15 root 5067:
1.1.1.6 root 5068: /* Fix up any gotos that jumped out to the outermost
5069: binding level of the function.
5070: Must follow emitting RETURN_LABEL. */
1.1.1.8 root 5071:
5072: /* If you have any cleanups to do at this point,
5073: and they need to create temporary variables,
5074: then you will lose. */
1.1.1.14 root 5075: fixup_gotos (0, 0, 0, get_insns (), 0);
1.1 root 5076: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.