|
|
1.1 ! root 1: /* Subroutines for manipulating rtx's in semantically interesting ways. ! 2: Copyright (C) 1987, 1991 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: #include "config.h" ! 22: #include "rtl.h" ! 23: #include "tree.h" ! 24: #include "flags.h" ! 25: #include "expr.h" ! 26: #include "hard-reg-set.h" ! 27: #include "insn-config.h" ! 28: #include "recog.h" ! 29: #include "insn-flags.h" ! 30: #include "insn-codes.h" ! 31: ! 32: /* Return an rtx for the sum of X and the integer C. ! 33: ! 34: This function should be used via the `plus_constant' macro. */ ! 35: ! 36: rtx ! 37: plus_constant_wide (x, c) ! 38: register rtx x; ! 39: register HOST_WIDE_INT c; ! 40: { ! 41: register RTX_CODE code; ! 42: register enum machine_mode mode; ! 43: register rtx tem; ! 44: int all_constant = 0; ! 45: ! 46: if (c == 0) ! 47: return x; ! 48: ! 49: restart: ! 50: ! 51: code = GET_CODE (x); ! 52: mode = GET_MODE (x); ! 53: switch (code) ! 54: { ! 55: case CONST_INT: ! 56: return GEN_INT (INTVAL (x) + c); ! 57: ! 58: case CONST_DOUBLE: ! 59: { ! 60: HOST_WIDE_INT l1 = CONST_DOUBLE_LOW (x); ! 61: HOST_WIDE_INT h1 = CONST_DOUBLE_HIGH (x); ! 62: HOST_WIDE_INT l2 = c; ! 63: HOST_WIDE_INT h2 = c < 0 ? ~0 : 0; ! 64: HOST_WIDE_INT lv, hv; ! 65: ! 66: add_double (l1, h1, l2, h2, &lv, &hv); ! 67: ! 68: return immed_double_const (lv, hv, VOIDmode); ! 69: } ! 70: ! 71: case MEM: ! 72: /* If this is a reference to the constant pool, try replacing it with ! 73: a reference to a new constant. If the resulting address isn't ! 74: valid, don't return it because we have no way to validize it. */ ! 75: if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF ! 76: && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))) ! 77: { ! 78: tem ! 79: = force_const_mem (GET_MODE (x), ! 80: plus_constant (get_pool_constant (XEXP (x, 0)), ! 81: c)); ! 82: if (memory_address_p (GET_MODE (tem), XEXP (tem, 0))) ! 83: return tem; ! 84: } ! 85: break; ! 86: ! 87: case CONST: ! 88: /* If adding to something entirely constant, set a flag ! 89: so that we can add a CONST around the result. */ ! 90: x = XEXP (x, 0); ! 91: all_constant = 1; ! 92: goto restart; ! 93: ! 94: case SYMBOL_REF: ! 95: case LABEL_REF: ! 96: all_constant = 1; ! 97: break; ! 98: ! 99: case PLUS: ! 100: /* The interesting case is adding the integer to a sum. ! 101: Look for constant term in the sum and combine ! 102: with C. For an integer constant term, we make a combined ! 103: integer. For a constant term that is not an explicit integer, ! 104: we cannot really combine, but group them together anyway. ! 105: ! 106: Use a recursive call in case the remaining operand is something ! 107: that we handle specially, such as a SYMBOL_REF. */ ! 108: ! 109: if (GET_CODE (XEXP (x, 1)) == CONST_INT) ! 110: return plus_constant (XEXP (x, 0), c + INTVAL (XEXP (x, 1))); ! 111: else if (CONSTANT_P (XEXP (x, 0))) ! 112: return gen_rtx (PLUS, mode, ! 113: plus_constant (XEXP (x, 0), c), ! 114: XEXP (x, 1)); ! 115: else if (CONSTANT_P (XEXP (x, 1))) ! 116: return gen_rtx (PLUS, mode, ! 117: XEXP (x, 0), ! 118: plus_constant (XEXP (x, 1), c)); ! 119: } ! 120: ! 121: if (c != 0) ! 122: x = gen_rtx (PLUS, mode, x, GEN_INT (c)); ! 123: ! 124: if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF) ! 125: return x; ! 126: else if (all_constant) ! 127: return gen_rtx (CONST, mode, x); ! 128: else ! 129: return x; ! 130: } ! 131: ! 132: /* This is the same as `plus_constant', except that it handles LO_SUM. ! 133: ! 134: This function should be used via the `plus_constant_for_output' macro. */ ! 135: ! 136: rtx ! 137: plus_constant_for_output_wide (x, c) ! 138: register rtx x; ! 139: register HOST_WIDE_INT c; ! 140: { ! 141: register RTX_CODE code = GET_CODE (x); ! 142: register enum machine_mode mode = GET_MODE (x); ! 143: int all_constant = 0; ! 144: ! 145: if (GET_CODE (x) == LO_SUM) ! 146: return gen_rtx (LO_SUM, mode, XEXP (x, 0), ! 147: plus_constant_for_output (XEXP (x, 1), c)); ! 148: ! 149: else ! 150: return plus_constant (x, c); ! 151: } ! 152: ! 153: /* If X is a sum, return a new sum like X but lacking any constant terms. ! 154: Add all the removed constant terms into *CONSTPTR. ! 155: X itself is not altered. The result != X if and only if ! 156: it is not isomorphic to X. */ ! 157: ! 158: rtx ! 159: eliminate_constant_term (x, constptr) ! 160: rtx x; ! 161: rtx *constptr; ! 162: { ! 163: register rtx x0, x1; ! 164: rtx tem; ! 165: ! 166: if (GET_CODE (x) != PLUS) ! 167: return x; ! 168: ! 169: /* First handle constants appearing at this level explicitly. */ ! 170: if (GET_CODE (XEXP (x, 1)) == CONST_INT ! 171: && 0 != (tem = simplify_binary_operation (PLUS, GET_MODE (x), *constptr, ! 172: XEXP (x, 1))) ! 173: && GET_CODE (tem) == CONST_INT) ! 174: { ! 175: *constptr = tem; ! 176: return eliminate_constant_term (XEXP (x, 0), constptr); ! 177: } ! 178: ! 179: tem = const0_rtx; ! 180: x0 = eliminate_constant_term (XEXP (x, 0), &tem); ! 181: x1 = eliminate_constant_term (XEXP (x, 1), &tem); ! 182: if ((x1 != XEXP (x, 1) || x0 != XEXP (x, 0)) ! 183: && 0 != (tem = simplify_binary_operation (PLUS, GET_MODE (x), ! 184: *constptr, tem)) ! 185: && GET_CODE (tem) == CONST_INT) ! 186: { ! 187: *constptr = tem; ! 188: return gen_rtx (PLUS, GET_MODE (x), x0, x1); ! 189: } ! 190: ! 191: return x; ! 192: } ! 193: ! 194: /* Returns the insn that next references REG after INSN, or 0 ! 195: if REG is clobbered before next referenced or we cannot find ! 196: an insn that references REG in a straight-line piece of code. */ ! 197: ! 198: rtx ! 199: find_next_ref (reg, insn) ! 200: rtx reg; ! 201: rtx insn; ! 202: { ! 203: rtx next; ! 204: ! 205: for (insn = NEXT_INSN (insn); insn; insn = next) ! 206: { ! 207: next = NEXT_INSN (insn); ! 208: if (GET_CODE (insn) == NOTE) ! 209: continue; ! 210: if (GET_CODE (insn) == CODE_LABEL ! 211: || GET_CODE (insn) == BARRIER) ! 212: return 0; ! 213: if (GET_CODE (insn) == INSN ! 214: || GET_CODE (insn) == JUMP_INSN ! 215: || GET_CODE (insn) == CALL_INSN) ! 216: { ! 217: if (reg_set_p (reg, insn)) ! 218: return 0; ! 219: if (reg_mentioned_p (reg, PATTERN (insn))) ! 220: return insn; ! 221: if (GET_CODE (insn) == JUMP_INSN) ! 222: { ! 223: if (simplejump_p (insn)) ! 224: next = JUMP_LABEL (insn); ! 225: else ! 226: return 0; ! 227: } ! 228: if (GET_CODE (insn) == CALL_INSN ! 229: && REGNO (reg) < FIRST_PSEUDO_REGISTER ! 230: && call_used_regs[REGNO (reg)]) ! 231: return 0; ! 232: } ! 233: else ! 234: abort (); ! 235: } ! 236: return 0; ! 237: } ! 238: ! 239: /* Return an rtx for the size in bytes of the value of EXP. */ ! 240: ! 241: rtx ! 242: expr_size (exp) ! 243: tree exp; ! 244: { ! 245: tree size = size_in_bytes (TREE_TYPE (exp)); ! 246: ! 247: if (TREE_CODE (size) != INTEGER_CST ! 248: && contains_placeholder_p (size)) ! 249: size = build (WITH_RECORD_EXPR, sizetype, size, exp); ! 250: ! 251: return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0); ! 252: } ! 253: ! 254: /* Return a copy of X in which all memory references ! 255: and all constants that involve symbol refs ! 256: have been replaced with new temporary registers. ! 257: Also emit code to load the memory locations and constants ! 258: into those registers. ! 259: ! 260: If X contains no such constants or memory references, ! 261: X itself (not a copy) is returned. ! 262: ! 263: If a constant is found in the address that is not a legitimate constant ! 264: in an insn, it is left alone in the hope that it might be valid in the ! 265: address. ! 266: ! 267: X may contain no arithmetic except addition, subtraction and multiplication. ! 268: Values returned by expand_expr with 1 for sum_ok fit this constraint. */ ! 269: ! 270: static rtx ! 271: break_out_memory_refs (x) ! 272: register rtx x; ! 273: { ! 274: if (GET_CODE (x) == MEM ! 275: || (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x) ! 276: && GET_MODE (x) != VOIDmode)) ! 277: { ! 278: register rtx temp = force_reg (GET_MODE (x), x); ! 279: mark_reg_pointer (temp); ! 280: x = temp; ! 281: } ! 282: else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS ! 283: || GET_CODE (x) == MULT) ! 284: { ! 285: register rtx op0 = break_out_memory_refs (XEXP (x, 0)); ! 286: register rtx op1 = break_out_memory_refs (XEXP (x, 1)); ! 287: if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) ! 288: x = gen_rtx (GET_CODE (x), Pmode, op0, op1); ! 289: } ! 290: return x; ! 291: } ! 292: ! 293: /* Given a memory address or facsimile X, construct a new address, ! 294: currently equivalent, that is stable: future stores won't change it. ! 295: ! 296: X must be composed of constants, register and memory references ! 297: combined with addition, subtraction and multiplication: ! 298: in other words, just what you can get from expand_expr if sum_ok is 1. ! 299: ! 300: Works by making copies of all regs and memory locations used ! 301: by X and combining them the same way X does. ! 302: You could also stabilize the reference to this address ! 303: by copying the address to a register with copy_to_reg; ! 304: but then you wouldn't get indexed addressing in the reference. */ ! 305: ! 306: rtx ! 307: copy_all_regs (x) ! 308: register rtx x; ! 309: { ! 310: if (GET_CODE (x) == REG) ! 311: { ! 312: if (REGNO (x) != FRAME_POINTER_REGNUM ! 313: #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM ! 314: && REGNO (x) != HARD_FRAME_POINTER_REGNUM ! 315: #endif ! 316: ) ! 317: x = copy_to_reg (x); ! 318: } ! 319: else if (GET_CODE (x) == MEM) ! 320: x = copy_to_reg (x); ! 321: else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS ! 322: || GET_CODE (x) == MULT) ! 323: { ! 324: register rtx op0 = copy_all_regs (XEXP (x, 0)); ! 325: register rtx op1 = copy_all_regs (XEXP (x, 1)); ! 326: if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1)) ! 327: x = gen_rtx (GET_CODE (x), Pmode, op0, op1); ! 328: } ! 329: return x; ! 330: } ! 331: ! 332: /* Return something equivalent to X but valid as a memory address ! 333: for something of mode MODE. When X is not itself valid, this ! 334: works by copying X or subexpressions of it into registers. */ ! 335: ! 336: rtx ! 337: memory_address (mode, x) ! 338: enum machine_mode mode; ! 339: register rtx x; ! 340: { ! 341: register rtx oldx; ! 342: ! 343: /* By passing constant addresses thru registers ! 344: we get a chance to cse them. */ ! 345: if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)) ! 346: return force_reg (Pmode, x); ! 347: ! 348: /* Accept a QUEUED that refers to a REG ! 349: even though that isn't a valid address. ! 350: On attempting to put this in an insn we will call protect_from_queue ! 351: which will turn it into a REG, which is valid. */ ! 352: if (GET_CODE (x) == QUEUED ! 353: && GET_CODE (QUEUED_VAR (x)) == REG) ! 354: return x; ! 355: ! 356: /* We get better cse by rejecting indirect addressing at this stage. ! 357: Let the combiner create indirect addresses where appropriate. ! 358: For now, generate the code so that the subexpressions useful to share ! 359: are visible. But not if cse won't be done! */ ! 360: oldx = x; ! 361: if (! cse_not_expected && GET_CODE (x) != REG) ! 362: x = break_out_memory_refs (x); ! 363: ! 364: /* At this point, any valid address is accepted. */ ! 365: GO_IF_LEGITIMATE_ADDRESS (mode, x, win); ! 366: ! 367: /* If it was valid before but breaking out memory refs invalidated it, ! 368: use it the old way. */ ! 369: if (memory_address_p (mode, oldx)) ! 370: goto win2; ! 371: ! 372: /* Perform machine-dependent transformations on X ! 373: in certain cases. This is not necessary since the code ! 374: below can handle all possible cases, but machine-dependent ! 375: transformations can make better code. */ ! 376: LEGITIMIZE_ADDRESS (x, oldx, mode, win); ! 377: ! 378: /* PLUS and MULT can appear in special ways ! 379: as the result of attempts to make an address usable for indexing. ! 380: Usually they are dealt with by calling force_operand, below. ! 381: But a sum containing constant terms is special ! 382: if removing them makes the sum a valid address: ! 383: then we generate that address in a register ! 384: and index off of it. We do this because it often makes ! 385: shorter code, and because the addresses thus generated ! 386: in registers often become common subexpressions. */ ! 387: if (GET_CODE (x) == PLUS) ! 388: { ! 389: rtx constant_term = const0_rtx; ! 390: rtx y = eliminate_constant_term (x, &constant_term); ! 391: if (constant_term == const0_rtx ! 392: || ! memory_address_p (mode, y)) ! 393: return force_operand (x, NULL_RTX); ! 394: ! 395: y = gen_rtx (PLUS, GET_MODE (x), copy_to_reg (y), constant_term); ! 396: if (! memory_address_p (mode, y)) ! 397: return force_operand (x, NULL_RTX); ! 398: return y; ! 399: } ! 400: if (GET_CODE (x) == MULT || GET_CODE (x) == MINUS) ! 401: return force_operand (x, NULL_RTX); ! 402: ! 403: /* If we have a register that's an invalid address, ! 404: it must be a hard reg of the wrong class. Copy it to a pseudo. */ ! 405: if (GET_CODE (x) == REG) ! 406: return copy_to_reg (x); ! 407: ! 408: /* Last resort: copy the value to a register, since ! 409: the register is a valid address. */ ! 410: return force_reg (Pmode, x); ! 411: ! 412: win2: ! 413: x = oldx; ! 414: win: ! 415: if (flag_force_addr && ! cse_not_expected && GET_CODE (x) != REG ! 416: /* Don't copy an addr via a reg if it is one of our stack slots. */ ! 417: && ! (GET_CODE (x) == PLUS ! 418: && (XEXP (x, 0) == virtual_stack_vars_rtx ! 419: || XEXP (x, 0) == virtual_incoming_args_rtx))) ! 420: { ! 421: if (general_operand (x, Pmode)) ! 422: return force_reg (Pmode, x); ! 423: else ! 424: return force_operand (x, NULL_RTX); ! 425: } ! 426: return x; ! 427: } ! 428: ! 429: /* Like `memory_address' but pretend `flag_force_addr' is 0. */ ! 430: ! 431: rtx ! 432: memory_address_noforce (mode, x) ! 433: enum machine_mode mode; ! 434: rtx x; ! 435: { ! 436: int ambient_force_addr = flag_force_addr; ! 437: rtx val; ! 438: ! 439: flag_force_addr = 0; ! 440: val = memory_address (mode, x); ! 441: flag_force_addr = ambient_force_addr; ! 442: return val; ! 443: } ! 444: ! 445: /* Convert a mem ref into one with a valid memory address. ! 446: Pass through anything else unchanged. */ ! 447: ! 448: rtx ! 449: validize_mem (ref) ! 450: rtx ref; ! 451: { ! 452: if (GET_CODE (ref) != MEM) ! 453: return ref; ! 454: if (memory_address_p (GET_MODE (ref), XEXP (ref, 0))) ! 455: return ref; ! 456: /* Don't alter REF itself, since that is probably a stack slot. */ ! 457: return change_address (ref, GET_MODE (ref), XEXP (ref, 0)); ! 458: } ! 459: ! 460: /* Return a modified copy of X with its memory address copied ! 461: into a temporary register to protect it from side effects. ! 462: If X is not a MEM, it is returned unchanged (and not copied). ! 463: Perhaps even if it is a MEM, if there is no need to change it. */ ! 464: ! 465: rtx ! 466: stabilize (x) ! 467: rtx x; ! 468: { ! 469: register rtx addr; ! 470: if (GET_CODE (x) != MEM) ! 471: return x; ! 472: addr = XEXP (x, 0); ! 473: if (rtx_unstable_p (addr)) ! 474: { ! 475: rtx temp = copy_all_regs (addr); ! 476: rtx mem; ! 477: if (GET_CODE (temp) != REG) ! 478: temp = copy_to_reg (temp); ! 479: mem = gen_rtx (MEM, GET_MODE (x), temp); ! 480: ! 481: /* Mark returned memref with in_struct if it's in an array or ! 482: structure. Copy const and volatile from original memref. */ ! 483: ! 484: MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (x) || GET_CODE (addr) == PLUS; ! 485: RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (x); ! 486: MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (x); ! 487: return mem; ! 488: } ! 489: return x; ! 490: } ! 491: ! 492: /* Copy the value or contents of X to a new temp reg and return that reg. */ ! 493: ! 494: rtx ! 495: copy_to_reg (x) ! 496: rtx x; ! 497: { ! 498: register rtx temp = gen_reg_rtx (GET_MODE (x)); ! 499: ! 500: /* If not an operand, must be an address with PLUS and MULT so ! 501: do the computation. */ ! 502: if (! general_operand (x, VOIDmode)) ! 503: x = force_operand (x, temp); ! 504: ! 505: if (x != temp) ! 506: emit_move_insn (temp, x); ! 507: ! 508: return temp; ! 509: } ! 510: ! 511: /* Like copy_to_reg but always give the new register mode Pmode ! 512: in case X is a constant. */ ! 513: ! 514: rtx ! 515: copy_addr_to_reg (x) ! 516: rtx x; ! 517: { ! 518: return copy_to_mode_reg (Pmode, x); ! 519: } ! 520: ! 521: /* Like copy_to_reg but always give the new register mode MODE ! 522: in case X is a constant. */ ! 523: ! 524: rtx ! 525: copy_to_mode_reg (mode, x) ! 526: enum machine_mode mode; ! 527: rtx x; ! 528: { ! 529: register rtx temp = gen_reg_rtx (mode); ! 530: ! 531: /* If not an operand, must be an address with PLUS and MULT so ! 532: do the computation. */ ! 533: if (! general_operand (x, VOIDmode)) ! 534: x = force_operand (x, temp); ! 535: ! 536: if (GET_MODE (x) != mode && GET_MODE (x) != VOIDmode) ! 537: abort (); ! 538: if (x != temp) ! 539: emit_move_insn (temp, x); ! 540: return temp; ! 541: } ! 542: ! 543: /* Load X into a register if it is not already one. ! 544: Use mode MODE for the register. ! 545: X should be valid for mode MODE, but it may be a constant which ! 546: is valid for all integer modes; that's why caller must specify MODE. ! 547: ! 548: The caller must not alter the value in the register we return, ! 549: since we mark it as a "constant" register. */ ! 550: ! 551: rtx ! 552: force_reg (mode, x) ! 553: enum machine_mode mode; ! 554: rtx x; ! 555: { ! 556: register rtx temp, insn; ! 557: ! 558: if (GET_CODE (x) == REG) ! 559: return x; ! 560: temp = gen_reg_rtx (mode); ! 561: insn = emit_move_insn (temp, x); ! 562: /* Let optimizers know that TEMP's value never changes ! 563: and that X can be substituted for it. */ ! 564: if (CONSTANT_P (x)) ! 565: { ! 566: rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX); ! 567: ! 568: if (note) ! 569: XEXP (note, 0) = x; ! 570: else ! 571: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, x, REG_NOTES (insn)); ! 572: } ! 573: return temp; ! 574: } ! 575: ! 576: /* If X is a memory ref, copy its contents to a new temp reg and return ! 577: that reg. Otherwise, return X. */ ! 578: ! 579: rtx ! 580: force_not_mem (x) ! 581: rtx x; ! 582: { ! 583: register rtx temp; ! 584: if (GET_CODE (x) != MEM || GET_MODE (x) == BLKmode) ! 585: return x; ! 586: temp = gen_reg_rtx (GET_MODE (x)); ! 587: emit_move_insn (temp, x); ! 588: return temp; ! 589: } ! 590: ! 591: /* Copy X to TARGET (if it's nonzero and a reg) ! 592: or to a new temp reg and return that reg. ! 593: MODE is the mode to use for X in case it is a constant. */ ! 594: ! 595: rtx ! 596: copy_to_suggested_reg (x, target, mode) ! 597: rtx x, target; ! 598: enum machine_mode mode; ! 599: { ! 600: register rtx temp; ! 601: ! 602: if (target && GET_CODE (target) == REG) ! 603: temp = target; ! 604: else ! 605: temp = gen_reg_rtx (mode); ! 606: ! 607: emit_move_insn (temp, x); ! 608: return temp; ! 609: } ! 610: ! 611: /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes). ! 612: This pops when ADJUST is positive. ADJUST need not be constant. */ ! 613: ! 614: void ! 615: adjust_stack (adjust) ! 616: rtx adjust; ! 617: { ! 618: rtx temp; ! 619: adjust = protect_from_queue (adjust, 0); ! 620: ! 621: if (adjust == const0_rtx) ! 622: return; ! 623: ! 624: temp = expand_binop (Pmode, ! 625: #ifdef STACK_GROWS_DOWNWARD ! 626: add_optab, ! 627: #else ! 628: sub_optab, ! 629: #endif ! 630: stack_pointer_rtx, adjust, stack_pointer_rtx, 0, ! 631: OPTAB_LIB_WIDEN); ! 632: ! 633: if (temp != stack_pointer_rtx) ! 634: emit_move_insn (stack_pointer_rtx, temp); ! 635: } ! 636: ! 637: /* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes). ! 638: This pushes when ADJUST is positive. ADJUST need not be constant. */ ! 639: ! 640: void ! 641: anti_adjust_stack (adjust) ! 642: rtx adjust; ! 643: { ! 644: rtx temp; ! 645: adjust = protect_from_queue (adjust, 0); ! 646: ! 647: if (adjust == const0_rtx) ! 648: return; ! 649: ! 650: temp = expand_binop (Pmode, ! 651: #ifdef STACK_GROWS_DOWNWARD ! 652: sub_optab, ! 653: #else ! 654: add_optab, ! 655: #endif ! 656: stack_pointer_rtx, adjust, stack_pointer_rtx, 0, ! 657: OPTAB_LIB_WIDEN); ! 658: ! 659: if (temp != stack_pointer_rtx) ! 660: emit_move_insn (stack_pointer_rtx, temp); ! 661: } ! 662: ! 663: /* Round the size of a block to be pushed up to the boundary required ! 664: by this machine. SIZE is the desired size, which need not be constant. */ ! 665: ! 666: rtx ! 667: round_push (size) ! 668: rtx size; ! 669: { ! 670: #ifdef STACK_BOUNDARY ! 671: int align = STACK_BOUNDARY / BITS_PER_UNIT; ! 672: if (align == 1) ! 673: return size; ! 674: if (GET_CODE (size) == CONST_INT) ! 675: { ! 676: int new = (INTVAL (size) + align - 1) / align * align; ! 677: if (INTVAL (size) != new) ! 678: size = GEN_INT (new); ! 679: } ! 680: else ! 681: { ! 682: size = expand_divmod (0, CEIL_DIV_EXPR, Pmode, size, GEN_INT (align), ! 683: NULL_RTX, 1); ! 684: size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1); ! 685: } ! 686: #endif /* STACK_BOUNDARY */ ! 687: return size; ! 688: } ! 689: ! 690: /* Save the stack pointer for the purpose in SAVE_LEVEL. PSAVE is a pointer ! 691: to a previously-created save area. If no save area has been allocated, ! 692: this function will allocate one. If a save area is specified, it ! 693: must be of the proper mode. ! 694: ! 695: The insns are emitted after insn AFTER, if nonzero, otherwise the insns ! 696: are emitted at the current position. */ ! 697: ! 698: void ! 699: emit_stack_save (save_level, psave, after) ! 700: enum save_level save_level; ! 701: rtx *psave; ! 702: rtx after; ! 703: { ! 704: rtx sa = *psave; ! 705: /* The default is that we use a move insn and save in a Pmode object. */ ! 706: rtx (*fcn) () = gen_move_insn; ! 707: enum machine_mode mode = Pmode; ! 708: ! 709: /* See if this machine has anything special to do for this kind of save. */ ! 710: switch (save_level) ! 711: { ! 712: #ifdef HAVE_save_stack_block ! 713: case SAVE_BLOCK: ! 714: if (HAVE_save_stack_block) ! 715: { ! 716: fcn = gen_save_stack_block; ! 717: mode = insn_operand_mode[CODE_FOR_save_stack_block][0]; ! 718: } ! 719: break; ! 720: #endif ! 721: #ifdef HAVE_save_stack_function ! 722: case SAVE_FUNCTION: ! 723: if (HAVE_save_stack_function) ! 724: { ! 725: fcn = gen_save_stack_function; ! 726: mode = insn_operand_mode[CODE_FOR_save_stack_function][0]; ! 727: } ! 728: break; ! 729: #endif ! 730: #ifdef HAVE_save_stack_nonlocal ! 731: case SAVE_NONLOCAL: ! 732: if (HAVE_save_stack_nonlocal) ! 733: { ! 734: fcn = gen_save_stack_nonlocal; ! 735: mode = insn_operand_mode[(int) CODE_FOR_save_stack_nonlocal][0]; ! 736: } ! 737: break; ! 738: #endif ! 739: } ! 740: ! 741: /* If there is no save area and we have to allocate one, do so. Otherwise ! 742: verify the save area is the proper mode. */ ! 743: ! 744: if (sa == 0) ! 745: { ! 746: if (mode != VOIDmode) ! 747: { ! 748: if (save_level == SAVE_NONLOCAL) ! 749: *psave = sa = assign_stack_local (mode, GET_MODE_SIZE (mode), 0); ! 750: else ! 751: *psave = sa = gen_reg_rtx (mode); ! 752: } ! 753: } ! 754: else ! 755: { ! 756: if (mode == VOIDmode || GET_MODE (sa) != mode) ! 757: abort (); ! 758: } ! 759: ! 760: if (after) ! 761: { ! 762: rtx seq; ! 763: ! 764: start_sequence (); ! 765: /* We must validize inside the sequence, to ensure that any instructions ! 766: created by the validize call also get moved to the right place. */ ! 767: if (sa != 0) ! 768: sa = validize_mem (sa); ! 769: emit_insn (fcn (sa, stack_pointer_rtx)); ! 770: seq = gen_sequence (); ! 771: end_sequence (); ! 772: emit_insn_after (seq, after); ! 773: } ! 774: else ! 775: { ! 776: if (sa != 0) ! 777: sa = validize_mem (sa); ! 778: emit_insn (fcn (sa, stack_pointer_rtx)); ! 779: } ! 780: } ! 781: ! 782: /* Restore the stack pointer for the purpose in SAVE_LEVEL. SA is the save ! 783: area made by emit_stack_save. If it is zero, we have nothing to do. ! 784: ! 785: Put any emitted insns after insn AFTER, if nonzero, otherwise at ! 786: current position. */ ! 787: ! 788: void ! 789: emit_stack_restore (save_level, sa, after) ! 790: enum save_level save_level; ! 791: rtx after; ! 792: rtx sa; ! 793: { ! 794: /* The default is that we use a move insn. */ ! 795: rtx (*fcn) () = gen_move_insn; ! 796: ! 797: /* See if this machine has anything special to do for this kind of save. */ ! 798: switch (save_level) ! 799: { ! 800: #ifdef HAVE_restore_stack_block ! 801: case SAVE_BLOCK: ! 802: if (HAVE_restore_stack_block) ! 803: fcn = gen_restore_stack_block; ! 804: break; ! 805: #endif ! 806: #ifdef HAVE_restore_stack_function ! 807: case SAVE_FUNCTION: ! 808: if (HAVE_restore_stack_function) ! 809: fcn = gen_restore_stack_function; ! 810: break; ! 811: #endif ! 812: #ifdef HAVE_restore_stack_nonlocal ! 813: ! 814: case SAVE_NONLOCAL: ! 815: if (HAVE_restore_stack_nonlocal) ! 816: fcn = gen_restore_stack_nonlocal; ! 817: break; ! 818: #endif ! 819: } ! 820: ! 821: if (sa != 0) ! 822: sa = validize_mem (sa); ! 823: ! 824: if (after) ! 825: { ! 826: rtx seq; ! 827: ! 828: start_sequence (); ! 829: emit_insn (fcn (stack_pointer_rtx, sa)); ! 830: seq = gen_sequence (); ! 831: end_sequence (); ! 832: emit_insn_after (seq, after); ! 833: } ! 834: else ! 835: emit_insn (fcn (stack_pointer_rtx, sa)); ! 836: } ! 837: ! 838: /* Return an rtx representing the address of an area of memory dynamically ! 839: pushed on the stack. This region of memory is always aligned to ! 840: a multiple of BIGGEST_ALIGNMENT. ! 841: ! 842: Any required stack pointer alignment is preserved. ! 843: ! 844: SIZE is an rtx representing the size of the area. ! 845: TARGET is a place in which the address can be placed. ! 846: ! 847: KNOWN_ALIGN is the alignment (in bits) that we know SIZE has. */ ! 848: ! 849: rtx ! 850: allocate_dynamic_stack_space (size, target, known_align) ! 851: rtx size; ! 852: rtx target; ! 853: int known_align; ! 854: { ! 855: /* Ensure the size is in the proper mode. */ ! 856: if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode) ! 857: size = convert_to_mode (Pmode, size, 1); ! 858: ! 859: /* We will need to ensure that the address we return is aligned to ! 860: BIGGEST_ALIGNMENT. If STACK_DYNAMIC_OFFSET is defined, we don't ! 861: always know its final value at this point in the compilation (it ! 862: might depend on the size of the outgoing parameter lists, for ! 863: example), so we must align the value to be returned in that case. ! 864: (Note that STACK_DYNAMIC_OFFSET will have a default non-zero value if ! 865: STACK_POINTER_OFFSET or ACCUMULATE_OUTGOING_ARGS are defined). ! 866: We must also do an alignment operation on the returned value if ! 867: the stack pointer alignment is less strict that BIGGEST_ALIGNMENT. ! 868: ! 869: If we have to align, we must leave space in SIZE for the hole ! 870: that might result from the alignment operation. */ ! 871: ! 872: #if defined (STACK_DYNAMIC_OFFSET) || defined(STACK_POINTER_OFFSET) || defined (ALLOCATE_OUTGOING_ARGS) ! 873: #define MUST_ALIGN ! 874: #endif ! 875: ! 876: #if ! defined (MUST_ALIGN) && (!defined(STACK_BOUNDARY) || STACK_BOUNDARY < BIGGEST_ALIGNMENT) ! 877: #define MUST_ALIGN ! 878: #endif ! 879: ! 880: #ifdef MUST_ALIGN ! 881: ! 882: #if 0 /* It turns out we must always make extra space, if MUST_ALIGN ! 883: because we must always round the address up at the end, ! 884: because we don't know whether the dynamic offset ! 885: will mess up the desired alignment. */ ! 886: /* If we have to round the address up regardless of known_align, ! 887: make extra space regardless, also. */ ! 888: if (known_align % BIGGEST_ALIGNMENT != 0) ! 889: #endif ! 890: { ! 891: if (GET_CODE (size) == CONST_INT) ! 892: size = GEN_INT (INTVAL (size) ! 893: + (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1)); ! 894: else ! 895: size = expand_binop (Pmode, add_optab, size, ! 896: GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT - 1), ! 897: NULL_RTX, 1, OPTAB_LIB_WIDEN); ! 898: } ! 899: ! 900: #endif ! 901: ! 902: #ifdef SETJMP_VIA_SAVE_AREA ! 903: /* If setjmp restores regs from a save area in the stack frame, ! 904: avoid clobbering the reg save area. Note that the offset of ! 905: virtual_incoming_args_rtx includes the preallocated stack args space. ! 906: It would be no problem to clobber that, but it's on the wrong side ! 907: of the old save area. */ ! 908: { ! 909: rtx dynamic_offset ! 910: = expand_binop (Pmode, sub_optab, virtual_stack_dynamic_rtx, ! 911: stack_pointer_rtx, NULL_RTX, 1, OPTAB_LIB_WIDEN); ! 912: size = expand_binop (Pmode, add_optab, size, dynamic_offset, ! 913: NULL_RTX, 1, OPTAB_LIB_WIDEN); ! 914: } ! 915: #endif /* SETJMP_VIA_SAVE_AREA */ ! 916: ! 917: /* Round the size to a multiple of the required stack alignment. ! 918: Since the stack if presumed to be rounded before this allocation, ! 919: this will maintain the required alignment. ! 920: ! 921: If the stack grows downward, we could save an insn by subtracting ! 922: SIZE from the stack pointer and then aligning the stack pointer. ! 923: The problem with this is that the stack pointer may be unaligned ! 924: between the execution of the subtraction and alignment insns and ! 925: some machines do not allow this. Even on those that do, some ! 926: signal handlers malfunction if a signal should occur between those ! 927: insns. Since this is an extremely rare event, we have no reliable ! 928: way of knowing which systems have this problem. So we avoid even ! 929: momentarily mis-aligning the stack. */ ! 930: ! 931: #ifdef STACK_BOUNDARY ! 932: /* If we added a variable amount to SIZE, ! 933: we can no longer assume it is aligned. */ ! 934: #if !defined (SETJMP_VIA_SAVE_AREA) && !defined (MUST_ALIGN) ! 935: if (known_align % STACK_BOUNDARY != 0) ! 936: #endif ! 937: size = round_push (size); ! 938: #endif ! 939: ! 940: do_pending_stack_adjust (); ! 941: ! 942: /* Don't use a TARGET that isn't a pseudo. */ ! 943: if (target == 0 || GET_CODE (target) != REG ! 944: || REGNO (target) < FIRST_PSEUDO_REGISTER) ! 945: target = gen_reg_rtx (Pmode); ! 946: ! 947: mark_reg_pointer (target); ! 948: ! 949: #ifndef STACK_GROWS_DOWNWARD ! 950: emit_move_insn (target, virtual_stack_dynamic_rtx); ! 951: #endif ! 952: ! 953: /* Perform the required allocation from the stack. Some systems do ! 954: this differently than simply incrementing/decrementing from the ! 955: stack pointer. */ ! 956: #ifdef HAVE_allocate_stack ! 957: if (HAVE_allocate_stack) ! 958: { ! 959: enum machine_mode mode ! 960: = insn_operand_mode[(int) CODE_FOR_allocate_stack][0]; ! 961: ! 962: if (insn_operand_predicate[(int) CODE_FOR_allocate_stack][0] ! 963: && ! ((*insn_operand_predicate[(int) CODE_FOR_allocate_stack][0]) ! 964: (size, mode))) ! 965: size = copy_to_mode_reg (mode, size); ! 966: ! 967: emit_insn (gen_allocate_stack (size)); ! 968: } ! 969: else ! 970: #endif ! 971: anti_adjust_stack (size); ! 972: ! 973: #ifdef STACK_GROWS_DOWNWARD ! 974: emit_move_insn (target, virtual_stack_dynamic_rtx); ! 975: #endif ! 976: ! 977: #ifdef MUST_ALIGN ! 978: #if 0 /* Even if we know the stack pointer has enough alignment, ! 979: there's no way to tell whether virtual_stack_dynamic_rtx shares that ! 980: alignment, so we still need to round the address up. */ ! 981: if (known_align % BIGGEST_ALIGNMENT != 0) ! 982: #endif ! 983: { ! 984: target = expand_divmod (0, CEIL_DIV_EXPR, Pmode, target, ! 985: GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT), ! 986: NULL_RTX, 1); ! 987: ! 988: target = expand_mult (Pmode, target, ! 989: GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT), ! 990: NULL_RTX, 1); ! 991: } ! 992: #endif ! 993: ! 994: /* Some systems require a particular insn to refer to the stack ! 995: to make the pages exist. */ ! 996: #ifdef HAVE_probe ! 997: if (HAVE_probe) ! 998: emit_insn (gen_probe ()); ! 999: #endif ! 1000: ! 1001: return target; ! 1002: } ! 1003: ! 1004: /* Return an rtx representing the register or memory location ! 1005: in which a scalar value of data type VALTYPE ! 1006: was returned by a function call to function FUNC. ! 1007: FUNC is a FUNCTION_DECL node if the precise function is known, ! 1008: otherwise 0. */ ! 1009: ! 1010: rtx ! 1011: hard_function_value (valtype, func) ! 1012: tree valtype; ! 1013: tree func; ! 1014: { ! 1015: return FUNCTION_VALUE (valtype, func); ! 1016: } ! 1017: ! 1018: /* Return an rtx representing the register or memory location ! 1019: in which a scalar value of mode MODE was returned by a library call. */ ! 1020: ! 1021: rtx ! 1022: hard_libcall_value (mode) ! 1023: enum machine_mode mode; ! 1024: { ! 1025: return LIBCALL_VALUE (mode); ! 1026: } ! 1027: ! 1028: /* Look up the tree code for a given rtx code ! 1029: to provide the arithmetic operation for REAL_ARITHMETIC. ! 1030: The function returns an int because the caller may not know ! 1031: what `enum tree_code' means. */ ! 1032: ! 1033: int ! 1034: rtx_to_tree_code (code) ! 1035: enum rtx_code code; ! 1036: { ! 1037: enum tree_code tcode; ! 1038: ! 1039: switch (code) ! 1040: { ! 1041: case PLUS: ! 1042: tcode = PLUS_EXPR; ! 1043: break; ! 1044: case MINUS: ! 1045: tcode = MINUS_EXPR; ! 1046: break; ! 1047: case MULT: ! 1048: tcode = MULT_EXPR; ! 1049: break; ! 1050: case DIV: ! 1051: tcode = RDIV_EXPR; ! 1052: break; ! 1053: case SMIN: ! 1054: tcode = MIN_EXPR; ! 1055: break; ! 1056: case SMAX: ! 1057: tcode = MAX_EXPR; ! 1058: break; ! 1059: default: ! 1060: tcode = LAST_AND_UNUSED_TREE_CODE; ! 1061: break; ! 1062: } ! 1063: return ((int) tcode); ! 1064: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.