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