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