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