|
|
1.1 ! root 1: /* Subroutines used for code generation on AMD Am29000. ! 2: Copyright (C) 1987, 1988, 1990, 1991 Free Software Foundation, Inc. ! 3: Contributed by Richard Kenner ([email protected]) ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: #include <stdio.h> ! 22: #include "config.h" ! 23: #include "rtl.h" ! 24: #include "regs.h" ! 25: #include "hard-reg-set.h" ! 26: #include "real.h" ! 27: #include "insn-config.h" ! 28: #include "conditions.h" ! 29: #include "insn-flags.h" ! 30: #include "output.h" ! 31: #include "insn-attr.h" ! 32: #include "flags.h" ! 33: #include "recog.h" ! 34: #include "expr.h" ! 35: #include "obstack.h" ! 36: #include "tree.h" ! 37: ! 38: #define min(A,B) ((A) < (B) ? (A) : (B)) ! 39: ! 40: /* This gives the size in words of the register stack for the current ! 41: procedure. */ ! 42: ! 43: static int a29k_regstack_size; ! 44: ! 45: /* This points to the last insn of the insn prologue. It is set when ! 46: an insn without a filled delay slot is found near the start of the ! 47: function. */ ! 48: ! 49: static char *a29k_last_prologue_insn; ! 50: ! 51: /* This points to the first insn that will be in the epilogue. It is null if ! 52: no epilogue is required. */ ! 53: ! 54: static char *a29k_first_epilogue_insn; ! 55: ! 56: /* This is nonzero if a a29k_first_epilogue_insn was put in a delay slot. It ! 57: indicates that an intermediate label needs to be written. */ ! 58: ! 59: static int a29k_first_epilogue_insn_used; ! 60: ! 61: /* Location to hold the name of the current function. We need this prolog to ! 62: contain the tag words prior to the declaration. So the name must be stored ! 63: away. */ ! 64: ! 65: char *a29k_function_name; ! 66: ! 67: /* Mapping of registers to debug register numbers. The only change is ! 68: for the frame pointer and the register numbers used for the incoming ! 69: arguments. */ ! 70: ! 71: int a29k_debug_reg_map[FIRST_PSEUDO_REGISTER]; ! 72: ! 73: /* Save information from a "cmpxx" operation until the branch or scc is ! 74: emitted. */ ! 75: ! 76: rtx a29k_compare_op0, a29k_compare_op1; ! 77: int a29k_compare_fp_p; ! 78: ! 79: /* Gives names for registers. */ ! 80: extern char *reg_names[]; ! 81: ! 82: /* Returns 1 if OP is a 8-bit constant. */ ! 83: ! 84: int ! 85: cint_8_operand (op, mode) ! 86: register rtx op; ! 87: enum machine_mode mode; ! 88: { ! 89: return GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffffff00) == 0; ! 90: } ! 91: ! 92: /* Returns 1 if OP is a 16-bit constant. */ ! 93: ! 94: int ! 95: cint_16_operand (op, mode) ! 96: rtx op; ! 97: enum machine_mode mode; ! 98: { ! 99: return GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0; ! 100: } ! 101: ! 102: /* Returns 1 if OP cannot be moved in a single insn. */ ! 103: ! 104: int ! 105: long_const_operand (op, mode) ! 106: register rtx op; ! 107: enum machine_mode mode; ! 108: { ! 109: if (! CONSTANT_P (op)) ! 110: return 0; ! 111: ! 112: if (TARGET_29050 && GET_CODE (op) == CONST_INT ! 113: && (INTVAL (op) & 0xffff) == 0) ! 114: return 0; ! 115: ! 116: return (GET_CODE (op) != CONST_INT ! 117: || ((INTVAL (op) & 0xffff0000) != 0 ! 118: && (INTVAL (op) & 0xffff0000) != 0xffff0000 ! 119: && INTVAL (op) != 0x80000000)); ! 120: } ! 121: ! 122: /* The following four functions detect constants of 0, 8, 16, and 24 used as ! 123: a position in ZERO_EXTRACT operations. They can either be the appropriate ! 124: constant integer or a shift (which will be produced by combine). */ ! 125: ! 126: static int ! 127: shift_constant_operand (op, mode, val) ! 128: rtx op; ! 129: enum machine_mode mode; ! 130: int val; ! 131: { ! 132: return ((GET_CODE (op) == CONST_INT && INTVAL (op) == val) ! 133: || (GET_CODE (op) == ASHIFT ! 134: && GET_CODE (XEXP (op, 0)) == CONST_INT ! 135: && INTVAL (XEXP (op, 0)) == val / 8 ! 136: && GET_CODE (XEXP (op, 1)) == CONST_INT ! 137: && INTVAL (XEXP (op, 1)) == 3)); ! 138: } ! 139: ! 140: int ! 141: const_0_operand (op, mode) ! 142: rtx op; ! 143: enum machine_mode mode; ! 144: { ! 145: return shift_constant_operand (op, mode, 0); ! 146: } ! 147: ! 148: int ! 149: const_8_operand (op, mode) ! 150: rtx op; ! 151: enum machine_mode mode; ! 152: { ! 153: return shift_constant_operand (op, mode, 8); ! 154: } ! 155: ! 156: int ! 157: const_16_operand (op, mode) ! 158: rtx op; ! 159: enum machine_mode; ! 160: { ! 161: return shift_constant_operand (op, mode, 16); ! 162: } ! 163: ! 164: int ! 165: const_24_operand (op, mode) ! 166: rtx op; ! 167: enum machine_mode; ! 168: { ! 169: return shift_constant_operand (op, mode, 24); ! 170: } ! 171: ! 172: /* Returns 1 if OP is a floating-point constant of the proper mode. */ ! 173: ! 174: int ! 175: float_const_operand (op, mode) ! 176: rtx op; ! 177: enum machine_mode mode; ! 178: { ! 179: return GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == mode; ! 180: } ! 181: ! 182: /* Returns 1 if OP is a floating-point constant of the proper mode or a ! 183: general-purpose register. */ ! 184: ! 185: int ! 186: gen_reg_or_float_constant_operand (op, mode) ! 187: rtx op; ! 188: enum machine_mode mode; ! 189: { ! 190: return float_const_operand (op, mode) || gen_reg_operand (op, mode); ! 191: } ! 192: ! 193: /* Returns 1 if OP is an integer constant of the proper mode or a ! 194: general-purpose register. */ ! 195: ! 196: int ! 197: gen_reg_or_integer_constant_operand (op, mode) ! 198: rtx op; ! 199: enum machine_mode mode; ! 200: { ! 201: return ((GET_MODE (op) == VOIDmode ! 202: && (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)) ! 203: || gen_reg_operand (op, mode)); ! 204: } ! 205: ! 206: /* Returns 1 if OP is a special machine register. */ ! 207: ! 208: int ! 209: spec_reg_operand (op, mode) ! 210: rtx op; ! 211: enum machine_mode mode; ! 212: { ! 213: return GET_MODE (op) == SImode && GET_CODE (op) == REG ! 214: && REGNO (op) >= R_BP && REGNO (op) <= R_EXO; ! 215: } ! 216: ! 217: /* Returns 1 if OP is an accumulator register. */ ! 218: ! 219: int ! 220: accum_reg_operand (op, mode) ! 221: rtx op; ! 222: enum machine_mode mode; ! 223: { ! 224: return (GET_CODE (op) == REG ! 225: && REGNO (op) >= R_ACC (0) && REGNO (op) <= R_ACC (3)); ! 226: } ! 227: ! 228: /* Returns 1 if OP is a normal data register. */ ! 229: ! 230: int ! 231: gen_reg_operand (op, mode) ! 232: rtx op; ! 233: enum machine_mode mode; ! 234: { ! 235: int regno; ! 236: ! 237: if (GET_MODE (op) != mode && mode != VOIDmode) ! 238: return 0; ! 239: ! 240: if (GET_CODE (op) == REG) ! 241: regno = REGNO (op); ! 242: else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG) ! 243: { ! 244: regno = REGNO (SUBREG_REG (op)); ! 245: if (regno < FIRST_PSEUDO_REGISTER) ! 246: regno += SUBREG_WORD (op); ! 247: } ! 248: else ! 249: return 0; ! 250: ! 251: return regno >= FIRST_PSEUDO_REGISTER || regno < R_BP; ! 252: } ! 253: ! 254: /* Returns 1 if OP is either an 8-bit constant integer or a general register. ! 255: If a register, it must be in the proper mode unless MODE is VOIDmode. */ ! 256: ! 257: int ! 258: srcb_operand (op, mode) ! 259: register rtx op; ! 260: enum machine_mode mode; ! 261: { ! 262: if (GET_CODE (op) == CONST_INT ! 263: && (mode == QImode ! 264: || (INTVAL (op) & 0xffffff00) == 0)) ! 265: return 1; ! 266: ! 267: if (GET_MODE (op) != mode && mode != VOIDmode) ! 268: return 0; ! 269: ! 270: return gen_reg_operand (op, mode); ! 271: } ! 272: ! 273: /* Return 1 if OP is either an immediate or a general register. This is used ! 274: for the input operand of mtsr/mtrsim. */ ! 275: ! 276: int ! 277: gen_reg_or_immediate_operand (op, mode) ! 278: rtx op; ! 279: enum machine_mode; ! 280: { ! 281: return gen_reg_operand (op, mode) || immediate_operand (op, mode); ! 282: } ! 283: ! 284: /* Return 1 if OP can be used as the second operand of and AND insn. This ! 285: includes srcb_operand and a constant whose complement fits in 8 bits. */ ! 286: ! 287: int ! 288: and_operand (op, mode) ! 289: rtx op; ! 290: enum machine_mode; ! 291: { ! 292: return (srcb_operand (op, mode) ! 293: || (GET_CODE (op) == CONST_INT ! 294: && ((unsigned) ((~ INTVAL (op)) & GET_MODE_MASK (mode)) < 256))); ! 295: } ! 296: ! 297: /* Return 1 if OP can be used as the second operand of an ADD insn. ! 298: This is the same as above, except we use negative, rather than ! 299: complement. */ ! 300: ! 301: int ! 302: add_operand (op, mode) ! 303: rtx op; ! 304: enum machine_mode; ! 305: { ! 306: return (srcb_operand (op, mode) ! 307: || (GET_CODE (op) == CONST_INT ! 308: && ((unsigned) ((- INTVAL (op)) & GET_MODE_MASK (mode)) < 256))); ! 309: } ! 310: ! 311: /* Return 1 if OP can be used as the input operand for a move insn. */ ! 312: ! 313: int ! 314: in_operand (op, mode) ! 315: rtx op; ! 316: enum machine_mode mode; ! 317: { ! 318: rtx orig_op = op; ! 319: ! 320: if (! general_operand (op, mode)) ! 321: return 0; ! 322: ! 323: while (GET_CODE (op) == SUBREG) ! 324: op = SUBREG_REG (op); ! 325: ! 326: switch (GET_CODE (op)) ! 327: { ! 328: case REG: ! 329: return 1; ! 330: ! 331: case MEM: ! 332: return (GET_MODE_SIZE (mode) >= UNITS_PER_WORD || TARGET_DW_ENABLE); ! 333: ! 334: case CONST_INT: ! 335: if (GET_MODE_CLASS (mode) != MODE_INT) ! 336: return 0; ! 337: ! 338: return 1; ! 339: ! 340: case CONST: ! 341: case SYMBOL_REF: ! 342: case LABEL_REF: ! 343: return (GET_MODE (op) == mode ! 344: || mode == SImode || mode == HImode || mode == QImode); ! 345: ! 346: case CONST_DOUBLE: ! 347: return ((GET_MODE_CLASS (mode) == MODE_FLOAT ! 348: && mode == GET_MODE (op)) ! 349: || (GET_MODE (op) == VOIDmode ! 350: && GET_MODE_CLASS (mode) == MODE_INT)); ! 351: ! 352: default: ! 353: return 0; ! 354: } ! 355: } ! 356: ! 357: /* Return 1 if OP can be used as the output operand for a move insn. */ ! 358: ! 359: int ! 360: out_operand (op, mode) ! 361: rtx op; ! 362: enum machine_mode mode; ! 363: { ! 364: rtx orig_op = op; ! 365: ! 366: if (! general_operand (op, mode)) ! 367: return 0; ! 368: ! 369: while (GET_CODE (op) == SUBREG) ! 370: op = SUBREG_REG (op); ! 371: ! 372: if (GET_CODE (op) == REG) ! 373: return (mode == SImode || gen_reg_operand (orig_op, mode) ! 374: || (GET_MODE_CLASS (mode) == MODE_FLOAT ! 375: && accum_reg_operand (orig_op, mode))); ! 376: ! 377: else if (GET_CODE (op) == MEM) ! 378: return mode == SImode || mode == SFmode || TARGET_DW_ENABLE; ! 379: ! 380: else ! 381: return 0; ! 382: } ! 383: ! 384: /* Return 1 if OP is some extension operator. */ ! 385: ! 386: int ! 387: extend_operator (op, mode) ! 388: rtx op; ! 389: enum machine_mode mode; ! 390: { ! 391: return ((mode == VOIDmode || GET_MODE (op) == mode) ! 392: && (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND)); ! 393: } ! 394: ! 395: /* Return 1 if OP is a comparison operator that we have in floating-point. */ ! 396: ! 397: int ! 398: fp_comparison_operator (op, mode) ! 399: rtx op; ! 400: enum machine_mode mode; ! 401: { ! 402: return ((mode == VOIDmode || mode == GET_MODE (op)) ! 403: && (GET_CODE (op) == EQ || GET_CODE (op) == GT || ! 404: GET_CODE (op) == GE)); ! 405: } ! 406: ! 407: /* Return 1 if OP is a valid branch comparison. */ ! 408: ! 409: int ! 410: branch_operator (op, mode) ! 411: rtx op; ! 412: enum machine_mode mode; ! 413: { ! 414: return ((mode == VOIDmode || mode == GET_MODE (op)) ! 415: && (GET_CODE (op) == GE || GET_CODE (op) == LT)); ! 416: } ! 417: ! 418: /* Return 1 if OP is a load multiple operation. It is known to be a ! 419: PARALLEL and the first three sections will be tested. */ ! 420: ! 421: int ! 422: load_multiple_operation (op, mode) ! 423: rtx op; ! 424: enum machine_mode mode; ! 425: { ! 426: int count = XVECLEN (op, 0) - 2; ! 427: int dest_regno; ! 428: rtx src_addr; ! 429: int i; ! 430: ! 431: /* Perform a quick check so we don't blow up below. */ ! 432: if (count <= 1 ! 433: || GET_CODE (XVECEXP (op, 0, 0)) != SET ! 434: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG ! 435: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) ! 436: return 0; ! 437: ! 438: dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); ! 439: src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); ! 440: ! 441: for (i = 1; i < count; i++) ! 442: { ! 443: rtx elt = XVECEXP (op, 0, i + 2); ! 444: ! 445: if (GET_CODE (elt) != SET ! 446: || GET_CODE (SET_DEST (elt)) != REG ! 447: || GET_MODE (SET_DEST (elt)) != SImode ! 448: || REGNO (SET_DEST (elt)) != dest_regno + i ! 449: || GET_CODE (SET_SRC (elt)) != MEM ! 450: || GET_MODE (SET_SRC (elt)) != SImode ! 451: || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS ! 452: || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) ! 453: || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT ! 454: || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) ! 455: return 0; ! 456: } ! 457: ! 458: return 1; ! 459: } ! 460: ! 461: /* Similar, but tests for store multiple. */ ! 462: ! 463: int ! 464: store_multiple_operation (op, mode) ! 465: rtx op; ! 466: enum machine_mode mode; ! 467: { ! 468: int num_special = TARGET_NO_STOREM_BUG ? 2 : 1; ! 469: int count = XVECLEN (op, 0) - num_special; ! 470: int src_regno; ! 471: rtx dest_addr; ! 472: int i; ! 473: ! 474: /* Perform a quick check so we don't blow up below. */ ! 475: if (count <= 1 ! 476: || GET_CODE (XVECEXP (op, 0, 0)) != SET ! 477: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM ! 478: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) ! 479: return 0; ! 480: ! 481: src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); ! 482: dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); ! 483: ! 484: for (i = 1; i < count; i++) ! 485: { ! 486: rtx elt = XVECEXP (op, 0, i + num_special); ! 487: ! 488: if (GET_CODE (elt) != SET ! 489: || GET_CODE (SET_SRC (elt)) != REG ! 490: || GET_MODE (SET_SRC (elt)) != SImode ! 491: || REGNO (SET_SRC (elt)) != src_regno + i ! 492: || GET_CODE (SET_DEST (elt)) != MEM ! 493: || GET_MODE (SET_DEST (elt)) != SImode ! 494: || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS ! 495: || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) ! 496: || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT ! 497: || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) ! 498: return 0; ! 499: } ! 500: ! 501: return 1; ! 502: } ! 503: ! 504: /* Given a special register REG and MASK, a value being masked against a ! 505: quantity to which the special register is set, return 1 if the masking ! 506: operation is built-in to the setting of that special register. */ ! 507: ! 508: int ! 509: masks_bits_for_special (reg, mask) ! 510: rtx reg; ! 511: rtx mask; ! 512: { ! 513: int needed_mask_value; ! 514: ! 515: if (GET_CODE (reg) != REG || GET_CODE (mask) != CONST_INT) ! 516: abort (); ! 517: ! 518: switch (REGNO (reg)) ! 519: { ! 520: case R_BP: ! 521: case R_INT: ! 522: needed_mask_value = 3; ! 523: break; ! 524: ! 525: case R_FC: ! 526: needed_mask_value = 31; ! 527: break; ! 528: ! 529: case R_CR: ! 530: case R_LRU: ! 531: needed_mask_value = 255; ! 532: break; ! 533: ! 534: case R_FPE: ! 535: needed_mask_value = 511; ! 536: break; ! 537: ! 538: case R_MMU: ! 539: needed_mask_value = 0x3ff; ! 540: break; ! 541: ! 542: case R_OPS: ! 543: case R_CPS: ! 544: case R_RBP: ! 545: case R_FPS: ! 546: needed_mask_value = 0xffff; ! 547: break; ! 548: ! 549: case R_VAB: ! 550: needed_mask_value = 0xffff0000; ! 551: break; ! 552: ! 553: case R_Q: ! 554: case R_CFG: ! 555: case R_CHA: ! 556: case R_CHD: ! 557: case R_CHC: ! 558: case R_TMC: ! 559: case R_TMR: ! 560: case R_PC0: ! 561: case R_PC1: ! 562: case R_PC2: ! 563: return 0; ! 564: ! 565: default: ! 566: abort (); ! 567: } ! 568: ! 569: return (INTVAL (mask) & ~ needed_mask_value) == 0; ! 570: } ! 571: ! 572: /* Return nonzero if this label is that of the return point, but there is ! 573: a non-null epilogue. */ ! 574: ! 575: int ! 576: epilogue_operand (op, mode) ! 577: rtx op; ! 578: enum machine_mode mode; ! 579: { ! 580: return next_active_insn (op) == 0 && a29k_first_epilogue_insn != 0; ! 581: } ! 582: ! 583: /* Return the register class of a scratch register needed to copy IN into ! 584: or out of a register in CLASS in MODE. If it can be done directly, ! 585: NO_REGS is returned. */ ! 586: ! 587: enum reg_class ! 588: secondary_reload_class (class, mode, in) ! 589: enum reg_class class; ! 590: enum machine_mode mode; ! 591: rtx in; ! 592: { ! 593: int regno = -1; ! 594: ! 595: if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG) ! 596: regno = true_regnum (in); ! 597: ! 598: /* We can place anything into GENERAL_REGS and can put GENERAL_REGS ! 599: into anything. */ ! 600: if (class == GENERAL_REGS || (regno != -1 && regno < R_BP)) ! 601: return NO_REGS; ! 602: ! 603: /* We can place 16-bit constants into a special register. */ ! 604: if (GET_CODE (in) == CONST_INT ! 605: && (GET_MODE_BITSIZE (mode) <= 16 ! 606: || (unsigned) INTVAL (in) <= 65535) ! 607: && (class == BP_REGS || class == Q_REGS || class == SPECIAL_REGS)) ! 608: return NO_REGS; ! 609: ! 610: /* Otherwise, we need GENERAL_REGS. */ ! 611: return GENERAL_REGS; ! 612: } ! 613: ! 614: /* START is the zero-based incoming argument register index used (0 is 160, ! 615: i.e., the first incoming argument register) and COUNT is the number used. ! 616: ! 617: Mark the corresponding incoming registers as neither fixed nor call used. ! 618: For each register used for incoming arguments, we have one less local ! 619: register that can be used. So also mark some high-numbered registers as ! 620: fixed. ! 621: ! 622: Return the first register number to use for the argument. */ ! 623: ! 624: int ! 625: incoming_reg (start, count) ! 626: int start; ! 627: int count; ! 628: { ! 629: int i; ! 630: ! 631: if (! TARGET_NO_REUSE_ARGS) ! 632: /* Mark all the used registers as not fixed and saved over calls. */ ! 633: for (i = R_AR (start); i < R_AR (16) && i < R_AR (start + count); i++) ! 634: { ! 635: fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0; ! 636: CLEAR_HARD_REG_BIT (fixed_reg_set, i); ! 637: CLEAR_HARD_REG_BIT (call_used_reg_set, i); ! 638: CLEAR_HARD_REG_BIT (call_fixed_reg_set, i); ! 639: } ! 640: ! 641: /* Shorten the maximum size of the frame. */ ! 642: for (i = R_AR (0) - start - count; i < R_AR (0) - start; i++) ! 643: { ! 644: fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1; ! 645: SET_HARD_REG_BIT (fixed_reg_set, i); ! 646: SET_HARD_REG_BIT (call_used_reg_set, i); ! 647: SET_HARD_REG_BIT (call_fixed_reg_set, i); ! 648: } ! 649: ! 650: return R_AR (start); ! 651: } ! 652: ! 653: /* These routines are used in finding insns to fill delay slots in the ! 654: epilogue. */ ! 655: ! 656: /* Return 1 if the current function will adjust the register stack. */ ! 657: ! 658: int ! 659: needs_regstack_p () ! 660: { ! 661: int i; ! 662: rtx insn; ! 663: ! 664: if (frame_pointer_needed) ! 665: return 1; ! 666: ! 667: /* If any local register is used, we need to adjust the regstack. */ ! 668: for (i = R_LR (127); i >= R_LR (0); i --) ! 669: if (regs_ever_live[i]) ! 670: return 1; ! 671: ! 672: /* We need a register stack if we make any calls. */ ! 673: for (insn = get_insns (); insn; insn = next_insn (insn)) ! 674: if (GET_CODE (insn) == CALL_INSN ! 675: || (GET_CODE (insn) == INSN ! 676: && GET_CODE (PATTERN (insn)) == SEQUENCE ! 677: && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)) ! 678: return 1; ! 679: ! 680: /* Otherwise, we don't. */ ! 681: return 0; ! 682: } ! 683: ! 684: /* Return 1 if X uses a local register. */ ! 685: ! 686: int ! 687: uses_local_reg_p (x) ! 688: rtx x; ! 689: { ! 690: char *fmt; ! 691: int i, j; ! 692: ! 693: switch (GET_CODE (x)) ! 694: { ! 695: case REG: ! 696: return REGNO (x) >= R_LR (0) && REGNO (x) <= R_FP; ! 697: ! 698: case CONST_INT: ! 699: case CONST: ! 700: case PC: ! 701: case CC0: ! 702: case LABEL_REF: ! 703: case SYMBOL_REF: ! 704: return 0; ! 705: } ! 706: ! 707: fmt = GET_RTX_FORMAT (GET_CODE (x)); ! 708: for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) ! 709: { ! 710: if (fmt[i] == 'e') ! 711: { ! 712: if (uses_local_reg_p (XEXP (x, i))) ! 713: return 1; ! 714: } ! 715: else if (fmt[i] == 'E') ! 716: { ! 717: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 718: if (uses_local_reg_p (XVECEXP (x, i, j))) ! 719: return 1; ! 720: } ! 721: } ! 722: ! 723: return 0; ! 724: } ! 725: ! 726: /* Returns 1 if this function is known to have a null epilogue. */ ! 727: ! 728: int ! 729: null_epilogue () ! 730: { ! 731: return (reload_completed && ! needs_regstack_p () ! 732: && get_frame_size () == 0 ! 733: && current_function_pretend_args_size == 0); ! 734: } ! 735: ! 736: /* Write out the assembler form of an operand. Recognize the following ! 737: special options: ! 738: ! 739: %N means write the low-order 8 bits of the negative of the constant ! 740: %Q means write a QImode operand (truncate constants to 8 bits) ! 741: %M means write the low-order 16 bits of the constant ! 742: %C means write the low-order 8 bits of the complement of the constant ! 743: %X means write the cntl values for LOAD with operand an extension op ! 744: %b means write `f' is this is a reversed condition, `t' otherwise ! 745: %B means write `t' is this is a reversed condition, `f' otherwise ! 746: %J means write the 29k opcode part for a comparison operation ! 747: %e means write the label with an extra `X' is this is the epilogue ! 748: otherwise the normal label name ! 749: %E means write nothing if this insn has a delay slot, ! 750: a nop unless this is the epilogue label, in which case ! 751: write the first epilogue insn ! 752: %F means write just the normal operand if the insn has a delay slot; ! 753: otherwise, this is a recursive call so output the ! 754: symbol + 4 and write the first prologue insn in the ! 755: delay slot. ! 756: %L means write the register number plus one ("low order" register) ! 757: or the low-order part of a multi-word constant ! 758: %O means write the register number plus two ! 759: %P means write the register number plus three ("low order" of TImode) ! 760: %S means write the number of words in the mode of the operand, ! 761: minus one (for CR) ! 762: %V means write the number of elements in a PARALLEL minus 1 ! 763: %# means write nothing if we have a delay slot, "\n\tnop" otherwise ! 764: %* means write the register name for TPC. */ ! 765: ! 766: void ! 767: print_operand (file, x, code) ! 768: FILE *file; ! 769: rtx x; ! 770: char code; ! 771: { ! 772: char buf[100]; ! 773: ! 774: /* These macros test for integers and extract the low-order bits. */ ! 775: #define INT_P(X) \ ! 776: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \ ! 777: && GET_MODE (X) == VOIDmode) ! 778: ! 779: #define INT_LOWPART(X) \ ! 780: (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X)) ! 781: ! 782: switch (code) ! 783: { ! 784: case 'Q': ! 785: if (GET_CODE (x) == REG) ! 786: break; ! 787: else if (! INT_P (x)) ! 788: output_operand_lossage ("invalid %%Q value"); ! 789: fprintf (file, "%d", INT_LOWPART (x) & 0xff); ! 790: return; ! 791: ! 792: case 'C': ! 793: if (! INT_P (x)) ! 794: output_operand_lossage ("invalid %%C value"); ! 795: fprintf (file, "%d", (~ INT_LOWPART (x)) & 0xff); ! 796: return; ! 797: ! 798: case 'N': ! 799: if (! INT_P (x)) ! 800: output_operand_lossage ("invalid %%N value"); ! 801: fprintf (file, "%d", (- INT_LOWPART (x)) & 0xff); ! 802: return; ! 803: ! 804: case 'M': ! 805: if (! INT_P (x)) ! 806: output_operand_lossage ("invalid %%M value"); ! 807: fprintf (file, "%d", INT_LOWPART (x) & 0xffff); ! 808: return; ! 809: ! 810: case 'X': ! 811: fprintf (file, "%d", ((GET_MODE (XEXP (x, 0)) == QImode ? 1 : 2) ! 812: + (GET_CODE (x) == SIGN_EXTEND ? 16 : 0))); ! 813: return; ! 814: ! 815: case 'b': ! 816: if (GET_CODE (x) == GE) ! 817: fprintf (file, "f"); ! 818: else ! 819: fprintf (file, "t"); ! 820: return; ! 821: ! 822: case 'B': ! 823: if (GET_CODE (x) == GE) ! 824: fprintf (file, "t"); ! 825: else ! 826: fprintf (file, "f"); ! 827: return; ! 828: ! 829: case 'J': ! 830: /* It so happens that the RTX names for the conditions are the same as ! 831: the 29k's insns except for "ne", which requires "neq". */ ! 832: fprintf (file, GET_RTX_NAME (GET_CODE (x))); ! 833: if (GET_CODE (x) == NE) ! 834: fprintf (file, "q"); ! 835: return; ! 836: ! 837: case 'e': ! 838: if (optimize && flag_delayed_branch ! 839: && a29k_last_prologue_insn == 0 && epilogue_operand (x, VOIDmode) ! 840: && dbr_sequence_length () == 0) ! 841: { ! 842: /* We need to output the label number of the last label in the ! 843: function, which is not necessarily X since there might be ! 844: a USE insn in between. First go forward to the last insn, then ! 845: back up to a label. */ ! 846: while (NEXT_INSN (x) != 0) ! 847: x = NEXT_INSN (x); ! 848: ! 849: while (GET_CODE (x) != CODE_LABEL) ! 850: x = PREV_INSN (x); ! 851: ! 852: ASM_GENERATE_INTERNAL_LABEL (buf, "LX", CODE_LABEL_NUMBER (x)); ! 853: assemble_name (file, buf); ! 854: } ! 855: else ! 856: output_asm_label (x); ! 857: return; ! 858: ! 859: case 'E': ! 860: if (dbr_sequence_length ()) ! 861: ; ! 862: else if (a29k_last_prologue_insn) ! 863: { ! 864: fprintf (file, "\n\t%s", a29k_last_prologue_insn); ! 865: a29k_last_prologue_insn = 0; ! 866: } ! 867: else if (optimize && flag_delayed_branch ! 868: && epilogue_operand (x, VOIDmode)) ! 869: { ! 870: fprintf (file, "\n\t%s", a29k_first_epilogue_insn); ! 871: a29k_first_epilogue_insn_used = 1; ! 872: } ! 873: else ! 874: fprintf (file, "\n\tnop"); ! 875: return; ! 876: ! 877: case 'F': ! 878: output_addr_const (file, x); ! 879: if (! strcmp (XSTR (x, 0), current_function_name) ! 880: && dbr_sequence_length () == 0) ! 881: fprintf (file, "+4\n\t%s,%d", ! 882: a29k_regstack_size >= 64 ? "const gr121" : "sub gr1,gr1", ! 883: a29k_regstack_size * 4); ! 884: return; ! 885: ! 886: case 'L': ! 887: if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode) ! 888: { ! 889: union real_extract u; ! 890: ! 891: bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u); ! 892: fprintf (file, "$double1(%.20e)", u.d); ! 893: } ! 894: else if (GET_CODE (x) == REG) ! 895: fprintf (file, "%s", reg_names[REGNO (x) + 1]); ! 896: else ! 897: output_operand_lossage ("invalid %%L value"); ! 898: return; ! 899: ! 900: case 'O': ! 901: if (GET_CODE (x) != REG) ! 902: output_operand_lossage ("invalid %%O value"); ! 903: fprintf (file, "%s", reg_names[REGNO (x) + 2]); ! 904: return; ! 905: ! 906: case 'P': ! 907: if (GET_CODE (x) != REG) ! 908: output_operand_lossage ("invalid %%P value"); ! 909: fprintf (file, "%s", reg_names[REGNO (x) + 3]); ! 910: return; ! 911: ! 912: case 'S': ! 913: fprintf (file, "%d", (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD)-1); ! 914: return; ! 915: ! 916: case 'V': ! 917: if (GET_CODE (x) != PARALLEL) ! 918: output_operand_lossage ("invalid %%V value"); ! 919: fprintf (file, "%d", XVECLEN (x, 0) - 2); ! 920: return; ! 921: ! 922: case '#': ! 923: if (dbr_sequence_length () == 0) ! 924: { ! 925: if (a29k_last_prologue_insn) ! 926: { ! 927: fprintf (file, "\n\t%s", a29k_last_prologue_insn); ! 928: a29k_last_prologue_insn = 0; ! 929: } ! 930: else ! 931: fprintf (file, "\n\tnop"); ! 932: } ! 933: return; ! 934: ! 935: case '*': ! 936: fprintf (file, "%s", reg_names [R_TPC]); ! 937: return; ! 938: } ! 939: ! 940: if (GET_CODE (x) == REG) ! 941: fprintf (file, "%s", reg_names [REGNO (x)]); ! 942: ! 943: else if (GET_CODE (x) == MEM) ! 944: output_address (XEXP (x, 0)); ! 945: ! 946: else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == SUBREG ! 947: && GET_CODE (SUBREG_REG (XEXP (x, 0))) == CONST_DOUBLE) ! 948: { ! 949: union real_extract u; ! 950: ! 951: if (GET_MODE (SUBREG_REG (XEXP (x, 0))) == SFmode) ! 952: fprintf (file, "$float"); ! 953: else ! 954: fprintf (file, "$double%d", SUBREG_WORD (XEXP (x, 0))); ! 955: bcopy (&CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))), &u, sizeof u); ! 956: fprintf (file, "(%.20e)", u.d); ! 957: } ! 958: ! 959: else if (GET_CODE (x) == CONST_DOUBLE ! 960: && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) ! 961: { ! 962: union real_extract u; ! 963: ! 964: bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u); ! 965: fprintf (file, "$%s(%.20e)", ! 966: GET_MODE (x) == SFmode ? "float" : "double0", u.d); ! 967: } ! 968: ! 969: else ! 970: output_addr_const (file, x); ! 971: } ! 972: ! 973: /* This page contains routines to output function prolog and epilog code. */ ! 974: ! 975: /* Output function prolog code to file FILE. Memory stack size is SIZE. ! 976: ! 977: Also sets register names for incoming arguments and frame pointer. */ ! 978: ! 979: void ! 980: output_prolog (file, size) ! 981: FILE *file; ! 982: int size; ! 983: { ! 984: int makes_calls = 0; ! 985: int arg_count = 0; ! 986: rtx insn; ! 987: int i; ! 988: unsigned int tag_word; ! 989: ! 990: /* See if we make any calls. We need to set lr1 if so. */ ! 991: for (insn = get_insns (); insn; insn = next_insn (insn)) ! 992: if (GET_CODE (insn) == CALL_INSN ! 993: || (GET_CODE (insn) == INSN ! 994: && GET_CODE (PATTERN (insn)) == SEQUENCE ! 995: && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)) ! 996: { ! 997: makes_calls = 1; ! 998: break; ! 999: } ! 1000: ! 1001: /* Find the highest local register used. */ ! 1002: for (i = R_LR (127); i >= R_LR (0); i--) ! 1003: if (regs_ever_live[i]) ! 1004: break; ! 1005: ! 1006: a29k_regstack_size = i - (R_LR (0) - 1); ! 1007: ! 1008: /* If calling routines, ensure we count lr0 & lr1. */ ! 1009: if (makes_calls && a29k_regstack_size < 2) ! 1010: a29k_regstack_size = 2; ! 1011: ! 1012: /* Count frame pointer and align to 8 byte boundary (even number of ! 1013: registers). */ ! 1014: a29k_regstack_size += frame_pointer_needed; ! 1015: if (a29k_regstack_size & 1) a29k_regstack_size++; ! 1016: ! 1017: /* See how many incoming arguments we have in registers. */ ! 1018: for (i = R_AR (0); i < R_AR (16); i++) ! 1019: if (! fixed_regs[i]) ! 1020: arg_count++; ! 1021: ! 1022: /* The argument count includes the caller's lr0 and lr1. */ ! 1023: arg_count += 2; ! 1024: ! 1025: /* Set the names and numbers of the frame pointer and incoming argument ! 1026: registers. */ ! 1027: ! 1028: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 1029: a29k_debug_reg_map[i] = i; ! 1030: ! 1031: reg_names[FRAME_POINTER_REGNUM] = reg_names[R_LR (a29k_regstack_size - 1)]; ! 1032: a29k_debug_reg_map[FRAME_POINTER_REGNUM] = R_LR (a29k_regstack_size - 1); ! 1033: ! 1034: for (i = 0; i < 16; i++) ! 1035: { ! 1036: reg_names[R_AR (i)] = reg_names[R_LR (a29k_regstack_size + i + 2)]; ! 1037: a29k_debug_reg_map[R_AR (i)] = R_LR (a29k_regstack_size + i + 2); ! 1038: } ! 1039: ! 1040: /* Compute memory stack size. Add in number of bytes that the we should ! 1041: push and pretend the caller did and the size of outgoing arguments. ! 1042: Then round to a doubleword boundary. */ ! 1043: size += (current_function_pretend_args_size ! 1044: + current_function_outgoing_args_size); ! 1045: size = (size + 7) & ~7; ! 1046: ! 1047: /* Write header words. See if one or two word form. */ ! 1048: tag_word = (frame_pointer_needed ? 0x400000 : 0) + (arg_count << 16); ! 1049: ! 1050: if (size / 8 > 0xff) ! 1051: fprintf (file, "\t.word %d, 0x%0x\n", (size / 8) << 2, ! 1052: 0x800000 + tag_word); ! 1053: else ! 1054: fprintf (file, "\t.word 0x%0x\n", tag_word + ((size / 8) << 3)); ! 1055: ! 1056: /* Define the function name. */ ! 1057: assemble_name (file, a29k_function_name); ! 1058: fprintf (file, ":\n"); ! 1059: ! 1060: /* Push the register stack by the proper amount. There are two possible ! 1061: ways to do this. */ ! 1062: if (a29k_regstack_size >= 256/4) ! 1063: fprintf (file, "\tconst %s,%d\n\tsub gr1,gr1,%s\n", ! 1064: reg_names[R_TAV], a29k_regstack_size * 4, reg_names[R_TAV]); ! 1065: else if (a29k_regstack_size) ! 1066: fprintf (file, "\tsub gr1,gr1,%d\n", a29k_regstack_size * 4); ! 1067: ! 1068: /* Test that the registers are available. */ ! 1069: if (a29k_regstack_size) ! 1070: fprintf (file, "\tasgeu V_%sSPILL,gr1,%s\n", ! 1071: TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RAB]); ! 1072: ! 1073: /* Set up frame pointer, if one is needed. */ ! 1074: if (frame_pointer_needed) ! 1075: fprintf (file, "\tsll %s,%s,0\n", reg_names[FRAME_POINTER_REGNUM], ! 1076: reg_names[R_MSP]); ! 1077: ! 1078: /* Make room for any frame space. There are three ways to do this. */ ! 1079: if (size >= 256) ! 1080: { ! 1081: fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size); ! 1082: if (size >= 65536) ! 1083: fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size); ! 1084: if (TARGET_STACK_CHECK) ! 1085: fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]); ! 1086: fprintf (file, "\tsub %s,%s,%s\n", ! 1087: reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]); ! 1088: } ! 1089: else if (size) ! 1090: { ! 1091: if (TARGET_STACK_CHECK) ! 1092: fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]); ! 1093: fprintf (file, "\tsub %s,%s,%d\n", ! 1094: reg_names[R_MSP], reg_names[R_MSP], size); ! 1095: } ! 1096: ! 1097: /* If this routine will make calls, set lr1. If we see an insn that ! 1098: can use a delay slot before a call or jump, save this insn for that ! 1099: slot (this condition is equivalent to seeing if we have an insn that ! 1100: needs delay slots before an insn that has a filled delay slot). */ ! 1101: a29k_last_prologue_insn = 0; ! 1102: if (makes_calls) ! 1103: { ! 1104: i = (a29k_regstack_size + arg_count) * 4; ! 1105: if (i >= 256) ! 1106: fprintf (file, "\tconst %s,%d\n\tadd lr1,gr1,%s\n", ! 1107: reg_names[R_TAV], i, reg_names[R_TAV]); ! 1108: else ! 1109: { ! 1110: if (optimize && flag_delayed_branch) ! 1111: for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) ! 1112: { ! 1113: if (GET_CODE (insn) == CODE_LABEL ! 1114: || (GET_CODE (insn) == INSN ! 1115: && GET_CODE (PATTERN (insn)) == SEQUENCE)) ! 1116: break; ! 1117: ! 1118: if (GET_CODE (insn) == NOTE ! 1119: || (GET_CODE (insn) == INSN ! 1120: && (GET_CODE (PATTERN (insn)) == USE ! 1121: || GET_CODE (PATTERN (insn)) == CLOBBER))) ! 1122: continue; ! 1123: ! 1124: if (num_delay_slots (insn) > 0) ! 1125: { ! 1126: a29k_last_prologue_insn = (char *) oballoc (100); ! 1127: sprintf (a29k_last_prologue_insn, "add lr1,gr1,%d", i); ! 1128: break; ! 1129: } ! 1130: } ! 1131: ! 1132: if (a29k_last_prologue_insn == 0) ! 1133: fprintf (file, "\tadd lr1,gr1,%d\n", i); ! 1134: } ! 1135: } ! 1136: ! 1137: /* Compute the first insn of the epilogue. */ ! 1138: a29k_first_epilogue_insn_used = 0; ! 1139: ! 1140: if (size == 0 && a29k_regstack_size == 0 && ! frame_pointer_needed) ! 1141: a29k_first_epilogue_insn = 0; ! 1142: else ! 1143: a29k_first_epilogue_insn = (char *) oballoc (100); ! 1144: ! 1145: if (frame_pointer_needed) ! 1146: sprintf (a29k_first_epilogue_insn, "sll %s,%s,0", ! 1147: reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]); ! 1148: else if (a29k_regstack_size) ! 1149: { ! 1150: if (a29k_regstack_size >= 256 / 4) ! 1151: sprintf (a29k_first_epilogue_insn, "const %s,%d", ! 1152: reg_names[R_TAV], a29k_regstack_size * 4); ! 1153: else ! 1154: sprintf (a29k_first_epilogue_insn, "add gr1,gr1,%d", ! 1155: a29k_regstack_size * 4); ! 1156: } ! 1157: else if (size) ! 1158: { ! 1159: if (size >= 256) ! 1160: sprintf (a29k_first_epilogue_insn, "const %s,%d", ! 1161: reg_names[R_TAV], size); ! 1162: else ! 1163: sprintf (a29k_first_epilogue_insn, "add %s,%s,%d", ! 1164: reg_names[R_MSP], reg_names[R_MSP], size); ! 1165: } ! 1166: } ! 1167: ! 1168: /* Call this after writing what might be the first instruction of the ! 1169: epilogue. If that first insn was used in a delay slot, an intermediate ! 1170: label is written. */ ! 1171: ! 1172: static void ! 1173: check_epilogue_internal_label (file) ! 1174: FILE *file; ! 1175: { ! 1176: rtx insn; ! 1177: ! 1178: if (! a29k_first_epilogue_insn_used) ! 1179: return; ! 1180: ! 1181: for (insn = get_last_insn (); ! 1182: GET_CODE (insn) != CODE_LABEL; ! 1183: insn = PREV_INSN (insn)) ! 1184: ; ! 1185: ! 1186: ASM_OUTPUT_INTERNAL_LABEL (file, "LX", CODE_LABEL_NUMBER (insn)); ! 1187: a29k_first_epilogue_insn_used = 0; ! 1188: } ! 1189: ! 1190: /* Output the epilog of the last procedure to file FILE. SIZE is the memory ! 1191: stack size. The register stack size is in the variable ! 1192: A29K_REGSTACK_SIZE. */ ! 1193: ! 1194: void ! 1195: output_epilog (file, size) ! 1196: FILE *file; ! 1197: int size; ! 1198: { ! 1199: rtx insn; ! 1200: int locals_unavailable = 0; /* True until after first insn ! 1201: after gr1 update. */ ! 1202: ! 1203: /* If we hit a BARRIER before a real insn or CODE_LABEL, we don't ! 1204: need to do anything because we are never jumped to. */ ! 1205: insn = get_last_insn (); ! 1206: if (GET_CODE (insn) == NOTE) ! 1207: insn = prev_nonnote_insn (insn); ! 1208: ! 1209: if (insn && GET_CODE (insn) == BARRIER) ! 1210: return; ! 1211: ! 1212: /* If a frame pointer was needed we must restore the memory stack pointer ! 1213: before adjusting the register stack. */ ! 1214: if (frame_pointer_needed) ! 1215: { ! 1216: fprintf (file, "\tsll %s,%s,0\n", ! 1217: reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]); ! 1218: check_epilogue_internal_label (file); ! 1219: } ! 1220: ! 1221: /* Restore the register stack. There are two ways to do this. */ ! 1222: if (a29k_regstack_size) ! 1223: { ! 1224: if (a29k_regstack_size >= 256/4) ! 1225: { ! 1226: fprintf (file, "\tconst %s,%d\n", ! 1227: reg_names[R_TAV], a29k_regstack_size * 4); ! 1228: check_epilogue_internal_label (file); ! 1229: fprintf (file, "\tadd gr1,gr1,%s\n", reg_names[R_TAV]); ! 1230: } ! 1231: else ! 1232: { ! 1233: fprintf (file, "\tadd gr1,gr1,%d\n", a29k_regstack_size * 4); ! 1234: check_epilogue_internal_label (file); ! 1235: } ! 1236: locals_unavailable = 1; ! 1237: } ! 1238: ! 1239: /* Restore the memory stack pointer if there is no frame pointer. ! 1240: Adjust the size to include any pretend arguments and pushed ! 1241: arguments and round to doubleword boundary. */ ! 1242: size += (current_function_pretend_args_size ! 1243: + current_function_outgoing_args_size); ! 1244: size = (size + 7) & ~7; ! 1245: ! 1246: if (size && ! frame_pointer_needed) ! 1247: { ! 1248: if (size >= 256) ! 1249: { ! 1250: fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size); ! 1251: check_epilogue_internal_label (file); ! 1252: locals_unavailable = 0; ! 1253: if (size >= 65536) ! 1254: fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size); ! 1255: fprintf (file, "\tadd %s,%s,%s\n", ! 1256: reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]); ! 1257: } ! 1258: else ! 1259: { ! 1260: fprintf (file, "\tadd %s,%s,%d\n", ! 1261: reg_names[R_MSP], reg_names[R_MSP], size); ! 1262: check_epilogue_internal_label (file); ! 1263: locals_unavailable = 0; ! 1264: } ! 1265: } ! 1266: ! 1267: if (locals_unavailable) ! 1268: { ! 1269: /* If we have an insn for this delay slot, write it. */ ! 1270: if (current_function_epilogue_delay_list) ! 1271: final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), ! 1272: file, 1, -2, 1); ! 1273: else ! 1274: fprintf (file, "\tnop\n"); ! 1275: } ! 1276: ! 1277: fprintf (file, "\tjmpi lr0\n"); ! 1278: if (a29k_regstack_size) ! 1279: fprintf (file, "\tasleu V_%sFILL,lr1,%s\n", ! 1280: TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RFB]); ! 1281: else if (current_function_epilogue_delay_list) ! 1282: final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), ! 1283: file, 1, -2, 1); ! 1284: else ! 1285: fprintf (file, "\tnop\n"); ! 1286: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.