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