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