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