|
|
1.1 root 1: /* Subroutines for insn-output.c for Sun SPARC. 1.1.1.4 ! root 2: Copyright (C) 1987, 88, 89, 92, 93, 94, 1995 Free Software Foundation, Inc. 1.1 root 3: Contributed by Michael Tiemann ([email protected]) 1.1.1.3 root 4: 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans, 5: at Cygnus Support. 1.1 root 6: 7: This file is part of GNU CC. 8: 9: GNU CC is free software; you can redistribute it and/or modify 10: it under the terms of the GNU General Public License as published by 11: the Free Software Foundation; either version 2, or (at your option) 12: any later version. 13: 14: GNU CC is distributed in the hope that it will be useful, 15: but WITHOUT ANY WARRANTY; without even the implied warranty of 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17: GNU General Public License for more details. 18: 19: You should have received a copy of the GNU General Public License 20: along with GNU CC; see the file COPYING. If not, write to 1.1.1.4 ! root 21: the Free Software Foundation, 59 Temple Place - Suite 330, ! 22: Boston, MA 02111-1307, USA. */ 1.1 root 23: 24: #include <stdio.h> 25: #include "config.h" 26: #include "tree.h" 27: #include "rtl.h" 28: #include "regs.h" 29: #include "hard-reg-set.h" 30: #include "real.h" 31: #include "insn-config.h" 32: #include "conditions.h" 33: #include "insn-flags.h" 34: #include "output.h" 35: #include "insn-attr.h" 36: #include "flags.h" 37: #include "expr.h" 38: #include "recog.h" 39: 1.1.1.3 root 40: /* 1 if the caller has placed an "unimp" insn immediately after the call. 41: This is used in v8 code when calling a function that returns a structure. 42: v9 doesn't have this. */ 43: 44: #define SKIP_CALLERS_UNIMP_P (!TARGET_V9 && current_function_returns_struct) 45: 1.1 root 46: /* Global variables for machine-dependent things. */ 47: 1.1.1.3 root 48: /* Says what architecture we're compiling for. */ 49: enum arch_type sparc_arch_type; 50: 51: /* Size of frame. Need to know this to emit return insns from leaf procedures. 52: ACTUAL_FSIZE is set by compute_frame_size() which is called during the 53: reload pass. This is important as the value is later used in insn 54: scheduling (to see what can go in a delay slot). 55: APPARENT_FSIZE is the size of the stack less the register save area and less 56: the outgoing argument area. It is used when saving call preserved regs. */ 57: static int apparent_fsize; 58: static int actual_fsize; 59: 1.1 root 60: /* Save the operands last given to a compare for use when we 61: generate a scc or bcc insn. */ 62: 63: rtx sparc_compare_op0, sparc_compare_op1; 64: 1.1.1.3 root 65: /* Count of named arguments (v9 only). 66: ??? INIT_CUMULATIVE_ARGS initializes these, and FUNCTION_ARG_ADVANCE 67: increments SPARC_ARG_COUNT. They are then used by 68: FUNCTION_ARG_CALLEE_COPIES to determine if the argument is really a named 69: argument or not. This hack is necessary because the NAMED argument to the 70: FUNCTION_ARG_XXX macros is not what it says it is: it does not include the 71: last named argument. */ 72: 73: int sparc_arg_count; 74: int sparc_n_named_args; 75: 1.1 root 76: /* We may need an epilogue if we spill too many registers. 77: If this is non-zero, then we branch here for the epilogue. */ 78: static rtx leaf_label; 79: 80: #ifdef LEAF_REGISTERS 81: 82: /* Vector to say how input registers are mapped to output 83: registers. FRAME_POINTER_REGNUM cannot be remapped by 84: this function to eliminate it. You must use -fomit-frame-pointer 85: to get that. */ 86: char leaf_reg_remap[] = 87: { 0, 1, 2, 3, 4, 5, 6, 7, 88: -1, -1, -1, -1, -1, -1, 14, -1, 89: -1, -1, -1, -1, -1, -1, -1, -1, 90: 8, 9, 10, 11, 12, 13, -1, 15, 91: 92: 32, 33, 34, 35, 36, 37, 38, 39, 93: 40, 41, 42, 43, 44, 45, 46, 47, 94: 48, 49, 50, 51, 52, 53, 54, 55, 1.1.1.3 root 95: 56, 57, 58, 59, 60, 61, 62, 63, 96: 64, 65, 66, 67, 68, 69, 70, 71, 97: 72, 73, 74, 75, 76, 77, 78, 79, 98: 80, 81, 82, 83, 84, 85, 86, 87, 99: 88, 89, 90, 91, 92, 93, 94, 95, 100: 96, 97, 98, 99}; 1.1 root 101: 1.1.1.2 root 102: #endif 1.1 root 103: 104: /* Name of where we pretend to think the frame pointer points. 105: Normally, this is "%fp", but if we are in a leaf procedure, 1.1.1.3 root 106: this is "%sp+something". We record "something" separately as it may be 107: too big for reg+constant addressing. */ 108: 109: static char *frame_base_name; 110: static int frame_base_offset; 1.1 root 111: 112: static rtx find_addr_reg (); 1.1.1.3 root 113: static void sparc_init_modes (); 114: 115: /* Option handling. */ 116: 117: /* Validate and override various options, and do some machine dependent 118: initialization. */ 119: 120: void 121: sparc_override_options () 122: { 123: /* Check for any conflicts in the choice of options. */ 124: /* ??? This stuff isn't really usable yet. */ 125: 126: if (! TARGET_V9) 127: { 128: if (target_flags & MASK_CODE_MODEL) 129: error ("code model support is only available with -mv9"); 130: if (TARGET_INT64) 131: error ("-mint64 is only available with -mv9"); 132: if (TARGET_LONG64) 133: error ("-mlong64 is only available with -mv9"); 134: if (TARGET_PTR64) 135: error ("-mptr64 is only available with -mv9"); 136: if (TARGET_ENV32) 137: error ("-menv32 is only available with -mv9"); 138: if (TARGET_STACK_BIAS) 139: error ("-mstack-bias is only available with -mv9"); 140: } 141: else 142: { 143: /* ??? Are there any options that aren't usable with v9. 144: -munaligned-doubles? */ 145: } 146: 147: /* Check for conflicts in cpu specification. 148: If we use -mcpu=xxx, this can be removed. */ 1.1 root 149: 1.1.1.3 root 150: if ((TARGET_V8 != 0) + (TARGET_SPARCLITE != 0) + (TARGET_V9 != 0) > 1) 151: error ("conflicting architectures defined"); 152: 153: /* Do various machine dependent initializations. */ 154: sparc_init_modes (); 155: } 156: 157: /* Float conversions (v9 only). 158: 159: The floating point registers cannot hold DImode values because SUBREG's 160: on them get the wrong register. "(subreg:SI (reg:DI M int-reg) 0)" is the 161: same as "(subreg:SI (reg:DI N float-reg) 1)", but gcc doesn't know how to 162: turn the "0" to a "1". Therefore, we must explicitly do the conversions 163: to/from int/fp regs. `sparc64_fpconv_stack_slot' is the address of an 164: 8 byte stack slot used during the transfer. 165: ??? I could have used [%fp-16] but I didn't want to add yet another 166: dependence on this. */ 167: /* ??? Can we use assign_stack_temp here? */ 168: 169: static rtx fpconv_stack_temp; 170: 171: /* Called once for each function. */ 172: 173: void 174: sparc64_init_expanders () 175: { 176: fpconv_stack_temp = NULL_RTX; 177: } 178: 179: /* Assign a stack temp for fp/int DImode conversions. */ 180: 181: rtx 182: sparc64_fpconv_stack_temp () 183: { 184: if (fpconv_stack_temp == NULL_RTX) 185: fpconv_stack_temp = 186: assign_stack_local (DImode, GET_MODE_SIZE (DImode), 0); 187: 188: return fpconv_stack_temp; 189: } 190: 1.1.1.4 ! root 191: /* Miscellaneous utilities. */ ! 192: ! 193: /* Nonzero if CODE, a comparison, is suitable for use in v9 conditional move ! 194: or branch on register contents instructions. */ ! 195: ! 196: int ! 197: v9_regcmp_p (code) ! 198: enum rtx_code code; ! 199: { ! 200: return (code == EQ || code == NE || code == GE || code == LT ! 201: || code == LE || code == GT); ! 202: } ! 203: ! 204: /* Operand constraints. */ ! 205: 1.1 root 206: /* Return non-zero only if OP is a register of mode MODE, 207: or const0_rtx. */ 208: int 209: reg_or_0_operand (op, mode) 210: rtx op; 211: enum machine_mode mode; 212: { 213: if (op == const0_rtx || register_operand (op, mode)) 214: return 1; 1.1.1.3 root 215: if (GET_MODE (op) == VOIDmode && GET_CODE (op) == CONST_DOUBLE 1.1 root 216: && CONST_DOUBLE_HIGH (op) == 0 217: && CONST_DOUBLE_LOW (op) == 0) 218: return 1; 1.1.1.2 root 219: if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT 220: && GET_CODE (op) == CONST_DOUBLE 221: && fp_zero_operand (op)) 222: return 1; 1.1 root 223: return 0; 224: } 225: 1.1.1.2 root 226: /* Nonzero if OP is a floating point value with value 0.0. */ 227: int 228: fp_zero_operand (op) 229: rtx op; 230: { 231: REAL_VALUE_TYPE r; 232: 233: REAL_VALUE_FROM_CONST_DOUBLE (r, op); 234: return REAL_VALUES_EQUAL (r, dconst0); 235: } 236: 1.1.1.3 root 237: /* Nonzero if OP is an integer register. */ 238: 239: int 240: intreg_operand (op, mode) 241: rtx op; 242: enum machine_mode mode; 243: { 244: return (register_operand (op, SImode) 245: || (TARGET_V9 && register_operand (op, DImode))); 246: } 247: 248: /* Nonzero if OP is a floating point condition code register. */ 249: 250: int 251: ccfp_reg_operand (op, mode) 252: rtx op; 253: enum machine_mode mode; 254: { 255: /* This can happen when recog is called from combine. Op may be a MEM. 256: Fail instead of calling abort in this case. */ 257: if (GET_CODE (op) != REG || REGNO (op) == 0) 258: return 0; 259: if (GET_MODE (op) != mode) 260: return 0; 261: 262: #if 0 /* ??? ==> 1 when %fcc1-3 are pseudos first. See gen_compare_reg(). */ 263: if (reg_renumber == 0) 264: return REGNO (op) >= FIRST_PSEUDO_REGISTER; 265: return REGNO_OK_FOR_CCFP_P (REGNO (op)); 266: #else 267: return (unsigned) REGNO (op) - 96 < 4; 268: #endif 269: } 270: 1.1 root 271: /* Nonzero if OP can appear as the dest of a RESTORE insn. */ 272: int 273: restore_operand (op, mode) 274: rtx op; 275: enum machine_mode mode; 276: { 277: return (GET_CODE (op) == REG && GET_MODE (op) == mode 278: && (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32))); 279: } 280: 281: /* Call insn on SPARC can take a PC-relative constant address, or any regular 282: memory address. */ 283: 284: int 285: call_operand (op, mode) 286: rtx op; 287: enum machine_mode mode; 288: { 289: if (GET_CODE (op) != MEM) 290: abort (); 291: op = XEXP (op, 0); 1.1.1.3 root 292: return (symbolic_operand (op, mode) || memory_address_p (Pmode, op)); 1.1 root 293: } 294: 295: int 296: call_operand_address (op, mode) 297: rtx op; 298: enum machine_mode mode; 299: { 1.1.1.3 root 300: return (symbolic_operand (op, mode) || memory_address_p (Pmode, op)); 1.1 root 301: } 302: 303: /* Returns 1 if OP is either a symbol reference or a sum of a symbol 304: reference and a constant. */ 305: 306: int 307: symbolic_operand (op, mode) 308: register rtx op; 309: enum machine_mode mode; 310: { 311: switch (GET_CODE (op)) 312: { 313: case SYMBOL_REF: 314: case LABEL_REF: 315: return 1; 316: 317: case CONST: 318: op = XEXP (op, 0); 319: return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF 320: || GET_CODE (XEXP (op, 0)) == LABEL_REF) 321: && GET_CODE (XEXP (op, 1)) == CONST_INT); 322: 323: /* ??? This clause seems to be irrelevant. */ 324: case CONST_DOUBLE: 325: return GET_MODE (op) == mode; 326: 327: default: 328: return 0; 329: } 330: } 331: 332: /* Return truth value of statement that OP is a symbolic memory 333: operand of mode MODE. */ 334: 335: int 336: symbolic_memory_operand (op, mode) 337: rtx op; 338: enum machine_mode mode; 339: { 340: if (GET_CODE (op) == SUBREG) 341: op = SUBREG_REG (op); 342: if (GET_CODE (op) != MEM) 343: return 0; 344: op = XEXP (op, 0); 345: return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST 346: || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF); 347: } 348: 1.1.1.3 root 349: /* Return 1 if the operand is a data segment reference. This includes 350: the readonly data segment, or in other words anything but the text segment. 351: This is needed in the medium/anywhere code model on v9. These values 352: are accessed with MEDANY_BASE_REG. */ 353: 354: int 355: data_segment_operand (op, mode) 356: rtx op; 357: enum machine_mode mode; 358: { 359: switch (GET_CODE (op)) 360: { 361: case SYMBOL_REF : 362: return ! SYMBOL_REF_FLAG (op); 363: case PLUS : 364: /* Assume canonical format of symbol + constant. */ 365: case CONST : 366: return data_segment_operand (XEXP (op, 0)); 367: default : 368: return 0; 369: } 370: } 371: 372: /* Return 1 if the operand is a text segment reference. 373: This is needed in the medium/anywhere code model on v9. */ 374: 375: int 376: text_segment_operand (op, mode) 377: rtx op; 378: enum machine_mode mode; 379: { 380: switch (GET_CODE (op)) 381: { 382: case LABEL_REF : 383: return 1; 384: case SYMBOL_REF : 385: return SYMBOL_REF_FLAG (op); 386: case PLUS : 387: /* Assume canonical format of symbol + constant. */ 388: case CONST : 389: return text_segment_operand (XEXP (op, 0)); 390: default : 391: return 0; 392: } 393: } 394: 1.1 root 395: /* Return 1 if the operand is either a register or a memory operand that is 396: not symbolic. */ 397: 398: int 399: reg_or_nonsymb_mem_operand (op, mode) 400: register rtx op; 401: enum machine_mode mode; 402: { 403: if (register_operand (op, mode)) 404: return 1; 405: 406: if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode)) 407: return 1; 408: 409: return 0; 410: } 411: 412: int 413: sparc_operand (op, mode) 414: rtx op; 415: enum machine_mode mode; 416: { 417: if (register_operand (op, mode)) 418: return 1; 419: if (GET_CODE (op) == CONST_INT) 420: return SMALL_INT (op); 421: if (GET_MODE (op) != mode) 422: return 0; 423: if (GET_CODE (op) == SUBREG) 424: op = SUBREG_REG (op); 425: if (GET_CODE (op) != MEM) 426: return 0; 427: 428: op = XEXP (op, 0); 429: if (GET_CODE (op) == LO_SUM) 430: return (GET_CODE (XEXP (op, 0)) == REG 431: && symbolic_operand (XEXP (op, 1), Pmode)); 432: return memory_address_p (mode, op); 433: } 434: 435: int 436: move_operand (op, mode) 437: rtx op; 438: enum machine_mode mode; 439: { 440: if (mode == DImode && arith_double_operand (op, mode)) 441: return 1; 442: if (register_operand (op, mode)) 443: return 1; 444: if (GET_CODE (op) == CONST_INT) 445: return (SMALL_INT (op) || (INTVAL (op) & 0x3ff) == 0); 446: 447: if (GET_MODE (op) != mode) 448: return 0; 449: if (GET_CODE (op) == SUBREG) 450: op = SUBREG_REG (op); 451: if (GET_CODE (op) != MEM) 452: return 0; 453: op = XEXP (op, 0); 454: if (GET_CODE (op) == LO_SUM) 455: return (register_operand (XEXP (op, 0), Pmode) 456: && CONSTANT_P (XEXP (op, 1))); 457: return memory_address_p (mode, op); 458: } 459: 460: int 461: move_pic_label (op, mode) 462: rtx op; 463: enum machine_mode mode; 464: { 465: /* Special case for PIC. */ 466: if (flag_pic && GET_CODE (op) == LABEL_REF) 467: return 1; 468: return 0; 469: } 470: 471: int 1.1.1.4 ! root 472: splittable_symbolic_memory_operand (op, mode) 1.1 root 473: rtx op; 474: enum machine_mode mode; 475: { 1.1.1.4 ! root 476: if (GET_CODE (op) != MEM) ! 477: return 0; ! 478: if (! symbolic_operand (XEXP (op, 0), Pmode)) ! 479: return 0; ! 480: return 1; ! 481: } ! 482: ! 483: int ! 484: splittable_immediate_memory_operand (op, mode) ! 485: rtx op; ! 486: enum machine_mode mode; ! 487: { ! 488: if (GET_CODE (op) != MEM) ! 489: return 0; ! 490: if (! immediate_operand (XEXP (op, 0), Pmode)) ! 491: return 0; ! 492: return 1; 1.1 root 493: } 494: 495: /* Return truth value of whether OP is EQ or NE. */ 496: 497: int 498: eq_or_neq (op, mode) 499: rtx op; 500: enum machine_mode mode; 501: { 502: return (GET_CODE (op) == EQ || GET_CODE (op) == NE); 503: } 504: 505: /* Return 1 if this is a comparison operator, but not an EQ, NE, GEU, 506: or LTU for non-floating-point. We handle those specially. */ 507: 508: int 509: normal_comp_operator (op, mode) 510: rtx op; 511: enum machine_mode mode; 512: { 513: enum rtx_code code = GET_CODE (op); 514: 515: if (GET_RTX_CLASS (code) != '<') 516: return 0; 517: 518: if (GET_MODE (XEXP (op, 0)) == CCFPmode 519: || GET_MODE (XEXP (op, 0)) == CCFPEmode) 520: return 1; 521: 522: return (code != NE && code != EQ && code != GEU && code != LTU); 523: } 524: 525: /* Return 1 if this is a comparison operator. This allows the use of 526: MATCH_OPERATOR to recognize all the branch insns. */ 527: 528: int 529: noov_compare_op (op, mode) 530: register rtx op; 531: enum machine_mode mode; 532: { 533: enum rtx_code code = GET_CODE (op); 534: 535: if (GET_RTX_CLASS (code) != '<') 536: return 0; 537: 538: if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode) 539: /* These are the only branches which work with CC_NOOVmode. */ 540: return (code == EQ || code == NE || code == GE || code == LT); 541: return 1; 542: } 543: 1.1.1.3 root 544: /* Nonzero if OP is a comparison operator suitable for use in v9 545: conditional move or branch on register contents instructions. */ 546: 547: int 548: v9_regcmp_op (op, mode) 549: register rtx op; 550: enum machine_mode mode; 551: { 552: enum rtx_code code = GET_CODE (op); 553: 554: if (GET_RTX_CLASS (code) != '<') 555: return 0; 556: 1.1.1.4 ! root 557: return v9_regcmp_p (code); 1.1.1.3 root 558: } 559: 1.1 root 560: /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */ 561: 562: int 563: extend_op (op, mode) 564: rtx op; 565: enum machine_mode mode; 566: { 567: return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND; 568: } 569: 570: /* Return nonzero if OP is an operator of mode MODE which can set 571: the condition codes explicitly. We do not include PLUS and MINUS 572: because these require CC_NOOVmode, which we handle explicitly. */ 573: 574: int 575: cc_arithop (op, mode) 576: rtx op; 577: enum machine_mode mode; 578: { 579: if (GET_CODE (op) == AND 580: || GET_CODE (op) == IOR 581: || GET_CODE (op) == XOR) 582: return 1; 583: 584: return 0; 585: } 586: 587: /* Return nonzero if OP is an operator of mode MODE which can bitwise 588: complement its second operand and set the condition codes explicitly. */ 589: 590: int 591: cc_arithopn (op, mode) 592: rtx op; 593: enum machine_mode mode; 594: { 595: /* XOR is not here because combine canonicalizes (xor (not ...) ...) 596: and (xor ... (not ...)) to (not (xor ...)). */ 597: return (GET_CODE (op) == AND 598: || GET_CODE (op) == IOR); 599: } 600: 601: /* Return true if OP is a register, or is a CONST_INT that can fit in a 13 602: bit immediate field. This is an acceptable SImode operand for most 3 603: address instructions. */ 604: 605: int 606: arith_operand (op, mode) 607: rtx op; 608: enum machine_mode mode; 609: { 610: return (register_operand (op, mode) 611: || (GET_CODE (op) == CONST_INT && SMALL_INT (op))); 612: } 613: 1.1.1.3 root 614: /* Return true if OP is a register, or is a CONST_INT that can fit in an 11 615: bit immediate field. This is an acceptable SImode operand for the movcc 616: instructions. */ 617: 618: int 619: arith11_operand (op, mode) 620: rtx op; 621: enum machine_mode mode; 622: { 623: return (register_operand (op, mode) 624: || (GET_CODE (op) == CONST_INT 625: && ((unsigned) (INTVAL (op) + 0x400) < 0x800))); 626: } 627: 628: /* Return true if OP is a register, or is a CONST_INT that can fit in an 10 629: bit immediate field. This is an acceptable SImode operand for the movrcc 630: instructions. */ 631: 632: int 633: arith10_operand (op, mode) 634: rtx op; 635: enum machine_mode mode; 636: { 637: return (register_operand (op, mode) 638: || (GET_CODE (op) == CONST_INT 639: && ((unsigned) (INTVAL (op) + 0x200) < 0x400))); 640: } 641: 642: /* Return true if OP is a register, is a CONST_INT that fits in a 13 bit 643: immediate field, or is a CONST_DOUBLE whose both parts fit in a 13 bit 644: immediate field. 645: v9: Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that 1.1 root 646: can fit in a 13 bit immediate field. This is an acceptable DImode operand 647: for most 3 address instructions. */ 648: 649: int 650: arith_double_operand (op, mode) 651: rtx op; 652: enum machine_mode mode; 653: { 654: return (register_operand (op, mode) 1.1.1.3 root 655: || (GET_CODE (op) == CONST_INT && SMALL_INT (op)) 656: || (! TARGET_V9 657: && GET_CODE (op) == CONST_DOUBLE 658: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 659: && (unsigned) (CONST_DOUBLE_HIGH (op) + 0x1000) < 0x2000) 660: || (TARGET_V9 661: && GET_CODE (op) == CONST_DOUBLE 1.1 root 662: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x1000) < 0x2000 663: && ((CONST_DOUBLE_HIGH (op) == -1 664: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0x1000) 665: || (CONST_DOUBLE_HIGH (op) == 0 1.1.1.3 root 666: && (CONST_DOUBLE_LOW (op) & 0x1000) == 0)))); 667: } 668: 669: /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that 670: can fit in an 11 bit immediate field. This is an acceptable DImode 671: operand for the movcc instructions. */ 672: /* ??? Replace with arith11_operand? */ 673: 674: int 675: arith11_double_operand (op, mode) 676: rtx op; 677: enum machine_mode mode; 678: { 679: return (register_operand (op, mode) 680: || (GET_CODE (op) == CONST_DOUBLE 681: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 682: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x400) < 0x800 683: && ((CONST_DOUBLE_HIGH (op) == -1 684: && (CONST_DOUBLE_LOW (op) & 0x400) == 0x400) 685: || (CONST_DOUBLE_HIGH (op) == 0 686: && (CONST_DOUBLE_LOW (op) & 0x400) == 0))) 687: || (GET_CODE (op) == CONST_INT 688: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 689: && (unsigned) (INTVAL (op) + 0x400) < 0x800)); 690: } 691: 692: /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that 693: can fit in an 10 bit immediate field. This is an acceptable DImode 694: operand for the movrcc instructions. */ 695: /* ??? Replace with arith10_operand? */ 696: 697: int 698: arith10_double_operand (op, mode) 699: rtx op; 700: enum machine_mode mode; 701: { 702: return (register_operand (op, mode) 703: || (GET_CODE (op) == CONST_DOUBLE 704: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 705: && (unsigned) (CONST_DOUBLE_LOW (op) + 0x200) < 0x400 706: && ((CONST_DOUBLE_HIGH (op) == -1 707: && (CONST_DOUBLE_LOW (op) & 0x200) == 0x200) 708: || (CONST_DOUBLE_HIGH (op) == 0 709: && (CONST_DOUBLE_LOW (op) & 0x200) == 0))) 1.1 root 710: || (GET_CODE (op) == CONST_INT 711: && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) 1.1.1.3 root 712: && (unsigned) (INTVAL (op) + 0x200) < 0x400)); 1.1 root 713: } 714: 715: /* Return truth value of whether OP is a integer which fits the 716: range constraining immediate operands in most three-address insns, 717: which have a 13 bit immediate field. */ 718: 719: int 720: small_int (op, mode) 721: rtx op; 722: enum machine_mode mode; 723: { 724: return (GET_CODE (op) == CONST_INT && SMALL_INT (op)); 725: } 726: 1.1.1.2 root 727: /* Recognize operand values for the umul instruction. That instruction sign 728: extends immediate values just like all other sparc instructions, but 729: interprets the extended result as an unsigned number. */ 730: 731: int 732: uns_small_int (op, mode) 733: rtx op; 734: enum machine_mode mode; 735: { 736: #if HOST_BITS_PER_WIDE_INT > 32 737: /* All allowed constants will fit a CONST_INT. */ 738: return (GET_CODE (op) == CONST_INT 739: && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) 740: || (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L))); 741: #else 742: return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) 743: || (GET_CODE (op) == CONST_DOUBLE 744: && CONST_DOUBLE_HIGH (op) == 0 745: && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); 746: #endif 747: } 748: 749: int 750: uns_arith_operand (op, mode) 751: rtx op; 752: enum machine_mode mode; 753: { 754: return register_operand (op, mode) || uns_small_int (op, mode); 755: } 756: 1.1 root 757: /* Return truth value of statement that OP is a call-clobbered register. */ 758: int 759: clobbered_register (op, mode) 760: rtx op; 761: enum machine_mode mode; 762: { 763: return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]); 764: } 765: 766: /* X and Y are two things to compare using CODE. Emit the compare insn and 1.1.1.3 root 767: return the rtx for the cc reg in the proper mode. */ 1.1 root 768: 769: rtx 770: gen_compare_reg (code, x, y) 771: enum rtx_code code; 772: rtx x, y; 773: { 774: enum machine_mode mode = SELECT_CC_MODE (code, x, y); 1.1.1.3 root 775: rtx cc_reg; 776: 777: /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the 778: fpcc regs (cse can't tell they're really call clobbered regs and will 779: remove a duplicate comparison even if there is an intervening function 780: call - it will then try to reload the cc reg via an int reg which is why 781: we need the movcc patterns). It is possible to provide the movcc 782: patterns by using the ldxfsr/stxfsr v9 insns. I tried it: you need two 783: registers (say %g1,%g5) and it takes about 6 insns. A better fix would be 1.1.1.4 ! root 784: to tell cse that CCFPE mode registers (even pseudos) are call 1.1.1.3 root 785: clobbered. */ 786: 787: /* ??? This is an experiment. Rather than making changes to cse which may 788: or may not be easy/clean, we do our own cse. This is possible because 789: we will generate hard registers. Cse knows they're call clobbered (it 790: doesn't know the same thing about pseudos). If we guess wrong, no big 791: deal, but if we win, great! */ 792: 793: if (TARGET_V9 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) 794: #if 1 /* experiment */ 795: { 796: int reg; 797: /* We cycle through the registers to ensure they're all exercised. */ 798: static int next_fpcc_reg = 0; 799: /* Previous x,y for each fpcc reg. */ 800: static rtx prev_args[4][2]; 801: 802: /* Scan prev_args for x,y. */ 803: for (reg = 0; reg < 4; reg++) 804: if (prev_args[reg][0] == x && prev_args[reg][1] == y) 805: break; 806: if (reg == 4) 807: { 808: reg = next_fpcc_reg; 809: prev_args[reg][0] = x; 810: prev_args[reg][1] = y; 811: next_fpcc_reg = (next_fpcc_reg + 1) & 3; 812: } 813: cc_reg = gen_rtx (REG, mode, reg + 96); 814: } 815: #else 816: cc_reg = gen_reg_rtx (mode); 817: #endif /* ! experiment */ 818: else 819: cc_reg = gen_rtx (REG, mode, 0); 1.1 root 820: 821: emit_insn (gen_rtx (SET, VOIDmode, cc_reg, 822: gen_rtx (COMPARE, mode, x, y))); 823: 824: return cc_reg; 825: } 1.1.1.3 root 826: 827: /* This function is used for v9 only. 828: CODE is the code for an Scc's comparison. 829: OPERANDS[0] is the target of the Scc insn. 830: OPERANDS[1] is the value we compare against const0_rtx (which hasn't 831: been generated yet). 832: 833: This function is needed to turn 834: 835: (set (reg:SI 110) 836: (gt (reg:CCX 0 %g0) 837: (const_int 0))) 838: into 839: (set (reg:SI 110) 840: (gt:DI (reg:CCX 0 %g0) 841: (const_int 0))) 842: 843: IE: The instruction recognizer needs to see the mode of the comparison to 844: find the right instruction. We could use "gt:DI" right in the 845: define_expand, but leaving it out allows us to handle DI, SI, etc. 846: 847: We refer to the global sparc compare operands sparc_compare_op0 and 848: sparc_compare_op1. 849: 850: ??? Some of this is outdated as the scc insns set the mode of the 851: comparison now. 852: 853: ??? We optimize for the case where op1 is 0 and the comparison allows us to 854: use the "movrCC" insns. This reduces the generated code from three to two 855: insns. This way seems too brute force though. Is there a more elegant way 856: to achieve the same effect? 857: 858: Currently, this function always returns 1. ??? Can it ever fail? */ 859: 860: int 861: gen_v9_scc (compare_code, operands) 862: enum rtx_code compare_code; 863: register rtx *operands; 864: { 865: rtx temp; 866: 867: if (GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) == MODE_INT 868: && sparc_compare_op1 == const0_rtx 869: && (compare_code == EQ || compare_code == NE 870: || compare_code == LT || compare_code == LE 871: || compare_code == GT || compare_code == GE)) 872: { 873: /* Special case for op0 != 0. This can be done with one instruction if 874: op0 can be clobbered. We store to a temp, and then clobber the temp, 875: but the combiner will remove the first insn. */ 876: 877: if (compare_code == NE 878: && GET_MODE (operands[0]) == DImode 879: && GET_MODE (sparc_compare_op0) == DImode) 880: { 881: emit_insn (gen_rtx (SET, VOIDmode, operands[0], sparc_compare_op0)); 882: emit_insn (gen_rtx (SET, VOIDmode, operands[0], 883: gen_rtx (IF_THEN_ELSE, VOIDmode, 884: gen_rtx (compare_code, DImode, 885: sparc_compare_op0, const0_rtx), 886: const1_rtx, 887: operands[0]))); 888: return 1; 889: } 890: 891: emit_insn (gen_rtx (SET, VOIDmode, operands[0], const0_rtx)); 892: if (GET_MODE (sparc_compare_op0) != DImode) 893: { 894: temp = gen_reg_rtx (DImode); 895: convert_move (temp, sparc_compare_op0, 0); 896: } 897: else 898: { 899: temp = sparc_compare_op0; 900: } 901: emit_insn (gen_rtx (SET, VOIDmode, operands[0], 902: gen_rtx (IF_THEN_ELSE, VOIDmode, 903: gen_rtx (compare_code, DImode, 904: temp, const0_rtx), 905: const1_rtx, 906: operands[0]))); 907: return 1; 908: } 909: else 910: { 911: operands[1] = gen_compare_reg (compare_code, 912: sparc_compare_op0, sparc_compare_op1); 913: 914: switch (GET_MODE (operands[1])) 915: { 916: case CCmode : 917: case CCXmode : 918: case CCFPEmode : 919: case CCFPmode : 920: break; 921: default : 922: abort (); 923: } 924: emit_insn (gen_rtx (SET, VOIDmode, operands[0], const0_rtx)); 925: emit_insn (gen_rtx (SET, VOIDmode, operands[0], 926: gen_rtx (IF_THEN_ELSE, VOIDmode, 927: gen_rtx (compare_code, 928: GET_MODE (operands[1]), 929: operands[1], const0_rtx), 930: const1_rtx, operands[0]))); 931: return 1; 932: } 933: } 934: 935: /* Emit a conditional jump insn for the v9 architecture using comparison code 936: CODE and jump target LABEL. 937: This function exists to take advantage of the v9 brxx insns. */ 938: 939: void 940: emit_v9_brxx_insn (code, op0, label) 941: enum rtx_code code; 942: rtx op0, label; 943: { 944: emit_jump_insn (gen_rtx (SET, VOIDmode, 945: pc_rtx, 946: gen_rtx (IF_THEN_ELSE, VOIDmode, 947: gen_rtx (code, GET_MODE (op0), 948: op0, const0_rtx), 949: gen_rtx (LABEL_REF, VOIDmode, label), 950: pc_rtx))); 951: } 1.1 root 952: 953: /* Return nonzero if a return peephole merging return with 954: setting of output register is ok. */ 955: int 956: leaf_return_peephole_ok () 957: { 958: return (actual_fsize == 0); 959: } 960: 961: /* Return nonzero if TRIAL can go into the function epilogue's 962: delay slot. SLOT is the slot we are trying to fill. */ 963: 964: int 965: eligible_for_epilogue_delay (trial, slot) 966: rtx trial; 967: int slot; 968: { 969: rtx pat, src; 970: 971: if (slot >= 1) 972: return 0; 973: if (GET_CODE (trial) != INSN 974: || GET_CODE (PATTERN (trial)) != SET) 975: return 0; 976: if (get_attr_length (trial) != 1) 977: return 0; 978: 979: /* In the case of a true leaf function, anything can go into the delay slot. 980: A delay slot only exists however if the frame size is zero, otherwise 981: we will put an insn to adjust the stack after the return. */ 982: if (leaf_function) 983: { 984: if (leaf_return_peephole_ok ()) 985: return (get_attr_in_uncond_branch_delay (trial) == IN_BRANCH_DELAY_TRUE); 986: return 0; 987: } 988: 989: /* Otherwise, only operations which can be done in tandem with 990: a `restore' insn can go into the delay slot. */ 991: pat = PATTERN (trial); 992: if (GET_CODE (SET_DEST (pat)) != REG 993: || REGNO (SET_DEST (pat)) == 0 994: || REGNO (SET_DEST (pat)) >= 32 995: || REGNO (SET_DEST (pat)) < 24) 996: return 0; 997: 998: src = SET_SRC (pat); 999: if (arith_operand (src, GET_MODE (src))) 1000: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); 1001: if (arith_double_operand (src, GET_MODE (src))) 1002: return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); 1003: if (GET_CODE (src) == PLUS) 1004: { 1005: if (register_operand (XEXP (src, 0), SImode) 1006: && arith_operand (XEXP (src, 1), SImode)) 1007: return 1; 1008: if (register_operand (XEXP (src, 1), SImode) 1009: && arith_operand (XEXP (src, 0), SImode)) 1010: return 1; 1011: if (register_operand (XEXP (src, 0), DImode) 1012: && arith_double_operand (XEXP (src, 1), DImode)) 1013: return 1; 1014: if (register_operand (XEXP (src, 1), DImode) 1015: && arith_double_operand (XEXP (src, 0), DImode)) 1016: return 1; 1017: } 1018: if (GET_CODE (src) == MINUS 1019: && register_operand (XEXP (src, 0), SImode) 1020: && small_int (XEXP (src, 1), VOIDmode)) 1021: return 1; 1022: if (GET_CODE (src) == MINUS 1023: && register_operand (XEXP (src, 0), DImode) 1024: && !register_operand (XEXP (src, 1), DImode) 1025: && arith_double_operand (XEXP (src, 1), DImode)) 1026: return 1; 1027: return 0; 1028: } 1029: 1030: int 1031: short_branch (uid1, uid2) 1032: int uid1, uid2; 1033: { 1034: unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2]; 1035: if (delta + 1024 < 2048) 1036: return 1; 1037: /* warning ("long branch, distance %d", delta); */ 1038: return 0; 1039: } 1040: 1041: /* Return non-zero if REG is not used after INSN. 1042: We assume REG is a reload reg, and therefore does 1043: not live past labels or calls or jumps. */ 1044: int 1045: reg_unused_after (reg, insn) 1046: rtx reg; 1047: rtx insn; 1048: { 1049: enum rtx_code code, prev_code = UNKNOWN; 1050: 1051: while (insn = NEXT_INSN (insn)) 1052: { 1053: if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)]) 1054: return 1; 1055: 1056: code = GET_CODE (insn); 1057: if (GET_CODE (insn) == CODE_LABEL) 1058: return 1; 1059: 1060: if (GET_RTX_CLASS (code) == 'i') 1061: { 1062: rtx set = single_set (insn); 1063: int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set)); 1064: if (set && in_src) 1065: return 0; 1066: if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) 1067: return 1; 1068: if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) 1069: return 0; 1070: } 1071: prev_code = code; 1072: } 1073: return 1; 1074: } 1075: 1.1.1.2 root 1076: /* The rtx for the global offset table which is a special form 1077: that *is* a position independent symbolic constant. */ 1078: static rtx pic_pc_rtx; 1079: 1080: /* Ensure that we are not using patterns that are not OK with PIC. */ 1081: 1082: int 1083: check_pic (i) 1084: int i; 1085: { 1086: switch (flag_pic) 1087: { 1088: case 1: 1089: if (GET_CODE (recog_operand[i]) == SYMBOL_REF 1090: || (GET_CODE (recog_operand[i]) == CONST 1091: && ! rtx_equal_p (pic_pc_rtx, recog_operand[i]))) 1092: abort (); 1093: case 2: 1094: default: 1095: return 1; 1096: } 1097: } 1098: 1099: /* Return true if X is an address which needs a temporary register when 1100: reloaded while generating PIC code. */ 1101: 1102: int 1103: pic_address_needs_scratch (x) 1104: rtx x; 1105: { 1106: /* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */ 1107: if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS 1108: && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF 1109: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 1110: && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) 1111: return 1; 1112: 1113: return 0; 1114: } 1115: 1.1 root 1116: /* Legitimize PIC addresses. If the address is already position-independent, 1117: we return ORIG. Newly generated position-independent addresses go into a 1118: reg. This is REG if non zero, otherwise we allocate register(s) as 1.1.1.2 root 1119: necessary. */ 1.1 root 1120: 1121: rtx 1.1.1.2 root 1122: legitimize_pic_address (orig, mode, reg) 1.1 root 1123: rtx orig; 1124: enum machine_mode mode; 1.1.1.2 root 1125: rtx reg; 1.1 root 1126: { 1127: if (GET_CODE (orig) == SYMBOL_REF) 1128: { 1129: rtx pic_ref, address; 1130: rtx insn; 1131: 1132: if (reg == 0) 1133: { 1134: if (reload_in_progress || reload_completed) 1135: abort (); 1136: else 1137: reg = gen_reg_rtx (Pmode); 1138: } 1139: 1140: if (flag_pic == 2) 1141: { 1142: /* If not during reload, allocate another temp reg here for loading 1143: in the address, so that these instructions can be optimized 1144: properly. */ 1145: rtx temp_reg = ((reload_in_progress || reload_completed) 1146: ? reg : gen_reg_rtx (Pmode)); 1147: 1148: /* Must put the SYMBOL_REF inside an UNSPEC here so that cse 1149: won't get confused into thinking that these two instructions 1150: are loading in the true address of the symbol. If in the 1151: future a PIC rtx exists, that should be used instead. */ 1152: emit_insn (gen_rtx (SET, VOIDmode, temp_reg, 1153: gen_rtx (HIGH, Pmode, 1154: gen_rtx (UNSPEC, Pmode, 1155: gen_rtvec (1, orig), 1156: 0)))); 1157: emit_insn (gen_rtx (SET, VOIDmode, temp_reg, 1158: gen_rtx (LO_SUM, Pmode, temp_reg, 1159: gen_rtx (UNSPEC, Pmode, 1160: gen_rtvec (1, orig), 1161: 0)))); 1162: address = temp_reg; 1163: } 1164: else 1165: address = orig; 1166: 1167: pic_ref = gen_rtx (MEM, Pmode, 1168: gen_rtx (PLUS, Pmode, 1169: pic_offset_table_rtx, address)); 1170: current_function_uses_pic_offset_table = 1; 1171: RTX_UNCHANGING_P (pic_ref) = 1; 1172: insn = emit_move_insn (reg, pic_ref); 1173: /* Put a REG_EQUAL note on this insn, so that it can be optimized 1174: by loop. */ 1175: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, orig, 1176: REG_NOTES (insn)); 1177: return reg; 1178: } 1179: else if (GET_CODE (orig) == CONST) 1180: { 1181: rtx base, offset; 1182: 1183: if (GET_CODE (XEXP (orig, 0)) == PLUS 1184: && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) 1185: return orig; 1186: 1187: if (reg == 0) 1188: { 1189: if (reload_in_progress || reload_completed) 1190: abort (); 1191: else 1192: reg = gen_reg_rtx (Pmode); 1193: } 1194: 1195: if (GET_CODE (XEXP (orig, 0)) == PLUS) 1196: { 1.1.1.2 root 1197: base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); 1.1 root 1198: offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, 1.1.1.2 root 1199: base == reg ? 0 : reg); 1.1 root 1200: } 1201: else 1202: abort (); 1203: 1204: if (GET_CODE (offset) == CONST_INT) 1205: { 1206: if (SMALL_INT (offset)) 1207: return plus_constant_for_output (base, INTVAL (offset)); 1208: else if (! reload_in_progress && ! reload_completed) 1209: offset = force_reg (Pmode, offset); 1210: else 1.1.1.2 root 1211: /* If we reach here, then something is seriously wrong. */ 1.1 root 1212: abort (); 1213: } 1214: return gen_rtx (PLUS, Pmode, base, offset); 1215: } 1216: else if (GET_CODE (orig) == LABEL_REF) 1217: current_function_uses_pic_offset_table = 1; 1218: 1219: return orig; 1220: } 1221: 1222: /* Set up PIC-specific rtl. This should not cause any insns 1223: to be emitted. */ 1224: 1225: void 1226: initialize_pic () 1227: { 1228: } 1229: 1230: /* Emit special PIC prologues and epilogues. */ 1231: 1232: void 1233: finalize_pic () 1234: { 1235: /* The table we use to reference PIC data. */ 1236: rtx global_offset_table; 1237: /* Labels to get the PC in the prologue of this function. */ 1238: rtx l1, l2; 1239: rtx seq; 1240: int orig_flag_pic = flag_pic; 1241: 1242: if (current_function_uses_pic_offset_table == 0) 1243: return; 1244: 1245: if (! flag_pic) 1246: abort (); 1247: 1248: flag_pic = 0; 1249: l1 = gen_label_rtx (); 1250: l2 = gen_label_rtx (); 1251: 1252: start_sequence (); 1253: 1254: emit_label (l1); 1255: /* Note that we pun calls and jumps here! */ 1256: emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, 1257: gen_rtvec (2, 1258: gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)), 1259: gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2))))); 1260: emit_label (l2); 1261: 1262: /* Initialize every time through, since we can't easily 1263: know this to be permanent. */ 1264: global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "_GLOBAL_OFFSET_TABLE_"); 1265: pic_pc_rtx = gen_rtx (CONST, Pmode, 1266: gen_rtx (MINUS, Pmode, 1267: global_offset_table, 1268: gen_rtx (CONST, Pmode, 1269: gen_rtx (MINUS, Pmode, 1270: gen_rtx (LABEL_REF, VOIDmode, l1), 1271: pc_rtx)))); 1272: 1.1.1.3 root 1273: if (Pmode == DImode) 1274: emit_insn (gen_rtx (PARALLEL, VOIDmode, 1275: gen_rtvec (2, 1276: gen_rtx (SET, VOIDmode, pic_offset_table_rtx, 1277: gen_rtx (HIGH, Pmode, pic_pc_rtx)), 1278: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, Pmode, 1))))); 1279: else 1280: emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx, 1281: gen_rtx (HIGH, Pmode, pic_pc_rtx))); 1282: 1.1 root 1283: emit_insn (gen_rtx (SET, VOIDmode, 1284: pic_offset_table_rtx, 1285: gen_rtx (LO_SUM, Pmode, 1286: pic_offset_table_rtx, pic_pc_rtx))); 1287: emit_insn (gen_rtx (SET, VOIDmode, 1288: pic_offset_table_rtx, 1289: gen_rtx (PLUS, Pmode, 1290: pic_offset_table_rtx, gen_rtx (REG, Pmode, 15)))); 1291: /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */ 1292: LABEL_PRESERVE_P (l1) = 1; 1293: LABEL_PRESERVE_P (l2) = 1; 1294: flag_pic = orig_flag_pic; 1295: 1296: seq = gen_sequence (); 1297: end_sequence (); 1298: emit_insn_after (seq, get_insns ()); 1299: 1300: /* Need to emit this whether or not we obey regdecls, 1301: since setjmp/longjmp can cause life info to screw up. */ 1302: emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx)); 1303: } 1304: 1305: /* Emit insns to move operands[1] into operands[0]. 1306: 1307: Return 1 if we have written out everything that needs to be done to 1308: do the move. Otherwise, return 0 and the caller will emit the move 1.1.1.2 root 1309: normally. */ 1.1 root 1310: 1311: int 1.1.1.2 root 1312: emit_move_sequence (operands, mode) 1.1 root 1313: rtx *operands; 1314: enum machine_mode mode; 1315: { 1316: register rtx operand0 = operands[0]; 1317: register rtx operand1 = operands[1]; 1318: 1.1.1.2 root 1319: if (CONSTANT_P (operand1) && flag_pic 1320: && pic_address_needs_scratch (operand1)) 1321: operands[1] = operand1 = legitimize_pic_address (operand1, mode, 0); 1322: 1.1 root 1323: /* Handle most common case first: storing into a register. */ 1324: if (register_operand (operand0, mode)) 1325: { 1326: if (register_operand (operand1, mode) 1327: || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) 1328: || (GET_CODE (operand1) == CONST_DOUBLE 1329: && arith_double_operand (operand1, DImode)) 1330: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode) 1331: /* Only `general_operands' can come here, so MEM is ok. */ 1332: || GET_CODE (operand1) == MEM) 1333: { 1334: /* Run this case quickly. */ 1335: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); 1336: return 1; 1337: } 1338: } 1339: else if (GET_CODE (operand0) == MEM) 1340: { 1341: if (register_operand (operand1, mode) || operand1 == const0_rtx) 1342: { 1343: /* Run this case quickly. */ 1344: emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1)); 1345: return 1; 1346: } 1347: if (! reload_in_progress) 1348: { 1349: operands[0] = validize_mem (operand0); 1350: operands[1] = operand1 = force_reg (mode, operand1); 1351: } 1352: } 1353: 1354: /* Simplify the source if we need to. Must handle DImode HIGH operators 1355: here because such a move needs a clobber added. */ 1356: if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) 1357: || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode)) 1358: { 1359: if (flag_pic && symbolic_operand (operand1, mode)) 1360: { 1361: rtx temp_reg = reload_in_progress ? operand0 : 0; 1362: 1.1.1.2 root 1363: operands[1] = legitimize_pic_address (operand1, mode, temp_reg); 1.1 root 1364: } 1365: else if (GET_CODE (operand1) == CONST_INT 1366: ? (! SMALL_INT (operand1) 1367: && (INTVAL (operand1) & 0x3ff) != 0) 1368: : (GET_CODE (operand1) == CONST_DOUBLE 1369: ? ! arith_double_operand (operand1, DImode) 1370: : 1)) 1371: { 1372: /* For DImode values, temp must be operand0 because of the way 1373: HI and LO_SUM work. The LO_SUM operator only copies half of 1374: the LSW from the dest of the HI operator. If the LO_SUM dest is 1375: not the same as the HI dest, then the MSW of the LO_SUM dest will 1376: never be set. 1377: 1378: ??? The real problem here is that the ...(HI:DImode pattern emits 1379: multiple instructions, and the ...(LO_SUM:DImode pattern emits 1380: one instruction. This fails, because the compiler assumes that 1381: LO_SUM copies all bits of the first operand to its dest. Better 1382: would be to have the HI pattern emit one instruction and the 1383: LO_SUM pattern multiple instructions. Even better would be 1384: to use four rtl insns. */ 1385: rtx temp = ((reload_in_progress || mode == DImode) 1386: ? operand0 : gen_reg_rtx (mode)); 1387: 1.1.1.3 root 1388: if (TARGET_V9 && mode == DImode) 1389: { 1390: int high_operand = 0; 1391: 1392: /* If the operand is already a HIGH, then remove the HIGH so 1393: that we won't get duplicate HIGH operators in this insn. 1394: Also, we must store the result into the original dest, 1395: because that is where the following LO_SUM expects it. */ 1396: if (GET_CODE (operand1) == HIGH) 1397: { 1398: operand1 = XEXP (operand1, 0); 1399: high_operand = 1; 1400: } 1401: 1402: emit_insn (gen_rtx (PARALLEL, VOIDmode, 1403: gen_rtvec (2, 1404: gen_rtx (SET, VOIDmode, temp, 1405: gen_rtx (HIGH, mode, operand1)), 1406: gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, DImode, 1))))); 1407: 1408: /* If this was a high operand, then we are now finished. */ 1409: if (high_operand) 1410: return 1; 1411: } 1412: else 1413: emit_insn (gen_rtx (SET, VOIDmode, temp, 1414: gen_rtx (HIGH, mode, operand1))); 1415: 1.1 root 1416: operands[1] = gen_rtx (LO_SUM, mode, temp, operand1); 1417: } 1418: } 1419: 1420: if (GET_CODE (operand1) == LABEL_REF && flag_pic) 1421: { 1422: /* The procedure for doing this involves using a call instruction to 1423: get the pc into o7. We need to indicate this explicitly because 1424: the tablejump pattern assumes that it can use this value also. */ 1425: emit_insn (gen_rtx (PARALLEL, VOIDmode, 1426: gen_rtvec (2, 1427: gen_rtx (SET, VOIDmode, operand0, 1428: operand1), 1429: gen_rtx (SET, VOIDmode, 1430: gen_rtx (REG, mode, 15), 1431: pc_rtx)))); 1432: return 1; 1433: } 1434: 1435: /* Now have insn-emit do whatever it normally does. */ 1436: return 0; 1437: } 1438: 1439: /* Return the best assembler insn template 1440: for moving operands[1] into operands[0] as a fullword. */ 1441: 1442: char * 1443: singlemove_string (operands) 1444: rtx *operands; 1445: { 1446: if (GET_CODE (operands[0]) == MEM) 1447: { 1448: if (GET_CODE (operands[1]) != MEM) 1449: return "st %r1,%0"; 1450: else 1451: abort (); 1452: } 1453: else if (GET_CODE (operands[1]) == MEM) 1454: return "ld %1,%0"; 1455: else if (GET_CODE (operands[1]) == CONST_DOUBLE) 1456: { 1.1.1.2 root 1457: REAL_VALUE_TYPE r; 1458: long i; 1.1 root 1459: 1460: /* Must be SFmode, otherwise this doesn't make sense. */ 1461: if (GET_MODE (operands[1]) != SFmode) 1462: abort (); 1463: 1.1.1.2 root 1464: REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); 1465: REAL_VALUE_TO_TARGET_SINGLE (r, i); 1.1 root 1466: operands[1] = gen_rtx (CONST_INT, VOIDmode, i); 1467: 1468: if (CONST_OK_FOR_LETTER_P (i, 'I')) 1469: return "mov %1,%0"; 1470: else if ((i & 0x000003FF) != 0) 1471: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; 1472: else 1473: return "sethi %%hi(%a1),%0"; 1474: } 1475: else if (GET_CODE (operands[1]) == CONST_INT 1476: && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) 1477: { 1478: int i = INTVAL (operands[1]); 1479: 1480: /* If all low order 10 bits are clear, then we only need a single 1481: sethi insn to load the constant. */ 1482: if ((i & 0x000003FF) != 0) 1483: return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; 1484: else 1485: return "sethi %%hi(%a1),%0"; 1486: } 1487: /* Operand 1 must be a register, or a 'I' type CONST_INT. */ 1488: return "mov %1,%0"; 1489: } 1490: 1491: /* Return non-zero if it is OK to assume that the given memory operand is 1492: aligned at least to a 8-byte boundary. This should only be called 1493: for memory accesses whose size is 8 bytes or larger. */ 1494: 1495: int 1496: mem_aligned_8 (mem) 1497: register rtx mem; 1498: { 1499: register rtx addr; 1500: register rtx base; 1501: register rtx offset; 1502: 1503: if (GET_CODE (mem) != MEM) 1504: return 0; /* It's gotta be a MEM! */ 1505: 1506: addr = XEXP (mem, 0); 1507: 1508: /* Now that all misaligned double parms are copied on function entry, 1509: we can assume any 64-bit object is 64-bit aligned except those which 1510: are at unaligned offsets from the stack or frame pointer. If the 1511: TARGET_UNALIGNED_DOUBLES switch is given, we do not make this 1512: assumption. */ 1513: 1514: /* See what register we use in the address. */ 1515: base = 0; 1516: if (GET_CODE (addr) == PLUS) 1517: { 1518: if (GET_CODE (XEXP (addr, 0)) == REG 1519: && GET_CODE (XEXP (addr, 1)) == CONST_INT) 1520: { 1521: base = XEXP (addr, 0); 1522: offset = XEXP (addr, 1); 1523: } 1524: } 1525: else if (GET_CODE (addr) == REG) 1526: { 1527: base = addr; 1528: offset = const0_rtx; 1529: } 1530: 1531: /* If it's the stack or frame pointer, check offset alignment. 1532: We can have improper alignment in the function entry code. */ 1533: if (base 1534: && (REGNO (base) == FRAME_POINTER_REGNUM 1535: || REGNO (base) == STACK_POINTER_REGNUM)) 1536: { 1.1.1.3 root 1537: if (((INTVAL (offset) - SPARC_STACK_BIAS) & 0x7) == 0) 1.1 root 1538: return 1; 1539: } 1540: /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES 1541: is true, in which case we can only assume that an access is aligned if 1.1.1.3 root 1542: it is to a constant address, or the address involves a LO_SUM. 1543: 1544: We used to assume an address was aligned if MEM_IN_STRUCT_P was true. 1545: That assumption was deleted so that gcc generated code can be used with 1546: memory allocators that only guarantee 4 byte alignment. */ 1547: else if (! TARGET_UNALIGNED_DOUBLES || CONSTANT_P (addr) 1548: || GET_CODE (addr) == LO_SUM) 1.1 root 1549: return 1; 1550: 1551: /* An obviously unaligned address. */ 1552: return 0; 1553: } 1554: 1555: enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }; 1556: 1557: /* Output assembler code to perform a doubleword move insn 1558: with operands OPERANDS. This is very similar to the following 1559: output_move_quad function. */ 1560: 1561: char * 1562: output_move_double (operands) 1563: rtx *operands; 1564: { 1565: register rtx op0 = operands[0]; 1566: register rtx op1 = operands[1]; 1567: register enum optype optype0; 1568: register enum optype optype1; 1569: rtx latehalf[2]; 1570: rtx addreg0 = 0; 1571: rtx addreg1 = 0; 1.1.1.2 root 1572: int highest_first = 0; 1573: int no_addreg1_decrement = 0; 1.1 root 1574: 1575: /* First classify both operands. */ 1576: 1577: if (REG_P (op0)) 1578: optype0 = REGOP; 1579: else if (offsettable_memref_p (op0)) 1580: optype0 = OFFSOP; 1581: else if (GET_CODE (op0) == MEM) 1582: optype0 = MEMOP; 1583: else 1584: optype0 = RNDOP; 1585: 1586: if (REG_P (op1)) 1587: optype1 = REGOP; 1588: else if (CONSTANT_P (op1)) 1589: optype1 = CNSTOP; 1590: else if (offsettable_memref_p (op1)) 1591: optype1 = OFFSOP; 1592: else if (GET_CODE (op1) == MEM) 1593: optype1 = MEMOP; 1594: else 1595: optype1 = RNDOP; 1596: 1597: /* Check for the cases that the operand constraints are not 1598: supposed to allow to happen. Abort if we get one, 1599: because generating code for these cases is painful. */ 1600: 1601: if (optype0 == RNDOP || optype1 == RNDOP 1602: || (optype0 == MEM && optype1 == MEM)) 1603: abort (); 1604: 1605: /* If an operand is an unoffsettable memory ref, find a register 1606: we can increment temporarily to make it refer to the second word. */ 1607: 1608: if (optype0 == MEMOP) 1609: addreg0 = find_addr_reg (XEXP (op0, 0)); 1610: 1611: if (optype1 == MEMOP) 1612: addreg1 = find_addr_reg (XEXP (op1, 0)); 1613: 1614: /* Ok, we can do one word at a time. 1615: Set up in LATEHALF the operands to use for the 1616: high-numbered (least significant) word and in some cases alter the 1617: operands in OPERANDS to be suitable for the low-numbered word. */ 1618: 1619: if (optype0 == REGOP) 1620: latehalf[0] = gen_rtx (REG, SImode, REGNO (op0) + 1); 1621: else if (optype0 == OFFSOP) 1622: latehalf[0] = adj_offsettable_operand (op0, 4); 1623: else 1624: latehalf[0] = op0; 1625: 1626: if (optype1 == REGOP) 1627: latehalf[1] = gen_rtx (REG, SImode, REGNO (op1) + 1); 1628: else if (optype1 == OFFSOP) 1629: latehalf[1] = adj_offsettable_operand (op1, 4); 1630: else if (optype1 == CNSTOP) 1.1.1.3 root 1631: { 1632: if (TARGET_V9) 1633: { 1634: if (arith_double_operand (op1, DImode)) 1635: { 1636: operands[1] = gen_rtx (CONST_INT, VOIDmode, 1637: CONST_DOUBLE_LOW (op1)); 1638: return "mov %1,%0"; 1639: } 1640: else 1641: { 1642: /* The only way to handle CONST_DOUBLEs or other 64 bit 1643: constants here is to use a temporary, such as is done 1644: for the V9 DImode sethi insn pattern. This is not 1645: a practical solution, so abort if we reach here. 1646: The md file should always force such constants to 1647: memory. */ 1648: abort (); 1649: } 1650: } 1651: else 1652: split_double (op1, &operands[1], &latehalf[1]); 1653: } 1.1 root 1654: else 1655: latehalf[1] = op1; 1656: 1657: /* Easy case: try moving both words at once. Check for moving between 1658: an even/odd register pair and a memory location. */ 1659: if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP 1.1.1.3 root 1660: && (TARGET_V9 || (REGNO (op0) & 1) == 0)) 1.1 root 1661: || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP 1.1.1.3 root 1662: && (TARGET_V9 || (REGNO (op1) & 1) == 0))) 1.1 root 1663: { 1.1.1.3 root 1664: register rtx mem,reg; 1.1 root 1665: 1666: if (optype0 == REGOP) 1.1.1.3 root 1667: mem = op1, reg = op0; 1.1 root 1668: else 1.1.1.3 root 1669: mem = op0, reg = op1; 1.1 root 1670: 1.1.1.3 root 1671: /* In v9, ldd can be used for word aligned addresses, so technically 1672: some of this logic is unneeded. We still avoid ldd if the address 1673: is obviously unaligned though. */ 1674: 1675: if (mem_aligned_8 (mem) 1676: /* If this is a floating point register higher than %f31, 1677: then we *must* use an aligned load, since `ld' will not accept 1678: the register number. */ 1679: || (TARGET_V9 && REGNO (reg) >= 64)) 1680: { 1681: if (FP_REG_P (reg) || ! TARGET_V9) 1682: return (mem == op1 ? "ldd %1,%0" : "std %1,%0"); 1683: else 1684: return (mem == op1 ? "ldx %1,%0" : "stx %1,%0"); 1685: } 1686: } 1687: 1688: if (TARGET_V9) 1689: { 1690: if (optype0 == REGOP && optype1 == REGOP) 1691: { 1692: if (FP_REG_P (op0)) 1693: return "fmovd %1,%0"; 1694: else 1695: return "mov %1,%0"; 1696: } 1.1 root 1697: } 1698: 1699: /* If the first move would clobber the source of the second one, 1700: do them in the other order. */ 1701: 1702: /* Overlapping registers. */ 1703: if (optype0 == REGOP && optype1 == REGOP 1704: && REGNO (op0) == REGNO (latehalf[1])) 1705: { 1706: /* Do that word. */ 1707: output_asm_insn (singlemove_string (latehalf), latehalf); 1708: /* Do low-numbered word. */ 1709: return singlemove_string (operands); 1710: } 1711: /* Loading into a register which overlaps a register used in the address. */ 1712: else if (optype0 == REGOP && optype1 != REGOP 1713: && reg_overlap_mentioned_p (op0, op1)) 1714: { 1.1.1.2 root 1715: /* If both halves of dest are used in the src memory address, 1716: add the two regs and put them in the low reg (op0). 1717: Then it works to load latehalf first. */ 1718: if (reg_mentioned_p (op0, XEXP (op1, 0)) 1719: && reg_mentioned_p (latehalf[0], XEXP (op1, 0))) 1720: { 1721: rtx xops[2]; 1722: xops[0] = latehalf[0]; 1723: xops[1] = op0; 1724: output_asm_insn ("add %1,%0,%1", xops); 1725: operands[1] = gen_rtx (MEM, DImode, op0); 1726: latehalf[1] = adj_offsettable_operand (operands[1], 4); 1727: addreg1 = 0; 1728: highest_first = 1; 1729: } 1730: /* Only one register in the dest is used in the src memory address, 1731: and this is the first register of the dest, so we want to do 1732: the late half first here also. */ 1733: else if (! reg_mentioned_p (latehalf[0], XEXP (op1, 0))) 1734: highest_first = 1; 1735: /* Only one register in the dest is used in the src memory address, 1736: and this is the second register of the dest, so we want to do 1737: the late half last. If addreg1 is set, and addreg1 is the same 1738: register as latehalf, then we must suppress the trailing decrement, 1739: because it would clobber the value just loaded. */ 1740: else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0])) 1741: no_addreg1_decrement = 1; 1.1 root 1742: } 1743: 1.1.1.2 root 1744: /* Normal case: do the two words, low-numbered first. 1745: Overlap case (highest_first set): do high-numbered word first. */ 1.1 root 1746: 1.1.1.2 root 1747: if (! highest_first) 1748: output_asm_insn (singlemove_string (operands), operands); 1.1 root 1749: 1750: /* Make any unoffsettable addresses point at high-numbered word. */ 1751: if (addreg0) 1752: output_asm_insn ("add %0,0x4,%0", &addreg0); 1753: if (addreg1) 1754: output_asm_insn ("add %0,0x4,%0", &addreg1); 1755: 1756: /* Do that word. */ 1757: output_asm_insn (singlemove_string (latehalf), latehalf); 1758: 1759: /* Undo the adds we just did. */ 1760: if (addreg0) 1761: output_asm_insn ("add %0,-0x4,%0", &addreg0); 1.1.1.2 root 1762: if (addreg1 && ! no_addreg1_decrement) 1.1 root 1763: output_asm_insn ("add %0,-0x4,%0", &addreg1); 1764: 1.1.1.2 root 1765: if (highest_first) 1766: output_asm_insn (singlemove_string (operands), operands); 1767: 1.1 root 1768: return ""; 1769: } 1770: 1771: /* Output assembler code to perform a quadword move insn 1772: with operands OPERANDS. This is very similar to the preceding 1773: output_move_double function. */ 1774: 1775: char * 1776: output_move_quad (operands) 1777: rtx *operands; 1778: { 1779: register rtx op0 = operands[0]; 1780: register rtx op1 = operands[1]; 1781: register enum optype optype0; 1782: register enum optype optype1; 1783: rtx wordpart[4][2]; 1784: rtx addreg0 = 0; 1785: rtx addreg1 = 0; 1786: 1787: /* First classify both operands. */ 1788: 1789: if (REG_P (op0)) 1790: optype0 = REGOP; 1791: else if (offsettable_memref_p (op0)) 1792: optype0 = OFFSOP; 1793: else if (GET_CODE (op0) == MEM) 1794: optype0 = MEMOP; 1795: else 1796: optype0 = RNDOP; 1797: 1798: if (REG_P (op1)) 1799: optype1 = REGOP; 1800: else if (CONSTANT_P (op1)) 1801: optype1 = CNSTOP; 1802: else if (offsettable_memref_p (op1)) 1803: optype1 = OFFSOP; 1804: else if (GET_CODE (op1) == MEM) 1805: optype1 = MEMOP; 1806: else 1807: optype1 = RNDOP; 1808: 1809: /* Check for the cases that the operand constraints are not 1810: supposed to allow to happen. Abort if we get one, 1811: because generating code for these cases is painful. */ 1812: 1813: if (optype0 == RNDOP || optype1 == RNDOP 1814: || (optype0 == MEM && optype1 == MEM)) 1815: abort (); 1816: 1817: /* If an operand is an unoffsettable memory ref, find a register 1818: we can increment temporarily to make it refer to the later words. */ 1819: 1820: if (optype0 == MEMOP) 1821: addreg0 = find_addr_reg (XEXP (op0, 0)); 1822: 1823: if (optype1 == MEMOP) 1824: addreg1 = find_addr_reg (XEXP (op1, 0)); 1825: 1826: /* Ok, we can do one word at a time. 1827: Set up in wordpart the operands to use for each word of the arguments. */ 1828: 1829: if (optype0 == REGOP) 1830: { 1831: wordpart[0][0] = gen_rtx (REG, SImode, REGNO (op0) + 0); 1832: wordpart[1][0] = gen_rtx (REG, SImode, REGNO (op0) + 1); 1833: wordpart[2][0] = gen_rtx (REG, SImode, REGNO (op0) + 2); 1834: wordpart[3][0] = gen_rtx (REG, SImode, REGNO (op0) + 3); 1835: } 1836: else if (optype0 == OFFSOP) 1837: { 1838: wordpart[0][0] = adj_offsettable_operand (op0, 0); 1839: wordpart[1][0] = adj_offsettable_operand (op0, 4); 1840: wordpart[2][0] = adj_offsettable_operand (op0, 8); 1841: wordpart[3][0] = adj_offsettable_operand (op0, 12); 1842: } 1843: else 1844: { 1845: wordpart[0][0] = op0; 1846: wordpart[1][0] = op0; 1847: wordpart[2][0] = op0; 1848: wordpart[3][0] = op0; 1849: } 1850: 1851: if (optype1 == REGOP) 1852: { 1853: wordpart[0][1] = gen_rtx (REG, SImode, REGNO (op1) + 0); 1854: wordpart[1][1] = gen_rtx (REG, SImode, REGNO (op1) + 1); 1855: wordpart[2][1] = gen_rtx (REG, SImode, REGNO (op1) + 2); 1856: wordpart[3][1] = gen_rtx (REG, SImode, REGNO (op1) + 3); 1857: } 1858: else if (optype1 == OFFSOP) 1859: { 1860: wordpart[0][1] = adj_offsettable_operand (op1, 0); 1861: wordpart[1][1] = adj_offsettable_operand (op1, 4); 1862: wordpart[2][1] = adj_offsettable_operand (op1, 8); 1863: wordpart[3][1] = adj_offsettable_operand (op1, 12); 1864: } 1865: else if (optype1 == CNSTOP) 1866: { 1.1.1.2 root 1867: REAL_VALUE_TYPE r; 1868: long l[4]; 1869: 1870: /* This only works for TFmode floating point constants. */ 1871: if (GET_CODE (op1) != CONST_DOUBLE || GET_MODE (op1) != TFmode) 1872: abort (); 1873: 1874: REAL_VALUE_FROM_CONST_DOUBLE (r, op1); 1875: REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); 1876: 1877: wordpart[0][1] = GEN_INT (l[0]); 1878: wordpart[1][1] = GEN_INT (l[1]); 1879: wordpart[2][1] = GEN_INT (l[2]); 1880: wordpart[3][1] = GEN_INT (l[3]); 1.1 root 1881: } 1882: else 1883: { 1884: wordpart[0][1] = op1; 1885: wordpart[1][1] = op1; 1886: wordpart[2][1] = op1; 1887: wordpart[3][1] = op1; 1888: } 1889: 1890: /* Easy case: try moving the quad as two pairs. Check for moving between 1.1.1.3 root 1891: an even/odd register pair and a memory location. 1892: Also handle new v9 fp regs here. */ 1.1 root 1893: /* ??? Should also handle the case of non-offsettable addresses here. 1894: We can at least do the first pair as a ldd/std, and then do the third 1895: and fourth words individually. */ 1896: if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0) 1897: || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0)) 1898: { 1.1.1.3 root 1899: rtx mem, reg; 1.1 root 1900: 1901: if (optype0 == REGOP) 1.1.1.3 root 1902: mem = op1, reg = op0; 1.1 root 1903: else 1.1.1.3 root 1904: mem = op0, reg = op1; 1.1 root 1905: 1.1.1.3 root 1906: if (mem_aligned_8 (mem) 1907: /* If this is a floating point register higher than %f31, 1908: then we *must* use an aligned load, since `ld' will not accept 1909: the register number. */ 1910: || (TARGET_V9 && REGNO (reg) >= 64)) 1.1 root 1911: { 1.1.1.3 root 1912: if (TARGET_V9 && FP_REG_P (reg)) 1913: { 1914: if ((REGNO (reg) & 3) != 0) 1915: abort (); 1916: return (mem == op1 ? "ldq %1,%0" : "stq %1,%0"); 1917: } 1.1 root 1918: operands[2] = adj_offsettable_operand (mem, 8); 1919: if (mem == op1) 1.1.1.3 root 1920: return TARGET_V9 ? "ldx %1,%0;ldx %2,%R0" : "ldd %1,%0;ldd %2,%S0"; 1.1 root 1921: else 1.1.1.3 root 1922: return TARGET_V9 ? "stx %1,%0;stx %R1,%2" : "std %1,%0;std %S1,%2"; 1.1 root 1923: } 1924: } 1925: 1926: /* If the first move would clobber the source of the second one, 1927: do them in the other order. */ 1928: 1929: /* Overlapping registers. */ 1930: if (optype0 == REGOP && optype1 == REGOP 1931: && (REGNO (op0) == REGNO (wordpart[1][3]) 1932: || REGNO (op0) == REGNO (wordpart[1][2]) 1933: || REGNO (op0) == REGNO (wordpart[1][1]))) 1934: { 1935: /* Do fourth word. */ 1936: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); 1937: /* Do the third word. */ 1938: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); 1939: /* Do the second word. */ 1940: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); 1941: /* Do lowest-numbered word. */ 1942: return singlemove_string (wordpart[0]); 1943: } 1944: /* Loading into a register which overlaps a register used in the address. */ 1945: if (optype0 == REGOP && optype1 != REGOP 1946: && reg_overlap_mentioned_p (op0, op1)) 1947: { 1948: /* ??? Not implemented yet. This is a bit complicated, because we 1949: must load which ever part overlaps the address last. If the address 1950: is a double-reg address, then there are two parts which need to 1951: be done last, which is impossible. We would need a scratch register 1952: in that case. */ 1953: abort (); 1954: } 1955: 1.1.1.4 ! root 1956: /* Normal case: move the four words in lowest to highest address order. */ 1.1 root 1957: 1958: output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]); 1959: 1960: /* Make any unoffsettable addresses point at the second word. */ 1961: if (addreg0) 1962: output_asm_insn ("add %0,0x4,%0", &addreg0); 1963: if (addreg1) 1964: output_asm_insn ("add %0,0x4,%0", &addreg1); 1965: 1966: /* Do the second word. */ 1967: output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); 1968: 1969: /* Make any unoffsettable addresses point at the third word. */ 1970: if (addreg0) 1971: output_asm_insn ("add %0,0x4,%0", &addreg0); 1972: if (addreg1) 1973: output_asm_insn ("add %0,0x4,%0", &addreg1); 1974: 1975: /* Do the third word. */ 1976: output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); 1977: 1978: /* Make any unoffsettable addresses point at the fourth word. */ 1979: if (addreg0) 1980: output_asm_insn ("add %0,0x4,%0", &addreg0); 1981: if (addreg1) 1982: output_asm_insn ("add %0,0x4,%0", &addreg1); 1983: 1984: /* Do the fourth word. */ 1985: output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); 1986: 1987: /* Undo the adds we just did. */ 1988: if (addreg0) 1989: output_asm_insn ("add %0,-0xc,%0", &addreg0); 1990: if (addreg1) 1991: output_asm_insn ("add %0,-0xc,%0", &addreg1); 1992: 1993: return ""; 1994: } 1995: 1996: /* Output assembler code to perform a doubleword move insn with operands 1997: OPERANDS, one of which must be a floating point register. */ 1998: 1999: char * 2000: output_fp_move_double (operands) 2001: rtx *operands; 2002: { 2003: if (FP_REG_P (operands[0])) 2004: { 2005: if (FP_REG_P (operands[1])) 1.1.1.3 root 2006: { 2007: if (TARGET_V9) 2008: return "fmovd %1,%0"; 2009: else 2010: return "fmovs %1,%0\n\tfmovs %R1,%R0"; 2011: } 1.1 root 2012: else if (GET_CODE (operands[1]) == REG) 2013: abort (); 2014: else 2015: return output_move_double (operands); 2016: } 2017: else if (FP_REG_P (operands[1])) 2018: { 2019: if (GET_CODE (operands[0]) == REG) 2020: abort (); 2021: else 2022: return output_move_double (operands); 2023: } 2024: else abort (); 2025: } 2026: 2027: /* Output assembler code to perform a quadword move insn with operands 2028: OPERANDS, one of which must be a floating point register. */ 2029: 2030: char * 2031: output_fp_move_quad (operands) 2032: rtx *operands; 2033: { 2034: register rtx op0 = operands[0]; 2035: register rtx op1 = operands[1]; 2036: 2037: if (FP_REG_P (op0)) 2038: { 2039: if (FP_REG_P (op1)) 1.1.1.3 root 2040: { 2041: if (TARGET_V9) 2042: return "fmovq %1,%0"; 2043: else 2044: return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0"; 2045: } 1.1 root 2046: else if (GET_CODE (op1) == REG) 2047: abort (); 2048: else 2049: return output_move_quad (operands); 2050: } 2051: else if (FP_REG_P (op1)) 2052: { 2053: if (GET_CODE (op0) == REG) 2054: abort (); 2055: else 2056: return output_move_quad (operands); 2057: } 2058: else 2059: abort (); 2060: } 2061: 2062: /* Return a REG that occurs in ADDR with coefficient 1. 2063: ADDR can be effectively incremented by incrementing REG. */ 2064: 2065: static rtx 2066: find_addr_reg (addr) 2067: rtx addr; 2068: { 2069: while (GET_CODE (addr) == PLUS) 2070: { 2071: /* We absolutely can not fudge the frame pointer here, because the 2072: frame pointer must always be 8 byte aligned. It also confuses 2073: debuggers. */ 2074: if (GET_CODE (XEXP (addr, 0)) == REG 2075: && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM) 2076: addr = XEXP (addr, 0); 2077: else if (GET_CODE (XEXP (addr, 1)) == REG 2078: && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM) 2079: addr = XEXP (addr, 1); 2080: else if (CONSTANT_P (XEXP (addr, 0))) 2081: addr = XEXP (addr, 1); 2082: else if (CONSTANT_P (XEXP (addr, 1))) 2083: addr = XEXP (addr, 0); 2084: else 2085: abort (); 2086: } 2087: if (GET_CODE (addr) == REG) 2088: return addr; 2089: abort (); 2090: } 2091: 1.1.1.2 root 2092: #if 0 /* not currently used */ 2093: 1.1 root 2094: void 2095: output_sized_memop (opname, mode, signedp) 2096: char *opname; 2097: enum machine_mode mode; 2098: int signedp; 2099: { 2100: static char *ld_size_suffix_u[] = { "ub", "uh", "", "?", "d" }; 2101: static char *ld_size_suffix_s[] = { "sb", "sh", "", "?", "d" }; 2102: static char *st_size_suffix[] = { "b", "h", "", "?", "d" }; 2103: char **opnametab, *modename; 2104: 2105: if (opname[0] == 'l') 2106: if (signedp) 2107: opnametab = ld_size_suffix_s; 2108: else 2109: opnametab = ld_size_suffix_u; 2110: else 2111: opnametab = st_size_suffix; 2112: modename = opnametab[GET_MODE_SIZE (mode) >> 1]; 2113: 2114: fprintf (asm_out_file, "\t%s%s", opname, modename); 2115: } 2116: 2117: void 2118: output_move_with_extension (operands) 2119: rtx *operands; 2120: { 2121: if (GET_MODE (operands[2]) == HImode) 2122: output_asm_insn ("sll %2,0x10,%0", operands); 2123: else if (GET_MODE (operands[2]) == QImode) 2124: output_asm_insn ("sll %2,0x18,%0", operands); 2125: else 2126: abort (); 2127: } 1.1.1.2 root 2128: #endif /* not currently used */ 1.1 root 2129: 2130: #if 0 2131: /* ??? These are only used by the movstrsi pattern, but we get better code 2132: in general without that, because emit_block_move can do just as good a 2133: job as this function does when alignment and size are known. When they 2134: aren't known, a call to strcpy may be faster anyways, because it is 2135: likely to be carefully crafted assembly language code, and below we just 2136: do a byte-wise copy. 2137: 2138: Also, emit_block_move expands into multiple read/write RTL insns, which 2139: can then be optimized, whereas our movstrsi pattern can not be optimized 2140: at all. */ 2141: 2142: /* Load the address specified by OPERANDS[3] into the register 2143: specified by OPERANDS[0]. 2144: 2145: OPERANDS[3] may be the result of a sum, hence it could either be: 2146: 2147: (1) CONST 2148: (2) REG 2149: (2) REG + CONST_INT 2150: (3) REG + REG + CONST_INT 2151: (4) REG + REG (special case of 3). 2152: 2153: Note that (3) is not a legitimate address. 2154: All cases are handled here. */ 2155: 2156: void 2157: output_load_address (operands) 2158: rtx *operands; 2159: { 2160: rtx base, offset; 2161: 2162: if (CONSTANT_P (operands[3])) 2163: { 2164: output_asm_insn ("set %3,%0", operands); 2165: return; 2166: } 2167: 2168: if (REG_P (operands[3])) 2169: { 2170: if (REGNO (operands[0]) != REGNO (operands[3])) 2171: output_asm_insn ("mov %3,%0", operands); 2172: return; 2173: } 2174: 2175: if (GET_CODE (operands[3]) != PLUS) 2176: abort (); 2177: 2178: base = XEXP (operands[3], 0); 2179: offset = XEXP (operands[3], 1); 2180: 2181: if (GET_CODE (base) == CONST_INT) 2182: { 2183: rtx tmp = base; 2184: base = offset; 2185: offset = tmp; 2186: } 2187: 2188: if (GET_CODE (offset) != CONST_INT) 2189: { 2190: /* Operand is (PLUS (REG) (REG)). */ 2191: base = operands[3]; 2192: offset = const0_rtx; 2193: } 2194: 2195: if (REG_P (base)) 2196: { 2197: operands[6] = base; 2198: operands[7] = offset; 2199: if (SMALL_INT (offset)) 2200: output_asm_insn ("add %6,%7,%0", operands); 2201: else 2202: output_asm_insn ("set %7,%0\n\tadd %0,%6,%0", operands); 2203: } 2204: else if (GET_CODE (base) == PLUS) 2205: { 2206: operands[6] = XEXP (base, 0); 2207: operands[7] = XEXP (base, 1); 2208: operands[8] = offset; 2209: 2210: if (SMALL_INT (offset)) 2211: output_asm_insn ("add %6,%7,%0\n\tadd %0,%8,%0", operands); 2212: else 2213: output_asm_insn ("set %8,%0\n\tadd %0,%6,%0\n\tadd %0,%7,%0", operands); 2214: } 2215: else 2216: abort (); 2217: } 2218: 2219: /* Output code to place a size count SIZE in register REG. 2220: ALIGN is the size of the unit of transfer. 2221: 2222: Because block moves are pipelined, we don't include the 2223: first element in the transfer of SIZE to REG. */ 2224: 2225: static void 2226: output_size_for_block_move (size, reg, align) 2227: rtx size, reg; 2228: rtx align; 2229: { 2230: rtx xoperands[3]; 2231: 2232: xoperands[0] = reg; 2233: xoperands[1] = size; 2234: xoperands[2] = align; 2235: if (GET_CODE (size) == REG) 2236: output_asm_insn ("sub %1,%2,%0", xoperands); 2237: else 2238: { 2239: xoperands[1] 2240: = gen_rtx (CONST_INT, VOIDmode, INTVAL (size) - INTVAL (align)); 2241: output_asm_insn ("set %1,%0", xoperands); 2242: } 2243: } 2244: 2245: /* Emit code to perform a block move. 2246: 2247: OPERANDS[0] is the destination. 2248: OPERANDS[1] is the source. 2249: OPERANDS[2] is the size. 2250: OPERANDS[3] is the alignment safe to use. 2251: OPERANDS[4] is a register we can safely clobber as a temp. */ 2252: 2253: char * 2254: output_block_move (operands) 2255: rtx *operands; 2256: { 2257: /* A vector for our computed operands. Note that load_output_address 2258: makes use of (and can clobber) up to the 8th element of this vector. */ 2259: rtx xoperands[10]; 2260: rtx zoperands[10]; 2261: static int movstrsi_label = 0; 2262: int i; 2263: rtx temp1 = operands[4]; 2264: rtx sizertx = operands[2]; 2265: rtx alignrtx = operands[3]; 2266: int align = INTVAL (alignrtx); 2267: char label3[30], label5[30]; 2268: 2269: xoperands[0] = operands[0]; 2270: xoperands[1] = operands[1]; 2271: xoperands[2] = temp1; 2272: 2273: /* We can't move more than this many bytes at a time because we have only 2274: one register, %g1, to move them through. */ 2275: if (align > UNITS_PER_WORD) 2276: { 2277: align = UNITS_PER_WORD; 2278: alignrtx = gen_rtx (CONST_INT, VOIDmode, UNITS_PER_WORD); 2279: } 2280: 2281: /* We consider 8 ld/st pairs, for a total of 16 inline insns to be 2282: reasonable here. (Actually will emit a maximum of 18 inline insns for 2283: the case of size == 31 and align == 4). */ 2284: 2285: if (GET_CODE (sizertx) == CONST_INT && (INTVAL (sizertx) / align) <= 8 2286: && memory_address_p (QImode, plus_constant_for_output (xoperands[0], 2287: INTVAL (sizertx))) 2288: && memory_address_p (QImode, plus_constant_for_output (xoperands[1], 2289: INTVAL (sizertx)))) 2290: { 2291: int size = INTVAL (sizertx); 2292: int offset = 0; 2293: 2294: /* We will store different integers into this particular RTX. */ 2295: xoperands[2] = rtx_alloc (CONST_INT); 2296: PUT_MODE (xoperands[2], VOIDmode); 2297: 2298: /* This case is currently not handled. Abort instead of generating 2299: bad code. */ 1.1.1.3 root 2300: if (align > UNITS_PER_WORD) 1.1 root 2301: abort (); 2302: 1.1.1.3 root 2303: if (TARGET_V9 && align >= 8) 2304: { 2305: for (i = (size >> 3) - 1; i >= 0; i--) 2306: { 2307: INTVAL (xoperands[2]) = (i << 3) + offset; 2308: output_asm_insn ("ldx [%a1+%2],%%g1\n\tstx %%g1,[%a0+%2]", 2309: xoperands); 2310: } 2311: offset += (size & ~0x7); 2312: size = size & 0x7; 2313: if (size == 0) 2314: return ""; 2315: } 2316: 1.1 root 2317: if (align >= 4) 2318: { 2319: for (i = (size >> 2) - 1; i >= 0; i--) 2320: { 2321: INTVAL (xoperands[2]) = (i << 2) + offset; 2322: output_asm_insn ("ld [%a1+%2],%%g1\n\tst %%g1,[%a0+%2]", 2323: xoperands); 2324: } 2325: offset += (size & ~0x3); 2326: size = size & 0x3; 2327: if (size == 0) 2328: return ""; 2329: } 2330: 2331: if (align >= 2) 2332: { 2333: for (i = (size >> 1) - 1; i >= 0; i--) 2334: { 2335: INTVAL (xoperands[2]) = (i << 1) + offset; 2336: output_asm_insn ("lduh [%a1+%2],%%g1\n\tsth %%g1,[%a0+%2]", 2337: xoperands); 2338: } 2339: offset += (size & ~0x1); 2340: size = size & 0x1; 2341: if (size == 0) 2342: return ""; 2343: } 2344: 2345: if (align >= 1) 2346: { 2347: for (i = size - 1; i >= 0; i--) 2348: { 2349: INTVAL (xoperands[2]) = i + offset; 2350: output_asm_insn ("ldub [%a1+%2],%%g1\n\tstb %%g1,[%a0+%2]", 2351: xoperands); 2352: } 2353: return ""; 2354: } 2355: 2356: /* We should never reach here. */ 2357: abort (); 2358: } 2359: 2360: /* If the size isn't known to be a multiple of the alignment, 2361: we have to do it in smaller pieces. If we could determine that 2362: the size was a multiple of 2 (or whatever), we could be smarter 2363: about this. */ 2364: if (GET_CODE (sizertx) != CONST_INT) 2365: align = 1; 2366: else 2367: { 2368: int size = INTVAL (sizertx); 2369: while (size % align) 2370: align >>= 1; 2371: } 2372: 2373: if (align != INTVAL (alignrtx)) 2374: alignrtx = gen_rtx (CONST_INT, VOIDmode, align); 2375: 2376: xoperands[3] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); 2377: xoperands[4] = gen_rtx (CONST_INT, VOIDmode, align); 2378: xoperands[5] = gen_rtx (CONST_INT, VOIDmode, movstrsi_label++); 2379: 2380: ASM_GENERATE_INTERNAL_LABEL (label3, "Lm", INTVAL (xoperands[3])); 2381: ASM_GENERATE_INTERNAL_LABEL (label5, "Lm", INTVAL (xoperands[5])); 2382: 2383: /* This is the size of the transfer. Emit code to decrement the size 2384: value by ALIGN, and store the result in the temp1 register. */ 2385: output_size_for_block_move (sizertx, temp1, alignrtx); 2386: 2387: /* Must handle the case when the size is zero or negative, so the first thing 2388: we do is compare the size against zero, and only copy bytes if it is 2389: zero or greater. Note that we have already subtracted off the alignment 2390: once, so we must copy 1 alignment worth of bytes if the size is zero 2391: here. 2392: 2393: The SUN assembler complains about labels in branch delay slots, so we 2394: do this before outputting the load address, so that there will always 2395: be a harmless insn between the branch here and the next label emitted 2396: below. */ 2397: 2398: { 2399: char pattern[100]; 2400: 2401: sprintf (pattern, "cmp %%2,0\n\tbl %s", &label5[1]); 2402: output_asm_insn (pattern, xoperands); 2403: } 2404: 2405: zoperands[0] = operands[0]; 2406: zoperands[3] = plus_constant_for_output (operands[0], align); 2407: output_load_address (zoperands); 2408: 2409: /* ??? This might be much faster if the loops below were preconditioned 2410: and unrolled. 2411: 2412: That is, at run time, copy enough bytes one at a time to ensure that the 2413: target and source addresses are aligned to the the largest possible 2414: alignment. Then use a preconditioned unrolled loop to copy say 16 2415: bytes at a time. Then copy bytes one at a time until finish the rest. */ 2416: 2417: /* Output the first label separately, so that it is spaced properly. */ 2418: 2419: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "Lm", INTVAL (xoperands[3])); 2420: 2421: { 2422: char pattern[200]; 1.1.1.3 root 2423: register char *ld_suffix = ((align == 1) ? "ub" : (align == 2) ? "uh" 2424: : (align == 8 && TARGET_V9) ? "x" : ""); 2425: register char *st_suffix = ((align == 1) ? "b" : (align == 2) ? "h" 2426: : (align == 8 && TARGET_V9) ? "x" : ""); 1.1 root 2427: 2428: 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]); 2429: output_asm_insn (pattern, xoperands); 2430: } 2431: 2432: return ""; 2433: } 2434: #endif 2435: 2436: /* Output reasonable peephole for set-on-condition-code insns. 2437: Note that these insns assume a particular way of defining 2438: labels. Therefore, *both* sparc.h and this function must 2439: be changed if a new syntax is needed. */ 2440: 2441: char * 2442: output_scc_insn (operands, insn) 2443: rtx operands[]; 2444: rtx insn; 2445: { 2446: static char string[100]; 2447: rtx label = 0, next = insn; 2448: int need_label = 0; 2449: 2450: /* Try doing a jump optimization which jump.c can't do for us 2451: because we did not expose that setcc works by using branches. 2452: 2453: If this scc insn is followed by an unconditional branch, then have 2454: the jump insn emitted here jump to that location, instead of to 2455: the end of the scc sequence as usual. */ 2456: 2457: do 2458: { 2459: if (GET_CODE (next) == CODE_LABEL) 2460: label = next; 2461: next = NEXT_INSN (next); 2462: if (next == 0) 2463: break; 2464: } 2465: while (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL); 2466: 2467: /* If we are in a sequence, and the following insn is a sequence also, 2468: then just following the current insn's next field will take us to the 2469: first insn of the next sequence, which is the wrong place. We don't 2470: want to optimize with a branch that has had its delay slot filled. 2471: Avoid this by verifying that NEXT_INSN (PREV_INSN (next)) == next 2472: which fails only if NEXT is such a branch. */ 2473: 2474: if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next) 2475: && (! final_sequence || NEXT_INSN (PREV_INSN (next)) == next)) 2476: label = JUMP_LABEL (next); 2477: /* If not optimizing, jump label fields are not set. To be safe, always 2478: check here to whether label is still zero. */ 2479: if (label == 0) 2480: { 2481: label = gen_label_rtx (); 2482: need_label = 1; 2483: } 2484: 2485: LABEL_NUSES (label) += 1; 2486: 2487: operands[2] = label; 2488: 2489: /* If we are in a delay slot, assume it is the delay slot of an fpcc 2490: insn since our type isn't allowed anywhere else. */ 2491: 2492: /* ??? Fpcc instructions no longer have delay slots, so this code is 2493: probably obsolete. */ 2494: 2495: /* The fastest way to emit code for this is an annulled branch followed 2496: by two move insns. This will take two cycles if the branch is taken, 2497: and three cycles if the branch is not taken. 2498: 2499: However, if we are in the delay slot of another branch, this won't work, 2500: because we can't put a branch in the delay slot of another branch. 2501: The above sequence would effectively take 3 or 4 cycles respectively 2502: since a no op would have be inserted between the two branches. 2503: In this case, we want to emit a move, annulled branch, and then the 2504: second move. This sequence always takes 3 cycles, and hence is faster 2505: when we are in a branch delay slot. */ 2506: 2507: if (final_sequence) 2508: { 2509: strcpy (string, "mov 0,%0\n\t"); 1.1.1.3 root 2510: strcat (string, output_cbranch (operands[1], 0, 2, 0, 1, 0)); 1.1 root 2511: strcat (string, "\n\tmov 1,%0"); 2512: } 2513: else 2514: { 1.1.1.3 root 2515: strcpy (string, output_cbranch (operands[1], 0, 2, 0, 1, 0)); 1.1 root 2516: strcat (string, "\n\tmov 1,%0\n\tmov 0,%0"); 2517: } 2518: 2519: if (need_label) 2520: strcat (string, "\n%l2:"); 2521: 2522: return string; 2523: } 2524: 1.1.1.3 root 2525: /* Vectors to keep interesting information about registers where it can easily 2526: be got. We use to use the actual mode value as the bit number, but there 2527: are more than 32 modes now. Instead we use two tables: one indexed by 2528: hard register number, and one indexed by mode. */ 2529: 2530: /* The purpose of sparc_mode_class is to shrink the range of modes so that 2531: they all fit (as bit numbers) in a 32 bit word (again). Each real mode is 2532: mapped into one sparc_mode_class mode. */ 2533: 2534: enum sparc_mode_class { 2535: C_MODE, CCFP_MODE, 2536: S_MODE, D_MODE, T_MODE, O_MODE, 2537: SF_MODE, DF_MODE, TF_MODE, OF_MODE 2538: }; 1.1 root 2539: 2540: /* Modes for condition codes. */ 1.1.1.3 root 2541: #define C_MODES ((1 << (int) C_MODE) | (1 << (int) CCFP_MODE)) 2542: #define CCFP_MODES (1 << (int) CCFP_MODE) 2543: 2544: /* Modes for single-word and smaller quantities. */ 2545: #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) 2546: 2547: /* Modes for double-word and smaller quantities. */ 2548: #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) 2549: 2550: /* Modes for quad-word and smaller quantities. */ 2551: #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE)) 1.1 root 2552: 2553: /* Modes for single-float quantities. We must allow any single word or 2554: smaller quantity. This is because the fix/float conversion instructions 2555: take integer inputs/outputs from the float registers. */ 2556: #define SF_MODES (S_MODES) 2557: 1.1.1.3 root 2558: /* Modes for double-float and smaller quantities. */ 2559: #define DF_MODES (S_MODES | D_MODES) 1.1 root 2560: 1.1.1.3 root 2561: /* ??? Sparc64 fp regs cannot hold DImode values. */ 2562: #define DF_MODES64 (SF_MODES | DF_MODE /* | D_MODE*/) 1.1 root 2563: 1.1.1.3 root 2564: /* Modes for double-float only quantities. */ 2565: /* ??? Sparc64 fp regs cannot hold DImode values. */ 2566: #define DF_ONLY_MODES ((1 << (int) DF_MODE) /*| (1 << (int) D_MODE)*/) 2567: 2568: /* Modes for double-float and larger quantities. */ 2569: #define DF_UP_MODES (DF_ONLY_MODES | TF_ONLY_MODES) 2570: 2571: /* Modes for quad-float only quantities. */ 2572: #define TF_ONLY_MODES (1 << (int) TF_MODE) 2573: 2574: /* Modes for quad-float and smaller quantities. */ 2575: #define TF_MODES (DF_MODES | TF_ONLY_MODES) 2576: 2577: /* ??? Sparc64 fp regs cannot hold DImode values. */ 2578: #define TF_MODES64 (DF_MODES64 | TF_ONLY_MODES) 2579: 2580: /* Value is 1 if register/mode pair is acceptable on sparc. 2581: The funny mixture of D and T modes is because integer operations 1.1 root 2582: do not specially operate on tetra quantities, so non-quad-aligned 2583: registers can hold quadword quantities (except %o4 and %i4 because 2584: they cross fixed registers. */ 2585: 1.1.1.3 root 2586: /* This points to either the 32 bit or the 64 bit version. */ 2587: int *hard_regno_mode_classes; 2588: 2589: static int hard_32bit_mode_classes[] = { 1.1 root 2590: C_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, 2591: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, 2592: T_MODES, S_MODES, T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, 2593: T_MODES, S_MODES, T_MODES, S_MODES, D_MODES, S_MODES, D_MODES, S_MODES, 2594: 2595: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2596: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2597: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 1.1.1.3 root 2598: TF_MODES, SF_MODES, DF_MODES, SF_MODES, TF_MODES, SF_MODES, DF_MODES, SF_MODES, 2599: }; 2600: 2601: static int hard_64bit_mode_classes[] = { 2602: C_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, 2603: T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, 2604: T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, 2605: T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, T_MODES, D_MODES, 2606: 2607: TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, 2608: TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, 2609: TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, 2610: TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, TF_MODES64, SF_MODES, DF_MODES64, SF_MODES, 2611: 2612: /* The remaining registers do not exist on a non-v9 sparc machine. 2613: FP regs f32 to f63. Only the even numbered registers actually exist, 2614: and none can hold SFmode/SImode values. */ 2615: DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, 2616: DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, 2617: DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, 2618: DF_UP_MODES, 0, DF_ONLY_MODES, 0, DF_UP_MODES, 0, DF_ONLY_MODES, 0, 2619: 2620: /* %fcc[0123] */ 2621: CCFP_MODE, CCFP_MODE, CCFP_MODE, CCFP_MODE 2622: }; 2623: 2624: int sparc_mode_class [NUM_MACHINE_MODES]; 2625: 2626: static void 2627: sparc_init_modes () 2628: { 2629: int i; 2630: 2631: sparc_arch_type = TARGET_V9 ? ARCH_64BIT : ARCH_32BIT; 2632: 2633: for (i = 0; i < NUM_MACHINE_MODES; i++) 2634: { 2635: switch (GET_MODE_CLASS (i)) 2636: { 2637: case MODE_INT: 2638: case MODE_PARTIAL_INT: 2639: case MODE_COMPLEX_INT: 2640: if (GET_MODE_SIZE (i) <= 4) 2641: sparc_mode_class[i] = 1 << (int) S_MODE; 2642: else if (GET_MODE_SIZE (i) == 8) 2643: sparc_mode_class[i] = 1 << (int) D_MODE; 2644: else if (GET_MODE_SIZE (i) == 16) 2645: sparc_mode_class[i] = 1 << (int) T_MODE; 2646: else if (GET_MODE_SIZE (i) == 32) 2647: sparc_mode_class[i] = 1 << (int) O_MODE; 2648: else 2649: sparc_mode_class[i] = 0; 2650: break; 2651: case MODE_FLOAT: 2652: case MODE_COMPLEX_FLOAT: 2653: if (GET_MODE_SIZE (i) <= 4) 2654: sparc_mode_class[i] = 1 << (int) SF_MODE; 2655: else if (GET_MODE_SIZE (i) == 8) 2656: sparc_mode_class[i] = 1 << (int) DF_MODE; 2657: else if (GET_MODE_SIZE (i) == 16) 2658: sparc_mode_class[i] = 1 << (int) TF_MODE; 2659: else if (GET_MODE_SIZE (i) == 32) 2660: sparc_mode_class[i] = 1 << (int) OF_MODE; 2661: else 2662: sparc_mode_class[i] = 0; 2663: break; 2664: case MODE_CC: 2665: default: 2666: /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so 2667: we must explicitly check for them here. */ 2668: if (i == (int) CCFPmode || i == (int) CCFPEmode) 2669: sparc_mode_class[i] = 1 << (int) CCFP_MODE; 2670: else if (i == (int) CCmode || i == (int) CC_NOOVmode 2671: #ifdef SPARCV9 2672: || i == (int) CCXmode 2673: || i == (int) CCX_NOOVmode 2674: #endif 2675: ) 2676: sparc_mode_class[i] = 1 << (int) C_MODE; 2677: else 2678: sparc_mode_class[i] = 0; 2679: break; 2680: } 2681: } 2682: 2683: if (TARGET_V9) 2684: hard_regno_mode_classes = hard_64bit_mode_classes; 2685: else 2686: hard_regno_mode_classes = hard_32bit_mode_classes; 2687: } 1.1 root 2688: 1.1.1.3 root 2689: /* Save non call used registers from LOW to HIGH at BASE+OFFSET. 2690: N_REGS is the number of 4-byte regs saved thus far. This applies even to 2691: v9 int regs as it simplifies the code. */ 2692: 1.1 root 2693: #ifdef __GNUC__ 1.1.1.3 root 2694: __inline__ 1.1 root 2695: #endif 2696: static int 1.1.1.3 root 2697: save_regs (file, low, high, base, offset, n_regs) 1.1 root 2698: FILE *file; 2699: int low, high; 2700: char *base; 2701: int offset; 1.1.1.3 root 2702: int n_regs; 1.1 root 2703: { 2704: int i; 2705: 1.1.1.3 root 2706: if (TARGET_V9 && high <= 32) 2707: { 2708: for (i = low; i < high; i++) 2709: { 2710: if (regs_ever_live[i] && ! call_used_regs[i]) 2711: fprintf (file, "\tstx %s,[%s+%d]\n", 2712: reg_names[i], base, offset + 4 * n_regs), 2713: n_regs += 2; 2714: } 2715: } 2716: else 1.1 root 2717: { 1.1.1.3 root 2718: for (i = low; i < high; i += 2) 2719: { 2720: if (regs_ever_live[i] && ! call_used_regs[i]) 2721: if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2722: fprintf (file, "\tstd %s,[%s+%d]\n", 2723: reg_names[i], base, offset + 4 * n_regs), 2724: n_regs += 2; 2725: else 2726: fprintf (file, "\tst %s,[%s+%d]\n", 2727: reg_names[i], base, offset + 4 * n_regs), 2728: n_regs += 2; 2729: else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2730: fprintf (file, "\tst %s,[%s+%d]\n", 2731: reg_names[i+1], base, offset + 4 * n_regs + 4), 2732: n_regs += 2; 2733: } 1.1 root 2734: } 1.1.1.3 root 2735: return n_regs; 1.1 root 2736: } 2737: 1.1.1.3 root 2738: /* Restore non call used registers from LOW to HIGH at BASE+OFFSET. 2739: 2740: N_REGS is the number of 4-byte regs saved thus far. This applies even to 2741: v9 int regs as it simplifies the code. */ 2742: 1.1 root 2743: #ifdef __GNUC__ 1.1.1.3 root 2744: __inline__ 1.1 root 2745: #endif 2746: static int 1.1.1.3 root 2747: restore_regs (file, low, high, base, offset, n_regs) 1.1 root 2748: FILE *file; 2749: int low, high; 2750: char *base; 2751: int offset; 1.1.1.3 root 2752: int n_regs; 1.1 root 2753: { 2754: int i; 2755: 1.1.1.3 root 2756: if (TARGET_V9 && high <= 32) 1.1 root 2757: { 1.1.1.3 root 2758: for (i = low; i < high; i++) 2759: { 2760: if (regs_ever_live[i] && ! call_used_regs[i]) 2761: fprintf (file, "\tldx [%s+%d], %s\n", 2762: base, offset + 4 * n_regs, reg_names[i]), 2763: n_regs += 2; 2764: } 1.1 root 2765: } 1.1.1.3 root 2766: else 2767: { 2768: for (i = low; i < high; i += 2) 2769: { 2770: if (regs_ever_live[i] && ! call_used_regs[i]) 2771: if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2772: fprintf (file, "\tldd [%s+%d], %s\n", 2773: base, offset + 4 * n_regs, reg_names[i]), 2774: n_regs += 2; 2775: else 2776: fprintf (file, "\tld [%s+%d],%s\n", 2777: base, offset + 4 * n_regs, reg_names[i]), 2778: n_regs += 2; 2779: else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) 2780: fprintf (file, "\tld [%s+%d],%s\n", 2781: base, offset + 4 * n_regs + 4, reg_names[i+1]), 2782: n_regs += 2; 2783: } 2784: } 2785: return n_regs; 1.1 root 2786: } 2787: 2788: /* Static variables we want to share between prologue and epilogue. */ 2789: 1.1.1.3 root 2790: /* Number of live general or floating point registers needed to be saved 2791: (as 4-byte quantities). This is only done if TARGET_EPILOGUE. */ 2792: static int num_gfregs; 2793: 2794: /* Compute the frame size required by the function. This function is called 2795: during the reload pass and also by output_function_prologue(). */ 1.1 root 2796: 2797: int 2798: compute_frame_size (size, leaf_function) 2799: int size; 2800: int leaf_function; 2801: { 1.1.1.3 root 2802: int n_regs = 0, i; 1.1 root 2803: int outgoing_args_size = (current_function_outgoing_args_size 1.1.1.3 root 2804: #ifndef SPARCV9 2805: + REG_PARM_STACK_SPACE (current_function_decl) 2806: #endif 2807: ); 1.1 root 2808: 1.1.1.3 root 2809: if (TARGET_EPILOGUE) 1.1 root 2810: { 1.1.1.3 root 2811: /* N_REGS is the number of 4-byte regs saved thus far. This applies 2812: even to v9 int regs to be consistent with save_regs/restore_regs. */ 2813: 2814: if (TARGET_V9) 2815: { 2816: for (i = 0; i < 8; i++) 2817: if (regs_ever_live[i] && ! call_used_regs[i]) 2818: n_regs += 2; 2819: } 2820: else 2821: { 2822: for (i = 0; i < 8; i += 2) 2823: if ((regs_ever_live[i] && ! call_used_regs[i]) 2824: || (regs_ever_live[i+1] && ! call_used_regs[i+1])) 2825: n_regs += 2; 2826: } 2827: 2828: for (i = 32; i < (TARGET_V9 ? 96 : 64); i += 2) 1.1 root 2829: if ((regs_ever_live[i] && ! call_used_regs[i]) 2830: || (regs_ever_live[i+1] && ! call_used_regs[i+1])) 1.1.1.3 root 2831: n_regs += 2; 1.1 root 2832: } 2833: 2834: /* Set up values for use in `function_epilogue'. */ 1.1.1.3 root 2835: num_gfregs = n_regs; 1.1 root 2836: 1.1.1.3 root 2837: if (leaf_function && n_regs == 0 2838: && size == 0 && current_function_outgoing_args_size == 0) 2839: { 2840: actual_fsize = apparent_fsize = 0; 2841: } 2842: else 2843: { 2844: /* We subtract STARTING_FRAME_OFFSET, remember it's negative. 2845: The stack bias (if any) is taken out to undo its effects. */ 2846: apparent_fsize = (size - STARTING_FRAME_OFFSET + SPARC_STACK_BIAS + 7) & -8; 2847: apparent_fsize += n_regs * 4; 2848: actual_fsize = apparent_fsize + ((outgoing_args_size + 7) & -8); 2849: } 1.1 root 2850: 2851: /* Make sure nothing can clobber our register windows. 2852: If a SAVE must be done, or there is a stack-local variable, 1.1.1.3 root 2853: the register window area must be allocated. 2854: ??? For v9 we need an additional 8 bytes of reserved space, apparently 2855: it's needed by v8 as well. */ 1.1 root 2856: if (leaf_function == 0 || size > 0) 1.1.1.3 root 2857: actual_fsize += (16 * UNITS_PER_WORD) + 8; 1.1 root 2858: 1.1.1.3 root 2859: return SPARC_STACK_ALIGN (actual_fsize); 2860: } 2861: 2862: /* Build a (32 bit) big number in a register. */ 2863: /* ??? We may be able to use the set macro here too. */ 2864: 2865: static void 2866: build_big_number (file, num, reg) 2867: FILE *file; 2868: int num; 2869: char *reg; 2870: { 2871: if (num >= 0 || ! TARGET_V9) 2872: { 2873: fprintf (file, "\tsethi %%hi(%d),%s\n", num, reg); 2874: if ((num & 0x3ff) != 0) 2875: fprintf (file, "\tor %s,%%lo(%d),%s\n", reg, num, reg); 2876: } 2877: else /* num < 0 && TARGET_V9 */ 2878: { 2879: /* Sethi does not sign extend, so we must use a little trickery 2880: to use it for negative numbers. Invert the constant before 2881: loading it in, then use xor immediate to invert the loaded bits 2882: (along with the upper 32 bits) to the desired constant. This 2883: works because the sethi and immediate fields overlap. */ 2884: int asize = num; 2885: int inv = ~asize; 2886: int low = -0x400 + (asize & 0x3FF); 2887: 2888: fprintf (file, "\tsethi %%hi(%d),%s\n\txor %s,%d,%s\n", 2889: inv, reg, reg, low, reg); 2890: } 1.1 root 2891: } 2892: 2893: /* Output code for the function prologue. */ 2894: 2895: void 2896: output_function_prologue (file, size, leaf_function) 2897: FILE *file; 2898: int size; 2899: int leaf_function; 2900: { 2901: /* Need to use actual_fsize, since we are also allocating 2902: space for our callee (and our own register save area). */ 2903: actual_fsize = compute_frame_size (size, leaf_function); 2904: 1.1.1.3 root 2905: if (leaf_function) 2906: { 2907: frame_base_name = "%sp"; 2908: frame_base_offset = actual_fsize + SPARC_STACK_BIAS; 2909: } 2910: else 2911: { 2912: frame_base_name = "%fp"; 2913: frame_base_offset = SPARC_STACK_BIAS; 2914: } 2915: 2916: /* This is only for the human reader. */ 1.1 root 2917: fprintf (file, "\t!#PROLOGUE# 0\n"); 1.1.1.3 root 2918: 1.1 root 2919: if (actual_fsize == 0) 2920: /* do nothing. */ ; 2921: else if (actual_fsize <= 4096) 2922: { 2923: if (! leaf_function) 2924: fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); 2925: else 2926: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize); 2927: } 2928: else if (actual_fsize <= 8192) 2929: { 2930: /* For frames in the range 4097..8192, we can use just two insns. */ 2931: if (! leaf_function) 2932: { 2933: fprintf (file, "\tsave %%sp,-4096,%%sp\n"); 2934: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); 2935: } 2936: else 2937: { 2938: fprintf (file, "\tadd %%sp,-4096,%%sp\n"); 2939: fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); 2940: } 2941: } 2942: else 2943: { 1.1.1.3 root 2944: build_big_number (file, -actual_fsize, "%g1"); 1.1 root 2945: if (! leaf_function) 1.1.1.3 root 2946: fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); 1.1 root 2947: else 1.1.1.3 root 2948: fprintf (file, "\tadd %%sp,%%g1,%%sp\n"); 1.1 root 2949: } 2950: 2951: /* If doing anything with PIC, do it now. */ 2952: if (! flag_pic) 2953: fprintf (file, "\t!#PROLOGUE# 1\n"); 2954: 1.1.1.3 root 2955: /* Call saved registers are saved just above the outgoing argument area. */ 2956: if (num_gfregs) 1.1 root 2957: { 1.1.1.3 root 2958: int offset, n_regs; 2959: char *base; 1.1 root 2960: 1.1.1.3 root 2961: offset = -apparent_fsize + frame_base_offset; 2962: if (offset < -4096 || offset + num_gfregs * 4 > 4096) 2963: { 2964: /* ??? This might be optimized a little as %g1 might already have a 2965: value close enough that a single add insn will do. */ 2966: /* ??? Although, all of this is probably only a temporary fix 2967: because if %g1 can hold a function result, then 2968: output_function_epilogue will lose (the result will get 2969: clobbered). */ 2970: build_big_number (file, offset, "%g1"); 2971: fprintf (file, "\tadd %s,%%g1,%%g1\n", frame_base_name); 2972: base = "%g1"; 2973: offset = 0; 2974: } 1.1 root 2975: else 1.1.1.3 root 2976: { 2977: base = frame_base_name; 2978: } 1.1 root 2979: 2980: if (TARGET_EPILOGUE && ! leaf_function) 1.1.1.3 root 2981: /* ??? Originally saved regs 0-15 here. */ 2982: n_regs = save_regs (file, 0, 8, base, offset, 0); 1.1 root 2983: else if (leaf_function) 1.1.1.3 root 2984: /* ??? Originally saved regs 0-31 here. */ 2985: n_regs = save_regs (file, 0, 8, base, offset, 0); 1.1 root 2986: if (TARGET_EPILOGUE) 1.1.1.3 root 2987: save_regs (file, 32, TARGET_V9 ? 96 : 64, base, offset, n_regs); 1.1 root 2988: } 2989: 2990: leaf_label = 0; 2991: if (leaf_function && actual_fsize != 0) 2992: { 2993: /* warning ("leaf procedure with frame size %d", actual_fsize); */ 2994: if (! TARGET_EPILOGUE) 2995: leaf_label = gen_label_rtx (); 2996: } 2997: } 2998: 2999: /* Output code for the function epilogue. */ 3000: 3001: void 3002: output_function_epilogue (file, size, leaf_function) 3003: FILE *file; 3004: int size; 3005: int leaf_function; 3006: { 3007: char *ret; 3008: 3009: if (leaf_label) 3010: { 3011: emit_label_after (leaf_label, get_last_insn ()); 3012: final_scan_insn (get_last_insn (), file, 0, 0, 1); 3013: } 3014: 1.1.1.3 root 3015: /* Restore any call saved registers. */ 3016: if (num_gfregs) 1.1 root 3017: { 1.1.1.3 root 3018: int offset, n_regs; 3019: char *base; 1.1 root 3020: 1.1.1.3 root 3021: offset = -apparent_fsize + frame_base_offset; 3022: if (offset < -4096 || offset + num_gfregs * 4 > 4096 - 8 /*double*/) 3023: { 3024: build_big_number (file, offset, "%g1"); 3025: fprintf (file, "\tadd %s,%%g1,%%g1\n", frame_base_name); 3026: base = "%g1"; 3027: offset = 0; 3028: } 1.1 root 3029: else 1.1.1.3 root 3030: { 3031: base = frame_base_name; 3032: } 1.1 root 3033: 3034: if (TARGET_EPILOGUE && ! leaf_function) 1.1.1.3 root 3035: /* ??? Originally saved regs 0-15 here. */ 3036: n_regs = restore_regs (file, 0, 8, base, offset, 0); 1.1 root 3037: else if (leaf_function) 1.1.1.3 root 3038: /* ??? Originally saved regs 0-31 here. */ 3039: n_regs = restore_regs (file, 0, 8, base, offset, 0); 1.1 root 3040: if (TARGET_EPILOGUE) 1.1.1.3 root 3041: restore_regs (file, 32, TARGET_V9 ? 96 : 64, base, offset, n_regs); 1.1 root 3042: } 3043: 3044: /* Work out how to skip the caller's unimp instruction if required. */ 3045: if (leaf_function) 1.1.1.3 root 3046: ret = (SKIP_CALLERS_UNIMP_P ? "jmp %o7+12" : "retl"); 1.1 root 3047: else 1.1.1.3 root 3048: ret = (SKIP_CALLERS_UNIMP_P ? "jmp %i7+12" : "ret"); 1.1 root 3049: 3050: if (TARGET_EPILOGUE || leaf_label) 3051: { 3052: int old_target_epilogue = TARGET_EPILOGUE; 3053: target_flags &= ~old_target_epilogue; 3054: 3055: if (! leaf_function) 3056: { 3057: /* If we wound up with things in our delay slot, flush them here. */ 3058: if (current_function_epilogue_delay_list) 3059: { 3060: rtx insn = emit_jump_insn_after (gen_rtx (RETURN, VOIDmode), 3061: get_last_insn ()); 3062: PATTERN (insn) = gen_rtx (PARALLEL, VOIDmode, 3063: gen_rtvec (2, 3064: PATTERN (XEXP (current_function_epilogue_delay_list, 0)), 3065: PATTERN (insn))); 3066: final_scan_insn (insn, file, 1, 0, 1); 3067: } 3068: else 3069: fprintf (file, "\t%s\n\trestore\n", ret); 3070: } 3071: /* All of the following cases are for leaf functions. */ 3072: else if (current_function_epilogue_delay_list) 3073: { 3074: /* eligible_for_epilogue_delay_slot ensures that if this is a 3075: leaf function, then we will only have insn in the delay slot 3076: if the frame size is zero, thus no adjust for the stack is 3077: needed here. */ 3078: if (actual_fsize != 0) 3079: abort (); 3080: fprintf (file, "\t%s\n", ret); 3081: final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), 3082: file, 1, 0, 1); 3083: } 3084: /* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to 3085: avoid generating confusing assembly language output. */ 3086: else if (actual_fsize == 0) 3087: fprintf (file, "\t%s\n\tnop\n", ret); 3088: else if (actual_fsize <= 4096) 3089: fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize); 3090: else if (actual_fsize <= 8192) 3091: fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n", 3092: ret, actual_fsize - 4096); 3093: else if ((actual_fsize & 0x3ff) == 0) 3094: fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", 3095: actual_fsize, ret); 3096: else 3097: fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", 3098: actual_fsize, actual_fsize, ret); 3099: target_flags |= old_target_epilogue; 3100: } 3101: } 3102: 1.1.1.3 root 3103: /* Do what is necessary for `va_start'. The argument is ignored. 3104: !v9: We look at the current function to determine if stdarg or varargs 3105: is used and return the address of the first unnamed parameter. 3106: v9: We save the argument integer and floating point regs in a buffer, and 3107: return the address of this buffer. The rest is handled in va-sparc.h. */ 3108: /* ??? This is currently conditioned on #ifdef SPARCV9 because 3109: current_function_args_info is different in each compiler. */ 3110: 3111: #ifdef SPARCV9 3112: 3113: rtx 3114: sparc_builtin_saveregs (arglist) 3115: tree arglist; 3116: { 3117: tree fntype = TREE_TYPE (current_function_decl); 3118: /* First unnamed integer register. */ 3119: int first_intreg = current_function_args_info.arg_count[(int) SPARC_ARG_INT]; 3120: /* Number of integer registers we need to save. */ 3121: int n_intregs = MAX (0, NPARM_REGS (SImode) - first_intreg); 3122: /* First unnamed SFmode float reg (no, you can't pass SFmode floats as 3123: unnamed arguments, we just number them that way). We must round up to 3124: the next double word float reg - that is the first one to save. */ 3125: int first_floatreg = current_function_args_info.arg_count[(int) SPARC_ARG_FLOAT] + 1 & ~1; 3126: /* Number of SFmode float regs to save. */ 3127: int n_floatregs = MAX (0, NPARM_REGS (SFmode) - first_floatreg); 3128: int ptrsize = GET_MODE_SIZE (Pmode); 3129: rtx valist, regbuf, fpregs; 3130: int bufsize, adjust, regno; 3131: 3132: /* Allocate block of memory for the regs. 3133: We only allocate as much as we need, but we must ensure quadword float 3134: regs are stored with the appropriate alignment. */ 3135: /* ??? If n_intregs + n_floatregs == 0, should we allocate at least 1 byte? 3136: Or can assign_stack_local accept a 0 SIZE argument? */ 3137: 3138: bufsize = (n_intregs * UNITS_PER_WORD) + (n_floatregs * (UNITS_PER_WORD / 2)); 3139: /* Add space in front of the int regs to ensure proper alignment of quadword 3140: fp regs. We must add the space in front because va_start assumes this. */ 3141: if (n_floatregs >= 4) 3142: adjust = ((n_intregs + first_floatreg / 2) % 2) * UNITS_PER_WORD; 3143: else 3144: adjust = 0; 3145: 3146: regbuf = assign_stack_local (BLKmode, bufsize + adjust, 3147: GET_MODE_BITSIZE (TFmode)); 3148: regbuf = gen_rtx (MEM, BLKmode, plus_constant (XEXP (regbuf, 0), adjust)); 3149: MEM_IN_STRUCT_P (regbuf) = 1; 3150: 3151: /* Save int args. 3152: This is optimized to only save the regs that are necessary. Explicitly 3153: named args need not be saved. */ 3154: 3155: if (n_intregs > 0) 3156: move_block_from_reg (BASE_INCOMING_ARG_REG (SImode) + first_intreg, 3157: regbuf, n_intregs, n_intregs * UNITS_PER_WORD); 3158: 3159: /* Save float args. 3160: This is optimized to only save the regs that are necessary. Explicitly 3161: named args need not be saved. 3162: We explicitly build a pointer to the buffer because it halves the insn 3163: count when not optimizing (otherwise the pointer is built for each reg 3164: saved). */ 3165: 3166: fpregs = gen_reg_rtx (Pmode); 3167: emit_move_insn (fpregs, plus_constant (XEXP (regbuf, 0), 3168: n_intregs * UNITS_PER_WORD)); 3169: for (regno = first_floatreg; regno < NPARM_REGS (SFmode); regno += 2) 3170: emit_move_insn (gen_rtx (MEM, DFmode, 3171: plus_constant (fpregs, 3172: GET_MODE_SIZE (SFmode) 3173: * (regno - first_floatreg))), 3174: gen_rtx (REG, DFmode, 3175: BASE_INCOMING_ARG_REG (DFmode) + regno)); 3176: 3177: /* Return the address of the regbuf. */ 3178: 3179: return XEXP (regbuf, 0); 3180: } 3181: 3182: #else /* ! SPARCV9 */ 1.1 root 3183: 3184: rtx 3185: sparc_builtin_saveregs (arglist) 3186: tree arglist; 3187: { 3188: tree fntype = TREE_TYPE (current_function_decl); 3189: int stdarg = (TYPE_ARG_TYPES (fntype) != 0 3190: && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 3191: != void_type_node)); 3192: int first_reg = current_function_args_info; 3193: rtx address; 3194: int regno; 3195: 3196: #if 0 /* This code seemed to have no effect except to make 3197: varargs not work right when va_list wasn't the first arg. */ 3198: if (! stdarg) 3199: first_reg = 0; 3200: #endif 3201: 1.1.1.3 root 3202: for (regno = first_reg; regno < NPARM_REGS (SImode); regno++) 1.1 root 3203: emit_move_insn (gen_rtx (MEM, word_mode, 3204: gen_rtx (PLUS, Pmode, 3205: frame_pointer_rtx, 3206: GEN_INT (STACK_POINTER_OFFSET 3207: + UNITS_PER_WORD * regno))), 3208: gen_rtx (REG, word_mode, BASE_INCOMING_ARG_REG (word_mode) 3209: + regno)); 3210: 3211: address = gen_rtx (PLUS, Pmode, 3212: frame_pointer_rtx, 3213: GEN_INT (STACK_POINTER_OFFSET 3214: + UNITS_PER_WORD * first_reg)); 3215: 3216: return address; 3217: } 1.1.1.3 root 3218: 3219: #endif /* ! SPARCV9 */ 1.1 root 3220: 3221: /* Return the string to output a conditional branch to LABEL, which is 3222: the operand number of the label. OP is the conditional expression. The 3223: mode of register 0 says what kind of comparison we made. 3224: 1.1.1.3 root 3225: FP_COND_REG indicates which fp condition code register to use if this is 3226: a floating point branch. 3227: 1.1 root 3228: REVERSED is non-zero if we should reverse the sense of the comparison. 3229: 3230: ANNUL is non-zero if we should generate an annulling branch. 3231: 3232: NOOP is non-zero if we have to follow this branch by a noop. */ 3233: 3234: char * 1.1.1.3 root 3235: output_cbranch (op, fp_cond_reg, label, reversed, annul, noop) 3236: rtx op, fp_cond_reg; 1.1 root 3237: int label; 3238: int reversed, annul, noop; 3239: { 3240: static char string[20]; 3241: enum rtx_code code = GET_CODE (op); 3242: enum machine_mode mode = GET_MODE (XEXP (op, 0)); 1.1.1.3 root 3243: static char v8_labelno[] = " %lX"; 3244: static char v9_icc_labelno[] = " %%icc,%lX"; 3245: static char v9_xcc_labelno[] = " %%xcc,%lX"; 3246: static char v9_fcc_labelno[] = " %%fccX,%lY"; 3247: char *labelno; 3248: int labeloff; 1.1 root 3249: 1.1.1.3 root 3250: /* ??? !v9: FP branches cannot be preceded by another floating point insn. 1.1 root 3251: Because there is currently no concept of pre-delay slots, we can fix 3252: this only by always emitting a nop before a floating point branch. */ 3253: 1.1.1.3 root 3254: if ((mode == CCFPmode || mode == CCFPEmode) && ! TARGET_V9) 1.1 root 3255: strcpy (string, "nop\n\t"); 1.1.1.3 root 3256: else 3257: string[0] = '\0'; 1.1 root 3258: 3259: /* If not floating-point or if EQ or NE, we can just reverse the code. */ 3260: if (reversed 3261: && ((mode != CCFPmode && mode != CCFPEmode) || code == EQ || code == NE)) 3262: code = reverse_condition (code), reversed = 0; 3263: 3264: /* Start by writing the branch condition. */ 3265: switch (code) 3266: { 3267: case NE: 3268: if (mode == CCFPmode || mode == CCFPEmode) 3269: strcat (string, "fbne"); 3270: else 3271: strcpy (string, "bne"); 3272: break; 3273: 3274: case EQ: 3275: if (mode == CCFPmode || mode == CCFPEmode) 3276: strcat (string, "fbe"); 3277: else 3278: strcpy (string, "be"); 3279: break; 3280: 3281: case GE: 3282: if (mode == CCFPmode || mode == CCFPEmode) 3283: { 3284: if (reversed) 3285: strcat (string, "fbul"); 3286: else 3287: strcat (string, "fbge"); 3288: } 3289: else if (mode == CC_NOOVmode) 3290: strcpy (string, "bpos"); 3291: else 3292: strcpy (string, "bge"); 3293: break; 3294: 3295: case GT: 3296: if (mode == CCFPmode || mode == CCFPEmode) 3297: { 3298: if (reversed) 3299: strcat (string, "fbule"); 3300: else 3301: strcat (string, "fbg"); 3302: } 3303: else 3304: strcpy (string, "bg"); 3305: break; 3306: 3307: case LE: 3308: if (mode == CCFPmode || mode == CCFPEmode) 3309: { 3310: if (reversed) 3311: strcat (string, "fbug"); 3312: else 3313: strcat (string, "fble"); 3314: } 3315: else 3316: strcpy (string, "ble"); 3317: break; 3318: 3319: case LT: 3320: if (mode == CCFPmode || mode == CCFPEmode) 3321: { 3322: if (reversed) 3323: strcat (string, "fbuge"); 3324: else 3325: strcat (string, "fbl"); 3326: } 3327: else if (mode == CC_NOOVmode) 3328: strcpy (string, "bneg"); 3329: else 3330: strcpy (string, "bl"); 3331: break; 3332: 3333: case GEU: 3334: strcpy (string, "bgeu"); 3335: break; 3336: 3337: case GTU: 3338: strcpy (string, "bgu"); 3339: break; 3340: 3341: case LEU: 3342: strcpy (string, "bleu"); 3343: break; 3344: 3345: case LTU: 3346: strcpy (string, "blu"); 3347: break; 3348: } 3349: 3350: /* Now add the annulling, the label, and a possible noop. */ 3351: if (annul) 3352: strcat (string, ",a"); 3353: 1.1.1.3 root 3354: /* ??? If v9, optional prediction bit ",pt" or ",pf" goes here. */ 3355: 3356: if (! TARGET_V9) 3357: { 3358: labeloff = 3; 3359: labelno = v8_labelno; 3360: } 3361: else 3362: { 3363: labeloff = 9; 3364: if (mode == CCFPmode || mode == CCFPEmode) 3365: { 3366: labeloff = 10; 3367: labelno = v9_fcc_labelno; 3368: /* Set the char indicating the number of the fcc reg to use. */ 3369: labelno[6] = REGNO (fp_cond_reg) - 96 + '0'; 3370: } 3371: else if (mode == CCXmode || mode == CCX_NOOVmode) 3372: labelno = v9_xcc_labelno; 3373: else 3374: labelno = v9_icc_labelno; 3375: } 3376: /* Set the char indicating the number of the operand containing the 3377: label_ref. */ 3378: labelno[labeloff] = label + '0'; 3379: strcat (string, labelno); 3380: 3381: if (noop) 3382: strcat (string, "\n\tnop"); 3383: 3384: return string; 3385: } 3386: 3387: /* Return the string to output a conditional branch to LABEL, testing 3388: register REG. LABEL is the operand number of the label; REG is the 3389: operand number of the reg. OP is the conditional expression. The mode 3390: of REG says what kind of comparison we made. 3391: 3392: REVERSED is non-zero if we should reverse the sense of the comparison. 3393: 3394: ANNUL is non-zero if we should generate an annulling branch. 3395: 3396: NOOP is non-zero if we have to follow this branch by a noop. */ 3397: 3398: char * 3399: output_v9branch (op, reg, label, reversed, annul, noop) 3400: rtx op; 3401: int reg, label; 3402: int reversed, annul, noop; 3403: { 3404: static char string[20]; 3405: enum rtx_code code = GET_CODE (op); 3406: enum machine_mode mode = GET_MODE (XEXP (op, 0)); 3407: static char labelno[] = " %X,%lX"; 3408: 3409: /* If not floating-point or if EQ or NE, we can just reverse the code. */ 3410: if (reversed) 3411: code = reverse_condition (code), reversed = 0; 3412: 3413: /* Only 64 bit versions of these instructions exist. */ 3414: if (mode != DImode) 3415: abort (); 3416: 3417: /* Start by writing the branch condition. */ 3418: 3419: switch (code) 3420: { 3421: case NE: 3422: strcpy (string, "brnz"); 3423: break; 3424: 3425: case EQ: 3426: strcpy (string, "brz"); 3427: break; 3428: 3429: case GE: 3430: strcpy (string, "brgez"); 3431: break; 3432: 3433: case LT: 3434: strcpy (string, "brlz"); 3435: break; 3436: 3437: case LE: 3438: strcpy (string, "brlez"); 3439: break; 3440: 3441: case GT: 3442: strcpy (string, "brgz"); 3443: break; 3444: 3445: default: 3446: abort (); 3447: } 3448: 3449: /* Now add the annulling, reg, label, and nop. */ 3450: if (annul) 3451: strcat (string, ",a"); 3452: 3453: /* ??? Optional prediction bit ",pt" or ",pf" goes here. */ 3454: 3455: labelno[2] = reg + '0'; 3456: labelno[6] = label + '0'; 1.1 root 3457: strcat (string, labelno); 3458: 3459: if (noop) 3460: strcat (string, "\n\tnop"); 3461: 3462: return string; 3463: } 3464: 3465: /* Output assembler code to return from a function. */ 3466: 1.1.1.3 root 3467: /* ??? v9: Update to use the new `return' instruction. Also, add patterns to 3468: md file for the `return' instruction. */ 3469: 1.1 root 3470: char * 3471: output_return (operands) 3472: rtx *operands; 3473: { 3474: if (leaf_label) 3475: { 3476: operands[0] = leaf_label; 3477: return "b,a %l0"; 3478: } 3479: else if (leaf_function) 3480: { 3481: /* If we didn't allocate a frame pointer for the current function, 3482: the stack pointer might have been adjusted. Output code to 3483: restore it now. */ 3484: 3485: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize); 3486: 3487: /* Use sub of negated value in first two cases instead of add to 3488: allow actual_fsize == 4096. */ 3489: 3490: if (actual_fsize <= 4096) 3491: { 1.1.1.3 root 3492: if (SKIP_CALLERS_UNIMP_P) 1.1 root 3493: return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp"; 3494: else 3495: return "retl\n\tsub %%sp,-%0,%%sp"; 3496: } 3497: else if (actual_fsize <= 8192) 3498: { 3499: operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096); 1.1.1.3 root 3500: if (SKIP_CALLERS_UNIMP_P) 1.1 root 3501: return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp"; 3502: else 3503: return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp"; 3504: } 1.1.1.3 root 3505: else if (SKIP_CALLERS_UNIMP_P) 1.1 root 3506: { 3507: if ((actual_fsize & 0x3ff) != 0) 3508: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; 3509: else 3510: return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; 3511: } 3512: else 3513: { 3514: if ((actual_fsize & 0x3ff) != 0) 3515: return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; 3516: else 3517: return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; 3518: } 3519: } 3520: else 3521: { 1.1.1.3 root 3522: if (SKIP_CALLERS_UNIMP_P) 1.1 root 3523: return "jmp %%i7+12\n\trestore"; 3524: else 3525: return "ret\n\trestore"; 3526: } 3527: } 3528: 3529: /* Leaf functions and non-leaf functions have different needs. */ 3530: 3531: static int 3532: reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER; 3533: 3534: static int 3535: reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER; 3536: 3537: static int *reg_alloc_orders[] = { 3538: reg_leaf_alloc_order, 3539: reg_nonleaf_alloc_order}; 3540: 3541: void 3542: order_regs_for_local_alloc () 3543: { 3544: static int last_order_nonleaf = 1; 3545: 3546: if (regs_ever_live[15] != last_order_nonleaf) 3547: { 3548: last_order_nonleaf = !last_order_nonleaf; 1.1.1.4 ! root 3549: bcopy ((char *) reg_alloc_orders[last_order_nonleaf], ! 3550: (char *) reg_alloc_order, FIRST_PSEUDO_REGISTER * sizeof (int)); 1.1 root 3551: } 3552: } 3553: 3554: /* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1. 3555: This makes them candidates for using ldd and std insns. 3556: 3557: Note reg1 and reg2 *must* be hard registers. To be sure we will 3558: abort if we are passed pseudo registers. */ 3559: 3560: int 3561: registers_ok_for_ldd_peep (reg1, reg2) 3562: rtx reg1, reg2; 3563: { 3564: /* We might have been passed a SUBREG. */ 3565: if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) 3566: return 0; 3567: 3568: if (REGNO (reg1) % 2 != 0) 3569: return 0; 3570: 3571: return (REGNO (reg1) == REGNO (reg2) - 1); 3572: } 3573: 3574: /* Return 1 if addr1 and addr2 are suitable for use in an ldd or 3575: std insn. 3576: 3577: This can only happen when addr1 and addr2 are consecutive memory 3578: locations (addr1 + 4 == addr2). addr1 must also be aligned on a 3579: 64 bit boundary (addr1 % 8 == 0). 3580: 3581: We know %sp and %fp are kept aligned on a 64 bit boundary. Other 3582: registers are assumed to *never* be properly aligned and are 3583: rejected. 3584: 3585: Knowing %sp and %fp are kept aligned on a 64 bit boundary, we 3586: need only check that the offset for addr1 % 8 == 0. */ 3587: 3588: int 3589: addrs_ok_for_ldd_peep (addr1, addr2) 3590: rtx addr1, addr2; 3591: { 3592: int reg1, offset1; 3593: 3594: /* Extract a register number and offset (if used) from the first addr. */ 3595: if (GET_CODE (addr1) == PLUS) 3596: { 3597: /* If not a REG, return zero. */ 3598: if (GET_CODE (XEXP (addr1, 0)) != REG) 3599: return 0; 3600: else 3601: { 3602: reg1 = REGNO (XEXP (addr1, 0)); 3603: /* The offset must be constant! */ 3604: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) 3605: return 0; 3606: offset1 = INTVAL (XEXP (addr1, 1)); 3607: } 3608: } 3609: else if (GET_CODE (addr1) != REG) 3610: return 0; 3611: else 3612: { 3613: reg1 = REGNO (addr1); 3614: /* This was a simple (mem (reg)) expression. Offset is 0. */ 3615: offset1 = 0; 3616: } 3617: 3618: /* Make sure the second address is a (mem (plus (reg) (const_int). */ 3619: if (GET_CODE (addr2) != PLUS) 3620: return 0; 3621: 3622: if (GET_CODE (XEXP (addr2, 0)) != REG 3623: || GET_CODE (XEXP (addr2, 1)) != CONST_INT) 3624: return 0; 3625: 3626: /* Only %fp and %sp are allowed. Additionally both addresses must 3627: use the same register. */ 3628: if (reg1 != FRAME_POINTER_REGNUM && reg1 != STACK_POINTER_REGNUM) 3629: return 0; 3630: 3631: if (reg1 != REGNO (XEXP (addr2, 0))) 3632: return 0; 3633: 3634: /* The first offset must be evenly divisible by 8 to ensure the 3635: address is 64 bit aligned. */ 3636: if (offset1 % 8 != 0) 3637: return 0; 3638: 3639: /* The offset for the second addr must be 4 more than the first addr. */ 3640: if (INTVAL (XEXP (addr2, 1)) != offset1 + 4) 3641: return 0; 3642: 3643: /* All the tests passed. addr1 and addr2 are valid for ldd and std 3644: instructions. */ 3645: return 1; 3646: } 3647: 3648: /* Return 1 if reg is a pseudo, or is the first register in 3649: a hard register pair. This makes it a candidate for use in 3650: ldd and std insns. */ 3651: 3652: int 3653: register_ok_for_ldd (reg) 3654: rtx reg; 3655: { 3656: /* We might have been passed a SUBREG. */ 3657: if (GET_CODE (reg) != REG) 3658: return 0; 3659: 3660: if (REGNO (reg) < FIRST_PSEUDO_REGISTER) 3661: return (REGNO (reg) % 2 == 0); 3662: else 3663: return 1; 3664: } 3665: 3666: /* Print operand X (an rtx) in assembler syntax to file FILE. 3667: CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified. 3668: For `%' followed by punctuation, CODE is the punctuation and X is null. */ 3669: 3670: void 3671: print_operand (file, x, code) 3672: FILE *file; 3673: rtx x; 3674: int code; 3675: { 3676: switch (code) 3677: { 3678: case '#': 3679: /* Output a 'nop' if there's nothing for the delay slot. */ 3680: if (dbr_sequence_length () == 0) 3681: fputs ("\n\tnop", file); 3682: return; 3683: case '*': 3684: /* Output an annul flag if there's nothing for the delay slot and we 3685: are optimizing. This is always used with '(' below. */ 3686: /* Sun OS 4.1.1 dbx can't handle an annulled unconditional branch; 3687: this is a dbx bug. So, we only do this when optimizing. */ 3688: if (dbr_sequence_length () == 0 && optimize) 3689: fputs (",a", file); 3690: return; 3691: case '(': 3692: /* Output a 'nop' if there's nothing for the delay slot and we are 3693: not optimizing. This is always used with '*' above. */ 3694: if (dbr_sequence_length () == 0 && ! optimize) 3695: fputs ("\n\tnop", file); 3696: return; 1.1.1.3 root 3697: case '_': 3698: /* Output the Medium/Anywhere code model base register. */ 3699: fputs (MEDANY_BASE_REG, file); 3700: return; 3701: case '@': 3702: /* Print out what we are using as the frame pointer. This might 3703: be %fp, or might be %sp+offset. */ 3704: /* ??? What if offset is too big? Perhaps the caller knows it isn't? */ 3705: fprintf (file, "%s+%d", frame_base_name, frame_base_offset); 3706: return; 1.1 root 3707: case 'Y': 3708: /* Adjust the operand to take into account a RESTORE operation. */ 3709: if (GET_CODE (x) != REG) 3710: output_operand_lossage ("Invalid %%Y operand"); 3711: else if (REGNO (x) < 8) 3712: fputs (reg_names[REGNO (x)], file); 3713: else if (REGNO (x) >= 24 && REGNO (x) < 32) 3714: fputs (reg_names[REGNO (x)-16], file); 3715: else 3716: output_operand_lossage ("Invalid %%Y operand"); 3717: return; 3718: case 'R': 3719: /* Print out the second register name of a register pair or quad. 3720: I.e., R (%o0) => %o1. */ 3721: fputs (reg_names[REGNO (x)+1], file); 3722: return; 3723: case 'S': 3724: /* Print out the third register name of a register quad. 3725: I.e., S (%o0) => %o2. */ 3726: fputs (reg_names[REGNO (x)+2], file); 3727: return; 3728: case 'T': 3729: /* Print out the fourth register name of a register quad. 3730: I.e., T (%o0) => %o3. */ 3731: fputs (reg_names[REGNO (x)+3], file); 3732: return; 3733: case 'm': 3734: /* Print the operand's address only. */ 3735: output_address (XEXP (x, 0)); 3736: return; 3737: case 'r': 3738: /* In this case we need a register. Use %g0 if the 3739: operand is const0_rtx. */ 3740: if (x == const0_rtx 3741: || (GET_MODE (x) != VOIDmode && x == CONST0_RTX (GET_MODE (x)))) 3742: { 3743: fputs ("%g0", file); 3744: return; 3745: } 3746: else 3747: break; 3748: 1.1.1.3 root 3749: case 'A': 1.1 root 3750: switch (GET_CODE (x)) 3751: { 3752: case IOR: fputs ("or", file); break; 3753: case AND: fputs ("and", file); break; 3754: case XOR: fputs ("xor", file); break; 3755: default: output_operand_lossage ("Invalid %%A operand"); 3756: } 3757: return; 3758: 3759: case 'B': 3760: switch (GET_CODE (x)) 3761: { 3762: case IOR: fputs ("orn", file); break; 3763: case AND: fputs ("andn", file); break; 3764: case XOR: fputs ("xnor", file); break; 3765: default: output_operand_lossage ("Invalid %%B operand"); 3766: } 3767: return; 3768: 1.1.1.3 root 3769: /* This is used by the conditional move instructions. */ 3770: case 'C': 3771: switch (GET_CODE (x)) 3772: { 3773: case NE: fputs ("ne", file); break; 3774: case EQ: fputs ("e", file); break; 3775: case GE: fputs ("ge", file); break; 3776: case GT: fputs ("g", file); break; 3777: case LE: fputs ("le", file); break; 3778: case LT: fputs ("l", file); break; 3779: case GEU: fputs ("geu", file); break; 3780: case GTU: fputs ("gu", file); break; 3781: case LEU: fputs ("leu", file); break; 3782: case LTU: fputs ("lu", file); break; 3783: default: output_operand_lossage ("Invalid %%C operand"); 3784: } 3785: return; 3786: 3787: /* This is used by the movr instruction pattern. */ 3788: case 'D': 3789: switch (GET_CODE (x)) 3790: { 3791: case NE: fputs ("ne", file); break; 3792: case EQ: fputs ("e", file); break; 3793: case GE: fputs ("gez", file); break; 3794: case LT: fputs ("lz", file); break; 3795: case LE: fputs ("lez", file); break; 3796: case GT: fputs ("gz", file); break; 3797: default: output_operand_lossage ("Invalid %%D operand"); 3798: } 3799: return; 3800: 1.1 root 3801: case 'b': 3802: { 3803: /* Print a sign-extended character. */ 3804: int i = INTVAL (x) & 0xff; 3805: if (i & 0x80) 3806: i |= 0xffffff00; 3807: fprintf (file, "%d", i); 3808: return; 3809: } 3810: 1.1.1.4 ! root 3811: case 'f': ! 3812: /* Operand must be a MEM; write its address. */ ! 3813: if (GET_CODE (x) != MEM) ! 3814: output_operand_lossage ("Invalid %%f operand"); ! 3815: output_address (XEXP (x, 0)); ! 3816: return; ! 3817: 1.1 root 3818: case 0: 3819: /* Do nothing special. */ 3820: break; 3821: 3822: default: 3823: /* Undocumented flag. */ 3824: output_operand_lossage ("invalid operand output code"); 3825: } 3826: 3827: if (GET_CODE (x) == REG) 3828: fputs (reg_names[REGNO (x)], file); 3829: else if (GET_CODE (x) == MEM) 3830: { 3831: fputc ('[', file); 3832: if (CONSTANT_P (XEXP (x, 0))) 3833: /* Poor Sun assembler doesn't understand absolute addressing. */ 3834: fputs ("%g0+", file); 3835: output_address (XEXP (x, 0)); 3836: fputc (']', file); 3837: } 3838: else if (GET_CODE (x) == HIGH) 3839: { 3840: fputs ("%hi(", file); 3841: output_addr_const (file, XEXP (x, 0)); 3842: fputc (')', file); 3843: } 3844: else if (GET_CODE (x) == LO_SUM) 3845: { 3846: print_operand (file, XEXP (x, 0), 0); 3847: fputs ("+%lo(", file); 3848: output_addr_const (file, XEXP (x, 1)); 3849: fputc (')', file); 3850: } 3851: else if (GET_CODE (x) == CONST_DOUBLE 3852: && (GET_MODE (x) == VOIDmode 3853: || GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)) 3854: { 3855: if (CONST_DOUBLE_HIGH (x) == 0) 3856: fprintf (file, "%u", CONST_DOUBLE_LOW (x)); 3857: else if (CONST_DOUBLE_HIGH (x) == -1 3858: && CONST_DOUBLE_LOW (x) < 0) 3859: fprintf (file, "%d", CONST_DOUBLE_LOW (x)); 3860: else 3861: output_operand_lossage ("long long constant not a valid immediate operand"); 3862: } 3863: else if (GET_CODE (x) == CONST_DOUBLE) 3864: output_operand_lossage ("floating point constant not a valid immediate operand"); 3865: else { output_addr_const (file, x); } 3866: } 3867: 3868: /* This function outputs assembler code for VALUE to FILE, where VALUE is 3869: a 64 bit (DImode) value. */ 3870: 3871: /* ??? If there is a 64 bit counterpart to .word that the assembler 3872: understands, then using that would simply this code greatly. */ 1.1.1.3 root 3873: /* ??? We only output .xword's for symbols and only then in environments 3874: where the assembler can handle them. */ 1.1 root 3875: 3876: void 3877: output_double_int (file, value) 3878: FILE *file; 3879: rtx value; 3880: { 3881: if (GET_CODE (value) == CONST_INT) 3882: { 3883: if (INTVAL (value) < 0) 3884: ASM_OUTPUT_INT (file, constm1_rtx); 3885: else 3886: ASM_OUTPUT_INT (file, const0_rtx); 3887: ASM_OUTPUT_INT (file, value); 3888: } 3889: else if (GET_CODE (value) == CONST_DOUBLE) 3890: { 3891: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, 3892: CONST_DOUBLE_HIGH (value))); 3893: ASM_OUTPUT_INT (file, gen_rtx (CONST_INT, VOIDmode, 3894: CONST_DOUBLE_LOW (value))); 3895: } 3896: else if (GET_CODE (value) == SYMBOL_REF 3897: || GET_CODE (value) == CONST 1.1.1.3 root 3898: || GET_CODE (value) == PLUS 3899: || (TARGET_V9 && 3900: (GET_CODE (value) == LABEL_REF 3901: || GET_CODE (value) == MINUS))) 1.1 root 3902: { 1.1.1.3 root 3903: if (!TARGET_V9 || TARGET_ENV32) 3904: { 3905: ASM_OUTPUT_INT (file, const0_rtx); 3906: ASM_OUTPUT_INT (file, value); 3907: } 3908: else 3909: { 3910: fprintf (file, "\t%s\t", ASM_LONGLONG); 3911: output_addr_const (file, value); 3912: fprintf (file, "\n"); 3913: } 1.1 root 3914: } 3915: else 3916: abort (); 3917: } 3918: 1.1.1.3 root 3919: /* Return the value of a code used in the .proc pseudo-op that says 3920: what kind of result this function returns. For non-C types, we pick 3921: the closest C type. */ 3922: 1.1 root 3923: #ifndef CHAR_TYPE_SIZE 3924: #define CHAR_TYPE_SIZE BITS_PER_UNIT 3925: #endif 3926: 3927: #ifndef SHORT_TYPE_SIZE 3928: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2) 3929: #endif 3930: 3931: #ifndef INT_TYPE_SIZE 3932: #define INT_TYPE_SIZE BITS_PER_WORD 3933: #endif 3934: 3935: #ifndef LONG_TYPE_SIZE 3936: #define LONG_TYPE_SIZE BITS_PER_WORD 3937: #endif 3938: 3939: #ifndef LONG_LONG_TYPE_SIZE 3940: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) 3941: #endif 3942: 3943: #ifndef FLOAT_TYPE_SIZE 3944: #define FLOAT_TYPE_SIZE BITS_PER_WORD 3945: #endif 3946: 3947: #ifndef DOUBLE_TYPE_SIZE 3948: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 3949: #endif 3950: 3951: #ifndef LONG_DOUBLE_TYPE_SIZE 3952: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) 3953: #endif 3954: 3955: unsigned long 3956: sparc_type_code (type) 3957: register tree type; 3958: { 3959: register unsigned long qualifiers = 0; 3960: register unsigned shift = 6; 3961: 1.1.1.4 ! root 3962: /* Only the first 30 bits of the qualifier are valid. We must refrain from 1.1.1.3 root 3963: setting more, since some assemblers will give an error for this. Also, 3964: we must be careful to avoid shifts of 32 bits or more to avoid getting 3965: unpredictable results. */ 3966: 1.1 root 3967: for (;;) 3968: { 3969: switch (TREE_CODE (type)) 3970: { 3971: case ERROR_MARK: 3972: return qualifiers; 3973: 3974: case ARRAY_TYPE: 1.1.1.3 root 3975: if (shift < 30) 3976: qualifiers |= (3 << shift); 1.1 root 3977: shift += 2; 3978: type = TREE_TYPE (type); 3979: break; 3980: 3981: case FUNCTION_TYPE: 3982: case METHOD_TYPE: 1.1.1.3 root 3983: if (shift < 30) 3984: qualifiers |= (2 << shift); 1.1 root 3985: shift += 2; 3986: type = TREE_TYPE (type); 3987: break; 3988: 3989: case POINTER_TYPE: 3990: case REFERENCE_TYPE: 3991: case OFFSET_TYPE: 1.1.1.3 root 3992: if (shift < 30) 3993: qualifiers |= (1 << shift); 1.1 root 3994: shift += 2; 3995: type = TREE_TYPE (type); 3996: break; 3997: 3998: case RECORD_TYPE: 3999: return (qualifiers | 8); 4000: 4001: case UNION_TYPE: 1.1.1.3 root 4002: case QUAL_UNION_TYPE: 1.1 root 4003: return (qualifiers | 9); 4004: 4005: case ENUMERAL_TYPE: 4006: return (qualifiers | 10); 4007: 4008: case VOID_TYPE: 4009: return (qualifiers | 16); 4010: 4011: case INTEGER_TYPE: 1.1.1.2 root 4012: /* If this is a range type, consider it to be the underlying 4013: type. */ 4014: if (TREE_TYPE (type) != 0) 4015: { 4016: type = TREE_TYPE (type); 4017: break; 4018: } 4019: 1.1 root 4020: /* Carefully distinguish all the standard types of C, 1.1.1.3 root 4021: without messing up if the language is not C. We do this by 4022: testing TYPE_PRECISION and TREE_UNSIGNED. The old code used to 4023: look at both the names and the above fields, but that's redundant. 4024: Any type whose size is between two C types will be considered 4025: to be the wider of the two types. Also, we do not have a 4026: special code to use for "long long", so anything wider than 4027: long is treated the same. Note that we can't distinguish 4028: between "int" and "long" in this code if they are the same 4029: size, but that's fine, since neither can the assembler. */ 4030: 4031: if (TYPE_PRECISION (type) <= CHAR_TYPE_SIZE) 4032: return (qualifiers | (TREE_UNSIGNED (type) ? 12 : 2)); 1.1 root 4033: 1.1.1.3 root 4034: else if (TYPE_PRECISION (type) <= SHORT_TYPE_SIZE) 4035: return (qualifiers | (TREE_UNSIGNED (type) ? 13 : 3)); 1.1 root 4036: 1.1.1.3 root 4037: else if (TYPE_PRECISION (type) <= INT_TYPE_SIZE) 1.1 root 4038: return (qualifiers | (TREE_UNSIGNED (type) ? 14 : 4)); 4039: 1.1.1.3 root 4040: else 1.1 root 4041: return (qualifiers | (TREE_UNSIGNED (type) ? 15 : 5)); 4042: 4043: case REAL_TYPE: 4044: /* Carefully distinguish all the standard types of C, 4045: without messing up if the language is not C. */ 1.1.1.3 root 4046: 1.1 root 4047: if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE) 4048: return (qualifiers | 6); 1.1.1.3 root 4049: 4050: else 4051: return (qualifiers | 7); 1.1 root 4052: 4053: case COMPLEX_TYPE: /* GNU Fortran COMPLEX type. */ 4054: /* ??? We need to distinguish between double and float complex types, 4055: but I don't know how yet because I can't reach this code from 4056: existing front-ends. */ 4057: return (qualifiers | 7); /* Who knows? */ 4058: 4059: case CHAR_TYPE: /* GNU Pascal CHAR type. Not used in C. */ 4060: case BOOLEAN_TYPE: /* GNU Fortran BOOLEAN type. */ 4061: case FILE_TYPE: /* GNU Pascal FILE type. */ 1.1.1.2 root 4062: case SET_TYPE: /* GNU Pascal SET type. */ 1.1 root 4063: case LANG_TYPE: /* ? */ 1.1.1.2 root 4064: return qualifiers; 1.1 root 4065: 4066: default: 4067: abort (); /* Not a type! */ 4068: } 4069: } 4070: } 4071: 1.1.1.3 root 4072: /* Nested function support. */ 4073: 4074: /* Emit RTL insns to initialize the variable parts of a trampoline. 4075: FNADDR is an RTX for the address of the function's pure code. 4076: CXT is an RTX for the static chain value for the function. 4077: 4078: This takes 16 insns: 2 shifts & 2 ands (to split up addresses), 4 sethi 4079: (to load in opcodes), 4 iors (to merge address and opcodes), and 4 writes 4080: (to store insns). This is a bit excessive. Perhaps a different 4081: mechanism would be better here. 4082: 1.1.1.4 ! root 4083: Emit enough FLUSH insns to synchronize the data and instruction caches. */ 1.1.1.3 root 4084: 4085: void 4086: sparc_initialize_trampoline (tramp, fnaddr, cxt) 4087: rtx tramp, fnaddr, cxt; 4088: { 4089: rtx high_cxt = expand_shift (RSHIFT_EXPR, SImode, cxt, 4090: size_int (10), 0, 1); 4091: rtx high_fn = expand_shift (RSHIFT_EXPR, SImode, fnaddr, 4092: size_int (10), 0, 1); 4093: rtx low_cxt = expand_and (cxt, gen_rtx (CONST_INT, VOIDmode, 0x3ff), 0); 4094: rtx low_fn = expand_and (fnaddr, gen_rtx (CONST_INT, VOIDmode, 0x3ff), 0); 4095: rtx g1_sethi = gen_rtx (HIGH, SImode, 4096: gen_rtx (CONST_INT, VOIDmode, 0x03000000)); 4097: rtx g2_sethi = gen_rtx (HIGH, SImode, 4098: gen_rtx (CONST_INT, VOIDmode, 0x05000000)); 4099: rtx g1_ori = gen_rtx (HIGH, SImode, 4100: gen_rtx (CONST_INT, VOIDmode, 0x82106000)); 4101: rtx g2_ori = gen_rtx (HIGH, SImode, 4102: gen_rtx (CONST_INT, VOIDmode, 0x8410A000)); 4103: rtx tem = gen_reg_rtx (SImode); 4104: emit_move_insn (tem, g1_sethi); 4105: emit_insn (gen_iorsi3 (high_fn, high_fn, tem)); 4106: emit_move_insn (gen_rtx (MEM, SImode, plus_constant (tramp, 0)), high_fn); 4107: emit_move_insn (tem, g1_ori); 4108: emit_insn (gen_iorsi3 (low_fn, low_fn, tem)); 4109: emit_move_insn (gen_rtx (MEM, SImode, plus_constant (tramp, 4)), low_fn); 4110: emit_move_insn (tem, g2_sethi); 4111: emit_insn (gen_iorsi3 (high_cxt, high_cxt, tem)); 4112: emit_move_insn (gen_rtx (MEM, SImode, plus_constant (tramp, 8)), high_cxt); 4113: emit_move_insn (tem, g2_ori); 4114: emit_insn (gen_iorsi3 (low_cxt, low_cxt, tem)); 4115: emit_move_insn (gen_rtx (MEM, SImode, plus_constant (tramp, 16)), low_cxt); 1.1.1.4 ! root 4116: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, SImode, tramp)))); ! 4117: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, SImode, ! 4118: plus_constant (tramp, 8))))); ! 4119: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, SImode, ! 4120: plus_constant (tramp, 16))))); 1.1.1.3 root 4121: } 4122: 1.1.1.4 ! root 4123: /* The 64 bit version is simpler because it makes more sense to load the ! 4124: values as "immediate" data out of the trampoline. It's also easier since ! 4125: we can read the PC without clobbering a register. */ ! 4126: 1.1.1.3 root 4127: void 4128: sparc64_initialize_trampoline (tramp, fnaddr, cxt) 4129: rtx tramp, fnaddr, cxt; 4130: { 1.1.1.4 ! root 4131: emit_move_insn (gen_rtx (MEM, DImode, plus_constant (tramp, 24)), cxt); ! 4132: emit_move_insn (gen_rtx (MEM, DImode, plus_constant (tramp, 32)), fnaddr); ! 4133: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, DImode, tramp)))); ! 4134: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, DImode, ! 4135: plus_constant (tramp, 8))))); ! 4136: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, DImode, ! 4137: plus_constant (tramp, 16))))); ! 4138: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, DImode, ! 4139: plus_constant (tramp, 24))))); ! 4140: emit_insn (gen_flush (validize_mem (gen_rtx (MEM, DImode, ! 4141: plus_constant (tramp, 32))))); 1.1.1.3 root 4142: } 4143: 1.1 root 4144: /* Subroutines to support a flat (single) register window calling 4145: convention. */ 4146: 4147: /* Single-register window sparc stack frames look like: 4148: 4149: Before call After call 4150: +-----------------------+ +-----------------------+ 1.1.1.3 root 4151: high | | | | 4152: mem | caller's temps. | | caller's temps. | 1.1 root 4153: | | | | 4154: +-----------------------+ +-----------------------+ 4155: | | | | 4156: | arguments on stack. | | arguments on stack. | 1.1.1.3 root 4157: | | | | 4158: +-----------------------+FP+92->+-----------------------+ 1.1 root 4159: | 6 words to save | | 6 words to save | 4160: | arguments passed | | arguments passed | 4161: | in registers, even | | in registers, even | 1.1.1.3 root 4162: | if not passed. | | if not passed. | 4163: SP+68->+-----------------------+FP+68->+-----------------------+ 4164: | 1 word struct addr | | 1 word struct addr | 4165: +-----------------------+FP+64->+-----------------------+ 4166: | | | | 4167: | 16 word reg save area | | 16 word reg save area | 4168: | | | | 4169: SP->+-----------------------+ FP->+-----------------------+ 4170: | 4 word area for | 4171: | fp/alu reg moves | 4172: FP-16->+-----------------------+ 4173: | | 4174: | local variables | 4175: | | 4176: +-----------------------+ 4177: | | 1.1 root 4178: | fp register save | 1.1.1.3 root 4179: | | 4180: +-----------------------+ 4181: | | 1.1 root 4182: | gp register save | 4183: | | 1.1.1.3 root 4184: +-----------------------+ 4185: | | 1.1 root 4186: | alloca allocations | 1.1.1.3 root 4187: | | 4188: +-----------------------+ 4189: | | 1.1 root 4190: | arguments on stack | 1.1.1.3 root 4191: | | 4192: SP+92->+-----------------------+ 1.1 root 4193: | 6 words to save | 1.1.1.3 root 4194: | arguments passed | 1.1 root 4195: | in registers, even | 1.1.1.3 root 4196: low | if not passed. | 4197: memory SP+68->+-----------------------+ 4198: | 1 word struct addr | 4199: SP+64->+-----------------------+ 4200: | | 4201: I 16 word reg save area | 4202: | | 4203: SP->+-----------------------+ */ 1.1 root 4204: 1.1.1.3 root 4205: /* Structure to be filled in by sparc_flat_compute_frame_size with register 1.1 root 4206: save masks, and offsets for the current function. */ 4207: 4208: struct sparc_frame_info 4209: { 4210: unsigned long total_size; /* # bytes that the entire frame takes up. */ 4211: unsigned long var_size; /* # bytes that variables take up. */ 4212: unsigned long args_size; /* # bytes that outgoing arguments take up. */ 4213: unsigned long extra_size; /* # bytes of extra gunk. */ 4214: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ 4215: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ 1.1.1.3 root 4216: unsigned long gmask; /* Mask of saved gp registers. */ 1.1 root 4217: unsigned long fmask; /* Mask of saved fp registers. */ 1.1.1.3 root 4218: unsigned long reg_offset; /* Offset from new sp to store regs. */ 1.1 root 4219: int initialized; /* Nonzero if frame size already calculated. */ 4220: }; 4221: 1.1.1.3 root 4222: /* Current frame information calculated by sparc_flat_compute_frame_size. */ 1.1 root 4223: struct sparc_frame_info current_frame_info; 4224: 4225: /* Zero structure to initialize current_frame_info. */ 4226: struct sparc_frame_info zero_frame_info; 4227: 4228: /* Tell prologue and epilogue if register REGNO should be saved / restored. */ 4229: 1.1.1.3 root 4230: #define RETURN_ADDR_REGNUM 15 4231: #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM)) 4232: #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM)) 4233: 1.1 root 4234: #define MUST_SAVE_REGISTER(regno) \ 4235: ((regs_ever_live[regno] && !call_used_regs[regno]) \ 4236: || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \ 1.1.1.3 root 4237: || (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM])) 1.1 root 4238: 4239: /* Return the bytes needed to compute the frame pointer from the current 4240: stack pointer. */ 4241: 4242: unsigned long 1.1.1.3 root 4243: sparc_flat_compute_frame_size (size) 1.1 root 4244: int size; /* # of var. bytes allocated. */ 4245: { 4246: int regno; 4247: unsigned long total_size; /* # bytes that the entire frame takes up. */ 4248: unsigned long var_size; /* # bytes that variables take up. */ 4249: unsigned long args_size; /* # bytes that outgoing arguments take up. */ 4250: unsigned long extra_size; /* # extra bytes. */ 4251: unsigned int gp_reg_size; /* # bytes needed to store gp regs. */ 4252: unsigned int fp_reg_size; /* # bytes needed to store fp regs. */ 1.1.1.3 root 4253: unsigned long gmask; /* Mask of saved gp registers. */ 1.1 root 4254: unsigned long fmask; /* Mask of saved fp registers. */ 1.1.1.3 root 4255: unsigned long reg_offset; /* Offset to register save area. */ 4256: int need_aligned_p; /* 1 if need the save area 8 byte aligned. */ 1.1 root 4257: 4258: /* This is the size of the 16 word reg save area, 1 word struct addr 4259: area, and 4 word fp/alu register copy area. */ 4260: extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0); 4261: var_size = size; 4262: /* Also include the size needed for the 6 parameter registers. */ 4263: args_size = current_function_outgoing_args_size + 24; 4264: total_size = var_size + args_size + extra_size; 4265: gp_reg_size = 0; 4266: fp_reg_size = 0; 1.1.1.3 root 4267: gmask = 0; 1.1 root 4268: fmask = 0; 1.1.1.3 root 4269: reg_offset = 0; 4270: need_aligned_p = 0; 1.1 root 4271: 4272: /* Calculate space needed for gp registers. */ 4273: for (regno = 1; regno <= 31; regno++) 4274: { 4275: if (MUST_SAVE_REGISTER (regno)) 4276: { 1.1.1.3 root 4277: /* If we need to save two regs in a row, ensure there's room to bump 4278: up the address to align it to a doubleword boundary. */ 1.1 root 4279: if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1)) 4280: { 4281: if (gp_reg_size % 8 != 0) 1.1.1.3 root 4282: gp_reg_size += 4; 1.1 root 4283: gp_reg_size += 2 * UNITS_PER_WORD; 1.1.1.3 root 4284: gmask |= 3 << regno; 1.1 root 4285: regno++; 1.1.1.3 root 4286: need_aligned_p = 1; 1.1 root 4287: } 4288: else 4289: { 4290: gp_reg_size += UNITS_PER_WORD; 1.1.1.3 root 4291: gmask |= 1 << regno; 1.1 root 4292: } 4293: } 4294: } 4295: 4296: /* Calculate space needed for fp registers. */ 4297: for (regno = 32; regno <= 63; regno++) 4298: { 4299: if (regs_ever_live[regno] && !call_used_regs[regno]) 4300: { 4301: fp_reg_size += UNITS_PER_WORD; 4302: fmask |= 1 << (regno - 32); 4303: } 4304: } 4305: 1.1.1.3 root 4306: if (gmask || fmask) 4307: { 4308: int n; 4309: reg_offset = FIRST_PARM_OFFSET(0) + args_size; 4310: /* Ensure save area is 8 byte aligned if we need it. */ 4311: n = reg_offset % 8; 4312: if (need_aligned_p && n != 0) 4313: { 4314: total_size += 8 - n; 4315: reg_offset += 8 - n; 4316: } 4317: total_size += gp_reg_size + fp_reg_size; 4318: } 1.1 root 4319: 1.1.1.3 root 4320: /* ??? This looks a little suspicious. Clarify. */ 1.1 root 4321: if (total_size == extra_size) 4322: total_size = extra_size = 0; 4323: 4324: total_size = SPARC_STACK_ALIGN (total_size); 4325: 4326: /* Save other computed information. */ 4327: current_frame_info.total_size = total_size; 4328: current_frame_info.var_size = var_size; 4329: current_frame_info.args_size = args_size; 4330: current_frame_info.extra_size = extra_size; 4331: current_frame_info.gp_reg_size = gp_reg_size; 4332: current_frame_info.fp_reg_size = fp_reg_size; 1.1.1.3 root 4333: current_frame_info.gmask = gmask; 1.1 root 4334: current_frame_info.fmask = fmask; 1.1.1.3 root 4335: current_frame_info.reg_offset = reg_offset; 1.1 root 4336: current_frame_info.initialized = reload_completed; 4337: 4338: /* Ok, we're done. */ 4339: return total_size; 4340: } 4341: 1.1.1.3 root 4342: /* Save/restore registers in GMASK and FMASK at register BASE_REG plus offset 4343: OFFSET. 4344: 4345: BASE_REG must be 8 byte aligned. This allows us to test OFFSET for 4346: appropriate alignment and use DOUBLEWORD_OP when we can. We assume 4347: [BASE_REG+OFFSET] will always be a valid address. 4348: 4349: WORD_OP is either "st" for save, "ld" for restore. 4350: DOUBLEWORD_OP is either "std" for save, "ldd" for restore. */ 1.1 root 4351: 4352: void 1.1.1.3 root 4353: sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, doubleword_op) 4354: FILE *file; 4355: char *base_reg; 4356: unsigned int offset; 4357: unsigned long gmask; 4358: unsigned long fmask; 4359: char *word_op; 4360: char *doubleword_op; 1.1 root 4361: { 4362: int regno; 4363: 1.1.1.3 root 4364: if (gmask == 0 && fmask == 0) 1.1 root 4365: return; 4366: 1.1.1.3 root 4367: /* Save registers starting from high to low. We've already saved the 4368: previous frame pointer and previous return address for the debugger's 4369: sake. The debugger allows us to not need a nop in the epilog if at least 4370: one register is reloaded in addition to return address. */ 1.1 root 4371: 1.1.1.3 root 4372: if (gmask) 1.1 root 4373: { 4374: for (regno = 1; regno <= 31; regno++) 4375: { 1.1.1.3 root 4376: if ((gmask & (1L << regno)) != 0) 1.1 root 4377: { 1.1.1.3 root 4378: if ((regno & 0x1) == 0 && ((gmask & (1L << (regno+1))) != 0)) 1.1 root 4379: { 1.1.1.3 root 4380: /* We can save two registers in a row. If we're not at a 4381: double word boundary, move to one. 4382: sparc_flat_compute_frame_size ensures there's room to do 4383: this. */ 4384: if (offset % 8 != 0) 4385: offset += UNITS_PER_WORD; 4386: 1.1 root 4387: if (word_op[0] == 's') 4388: fprintf (file, "\t%s %s,[%s+%d]\n", 4389: doubleword_op, reg_names[regno], 1.1.1.3 root 4390: base_reg, offset); 1.1 root 4391: else 4392: fprintf (file, "\t%s [%s+%d],%s\n", 1.1.1.3 root 4393: doubleword_op, base_reg, offset, 1.1 root 4394: reg_names[regno]); 4395: 1.1.1.3 root 4396: offset += 2 * UNITS_PER_WORD; 1.1 root 4397: regno++; 4398: } 4399: else 4400: { 4401: if (word_op[0] == 's') 4402: fprintf (file, "\t%s %s,[%s+%d]\n", 4403: word_op, reg_names[regno], 1.1.1.3 root 4404: base_reg, offset); 1.1 root 4405: else 4406: fprintf (file, "\t%s [%s+%d],%s\n", 1.1.1.3 root 4407: word_op, base_reg, offset, reg_names[regno]); 1.1 root 4408: 1.1.1.3 root 4409: offset += UNITS_PER_WORD; 1.1 root 4410: } 4411: } 4412: } 4413: } 4414: 4415: if (fmask) 4416: { 4417: for (regno = 32; regno <= 63; regno++) 4418: { 4419: if ((fmask & (1L << (regno - 32))) != 0) 4420: { 4421: if (word_op[0] == 's') 4422: fprintf (file, "\t%s %s,[%s+%d]\n", 4423: word_op, reg_names[regno], 1.1.1.3 root 4424: base_reg, offset); 1.1 root 4425: else 4426: fprintf (file, "\t%s [%s+%d],%s\n", 1.1.1.3 root 4427: word_op, base_reg, offset, reg_names[regno]); 1.1 root 4428: 1.1.1.3 root 4429: offset += UNITS_PER_WORD; 1.1 root 4430: } 4431: } 4432: } 4433: } 4434: 4435: /* Set up the stack and frame (if desired) for the function. */ 4436: 4437: void 1.1.1.3 root 4438: sparc_flat_output_function_prologue (file, size) 1.1 root 4439: FILE *file; 4440: int size; 4441: { 4442: char *sp_str = reg_names[STACK_POINTER_REGNUM]; 1.1.1.3 root 4443: unsigned long gmask = current_frame_info.gmask; 1.1 root 4444: 1.1.1.3 root 4445: /* This is only for the human reader. */ 1.1 root 4446: fprintf (file, "\t!#PROLOGUE# 0\n"); 1.1.1.3 root 4447: fprintf (file, "\t!# vars= %d, regs= %d/%d, args= %d, extra= %d\n", 4448: current_frame_info.var_size, 4449: current_frame_info.gp_reg_size / 4, 4450: current_frame_info.fp_reg_size / 4, 4451: current_function_outgoing_args_size, 4452: current_frame_info.extra_size); 1.1 root 4453: 4454: size = SPARC_STACK_ALIGN (size); 1.1.1.3 root 4455: size = (! current_frame_info.initialized 4456: ? sparc_flat_compute_frame_size (size) 4457: : current_frame_info.total_size); 1.1 root 4458: 1.1.1.3 root 4459: /* These cases shouldn't happen. Catch them now. */ 4460: if (size == 0 && (gmask || current_frame_info.fmask)) 4461: abort (); 4462: 4463: /* Allocate our stack frame by decrementing %sp. 4464: At present, the only algorithm gdb can use to determine if this is a 4465: flat frame is if we always set %i7 if we set %sp. This can be optimized 4466: in the future by putting in some sort of debugging information that says 4467: this is a `flat' function. However, there is still the case of debugging 4468: code without such debugging information (including cases where most fns 4469: have such info, but there is one that doesn't). So, always do this now 4470: so we don't get a lot of code out there that gdb can't handle. 4471: If the frame pointer isn't needn't then that's ok - gdb won't be able to 4472: distinguish us from a non-flat function but there won't (and shouldn't) 4473: be any differences anyway. The return pc is saved (if necessary) right 4474: after %i7 so gdb won't have to look too far to find it. */ 4475: if (size > 0) 4476: { 4477: unsigned int reg_offset = current_frame_info.reg_offset; 4478: char *fp_str = reg_names[FRAME_POINTER_REGNUM]; 4479: char *t1_str = "%g1"; 4480: 4481: /* Things get a little tricky if local variables take up more than ~4096 4482: bytes and outgoing arguments take up more than ~4096 bytes. When that 4483: happens, the register save area can't be accessed from either end of 4484: the frame. Handle this by decrementing %sp to the start of the gp 4485: register save area, save the regs, update %i7, and then set %sp to its 4486: final value. Given that we only have one scratch register to play 4487: with it is the cheapest solution, and it helps gdb out as it won't 4488: slow down recognition of flat functions. 4489: Don't change the order of insns emitted here without checking with 4490: the gdb folk first. */ 4491: 1.1.1.4 ! root 4492: /* Is the entire register save area offsettable from %sp? */ 1.1.1.3 root 4493: if (reg_offset < 4096 - 64 * UNITS_PER_WORD) 4494: { 4495: if (size <= 4096) 4496: { 4497: fprintf (file, "\tadd %s,%d,%s\n", 4498: sp_str, -size, sp_str); 4499: if (gmask & FRAME_POINTER_MASK) 4500: { 4501: fprintf (file, "\tst %s,[%s+%d]\n", 4502: fp_str, sp_str, reg_offset); 4503: fprintf (file, "\tsub %s,%d,%s\t!# set up frame pointer\n", 4504: sp_str, -size, fp_str); 4505: reg_offset += 4; 4506: } 4507: } 4508: else 4509: { 4510: fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", 4511: size, t1_str, sp_str, t1_str, sp_str); 4512: if (gmask & FRAME_POINTER_MASK) 4513: { 4514: fprintf (file, "\tst %s,[%s+%d]\n", 4515: fp_str, sp_str, reg_offset); 4516: fprintf (file, "\tadd %s,%s,%s\t!# set up frame pointer\n", 4517: sp_str, t1_str, fp_str); 4518: reg_offset += 4; 4519: } 4520: } 4521: if (gmask & RETURN_ADDR_MASK) 4522: { 4523: fprintf (file, "\tst %s,[%s+%d]\n", 4524: reg_names[RETURN_ADDR_REGNUM], sp_str, reg_offset); 4525: reg_offset += 4; 4526: } 4527: sparc_flat_save_restore (file, sp_str, reg_offset, 4528: gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 4529: current_frame_info.fmask, 4530: "st", "std"); 4531: } 1.1 root 4532: else 1.1.1.3 root 4533: { 4534: /* Subtract %sp in two steps, but make sure there is always a 4535: 64 byte register save area, and %sp is properly aligned. */ 4536: /* Amount to decrement %sp by, the first time. */ 4537: unsigned int size1 = ((size - reg_offset + 64) + 15) & -16; 4538: /* Offset to register save area from %sp. */ 4539: unsigned int offset = size1 - (size - reg_offset); 4540: 4541: if (size1 <= 4096) 4542: { 4543: fprintf (file, "\tadd %s,%d,%s\n", 4544: sp_str, -size1, sp_str); 4545: if (gmask & FRAME_POINTER_MASK) 4546: { 4547: fprintf (file, "\tst %s,[%s+%d]\n\tsub %s,%d,%s\t!# set up frame pointer\n", 4548: fp_str, sp_str, offset, sp_str, -size1, fp_str); 4549: offset += 4; 4550: } 4551: } 4552: else 4553: { 4554: fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", 4555: size1, t1_str, sp_str, t1_str, sp_str); 4556: if (gmask & FRAME_POINTER_MASK) 4557: { 4558: fprintf (file, "\tst %s,[%s+%d]\n\tadd %s,%s,%s\t!# set up frame pointer\n", 4559: fp_str, sp_str, offset, sp_str, t1_str, fp_str); 4560: offset += 4; 4561: } 4562: } 4563: if (gmask & RETURN_ADDR_MASK) 4564: { 4565: fprintf (file, "\tst %s,[%s+%d]\n", 4566: reg_names[RETURN_ADDR_REGNUM], sp_str, offset); 4567: offset += 4; 4568: } 4569: sparc_flat_save_restore (file, sp_str, offset, 4570: gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 4571: current_frame_info.fmask, 4572: "st", "std"); 4573: fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", 4574: size - size1, t1_str, sp_str, t1_str, sp_str); 4575: } 1.1 root 4576: } 1.1.1.3 root 4577: 4578: fprintf (file, "\t!#PROLOGUE# 1\n"); 1.1 root 4579: } 4580: 4581: /* Do any necessary cleanup after a function to restore stack, frame, 4582: and regs. */ 4583: 4584: void 1.1.1.3 root 4585: sparc_flat_output_function_epilogue (file, size) 1.1 root 4586: FILE *file; 4587: int size; 4588: { 4589: rtx epilogue_delay = current_function_epilogue_delay_list; 4590: int noepilogue = FALSE; 4591: 1.1.1.3 root 4592: /* This is only for the human reader. */ 4593: fprintf (file, "\t!#EPILOGUE#\n"); 4594: 1.1 root 4595: /* The epilogue does not depend on any registers, but the stack 4596: registers, so we assume that if we have 1 pending nop, it can be 4597: ignored, and 2 it must be filled (2 nops occur for integer 4598: multiply and divide). */ 4599: 4600: size = SPARC_STACK_ALIGN (size); 1.1.1.3 root 4601: size = (!current_frame_info.initialized 4602: ? sparc_flat_compute_frame_size (size) 1.1 root 4603: : current_frame_info.total_size); 4604: 1.1.1.3 root 4605: if (size == 0 && epilogue_delay == 0) 1.1 root 4606: { 4607: rtx insn = get_last_insn (); 4608: 4609: /* If the last insn was a BARRIER, we don't have to write any code 4610: because a jump (aka return) was put there. */ 4611: if (GET_CODE (insn) == NOTE) 4612: insn = prev_nonnote_insn (insn); 4613: if (insn && GET_CODE (insn) == BARRIER) 4614: noepilogue = TRUE; 4615: } 4616: 4617: if (!noepilogue) 4618: { 1.1.1.3 root 4619: unsigned int reg_offset = current_frame_info.reg_offset; 4620: unsigned int size1; 4621: char *sp_str = reg_names[STACK_POINTER_REGNUM]; 4622: char *fp_str = reg_names[FRAME_POINTER_REGNUM]; 4623: char *t1_str = "%g1"; 4624: 1.1 root 4625: /* In the reload sequence, we don't need to fill the load delay 4626: slots for most of the loads, also see if we can fill the final 4627: delay slot if not otherwise filled by the reload sequence. */ 4628: 1.1.1.3 root 4629: if (size > 4095) 4630: fprintf (file, "\tset %d,%s\n", size, t1_str); 1.1 root 4631: 4632: if (frame_pointer_needed) 4633: { 1.1.1.3 root 4634: if (size > 4095) 4635: fprintf (file,"\tsub %s,%s,%s\t\t!# sp not trusted here\n", 1.1 root 4636: fp_str, t1_str, sp_str); 4637: else 1.1.1.3 root 4638: fprintf (file,"\tsub %s,%d,%s\t\t!# sp not trusted here\n", 4639: fp_str, size, sp_str); 1.1 root 4640: } 4641: 1.1.1.4 ! root 4642: /* Is the entire register save area offsettable from %sp? */ 1.1.1.3 root 4643: if (reg_offset < 4096 - 64 * UNITS_PER_WORD) 4644: { 4645: size1 = 0; 4646: } 4647: else 4648: { 4649: /* Restore %sp in two steps, but make sure there is always a 4650: 64 byte register save area, and %sp is properly aligned. */ 4651: /* Amount to increment %sp by, the first time. */ 4652: size1 = ((reg_offset - 64 - 16) + 15) & -16; 4653: /* Offset to register save area from %sp. */ 4654: reg_offset = size1 - reg_offset; 4655: 4656: fprintf (file, "\tset %d,%s\n\tadd %s,%s,%s\n", 4657: size1, t1_str, sp_str, t1_str, sp_str); 4658: } 4659: 4660: /* We must restore the frame pointer and return address reg first 4661: because they are treated specially by the prologue output code. */ 4662: if (current_frame_info.gmask & FRAME_POINTER_MASK) 4663: { 4664: fprintf (file, "\tld [%s+%d],%s\n", 4665: sp_str, reg_offset, fp_str); 4666: reg_offset += 4; 4667: } 4668: if (current_frame_info.gmask & RETURN_ADDR_MASK) 4669: { 4670: fprintf (file, "\tld [%s+%d],%s\n", 4671: sp_str, reg_offset, reg_names[RETURN_ADDR_REGNUM]); 4672: reg_offset += 4; 4673: } 4674: 4675: /* Restore any remaining saved registers. */ 4676: sparc_flat_save_restore (file, sp_str, reg_offset, 4677: current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 4678: current_frame_info.fmask, 4679: "ld", "ldd"); 4680: 4681: /* If we had to increment %sp in two steps, record it so the second 4682: restoration in the epilogue finishes up. */ 4683: if (size1 > 0) 4684: { 4685: size -= size1; 4686: if (size > 4095) 4687: fprintf (file, "\tset %d,%s\n", 4688: size, t1_str); 4689: } 1.1 root 4690: 4691: if (current_function_returns_struct) 4692: fprintf (file, "\tjmp %%o7+12\n"); 4693: else 4694: fprintf (file, "\tretl\n"); 4695: 4696: /* If the only register saved is the return address, we need a 4697: nop, unless we have an instruction to put into it. Otherwise 4698: we don't since reloading multiple registers doesn't reference 4699: the register being loaded. */ 4700: 4701: if (epilogue_delay) 4702: { 1.1.1.3 root 4703: if (size) 1.1 root 4704: abort (); 4705: final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1); 4706: } 4707: 1.1.1.3 root 4708: else if (size > 4095) 1.1 root 4709: fprintf (file, "\tadd %s,%s,%s\n", sp_str, t1_str, sp_str); 4710: 1.1.1.3 root 4711: else if (size > 0) 4712: fprintf (file, "\tadd %s,%d,%s\n", sp_str, size, sp_str); 1.1 root 4713: 4714: else 4715: fprintf (file, "\tnop\n"); 4716: } 4717: 4718: /* Reset state info for each function. */ 4719: current_frame_info = zero_frame_info; 4720: } 4721: 4722: /* Define the number of delay slots needed for the function epilogue. 4723: 4724: On the sparc, we need a slot if either no stack has been allocated, 4725: or the only register saved is the return register. */ 4726: 4727: int 1.1.1.3 root 4728: sparc_flat_epilogue_delay_slots () 1.1 root 4729: { 4730: if (!current_frame_info.initialized) 1.1.1.3 root 4731: (void) sparc_flat_compute_frame_size (get_frame_size ()); 1.1 root 4732: 4733: if (current_frame_info.total_size == 0) 4734: return 1; 4735: 4736: return 0; 4737: } 4738: 4739: /* Return true is TRIAL is a valid insn for the epilogue delay slot. 4740: Any single length instruction which doesn't reference the stack or frame 4741: pointer is OK. */ 4742: 4743: int 1.1.1.3 root 4744: sparc_flat_eligible_for_epilogue_delay (trial, slot) 1.1 root 4745: rtx trial; 4746: int slot; 4747: { 4748: if (get_attr_length (trial) == 1 4749: && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial)) 4750: && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial))) 4751: return 1; 4752: return 0; 4753: } 1.1.1.3 root 4754: 4755: /* Adjust the cost of a scheduling dependency. Return the new cost of 4756: a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 4757: 4758: int 4759: supersparc_adjust_cost (insn, link, dep_insn, cost) 4760: rtx insn; 4761: rtx link; 4762: rtx dep_insn; 4763: int cost; 4764: { 4765: enum attr_type insn_type; 4766: 4767: if (! recog_memoized (insn)) 4768: return 0; 4769: 4770: insn_type = get_attr_type (insn); 4771: 4772: if (REG_NOTE_KIND (link) == 0) 4773: { 4774: /* Data dependency; DEP_INSN writes a register that INSN reads some 4775: cycles later. */ 4776: 4777: /* if a load, then the dependence must be on the memory address; 4778: add an extra 'cycle'. Note that the cost could be two cycles 4779: if the reg was written late in an instruction group; we can't tell 4780: here. */ 4781: if (insn_type == TYPE_LOAD || insn_type == TYPE_FPLOAD) 4782: return cost + 3; 4783: 4784: /* Get the delay only if the address of the store is the dependence. */ 4785: if (insn_type == TYPE_STORE || insn_type == TYPE_FPSTORE) 4786: { 4787: rtx pat = PATTERN(insn); 4788: rtx dep_pat = PATTERN (dep_insn); 4789: 4790: if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) 4791: return cost; /* This shouldn't happen! */ 4792: 4793: /* The dependency between the two instructions was on the data that 4794: is being stored. Assume that this implies that the address of the 4795: store is not dependent. */ 4796: if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) 4797: return cost; 4798: 4799: return cost + 3; /* An approximation. */ 4800: } 4801: 4802: /* A shift instruction cannot receive its data from an instruction 4803: in the same cycle; add a one cycle penalty. */ 4804: if (insn_type == TYPE_SHIFT) 4805: return cost + 3; /* Split before cascade into shift. */ 4806: } 4807: else 4808: { 4809: /* Anti- or output- dependency; DEP_INSN reads/writes a register that 4810: INSN writes some cycles later. */ 4811: 4812: /* These are only significant for the fpu unit; writing a fp reg before 4813: the fpu has finished with it stalls the processor. */ 4814: 4815: /* Reusing an integer register causes no problems. */ 4816: if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT) 4817: return 0; 4818: } 4819: 4820: return cost; 4821: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.