|
|
1.1 root 1: /* Subroutines for insn-output.c for Sun SPARC. 1.1.1.2 ! root 2: Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc. 1.1 root 3: Contributed by Michael Tiemann ([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 "tree.h" 24: #include "rtl.h" 25: #include "regs.h" 26: #include "hard-reg-set.h" 27: #include "real.h" 28: #include "insn-config.h" 29: #include "conditions.h" 30: #include "insn-flags.h" 31: #include "output.h" 32: #include "insn-attr.h" 33: #include "flags.h" 34: #include "expr.h" 35: #include "recog.h" 36: 37: /* Global variables for machine-dependent things. */ 38: 39: /* Save the operands last given to a compare for use when we 40: generate a scc or bcc insn. */ 41: 42: rtx sparc_compare_op0, sparc_compare_op1; 43: 44: /* We may need an epilogue if we spill too many registers. 45: If this is non-zero, then we branch here for the epilogue. */ 46: static rtx leaf_label; 47: 48: #ifdef LEAF_REGISTERS 49: 50: /* Vector to say how input registers are mapped to output 51: registers. FRAME_POINTER_REGNUM cannot be remapped by 52: this function to eliminate it. You must use -fomit-frame-pointer 53: to get that. */ 54: char leaf_reg_remap[] = 55: { 0, 1, 2, 3, 4, 5, 6, 7, 56: -1, -1, -1, -1, -1, -1, 14, -1, 57: -1, -1, -1, -1, -1, -1, -1, -1, 58: 8, 9, 10, 11, 12, 13, -1, 15, 59: 60: 32, 33, 34, 35, 36, 37, 38, 39, 61: 40, 41, 42, 43, 44, 45, 46, 47, 62: 48, 49, 50, 51, 52, 53, 54, 55, 63: 56, 57, 58, 59, 60, 61, 62, 63}; 64: 1.1.1.2 ! root 65: #if 0 /* not used anymore */ 1.1 root 66: char leaf_reg_backmap[] = 67: { 0, 1, 2, 3, 4, 5, 6, 7, 68: 24, 25, 26, 27, 28, 29, 14, 31, 69: -1, -1, -1, -1, -1, -1, -1, -1, 70: -1, -1, -1, -1, -1, -1, -1, -1, 71: 72: 32, 33, 34, 35, 36, 37, 38, 39, 73: 40, 41, 42, 43, 44, 45, 46, 47, 74: 48, 49, 50, 51, 52, 53, 54, 55, 75: 56, 57, 58, 59, 60, 61, 62, 63}; 76: #endif 1.1.1.2 ! root 77: #endif 1.1 root 78: 79: /* Global variables set by FUNCTION_PROLOGUE. */ 80: /* Size of frame. Need to know this to emit return insns from 81: leaf procedures. */ 1.1.1.2 ! root 82: static int apparent_fsize; ! 83: static int actual_fsize; 1.1 root 84: 85: /* Name of where we pretend to think the frame pointer points. 86: Normally, this is "%fp", but if we are in a leaf procedure, 87: this is "%sp+something". */ 88: char *frame_base_name; 89: 90: static rtx find_addr_reg (); 91: 92: /* Return non-zero only if OP is a register of mode MODE, 93: or const0_rtx. */ 94: int 95: reg_or_0_operand (op, mode) 96: rtx op; 97: enum machine_mode mode; 98: { 99: if (op == const0_rtx || register_operand (op, mode)) 100: return 1; 1.1.1.2 ! root 101: if (GET_MODE (op) == DImode && GET_CODE (op) == CONST_DOUBLE 1.1 root 102: && CONST_DOUBLE_HIGH (op) == 0 103: && CONST_DOUBLE_LOW (op) == 0) 104: return 1; 1.1.1.2 ! root 105: if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT ! 106: && GET_CODE (op) == CONST_DOUBLE ! 107: && fp_zero_operand (op)) ! 108: return 1; 1.1 root 109: return 0; 110: } 111: 1.1.1.2 ! root 112: /* Nonzero if OP is a floating point value with value 0.0. */ ! 113: int ! 114: fp_zero_operand (op) ! 115: rtx op; ! 116: { ! 117: REAL_VALUE_TYPE r; ! 118: ! 119: REAL_VALUE_FROM_CONST_DOUBLE (r, op); ! 120: return REAL_VALUES_EQUAL (r, dconst0); ! 121: } ! 122: 1.1 root 123: /* Nonzero if OP can appear as the dest of a RESTORE insn. */ 124: int 125: restore_operand (op, mode) 126: rtx op; 127: enum machine_mode mode; 128: { 129: return (GET_CODE (op) == REG && GET_MODE (op) == mode 130: && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32))); 131: } 132: 133: /* Call insn on SPARC can take a PC-relative constant address, or any regular 134: memory address. */ 135: 136: int 137: call_operand (op, mode) 138: rtx op; 139: enum machine_mode mode; 140: { 141: if (GET_CODE (op) != MEM) 142: abort (); 143: op = XEXP (op, 0); 144: return (CONSTANT_P (op) || memory_address_p (Pmode, op)); 145: } 146: 147: int 148: call_operand_address (op, mode) 149: rtx op; 150: enum machine_mode mode; 151: { 152: return (CONSTANT_P (op) || memory_address_p (Pmode, op)); 153: } 154: 155: /* Returns 1 if OP is either a symbol reference or a sum of a symbol 156: reference and a constant. */ 157: 158: int 159: symbolic_operand (op, mode) 160: register rtx op; 161: enum machine_mode mode; 162: { 163: switch (GET_CODE (op)) 164: { 165: case SYMBOL_REF: 166: case LABEL_REF: 167: return 1; 168: 169: case CONST: 170: op = XEXP (op, 0); 171: return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF 172: || GET_CODE (XEXP (op, 0)) == LABEL_REF) 173: && GET_CODE (XEXP (op, 1)) == CONST_INT); 174: 175: /* ??? This clause seems to be irrelevant. */ 176: case CONST_DOUBLE: 177: return GET_MODE (op) == mode; 178: 179: default: 180: return 0; 181: } 182: } 183: 184: /* Return truth value of statement that OP is a symbolic memory 185: operand of mode MODE. */ 186: 187: int 188: symbolic_memory_operand (op, mode) 189: rtx op; 190: enum machine_mode mode; 191: { 192: if (GET_CODE (op) == SUBREG) 193: op = SUBREG_REG (op); 194: if (GET_CODE (op) != MEM) 195: return 0; 196: op = XEXP (op, 0); 197: return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST 198: || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF); 199: } 200: 201: /* Return 1 if the operand is either a register or a memory operand that is 202: not symbolic. */ 203: 204: int 205: reg_or_nonsymb_mem_operand (op, mode) 206: register rtx op; 207: enum machine_mode mode; 208: { 209: if (register_operand (op, mode)) 210: return 1; 211: 212: if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) 213: return 1; 214: 215: return 0; 216: } 217: 218: int 219: sparc_operand (op, mode) 220: rtx op; 221: enum machine_mode mode; 222: { 223: if (register_operand (op, mode)) 224: return 1; 225: if (GET_CODE (op) == CONST_INT) 226: return SMALL_INT (op); 227: if (GET_MODE (op) != mode) 228: return 0; 229: if (GET_CODE (op) == SUBREG) 230: op = SUBREG_REG (op); 231: if (GET_CODE (op) != MEM) 232: return 0; 233: 234: op = XEXP (op, 0); 235: if (GET_CODE (op) == LO_SUM) 236: return (GET_CODE (XEXP (op, 0)) == REG 237: && symbolic_operand (XEXP (op, 1), Pmode)); 238: return memory_address_p (mode, op); 239: } 240: 241: int 242: move_operand (op, mode) 243: rtx op; 244: enum machine_mode mode; 245: { 246: if (mode == DImode && arith_double_operand (op, mode)) 247: return 1; 248: if (register_operand (op, mode)) 249: return 1; 250: if (GET_CODE (op) == CONST_INT) 251: return (SMALL_INT (op) || (INTVAL (op) & 0x3ff) == 0); 252: 253: if (GET_MODE (op) != mode) 254: return 0; 255: if (GET_CODE (op) == SUBREG) 256: op = SUBREG_REG (op); 257: if (GET_CODE (op) != MEM) 258: return 0; 259: op = XEXP (op, 0); 260: if (GET_CODE (op) == LO_SUM) 261: return (register_operand (XEXP (op, 0), Pmode) 262: && CONSTANT_P (XEXP (op, 1))); 263: return memory_address_p (mode, op); 264: } 265: 266: int 267: move_pic_label (op, mode) 268: rtx op; 269: enum machine_mode mode; 270: { 271: /* Special case for PIC. */ 272: if (flag_pic && GET_CODE (op) == LABEL_REF) 273: return 1; 274: return 0; 275: } 276: 277: int 278: memop (op, mode) 279: rtx op; 280: enum machine_mode mode; 281: { 282: if (GET_CODE (op) == MEM) 283: return (mode == VOIDmode || mode == GET_MODE (op)); 284: return 0; 285: } 286: 287: /* Return truth value of whether OP is EQ or NE. */ 288: 289: int 290: eq_or_neq (op, mode) 291: rtx op; 292: enum machine_mode mode; 293: { 294: return (GET_CODE (op) == EQ || GET_CODE (op) == NE); 295: } 296: 297: /* Return 1 if this is a comparison operator, but not an EQ, NE, GEU, 298: or LTU for non-floating-point. We handle those specially. */ 299: 300: int 301: normal_comp_operator (op, mode) 302: rtx op; 303: enum machine_mode mode; 304: { 305: enum rtx_code code = GET_CODE (op); 306: 307: if (GET_RTX_CLASS (code) != '<') 308: return 0; 309: 310: if (GET_MODE (XEXP (op, 0)) == CCFPmode 311: || GET_MODE (XEXP (op, 0)) == CCFPEmode) 312: return 1; 313: 314: return (code != NE && code != EQ && code != GEU && code != LTU); 315: } 316: 317: /* Return 1 if this is a comparison operator. This allows the use of 318: MATCH_OPERATOR to recognize all the branch insns. */ 319: 320: int 321: noov_compare_op (op, mode) 322: register rtx op; 323: enum machine_mode mode; 324: { 325: enum rtx_code code = GET_CODE (op); 326: 327: if (GET_RTX_CLASS (code) != '<') 328: return 0; 329: 330: if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode) 331: /* These are the only branches which work with CC_NOOVmode. */ 332: return (code == EQ || code == NE || code == GE || code == LT); 333: return 1; 334: } 335: 336: /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */ 337: 338: int 339: extend_op (op, mode) 340: rtx op; 341: enum machine_mode mode; 342: { 343: return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND; 344: } 345: 346: /* Return nonzero if OP is an operator of mode MODE which can set 347: the condition codes explicitly. We do not include PLUS and MINUS 348: because these require CC_NOOVmode, which we handle explicitly. */ 349: 350: int 351: cc_arithop (op, mode) 352: rtx op; 353: enum machine_mode mode; 354: { 355: if (GET_CODE (op) == AND 356: || GET_CODE (op) == IOR 357: || GET_CODE (op) == XOR) 358: return 1; 359: 360: return 0; 361: } 362: 363: /* Return nonzero if OP is an operator of mode MODE which can bitwise 364: complement its second operand and set the condition codes explicitly. */ 365: 366: int 367: cc_arithopn (op, mode) 368: rtx op; 369: enum machine_mode mode; 370: { 371: /* XOR is not here because combine canonicalizes (xor (not ...) ...) 372: and (xor ... (not ...)) to (not (xor ...)). */ 373: return (GET_CODE (op) == AND 374: || GET_CODE (op) == IOR); 375: } 376: 377: /* Return true if OP is a register, or is a CONST_INT that can fit in a 13 378: bit immediate field. This is an acceptable SImode operand for most 3 379: address instructions. */ 380: 381: int 382: arith_operand (op, mode) 383: rtx op; 384: enum machine_mode mode; 385: { 386: return (register_operand (op, mode) 387: || (GET_CODE (op) == CONST_INT && SMALL_INT (op))); 388: } 389: 390: /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that 391: can fit in a 13 bit immediate field. This is an acceptable DImode operand 392: for most 3 address instructions. */ 393: 394: int 395: arith_double_operand (op, mode) 396: rtx op; 397: enum machine_mode mode; 398: { 399: return (register_operand (op, mode) 400: || (GET_CODE (op) == CONST_DOUBLE 401: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 402: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 403: && ((CONST_DOUBLE_HIGH (op) == -1 404: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0x1000) 405: || (CONST_DOUBLE_HIGH (op) == 0 406: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0))) 407: || (GET_CODE (op) == CONST_INT 408: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 409: && (unsigned) (INTVAL (op) + 0x1000) < 0x2000)); 410: } 411: 412: /* Return truth value of whether OP is a integer which fits the 413: range constraining immediate operands in most three-address insns, 414: which have a 13 bit immediate field. */ 415: 416: int 417: small_int (op, mode) 418: rtx op; 419: enum machine_mode mode; 420: { 421: return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); 422: } 423: 1.1.1.2 ! root 424: /* Recognize operand values for the umul instruction. That instruction sign ! 425: extends immediate values just like all other sparc instructions, but ! 426: interprets the extended result as an unsigned number. */ ! 427: ! 428: int ! 429: uns_small_int (op, mode) ! 430: rtx op; ! 431: enum machine_mode mode; ! 432: { ! 433: #if HOST_BITS_PER_WIDE_INT > 32 ! 434: /* All allowed constants will fit a CONST_INT. */ ! 435: return (GET_CODE (op) == CONST_INT ! 436: && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) ! 437: || (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L))); ! 438: #else ! 439: return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) ! 440: || (GET_CODE (op) == CONST_DOUBLE ! 441: && CONST_DOUBLE_HIGH (op) == 0 ! 442: && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); ! 443: #endif ! 444: } ! 445: ! 446: int ! 447: uns_arith_operand (op, mode) ! 448: rtx op; ! 449: enum machine_mode mode; ! 450: { ! 451: return register_operand (op, mode) || uns_small_int (op, mode); ! 452: } ! 453: 1.1 root 454: /* Return truth value of statement that OP is a call-clobbered register. */ 455: int 456: clobbered_register (op, mode) 457: rtx op; 458: enum machine_mode mode; 459: { 460: return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]); 461: } 462: 463: /* X and Y are two things to compare using CODE. Emit the compare insn and 464: return the rtx for register 0 in the proper mode. */ 465: 466: rtx 467: gen_compare_reg (code, x, y) 468: enum rtx_code code; 469: rtx x, y; 470: { 471: enum machine_mode mode = SELECT_CC_MODE (code, x, y); 472: rtx cc_reg = gen_rtx (REG, mode, 0); 473: 474: emit_insn (gen_rtx (SET, VOIDmode, cc_reg, 475: gen_rtx (COMPARE, mode, x, y))); 476: 477: return cc_reg; 478: } 479: 480: /* Return nonzero if a return peephole merging return with 481: setting of output register is ok. */ 482: int 483: leaf_return_peephole_ok () 484: { 485: return (actual_fsize == 0); 486: } 487: 488: /* Return nonzero if TRIAL can go into the function epilogue's 489: delay slot. SLOT is the slot we are trying to fill. */ 490: 491: int 492: eligible_for_epilogue_delay (trial, slot) 493: rtx trial; 494: int slot; 495: { 496: rtx pat, src; 497: 498: if (slot >= 1) 499: return 0; 500: if (GET_CODE (trial) != INSN 501: || GET_CODE (PATTERN (trial)) != SET) 502: return 0; 503: if (get_attr_length (trial) != 1) 504: return 0; 505: 506: /* In the case of a true leaf function, anything can go into the delay slot. 507: A delay slot only exists however if the frame size is zero, otherwise 508: we will put an insn to adjust the stack after the return. */ 509: if (leaf_function) 510: { 511: if (leaf_return_peephole_ok ()) 512: return (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE); 513: return 0; 514: } 515: 516: /* Otherwise, only operations which can be done in tandem with 517: a `restore' insn can go into the delay slot. */ 518: pat = PATTERN (trial); 519: if (GET_CODE (SET_DEST (pat)) != REG 520: || REGNO (SET_DEST (pat)) == 0 521: || REGNO (SET_DEST (pat)) >= 32 522: || REGNO (SET_DEST (pat)) < 24) 523: return 0; 524: 525: src = SET_SRC (pat); 526: if (arith_operand (src, GET_MODE (src))) 527: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); 528: if (arith_double_operand (src, GET_MODE (src))) 529: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); 530: if (GET_CODE (src) == PLUS) 531: { 532: if (register_operand (XEXP (src, 0), SImode) 533: && arith_operand (XEXP (src, 1), SImode)) 534: return 1; 535: if (register_operand (XEXP (src, 1), SImode) 536: && arith_operand (XEXP (src, 0), SImode)) 537: return 1; 538: if (register_operand (XEXP (src, 0), DImode) 539: && arith_double_operand (XEXP (src, 1), DImode)) 540: return 1; 541: if (register_operand (XEXP (src, 1), DImode) 542: && arith_double_operand (XEXP (src, 0), DImode)) 543: return 1; 544: } 545: if (GET_CODE (src) == MINUS 546: && register_operand (XEXP (src, 0), SImode) 547: && small_int (XEXP (src, 1), VOIDmode)) 548: return 1; 549: if (GET_CODE (src) == MINUS 550: && register_operand (XEXP (src, 0), DImode) 551: && !register_operand (XEXP (src, 1), DImode) 552: && arith_double_operand (XEXP (src, 1), DImode)) 553: return 1; 554: return 0; 555: } 556: 557: int 558: short_branch (uid1, uid2) 559: int uid1, uid2; 560: { 561: unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2]; 562: if (delta + 1024 < 2048) 563: return 1; 564: /* warning ("long branch, distance %d", delta); */ 565: return 0; 566: } 567: 568: /* Return non-zero if REG is not used after INSN. 569: We assume REG is a reload reg, and therefore does 570: not live past labels or calls or jumps. */ 571: int 572: reg_unused_after (reg, insn) 573: rtx reg; 574: rtx insn; 575: { 576: enum rtx_code code, prev_code = UNKNOWN; 577: 578: while (insn = NEXT_INSN (insn)) 579: { 580: if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)]) 581: return 1; 582: 583: code = GET_CODE (insn); 584: if (GET_CODE (insn) == CODE_LABEL) 585: return 1; 586: 587: if (GET_RTX_CLASS (code) == 'i') 588: { 589: rtx set = single_set (insn); 590: int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set)); 591: if (set && in_src) 592: return 0; 593: if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) 594: return 1; 595: if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) 596: return 0; 597: } 598: prev_code = code; 599: } 600: return 1; 601: } 602: 1.1.1.2 ! root 603: /* The rtx for the global offset table which is a special form ! 604: that *is* a position independent symbolic constant. */ ! 605: static rtx pic_pc_rtx; ! 606: ! 607: /* Ensure that we are not using patterns that are not OK with PIC. */ ! 608: ! 609: int ! 610: check_pic (i) ! 611: int i; ! 612: { ! 613: switch (flag_pic) ! 614: { ! 615: case 1: ! 616: if (GET_CODE (recog_operand[i]) == SYMBOL_REF ! 617: || (GET_CODE (recog_operand[i]) == CONST ! 618: && ! rtx_equal_p (pic_pc_rtx, recog_operand[i]))) ! 619: abort (); ! 620: case 2: ! 621: default: ! 622: return 1; ! 623: } ! 624: } ! 625: ! 626: /* Return true if X is an address which needs a temporary register when ! 627: reloaded while generating PIC code. */ ! 628: ! 629: int ! 630: pic_address_needs_scratch (x) ! 631: rtx x; ! 632: { ! 633: /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ ! 634: if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS ! 635: && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF ! 636: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! 637: && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) ! 638: return 1; ! 639: ! 640: return 0; ! 641: } ! 642: 1.1 root 643: /* Legitimize PIC addresses. If the address is already position-independent, 644: we return ORIG. Newly generated position-independent addresses go into a 645: reg. This is REG if non zero, otherwise we allocate register(s) as 1.1.1.2 ! root 646: necessary. */ 1.1 root 647: 648: rtx 1.1.1.2 ! root 649: legitimize_pic_address (orig, mode, reg) 1.1 root 650: rtx orig; 651: enum machine_mode mode; 1.1.1.2 ! root 652: rtx reg; 1.1 root 653: { 654: if (GET_CODE (orig) == SYMBOL_REF) 655: { 656: rtx pic_ref, address; 657: rtx insn; 658: 659: if (reg == 0) 660: { 661: if (reload_in_progress || reload_completed) 662: abort (); 663: else 664: reg = gen_reg_rtx (Pmode); 665: } 666: 667: if (flag_pic == 2) 668: { 669: /* If not during reload, allocate another temp reg here for loading 670: in the address, so that these instructions can be optimized 671: properly. */ 672: rtx temp_reg = ((reload_in_progress || reload_completed) 673: ? reg : gen_reg_rtx (Pmode)); 674: 675: /* Must put the SYMBOL_REF inside an UNSPEC here so that cse 676: won't get confused into thinking that these two instructions 677: are loading in the true address of the symbol. If in the 678: future a PIC rtx exists, that should be used instead. */ 679: emit_insn (gen_rtx (SET, VOIDmode, temp_reg, 680: gen_rtx (HIGH, Pmode, 681: gen_rtx (UNSPEC, Pmode, 682: gen_rtvec (1, orig), 683: 0)))); 684: emit_insn (gen_rtx (SET, VOIDmode, temp_reg, 685: gen_rtx (LO_SUM, Pmode, temp_reg, 686: gen_rtx (UNSPEC, Pmode, 687: gen_rtvec (1, orig), 688: 0)))); 689: address = temp_reg; 690: } 691: else 692: address = orig; 693: 694: pic_ref = gen_rtx (MEM, Pmode, 695: gen_rtx (PLUS, Pmode, 696: pic_offset_table_rtx, address)); 697: current_function_uses_pic_offset_table = 1; 698: RTX_UNCHANGING_P (pic_ref) = 1; 699: insn = emit_move_insn (reg, pic_ref); 700: /* Put a REG_EQUAL note on this insn, so that it can be optimized 701: by loop. */ 702: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig, 703: REG_NOTES (insn)); 704: return reg; 705: } 706: else if (GET_CODE (orig) == CONST) 707: { 708: rtx base, offset; 709: 710: if (GET_CODE (XEXP (orig, 0)) == PLUS 711: && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) 712: return orig; 713: 714: if (reg == 0) 715: { 716: if (reload_in_progress || reload_completed) 717: abort (); 718: else 719: reg = gen_reg_rtx (Pmode); 720: } 721: 722: if (GET_CODE (XEXP (orig, 0)) == PLUS) 723: { 1.1.1.2 ! root 724: base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); 1.1 root 725: offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, 1.1.1.2 ! root 726: base == reg ? 0 : reg); 1.1 root 727: } 728: else 729: abort (); 730: 731: if (GET_CODE (offset) == CONST_INT) 732: { 733: if (SMALL_INT (offset)) 734: return plus_constant_for_output (base, INTVAL (offset)); 735: else if (! reload_in_progress && ! reload_completed) 736: offset = force_reg (Pmode, offset); 737: else 1.1.1.2 ! root 738: /* If we reach here, then something is seriously wrong. */ 1.1 root 739: abort (); 740: } 741: return gen_rtx (PLUS, Pmode, base, offset); 742: } 743: else if (GET_CODE (orig) == LABEL_REF) 744: current_function_uses_pic_offset_table = 1; 745: 746: return orig; 747: } 748: 749: /* Set up PIC-specific rtl. This should not cause any insns 750: to be emitted. */ 751: 752: void 753: initialize_pic () 754: { 755: } 756: 757: /* Emit special PIC prologues and epilogues. */ 758: 759: void 760: finalize_pic () 761: { 762: /* The table we use to reference PIC data. */ 763: rtx global_offset_table; 764: /* Labels to get the PC in the prologue of this function. */ 765: rtx l1, l2; 766: rtx seq; 767: int orig_flag_pic = flag_pic; 768: 769: if (current_function_uses_pic_offset_table == 0) 770: return; 771: 772: if (! flag_pic) 773: abort (); 774: 775: flag_pic = 0; 776: l1 = gen_label_rtx (); 777: l2 = gen_label_rtx (); 778: 779: start_sequence (); 780: 781: emit_label (l1); 782: /* Note that we pun calls and jumps here! */ 783: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, 784: gen_rtvec (2, 785: gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)), 786: gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2))))); 787: emit_label (l2); 788: 789: /* Initialize every time through, since we can't easily 790: know this to be permanent. */ 791: global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_"); 792: pic_pc_rtx = gen_rtx (CONST, Pmode, 793: gen_rtx (MINUS, Pmode, 794: global_offset_table, 795: gen_rtx (CONST, Pmode, 796: gen_rtx (MINUS, Pmode, 797: gen_rtx (LABEL_REF, VOIDmode, l1), 798: pc_rtx)))); 799: 800: emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx, 801: gen_rtx (HIGH, Pmode, pic_pc_rtx))); 802: emit_insn (gen_rtx (SET, VOIDmode, 803: pic_offset_table_rtx, 804: gen_rtx (LO_SUM, Pmode, 805: pic_offset_table_rtx, pic_pc_rtx))); 806: emit_insn (gen_rtx (SET, VOIDmode, 807: pic_offset_table_rtx, 808: gen_rtx (PLUS, Pmode, 809: pic_offset_table_rtx, gen_rtx (REG, Pmode, 15)))); 810: /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */ 811: LABEL_PRESERVE_P (l1) = 1; 812: LABEL_PRESERVE_P (l2) = 1; 813: flag_pic = orig_flag_pic; 814: 815: seq = gen_sequence (); 816: end_sequence (); 817: emit_insn_after (seq, get_insns ()); 818: 819: /* Need to emit this whether or not we obey regdecls, 820: since setjmp/longjmp can cause life info to screw up. */ 821: emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); 822: } 823: 824: /* For the SPARC, REG and REG+CONST is cost 0, REG+REG is cost 1, 825: and addresses involving symbolic constants are cost 2. 826: 827: We make REG+REG slightly more expensive because it might keep 828: a register live for longer than we might like. 829: 830: PIC addresses are very expensive. 831: 832: It is no coincidence that this has the same structure 833: as GO_IF_LEGITIMATE_ADDRESS. */ 834: int 835: sparc_address_cost (X) 836: rtx X; 837: { 838: #if 0 839: /* Handled before calling here. */ 840: if (GET_CODE (X) == REG) 841: { return 1; } 842: #endif 843: if (GET_CODE (X) == PLUS) 844: { 845: if (GET_CODE (XEXP (X, 0)) == REG 846: && GET_CODE (XEXP (X, 1)) == REG) 847: return 2; 848: return 1; 849: } 850: else if (GET_CODE (X) == LO_SUM) 851: return 1; 852: else if (GET_CODE (X) == HIGH) 853: return 2; 854: return 4; 855: } 856: 857: /* Emit insns to move operands[1] into operands[0]. 858: 859: Return 1 if we have written out everything that needs to be done to 860: do the move. Otherwise, return 0 and the caller will emit the move 1.1.1.2 ! root 861: normally. */ 1.1 root 862: 863: int 1.1.1.2 ! root 864: emit_move_sequence (operands, mode) 1.1 root 865: rtx *operands; 866: enum machine_mode mode; 867: { 868: register rtx operand0 = operands[0]; 869: register rtx operand1 = operands[1]; 870: 1.1.1.2 ! root 871: if (CONSTANT_P (operand1) && flag_pic ! 872: && pic_address_needs_scratch (operand1)) ! 873: operands[1] = operand1 = legitimize_pic_address (operand1, mode, 0); ! 874: 1.1 root 875: /* Handle most common case first: storing into a register. */ 876: if (register_operand (operand0, mode)) 877: { 878: if (register_operand (operand1, mode) 879: || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) 880: || (GET_CODE (operand1) == CONST_DOUBLE 881: && arith_double_operand (operand1, DImode)) 882: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode) 883: /* Only `general_operands' can come here, so MEM is ok. */ 884: || GET_CODE (operand1) == MEM) 885: { 886: /* Run this case quickly. */ 887: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); 888: return 1; 889: } 890: } 891: else if (GET_CODE (operand0) == MEM) 892: { 893: if (register_operand (operand1, mode) || operand1 == const0_rtx) 894: { 895: /* Run this case quickly. */ 896: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); 897: return 1; 898: } 899: if (! reload_in_progress) 900: { 901: operands[0] = validize_mem (operand0); 902: operands[1] = operand1 = force_reg (mode, operand1); 903: } 904: } 905: 906: /* Simplify the source if we need to. Must handle DImode HIGH operators 907: here because such a move needs a clobber added. */ 908: if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) 909: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode)) 910: { 911: if (flag_pic && symbolic_operand (operand1, mode)) 912: { 913: rtx temp_reg = reload_in_progress ? operand0 : 0; 914: 1.1.1.2 ! root 915: operands[1] = legitimize_pic_address (operand1, mode, temp_reg); 1.1 root 916: } 917: else if (GET_CODE (operand1) == CONST_INT 918: ? (! SMALL_INT (operand1) 919: && (INTVAL (operand1) & 0x3ff) != 0) 920: : (GET_CODE (operand1) == CONST_DOUBLE 921: ? ! arith_double_operand (operand1, DImode) 922: : 1)) 923: { 924: /* For DImode values, temp must be operand0 because of the way 925: HI and LO_SUM work. The LO_SUM operator only copies half of 926: the LSW from the dest of the HI operator. If the LO_SUM dest is 927: not the same as the HI dest, then the MSW of the LO_SUM dest will 928: never be set. 929: 930: ??? The real problem here is that the ...(HI:DImode pattern emits 931: multiple instructions, and the ...(LO_SUM:DImode pattern emits 932: one instruction. This fails, because the compiler assumes that 933: LO_SUM copies all bits of the first operand to its dest. Better 934: would be to have the HI pattern emit one instruction and the 935: LO_SUM pattern multiple instructions. Even better would be 936: to use four rtl insns. */ 937: rtx temp = ((reload_in_progress || mode == DImode) 938: ? operand0 : gen_reg_rtx (mode)); 939: 940: emit_insn (gen_rtx (SET, VOIDmode, temp, 941: gen_rtx (HIGH, mode, operand1))); 942: operands[1] = gen_rtx (LO_SUM, mode, temp, operand1); 943: } 944: } 945: 946: if (GET_CODE (operand1) == LABEL_REF && flag_pic) 947: { 948: /* The procedure for doing this involves using a call instruction to 949: get the pc into o7. We need to indicate this explicitly because 950: the tablejump pattern assumes that it can use this value also. */ 951: emit_insn (gen_rtx (PARALLEL, VOIDmode, 952: gen_rtvec (2, 953: gen_rtx (SET, VOIDmode, operand0, 954: operand1), 955: gen_rtx (SET, VOIDmode, 956: gen_rtx (REG, mode, 15), 957: pc_rtx)))); 958: return 1; 959: } 960: 961: /* Now have insn-emit do whatever it normally does. */ 962: return 0; 963: } 964: 965: /* Return the best assembler insn template 966: for moving operands[1] into operands[0] as a fullword. */ 967: 968: char * 969: singlemove_string (operands) 970: rtx *operands; 971: { 972: if (GET_CODE (operands[0]) == MEM) 973: { 974: if (GET_CODE (operands[1]) != MEM) 975: return "st %r1,%0"; 976: else 977: abort (); 978: } 979: else if (GET_CODE (operands[1]) == MEM) 980: return "ld %1,%0"; 981: else if (GET_CODE (operands[1]) == CONST_DOUBLE) 982: { 1.1.1.2 ! root 983: REAL_VALUE_TYPE r; ! 984: long i; 1.1 root 985: 986: /* Must be SFmode, otherwise this doesn't make sense. */ 987: if (GET_MODE (operands[1]) != SFmode) 988: abort (); 989: 1.1.1.2 ! root 990: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); ! 991: REAL_VALUE_TO_TARGET_SINGLE (r, i); 1.1 root 992: operands[1] = gen_rtx (CONST_INT, VOIDmode, i); 993: 994: if (CONST_OK_FOR_LETTER_P (i, 'I')) 995: return "mov %1,%0"; 996: else if ((i & 0x000003FF) != 0) 997: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; 998: else 999: return "sethi %%hi(%a1),%0"; 1000: } 1001: else if (GET_CODE (operands[1]) == CONST_INT 1002: && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) 1003: { 1004: int i = INTVAL (operands[1]); 1005: 1006: /* If all low order 10 bits are clear, then we only need a single 1007: sethi insn to load the constant. */ 1008: if ((i & 0x000003FF) != 0) 1009: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; 1010: else 1011: return "sethi %%hi(%a1),%0"; 1012: } 1013: /* Operand 1 must be a register, or a 'I' type CONST_INT. */ 1014: return "mov %1,%0"; 1015: } 1016: 1017: /* Return non-zero if it is OK to assume that the given memory operand is 1018: aligned at least to a 8-byte boundary. This should only be called 1019: for memory accesses whose size is 8 bytes or larger. */ 1020: 1021: int 1022: mem_aligned_8 (mem) 1023: register rtx mem; 1024: { 1025: register rtx addr; 1026: register rtx base; 1027: register rtx offset; 1028: 1029: if (GET_CODE (mem) != MEM) 1030: return 0; /* It's gotta be a MEM! */ 1031: 1032: addr = XEXP (mem, 0); 1033: 1034: /* Now that all misaligned double parms are copied on function entry, 1035: we can assume any 64-bit object is 64-bit aligned except those which 1036: are at unaligned offsets from the stack or frame pointer. If the 1037: TARGET_UNALIGNED_DOUBLES switch is given, we do not make this 1038: assumption. */ 1039: 1040: /* See what register we use in the address. */ 1041: base = 0; 1042: if (GET_CODE (addr) == PLUS) 1043: { 1044: if (GET_CODE (XEXP (addr, 0)) == REG 1045: && GET_CODE (XEXP (addr, 1)) == CONST_INT) 1046: { 1047: base = XEXP (addr, 0); 1048: offset = XEXP (addr, 1); 1049: } 1050: } 1051: else if (GET_CODE (addr) == REG) 1052: { 1053: base = addr; 1054: offset = const0_rtx; 1055: } 1056: 1057: /* If it's the stack or frame pointer, check offset alignment. 1058: We can have improper alignment in the function entry code. */ 1059: if (base 1060: && (REGNO (base) == FRAME_POINTER_REGNUM 1061: || REGNO (base) == STACK_POINTER_REGNUM)) 1062: { 1063: if ((INTVAL (offset) & 0x7) == 0) 1064: return 1; 1065: } 1066: /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES 1067: is true, in which case we can only assume that an access is aligned if 1068: it is to an aggregate, it is to a constant address, or the address 1069: involves a LO_SUM. */ 1070: else if (! TARGET_UNALIGNED_DOUBLES || MEM_IN_STRUCT_P (mem) 1071: || CONSTANT_P (addr) || GET_CODE (addr) == LO_SUM) 1072: return 1; 1073: 1074: /* An obviously unaligned address. */ 1075: return 0; 1076: } 1077: 1078: enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }; 1079: 1080: /* Output assembler code to perform a doubleword move insn 1081: with operands OPERANDS. This is very similar to the following 1082: output_move_quad function. */ 1083: 1084: char * 1085: output_move_double (operands) 1086: rtx *operands; 1087: { 1088: register rtx op0 = operands[0]; 1089: register rtx op1 = operands[1]; 1090: register enum optype optype0; 1091: register enum optype optype1; 1092: rtx latehalf[2]; 1093: rtx addreg0 = 0; 1094: rtx addreg1 = 0; 1.1.1.2 ! root 1095: int highest_first = 0; ! 1096: int no_addreg1_decrement = 0; 1.1 root 1097: 1098: /* First classify both operands. */ 1099: 1100: if (REG_P (op0)) 1101: optype0 = REGOP; 1102: else if (offsettable_memref_p (op0)) 1103: optype0 = OFFSOP; 1104: else if (GET_CODE (op0) == MEM) 1105: optype0 = MEMOP; 1106: else 1107: optype0 = RNDOP; 1108: 1109: if (REG_P (op1)) 1110: optype1 = REGOP; 1111: else if (CONSTANT_P (op1)) 1112: optype1 = CNSTOP; 1113: else if (offsettable_memref_p (op1)) 1114: optype1 = OFFSOP; 1115: else if (GET_CODE (op1) == MEM) 1116: optype1 = MEMOP; 1117: else 1118: optype1 = RNDOP; 1119: 1120: /* Check for the cases that the operand constraints are not 1121: supposed to allow to happen. Abort if we get one, 1122: because generating code for these cases is painful. */ 1123: 1124: if (optype0 == RNDOP || optype1 == RNDOP 1125: || (optype0 == MEM && optype1 == MEM)) 1126: abort (); 1127: 1128: /* If an operand is an unoffsettable memory ref, find a register 1129: we can increment temporarily to make it refer to the second word. */ 1130: 1131: if (optype0 == MEMOP) 1132: addreg0 = find_addr_reg (XEXP (op0, 0)); 1133: 1134: if (optype1 == MEMOP) 1135: addreg1 = find_addr_reg (XEXP (op1, 0)); 1136: 1137: /* Ok, we can do one word at a time. 1138: Set up in LATEHALF the operands to use for the 1139: high-numbered (least significant) word and in some cases alter the 1140: operands in OPERANDS to be suitable for the low-numbered word. */ 1141: 1142: if (optype0 == REGOP) 1143: latehalf[0] = gen_rtx (REG, SImode, REGNO (op0) + 1); 1144: else if (optype0 == OFFSOP) 1145: latehalf[0] = adj_offsettable_operand (op0, 4); 1146: else 1147: latehalf[0] = op0; 1148: 1149: if (optype1 == REGOP) 1150: latehalf[1] = gen_rtx (REG, SImode, REGNO (op1) + 1); 1151: else if (optype1 == OFFSOP) 1152: latehalf[1] = adj_offsettable_operand (op1, 4); 1153: else if (optype1 == CNSTOP) 1154: split_double (op1, &operands[1], &latehalf[1]); 1155: else 1156: latehalf[1] = op1; 1157: 1158: /* Easy case: try moving both words at once. Check for moving between 1159: an even/odd register pair and a memory location. */ 1160: if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP 1161: && (REGNO (op0) & 1) == 0) 1162: || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP 1163: && (REGNO (op1) & 1) == 0)) 1164: { 1165: register rtx mem; 1166: 1167: if (optype0 == REGOP) 1168: mem = op1; 1169: else 1170: mem = op0; 1171: 1172: if (mem_aligned_8 (mem)) 1173: return (mem == op1 ? "ldd %1,%0" : "std %1,%0"); 1174: } 1175: 1176: /* If the first move would clobber the source of the second one, 1177: do them in the other order. */ 1178: 1179: /* Overlapping registers. */ 1180: if (optype0 == REGOP && optype1 == REGOP 1181: && REGNO (op0) == REGNO (latehalf[1])) 1182: { 1183: /* Do that word. */ 1184: output_asm_insn (singlemove_string (latehalf), latehalf); 1185: /* Do low-numbered word. */ 1186: return singlemove_string (operands); 1187: } 1188: /* Loading into a register which overlaps a register used in the address. */ 1189: else if (optype0 == REGOP && optype1 != REGOP 1190: && reg_overlap_mentioned_p (op0, op1)) 1191: { 1.1.1.2 ! root 1192: /* If both halves of dest are used in the src memory address, ! 1193: add the two regs and put them in the low reg (op0). ! 1194: Then it works to load latehalf first. */ ! 1195: if (reg_mentioned_p (op0, XEXP (op1, 0)) ! 1196: && reg_mentioned_p (latehalf[0], XEXP (op1, 0))) ! 1197: { ! 1198: rtx xops[2]; ! 1199: xops[0] = latehalf[0]; ! 1200: xops[1] = op0; ! 1201: output_asm_insn ("add %1,%0,%1", xops); ! 1202: operands[1] = gen_rtx (MEM, DImode, op0); ! 1203: latehalf[1] = adj_offsettable_operand (operands[1], 4); ! 1204: addreg1 = 0; ! 1205: highest_first = 1; ! 1206: } ! 1207: /* Only one register in the dest is used in the src memory address, ! 1208: and this is the first register of the dest, so we want to do ! 1209: the late half first here also. */ ! 1210: else if (! reg_mentioned_p (latehalf[0], XEXP (op1, 0))) ! 1211: highest_first = 1; ! 1212: /* Only one register in the dest is used in the src memory address, ! 1213: and this is the second register of the dest, so we want to do ! 1214: the late half last. If addreg1 is set, and addreg1 is the same ! 1215: register as latehalf, then we must suppress the trailing decrement, ! 1216: because it would clobber the value just loaded. */ ! 1217: else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0])) ! 1218: no_addreg1_decrement = 1; 1.1 root 1219: } 1220: 1.1.1.2 ! root 1221: /* Normal case: do the two words, low-numbered first. ! 1222: Overlap case (highest_first set): do high-numbered word first. */ 1.1 root 1223: 1.1.1.2 ! root 1224: if (! highest_first) ! 1225: output_asm_insn (singlemove_string (operands), operands); 1.1 root 1226: 1227: /* Make any unoffsettable addresses point at high-numbered word. */ 1228: if (addreg0) 1229: output_asm_insn ("add %0,0x4,%0", &addreg0); 1230: if (addreg1) 1231: output_asm_insn ("add %0,0x4,%0", &addreg1); 1232: 1233: /* Do that word. */ 1234: output_asm_insn (singlemove_string (latehalf), latehalf); 1235: 1236: /* Undo the adds we just did. */ 1237: if (addreg0) 1238: output_asm_insn ("add %0,-0x4,%0", &addreg0); 1.1.1.2 ! root 1239: if (addreg1 && ! no_addreg1_decrement) 1.1 root 1240: output_asm_insn ("add %0,-0x4,%0", &addreg1); 1241: 1.1.1.2 ! root 1242: if (highest_first) ! 1243: output_asm_insn (singlemove_string (operands), operands); ! 1244: 1.1 root 1245: return ""; 1246: } 1247: 1248: /* Output assembler code to perform a quadword move insn 1249: with operands OPERANDS. This is very similar to the preceding 1250: output_move_double function. */ 1251: 1252: char * 1253: output_move_quad (operands) 1254: rtx *operands; 1255: { 1256: register rtx op0 = operands[0]; 1257: register rtx op1 = operands[1]; 1258: register enum optype optype0; 1259: register enum optype optype1; 1260: rtx wordpart[4][2]; 1261: rtx addreg0 = 0; 1262: rtx addreg1 = 0; 1263: 1264: /* First classify both operands. */ 1265: 1266: if (REG_P (op0)) 1267: optype0 = REGOP; 1268: else if (offsettable_memref_p (op0)) 1269: optype0 = OFFSOP; 1270: else if (GET_CODE (op0) == MEM) 1271: optype0 = MEMOP; 1272: else 1273: optype0 = RNDOP; 1274: 1275: if (REG_P (op1)) 1276: optype1 = REGOP; 1277: else if (CONSTANT_P (op1)) 1278: optype1 = CNSTOP; 1279: else if (offsettable_memref_p (op1)) 1280: optype1 = OFFSOP; 1281: else if (GET_CODE (op1) == MEM) 1282: optype1 = MEMOP; 1283: else 1284: optype1 = RNDOP; 1285: 1286: /* Check for the cases that the operand constraints are not 1287: supposed to allow to happen. Abort if we get one, 1288: because generating code for these cases is painful. */ 1289: 1290: if (optype0 == RNDOP || optype1 == RNDOP 1291: || (optype0 == MEM && optype1 == MEM)) 1292: abort (); 1293: 1294: /* If an operand is an unoffsettable memory ref, find a register 1295: we can increment temporarily to make it refer to the later words. */ 1296: 1297: if (optype0 == MEMOP) 1298: addreg0 = find_addr_reg (XEXP (op0, 0)); 1299: 1300: if (optype1 == MEMOP) 1301: addreg1 = find_addr_reg (XEXP (op1, 0)); 1302: 1303: /* Ok, we can do one word at a time. 1304: Set up in wordpart the operands to use for each word of the arguments. */ 1305: 1306: if (optype0 == REGOP) 1307: { 1308: wordpart[0][0] = gen_rtx (REG, SImode, REGNO (op0) + 0); 1309: wordpart[1][0] = gen_rtx (REG, SImode, REGNO (op0) + 1); 1310: wordpart[2][0] = gen_rtx (REG, SImode, REGNO (op0) + 2); 1311: wordpart[3][0] = gen_rtx (REG, SImode, REGNO (op0) + 3); 1312: } 1313: else if (optype0 == OFFSOP) 1314: { 1315: wordpart[0][0] = adj_offsettable_operand (op0, 0); 1316: wordpart[1][0] = adj_offsettable_operand (op0, 4); 1317: wordpart[2][0] = adj_offsettable_operand (op0, 8); 1318: wordpart[3][0] = adj_offsettable_operand (op0, 12); 1319: } 1320: else 1321: { 1322: wordpart[0][0] = op0; 1323: wordpart[1][0] = op0; 1324: wordpart[2][0] = op0; 1325: wordpart[3][0] = op0; 1326: } 1327: 1328: if (optype1 == REGOP) 1329: { 1330: wordpart[0][1] = gen_rtx (REG, SImode, REGNO (op1) + 0); 1331: wordpart[1][1] = gen_rtx (REG, SImode, REGNO (op1) + 1); 1332: wordpart[2][1] = gen_rtx (REG, SImode, REGNO (op1) + 2); 1333: wordpart[3][1] = gen_rtx (REG, SImode, REGNO (op1) + 3); 1334: } 1335: else if (optype1 == OFFSOP) 1336: { 1337: wordpart[0][1] = adj_offsettable_operand (op1, 0); 1338: wordpart[1][1] = adj_offsettable_operand (op1, 4); 1339: wordpart[2][1] = adj_offsettable_operand (op1, 8); 1340: wordpart[3][1] = adj_offsettable_operand (op1, 12); 1341: } 1342: else if (optype1 == CNSTOP) 1343: { 1.1.1.2 ! root 1344: REAL_VALUE_TYPE r; ! 1345: long l[4]; ! 1346: ! 1347: /* This only works for TFmode floating point constants. */ ! 1348: if (GET_CODE (op1) != CONST_DOUBLE || GET_MODE (op1) != TFmode) ! 1349: abort (); ! 1350: ! 1351: REAL_VALUE_FROM_CONST_DOUBLE (r, op1); ! 1352: REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); ! 1353: ! 1354: wordpart[0][1] = GEN_INT (l[0]); ! 1355: wordpart[1][1] = GEN_INT (l[1]); ! 1356: wordpart[2][1] = GEN_INT (l[2]); ! 1357: wordpart[3][1] = GEN_INT (l[3]); 1.1 root 1358: } 1359: else 1360: { 1361: wordpart[0][1] = op1; 1362: wordpart[1][1] = op1; 1363: wordpart[2][1] = op1; 1364: wordpart[3][1] = op1; 1365: } 1366: 1367: /* Easy case: try moving the quad as two pairs. Check for moving between 1368: an even/odd register pair and a memory location. */ 1369: /* ??? Should also handle the case of non-offsettable addresses here. 1370: We can at least do the first pair as a ldd/std, and then do the third 1371: and fourth words individually. */ 1372: if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0) 1373: || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0)) 1374: { 1375: rtx mem; 1376: 1377: if (optype0 == REGOP) 1378: mem = op1; 1379: else 1380: mem = op0; 1381: 1382: if (mem_aligned_8 (mem)) 1383: { 1384: operands[2] = adj_offsettable_operand (mem, 8); 1385: if (mem == op1) 1386: return "ldd %1,%0;ldd %2,%S0"; 1387: else 1388: return "std %1,%0;std %S1,%2"; 1389: } 1390: } 1391: 1392: /* If the first move would clobber the source of the second one, 1393: do them in the other order. */ 1394: 1395: /* Overlapping registers. */ 1396: if (optype0 == REGOP && optype1 == REGOP 1397: && (REGNO (op0) == REGNO (wordpart[1][3]) 1398: || REGNO (op0) == REGNO (wordpart[1][2]) 1399: || REGNO (op0) == REGNO (wordpart[1][1]))) 1400: { 1401: /* Do fourth word. */ 1402: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); 1403: /* Do the third word. */ 1404: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); 1405: /* Do the second word. */ 1406: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); 1407: /* Do lowest-numbered word. */ 1408: return singlemove_string (wordpart[0]); 1409: } 1410: /* Loading into a register which overlaps a register used in the address. */ 1411: if (optype0 == REGOP && optype1 != REGOP 1412: && reg_overlap_mentioned_p (op0, op1)) 1413: { 1414: /* ??? Not implemented yet. This is a bit complicated, because we 1415: must load which ever part overlaps the address last. If the address 1416: is a double-reg address, then there are two parts which need to 1417: be done last, which is impossible. We would need a scratch register 1418: in that case. */ 1419: abort (); 1420: } 1421: 1422: /* Normal case: move the four words in lowest to higest address order. */ 1423: 1424: output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]); 1425: 1426: /* Make any unoffsettable addresses point at the second word. */ 1427: if (addreg0) 1428: output_asm_insn ("add %0,0x4,%0", &addreg0); 1429: if (addreg1) 1430: output_asm_insn ("add %0,0x4,%0", &addreg1); 1431: 1432: /* Do the second word. */ 1433: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); 1434: 1435: /* Make any unoffsettable addresses point at the third word. */ 1436: if (addreg0) 1437: output_asm_insn ("add %0,0x4,%0", &addreg0); 1438: if (addreg1) 1439: output_asm_insn ("add %0,0x4,%0", &addreg1); 1440: 1441: /* Do the third word. */ 1442: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); 1443: 1444: /* Make any unoffsettable addresses point at the fourth word. */ 1445: if (addreg0) 1446: output_asm_insn ("add %0,0x4,%0", &addreg0); 1447: if (addreg1) 1448: output_asm_insn ("add %0,0x4,%0", &addreg1); 1449: 1450: /* Do the fourth word. */ 1451: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); 1452: 1453: /* Undo the adds we just did. */ 1454: if (addreg0) 1455: output_asm_insn ("add %0,-0xc,%0", &addreg0); 1456: if (addreg1) 1457: output_asm_insn ("add %0,-0xc,%0", &addreg1); 1458: 1459: return ""; 1460: } 1461: 1462: /* Output assembler code to perform a doubleword move insn with operands 1463: OPERANDS, one of which must be a floating point register. */ 1464: 1465: char * 1466: output_fp_move_double (operands) 1467: rtx *operands; 1468: { 1469: if (FP_REG_P (operands[0])) 1470: { 1471: if (FP_REG_P (operands[1])) 1472: return "fmovs %1,%0\n\tfmovs %R1,%R0"; 1473: else if (GET_CODE (operands[1]) == REG) 1474: abort (); 1475: else 1476: return output_move_double (operands); 1477: } 1478: else if (FP_REG_P (operands[1])) 1479: { 1480: if (GET_CODE (operands[0]) == REG) 1481: abort (); 1482: else 1483: return output_move_double (operands); 1484: } 1485: else abort (); 1486: } 1487: 1488: /* Output assembler code to perform a quadword move insn with operands 1489: OPERANDS, one of which must be a floating point register. */ 1490: 1491: char * 1492: output_fp_move_quad (operands) 1493: rtx *operands; 1494: { 1495: register rtx op0 = operands[0]; 1496: register rtx op1 = operands[1]; 1497: 1498: if (FP_REG_P (op0)) 1499: { 1500: if (FP_REG_P (op1)) 1501: return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0"; 1502: else if (GET_CODE (op1) == REG) 1503: abort (); 1504: else 1505: return output_move_quad (operands); 1506: } 1507: else if (FP_REG_P (op1)) 1508: { 1509: if (GET_CODE (op0) == REG) 1510: abort (); 1511: else 1512: return output_move_quad (operands); 1513: } 1514: else 1515: abort (); 1516: } 1517: 1518: /* Return a REG that occurs in ADDR with coefficient 1. 1519: ADDR can be effectively incremented by incrementing REG. */ 1520: 1521: static rtx 1522: find_addr_reg (addr) 1523: rtx addr; 1524: { 1525: while (GET_CODE (addr) == PLUS) 1526: { 1527: /* We absolutely can not fudge the frame pointer here, because the 1528: frame pointer must always be 8 byte aligned. It also confuses 1529: debuggers. */ 1530: if (GET_CODE (XEXP (addr, 0)) == REG 1531: && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM) 1532: addr = XEXP (addr, 0); 1533: else if (GET_CODE (XEXP (addr, 1)) == REG 1534: && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM) 1535: addr = XEXP (addr, 1); 1536: else if (CONSTANT_P (XEXP (addr, 0))) 1537: addr = XEXP (addr, 1); 1538: else if (CONSTANT_P (XEXP (addr, 1))) 1539: addr = XEXP (addr, 0); 1540: else 1541: abort (); 1542: } 1543: if (GET_CODE (addr) == REG) 1544: return addr; 1545: abort (); 1546: } 1547: 1.1.1.2 ! root 1548: #if 0 /* not currently used */ ! 1549: 1.1 root 1550: void 1551: output_sized_memop (opname, mode, signedp) 1552: char *opname; 1553: enum machine_mode mode; 1554: int signedp; 1555: { 1556: static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" }; 1557: static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" }; 1558: static char *st_size_suffix[] = { "b", "h", "", "?", "d" }; 1559: char **opnametab, *modename; 1560: 1561: if (opname[0] == 'l') 1562: if (signedp) 1563: opnametab = ld_size_suffix_s; 1564: else 1565: opnametab = ld_size_suffix_u; 1566: else 1567: opnametab = st_size_suffix; 1568: modename = opnametab[GET_MODE_SIZE (mode) >> 1]; 1569: 1570: fprintf (asm_out_file, "\t%s%s", opname, modename); 1571: } 1572: 1573: void 1574: output_move_with_extension (operands) 1575: rtx *operands; 1576: { 1577: if (GET_MODE (operands[2]) == HImode) 1578: output_asm_insn ("sll %2,0x10,%0", operands); 1579: else if (GET_MODE (operands[2]) == QImode) 1580: output_asm_insn ("sll %2,0x18,%0", operands); 1581: else 1582: abort (); 1583: } 1.1.1.2 ! root 1584: #endif /* not currently used */ 1.1 root 1585: 1586: #if 0 1587: /* ??? These are only used by the movstrsi pattern, but we get better code 1588: in general without that, because emit_block_move can do just as good a 1589: job as this function does when alignment and size are known. When they 1590: aren't known, a call to strcpy may be faster anyways, because it is 1591: likely to be carefully crafted assembly language code, and below we just 1592: do a byte-wise copy. 1593: 1594: Also, emit_block_move expands into multiple read/write RTL insns, which 1595: can then be optimized, whereas our movstrsi pattern can not be optimized 1596: at all. */ 1597: 1598: /* Load the address specified by OPERANDS[3] into the register 1599: specified by OPERANDS[0]. 1600: 1601: OPERANDS[3] may be the result of a sum, hence it could either be: 1602: 1603: (1) CONST 1604: (2) REG 1605: (2) REG + CONST_INT 1606: (3) REG + REG + CONST_INT 1607: (4) REG + REG (special case of 3). 1608: 1609: Note that (3) is not a legitimate address. 1610: All cases are handled here. */ 1611: 1612: void 1613: output_load_address (operands) 1614: rtx *operands; 1615: { 1616: rtx base, offset; 1617: 1618: if (CONSTANT_P (operands[3])) 1619: { 1620: output_asm_insn ("set %3,%0", operands); 1621: return; 1622: } 1623: 1624: if (REG_P (operands[3])) 1625: { 1626: if (REGNO (operands[0]) != REGNO (operands[3])) 1627: output_asm_insn ("mov %3,%0", operands); 1628: return; 1629: } 1630: 1631: if (GET_CODE (operands[3]) != PLUS) 1632: abort (); 1633: 1634: base = XEXP (operands[3], 0); 1635: offset = XEXP (operands[3], 1); 1636: 1637: if (GET_CODE (base) == CONST_INT) 1638: { 1639: rtx tmp = base; 1640: base = offset; 1641: offset = tmp; 1642: } 1643: 1644: if (GET_CODE (offset) != CONST_INT) 1645: { 1646: /* Operand is (PLUS (REG) (REG)). */ 1647: base = operands[3]; 1648: offset = const0_rtx; 1649: } 1650: 1651: if (REG_P (base)) 1652: { 1653: operands[6] = base; 1654: operands[7] = offset; 1655: if (SMALL_INT (offset)) 1656: output_asm_insn ("add %6,%7,%0", operands); 1657: else 1658: output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands); 1659: } 1660: else if (GET_CODE (base) == PLUS) 1661: { 1662: operands[6] = XEXP (base, 0); 1663: operands[7] = XEXP (base, 1); 1664: operands[8] = offset; 1665: 1666: if (SMALL_INT (offset)) 1667: output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands); 1668: else 1669: output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands); 1670: } 1671: else 1672: abort (); 1673: } 1674: 1675: /* Output code to place a size count SIZE in register REG. 1676: ALIGN is the size of the unit of transfer. 1677: 1678: Because block moves are pipelined, we don't include the 1679: first element in the transfer of SIZE to REG. */ 1680: 1681: static void 1682: output_size_for_block_move (size, reg, align) 1683: rtx size, reg; 1684: rtx align; 1685: { 1686: rtx xoperands[3]; 1687: 1688: xoperands[0] = reg; 1689: xoperands[1] = size; 1690: xoperands[2] = align; 1691: if (GET_CODE (size) == REG) 1692: output_asm_insn ("sub %1,%2,%0", xoperands); 1693: else 1694: { 1695: xoperands[1] 1696: = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align)); 1697: output_asm_insn ("set %1,%0", xoperands); 1698: } 1699: } 1700: 1701: /* Emit code to perform a block move. 1702: 1703: OPERANDS[0] is the destination. 1704: OPERANDS[1] is the source. 1705: OPERANDS[2] is the size. 1706: OPERANDS[3] is the alignment safe to use. 1707: OPERANDS[4] is a register we can safely clobber as a temp. */ 1708: 1709: char * 1710: output_block_move (operands) 1711: rtx *operands; 1712: { 1713: /* A vector for our computed operands. Note that load_output_address 1714: makes use of (and can clobber) up to the 8th element of this vector. */ 1715: rtx xoperands[10]; 1716: rtx zoperands[10]; 1717: static int movstrsi_label = 0; 1718: int i; 1719: rtx temp1 = operands[4]; 1720: rtx sizertx = operands[2]; 1721: rtx alignrtx = operands[3]; 1722: int align = INTVAL (alignrtx); 1723: char label3[30], label5[30]; 1724: 1725: xoperands[0] = operands[0]; 1726: xoperands[1] = operands[1]; 1727: xoperands[2] = temp1; 1728: 1729: /* We can't move more than this many bytes at a time because we have only 1730: one register, %g1, to move them through. */ 1731: if (align > UNITS_PER_WORD) 1732: { 1733: align = UNITS_PER_WORD; 1734: alignrtx = gen_rtx (CONST_INT, VOIDmode, UNITS_PER_WORD); 1735: } 1736: 1737: /* We consider 8 ld/st pairs, for a total of 16 inline insns to be 1738: reasonable here. (Actually will emit a maximum of 18 inline insns for 1739: the case of size == 31 and align == 4). */ 1740: 1741: if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8 1742: && memory_address_p (QImode, plus_constant_for_output (xoperands[0], 1743: INTVAL (sizertx))) 1744: && memory_address_p (QImode, plus_constant_for_output (xoperands[1], 1745: INTVAL (sizertx)))) 1746: { 1747: int size = INTVAL (sizertx); 1748: int offset = 0; 1749: 1750: /* We will store different integers into this particular RTX. */ 1751: xoperands[2] = rtx_alloc (CONST_INT); 1752: PUT_MODE (xoperands[2], VOIDmode); 1753: 1754: /* This case is currently not handled. Abort instead of generating 1755: bad code. */ 1756: if (align > 4) 1757: abort (); 1758: 1759: if (align >= 4) 1760: { 1761: for (i = (size >> 2) - 1; i >= 0; i--) 1762: { 1763: INTVAL (xoperands[2]) = (i << 2) + offset; 1764: output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]", 1765: xoperands); 1766: } 1767: offset += (size & ~0x3); 1768: size = size & 0x3; 1769: if (size == 0) 1770: return ""; 1771: } 1772: 1773: if (align >= 2) 1774: { 1775: for (i = (size >> 1) - 1; i >= 0; i--) 1776: { 1777: INTVAL (xoperands[2]) = (i << 1) + offset; 1778: output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]", 1779: xoperands); 1780: } 1781: offset += (size & ~0x1); 1782: size = size & 0x1; 1783: if (size == 0) 1784: return ""; 1785: } 1786: 1787: if (align >= 1) 1788: { 1789: for (i = size - 1; i >= 0; i--) 1790: { 1791: INTVAL (xoperands[2]) = i + offset; 1792: output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]", 1793: xoperands); 1794: } 1795: return ""; 1796: } 1797: 1798: /* We should never reach here. */ 1799: abort (); 1800: } 1801: 1802: /* If the size isn't known to be a multiple of the alignment, 1803: we have to do it in smaller pieces. If we could determine that 1804: the size was a multiple of 2 (or whatever), we could be smarter 1805: about this. */ 1806: if (GET_CODE (sizertx) != CONST_INT) 1807: align = 1; 1808: else 1809: { 1810: int size = INTVAL (sizertx); 1811: while (size % align) 1812: align >>= 1; 1813: } 1814: 1815: if (align != INTVAL (alignrtx)) 1816: alignrtx = gen_rtx (CONST_INT, VOIDmode, align); 1817: 1818: xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); 1819: xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align); 1820: xoperands[5] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); 1821: 1822: ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3])); 1823: ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5])); 1824: 1825: /* This is the size of the transfer. Emit code to decrement the size 1826: value by ALIGN, and store the result in the temp1 register. */ 1827: output_size_for_block_move (sizertx, temp1, alignrtx); 1828: 1829: /* Must handle the case when the size is zero or negative, so the first thing 1830: we do is compare the size against zero, and only copy bytes if it is 1831: zero or greater. Note that we have already subtracted off the alignment 1832: once, so we must copy 1 alignment worth of bytes if the size is zero 1833: here. 1834: 1835: The SUN assembler complains about labels in branch delay slots, so we 1836: do this before outputting the load address, so that there will always 1837: be a harmless insn between the branch here and the next label emitted 1838: below. */ 1839: 1840: { 1841: char pattern[100]; 1842: 1843: sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]); 1844: output_asm_insn (pattern, xoperands); 1845: } 1846: 1847: zoperands[0] = operands[0]; 1848: zoperands[3] = plus_constant_for_output (operands[0], align); 1849: output_load_address (zoperands); 1850: 1851: /* ??? This might be much faster if the loops below were preconditioned 1852: and unrolled. 1853: 1854: That is, at run time, copy enough bytes one at a time to ensure that the 1855: target and source addresses are aligned to the the largest possible 1856: alignment. Then use a preconditioned unrolled loop to copy say 16 1857: bytes at a time. Then copy bytes one at a time until finish the rest. */ 1858: 1859: /* Output the first label separately, so that it is spaced properly. */ 1860: 1861: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3])); 1862: 1863: { 1864: char pattern[200]; 1865: register char *ld_suffix = (align == 1) ? "ub" : (align == 2) ? "uh" : ""; 1866: register char *st_suffix = (align == 1) ? "b" : (align == 2) ? "h" : ""; 1867: 1868: sprintf (pattern, "ld%s [%%1+%%2],%%%%g1\n\tsubcc %%2,%%4,%%2\n\tbge %s\n\tst%s %%%%g1,[%%0+%%2]\n%s:", ld_suffix, &label3[1], st_suffix, &label5[1]); 1869: output_asm_insn (pattern, xoperands); 1870: } 1871: 1872: return ""; 1873: } 1874: #endif 1875: 1876: /* Output reasonable peephole for set-on-condition-code insns. 1877: Note that these insns assume a particular way of defining 1878: labels. Therefore, *both* sparc.h and this function must 1879: be changed if a new syntax is needed. */ 1880: 1881: char * 1882: output_scc_insn (operands, insn) 1883: rtx operands[]; 1884: rtx insn; 1885: { 1886: static char string[100]; 1887: rtx label = 0, next = insn; 1888: int need_label = 0; 1889: 1890: /* Try doing a jump optimization which jump.c can't do for us 1891: because we did not expose that setcc works by using branches. 1892: 1893: If this scc insn is followed by an unconditional branch, then have 1894: the jump insn emitted here jump to that location, instead of to 1895: the end of the scc sequence as usual. */ 1896: 1897: do 1898: { 1899: if (GET_CODE (next) == CODE_LABEL) 1900: label = next; 1901: next = NEXT_INSN (next); 1902: if (next == 0) 1903: break; 1904: } 1905: while (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL); 1906: 1907: /* If we are in a sequence, and the following insn is a sequence also, 1908: then just following the current insn's next field will take us to the 1909: first insn of the next sequence, which is the wrong place. We don't 1910: want to optimize with a branch that has had its delay slot filled. 1911: Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next 1912: which fails only if NEXT is such a branch. */ 1913: 1914: if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next) 1915: && (! final_sequence || NEXT_INSN (PREV_INSN (next)) == next)) 1916: label = JUMP_LABEL (next); 1917: /* If not optimizing, jump label fields are not set. To be safe, always 1918: check here to whether label is still zero. */ 1919: if (label == 0) 1920: { 1921: label = gen_label_rtx (); 1922: need_label = 1; 1923: } 1924: 1925: LABEL_NUSES (label) += 1; 1926: 1927: operands[2] = label; 1928: 1929: /* If we are in a delay slot, assume it is the delay slot of an fpcc 1930: insn since our type isn't allowed anywhere else. */ 1931: 1932: /* ??? Fpcc instructions no longer have delay slots, so this code is 1933: probably obsolete. */ 1934: 1935: /* The fastest way to emit code for this is an annulled branch followed 1936: by two move insns. This will take two cycles if the branch is taken, 1937: and three cycles if the branch is not taken. 1938: 1939: However, if we are in the delay slot of another branch, this won't work, 1940: because we can't put a branch in the delay slot of another branch. 1941: The above sequence would effectively take 3 or 4 cycles respectively 1942: since a no op would have be inserted between the two branches. 1943: In this case, we want to emit a move, annulled branch, and then the 1944: second move. This sequence always takes 3 cycles, and hence is faster 1945: when we are in a branch delay slot. */ 1946: 1947: if (final_sequence) 1948: { 1949: strcpy (string, "mov 0,%0\n\t"); 1950: strcat (string, output_cbranch (operands[1], 2, 0, 1, 0)); 1951: strcat (string, "\n\tmov 1,%0"); 1952: } 1953: else 1954: { 1955: strcpy (string, output_cbranch (operands[1], 2, 0, 1, 0)); 1956: strcat (string, "\n\tmov 1,%0\n\tmov 0,%0"); 1957: } 1958: 1959: if (need_label) 1960: strcat (string, "\n%l2:"); 1961: 1962: return string; 1963: } 1964: 1965: /* Vectors to keep interesting information about registers where 1966: it can easily be got. */ 1967: 1968: /* Modes for condition codes. */ 1969: #define C_MODES \ 1970: ((1 << (int) CCmode) | (1 << (int) CC_NOOVmode) \ 1971: | (1 << (int) CCFPmode) | (1 << (int) CCFPEmode)) 1972: 1973: /* Modes for single-word (and smaller) quantities. */ 1974: #define S_MODES \ 1975: ((1 << (int) QImode) | (1 << (int) HImode) | (1 << (int) SImode) \ 1976: | (1 << (int) QFmode) | (1 << (int) HFmode) | (1 << (int) SFmode) \ 1977: | (1 << (int) CQImode) | (1 << (int) CHImode)) 1978: 1979: /* Modes for double-word (and smaller) quantities. */ 1980: #define D_MODES \ 1981: (S_MODES | (1 << (int) DImode) | (1 << (int) DFmode) \ 1982: | (1 << (int) CSImode) | (1 << (int) SCmode)) 1983: 1984: /* Modes for quad-word quantities. */ 1985: #define T_MODES \ 1986: (D_MODES | (1 << (int) TImode) | (1 << (int) TFmode) \ 1987: | (1 << (int) DCmode) | (1 << (int) CDImode)) 1988: 1989: /* Modes for single-float quantities. We must allow any single word or 1990: smaller quantity. This is because the fix/float conversion instructions 1991: take integer inputs/outputs from the float registers. */ 1992: #define SF_MODES (S_MODES) 1993: 1994: /* Modes for double-float quantities. */ 1995: #define DF_MODES (SF_MODES | (1 << (int) DFmode) | (1 << (int) SCmode)) 1996: 1997: /* Modes for quad-float quantities. */ 1998: #define TF_MODES (DF_MODES | (1 << (int) TFmode) | (1 << (int) DCmode)) 1999: 2000: /* Value is 1 if register/mode pair is acceptable on sparc. 2001: The funny mixture of D and T modes is because integer operations 2002: do not specially operate on tetra quantities, so non-quad-aligned 2003: registers can hold quadword quantities (except %o4 and %i4 because 2004: they cross fixed registers. */ 2005: 2006: int hard_regno_mode_ok[] = { 2007: C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, 2008: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, 2009: T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, 2010: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, 2011: 2012: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2013: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2014: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2015: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES}; 2016: 2017: #ifdef __GNUC__ 2018: inline 2019: #endif 2020: static int 2021: save_regs (file, low, high, base, offset, n_fregs) 2022: FILE *file; 2023: int low, high; 2024: char *base; 2025: int offset; 2026: int n_fregs; 2027: { 2028: int i; 2029: 2030: for (i = low; i < high; i += 2) 2031: { 2032: if (regs_ever_live[i] && ! call_used_regs[i]) 2033: if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2034: fprintf (file, "\tstd %s,[%s+%d]\n", 2035: reg_names[i], base, offset + 4 * n_fregs), 2036: n_fregs += 2; 2037: else 2038: fprintf (file, "\tst %s,[%s+%d]\n", 2039: reg_names[i], base, offset + 4 * n_fregs), 2040: n_fregs += 2; 2041: else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2042: fprintf (file, "\tst %s,[%s+%d]\n", 2043: reg_names[i+1], base, offset + 4 * n_fregs), 2044: n_fregs += 2; 2045: } 2046: return n_fregs; 2047: } 2048: 2049: #ifdef __GNUC__ 2050: inline 2051: #endif 2052: static int 2053: restore_regs (file, low, high, base, offset, n_fregs) 2054: FILE *file; 2055: int low, high; 2056: char *base; 2057: int offset; 2058: { 2059: int i; 2060: 2061: for (i = low; i < high; i += 2) 2062: { 2063: if (regs_ever_live[i] && ! call_used_regs[i]) 2064: if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2065: fprintf (file, "\tldd [%s+%d], %s\n", 2066: base, offset + 4 * n_fregs, reg_names[i]), 2067: n_fregs += 2; 2068: else 2069: fprintf (file, "\tld [%s+%d],%s\n", 2070: base, offset + 4 * n_fregs, reg_names[i]), 2071: n_fregs += 2; 2072: else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2073: fprintf (file, "\tld [%s+%d],%s\n", 2074: base, offset + 4 * n_fregs, reg_names[i+1]), 2075: n_fregs += 2; 2076: } 2077: return n_fregs; 2078: } 2079: 2080: /* Static variables we want to share between prologue and epilogue. */ 2081: 2082: /* Number of live floating point registers needed to be saved. */ 2083: static int num_fregs; 2084: 2085: int 2086: compute_frame_size (size, leaf_function) 2087: int size; 2088: int leaf_function; 2089: { 2090: int fregs_ever_live = 0; 2091: int n_fregs = 0, i; 2092: int outgoing_args_size = (current_function_outgoing_args_size 2093: + REG_PARM_STACK_SPACE (current_function_decl)); 2094: 2095: apparent_fsize = ((size) + 7 - STARTING_FRAME_OFFSET) & -8; 2096: for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2) 2097: fregs_ever_live |= regs_ever_live[i]|regs_ever_live[i+1]; 2098: 2099: if (TARGET_EPILOGUE && fregs_ever_live) 2100: { 2101: for (i = 32; i < FIRST_PSEUDO_REGISTER; i += 2) 2102: if ((regs_ever_live[i] && ! call_used_regs[i]) 2103: || (regs_ever_live[i+1] && ! call_used_regs[i+1])) 2104: n_fregs += 2; 2105: } 2106: 2107: /* Set up values for use in `function_epilogue'. */ 2108: num_fregs = n_fregs; 2109: 2110: apparent_fsize += (outgoing_args_size+7) & -8; 2111: if (leaf_function && n_fregs == 0 2112: && apparent_fsize == (REG_PARM_STACK_SPACE (current_function_decl) 2113: - STARTING_FRAME_OFFSET)) 2114: apparent_fsize = 0; 2115: 2116: actual_fsize = apparent_fsize + n_fregs*4; 2117: 2118: /* Make sure nothing can clobber our register windows. 2119: If a SAVE must be done, or there is a stack-local variable, 2120: the register window area must be allocated. */ 2121: if (leaf_function == 0 || size > 0) 2122: actual_fsize += (16 * UNITS_PER_WORD)+8; 2123: 2124: return actual_fsize; 2125: } 2126: 2127: /* Output code for the function prologue. */ 2128: 2129: void 2130: output_function_prologue (file, size, leaf_function) 2131: FILE *file; 2132: int size; 2133: int leaf_function; 2134: { 2135: /* ??? This should be %sp+actual_fsize for a leaf function. I think it 2136: works only because it is never used. */ 2137: if (leaf_function) 2138: frame_base_name = "%sp+80"; 2139: else 2140: frame_base_name = "%fp"; 2141: 2142: /* Need to use actual_fsize, since we are also allocating 2143: space for our callee (and our own register save area). */ 2144: actual_fsize = compute_frame_size (size, leaf_function); 2145: 2146: fprintf (file, "\t!#PROLOGUE# 0\n"); 2147: if (actual_fsize == 0) 2148: /* do nothing. */ ; 2149: else if (actual_fsize <= 4096) 2150: { 2151: if (! leaf_function) 2152: fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); 2153: else 2154: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize); 2155: } 2156: else if (actual_fsize <= 8192) 2157: { 2158: /* For frames in the range 4097..8192, we can use just two insns. */ 2159: if (! leaf_function) 2160: { 2161: fprintf (file, "\tsave %%sp,-4096,%%sp\n"); 2162: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); 2163: } 2164: else 2165: { 2166: fprintf (file, "\tadd %%sp,-4096,%%sp\n"); 2167: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); 2168: } 2169: } 2170: else 2171: { 2172: if (! leaf_function) 2173: { 2174: fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); 2175: if ((actual_fsize & 0x3ff) != 0) 2176: fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize); 2177: fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); 2178: } 2179: else 2180: { 2181: fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); 2182: if ((actual_fsize & 0x3ff) != 0) 2183: fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize); 2184: fprintf (file, "\tadd %%sp,%%g1,%%sp\n"); 2185: } 2186: } 2187: 2188: /* If doing anything with PIC, do it now. */ 2189: if (! flag_pic) 2190: fprintf (file, "\t!#PROLOGUE# 1\n"); 2191: 2192: /* Figure out where to save any special registers. */ 2193: if (num_fregs) 2194: { 2195: int offset, n_fregs = num_fregs; 2196: 2197: /* ??? This should always be -apparent_fsize. */ 2198: if (! leaf_function) 2199: offset = -apparent_fsize; 2200: else 2201: offset = 0; 2202: 2203: if (TARGET_EPILOGUE && ! leaf_function) 2204: n_fregs = save_regs (file, 0, 16, frame_base_name, offset, 0); 2205: else if (leaf_function) 2206: n_fregs = save_regs (file, 0, 32, frame_base_name, offset, 0); 2207: if (TARGET_EPILOGUE) 2208: save_regs (file, 32, FIRST_PSEUDO_REGISTER, 2209: frame_base_name, offset, n_fregs); 2210: } 2211: 2212: leaf_label = 0; 2213: if (leaf_function && actual_fsize != 0) 2214: { 2215: /* warning ("leaf procedure with frame size %d", actual_fsize); */ 2216: if (! TARGET_EPILOGUE) 2217: leaf_label = gen_label_rtx (); 2218: } 2219: } 2220: 2221: /* Output code for the function epilogue. */ 2222: 2223: void 2224: output_function_epilogue (file, size, leaf_function) 2225: FILE *file; 2226: int size; 2227: int leaf_function; 2228: { 2229: char *ret; 2230: 2231: if (leaf_label) 2232: { 2233: emit_label_after (leaf_label, get_last_insn ()); 2234: final_scan_insn (get_last_insn (), file, 0, 0, 1); 2235: } 2236: 2237: if (num_fregs) 2238: { 2239: int offset, n_fregs = num_fregs; 2240: 2241: /* ??? This should always be -apparent_fsize. */ 2242: if (! leaf_function) 2243: offset = -apparent_fsize; 2244: else 2245: offset = 0; 2246: 2247: if (TARGET_EPILOGUE && ! leaf_function) 2248: n_fregs = restore_regs (file, 0, 16, frame_base_name, offset, 0); 2249: else if (leaf_function) 2250: n_fregs = restore_regs (file, 0, 32, frame_base_name, offset, 0); 2251: if (TARGET_EPILOGUE) 2252: restore_regs (file, 32, FIRST_PSEUDO_REGISTER, 2253: frame_base_name, offset, n_fregs); 2254: } 2255: 2256: /* Work out how to skip the caller's unimp instruction if required. */ 2257: if (leaf_function) 2258: ret = (current_function_returns_struct ? "jmp %o7+12" : "retl"); 2259: else 2260: ret = (current_function_returns_struct ? "jmp %i7+12" : "ret"); 2261: 2262: if (TARGET_EPILOGUE || leaf_label) 2263: { 2264: int old_target_epilogue = TARGET_EPILOGUE; 2265: target_flags &= ~old_target_epilogue; 2266: 2267: if (! leaf_function) 2268: { 2269: /* If we wound up with things in our delay slot, flush them here. */ 2270: if (current_function_epilogue_delay_list) 2271: { 2272: rtx insn = emit_jump_insn_after (gen_rtx (RETURN, VOIDmode), 2273: get_last_insn ()); 2274: PATTERN (insn) = gen_rtx (PARALLEL, VOIDmode, 2275: gen_rtvec (2, 2276: PATTERN (XEXP (current_function_epilogue_delay_list, 0)), 2277: PATTERN (insn))); 2278: final_scan_insn (insn, file, 1, 0, 1); 2279: } 2280: else 2281: fprintf (file, "\t%s\n\trestore\n", ret); 2282: } 2283: /* All of the following cases are for leaf functions. */ 2284: else if (current_function_epilogue_delay_list) 2285: { 2286: /* eligible_for_epilogue_delay_slot ensures that if this is a 2287: leaf function, then we will only have insn in the delay slot 2288: if the frame size is zero, thus no adjust for the stack is 2289: needed here. */ 2290: if (actual_fsize != 0) 2291: abort (); 2292: fprintf (file, "\t%s\n", ret); 2293: final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), 2294: file, 1, 0, 1); 2295: } 2296: /* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to 2297: avoid generating confusing assembly language output. */ 2298: else if (actual_fsize == 0) 2299: fprintf (file, "\t%s\n\tnop\n", ret); 2300: else if (actual_fsize <= 4096) 2301: fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize); 2302: else if (actual_fsize <= 8192) 2303: fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n", 2304: ret, actual_fsize - 4096); 2305: else if ((actual_fsize & 0x3ff) == 0) 2306: fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", 2307: actual_fsize, ret); 2308: else 2309: fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", 2310: actual_fsize, actual_fsize, ret); 2311: target_flags |= old_target_epilogue; 2312: } 2313: } 2314: 2315: /* Do what is necessary for `va_start'. The argument is ignored; 2316: We look at the current function to determine if stdarg or varargs 2317: is used and return the address of the first unnamed parameter. */ 2318: 2319: rtx 2320: sparc_builtin_saveregs (arglist) 2321: tree arglist; 2322: { 2323: tree fntype = TREE_TYPE (current_function_decl); 2324: int stdarg = (TYPE_ARG_TYPES (fntype) != 0 2325: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 2326: != void_type_node)); 2327: int first_reg = current_function_args_info; 2328: rtx address; 2329: int regno; 2330: 2331: #if 0 /* This code seemed to have no effect except to make 2332: varargs not work right when va_list wasn't the first arg. */ 2333: if (! stdarg) 2334: first_reg = 0; 2335: #endif 2336: 2337: for (regno = first_reg; regno < NPARM_REGS; regno++) 2338: emit_move_insn (gen_rtx (MEM, word_mode, 2339: gen_rtx (PLUS, Pmode, 2340: frame_pointer_rtx, 2341: GEN_INT (STACK_POINTER_OFFSET 2342: + UNITS_PER_WORD * regno))), 2343: gen_rtx (REG, word_mode, BASE_INCOMING_ARG_REG (word_mode) 2344: + regno)); 2345: 2346: address = gen_rtx (PLUS, Pmode, 2347: frame_pointer_rtx, 2348: GEN_INT (STACK_POINTER_OFFSET 2349: + UNITS_PER_WORD * first_reg)); 2350: 2351: return address; 2352: } 2353: 2354: /* Return the string to output a conditional branch to LABEL, which is 2355: the operand number of the label. OP is the conditional expression. The 2356: mode of register 0 says what kind of comparison we made. 2357: 2358: REVERSED is non-zero if we should reverse the sense of the comparison. 2359: 2360: ANNUL is non-zero if we should generate an annulling branch. 2361: 2362: NOOP is non-zero if we have to follow this branch by a noop. */ 2363: 2364: char * 2365: output_cbranch (op, label, reversed, annul, noop) 2366: rtx op; 2367: int label; 2368: int reversed, annul, noop; 2369: { 2370: static char string[20]; 2371: enum rtx_code code = GET_CODE (op); 2372: enum machine_mode mode = GET_MODE (XEXP (op, 0)); 2373: static char labelno[] = " %lX"; 2374: 2375: /* ??? FP branches can not be preceded by another floating point insn. 2376: Because there is currently no concept of pre-delay slots, we can fix 2377: this only by always emitting a nop before a floating point branch. */ 2378: 2379: if (mode == CCFPmode || mode == CCFPEmode) 2380: strcpy (string, "nop\n\t"); 2381: 2382: /* If not floating-point or if EQ or NE, we can just reverse the code. */ 2383: if (reversed 2384: && ((mode != CCFPmode && mode != CCFPEmode) || code == EQ || code == NE)) 2385: code = reverse_condition (code), reversed = 0; 2386: 2387: /* Start by writing the branch condition. */ 2388: switch (code) 2389: { 2390: case NE: 2391: if (mode == CCFPmode || mode == CCFPEmode) 2392: strcat (string, "fbne"); 2393: else 2394: strcpy (string, "bne"); 2395: break; 2396: 2397: case EQ: 2398: if (mode == CCFPmode || mode == CCFPEmode) 2399: strcat (string, "fbe"); 2400: else 2401: strcpy (string, "be"); 2402: break; 2403: 2404: case GE: 2405: if (mode == CCFPmode || mode == CCFPEmode) 2406: { 2407: if (reversed) 2408: strcat (string, "fbul"); 2409: else 2410: strcat (string, "fbge"); 2411: } 2412: else if (mode == CC_NOOVmode) 2413: strcpy (string, "bpos"); 2414: else 2415: strcpy (string, "bge"); 2416: break; 2417: 2418: case GT: 2419: if (mode == CCFPmode || mode == CCFPEmode) 2420: { 2421: if (reversed) 2422: strcat (string, "fbule"); 2423: else 2424: strcat (string, "fbg"); 2425: } 2426: else 2427: strcpy (string, "bg"); 2428: break; 2429: 2430: case LE: 2431: if (mode == CCFPmode || mode == CCFPEmode) 2432: { 2433: if (reversed) 2434: strcat (string, "fbug"); 2435: else 2436: strcat (string, "fble"); 2437: } 2438: else 2439: strcpy (string, "ble"); 2440: break; 2441: 2442: case LT: 2443: if (mode == CCFPmode || mode == CCFPEmode) 2444: { 2445: if (reversed) 2446: strcat (string, "fbuge"); 2447: else 2448: strcat (string, "fbl"); 2449: } 2450: else if (mode == CC_NOOVmode) 2451: strcpy (string, "bneg"); 2452: else 2453: strcpy (string, "bl"); 2454: break; 2455: 2456: case GEU: 2457: strcpy (string, "bgeu"); 2458: break; 2459: 2460: case GTU: 2461: strcpy (string, "bgu"); 2462: break; 2463: 2464: case LEU: 2465: strcpy (string, "bleu"); 2466: break; 2467: 2468: case LTU: 2469: strcpy (string, "blu"); 2470: break; 2471: } 2472: 2473: /* Now add the annulling, the label, and a possible noop. */ 2474: if (annul) 2475: strcat (string, ",a"); 2476: 2477: labelno[3] = label + '0'; 2478: strcat (string, labelno); 2479: 2480: if (noop) 2481: strcat (string, "\n\tnop"); 2482: 2483: return string; 2484: } 2485: 2486: /* Output assembler code to return from a function. */ 2487: 2488: char * 2489: output_return (operands) 2490: rtx *operands; 2491: { 2492: if (leaf_label) 2493: { 2494: operands[0] = leaf_label; 2495: return "b,a %l0"; 2496: } 2497: else if (leaf_function) 2498: { 2499: /* If we didn't allocate a frame pointer for the current function, 2500: the stack pointer might have been adjusted. Output code to 2501: restore it now. */ 2502: 2503: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize); 2504: 2505: /* Use sub of negated value in first two cases instead of add to 2506: allow actual_fsize == 4096. */ 2507: 2508: if (actual_fsize <= 4096) 2509: { 2510: if (current_function_returns_struct) 2511: return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp"; 2512: else 2513: return "retl\n\tsub %%sp,-%0,%%sp"; 2514: } 2515: else if (actual_fsize <= 8192) 2516: { 2517: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096); 2518: if (current_function_returns_struct) 2519: return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp"; 2520: else 2521: return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp"; 2522: } 2523: else if (current_function_returns_struct) 2524: { 2525: if ((actual_fsize & 0x3ff) != 0) 2526: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; 2527: else 2528: return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; 2529: } 2530: else 2531: { 2532: if ((actual_fsize & 0x3ff) != 0) 2533: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; 2534: else 2535: return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; 2536: } 2537: } 2538: else 2539: { 2540: if (current_function_returns_struct) 2541: return "jmp %%i7+12\n\trestore"; 2542: else 2543: return "ret\n\trestore"; 2544: } 2545: } 2546: 2547: /* Leaf functions and non-leaf functions have different needs. */ 2548: 2549: static int 2550: reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER; 2551: 2552: static int 2553: reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER; 2554: 2555: static int *reg_alloc_orders[] = { 2556: reg_leaf_alloc_order, 2557: reg_nonleaf_alloc_order}; 2558: 2559: void 2560: order_regs_for_local_alloc () 2561: { 2562: static int last_order_nonleaf = 1; 2563: 2564: if (regs_ever_live[15] != last_order_nonleaf) 2565: { 2566: last_order_nonleaf = !last_order_nonleaf; 2567: bcopy (reg_alloc_orders[last_order_nonleaf], reg_alloc_order, 2568: FIRST_PSEUDO_REGISTER * sizeof (int)); 2569: } 2570: } 2571: 2572: /* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1. 2573: This makes them candidates for using ldd and std insns. 2574: 2575: Note reg1 and reg2 *must* be hard registers. To be sure we will 2576: abort if we are passed pseudo registers. */ 2577: 2578: int 2579: registers_ok_for_ldd_peep (reg1, reg2) 2580: rtx reg1, reg2; 2581: { 2582: 2583: /* We might have been passed a SUBREG. */ 2584: if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) 2585: return 0; 2586: 2587: if (REGNO (reg1) % 2 != 0) 2588: return 0; 2589: 2590: return (REGNO (reg1) == REGNO (reg2) - 1); 2591: 2592: } 2593: 2594: /* Return 1 if addr1 and addr2 are suitable for use in an ldd or 2595: std insn. 2596: 2597: This can only happen when addr1 and addr2 are consecutive memory 2598: locations (addr1 + 4 == addr2). addr1 must also be aligned on a 2599: 64 bit boundary (addr1 % 8 == 0). 2600: 2601: We know %sp and %fp are kept aligned on a 64 bit boundary. Other 2602: registers are assumed to *never* be properly aligned and are 2603: rejected. 2604: 2605: Knowing %sp and %fp are kept aligned on a 64 bit boundary, we 2606: need only check that the offset for addr1 % 8 == 0. */ 2607: 2608: int 2609: addrs_ok_for_ldd_peep (addr1, addr2) 2610: rtx addr1, addr2; 2611: { 2612: int reg1, offset1; 2613: 2614: /* Extract a register number and offset (if used) from the first addr. */ 2615: if (GET_CODE (addr1) == PLUS) 2616: { 2617: /* If not a REG, return zero. */ 2618: if (GET_CODE (XEXP (addr1, 0)) != REG) 2619: return 0; 2620: else 2621: { 2622: reg1 = REGNO (XEXP (addr1, 0)); 2623: /* The offset must be constant! */ 2624: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) 2625: return 0; 2626: offset1 = INTVAL (XEXP (addr1, 1)); 2627: } 2628: } 2629: else if (GET_CODE (addr1) != REG) 2630: return 0; 2631: else 2632: { 2633: reg1 = REGNO (addr1); 2634: /* This was a simple (mem (reg)) expression. Offset is 0. */ 2635: offset1 = 0; 2636: } 2637: 2638: /* Make sure the second address is a (mem (plus (reg) (const_int). */ 2639: if (GET_CODE (addr2) != PLUS) 2640: return 0; 2641: 2642: if (GET_CODE (XEXP (addr2, 0)) != REG 2643: || GET_CODE (XEXP (addr2, 1)) != CONST_INT) 2644: return 0; 2645: 2646: /* Only %fp and %sp are allowed. Additionally both addresses must 2647: use the same register. */ 2648: if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM) 2649: return 0; 2650: 2651: if (reg1 != REGNO (XEXP (addr2, 0))) 2652: return 0; 2653: 2654: /* The first offset must be evenly divisible by 8 to ensure the 2655: address is 64 bit aligned. */ 2656: if (offset1 % 8 != 0) 2657: return 0; 2658: 2659: /* The offset for the second addr must be 4 more than the first addr. */ 2660: if (INTVAL (XEXP (addr2, 1)) != offset1 + 4) 2661: return 0; 2662: 2663: /* All the tests passed. addr1 and addr2 are valid for ldd and std 2664: instructions. */ 2665: return 1; 2666: } 2667: 2668: /* Return 1 if reg is a pseudo, or is the first register in 2669: a hard register pair. This makes it a candidate for use in 2670: ldd and std insns. */ 2671: 2672: int 2673: register_ok_for_ldd (reg) 2674: rtx reg; 2675: { 2676: 2677: /* We might have been passed a SUBREG. */ 2678: if (GET_CODE (reg) != REG) 2679: return 0; 2680: 2681: if (REGNO (reg) < FIRST_PSEUDO_REGISTER) 2682: return (REGNO (reg) % 2 == 0); 2683: else 2684: return 1; 2685: 2686: } 2687: 2688: /* Print operand X (an rtx) in assembler syntax to file FILE. 2689: CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. 2690: For `%' followed by punctuation, CODE is the punctuation and X is null. */ 2691: 2692: void 2693: print_operand (file, x, code) 2694: FILE *file; 2695: rtx x; 2696: int code; 2697: { 2698: switch (code) 2699: { 2700: case '#': 2701: /* Output a 'nop' if there's nothing for the delay slot. */ 2702: if (dbr_sequence_length () == 0) 2703: fputs ("\n\tnop", file); 2704: return; 2705: case '*': 2706: /* Output an annul flag if there's nothing for the delay slot and we 2707: are optimizing. This is always used with '(' below. */ 2708: /* Sun OS 4.1.1 dbx can't handle an annulled unconditional branch; 2709: this is a dbx bug. So, we only do this when optimizing. */ 2710: if (dbr_sequence_length () == 0 && optimize) 2711: fputs (",a", file); 2712: return; 2713: case '(': 2714: /* Output a 'nop' if there's nothing for the delay slot and we are 2715: not optimizing. This is always used with '*' above. */ 2716: if (dbr_sequence_length () == 0 && ! optimize) 2717: fputs ("\n\tnop", file); 2718: return; 2719: case 'Y': 2720: /* Adjust the operand to take into account a RESTORE operation. */ 2721: if (GET_CODE (x) != REG) 2722: output_operand_lossage ("Invalid %%Y operand"); 2723: else if (REGNO (x) < 8) 2724: fputs (reg_names[REGNO (x)], file); 2725: else if (REGNO (x) >= 24 && REGNO (x) < 32) 2726: fputs (reg_names[REGNO (x)-16], file); 2727: else 2728: output_operand_lossage ("Invalid %%Y operand"); 2729: return; 2730: case 'R': 2731: /* Print out the second register name of a register pair or quad. 2732: I.e., R (%o0) => %o1. */ 2733: fputs (reg_names[REGNO (x)+1], file); 2734: return; 2735: case 'S': 2736: /* Print out the third register name of a register quad. 2737: I.e., S (%o0) => %o2. */ 2738: fputs (reg_names[REGNO (x)+2], file); 2739: return; 2740: case 'T': 2741: /* Print out the fourth register name of a register quad. 2742: I.e., T (%o0) => %o3. */ 2743: fputs (reg_names[REGNO (x)+3], file); 2744: return; 2745: case 'm': 2746: /* Print the operand's address only. */ 2747: output_address (XEXP (x, 0)); 2748: return; 2749: case 'r': 2750: /* In this case we need a register. Use %g0 if the 2751: operand is const0_rtx. */ 2752: if (x == const0_rtx 2753: || (GET_MODE (x) != VOIDmode && x == CONST0_RTX (GET_MODE (x)))) 2754: { 2755: fputs ("%g0", file); 2756: return; 2757: } 2758: else 2759: break; 2760: 2761: case 'A': 2762: switch (GET_CODE (x)) 2763: { 2764: case IOR: fputs ("or", file); break; 2765: case AND: fputs ("and", file); break; 2766: case XOR: fputs ("xor", file); break; 2767: default: output_operand_lossage ("Invalid %%A operand"); 2768: } 2769: return; 2770: 2771: case 'B': 2772: switch (GET_CODE (x)) 2773: { 2774: case IOR: fputs ("orn", file); break; 2775: case AND: fputs ("andn", file); break; 2776: case XOR: fputs ("xnor", file); break; 2777: default: output_operand_lossage ("Invalid %%B operand"); 2778: } 2779: return; 2780: 2781: case 'b': 2782: { 2783: /* Print a sign-extended character. */ 2784: int i = INTVAL (x) & 0xff; 2785: if (i & 0x80) 2786: i |= 0xffffff00; 2787: fprintf (file, "%d", i); 2788: return; 2789: } 2790: 2791: case 0: 2792: /* Do nothing special. */ 2793: break; 2794: 2795: default: 2796: /* Undocumented flag. */ 2797: output_operand_lossage ("invalid operand output code"); 2798: } 2799: 2800: if (GET_CODE (x) == REG) 2801: fputs (reg_names[REGNO (x)], file); 2802: else if (GET_CODE (x) == MEM) 2803: { 2804: fputc ('[', file); 2805: if (CONSTANT_P (XEXP (x, 0))) 2806: /* Poor Sun assembler doesn't understand absolute addressing. */ 2807: fputs ("%g0+", file); 2808: output_address (XEXP (x, 0)); 2809: fputc (']', file); 2810: } 2811: else if (GET_CODE (x) == HIGH) 2812: { 2813: fputs ("%hi(", file); 2814: output_addr_const (file, XEXP (x, 0)); 2815: fputc (')', file); 2816: } 2817: else if (GET_CODE (x) == LO_SUM) 2818: { 2819: print_operand (file, XEXP (x, 0), 0); 2820: fputs ("+%lo(", file); 2821: output_addr_const (file, XEXP (x, 1)); 2822: fputc (')', file); 2823: } 2824: else if (GET_CODE (x) == CONST_DOUBLE 2825: && (GET_MODE (x) == VOIDmode 2826: || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)) 2827: { 2828: if (CONST_DOUBLE_HIGH (x) == 0) 2829: fprintf (file, "%u", CONST_DOUBLE_LOW (x)); 2830: else if (CONST_DOUBLE_HIGH (x) == -1 2831: && CONST_DOUBLE_LOW (x) < 0) 2832: fprintf (file, "%d", CONST_DOUBLE_LOW (x)); 2833: else 2834: output_operand_lossage ("long long constant not a valid immediate operand"); 2835: } 2836: else if (GET_CODE (x) == CONST_DOUBLE) 2837: output_operand_lossage ("floating point constant not a valid immediate operand"); 2838: else { output_addr_const (file, x); } 2839: } 2840: 2841: /* This function outputs assembler code for VALUE to FILE, where VALUE is 2842: a 64 bit (DImode) value. */ 2843: 2844: /* ??? If there is a 64 bit counterpart to .word that the assembler 2845: understands, then using that would simply this code greatly. */ 2846: 2847: void 2848: output_double_int (file, value) 2849: FILE *file; 2850: rtx value; 2851: { 2852: if (GET_CODE (value) == CONST_INT) 2853: { 2854: if (INTVAL (value) < 0) 2855: ASM_OUTPUT_INT (file, constm1_rtx); 2856: else 2857: ASM_OUTPUT_INT (file, const0_rtx); 2858: ASM_OUTPUT_INT (file, value); 2859: } 2860: else if (GET_CODE (value) == CONST_DOUBLE) 2861: { 2862: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, 2863: CONST_DOUBLE_HIGH (value))); 2864: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, 2865: CONST_DOUBLE_LOW (value))); 2866: } 2867: else if (GET_CODE (value) == SYMBOL_REF 2868: || GET_CODE (value) == CONST 2869: || GET_CODE (value) == PLUS) 2870: { 2871: /* Addresses are only 32 bits. */ 2872: ASM_OUTPUT_INT (file, const0_rtx); 2873: ASM_OUTPUT_INT (file, value); 2874: } 2875: else 2876: abort (); 2877: } 2878: 2879: #ifndef CHAR_TYPE_SIZE 2880: #define CHAR_TYPE_SIZE BITS_PER_UNIT 2881: #endif 2882: 2883: #ifndef SHORT_TYPE_SIZE 2884: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2) 2885: #endif 2886: 2887: #ifndef INT_TYPE_SIZE 2888: #define INT_TYPE_SIZE BITS_PER_WORD 2889: #endif 2890: 2891: #ifndef LONG_TYPE_SIZE 2892: #define LONG_TYPE_SIZE BITS_PER_WORD 2893: #endif 2894: 2895: #ifndef LONG_LONG_TYPE_SIZE 2896: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) 2897: #endif 2898: 2899: #ifndef FLOAT_TYPE_SIZE 2900: #define FLOAT_TYPE_SIZE BITS_PER_WORD 2901: #endif 2902: 2903: #ifndef DOUBLE_TYPE_SIZE 2904: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 2905: #endif 2906: 2907: #ifndef LONG_DOUBLE_TYPE_SIZE 2908: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 2909: #endif 2910: 2911: unsigned long 2912: sparc_type_code (type) 2913: register tree type; 2914: { 2915: register unsigned long qualifiers = 0; 2916: register unsigned shift = 6; 2917: 2918: for (;;) 2919: { 2920: switch (TREE_CODE (type)) 2921: { 2922: case ERROR_MARK: 2923: return qualifiers; 2924: 2925: case ARRAY_TYPE: 2926: qualifiers |= (3 << shift); 2927: shift += 2; 2928: type = TREE_TYPE (type); 2929: break; 2930: 2931: case FUNCTION_TYPE: 2932: case METHOD_TYPE: 2933: qualifiers |= (2 << shift); 2934: shift += 2; 2935: type = TREE_TYPE (type); 2936: break; 2937: 2938: case POINTER_TYPE: 2939: case REFERENCE_TYPE: 2940: case OFFSET_TYPE: 2941: qualifiers |= (1 << shift); 2942: shift += 2; 2943: type = TREE_TYPE (type); 2944: break; 2945: 2946: case RECORD_TYPE: 2947: return (qualifiers | 8); 2948: 2949: case UNION_TYPE: 2950: return (qualifiers | 9); 2951: 2952: case ENUMERAL_TYPE: 2953: return (qualifiers | 10); 2954: 2955: case VOID_TYPE: 2956: return (qualifiers | 16); 2957: 2958: case INTEGER_TYPE: 1.1.1.2 ! root 2959: /* If this is a range type, consider it to be the underlying ! 2960: type. */ ! 2961: if (TREE_TYPE (type) != 0) ! 2962: { ! 2963: type = TREE_TYPE (type); ! 2964: break; ! 2965: } ! 2966: 1.1 root 2967: /* Carefully distinguish all the standard types of C, 2968: without messing up if the language is not C. 2969: Note that we check only for the names that contain spaces; 2970: other names might occur by coincidence in other languages. */ 2971: if (TYPE_NAME (type) != 0 2972: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 2973: && DECL_NAME (TYPE_NAME (type)) != 0 2974: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) 2975: { 2976: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 2977: 2978: if (!strcmp (name, "unsigned char")) 2979: return (qualifiers | 12); 2980: if (!strcmp (name, "signed char")) 2981: return (qualifiers | 2); 2982: if (!strcmp (name, "unsigned int")) 2983: return (qualifiers | 14); 2984: if (!strcmp (name, "short int")) 2985: return (qualifiers | 3); 2986: if (!strcmp (name, "short unsigned int")) 2987: return (qualifiers | 13); 2988: if (!strcmp (name, "long int")) 2989: return (qualifiers | 5); 2990: if (!strcmp (name, "long unsigned int")) 2991: return (qualifiers | 15); 2992: if (!strcmp (name, "long long int")) 2993: return (qualifiers | 5); /* Who knows? */ 2994: if (!strcmp (name, "long long unsigned int")) 2995: return (qualifiers | 15); /* Who knows? */ 2996: } 2997: 2998: /* Most integer types will be sorted out above, however, for the 2999: sake of special `array index' integer types, the following code 3000: is also provided. */ 3001: 3002: if (TYPE_PRECISION (type) == INT_TYPE_SIZE) 3003: return (qualifiers | (TREE_UNSIGNED (type) ? 14 : 4)); 3004: 3005: if (TYPE_PRECISION (type) == LONG_TYPE_SIZE) 3006: return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5)); 3007: 3008: if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE) 3009: return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5)); 3010: 3011: if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE) 3012: return (qualifiers | (TREE_UNSIGNED (type) ? 13 : 3)); 3013: 3014: if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE) 3015: return (qualifiers | (TREE_UNSIGNED (type) ? 12 : 2)); 3016: 3017: abort (); 3018: 3019: case REAL_TYPE: 3020: /* Carefully distinguish all the standard types of C, 3021: without messing up if the language is not C. */ 3022: if (TYPE_NAME (type) != 0 3023: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 3024: && DECL_NAME (TYPE_NAME (type)) != 0 3025: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) 3026: { 3027: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); 3028: 3029: if (!strcmp (name, "long double")) 3030: return (qualifiers | 7); /* Who knows? */ 3031: } 3032: 3033: if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE) 3034: return (qualifiers | 7); 3035: if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE) 3036: return (qualifiers | 6); 3037: if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE) 3038: return (qualifiers | 7); /* Who knows? */ 3039: abort (); 3040: 3041: case COMPLEX_TYPE: /* GNU Fortran COMPLEX type. */ 3042: /* ??? We need to distinguish between double and float complex types, 3043: but I don't know how yet because I can't reach this code from 3044: existing front-ends. */ 3045: return (qualifiers | 7); /* Who knows? */ 3046: 3047: case CHAR_TYPE: /* GNU Pascal CHAR type. Not used in C. */ 3048: case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */ 3049: case FILE_TYPE: /* GNU Pascal FILE type. */ 1.1.1.2 ! root 3050: case STRING_TYPE: /* GNU Fortran STRING type. */ ! 3051: case SET_TYPE: /* GNU Pascal SET type. */ 1.1 root 3052: case LANG_TYPE: /* ? */ 1.1.1.2 ! root 3053: return qualifiers; 1.1 root 3054: 3055: default: 3056: abort (); /* Not a type! */ 3057: } 3058: } 3059: } 3060: 3061: /* Subroutines to support a flat (single) register window calling 3062: convention. */ 3063: 3064: /* Single-register window sparc stack frames look like: 3065: 3066: Before call After call 3067: +-----------------------+ +-----------------------+ 3068: high | | | | 3069: mem. | | | | 3070: | caller's temps. | | caller's temps. | 3071: | | | | 3072: +-----------------------+ +-----------------------+ 3073: | | | | 3074: | arguments on stack. | | arguments on stack. | 3075: | |FP+92->| | 3076: +-----------------------+ +-----------------------+ 3077: | 6 words to save | | 6 words to save | 3078: | arguments passed | | arguments passed | 3079: | in registers, even | | in registers, even | 3080: SP+68->| if not passed. |FP+68->| if not passed. | 3081: +-----------------------+ +-----------------------+ 3082: | 1 word struct addr |FP+64->| 1 word struct addr | 3083: +-----------------------+ +-----------------------+ 3084: | | | | 3085: | 16 word reg save area | | 16 word reg save area | 3086: SP->| | FP->| | 3087: +-----------------------+ +-----------------------+ 3088: | 4 word area for | 3089: FP-16->| fp/alu reg moves | 3090: +-----------------------+ 3091: | | 3092: | local variables | 3093: | | 3094: +-----------------------+ 3095: | | 3096: | fp register save | 3097: | | 3098: +-----------------------+ 3099: | | 3100: | gp register save | 3101: | | 3102: +-----------------------+ 3103: | | 3104: | alloca allocations | 3105: | | 3106: +-----------------------+ 3107: | | 3108: | arguments on stack | 3109: SP+92->| | 3110: +-----------------------+ 3111: | 6 words to save | 3112: | arguments passed | 3113: | in registers, even | 3114: low SP+68->| if not passed. | 3115: memory +-----------------------+ 3116: SP+64->| 1 word struct addr | 3117: +-----------------------+ 3118: | | 3119: I 16 word reg save area | 3120: SP->| | 3121: +-----------------------+ */ 3122: 3123: /* Structure to be filled in by sparc_frw_compute_frame_size with register 3124: save masks, and offsets for the current function. */ 3125: 3126: struct sparc_frame_info 3127: { 3128: unsigned long total_size; /* # bytes that the entire frame takes up. */ 3129: unsigned long var_size; /* # bytes that variables take up. */ 3130: unsigned long args_size; /* # bytes that outgoing arguments take up. */ 3131: unsigned long extra_size; /* # bytes of extra gunk. */ 3132: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ 3133: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ 3134: unsigned long mask; /* Mask of saved gp registers. */ 3135: unsigned long fmask; /* Mask of saved fp registers. */ 3136: unsigned long gp_sp_offset; /* Offset from new sp to store gp regs. */ 3137: unsigned long fp_sp_offset; /* Offset from new sp to store fp regs. */ 3138: int initialized; /* Nonzero if frame size already calculated. */ 3139: }; 3140: 3141: /* Current frame information calculated by sparc_frw_compute_frame_size. */ 3142: struct sparc_frame_info current_frame_info; 3143: 3144: /* Zero structure to initialize current_frame_info. */ 3145: struct sparc_frame_info zero_frame_info; 3146: 3147: /* Tell prologue and epilogue if register REGNO should be saved / restored. */ 3148: 3149: #define MUST_SAVE_REGISTER(regno) \ 3150: ((regs_ever_live[regno] && !call_used_regs[regno]) \ 3151: || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \ 3152: || (regno == 15 && regs_ever_live[15])) 3153: 3154: /* Return the bytes needed to compute the frame pointer from the current 3155: stack pointer. */ 3156: 3157: unsigned long 3158: sparc_frw_compute_frame_size (size) 3159: int size; /* # of var. bytes allocated. */ 3160: { 3161: int regno; 3162: unsigned long total_size; /* # bytes that the entire frame takes up. */ 3163: unsigned long var_size; /* # bytes that variables take up. */ 3164: unsigned long args_size; /* # bytes that outgoing arguments take up. */ 3165: unsigned long extra_size; /* # extra bytes. */ 3166: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ 3167: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ 3168: unsigned long mask; /* Mask of saved gp registers. */ 3169: unsigned long fmask; /* Mask of saved fp registers. */ 3170: 3171: /* This is the size of the 16 word reg save area, 1 word struct addr 3172: area, and 4 word fp/alu register copy area. */ 3173: extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0); 3174: var_size = size; 3175: /* Also include the size needed for the 6 parameter registers. */ 3176: args_size = current_function_outgoing_args_size + 24; 3177: total_size = var_size + args_size + extra_size; 3178: gp_reg_size = 0; 3179: fp_reg_size = 0; 3180: mask = 0; 3181: fmask = 0; 3182: 3183: /* Calculate space needed for gp registers. */ 3184: for (regno = 1; regno <= 31; regno++) 3185: { 3186: if (MUST_SAVE_REGISTER (regno)) 3187: { 3188: if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1)) 3189: { 3190: if (gp_reg_size % 8 != 0) 3191: gp_reg_size += UNITS_PER_WORD; 3192: gp_reg_size += 2 * UNITS_PER_WORD; 3193: mask |= 3 << regno; 3194: regno++; 3195: } 3196: else 3197: { 3198: gp_reg_size += UNITS_PER_WORD; 3199: mask |= 1 << regno; 3200: } 3201: } 3202: } 3203: /* Add extra word in case we have to align the space to a double word 3204: boundary. */ 3205: if (gp_reg_size != 0) 3206: gp_reg_size += UNITS_PER_WORD; 3207: 3208: /* Calculate space needed for fp registers. */ 3209: for (regno = 32; regno <= 63; regno++) 3210: { 3211: if (regs_ever_live[regno] && !call_used_regs[regno]) 3212: { 3213: fp_reg_size += UNITS_PER_WORD; 3214: fmask |= 1 << (regno - 32); 3215: } 3216: } 3217: 3218: total_size += gp_reg_size + fp_reg_size; 3219: 3220: if (total_size == extra_size) 3221: total_size = extra_size = 0; 3222: 3223: total_size = SPARC_STACK_ALIGN (total_size); 3224: 3225: /* Save other computed information. */ 3226: current_frame_info.total_size = total_size; 3227: current_frame_info.var_size = var_size; 3228: current_frame_info.args_size = args_size; 3229: current_frame_info.extra_size = extra_size; 3230: current_frame_info.gp_reg_size = gp_reg_size; 3231: current_frame_info.fp_reg_size = fp_reg_size; 3232: current_frame_info.mask = mask; 3233: current_frame_info.fmask = fmask; 3234: current_frame_info.initialized = reload_completed; 3235: 3236: if (mask) 3237: { 3238: unsigned long offset = args_size; 3239: if (extra_size) 3240: offset += FIRST_PARM_OFFSET(0); 3241: current_frame_info.gp_sp_offset = offset; 3242: } 3243: 3244: if (fmask) 3245: { 3246: unsigned long offset = args_size + gp_reg_size; 3247: if (extra_size) 3248: offset += FIRST_PARM_OFFSET(0); 3249: current_frame_info.fp_sp_offset = offset; 3250: } 3251: 3252: /* Ok, we're done. */ 3253: return total_size; 3254: } 3255: 3256: /* Common code to save/restore registers. */ 3257: 3258: void 3259: sparc_frw_save_restore (file, word_op, doubleword_op) 3260: FILE *file; /* Stream to write to. */ 3261: char *word_op; /* Operation to do for one word. */ 3262: char *doubleword_op; /* Operation to do for doubleword. */ 3263: { 3264: int regno; 3265: unsigned long mask = current_frame_info.mask; 3266: unsigned long fmask = current_frame_info.fmask; 3267: unsigned long gp_offset; 3268: unsigned long fp_offset; 3269: unsigned long max_offset; 3270: char *base_reg; 3271: 3272: if (mask == 0 && fmask == 0) 3273: return; 3274: 3275: base_reg = reg_names[STACK_POINTER_REGNUM]; 3276: gp_offset = current_frame_info.gp_sp_offset; 3277: fp_offset = current_frame_info.fp_sp_offset; 3278: max_offset = (gp_offset > fp_offset) ? gp_offset : fp_offset; 3279: 3280: /* Deal with calling functions with a large structure. */ 3281: if (max_offset >= 4096) 3282: { 3283: char *temp = "%g2"; 3284: fprintf (file, "\tset %ld,%s\n", max_offset, temp); 3285: fprintf (file, "\tadd %s,%s,%s\n", temp, base_reg, temp); 3286: base_reg = temp; 3287: gp_offset = max_offset - gp_offset; 3288: fp_offset = max_offset - fp_offset; 3289: } 3290: 3291: /* Save registers starting from high to low. The debuggers prefer 3292: at least the return register be stored at func+4, and also it 3293: allows us not to need a nop in the epilog if at least one 3294: register is reloaded in addition to return address. */ 3295: 3296: if (mask || frame_pointer_needed) 3297: { 3298: for (regno = 1; regno <= 31; regno++) 3299: { 3300: if ((mask & (1L << regno)) != 0 3301: || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) 3302: { 1.1.1.2 ! root 3303: if ((regno & 0x1) == 0 && ((mask & (1L << (regno+1))) != 0)) 1.1 root 3304: { 3305: if (gp_offset % 8 != 0) 3306: gp_offset += UNITS_PER_WORD; 3307: 3308: if (word_op[0] == 's') 3309: fprintf (file, "\t%s %s,[%s+%d]\n", 3310: doubleword_op, reg_names[regno], 3311: base_reg, gp_offset); 3312: else 3313: fprintf (file, "\t%s [%s+%d],%s\n", 3314: doubleword_op, base_reg, gp_offset, 3315: reg_names[regno]); 3316: 3317: gp_offset += 2 * UNITS_PER_WORD; 3318: regno++; 3319: } 3320: else 3321: { 3322: if (word_op[0] == 's') 3323: fprintf (file, "\t%s %s,[%s+%d]\n", 3324: word_op, reg_names[regno], 3325: base_reg, gp_offset); 3326: else 3327: fprintf (file, "\t%s [%s+%d],%s\n", 3328: word_op, base_reg, gp_offset, reg_names[regno]); 3329: 3330: gp_offset += UNITS_PER_WORD; 3331: } 3332: } 3333: } 3334: } 3335: 3336: if (fmask) 3337: { 3338: for (regno = 32; regno <= 63; regno++) 3339: { 3340: if ((fmask & (1L << (regno - 32))) != 0) 3341: { 3342: if (word_op[0] == 's') 3343: fprintf (file, "\t%s %s,[%s+%d]\n", 3344: word_op, reg_names[regno], 3345: base_reg, gp_offset); 3346: else 3347: fprintf (file, "\t%s [%s+%d],%s\n", 3348: word_op, base_reg, gp_offset, reg_names[regno]); 3349: 3350: fp_offset += UNITS_PER_WORD; 3351: } 3352: } 3353: } 3354: } 3355: 3356: /* Set up the stack and frame (if desired) for the function. */ 3357: 3358: void 3359: sparc_frw_output_function_prologue (file, size, ignored) 3360: FILE *file; 3361: int size; 3362: { 3363: extern char call_used_regs[]; 3364: int tsize; 3365: char *sp_str = reg_names[STACK_POINTER_REGNUM]; 3366: 3367: /* ??? This should be %sp+actual_fsize for a leaf function. I think it 3368: works only because it is never used. */ 3369: frame_base_name 3370: = (!frame_pointer_needed) ? "%sp+80" : reg_names[FRAME_POINTER_REGNUM]; 3371: 3372: fprintf (file, "\t!#PROLOGUE# 0\n"); 3373: 3374: size = SPARC_STACK_ALIGN (size); 3375: tsize = (! current_frame_info.initialized 3376: ? sparc_frw_compute_frame_size (size) 3377: : current_frame_info.total_size); 3378: 3379: if (tsize > 0) 3380: { 3381: if (tsize <= 4095) 3382: fprintf (file, 3383: "\tsub %s,%d,%s\t\t!# vars= %d, regs= %d/%d, args = %d, extra= %d\n", 3384: sp_str, tsize, sp_str, current_frame_info.var_size, 3385: current_frame_info.gp_reg_size / 4, 3386: current_frame_info.fp_reg_size / 8, 3387: current_function_outgoing_args_size, 3388: current_frame_info.extra_size); 3389: else 3390: fprintf (file, 3391: "\tset %d,%s\n\tsub\t%s,%s,%s\t\t!# vars= %d, regs= %d/%d, args = %d, sfo= %d\n", 3392: tsize, "%g1", sp_str, "%g1", 3393: sp_str, current_frame_info.var_size, 3394: current_frame_info.gp_reg_size / 4, 3395: current_frame_info.fp_reg_size / 8, 3396: current_function_outgoing_args_size, 3397: current_frame_info.extra_size); 3398: } 3399: 3400: sparc_frw_save_restore (file, "st", "std"); 3401: 3402: if (frame_pointer_needed) 3403: { 3404: if (tsize <= 4095) 3405: fprintf (file, "\tadd %s,%d,%s\t!# set up frame pointer\n", sp_str, 3406: tsize, frame_base_name); 3407: else 3408: fprintf (file, "\tadd %s,%s,%s\t!# set up frame pointer\n", sp_str, 3409: "%g1", frame_base_name); 3410: } 3411: } 3412: 3413: /* Do any necessary cleanup after a function to restore stack, frame, 3414: and regs. */ 3415: 3416: void 3417: sparc_frw_output_function_epilogue (file, size, ignored1, ignored2) 3418: FILE *file; 3419: int size; 3420: { 3421: extern FILE *asm_out_data_file, *asm_out_file; 3422: extern char call_used_regs[]; 3423: extern int frame_pointer_needed; 3424: int tsize; 3425: char *sp_str = reg_names[STACK_POINTER_REGNUM]; 3426: char *t1_str = "%g1"; 3427: rtx epilogue_delay = current_function_epilogue_delay_list; 3428: int noepilogue = FALSE; 3429: 3430: /* The epilogue does not depend on any registers, but the stack 3431: registers, so we assume that if we have 1 pending nop, it can be 3432: ignored, and 2 it must be filled (2 nops occur for integer 3433: multiply and divide). */ 3434: 3435: size = SPARC_STACK_ALIGN (size); 3436: tsize = (!current_frame_info.initialized 3437: ? sparc_frw_compute_frame_size (size) 3438: : current_frame_info.total_size); 3439: 3440: if (tsize == 0 && epilogue_delay == 0) 3441: { 3442: rtx insn = get_last_insn (); 3443: 3444: /* If the last insn was a BARRIER, we don't have to write any code 3445: because a jump (aka return) was put there. */ 3446: if (GET_CODE (insn) == NOTE) 3447: insn = prev_nonnote_insn (insn); 3448: if (insn && GET_CODE (insn) == BARRIER) 3449: noepilogue = TRUE; 3450: } 3451: 3452: if (!noepilogue) 3453: { 3454: /* In the reload sequence, we don't need to fill the load delay 3455: slots for most of the loads, also see if we can fill the final 3456: delay slot if not otherwise filled by the reload sequence. */ 3457: 3458: if (tsize > 4095) 3459: fprintf (file, "\tset %d,%s\n", tsize, t1_str); 3460: 3461: if (frame_pointer_needed) 3462: { 3463: char *fp_str = reg_names[FRAME_POINTER_REGNUM]; 3464: if (tsize > 4095) 3465: fprintf (file,"\tsub %s,%s,%s\t\t!# sp not trusted here\n", 3466: fp_str, t1_str, sp_str); 3467: else 3468: fprintf (file,"\tsub %s,%d,%s\t\t!# sp not trusted here\n", 3469: fp_str, tsize, sp_str); 3470: } 3471: 3472: sparc_frw_save_restore (file, "ld", "ldd"); 3473: 3474: if (current_function_returns_struct) 3475: fprintf (file, "\tjmp %%o7+12\n"); 3476: else 3477: fprintf (file, "\tretl\n"); 3478: 3479: /* If the only register saved is the return address, we need a 3480: nop, unless we have an instruction to put into it. Otherwise 3481: we don't since reloading multiple registers doesn't reference 3482: the register being loaded. */ 3483: 3484: if (epilogue_delay) 3485: { 3486: if (tsize) 3487: abort (); 3488: final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1); 3489: } 3490: 3491: else if (tsize > 4095) 3492: fprintf (file, "\tadd %s,%s,%s\n", sp_str, t1_str, sp_str); 3493: 3494: else if (tsize > 0) 3495: fprintf (file, "\tadd %s,%d,%s\n", sp_str, tsize, sp_str); 3496: 3497: else 3498: fprintf (file, "\tnop\n"); 3499: } 3500: 3501: /* Reset state info for each function. */ 3502: current_frame_info = zero_frame_info; 3503: } 3504: 3505: /* Define the number of delay slots needed for the function epilogue. 3506: 3507: On the sparc, we need a slot if either no stack has been allocated, 3508: or the only register saved is the return register. */ 3509: 3510: int 3511: sparc_frw_epilogue_delay_slots () 3512: { 3513: if (!current_frame_info.initialized) 3514: (void) sparc_frw_compute_frame_size (get_frame_size ()); 3515: 3516: if (current_frame_info.total_size == 0) 3517: return 1; 3518: 3519: return 0; 3520: } 3521: 3522: /* Return true is TRIAL is a valid insn for the epilogue delay slot. 3523: Any single length instruction which doesn't reference the stack or frame 3524: pointer is OK. */ 3525: 3526: int 3527: sparc_frw_eligible_for_epilogue_delay (trial, slot) 3528: rtx trial; 3529: int slot; 3530: { 3531: if (get_attr_length (trial) == 1 3532: && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial)) 3533: && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial))) 3534: return 1; 3535: return 0; 3536: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.