|
|
1.1 root 1: /* Subroutines used for code generation on IBM RS/6000. 1.1.1.4 ! root 2: Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc. 1.1.1.3 root 3: Contributed by Richard Kenner ([email protected]) 1.1 root 4: 5: This file is part of GNU CC. 6: 7: GNU CC is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU CC is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU CC; see the file COPYING. If not, write to 1.1.1.4 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: Boston, MA 02111-1307, USA. */ 1.1 root 21: 22: #include <stdio.h> 1.1.1.3 root 23: #include <ctype.h> 1.1 root 24: #include "config.h" 25: #include "rtl.h" 26: #include "regs.h" 27: #include "hard-reg-set.h" 28: #include "real.h" 29: #include "insn-config.h" 30: #include "conditions.h" 31: #include "insn-flags.h" 32: #include "output.h" 33: #include "insn-attr.h" 34: #include "flags.h" 35: #include "recog.h" 36: #include "expr.h" 37: #include "obstack.h" 38: #include "tree.h" 39: 40: extern char *language_string; 1.1.1.2 root 41: extern int profile_block_flag; 1.1 root 42: 43: #define min(A,B) ((A) < (B) ? (A) : (B)) 44: #define max(A,B) ((A) > (B) ? (A) : (B)) 45: 1.1.1.2 root 46: /* Target cpu type */ 47: 48: enum processor_type rs6000_cpu; 49: char *rs6000_cpu_string; 50: 1.1 root 51: /* Set to non-zero by "fix" operation to indicate that itrunc and 52: uitrunc must be defined. */ 53: 54: int rs6000_trunc_used; 55: 56: /* Set to non-zero once they have been defined. */ 57: 58: static int trunc_defined; 59: 1.1.1.3 root 60: /* Set to non-zero once AIX common-mode calls have been defined. */ 61: static int common_mode_defined; 1.1 root 62: /* Save information from a "cmpxx" operation until the branch or scc is 63: emitted. */ 64: 65: rtx rs6000_compare_op0, rs6000_compare_op1; 66: int rs6000_compare_fp_p; 1.1.1.4 ! root 67: ! 68: #ifdef USING_SVR4_H ! 69: /* Label number of label created for -mrelocatable, to call to so we can ! 70: get the address of the GOT section */ ! 71: int rs6000_pic_labelno; ! 72: #endif ! 73: ! 74: /* Whether a System V.4 varargs area was created. */ ! 75: int rs6000_sysv_varargs_p; ! 76: ! 77: /* Temporary memory used to convert integer -> float */ ! 78: static rtx stack_temps[NUM_MACHINE_MODES]; ! 79: ! 80: ! 81: /* Print the options used in the assembly file. */ ! 82: ! 83: extern char *version_string, *language_string; ! 84: ! 85: struct asm_option ! 86: { ! 87: char *string; ! 88: int *variable; ! 89: int on_value; ! 90: }; ! 91: ! 92: #define MAX_LINE 79 ! 93: ! 94: static int ! 95: output_option (file, type, name, pos) ! 96: FILE *file; ! 97: char *type; ! 98: char *name; ! 99: int pos; ! 100: { ! 101: int type_len = strlen (type); ! 102: int name_len = strlen (name); ! 103: ! 104: if (1 + type_len + name_len + pos > MAX_LINE) ! 105: { ! 106: fprintf (file, "\n # %s%s", type, name); ! 107: return 3 + type_len + name_len; ! 108: } ! 109: fprintf (file, " %s%s", type, name); ! 110: return pos + 1 + type_len + name_len; ! 111: } ! 112: ! 113: static struct { char *name; int value; } m_options[] = TARGET_SWITCHES; ! 114: ! 115: void ! 116: output_options (file, f_options, f_len, W_options, W_len) ! 117: FILE *file; ! 118: struct asm_option *f_options; ! 119: int f_len; ! 120: struct asm_option *W_options; ! 121: int W_len; ! 122: { ! 123: int j; ! 124: int flags = target_flags; ! 125: int pos = 32767; ! 126: ! 127: fprintf (file, " # %s %s", language_string, version_string); ! 128: ! 129: if (optimize) ! 130: { ! 131: char opt_string[20]; ! 132: sprintf (opt_string, "%d", optimize); ! 133: pos = output_option (file, "-O", opt_string, pos); ! 134: } ! 135: ! 136: if (profile_flag) ! 137: pos = output_option (file, "-p", "", pos); ! 138: ! 139: if (profile_block_flag) ! 140: pos = output_option (file, "-a", "", pos); ! 141: ! 142: if (inhibit_warnings) ! 143: pos = output_option (file, "-w", "", pos); ! 144: ! 145: for (j = 0; j < f_len; j++) ! 146: { ! 147: if (*f_options[j].variable == f_options[j].on_value) ! 148: pos = output_option (file, "-f", f_options[j].string, pos); ! 149: } ! 150: ! 151: for (j = 0; j < W_len; j++) ! 152: { ! 153: if (*W_options[j].variable == W_options[j].on_value) ! 154: pos = output_option (file, "-W", W_options[j].string, pos); ! 155: } ! 156: ! 157: for (j = 0; j < sizeof m_options / sizeof m_options[0]; j++) ! 158: { ! 159: if (m_options[j].name[0] != '\0' ! 160: && m_options[j].value > 0 ! 161: && ((m_options[j].value & flags) == m_options[j].value)) ! 162: { ! 163: pos = output_option (file, "-m", m_options[j].name, pos); ! 164: flags &= ~ m_options[j].value; ! 165: } ! 166: } ! 167: ! 168: if (rs6000_cpu_string != (char *)0) ! 169: pos = output_option (file, "-mcpu=", rs6000_cpu_string, pos); ! 170: ! 171: fputs ("\n\n", file); ! 172: } ! 173: 1.1 root 174: 1.1.1.2 root 175: /* Override command line options. Mostly we process the processor 176: type and sometimes adjust other TARGET_ options. */ 177: 178: void 179: rs6000_override_options () 180: { 181: int i; 182: 183: /* Simplify the entries below by making a mask for any POWER 184: variant and any PowerPC variant. */ 185: 1.1.1.4 ! root 186: #define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING) 1.1.1.3 root 187: #define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \ 188: | MASK_PPC_GFXOPT | MASK_POWERPC64) 189: #define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT) 1.1.1.2 root 190: 191: static struct ptt 192: { 193: char *name; /* Canonical processor name. */ 194: enum processor_type processor; /* Processor type enum value. */ 195: int target_enable; /* Target flags to enable. */ 196: int target_disable; /* Target flags to disable. */ 197: } processor_target_table[] 1.1.1.3 root 198: = {{"common", PROCESSOR_COMMON, 0, POWER_MASKS | POWERPC_MASKS}, 199: {"power", PROCESSOR_POWER, 1.1.1.4 ! root 200: MASK_POWER | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 201: MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, 202: {"powerpc", PROCESSOR_POWERPC, 203: MASK_POWERPC | MASK_NEW_MNEMONICS, 204: POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, 205: {"rios", PROCESSOR_RIOS1, 1.1.1.4 ! root 206: MASK_POWER | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 207: MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, 208: {"rios1", PROCESSOR_RIOS1, 1.1.1.4 ! root 209: MASK_POWER | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 210: MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, 211: {"rsc", PROCESSOR_PPC601, 1.1.1.4 ! root 212: MASK_POWER | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 213: MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, 214: {"rsc1", PROCESSOR_PPC601, 1.1.1.4 ! root 215: MASK_POWER | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 216: MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS}, 217: {"rios2", PROCESSOR_RIOS2, 1.1.1.4 ! root 218: MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2, 1.1.1.3 root 219: POWERPC_MASKS | MASK_NEW_MNEMONICS}, 1.1.1.4 ! root 220: {"403", PROCESSOR_PPC403, ! 221: MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS, ! 222: POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}, 1.1.1.2 root 223: {"601", PROCESSOR_PPC601, 1.1.1.4 ! root 224: MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING, 1.1.1.3 root 225: MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64}, 1.1.1.2 root 226: {"603", PROCESSOR_PPC603, 1.1.1.3 root 227: MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, 228: POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}, 1.1.1.2 root 229: {"604", PROCESSOR_PPC604, 1.1.1.3 root 230: MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS, 1.1.1.4 ! root 231: POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64}}; 1.1.1.2 root 232: 233: int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt); 234: 1.1.1.4 ! root 235: int multiple = TARGET_MULTIPLE; /* save current -mmultiple/-mno-multiple status */ ! 236: int string = TARGET_STRING; /* save current -mstring/-mno-string status */ ! 237: 1.1.1.2 root 238: profile_block_flag = 0; 239: 240: /* Identify the processor type */ 241: if (rs6000_cpu_string == 0) 242: rs6000_cpu = PROCESSOR_DEFAULT; 243: else 244: { 245: for (i = 0; i < ptt_size; i++) 246: if (! strcmp (rs6000_cpu_string, processor_target_table[i].name)) 247: { 248: rs6000_cpu = processor_target_table[i].processor; 249: target_flags |= processor_target_table[i].target_enable; 250: target_flags &= ~processor_target_table[i].target_disable; 251: break; 252: } 253: 254: if (i == ptt_size) 255: { 256: error ("bad value (%s) for -mcpu= switch", rs6000_cpu_string); 257: rs6000_cpu_string = "default"; 258: rs6000_cpu = PROCESSOR_DEFAULT; 259: } 260: } 1.1.1.4 ! root 261: ! 262: /* If -mmultiple or -mno-multiple was explicitly used, don't ! 263: override with the processor default */ ! 264: if (TARGET_MULTIPLE_SET) ! 265: target_flags = (target_flags & ~MASK_MULTIPLE) | multiple; ! 266: ! 267: /* If -mstring or -mno-string was explicitly used, don't ! 268: override with the processor default */ ! 269: if (TARGET_STRING_SET) ! 270: target_flags = (target_flags & ~MASK_STRING) | string; ! 271: ! 272: /* Don't allow -mmultiple or -mstring on little endian systems, because the ! 273: hardware doesn't support the instructions used in little endian mode */ ! 274: if (!BYTES_BIG_ENDIAN) ! 275: { ! 276: if (TARGET_MULTIPLE) ! 277: { ! 278: target_flags &= ~MASK_MULTIPLE; ! 279: if (TARGET_MULTIPLE_SET) ! 280: warning ("-mmultiple is not supported on little endian systems"); ! 281: } ! 282: ! 283: if (TARGET_STRING) ! 284: { ! 285: target_flags &= ~MASK_STRING; ! 286: if (TARGET_STRING_SET) ! 287: warning ("-mstring is not supported on little endian systems"); ! 288: } ! 289: } ! 290: ! 291: #ifdef SUBTARGET_OVERRIDE_OPTIONS ! 292: SUBTARGET_OVERRIDE_OPTIONS; ! 293: #endif ! 294: } ! 295: ! 296: /* Create a CONST_DOUBLE from a string. */ ! 297: ! 298: struct rtx_def * ! 299: rs6000_float_const (string, mode) ! 300: char *string; ! 301: enum machine_mode mode; ! 302: { ! 303: REAL_VALUE_TYPE value = REAL_VALUE_ATOF (string, mode); ! 304: return immed_real_const_1 (value, mode); 1.1.1.2 root 305: } 1.1.1.4 ! root 306: ! 307: ! 308: /* Create a CONST_DOUBLE like immed_double_const, except reverse the ! 309: two parts of the constant if the target is little endian. */ ! 310: ! 311: struct rtx_def * ! 312: rs6000_immed_double_const (i0, i1, mode) ! 313: HOST_WIDE_INT i0, i1; ! 314: enum machine_mode mode; ! 315: { ! 316: if (! WORDS_BIG_ENDIAN) ! 317: return immed_double_const (i1, i0, mode); ! 318: ! 319: return immed_double_const (i0, i1, mode); ! 320: } ! 321: 1.1.1.2 root 322: 1.1 root 323: /* Return non-zero if this function is known to have a null epilogue. */ 324: 325: int 326: direct_return () 327: { 1.1.1.4 ! root 328: if (reload_completed) ! 329: { ! 330: rs6000_stack_t *info = rs6000_stack_info (); ! 331: ! 332: if (info->first_gp_reg_save == 32 ! 333: && info->first_fp_reg_save == 64 ! 334: && !info->lr_save_p ! 335: && !info->cr_save_p ! 336: && !info->push_p) ! 337: return 1; ! 338: } ! 339: ! 340: return 0; 1.1 root 341: } 342: 343: /* Returns 1 always. */ 344: 345: int 346: any_operand (op, mode) 347: register rtx op; 348: enum machine_mode mode; 349: { 350: return 1; 351: } 352: 353: /* Return 1 if OP is a constant that can fit in a D field. */ 354: 355: int 356: short_cint_operand (op, mode) 357: register rtx op; 358: enum machine_mode mode; 359: { 360: return (GET_CODE (op) == CONST_INT 361: && (unsigned) (INTVAL (op) + 0x8000) < 0x10000); 362: } 363: 364: /* Similar for a unsigned D field. */ 365: 366: int 367: u_short_cint_operand (op, mode) 368: register rtx op; 369: enum machine_mode mode; 370: { 371: return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0); 372: } 373: 374: /* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */ 375: 376: int 377: non_short_cint_operand (op, mode) 378: register rtx op; 379: enum machine_mode mode; 380: { 381: return (GET_CODE (op) == CONST_INT 382: && (unsigned) (INTVAL (op) + 0x8000) >= 0x10000); 383: } 384: 385: /* Returns 1 if OP is a register that is not special (i.e., not MQ, 386: ctr, or lr). */ 387: 388: int 389: gpc_reg_operand (op, mode) 390: register rtx op; 391: enum machine_mode mode; 392: { 393: return (register_operand (op, mode) 394: && (GET_CODE (op) != REG || REGNO (op) >= 67 || REGNO (op) < 64)); 395: } 396: 397: /* Returns 1 if OP is either a pseudo-register or a register denoting a 398: CR field. */ 399: 400: int 401: cc_reg_operand (op, mode) 402: register rtx op; 403: enum machine_mode mode; 404: { 405: return (register_operand (op, mode) 406: && (GET_CODE (op) != REG 407: || REGNO (op) >= FIRST_PSEUDO_REGISTER 408: || CR_REGNO_P (REGNO (op)))); 409: } 410: 411: /* Returns 1 if OP is either a constant integer valid for a D-field or a 412: non-special register. If a register, it must be in the proper mode unless 413: MODE is VOIDmode. */ 414: 415: int 416: reg_or_short_operand (op, mode) 417: register rtx op; 418: enum machine_mode mode; 419: { 1.1.1.2 root 420: return short_cint_operand (op, mode) || gpc_reg_operand (op, mode); 1.1 root 421: } 422: 423: /* Similar, except check if the negation of the constant would be valid for 424: a D-field. */ 425: 426: int 427: reg_or_neg_short_operand (op, mode) 428: register rtx op; 429: enum machine_mode mode; 430: { 431: if (GET_CODE (op) == CONST_INT) 432: return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P'); 433: 434: return gpc_reg_operand (op, mode); 435: } 436: 437: /* Return 1 if the operand is either a register or an integer whose high-order 438: 16 bits are zero. */ 439: 440: int 441: reg_or_u_short_operand (op, mode) 442: register rtx op; 443: enum machine_mode mode; 444: { 445: if (GET_CODE (op) == CONST_INT 446: && (INTVAL (op) & 0xffff0000) == 0) 447: return 1; 448: 449: return gpc_reg_operand (op, mode); 450: } 451: 452: /* Return 1 is the operand is either a non-special register or ANY 453: constant integer. */ 454: 455: int 456: reg_or_cint_operand (op, mode) 457: register rtx op; 458: enum machine_mode mode; 459: { 460: return GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode); 461: } 462: 1.1.1.2 root 463: /* Return 1 if the operand is a CONST_DOUBLE and it can be put into a register 464: with one instruction per word. We only do this if we can safely read 465: CONST_DOUBLE_{LOW,HIGH}. */ 1.1 root 466: 467: int 468: easy_fp_constant (op, mode) 469: register rtx op; 470: register enum machine_mode mode; 471: { 472: rtx low, high; 473: 474: if (GET_CODE (op) != CONST_DOUBLE 475: || GET_MODE (op) != mode 476: || GET_MODE_CLASS (mode) != MODE_FLOAT) 477: return 0; 478: 479: high = operand_subword (op, 0, 0, mode); 480: low = operand_subword (op, 1, 0, mode); 481: 1.1.1.2 root 482: if (high == 0 || ! input_operand (high, word_mode)) 1.1 root 483: return 0; 484: 485: return (mode == SFmode 1.1.1.2 root 486: || (low != 0 && input_operand (low, word_mode))); 1.1 root 487: } 1.1.1.4 ! root 488: ! 489: /* Return 1 if the operand is an offsettable memory address. */ ! 490: ! 491: int ! 492: offsettable_addr_operand (op, mode) ! 493: register rtx op; ! 494: enum machine_mode mode; ! 495: { ! 496: return offsettable_address_p (reload_completed | reload_in_progress, ! 497: mode, op); ! 498: } ! 499: 1.1 root 500: /* Return 1 if the operand is either a floating-point register, a pseudo 501: register, or memory. */ 502: 503: int 504: fp_reg_or_mem_operand (op, mode) 505: register rtx op; 506: enum machine_mode mode; 507: { 508: return (memory_operand (op, mode) 509: || (register_operand (op, mode) 510: && (GET_CODE (op) != REG 511: || REGNO (op) >= FIRST_PSEUDO_REGISTER 512: || FP_REGNO_P (REGNO (op))))); 513: } 514: 515: /* Return 1 if the operand is either an easy FP constant (see above) or 516: memory. */ 517: 518: int 519: mem_or_easy_const_operand (op, mode) 520: register rtx op; 521: enum machine_mode mode; 522: { 523: return memory_operand (op, mode) || easy_fp_constant (op, mode); 524: } 525: 526: /* Return 1 if the operand is either a non-special register or an item 527: that can be used as the operand of an SI add insn. */ 528: 529: int 530: add_operand (op, mode) 531: register rtx op; 532: enum machine_mode mode; 533: { 534: return (reg_or_short_operand (op, mode) 535: || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0)); 536: } 537: 538: /* Return 1 if OP is a constant but not a valid add_operand. */ 539: 540: int 541: non_add_cint_operand (op, mode) 542: register rtx op; 543: enum machine_mode mode; 544: { 545: return (GET_CODE (op) == CONST_INT 546: && (unsigned) (INTVAL (op) + 0x8000) >= 0x10000 547: && (INTVAL (op) & 0xffff) != 0); 548: } 549: 550: /* Return 1 if the operand is a non-special register or a constant that 551: can be used as the operand of an OR or XOR insn on the RS/6000. */ 552: 553: int 554: logical_operand (op, mode) 555: register rtx op; 556: enum machine_mode mode; 557: { 558: return (gpc_reg_operand (op, mode) 559: || (GET_CODE (op) == CONST_INT 560: && ((INTVAL (op) & 0xffff0000) == 0 561: || (INTVAL (op) & 0xffff) == 0))); 562: } 563: 564: /* Return 1 if C is a constant that is not a logical operand (as 565: above). */ 566: 567: int 568: non_logical_cint_operand (op, mode) 569: register rtx op; 570: enum machine_mode mode; 571: { 572: return (GET_CODE (op) == CONST_INT 573: && (INTVAL (op) & 0xffff0000) != 0 574: && (INTVAL (op) & 0xffff) != 0); 575: } 576: 577: /* Return 1 if C is a constant that can be encoded in a mask on the 578: RS/6000. It is if there are no more than two 1->0 or 0->1 transitions. 579: Reject all ones and all zeros, since these should have been optimized 580: away and confuse the making of MB and ME. */ 581: 582: int 583: mask_constant (c) 584: register int c; 585: { 586: int i; 587: int last_bit_value; 588: int transitions = 0; 589: 590: if (c == 0 || c == ~0) 591: return 0; 592: 593: last_bit_value = c & 1; 594: 595: for (i = 1; i < 32; i++) 596: if (((c >>= 1) & 1) != last_bit_value) 597: last_bit_value ^= 1, transitions++; 598: 599: return transitions <= 2; 600: } 601: 602: /* Return 1 if the operand is a constant that is a mask on the RS/6000. */ 603: 604: int 605: mask_operand (op, mode) 606: register rtx op; 607: enum machine_mode mode; 608: { 609: return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op)); 610: } 611: 612: /* Return 1 if the operand is either a non-special register or a 613: constant that can be used as the operand of an RS/6000 logical AND insn. */ 614: 615: int 616: and_operand (op, mode) 617: register rtx op; 618: enum machine_mode mode; 619: { 620: return (reg_or_short_operand (op, mode) 621: || logical_operand (op, mode) 622: || mask_operand (op, mode)); 623: } 624: 625: /* Return 1 if the operand is a constant but not a valid operand for an AND 626: insn. */ 627: 628: int 629: non_and_cint_operand (op, mode) 630: register rtx op; 631: enum machine_mode mode; 632: { 633: return GET_CODE (op) == CONST_INT && ! and_operand (op, mode); 634: } 635: 636: /* Return 1 if the operand is a general register or memory operand. */ 637: 638: int 639: reg_or_mem_operand (op, mode) 640: register rtx op; 641: register enum machine_mode mode; 642: { 643: return gpc_reg_operand (op, mode) || memory_operand (op, mode); 644: } 645: 1.1.1.4 ! root 646: /* Return 1 if the operand is a general register or memory operand without ! 647: pre-inc or pre_dec which produces invalid form of PowerPC lwa ! 648: instruction. */ ! 649: ! 650: int ! 651: lwa_operand (op, mode) ! 652: register rtx op; ! 653: register enum machine_mode mode; ! 654: { ! 655: rtx inner = op; ! 656: ! 657: if (reload_completed && GET_CODE (inner) == SUBREG) ! 658: inner = SUBREG_REG (inner); ! 659: ! 660: return gpc_reg_operand (inner, mode) ! 661: || (memory_operand (inner, mode) ! 662: && GET_CODE (XEXP (inner, 0)) != PRE_INC ! 663: && GET_CODE (XEXP (inner, 0)) != PRE_DEC); ! 664: } ! 665: 1.1 root 666: /* Return 1 if the operand, used inside a MEM, is a valid first argument 667: to CALL. This is a SYMBOL_REF or a pseudo-register, which will be 668: forced to lr. */ 669: 670: int 671: call_operand (op, mode) 672: register rtx op; 673: enum machine_mode mode; 674: { 675: if (mode != VOIDmode && GET_MODE (op) != mode) 676: return 0; 677: 678: return (GET_CODE (op) == SYMBOL_REF 679: || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER)); 680: } 681: 1.1.1.2 root 682: 683: /* Return 1 if the operand is a SYMBOL_REF for a function known to be in 684: this file. */ 685: 686: int 687: current_file_function_operand (op, mode) 688: register rtx op; 689: enum machine_mode mode; 690: { 691: return (GET_CODE (op) == SYMBOL_REF 692: && (SYMBOL_REF_FLAG (op) 693: || op == XEXP (DECL_RTL (current_function_decl), 0))); 694: } 695: 696: 1.1 root 697: /* Return 1 if this operand is a valid input for a move insn. */ 698: 699: int 700: input_operand (op, mode) 701: register rtx op; 702: enum machine_mode mode; 703: { 1.1.1.2 root 704: /* Memory is always valid. */ 1.1 root 705: if (memory_operand (op, mode)) 706: return 1; 707: 1.1.1.2 root 708: /* For floating-point, easy constants are valid. */ 709: if (GET_MODE_CLASS (mode) == MODE_FLOAT 710: && CONSTANT_P (op) 711: && easy_fp_constant (op, mode)) 712: return 1; 713: 714: /* For floating-point or multi-word mode, the only remaining valid type 715: is a register. */ 1.1 root 716: if (GET_MODE_CLASS (mode) == MODE_FLOAT 717: || GET_MODE_SIZE (mode) > UNITS_PER_WORD) 1.1.1.2 root 718: return register_operand (op, mode); 1.1 root 719: 720: /* The only cases left are integral modes one word or smaller (we 721: do not get called for MODE_CC values). These can be in any 722: register. */ 723: if (register_operand (op, mode)) 1.1.1.2 root 724: return 1; 1.1 root 725: 726: /* For HImode and QImode, any constant is valid. */ 727: if ((mode == HImode || mode == QImode) 728: && GET_CODE (op) == CONST_INT) 729: return 1; 730: 1.1.1.3 root 731: /* A SYMBOL_REF referring to the TOC is valid. */ 1.1.1.4 ! root 732: if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op)) 1.1.1.3 root 733: return 1; 734: 1.1 root 735: /* Otherwise, we will be doing this SET with an add, so anything valid 736: for an add will be valid. */ 737: return add_operand (op, mode); 738: } 739: 1.1.1.4 ! root 740: /* Initialize a variable CUM of type CUMULATIVE_ARGS ! 741: for a call to a function whose data type is FNTYPE. ! 742: For a library call, FNTYPE is 0. ! 743: ! 744: For incoming args we set the number of arguments in the prototype large ! 745: so we never return an EXPR_LIST. */ ! 746: ! 747: void ! 748: init_cumulative_args (cum, fntype, libname, incoming) ! 749: CUMULATIVE_ARGS *cum; ! 750: tree fntype; ! 751: rtx libname; ! 752: int incoming; ! 753: { ! 754: static CUMULATIVE_ARGS zero_cumulative; ! 755: ! 756: *cum = zero_cumulative; ! 757: cum->words = 0; ! 758: cum->fregno = FP_ARG_MIN_REG; ! 759: cum->prototype = (fntype && TYPE_ARG_TYPES (fntype)); ! 760: ! 761: if (incoming) ! 762: { ! 763: cum->nargs_prototype = 1000; /* don't return an EXPR_LIST */ ! 764: #ifdef TARGET_V4_CALLS ! 765: if (TARGET_V4_CALLS) ! 766: cum->varargs_offset = RS6000_VARARGS_OFFSET; ! 767: #endif ! 768: } ! 769: ! 770: else if (cum->prototype) ! 771: cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1 ! 772: + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode ! 773: || RETURN_IN_MEMORY (TREE_TYPE (fntype)))); ! 774: ! 775: else ! 776: cum->nargs_prototype = 0; ! 777: ! 778: cum->orig_nargs = cum->nargs_prototype; ! 779: if (TARGET_DEBUG_ARG) ! 780: { ! 781: fprintf (stderr, "\ninit_cumulative_args:"); ! 782: if (fntype) ! 783: { ! 784: tree ret_type = TREE_TYPE (fntype); ! 785: fprintf (stderr, " ret code = %s,", ! 786: tree_code_name[ (int)TREE_CODE (ret_type) ]); ! 787: } ! 788: ! 789: #ifdef TARGET_V4_CALLS ! 790: if (TARGET_V4_CALLS && incoming) ! 791: fprintf (stderr, " varargs = %d, ", cum->varargs_offset); ! 792: #endif ! 793: ! 794: fprintf (stderr, " proto = %d, nargs = %d\n", ! 795: cum->prototype, cum->nargs_prototype); ! 796: } ! 797: } ! 798: ! 799: /* Update the data in CUM to advance over an argument ! 800: of mode MODE and data type TYPE. ! 801: (TYPE is null for libcalls where that information may not be available.) */ ! 802: ! 803: void ! 804: function_arg_advance (cum, mode, type, named) ! 805: CUMULATIVE_ARGS *cum; ! 806: enum machine_mode mode; ! 807: tree type; ! 808: int named; ! 809: { ! 810: cum->nargs_prototype--; ! 811: ! 812: #ifdef TARGET_V4_CALLS ! 813: if (TARGET_V4_CALLS) ! 814: { ! 815: /* Long longs must not be split between registers and stack */ ! 816: if ((GET_MODE_CLASS (mode) != MODE_FLOAT || TARGET_SOFT_FLOAT) ! 817: && type && !AGGREGATE_TYPE_P (type) ! 818: && cum->words < GP_ARG_NUM_REG ! 819: && cum->words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG) ! 820: { ! 821: cum->words = GP_ARG_NUM_REG; ! 822: } ! 823: ! 824: /* Aggregates get passed as pointers */ ! 825: if (type && AGGREGATE_TYPE_P (type)) ! 826: cum->words++; ! 827: ! 828: /* Floats go in registers, & don't occupy space in the GP registers ! 829: like they do for AIX unless software floating point. */ ! 830: else if (GET_MODE_CLASS (mode) == MODE_FLOAT ! 831: && TARGET_HARD_FLOAT ! 832: && cum->fregno <= FP_ARG_V4_MAX_REG) ! 833: cum->fregno++; ! 834: ! 835: else ! 836: cum->words += RS6000_ARG_SIZE (mode, type, 1); ! 837: } ! 838: else ! 839: #endif ! 840: if (named) ! 841: { ! 842: cum->words += RS6000_ARG_SIZE (mode, type, named); ! 843: if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT) ! 844: cum->fregno++; ! 845: } ! 846: ! 847: if (TARGET_DEBUG_ARG) ! 848: fprintf (stderr, ! 849: "function_adv: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d\n", ! 850: cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named); ! 851: } ! 852: ! 853: /* Determine where to put an argument to a function. ! 854: Value is zero to push the argument on the stack, ! 855: or a hard register in which to store the argument. ! 856: ! 857: MODE is the argument's machine mode. ! 858: TYPE is the data type of the argument (as a tree). ! 859: This is null for libcalls where that information may ! 860: not be available. ! 861: CUM is a variable of type CUMULATIVE_ARGS which gives info about ! 862: the preceding args and about the function being called. ! 863: NAMED is nonzero if this argument is a named parameter ! 864: (otherwise it is an extra parameter matching an ellipsis). ! 865: ! 866: On RS/6000 the first eight words of non-FP are normally in registers ! 867: and the rest are pushed. Under AIX, the first 13 FP args are in registers. ! 868: Under V.4, the first 8 FP args are in registers. ! 869: ! 870: If this is floating-point and no prototype is specified, we use ! 871: both an FP and integer register (or possibly FP reg and stack). Library ! 872: functions (when TYPE is zero) always have the proper types for args, ! 873: so we can pass the FP value just in one register. emit_library_function ! 874: doesn't support EXPR_LIST anyway. */ ! 875: ! 876: struct rtx_def * ! 877: function_arg (cum, mode, type, named) ! 878: CUMULATIVE_ARGS *cum; ! 879: enum machine_mode mode; ! 880: tree type; ! 881: int named; ! 882: { ! 883: if (TARGET_DEBUG_ARG) ! 884: fprintf (stderr, ! 885: "function_arg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, named = %d\n", ! 886: cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), named); ! 887: ! 888: /* Return a marker to indicate whether CR1 needs to set or clear the bit that V.4 ! 889: uses to say fp args were passed in registers. Assume that we don't need the ! 890: marker for software floating point, or compiler generated library calls. */ ! 891: if (mode == VOIDmode) ! 892: { ! 893: #ifdef TARGET_V4_CALLS ! 894: if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && cum->nargs_prototype < 0 ! 895: && type && (cum->prototype || TARGET_NO_PROTOTYPE)) ! 896: return GEN_INT ((cum->fregno == FP_ARG_MIN_REG) ? -1 : 1); ! 897: #endif ! 898: ! 899: return GEN_INT (0); ! 900: } ! 901: ! 902: if (!named) ! 903: { ! 904: #ifdef TARGET_V4_CALLS ! 905: if (!TARGET_V4_CALLS) ! 906: #endif ! 907: return NULL_RTX; ! 908: } ! 909: ! 910: if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) ! 911: return NULL_RTX; ! 912: ! 913: if (USE_FP_FOR_ARG_P (*cum, mode, type)) ! 914: { ! 915: if ((cum->nargs_prototype > 0) ! 916: #ifdef TARGET_V4_CALLS ! 917: || TARGET_V4_CALLS /* V.4 never passes FP values in GP registers */ ! 918: #endif ! 919: || !type) ! 920: return gen_rtx (REG, mode, cum->fregno); ! 921: ! 922: return gen_rtx (EXPR_LIST, VOIDmode, ! 923: ((cum->words < GP_ARG_NUM_REG) ! 924: ? gen_rtx (REG, mode, GP_ARG_MIN_REG + cum->words) ! 925: : NULL_RTX), ! 926: gen_rtx (REG, mode, cum->fregno)); ! 927: } ! 928: ! 929: #ifdef TARGET_V4_CALLS ! 930: /* Long longs won't be split between register and stack */ ! 931: else if (TARGET_V4_CALLS && ! 932: cum->words + RS6000_ARG_SIZE (mode, type, named) > GP_ARG_NUM_REG) ! 933: { ! 934: return NULL_RTX; ! 935: } ! 936: #endif ! 937: ! 938: else if (cum->words < GP_ARG_NUM_REG) ! 939: return gen_rtx (REG, mode, GP_ARG_MIN_REG + cum->words); ! 940: ! 941: return NULL_RTX; ! 942: } ! 943: ! 944: /* For an arg passed partly in registers and partly in memory, ! 945: this is the number of registers used. ! 946: For args passed entirely in registers or entirely in memory, zero. */ ! 947: ! 948: int ! 949: function_arg_partial_nregs (cum, mode, type, named) ! 950: CUMULATIVE_ARGS *cum; ! 951: enum machine_mode mode; ! 952: tree type; ! 953: int named; ! 954: { ! 955: if (! named) ! 956: return 0; ! 957: ! 958: #ifdef TARGET_V4_CALLS ! 959: if (TARGET_V4_CALLS) ! 960: return 0; ! 961: #endif ! 962: ! 963: if (USE_FP_FOR_ARG_P (*cum, mode, type)) ! 964: { ! 965: if (cum->nargs_prototype >= 0) ! 966: return 0; ! 967: } ! 968: ! 969: if (cum->words < GP_ARG_NUM_REG ! 970: && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type, named))) ! 971: { ! 972: int ret = GP_ARG_NUM_REG - cum->words; ! 973: if (ret && TARGET_DEBUG_ARG) ! 974: fprintf (stderr, "function_arg_partial_nregs: %d\n", ret); ! 975: ! 976: return ret; ! 977: } ! 978: ! 979: return 0; ! 980: } ! 981: ! 982: /* A C expression that indicates when an argument must be passed by ! 983: reference. If nonzero for an argument, a copy of that argument is ! 984: made in memory and a pointer to the argument is passed instead of ! 985: the argument itself. The pointer is passed in whatever way is ! 986: appropriate for passing a pointer to that type. ! 987: ! 988: Under V.4, structures and unions are passed by reference. */ ! 989: ! 990: int ! 991: function_arg_pass_by_reference (cum, mode, type, named) ! 992: CUMULATIVE_ARGS *cum; ! 993: enum machine_mode mode; ! 994: tree type; ! 995: int named; ! 996: { ! 997: #ifdef TARGET_V4_CALLS ! 998: if (TARGET_V4_CALLS && type && AGGREGATE_TYPE_P (type)) ! 999: { ! 1000: if (TARGET_DEBUG_ARG) ! 1001: fprintf (stderr, "function_arg_pass_by_reference: aggregate\n"); ! 1002: ! 1003: return 1; ! 1004: } ! 1005: #endif ! 1006: ! 1007: return 0; ! 1008: } ! 1009: ! 1010: ! 1011: /* Perform any needed actions needed for a function that is receiving a ! 1012: variable number of arguments. ! 1013: ! 1014: CUM is as above. ! 1015: ! 1016: MODE and TYPE are the mode and type of the current parameter. ! 1017: ! 1018: PRETEND_SIZE is a variable that should be set to the amount of stack ! 1019: that must be pushed by the prolog to pretend that our caller pushed ! 1020: it. ! 1021: ! 1022: Normally, this macro will push all remaining incoming registers on the ! 1023: stack and set PRETEND_SIZE to the length of the registers pushed. */ ! 1024: ! 1025: void ! 1026: setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) ! 1027: CUMULATIVE_ARGS *cum; ! 1028: enum machine_mode mode; ! 1029: tree type; ! 1030: int *pretend_size; ! 1031: int no_rtl; ! 1032: ! 1033: { ! 1034: rtx save_area = virtual_incoming_args_rtx; ! 1035: int reg_size = (TARGET_64BIT) ? 8 : 4; ! 1036: ! 1037: if (TARGET_DEBUG_ARG) ! 1038: fprintf (stderr, ! 1039: "setup_vararg: words = %2d, fregno = %2d, nargs = %4d, proto = %d, mode = %4s, no_rtl= %d\n", ! 1040: cum->words, cum->fregno, cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode), no_rtl); ! 1041: ! 1042: #ifdef TARGET_V4_CALLS ! 1043: if (TARGET_V4_CALLS && !no_rtl) ! 1044: { ! 1045: rs6000_sysv_varargs_p = 1; ! 1046: save_area = plus_constant (frame_pointer_rtx, RS6000_VARARGS_OFFSET); ! 1047: } ! 1048: #endif ! 1049: ! 1050: if (cum->words < 8) ! 1051: { ! 1052: int first_reg_offset = cum->words; ! 1053: ! 1054: if (MUST_PASS_IN_STACK (mode, type)) ! 1055: first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type, 1); ! 1056: ! 1057: if (first_reg_offset > GP_ARG_NUM_REG) ! 1058: first_reg_offset = GP_ARG_NUM_REG; ! 1059: ! 1060: if (!no_rtl && first_reg_offset != GP_ARG_NUM_REG) ! 1061: move_block_from_reg ! 1062: (GP_ARG_MIN_REG + first_reg_offset, ! 1063: gen_rtx (MEM, BLKmode, ! 1064: plus_constant (save_area, first_reg_offset * reg_size)), ! 1065: GP_ARG_NUM_REG - first_reg_offset, ! 1066: (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD); ! 1067: ! 1068: *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD; ! 1069: } ! 1070: ! 1071: #ifdef TARGET_V4_CALLS ! 1072: /* Save FP registers if needed. */ ! 1073: if (TARGET_V4_CALLS && TARGET_HARD_FLOAT && !no_rtl) ! 1074: { ! 1075: int fregno = cum->fregno; ! 1076: int num_fp_reg = FP_ARG_V4_MAX_REG + 1 - fregno; ! 1077: ! 1078: if (num_fp_reg >= 0) ! 1079: { ! 1080: rtx cr1 = gen_rtx (REG, CCmode, 69); ! 1081: rtx lab = gen_label_rtx (); ! 1082: int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8); ! 1083: ! 1084: emit_jump_insn (gen_rtx (SET, VOIDmode, ! 1085: pc_rtx, ! 1086: gen_rtx (IF_THEN_ELSE, VOIDmode, ! 1087: gen_rtx (NE, VOIDmode, cr1, const0_rtx), ! 1088: gen_rtx (LABEL_REF, VOIDmode, lab), ! 1089: pc_rtx))); ! 1090: ! 1091: while ( num_fp_reg-- >= 0) ! 1092: { ! 1093: emit_move_insn (gen_rtx (MEM, DFmode, plus_constant (save_area, off)), ! 1094: gen_rtx (REG, DFmode, fregno++)); ! 1095: off += 8; ! 1096: } ! 1097: ! 1098: emit_label (lab); ! 1099: } ! 1100: } ! 1101: #endif ! 1102: } ! 1103: ! 1104: /* If defined, is a C expression that produces the machine-specific ! 1105: code for a call to `__builtin_saveregs'. This code will be moved ! 1106: to the very beginning of the function, before any parameter access ! 1107: are made. The return value of this function should be an RTX that ! 1108: contains the value to use as the return of `__builtin_saveregs'. ! 1109: ! 1110: The argument ARGS is a `tree_list' containing the arguments that ! 1111: were passed to `__builtin_saveregs'. ! 1112: ! 1113: If this macro is not defined, the compiler will output an ordinary ! 1114: call to the library function `__builtin_saveregs'. ! 1115: ! 1116: On the Power/PowerPC return the address of the area on the stack ! 1117: used to hold arguments. Under AIX, this includes the 8 word register ! 1118: save area. Under V.4 this does not. */ ! 1119: ! 1120: struct rtx_def * ! 1121: expand_builtin_saveregs (args) ! 1122: tree args; ! 1123: { ! 1124: return virtual_incoming_args_rtx; ! 1125: } ! 1126: ! 1127: ! 1128: /* Allocate a stack temp. Only allocate one stack temp per type for a ! 1129: function. */ ! 1130: ! 1131: struct rtx_def * ! 1132: rs6000_stack_temp (mode, size) ! 1133: enum machine_mode mode; ! 1134: int size; ! 1135: { ! 1136: rtx temp = stack_temps[ (int)mode ]; ! 1137: rtx addr; ! 1138: ! 1139: if (temp == NULL_RTX) ! 1140: { ! 1141: temp = assign_stack_local (mode, size, 0); ! 1142: addr = XEXP (temp, 0); ! 1143: ! 1144: if ((size > 4 && !offsettable_address_p (0, mode, addr)) ! 1145: || (size <= 4 && !memory_address_p (mode, addr))) ! 1146: { ! 1147: XEXP (temp, 0) = copy_addr_to_reg (addr); ! 1148: } ! 1149: ! 1150: stack_temps[ (int)mode ] = temp; ! 1151: } ! 1152: ! 1153: return temp; ! 1154: } ! 1155: ! 1156: ! 1157: /* Generate a memory reference for expand_block_move, copying volatile, ! 1158: and other bits from an original memory reference. */ ! 1159: ! 1160: static rtx ! 1161: expand_block_move_mem (mode, addr, orig_mem) ! 1162: enum machine_mode mode; ! 1163: rtx addr; ! 1164: rtx orig_mem; ! 1165: { ! 1166: rtx mem = gen_rtx (MEM, mode, addr); ! 1167: MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem); ! 1168: MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (orig_mem); ! 1169: return mem; ! 1170: } ! 1171: ! 1172: /* Expand a block move operation, and return 1 if successful. Return 0 ! 1173: if we should let the compiler generate normal code. ! 1174: ! 1175: operands[0] is the destination ! 1176: operands[1] is the source ! 1177: operands[2] is the length ! 1178: operands[3] is the alignment */ ! 1179: ! 1180: #define MAX_MOVE_REG 4 ! 1181: ! 1182: int ! 1183: expand_block_move (operands) ! 1184: rtx operands[]; ! 1185: { ! 1186: rtx bytes_rtx = operands[2]; ! 1187: rtx align_rtx = operands[3]; ! 1188: int constp = (GET_CODE (bytes_rtx) == CONST_INT); ! 1189: int align = XINT (align_rtx, 0); ! 1190: int bytes; ! 1191: int offset; ! 1192: int num_reg; ! 1193: int i; ! 1194: rtx src_reg; ! 1195: rtx dest_reg; ! 1196: rtx src_addr; ! 1197: rtx dest_addr; ! 1198: rtx tmp_reg; ! 1199: rtx stores[MAX_MOVE_REG]; ! 1200: int move_bytes; ! 1201: ! 1202: /* If this is not a fixed size move, just call memcpy */ ! 1203: if (!constp) ! 1204: return 0; ! 1205: ! 1206: /* Anything to move? */ ! 1207: bytes = INTVAL (bytes_rtx); ! 1208: if (bytes <= 0) ! 1209: return 1; ! 1210: ! 1211: /* Don't support real large moves. If string instructions are not used, ! 1212: then don't generate more than 8 loads. */ ! 1213: if (TARGET_STRING) ! 1214: { ! 1215: if (bytes > 4*8) ! 1216: return 0; ! 1217: } ! 1218: else if (!STRICT_ALIGNMENT) ! 1219: { ! 1220: if (bytes > 4*8) ! 1221: return 0; ! 1222: } ! 1223: else if (bytes > 8*align) ! 1224: return 0; ! 1225: ! 1226: /* Move the address into scratch registers. */ ! 1227: dest_reg = copy_addr_to_reg (XEXP (operands[0], 0)); ! 1228: src_reg = copy_addr_to_reg (XEXP (operands[1], 0)); ! 1229: ! 1230: if (TARGET_STRING) /* string instructions are available */ ! 1231: { ! 1232: for ( ; bytes > 0; bytes -= move_bytes) ! 1233: { ! 1234: if (bytes > 24 /* move up to 32 bytes at a time */ ! 1235: && !fixed_regs[5] ! 1236: && !fixed_regs[6] ! 1237: && !fixed_regs[7] ! 1238: && !fixed_regs[8] ! 1239: && !fixed_regs[9] ! 1240: && !fixed_regs[10] ! 1241: && !fixed_regs[11] ! 1242: && !fixed_regs[12]) ! 1243: { ! 1244: move_bytes = (bytes > 32) ? 32 : bytes; ! 1245: emit_insn (gen_movstrsi_8reg (dest_reg, ! 1246: src_reg, ! 1247: GEN_INT ((move_bytes == 32) ? 0 : move_bytes), ! 1248: align_rtx)); ! 1249: } ! 1250: else if (bytes > 16 /* move up to 24 bytes at a time */ ! 1251: && !fixed_regs[7] ! 1252: && !fixed_regs[8] ! 1253: && !fixed_regs[9] ! 1254: && !fixed_regs[10] ! 1255: && !fixed_regs[11] ! 1256: && !fixed_regs[12]) ! 1257: { ! 1258: move_bytes = (bytes > 24) ? 24 : bytes; ! 1259: emit_insn (gen_movstrsi_6reg (dest_reg, ! 1260: src_reg, ! 1261: GEN_INT (move_bytes), ! 1262: align_rtx)); ! 1263: } ! 1264: else if (bytes > 8 /* move up to 16 bytes at a time */ ! 1265: && !fixed_regs[9] ! 1266: && !fixed_regs[10] ! 1267: && !fixed_regs[11] ! 1268: && !fixed_regs[12]) ! 1269: { ! 1270: move_bytes = (bytes > 16) ? 16 : bytes; ! 1271: emit_insn (gen_movstrsi_4reg (dest_reg, ! 1272: src_reg, ! 1273: GEN_INT (move_bytes), ! 1274: align_rtx)); ! 1275: } ! 1276: else if (bytes > 4 && !TARGET_64BIT) ! 1277: { /* move up to 8 bytes at a time */ ! 1278: move_bytes = (bytes > 8) ? 8 : bytes; ! 1279: emit_insn (gen_movstrsi_2reg (dest_reg, ! 1280: src_reg, ! 1281: GEN_INT (move_bytes), ! 1282: align_rtx)); ! 1283: } ! 1284: else if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) ! 1285: { /* move 4 bytes */ ! 1286: move_bytes = 4; ! 1287: tmp_reg = gen_reg_rtx (SImode); ! 1288: emit_move_insn (tmp_reg, gen_rtx (MEM, SImode, src_reg)); ! 1289: emit_move_insn (gen_rtx (MEM, SImode, dest_reg), tmp_reg); ! 1290: } ! 1291: else if (bytes == 2 && (align >= 2 || !STRICT_ALIGNMENT)) ! 1292: { /* move 2 bytes */ ! 1293: move_bytes = 2; ! 1294: tmp_reg = gen_reg_rtx (HImode); ! 1295: emit_move_insn (tmp_reg, gen_rtx (MEM, HImode, src_reg)); ! 1296: emit_move_insn (gen_rtx (MEM, HImode, dest_reg), tmp_reg); ! 1297: } ! 1298: else if (bytes == 1) /* move 1 byte */ ! 1299: { ! 1300: move_bytes = 1; ! 1301: tmp_reg = gen_reg_rtx (QImode); ! 1302: emit_move_insn (tmp_reg, gen_rtx (MEM, QImode, src_reg)); ! 1303: emit_move_insn (gen_rtx (MEM, QImode, dest_reg), tmp_reg); ! 1304: } ! 1305: else ! 1306: { /* move up to 4 bytes at a time */ ! 1307: move_bytes = (bytes > 4) ? 4 : bytes; ! 1308: emit_insn (gen_movstrsi_1reg (dest_reg, ! 1309: src_reg, ! 1310: GEN_INT (move_bytes), ! 1311: align_rtx)); ! 1312: } ! 1313: ! 1314: if (bytes > move_bytes) ! 1315: { ! 1316: emit_insn (gen_addsi3 (src_reg, src_reg, GEN_INT (move_bytes))); ! 1317: emit_insn (gen_addsi3 (dest_reg, dest_reg, GEN_INT (move_bytes))); ! 1318: } ! 1319: } ! 1320: } ! 1321: ! 1322: else /* string instructions not available */ ! 1323: { ! 1324: num_reg = offset = 0; ! 1325: for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes)) ! 1326: { ! 1327: /* Calculate the correct offset for src/dest */ ! 1328: if (offset == 0) ! 1329: { ! 1330: src_addr = src_reg; ! 1331: dest_addr = dest_reg; ! 1332: } ! 1333: else ! 1334: { ! 1335: src_addr = gen_rtx (PLUS, Pmode, src_reg, GEN_INT (offset)); ! 1336: dest_addr = gen_rtx (PLUS, Pmode, dest_reg, GEN_INT (offset)); ! 1337: } ! 1338: ! 1339: /* Generate the appropriate load and store, saving the stores for later */ ! 1340: if (bytes >= 4 && (align >= 4 || !STRICT_ALIGNMENT)) ! 1341: { ! 1342: move_bytes = 4; ! 1343: tmp_reg = gen_reg_rtx (SImode); ! 1344: emit_insn (gen_movsi (tmp_reg, gen_rtx (MEM, SImode, src_addr))); ! 1345: stores[ num_reg++ ] = gen_movsi (gen_rtx (MEM, SImode, dest_addr), tmp_reg); ! 1346: } ! 1347: else if (bytes >= 2 && (align >= 2 || !STRICT_ALIGNMENT)) ! 1348: { ! 1349: move_bytes = 2; ! 1350: tmp_reg = gen_reg_rtx (HImode); ! 1351: emit_insn (gen_movhi (tmp_reg, gen_rtx (MEM, HImode, src_addr))); ! 1352: stores[ num_reg++ ] = gen_movhi (gen_rtx (MEM, HImode, dest_addr), tmp_reg); ! 1353: } ! 1354: else ! 1355: { ! 1356: move_bytes = 1; ! 1357: tmp_reg = gen_reg_rtx (QImode); ! 1358: emit_insn (gen_movqi (tmp_reg, gen_rtx (MEM, QImode, src_addr))); ! 1359: stores[ num_reg++ ] = gen_movqi (gen_rtx (MEM, QImode, dest_addr), tmp_reg); ! 1360: } ! 1361: ! 1362: if (num_reg >= MAX_MOVE_REG) ! 1363: { ! 1364: for (i = 0; i < num_reg; i++) ! 1365: emit_insn (stores[i]); ! 1366: num_reg = 0; ! 1367: } ! 1368: } ! 1369: ! 1370: if (num_reg > 0) ! 1371: { ! 1372: for (i = 0; i < num_reg; i++) ! 1373: emit_insn (stores[i]); ! 1374: } ! 1375: } ! 1376: ! 1377: return 1; ! 1378: } ! 1379: ! 1380: 1.1 root 1381: /* Return 1 if OP is a load multiple operation. It is known to be a 1382: PARALLEL and the first section will be tested. */ 1383: 1384: int 1385: load_multiple_operation (op, mode) 1386: rtx op; 1387: enum machine_mode mode; 1388: { 1389: int count = XVECLEN (op, 0); 1390: int dest_regno; 1391: rtx src_addr; 1392: int i; 1393: 1394: /* Perform a quick check so we don't blow up below. */ 1395: if (count <= 1 1396: || GET_CODE (XVECEXP (op, 0, 0)) != SET 1397: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG 1398: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM) 1399: return 0; 1400: 1401: dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0))); 1402: src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0); 1403: 1404: for (i = 1; i < count; i++) 1405: { 1406: rtx elt = XVECEXP (op, 0, i); 1407: 1408: if (GET_CODE (elt) != SET 1409: || GET_CODE (SET_DEST (elt)) != REG 1410: || GET_MODE (SET_DEST (elt)) != SImode 1411: || REGNO (SET_DEST (elt)) != dest_regno + i 1412: || GET_CODE (SET_SRC (elt)) != MEM 1413: || GET_MODE (SET_SRC (elt)) != SImode 1414: || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS 1415: || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr) 1416: || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT 1417: || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4) 1418: return 0; 1419: } 1420: 1421: return 1; 1422: } 1423: 1424: /* Similar, but tests for store multiple. Here, the second vector element 1425: is a CLOBBER. It will be tested later. */ 1426: 1427: int 1428: store_multiple_operation (op, mode) 1429: rtx op; 1430: enum machine_mode mode; 1431: { 1432: int count = XVECLEN (op, 0) - 1; 1433: int src_regno; 1434: rtx dest_addr; 1435: int i; 1436: 1437: /* Perform a quick check so we don't blow up below. */ 1438: if (count <= 1 1439: || GET_CODE (XVECEXP (op, 0, 0)) != SET 1440: || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM 1441: || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG) 1442: return 0; 1443: 1444: src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0))); 1445: dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0); 1446: 1447: for (i = 1; i < count; i++) 1448: { 1449: rtx elt = XVECEXP (op, 0, i + 1); 1450: 1451: if (GET_CODE (elt) != SET 1452: || GET_CODE (SET_SRC (elt)) != REG 1453: || GET_MODE (SET_SRC (elt)) != SImode 1454: || REGNO (SET_SRC (elt)) != src_regno + i 1455: || GET_CODE (SET_DEST (elt)) != MEM 1456: || GET_MODE (SET_DEST (elt)) != SImode 1457: || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS 1458: || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr) 1459: || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT 1460: || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4) 1461: return 0; 1462: } 1463: 1464: return 1; 1465: } 1466: 1467: /* Return 1 if OP is a comparison operation that is valid for a branch insn. 1468: We only check the opcode against the mode of the CC value here. */ 1469: 1470: int 1471: branch_comparison_operator (op, mode) 1472: register rtx op; 1473: enum machine_mode mode; 1474: { 1475: enum rtx_code code = GET_CODE (op); 1476: enum machine_mode cc_mode; 1477: 1478: if (GET_RTX_CLASS (code) != '<') 1479: return 0; 1480: 1481: cc_mode = GET_MODE (XEXP (op, 0)); 1482: if (GET_MODE_CLASS (cc_mode) != MODE_CC) 1483: return 0; 1484: 1485: if ((code == GT || code == LT || code == GE || code == LE) 1486: && cc_mode == CCUNSmode) 1487: return 0; 1488: 1489: if ((code == GTU || code == LTU || code == GEU || code == LEU) 1490: && (cc_mode != CCUNSmode)) 1491: return 0; 1492: 1493: return 1; 1494: } 1495: 1496: /* Return 1 if OP is a comparison operation that is valid for an scc insn. 1497: We check the opcode against the mode of the CC value and disallow EQ or 1498: NE comparisons for integers. */ 1499: 1500: int 1501: scc_comparison_operator (op, mode) 1502: register rtx op; 1503: enum machine_mode mode; 1504: { 1505: enum rtx_code code = GET_CODE (op); 1506: enum machine_mode cc_mode; 1507: 1508: if (GET_MODE (op) != mode && mode != VOIDmode) 1509: return 0; 1510: 1511: if (GET_RTX_CLASS (code) != '<') 1512: return 0; 1513: 1514: cc_mode = GET_MODE (XEXP (op, 0)); 1515: if (GET_MODE_CLASS (cc_mode) != MODE_CC) 1516: return 0; 1517: 1518: if (code == NE && cc_mode != CCFPmode) 1519: return 0; 1520: 1521: if ((code == GT || code == LT || code == GE || code == LE) 1522: && cc_mode == CCUNSmode) 1523: return 0; 1524: 1525: if ((code == GTU || code == LTU || code == GEU || code == LEU) 1526: && (cc_mode != CCUNSmode)) 1527: return 0; 1528: 1529: if (cc_mode == CCEQmode && code != EQ && code != NE) 1530: return 0; 1531: 1532: return 1; 1533: } 1534: 1535: /* Return 1 if ANDOP is a mask that has no bits on that are not in the 1536: mask required to convert the result of a rotate insn into a shift 1537: left insn of SHIFTOP bits. Both are known to be CONST_INT. */ 1538: 1539: int 1540: includes_lshift_p (shiftop, andop) 1541: register rtx shiftop; 1542: register rtx andop; 1543: { 1544: int shift_mask = (~0 << INTVAL (shiftop)); 1545: 1546: return (INTVAL (andop) & ~shift_mask) == 0; 1547: } 1548: 1549: /* Similar, but for right shift. */ 1550: 1551: int 1552: includes_rshift_p (shiftop, andop) 1553: register rtx shiftop; 1554: register rtx andop; 1555: { 1556: unsigned shift_mask = ~0; 1557: 1558: shift_mask >>= INTVAL (shiftop); 1559: 1560: return (INTVAL (andop) & ~ shift_mask) == 0; 1561: } 1.1.1.4 ! root 1562: ! 1563: /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates ! 1564: for lfq and stfq insns. ! 1565: ! 1566: Note reg1 and reg2 *must* be hard registers. To be sure we will ! 1567: abort if we are passed pseudo registers. */ ! 1568: ! 1569: int ! 1570: registers_ok_for_quad_peep (reg1, reg2) ! 1571: rtx reg1, reg2; ! 1572: { ! 1573: /* We might have been passed a SUBREG. */ ! 1574: if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) ! 1575: return 0; ! 1576: ! 1577: return (REGNO (reg1) == REGNO (reg2) - 1); ! 1578: } ! 1579: ! 1580: /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn. addr1 and ! 1581: addr2 must be in consecutive memory locations (addr2 == addr1 + 8). */ ! 1582: ! 1583: int ! 1584: addrs_ok_for_quad_peep (addr1, addr2) ! 1585: register rtx addr1; ! 1586: register rtx addr2; ! 1587: { ! 1588: int reg1; ! 1589: int offset1; ! 1590: ! 1591: /* Extract an offset (if used) from the first addr. */ ! 1592: if (GET_CODE (addr1) == PLUS) ! 1593: { ! 1594: /* If not a REG, return zero. */ ! 1595: if (GET_CODE (XEXP (addr1, 0)) != REG) ! 1596: return 0; ! 1597: else ! 1598: { ! 1599: reg1 = REGNO (XEXP (addr1, 0)); ! 1600: /* The offset must be constant! */ ! 1601: if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) ! 1602: return 0; ! 1603: offset1 = INTVAL (XEXP (addr1, 1)); ! 1604: } ! 1605: } ! 1606: else if (GET_CODE (addr1) != REG) ! 1607: return 0; ! 1608: else ! 1609: { ! 1610: reg1 = REGNO (addr1); ! 1611: /* This was a simple (mem (reg)) expression. Offset is 0. */ ! 1612: offset1 = 0; ! 1613: } ! 1614: ! 1615: /* Make sure the second address is a (mem (plus (reg) (const_int). */ ! 1616: if (GET_CODE (addr2) != PLUS) ! 1617: return 0; ! 1618: ! 1619: if (GET_CODE (XEXP (addr2, 0)) != REG ! 1620: || GET_CODE (XEXP (addr2, 1)) != CONST_INT) ! 1621: return 0; ! 1622: ! 1623: if (reg1 != REGNO (XEXP (addr2, 0))) ! 1624: return 0; ! 1625: ! 1626: /* The offset for the second addr must be 8 more than the first addr. */ ! 1627: if (INTVAL (XEXP (addr2, 1)) != offset1 + 8) ! 1628: return 0; ! 1629: ! 1630: /* All the tests passed. addr1 and addr2 are valid for lfq or stfq ! 1631: instructions. */ ! 1632: return 1; ! 1633: } 1.1 root 1634: 1635: /* Return the register class of a scratch register needed to copy IN into 1636: or out of a register in CLASS in MODE. If it can be done directly, 1637: NO_REGS is returned. */ 1638: 1639: enum reg_class 1640: secondary_reload_class (class, mode, in) 1641: enum reg_class class; 1642: enum machine_mode mode; 1643: rtx in; 1644: { 1645: int regno = true_regnum (in); 1646: 1647: if (regno >= FIRST_PSEUDO_REGISTER) 1648: regno = -1; 1649: 1650: /* We can place anything into GENERAL_REGS and can put GENERAL_REGS 1651: into anything. */ 1652: if (class == GENERAL_REGS || class == BASE_REGS 1653: || (regno >= 0 && INT_REGNO_P (regno))) 1654: return NO_REGS; 1655: 1656: /* Constants, memory, and FP registers can go into FP registers. */ 1657: if ((regno == -1 || FP_REGNO_P (regno)) 1658: && (class == FLOAT_REGS || class == NON_SPECIAL_REGS)) 1659: return NO_REGS; 1660: 1661: /* We can copy among the CR registers. */ 1662: if ((class == CR_REGS || class == CR0_REGS) 1663: && regno >= 0 && CR_REGNO_P (regno)) 1664: return NO_REGS; 1665: 1666: /* Otherwise, we need GENERAL_REGS. */ 1667: return GENERAL_REGS; 1668: } 1669: 1670: /* Given a comparison operation, return the bit number in CCR to test. We 1671: know this is a valid comparison. 1672: 1673: SCC_P is 1 if this is for an scc. That means that %D will have been 1674: used instead of %C, so the bits will be in different places. 1675: 1676: Return -1 if OP isn't a valid comparison for some reason. */ 1677: 1678: int 1679: ccr_bit (op, scc_p) 1680: register rtx op; 1681: int scc_p; 1682: { 1683: enum rtx_code code = GET_CODE (op); 1684: enum machine_mode cc_mode; 1685: int cc_regnum; 1686: int base_bit; 1687: 1688: if (GET_RTX_CLASS (code) != '<') 1689: return -1; 1690: 1691: cc_mode = GET_MODE (XEXP (op, 0)); 1692: cc_regnum = REGNO (XEXP (op, 0)); 1693: base_bit = 4 * (cc_regnum - 68); 1694: 1695: /* In CCEQmode cases we have made sure that the result is always in the 1696: third bit of the CR field. */ 1697: 1698: if (cc_mode == CCEQmode) 1699: return base_bit + 3; 1700: 1701: switch (code) 1702: { 1703: case NE: 1704: return scc_p ? base_bit + 3 : base_bit + 2; 1705: case EQ: 1706: return base_bit + 2; 1707: case GT: case GTU: 1708: return base_bit + 1; 1709: case LT: case LTU: 1710: return base_bit; 1711: 1712: case GE: case GEU: 1713: /* If floating-point, we will have done a cror to put the bit in the 1714: unordered position. So test that bit. For integer, this is ! LT 1715: unless this is an scc insn. */ 1716: return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit; 1717: 1718: case LE: case LEU: 1719: return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1; 1720: 1721: default: 1722: abort (); 1723: } 1724: } 1725: 1726: /* Print an operand. Recognize special options, documented below. */ 1727: 1728: void 1729: print_operand (file, x, code) 1730: FILE *file; 1731: rtx x; 1732: char code; 1733: { 1734: int i; 1735: int val; 1736: 1737: /* These macros test for integers and extract the low-order bits. */ 1738: #define INT_P(X) \ 1739: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \ 1740: && GET_MODE (X) == VOIDmode) 1741: 1742: #define INT_LOWPART(X) \ 1743: (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X)) 1744: 1745: switch (code) 1746: { 1.1.1.2 root 1747: case '.': 1748: /* Write out an instruction after the call which may be replaced 1749: with glue code by the loader. This depends on the AIX version. */ 1750: asm_fprintf (file, RS6000_CALL_GLUE); 1751: return; 1752: 1.1.1.3 root 1753: case '*': 1754: /* Write the register number of the TOC register. */ 1.1.1.4 ! root 1755: fputs (TARGET_MINIMAL_TOC ? reg_names[30] : reg_names[2], file); 1.1.1.3 root 1756: return; 1757: 1.1 root 1758: case 'A': 1759: /* If X is a constant integer whose low-order 5 bits are zero, 1760: write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug 1.1.1.2 root 1761: in the AIX assembler where "sri" with a zero shift count 1.1 root 1762: write a trash instruction. */ 1763: if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) 1.1.1.2 root 1764: putc ('l', file); 1.1 root 1765: else 1.1.1.2 root 1766: putc ('r', file); 1.1 root 1767: return; 1768: 1769: case 'b': 1770: /* Low-order 16 bits of constant, unsigned. */ 1771: if (! INT_P (x)) 1772: output_operand_lossage ("invalid %%b value"); 1773: 1774: fprintf (file, "%d", INT_LOWPART (x) & 0xffff); 1775: return; 1776: 1777: case 'C': 1778: /* This is an optional cror needed for LE or GE floating-point 1779: comparisons. Otherwise write nothing. */ 1780: if ((GET_CODE (x) == LE || GET_CODE (x) == GE) 1781: && GET_MODE (XEXP (x, 0)) == CCFPmode) 1782: { 1783: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); 1784: 1785: fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, 1786: base_bit + 2, base_bit + (GET_CODE (x) == GE)); 1787: } 1788: return; 1789: 1790: case 'D': 1791: /* Similar, except that this is for an scc, so we must be able to 1792: encode the test in a single bit that is one. We do the above 1793: for any LE, GE, GEU, or LEU and invert the bit for NE. */ 1794: if (GET_CODE (x) == LE || GET_CODE (x) == GE 1795: || GET_CODE (x) == LEU || GET_CODE (x) == GEU) 1796: { 1797: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); 1798: 1799: fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, 1800: base_bit + 2, 1801: base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU)); 1802: } 1803: 1804: else if (GET_CODE (x) == NE) 1805: { 1806: int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); 1807: 1808: fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3, 1809: base_bit + 2, base_bit + 2); 1810: } 1811: return; 1812: 1813: case 'E': 1814: /* X is a CR register. Print the number of the third bit of the CR */ 1815: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 1816: output_operand_lossage ("invalid %%E value"); 1817: 1818: fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3); 1.1.1.2 root 1819: return; 1.1 root 1820: 1821: case 'f': 1822: /* X is a CR register. Print the shift count needed to move it 1823: to the high-order four bits. */ 1824: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 1825: output_operand_lossage ("invalid %%f value"); 1826: else 1827: fprintf (file, "%d", 4 * (REGNO (x) - 68)); 1828: return; 1829: 1830: case 'F': 1831: /* Similar, but print the count for the rotate in the opposite 1832: direction. */ 1833: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 1834: output_operand_lossage ("invalid %%F value"); 1835: else 1836: fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68)); 1837: return; 1838: 1839: case 'G': 1840: /* X is a constant integer. If it is negative, print "m", 1841: otherwise print "z". This is to make a aze or ame insn. */ 1842: if (GET_CODE (x) != CONST_INT) 1843: output_operand_lossage ("invalid %%G value"); 1844: else if (INTVAL (x) >= 0) 1.1.1.2 root 1845: putc ('z', file); 1.1 root 1846: else 1.1.1.2 root 1847: putc ('m', file); 1.1 root 1848: return; 1849: 1850: case 'h': 1851: /* If constant, output low-order five bits. Otherwise, 1852: write normally. */ 1853: if (INT_P (x)) 1854: fprintf (file, "%d", INT_LOWPART (x) & 31); 1855: else 1856: print_operand (file, x, 0); 1857: return; 1858: 1859: case 'I': 1860: /* Print `i' if this is a constant, else nothing. */ 1861: if (INT_P (x)) 1.1.1.2 root 1862: putc ('i', file); 1.1 root 1863: return; 1864: 1865: case 'j': 1866: /* Write the bit number in CCR for jump. */ 1867: i = ccr_bit (x, 0); 1868: if (i == -1) 1869: output_operand_lossage ("invalid %%j code"); 1870: else 1871: fprintf (file, "%d", i); 1872: return; 1873: 1874: case 'J': 1875: /* Similar, but add one for shift count in rlinm for scc and pass 1876: scc flag to `ccr_bit'. */ 1877: i = ccr_bit (x, 1); 1878: if (i == -1) 1879: output_operand_lossage ("invalid %%J code"); 1880: else 1.1.1.2 root 1881: /* If we want bit 31, write a shift count of zero, not 32. */ 1882: fprintf (file, "%d", i == 31 ? 0 : i + 1); 1.1 root 1883: return; 1884: 1885: case 'k': 1886: /* X must be a constant. Write the 1's complement of the 1887: constant. */ 1888: if (! INT_P (x)) 1889: output_operand_lossage ("invalid %%k value"); 1890: 1891: fprintf (file, "%d", ~ INT_LOWPART (x)); 1892: return; 1893: 1894: case 'L': 1895: /* Write second word of DImode or DFmode reference. Works on register 1896: or non-indexed memory only. */ 1897: if (GET_CODE (x) == REG) 1898: fprintf (file, "%d", REGNO (x) + 1); 1899: else if (GET_CODE (x) == MEM) 1900: { 1901: /* Handle possible auto-increment. Since it is pre-increment and 1902: we have already done it, we can just use an offset of four. */ 1903: if (GET_CODE (XEXP (x, 0)) == PRE_INC 1904: || GET_CODE (XEXP (x, 0)) == PRE_DEC) 1905: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4)); 1906: else 1907: output_address (plus_constant (XEXP (x, 0), 4)); 1908: } 1909: return; 1910: 1911: case 'm': 1912: /* MB value for a mask operand. */ 1913: if (! mask_operand (x, VOIDmode)) 1914: output_operand_lossage ("invalid %%m value"); 1915: 1916: val = INT_LOWPART (x); 1917: 1918: /* If the high bit is set and the low bit is not, the value is zero. 1919: If the high bit is zero, the value is the first 1 bit we find from 1920: the left. */ 1921: if (val < 0 && (val & 1) == 0) 1922: { 1923: fprintf (file, "0"); 1924: return; 1925: } 1926: else if (val >= 0) 1927: { 1928: for (i = 1; i < 32; i++) 1929: if ((val <<= 1) < 0) 1930: break; 1931: fprintf (file, "%d", i); 1932: return; 1933: } 1934: 1935: /* Otherwise, look for the first 0 bit from the right. The result is its 1936: number plus 1. We know the low-order bit is one. */ 1937: for (i = 0; i < 32; i++) 1938: if (((val >>= 1) & 1) == 0) 1939: break; 1940: 1941: /* If we ended in ...01, I would be 0. The correct value is 31, so 1942: we want 31 - i. */ 1943: fprintf (file, "%d", 31 - i); 1944: return; 1945: 1946: case 'M': 1947: /* ME value for a mask operand. */ 1948: if (! mask_operand (x, VOIDmode)) 1949: output_operand_lossage ("invalid %%m value"); 1950: 1951: val = INT_LOWPART (x); 1952: 1953: /* If the low bit is set and the high bit is not, the value is 31. 1954: If the low bit is zero, the value is the first 1 bit we find from 1955: the right. */ 1956: if ((val & 1) && val >= 0) 1957: { 1.1.1.2 root 1958: fputs ("31", file); 1.1 root 1959: return; 1960: } 1961: else if ((val & 1) == 0) 1962: { 1963: for (i = 0; i < 32; i++) 1964: if ((val >>= 1) & 1) 1965: break; 1966: 1967: /* If we had ....10, I would be 0. The result should be 1968: 30, so we need 30 - i. */ 1969: fprintf (file, "%d", 30 - i); 1970: return; 1971: } 1972: 1973: /* Otherwise, look for the first 0 bit from the left. The result is its 1974: number minus 1. We know the high-order bit is one. */ 1975: for (i = 0; i < 32; i++) 1976: if ((val <<= 1) >= 0) 1977: break; 1978: 1979: fprintf (file, "%d", i); 1980: return; 1981: 1982: case 'N': 1983: /* Write the number of elements in the vector times 4. */ 1984: if (GET_CODE (x) != PARALLEL) 1985: output_operand_lossage ("invalid %%N value"); 1986: 1987: fprintf (file, "%d", XVECLEN (x, 0) * 4); 1988: return; 1989: 1990: case 'O': 1991: /* Similar, but subtract 1 first. */ 1992: if (GET_CODE (x) != PARALLEL) 1993: output_operand_lossage ("invalid %%N value"); 1994: 1995: fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4); 1996: return; 1997: 1998: case 'p': 1999: /* X is a CONST_INT that is a power of two. Output the logarithm. */ 2000: if (! INT_P (x) 2001: || (i = exact_log2 (INT_LOWPART (x))) < 0) 2002: output_operand_lossage ("invalid %%p value"); 2003: 2004: fprintf (file, "%d", i); 2005: return; 2006: 2007: case 'P': 2008: /* The operand must be an indirect memory reference. The result 2009: is the register number. */ 2010: if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG 2011: || REGNO (XEXP (x, 0)) >= 32) 2012: output_operand_lossage ("invalid %%P value"); 2013: 2014: fprintf (file, "%d", REGNO (XEXP (x, 0))); 2015: return; 2016: 2017: case 'R': 2018: /* X is a CR register. Print the mask for `mtcrf'. */ 2019: if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x))) 2020: output_operand_lossage ("invalid %%R value"); 2021: else 2022: fprintf (file, "%d", 128 >> (REGNO (x) - 68)); 2023: return; 2024: 2025: case 's': 2026: /* Low 5 bits of 32 - value */ 2027: if (! INT_P (x)) 2028: output_operand_lossage ("invalid %%s value"); 2029: 2030: fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31); 2031: return; 2032: 2033: case 't': 2034: /* Write 12 if this jump operation will branch if true, 4 otherwise. 2035: All floating-point operations except NE branch true and integer 2036: EQ, LT, GT, LTU and GTU also branch true. */ 2037: if (GET_RTX_CLASS (GET_CODE (x)) != '<') 2038: output_operand_lossage ("invalid %%t value"); 2039: 2040: else if ((GET_MODE (XEXP (x, 0)) == CCFPmode 2041: && GET_CODE (x) != NE) 2042: || GET_CODE (x) == EQ 2043: || GET_CODE (x) == LT || GET_CODE (x) == GT 2044: || GET_CODE (x) == LTU || GET_CODE (x) == GTU) 1.1.1.2 root 2045: fputs ("12", file); 1.1 root 2046: else 1.1.1.2 root 2047: putc ('4', file); 1.1 root 2048: return; 2049: 2050: case 'T': 2051: /* Opposite of 't': write 4 if this jump operation will branch if true, 2052: 12 otherwise. */ 2053: if (GET_RTX_CLASS (GET_CODE (x)) != '<') 2054: output_operand_lossage ("invalid %%t value"); 2055: 2056: else if ((GET_MODE (XEXP (x, 0)) == CCFPmode 2057: && GET_CODE (x) != NE) 2058: || GET_CODE (x) == EQ 2059: || GET_CODE (x) == LT || GET_CODE (x) == GT 2060: || GET_CODE (x) == LTU || GET_CODE (x) == GTU) 1.1.1.2 root 2061: putc ('4', file); 1.1 root 2062: else 1.1.1.2 root 2063: fputs ("12", file); 1.1 root 2064: return; 2065: 2066: case 'u': 2067: /* High-order 16 bits of constant. */ 2068: if (! INT_P (x)) 2069: output_operand_lossage ("invalid %%u value"); 2070: 1.1.1.2 root 2071: fprintf (file, "0x%x", (INT_LOWPART (x) >> 16) & 0xffff); 1.1 root 2072: return; 2073: 2074: case 'U': 2075: /* Print `u' if this has an auto-increment or auto-decrement. */ 2076: if (GET_CODE (x) == MEM 2077: && (GET_CODE (XEXP (x, 0)) == PRE_INC 2078: || GET_CODE (XEXP (x, 0)) == PRE_DEC)) 1.1.1.2 root 2079: putc ('u', file); 1.1 root 2080: return; 2081: 2082: case 'w': 2083: /* If constant, low-order 16 bits of constant, signed. Otherwise, write 2084: normally. */ 2085: if (INT_P (x)) 2086: fprintf (file, "%d", 2087: (INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000)); 2088: else 2089: print_operand (file, x, 0); 2090: return; 2091: 2092: case 'W': 2093: /* If constant, low-order 16 bits of constant, unsigned. 2094: Otherwise, write normally. */ 2095: if (INT_P (x)) 2096: fprintf (file, "%d", INT_LOWPART (x) & 0xffff); 2097: else 2098: print_operand (file, x, 0); 2099: return; 2100: 2101: case 'X': 2102: if (GET_CODE (x) == MEM 2103: && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0))) 1.1.1.2 root 2104: putc ('x', file); 1.1 root 2105: return; 2106: 2107: case 'Y': 2108: /* Like 'L', for third word of TImode */ 2109: if (GET_CODE (x) == REG) 2110: fprintf (file, "%d", REGNO (x) + 2); 2111: else if (GET_CODE (x) == MEM) 2112: { 2113: if (GET_CODE (XEXP (x, 0)) == PRE_INC 2114: || GET_CODE (XEXP (x, 0)) == PRE_DEC) 2115: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8)); 2116: else 2117: output_address (plus_constant (XEXP (x, 0), 8)); 2118: } 2119: return; 2120: 2121: case 'z': 2122: /* X is a SYMBOL_REF. Write out the name preceded by a 2123: period and without any trailing data in brackets. Used for function 1.1.1.4 ! root 2124: names. If we are configured for System V (or the embedded ABI) on ! 2125: the PowerPC, do not emit the period, since those systems do not use ! 2126: TOCs and the like. */ 1.1 root 2127: if (GET_CODE (x) != SYMBOL_REF) 2128: abort (); 2129: 1.1.1.4 ! root 2130: #ifndef USING_SVR4_H 1.1.1.2 root 2131: putc ('.', file); 1.1.1.4 ! root 2132: #endif 1.1 root 2133: RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); 2134: return; 2135: 2136: case 'Z': 2137: /* Like 'L', for last word of TImode. */ 2138: if (GET_CODE (x) == REG) 2139: fprintf (file, "%d", REGNO (x) + 3); 2140: else if (GET_CODE (x) == MEM) 2141: { 2142: if (GET_CODE (XEXP (x, 0)) == PRE_INC 2143: || GET_CODE (XEXP (x, 0)) == PRE_DEC) 2144: output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12)); 2145: else 2146: output_address (plus_constant (XEXP (x, 0), 12)); 2147: } 2148: return; 2149: 2150: case 0: 2151: if (GET_CODE (x) == REG) 2152: fprintf (file, "%s", reg_names[REGNO (x)]); 2153: else if (GET_CODE (x) == MEM) 2154: { 2155: /* We need to handle PRE_INC and PRE_DEC here, since we need to 2156: know the width from the mode. */ 2157: if (GET_CODE (XEXP (x, 0)) == PRE_INC) 2158: fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)), 2159: REGNO (XEXP (XEXP (x, 0), 0))); 2160: else if (GET_CODE (XEXP (x, 0)) == PRE_DEC) 2161: fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)), 2162: REGNO (XEXP (XEXP (x, 0), 0))); 2163: else 2164: output_address (XEXP (x, 0)); 2165: } 2166: else 2167: output_addr_const (file, x); 1.1.1.2 root 2168: return; 1.1 root 2169: 2170: default: 2171: output_operand_lossage ("invalid %%xn code"); 2172: } 2173: } 2174: 2175: /* Print the address of an operand. */ 2176: 2177: void 2178: print_operand_address (file, x) 2179: FILE *file; 2180: register rtx x; 2181: { 2182: if (GET_CODE (x) == REG) 1.1.1.4 ! root 2183: fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); 1.1 root 2184: else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST) 2185: { 2186: output_addr_const (file, x); 1.1.1.2 root 2187: /* When TARGET_MINIMAL_TOC, use the indirected toc table pointer instead 2188: of the toc pointer. */ 1.1.1.4 ! root 2189: #ifdef TARGET_NO_TOC ! 2190: if (TARGET_NO_TOC) ! 2191: ; 1.1.1.2 root 2192: else 1.1.1.4 ! root 2193: #endif ! 2194: fprintf (file, "(%s)", reg_names[ TARGET_MINIMAL_TOC ? 30 : 2 ]); 1.1 root 2195: } 2196: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG) 2197: { 2198: if (REGNO (XEXP (x, 0)) == 0) 1.1.1.4 ! root 2199: fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ], ! 2200: reg_names[ REGNO (XEXP (x, 0)) ]); 1.1 root 2201: else 1.1.1.4 ! root 2202: fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ], ! 2203: reg_names[ REGNO (XEXP (x, 1)) ]); 1.1 root 2204: } 2205: else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) 1.1.1.4 ! root 2206: fprintf (file, "%d(%s)", INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]); ! 2207: else if (TARGET_ELF && !TARGET_64BIT && GET_CODE (x) == LO_SUM ! 2208: && GET_CODE (XEXP (x, 0)) == REG && CONSTANT_P (XEXP (x, 1))) ! 2209: { ! 2210: output_addr_const (file, XEXP (x, 1)); ! 2211: fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]); ! 2212: } 1.1 root 2213: else 2214: abort (); 2215: } 2216: 2217: /* This page contains routines that are used to determine what the function 2218: prologue and epilogue code will do and write them out. */ 2219: 2220: /* Return the first fixed-point register that is required to be saved. 32 if 2221: none. */ 2222: 2223: int 2224: first_reg_to_save () 2225: { 2226: int first_reg; 2227: 2228: /* Find lowest numbered live register. */ 2229: for (first_reg = 13; first_reg <= 31; first_reg++) 2230: if (regs_ever_live[first_reg]) 2231: break; 2232: 2233: /* If profiling, then we must save/restore every register that contains 2234: a parameter before/after the .mcount call. Use registers from 30 down 2235: to 23 to do this. Don't use the frame pointer in reg 31. 2236: 2237: For now, save enough room for all of the parameter registers. */ 1.1.1.4 ! root 2238: #ifndef USING_SVR4_H 1.1 root 2239: if (profile_flag) 2240: if (first_reg > 23) 2241: first_reg = 23; 1.1.1.4 ! root 2242: #endif 1.1 root 2243: 2244: return first_reg; 2245: } 2246: 2247: /* Similar, for FP regs. */ 2248: 2249: int 2250: first_fp_reg_to_save () 2251: { 2252: int first_reg; 2253: 2254: /* Find lowest numbered live register. */ 2255: for (first_reg = 14 + 32; first_reg <= 63; first_reg++) 2256: if (regs_ever_live[first_reg]) 2257: break; 2258: 2259: return first_reg; 2260: } 2261: 2262: /* Return non-zero if this function makes calls. */ 2263: 2264: int 2265: rs6000_makes_calls () 2266: { 2267: rtx insn; 2268: 2269: /* If we are profiling, we will be making a call to mcount. */ 2270: if (profile_flag) 2271: return 1; 2272: 2273: for (insn = get_insns (); insn; insn = next_insn (insn)) 2274: if (GET_CODE (insn) == CALL_INSN) 2275: return 1; 2276: 2277: return 0; 2278: } 2279: 1.1.1.4 ! root 2280: ! 2281: /* Calculate the stack information for the current function. This is ! 2282: complicated by having two separate calling sequences, the AIX calling ! 2283: sequence and the V.4 calling sequence. ! 2284: ! 2285: AIX stack frames look like: ! 2286: ! 2287: SP----> +---------------------------------------+ ! 2288: | back chain to caller | 0 ! 2289: +---------------------------------------+ ! 2290: | saved CR | 4 ! 2291: +---------------------------------------+ ! 2292: | saved LR | 8 ! 2293: +---------------------------------------+ ! 2294: | reserved for compilers | 12 ! 2295: +---------------------------------------+ ! 2296: | reserved for binders | 16 ! 2297: +---------------------------------------+ ! 2298: | saved TOC pointer | 20 ! 2299: +---------------------------------------+ ! 2300: | Parameter save area (P) | 24 ! 2301: +---------------------------------------+ ! 2302: | Alloca space (A) | 24+P ! 2303: +---------------------------------------+ ! 2304: | Local variable space (L) | 24+P+A ! 2305: +---------------------------------------+ ! 2306: | Save area for GP registers (G) | 24+P+A+L ! 2307: +---------------------------------------+ ! 2308: | Save area for FP registers (F) | 24+P+A+L+G ! 2309: +---------------------------------------+ ! 2310: old SP->| back chain to caller's caller | ! 2311: +---------------------------------------+ ! 2312: ! 2313: V.4 stack frames look like: ! 2314: ! 2315: SP----> +---------------------------------------+ ! 2316: | back chain to caller | 0 ! 2317: +---------------------------------------+ ! 2318: | caller's saved LR | 4 ! 2319: +---------------------------------------+ ! 2320: | Parameter save area (P) | 8 ! 2321: +---------------------------------------+ ! 2322: | Alloca space (A) | 8+P ! 2323: +---------------------------------------+ ! 2324: | Varargs save area (V) | 8+P+A ! 2325: +---------------------------------------+ ! 2326: | Local variable space (L) | 8+P+A+V ! 2327: +---------------------------------------+ ! 2328: | saved CR (C) | 8+P+A+V+L ! 2329: +---------------------------------------+ ! 2330: | Save area for GP registers (G) | 8+P+A+V+L+C ! 2331: +---------------------------------------+ ! 2332: | Save area for FP registers (F) | 8+P+A+V+L+C+G ! 2333: +---------------------------------------+ ! 2334: old SP->| back chain to caller's caller | ! 2335: +---------------------------------------+ ! 2336: */ ! 2337: ! 2338: rs6000_stack_t * ! 2339: rs6000_stack_info () ! 2340: { ! 2341: static rs6000_stack_t info, zero_info; ! 2342: rs6000_stack_t *info_ptr = &info; ! 2343: int reg_size = TARGET_64BIT ? 8 : 4; ! 2344: enum rs6000_abi abi; ! 2345: ! 2346: /* Zero all fields portably */ ! 2347: info = zero_info; ! 2348: ! 2349: /* Select which calling sequence */ ! 2350: #ifdef TARGET_V4_CALLS ! 2351: if (TARGET_V4_CALLS) ! 2352: abi = ABI_V4; ! 2353: else ! 2354: #endif ! 2355: abi = ABI_AIX; 1.1 root 2356: 1.1.1.4 ! root 2357: info_ptr->abi = abi; ! 2358: ! 2359: /* Calculate which registers need to be saved & save area size */ ! 2360: info_ptr->first_gp_reg_save = first_reg_to_save (); ! 2361: info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save); ! 2362: ! 2363: info_ptr->first_fp_reg_save = first_fp_reg_to_save (); ! 2364: info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); ! 2365: ! 2366: /* Does this function call anything? */ ! 2367: info_ptr->calls_p = rs6000_makes_calls (); ! 2368: ! 2369: /* Determine if we need to save the link register */ ! 2370: if (regs_ever_live[65] || profile_flag ! 2371: #ifdef TARGET_RELOCATABLE ! 2372: || (TARGET_RELOCATABLE && (get_pool_size () != 0)) ! 2373: #endif ! 2374: || (info_ptr->first_fp_reg_save != 64 ! 2375: && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save)) ! 2376: || (abi == ABI_V4 && current_function_calls_alloca) ! 2377: || info_ptr->calls_p) ! 2378: { ! 2379: info_ptr->lr_save_p = 1; ! 2380: regs_ever_live[65] = 1; ! 2381: } ! 2382: ! 2383: /* Determine if we need to save the condition code registers */ ! 2384: if (regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72]) ! 2385: { ! 2386: info_ptr->cr_save_p = 1; ! 2387: if (abi == ABI_V4) ! 2388: info_ptr->cr_size = reg_size; ! 2389: } ! 2390: ! 2391: /* Determine various sizes */ ! 2392: info_ptr->reg_size = reg_size; ! 2393: info_ptr->fixed_size = RS6000_SAVE_AREA; ! 2394: info_ptr->varargs_size = RS6000_VARARGS_AREA; ! 2395: info_ptr->vars_size = ALIGN (get_frame_size (), 8); ! 2396: info_ptr->parm_size = ALIGN (current_function_outgoing_args_size, 8); ! 2397: info_ptr->save_size = ALIGN (info_ptr->fp_size + info_ptr->gp_size + info_ptr->cr_size, 8); ! 2398: info_ptr->total_size = ALIGN (info_ptr->vars_size ! 2399: + info_ptr->parm_size ! 2400: + info_ptr->save_size ! 2401: + info_ptr->varargs_size ! 2402: + info_ptr->fixed_size, STACK_BOUNDARY / BITS_PER_UNIT); ! 2403: ! 2404: /* Determine if we need to allocate any stack frame. ! 2405: For AIX We need to push the stack if a frame pointer is needed (because ! 2406: the stack might be dynamically adjusted), if we are debugging, if the ! 2407: total stack size is more than 220 bytes, or if we make calls. ! 2408: ! 2409: For V.4 we don't have the stack cushion that AIX uses, but assume that ! 2410: the debugger can handle stackless frames. */ ! 2411: ! 2412: if (info_ptr->calls_p) ! 2413: info_ptr->push_p = 1; ! 2414: ! 2415: else if (abi == ABI_V4) ! 2416: info_ptr->push_p = (info_ptr->total_size > info_ptr->fixed_size ! 2417: || info_ptr->lr_save_p); ! 2418: ! 2419: else ! 2420: info_ptr->push_p = (frame_pointer_needed ! 2421: || write_symbols != NO_DEBUG ! 2422: || info_ptr->total_size > 220); ! 2423: ! 2424: /* Calculate the offsets */ ! 2425: info_ptr->fp_save_offset = - info_ptr->fp_size; ! 2426: info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; ! 2427: switch (abi) ! 2428: { ! 2429: default: ! 2430: info_ptr->cr_save_offset = 4; ! 2431: info_ptr->lr_save_offset = 8; ! 2432: break; ! 2433: ! 2434: case ABI_V4: ! 2435: info_ptr->cr_save_offset = info_ptr->gp_save_offset - reg_size; ! 2436: info_ptr->lr_save_offset = reg_size; ! 2437: break; ! 2438: } ! 2439: ! 2440: /* Zero offsets if we're not saving those registers */ ! 2441: if (!info_ptr->fp_size) ! 2442: info_ptr->fp_save_offset = 0; ! 2443: ! 2444: if (!info_ptr->gp_size) ! 2445: info_ptr->gp_save_offset = 0; ! 2446: ! 2447: if (!info_ptr->lr_save_p) ! 2448: info_ptr->lr_save_offset = 0; ! 2449: ! 2450: if (!info_ptr->cr_save_p) ! 2451: info_ptr->cr_save_offset = 0; ! 2452: ! 2453: return info_ptr; ! 2454: } ! 2455: ! 2456: void ! 2457: debug_stack_info (info) ! 2458: rs6000_stack_t *info; 1.1 root 2459: { 1.1.1.4 ! root 2460: char *abi_string; ! 2461: ! 2462: if (!info) ! 2463: info = rs6000_stack_info (); ! 2464: ! 2465: fprintf (stderr, "\nStack information for function %s:\n", ! 2466: ((current_function_decl && DECL_NAME (current_function_decl)) ! 2467: ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl)) ! 2468: : "<unknown>")); ! 2469: ! 2470: switch (info->abi) ! 2471: { ! 2472: default: abi_string = "Unknown"; break; ! 2473: case ABI_NONE: abi_string = "NONE"; break; ! 2474: case ABI_AIX: abi_string = "AIX"; break; ! 2475: case ABI_V4: abi_string = "V.4"; break; ! 2476: } ! 2477: ! 2478: fprintf (stderr, "\tABI = %5s\n", abi_string); ! 2479: ! 2480: if (info->first_gp_reg_save != 32) ! 2481: fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save); ! 2482: ! 2483: if (info->first_fp_reg_save != 64) ! 2484: fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save); ! 2485: ! 2486: if (info->lr_save_p) ! 2487: fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p); ! 2488: ! 2489: if (info->cr_save_p) ! 2490: fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p); ! 2491: ! 2492: if (info->push_p) ! 2493: fprintf (stderr, "\tpush_p = %5d\n", info->push_p); ! 2494: ! 2495: if (info->calls_p) ! 2496: fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p); ! 2497: ! 2498: if (info->gp_save_offset) ! 2499: fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset); 1.1 root 2500: 1.1.1.4 ! root 2501: if (info->fp_save_offset) ! 2502: fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset); 1.1 root 2503: 1.1.1.4 ! root 2504: if (info->lr_save_offset) ! 2505: fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset); ! 2506: ! 2507: if (info->cr_save_offset) ! 2508: fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset); ! 2509: ! 2510: if (info->varargs_save_offset) ! 2511: fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset); ! 2512: ! 2513: if (info->total_size) ! 2514: fprintf (stderr, "\ttotal_size = %5d\n", info->total_size); ! 2515: ! 2516: if (info->varargs_size) ! 2517: fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size); ! 2518: ! 2519: if (info->vars_size) ! 2520: fprintf (stderr, "\tvars_size = %5d\n", info->vars_size); ! 2521: ! 2522: if (info->parm_size) ! 2523: fprintf (stderr, "\tparm_size = %5d\n", info->parm_size); ! 2524: ! 2525: if (info->fixed_size) ! 2526: fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size); ! 2527: ! 2528: if (info->gp_size) ! 2529: fprintf (stderr, "\tgp_size = %5d\n", info->gp_size); ! 2530: ! 2531: if (info->fp_size) ! 2532: fprintf (stderr, "\tfp_size = %5d\n", info->fp_size); ! 2533: ! 2534: if (info->cr_size) ! 2535: fprintf (stderr, "\tcr_size = %5d\n", info->cr_size); ! 2536: ! 2537: if (info->save_size) ! 2538: fprintf (stderr, "\tsave_size = %5d\n", info->save_size); ! 2539: ! 2540: if (info->reg_size != 4) ! 2541: fprintf (stderr, "\treg_size = %5d\n", info->reg_size); ! 2542: ! 2543: fprintf (stderr, "\n"); 1.1 root 2544: } 2545: 1.1.1.4 ! root 2546: ! 2547: ! 2548: #ifdef USING_SVR4_H ! 2549: /* Write out a System V.4 style traceback table before the prologue ! 2550: ! 2551: At present, only emit the basic tag table (ie, do not emit tag_types other ! 2552: than 0, which might use more than 1 tag word). ! 2553: ! 2554: The first tag word looks like: ! 2555: ! 2556: 0 1 2 3 ! 2557: 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ! 2558: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! 2559: | 0 |ver| tag |e|s| alloca | # fprs | # gprs |s|l|c|f| ! 2560: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ! 2561: ! 2562: */ ! 2563: ! 2564: void ! 2565: svr4_traceback (file, name, decl) ! 2566: FILE *file; ! 2567: tree name, decl; ! 2568: { ! 2569: rs6000_stack_t *info = rs6000_stack_info (); ! 2570: long tag; ! 2571: long version = 0; /* version number */ ! 2572: long tag_type = 0; /* function type */ ! 2573: long extended_tag = 0; /* additional tag words needed */ ! 2574: long spare = 0; /* reserved for future use */ ! 2575: long fpscr_max = 0; /* 1 if the function has a FPSCR save word */ ! 2576: long fpr_max = 64 - info->first_fp_reg_save; /* # of floating point registers saved */ ! 2577: long gpr_max = 32 - info->first_gp_reg_save; /* # of general purpose registers saved */ ! 2578: long alloca_reg; /* stack/frame register */ ! 2579: ! 2580: if (frame_pointer_needed) ! 2581: alloca_reg = 31; ! 2582: ! 2583: else if (info->push_p != 0) ! 2584: alloca_reg = 1; ! 2585: ! 2586: else ! 2587: alloca_reg = 0; 1.1 root 2588: 1.1.1.4 ! root 2589: tag = ((version << 24) ! 2590: | (tag_type << 21) ! 2591: | (extended_tag << 20) ! 2592: | (spare << 19) ! 2593: | (alloca_reg << 14) ! 2594: | (fpr_max << 9) ! 2595: | (gpr_max << 4) ! 2596: | (info->push_p << 3) ! 2597: | (info->lr_save_p << 2) ! 2598: | (info->cr_save_p << 1) ! 2599: | (fpscr_max << 0)); ! 2600: ! 2601: fprintf (file, "\t.long 0x%lx\n", tag); ! 2602: } ! 2603: ! 2604: #endif /* USING_SVR4_H */ ! 2605: ! 2606: /* Write function prologue. */ 1.1 root 2607: void 2608: output_prolog (file, size) 2609: FILE *file; 2610: int size; 2611: { 1.1.1.4 ! root 2612: rs6000_stack_t *info = rs6000_stack_info (); ! 2613: char *store_reg = (TARGET_64BIT) ? "\tstd %s,%d(%s)" : "\t{st|stw} %s,%d(%s)\n"; 1.1 root 2614: 1.1.1.4 ! root 2615: if (TARGET_DEBUG_STACK) ! 2616: debug_stack_info (info); 1.1 root 2617: 2618: /* Write .extern for any function we will call to save and restore fp 2619: values. */ 1.1.1.4 ! root 2620: #ifndef USING_SVR4_H ! 2621: if (info->first_fp_reg_save < 62) ! 2622: fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n", ! 2623: SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX, ! 2624: RESTORE_FP_PREFIX, info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); ! 2625: #endif 1.1 root 2626: 2627: /* Write .extern for truncation routines, if needed. */ 2628: if (rs6000_trunc_used && ! trunc_defined) 2629: { 1.1.1.3 root 2630: fprintf (file, "\t.extern .%s\n\t.extern .%s\n", 2631: RS6000_ITRUNC, RS6000_UITRUNC); 1.1 root 2632: trunc_defined = 1; 2633: } 1.1.1.4 ! root 2634: 1.1.1.3 root 2635: /* Write .extern for AIX common mode routines, if needed. */ 2636: if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined) 2637: { 2638: fputs ("\t.extern __mulh\n", file); 2639: fputs ("\t.extern __mull\n", file); 2640: fputs ("\t.extern __divss\n", file); 2641: fputs ("\t.extern __divus\n", file); 2642: fputs ("\t.extern __quoss\n", file); 2643: fputs ("\t.extern __quous\n", file); 2644: common_mode_defined = 1; 2645: } 1.1 root 2646: 2647: /* If we use the link register, get it into r0. */ 1.1.1.4 ! root 2648: if (info->lr_save_p) ! 2649: asm_fprintf (file, "\tmflr %s\n", reg_names[0]); 1.1 root 2650: 2651: /* If we need to save CR, put it into r12. */ 1.1.1.4 ! root 2652: if (info->cr_save_p) ! 2653: asm_fprintf (file, "\tmfcr %s\n", reg_names[12]); 1.1 root 2654: 2655: /* Do any required saving of fpr's. If only one or two to save, do it 1.1.1.2 root 2656: ourself. Otherwise, call function. Note that since they are statically 2657: linked, we do not need a nop following them. */ 1.1.1.4 ! root 2658: if (FP_SAVE_INLINE (info->first_fp_reg_save)) ! 2659: { ! 2660: int regno = info->first_fp_reg_save; ! 2661: int loc = info->fp_save_offset; ! 2662: ! 2663: for ( ; regno < 64; regno++, loc += 8) ! 2664: asm_fprintf (file, "\tstfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]); ! 2665: } ! 2666: else if (info->first_fp_reg_save != 64) ! 2667: asm_fprintf (file, "\tbl %s%d%s\n", SAVE_FP_PREFIX, ! 2668: info->first_fp_reg_save - 32, SAVE_FP_SUFFIX); 1.1 root 2669: 2670: /* Now save gpr's. */ 1.1.1.4 ! root 2671: if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) 1.1.1.2 root 2672: { 1.1.1.4 ! root 2673: int regno = info->first_gp_reg_save; ! 2674: int loc = info->gp_save_offset; ! 2675: int reg_size = (TARGET_64BIT) ? 8 : 4; 1.1.1.2 root 2676: 1.1.1.4 ! root 2677: for ( ; regno < 32; regno++, loc += reg_size) ! 2678: asm_fprintf (file, store_reg, reg_names[regno], loc, reg_names[1]); 1.1.1.2 root 2679: } 2680: 1.1.1.4 ! root 2681: else if (info->first_gp_reg_save != 32) ! 2682: asm_fprintf (file, "\t{stm|stmw} %s,%d(%s)\n", ! 2683: reg_names[info->first_gp_reg_save], ! 2684: info->gp_save_offset, ! 2685: reg_names[1]); 1.1 root 2686: 2687: /* Save lr if we used it. */ 1.1.1.4 ! root 2688: if (info->lr_save_p) ! 2689: asm_fprintf (file, store_reg, reg_names[0], info->lr_save_offset, reg_names[1]); 1.1 root 2690: 2691: /* Save CR if we use any that must be preserved. */ 1.1.1.4 ! root 2692: if (info->cr_save_p) ! 2693: asm_fprintf (file, store_reg, reg_names[12], info->cr_save_offset, reg_names[1]); 1.1 root 2694: 2695: /* Update stack and set back pointer. */ 1.1.1.4 ! root 2696: if (info->push_p) 1.1 root 2697: { 1.1.1.4 ! root 2698: if (info->total_size < 32767) ! 2699: asm_fprintf (file, ! 2700: (TARGET_64BIT) ? "\tstdu %s,%d(%s)\n" : "\t{stu|stwu} %s,%d(%s)\n", ! 2701: reg_names[1], - info->total_size, reg_names[1]); 1.1 root 2702: else 2703: { 1.1.1.4 ! root 2704: int neg_size = - info->total_size; ! 2705: asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n", ! 2706: reg_names[0], (neg_size >> 16) & 0xffff, ! 2707: reg_names[0], reg_names[0], neg_size & 0xffff); ! 2708: asm_fprintf (file, ! 2709: (TARGET_64BIT) ? "\tstdux %s,%s,%s\n" : "\t{stux|stwux} %s,%s,%s\n", ! 2710: reg_names[1], reg_names[1], reg_names[0]); 1.1 root 2711: } 2712: } 2713: 2714: /* Set frame pointer, if needed. */ 2715: if (frame_pointer_needed) 1.1.1.4 ! root 2716: asm_fprintf (file, "\tmr %s,%s\n", reg_names[31], reg_names[1]); 1.1.1.2 root 2717: 2718: /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the 2719: TOC_TABLE address into register 30. */ 1.1.1.4 ! root 2720: if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0) 1.1.1.3 root 2721: { 1.1.1.4 ! root 2722: char buf[256]; 1.1.1.3 root 2723: 1.1.1.4 ! root 2724: #ifdef USING_SVR4_H ! 2725: if (TARGET_RELOCATABLE) ! 2726: { ! 2727: ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); ! 2728: fprintf (file, "\tbl "); ! 2729: assemble_name (file, buf); ! 2730: fprintf (file, "\n"); ! 2731: ! 2732: ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno); ! 2733: fprintf (file, "\tmflr %s\n", reg_names[30]); ! 2734: ! 2735: if (TARGET_POWERPC64) ! 2736: fprintf (file, "\tld"); ! 2737: else if (TARGET_NEW_MNEMONICS) ! 2738: fprintf (file, "\tlwz"); ! 2739: else ! 2740: fprintf (file, "\tl"); ! 2741: ! 2742: fprintf (file, " %s,(", reg_names[0]); ! 2743: ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); ! 2744: assemble_name (file, buf); ! 2745: fprintf (file, "-"); ! 2746: ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); ! 2747: assemble_name (file, buf); ! 2748: fprintf (file, ")(%s)\n", reg_names[30]); ! 2749: asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", ! 2750: reg_names[30], reg_names[0], reg_names[30]); ! 2751: rs6000_pic_labelno++; ! 2752: } ! 2753: else if (!TARGET_64BIT) ! 2754: { ! 2755: ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); ! 2756: asm_fprintf (file, "\t{cau|addis} %s,%s,", reg_names[30], reg_names[0]); ! 2757: assemble_name (file, buf); ! 2758: asm_fprintf (file, "@ha\n"); ! 2759: if (TARGET_NEW_MNEMONICS) ! 2760: { ! 2761: asm_fprintf (file, "\taddi %s,%s,", reg_names[30], reg_names[30]); ! 2762: assemble_name (file, buf); ! 2763: asm_fprintf (file, "@l\n"); ! 2764: } ! 2765: else ! 2766: { ! 2767: asm_fprintf (file, "\tcal %s,", reg_names[30]); ! 2768: assemble_name (file, buf); ! 2769: asm_fprintf (file, "@l(%s)\n", reg_names[30]); ! 2770: } ! 2771: } ! 2772: else ! 2773: abort (); ! 2774: ! 2775: #else /* !USING_SVR4_H */ 1.1.1.3 root 2776: ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0); 1.1.1.4 ! root 2777: asm_fprintf (file, "\t{l|lwz} %s,", reg_names[30]); 1.1.1.3 root 2778: assemble_name (file, buf); 1.1.1.4 ! root 2779: asm_fprintf (file, "(%s)\n", reg_names[2]); ! 2780: #endif /* USING_SVR4_H */ 1.1.1.3 root 2781: } 1.1 root 2782: } 2783: 2784: /* Write function epilogue. */ 2785: 2786: void 2787: output_epilog (file, size) 2788: FILE *file; 2789: int size; 2790: { 1.1.1.4 ! root 2791: rs6000_stack_t *info = rs6000_stack_info (); ! 2792: char *load_reg = (TARGET_64BIT) ? "\tld %s,%d(%s)" : "\t{l|lwz} %s,%d(%s)\n"; 1.1 root 2793: rtx insn = get_last_insn (); 1.1.1.4 ! root 2794: int i; 1.1 root 2795: 1.1.1.4 ! root 2796: /* Forget about any temporaries created */ ! 2797: for (i = 0; i < NUM_MACHINE_MODES; i++) ! 2798: stack_temps[i] = NULL_RTX; 1.1 root 2799: 2800: /* If the last insn was a BARRIER, we don't have to write anything except 2801: the trace table. */ 2802: if (GET_CODE (insn) == NOTE) 2803: insn = prev_nonnote_insn (insn); 2804: if (insn == 0 || GET_CODE (insn) != BARRIER) 2805: { 2806: /* If we have a frame pointer, a call to alloca, or a large stack 2807: frame, restore the old stack pointer using the backchain. Otherwise, 2808: we know what size to update it with. */ 2809: if (frame_pointer_needed || current_function_calls_alloca 1.1.1.4 ! root 2810: || info->total_size > 32767) ! 2811: asm_fprintf (file, load_reg, reg_names[1], 0, reg_names[1]); ! 2812: else if (info->push_p) ! 2813: { ! 2814: if (TARGET_NEW_MNEMONICS) ! 2815: asm_fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], info->total_size); ! 2816: else ! 2817: asm_fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], info->total_size, reg_names[1]); ! 2818: } 1.1 root 2819: 2820: /* Get the old lr if we saved it. */ 1.1.1.4 ! root 2821: if (info->lr_save_p) ! 2822: asm_fprintf (file, load_reg, reg_names[0], info->lr_save_offset, reg_names[1]); 1.1 root 2823: 2824: /* Get the old cr if we saved it. */ 1.1.1.4 ! root 2825: if (info->cr_save_p) ! 2826: asm_fprintf (file, load_reg, reg_names[12], info->cr_save_offset, reg_names[1]); 1.1 root 2827: 2828: /* Set LR here to try to overlap restores below. */ 1.1.1.4 ! root 2829: if (info->lr_save_p) ! 2830: asm_fprintf (file, "\tmtlr %s\n", reg_names[0]); 1.1 root 2831: 2832: /* Restore gpr's. */ 1.1.1.4 ! root 2833: if (! TARGET_MULTIPLE || info->first_gp_reg_save == 31 || TARGET_64BIT) 1.1.1.2 root 2834: { 1.1.1.4 ! root 2835: int regno = info->first_gp_reg_save; ! 2836: int loc = info->gp_save_offset; ! 2837: int reg_size = (TARGET_64BIT) ? 8 : 4; 1.1.1.2 root 2838: 1.1.1.4 ! root 2839: for ( ; regno < 32; regno++, loc += reg_size) ! 2840: asm_fprintf (file, load_reg, reg_names[regno], loc, reg_names[1]); 1.1.1.2 root 2841: } 2842: 1.1.1.4 ! root 2843: else if (info->first_gp_reg_save != 32) ! 2844: asm_fprintf (file, "\t{lm|lmw} %s,%d(%s)\n", ! 2845: reg_names[info->first_gp_reg_save], ! 2846: info->gp_save_offset, ! 2847: reg_names[1]); 1.1 root 2848: 2849: /* Restore fpr's if we can do it without calling a function. */ 1.1.1.4 ! root 2850: if (FP_SAVE_INLINE (info->first_fp_reg_save)) ! 2851: { ! 2852: int regno = info->first_fp_reg_save; ! 2853: int loc = info->fp_save_offset; ! 2854: ! 2855: for ( ; regno < 64; regno++, loc += 8) ! 2856: asm_fprintf (file, "\tlfd %s,%d(%s)\n", reg_names[regno], loc, reg_names[1]); ! 2857: } 1.1 root 2858: 2859: /* If we saved cr, restore it here. Just those of cr2, cr3, and cr4 2860: that were used. */ 1.1.1.4 ! root 2861: if (info->cr_save_p) ! 2862: asm_fprintf (file, "\tmtcrf %d,%s\n", 1.1.1.2 root 2863: (regs_ever_live[70] != 0) * 0x20 2864: + (regs_ever_live[71] != 0) * 0x10 1.1.1.4 ! root 2865: + (regs_ever_live[72] != 0) * 0x8, reg_names[12]); 1.1 root 2866: 2867: /* If we have to restore more than two FP registers, branch to the 2868: restore function. It will return to our caller. */ 1.1.1.4 ! root 2869: if (info->first_fp_reg_save != 64 && !FP_SAVE_INLINE (info->first_fp_reg_save)) ! 2870: asm_fprintf (file, "\tb %s%d%s\n", RESTORE_FP_PREFIX, ! 2871: info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX); 1.1 root 2872: else 1.1.1.2 root 2873: asm_fprintf (file, "\t{br|blr}\n"); 1.1 root 2874: } 2875: 2876: /* Output a traceback table here. See /usr/include/sys/debug.h for info 1.1.1.3 root 2877: on its format. 1.1 root 2878: 1.1.1.3 root 2879: We don't output a traceback table if -finhibit-size-directive was 2880: used. The documentation for -finhibit-size-directive reads 2881: ``don't output a @code{.size} assembler directive, or anything 2882: else that would cause trouble if the function is split in the 2883: middle, and the two halves are placed at locations far apart in 2884: memory.'' The traceback table has this property, since it 2885: includes the offset from the start of the function to the 1.1.1.4 ! root 2886: traceback table itself. ! 2887: ! 2888: System V.4 Powerpc's (and the embedded ABI derived from it) use a ! 2889: different traceback table located before the prologue. */ ! 2890: #ifndef USING_SVR4_H 1.1.1.3 root 2891: if (! flag_inhibit_size_directive) 2892: { 2893: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); 2894: int fixed_parms, float_parms, parm_info; 2895: int i; 2896: 2897: /* Need label immediately before tbtab, so we can compute its offset 2898: from the function start. */ 2899: if (*fname == '*') 2900: ++fname; 2901: ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); 2902: ASM_OUTPUT_LABEL (file, fname); 2903: 2904: /* The .tbtab pseudo-op can only be used for the first eight 2905: expressions, since it can't handle the possibly variable 2906: length fields that follow. However, if you omit the optional 2907: fields, the assembler outputs zeros for all optional fields 2908: anyways, giving each variable length field is minimum length 2909: (as defined in sys/debug.h). Thus we can not use the .tbtab 2910: pseudo-op at all. */ 2911: 2912: /* An all-zero word flags the start of the tbtab, for debuggers 2913: that have to find it by searching forward from the entry 2914: point or from the current pc. */ 2915: fprintf (file, "\t.long 0\n"); 2916: 2917: /* Tbtab format type. Use format type 0. */ 2918: fprintf (file, "\t.byte 0,"); 2919: 2920: /* Language type. Unfortunately, there doesn't seem to be any 2921: official way to get this info, so we use language_string. C 2922: is 0. C++ is 9. No number defined for Obj-C, so use the 2923: value for C for now. */ 2924: if (! strcmp (language_string, "GNU C") 2925: || ! strcmp (language_string, "GNU Obj-C")) 2926: i = 0; 2927: else if (! strcmp (language_string, "GNU F77")) 2928: i = 1; 2929: else if (! strcmp (language_string, "GNU Ada")) 2930: i = 3; 2931: else if (! strcmp (language_string, "GNU PASCAL")) 2932: i = 2; 2933: else if (! strcmp (language_string, "GNU C++")) 2934: i = 9; 2935: else 2936: abort (); 2937: fprintf (file, "%d,", i); 1.1 root 2938: 1.1.1.3 root 2939: /* 8 single bit fields: global linkage (not set for C extern linkage, 2940: apparently a PL/I convention?), out-of-line epilogue/prologue, offset 2941: from start of procedure stored in tbtab, internal function, function 2942: has controlled storage, function has no toc, function uses fp, 2943: function logs/aborts fp operations. */ 2944: /* Assume that fp operations are used if any fp reg must be saved. */ 1.1.1.4 ! root 2945: fprintf (file, "%d,", (1 << 5) | ((info->first_fp_reg_save != 64) << 1)); 1.1.1.3 root 2946: 2947: /* 6 bitfields: function is interrupt handler, name present in 2948: proc table, function calls alloca, on condition directives 2949: (controls stack walks, 3 bits), saves condition reg, saves 2950: link reg. */ 2951: /* The `function calls alloca' bit seems to be set whenever reg 31 is 2952: set up as a frame pointer, even when there is no alloca call. */ 2953: fprintf (file, "%d,", 2954: ((1 << 6) | (frame_pointer_needed << 5) 1.1.1.4 ! root 2955: | (info->cr_save_p << 1) | (info->lr_save_p))); 1.1.1.3 root 2956: 2957: /* 3 bitfields: saves backchain, spare bit, number of fpr saved 2958: (6 bits). */ 2959: fprintf (file, "%d,", 1.1.1.4 ! root 2960: (info->push_p << 7) | (64 - info->first_fp_reg_save)); 1.1.1.3 root 2961: 2962: /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */ 2963: fprintf (file, "%d,", (32 - first_reg_to_save ())); 2964: 2965: { 2966: /* Compute the parameter info from the function decl argument 2967: list. */ 2968: tree decl; 2969: int next_parm_info_bit; 2970: 2971: next_parm_info_bit = 31; 2972: parm_info = 0; 2973: fixed_parms = 0; 2974: float_parms = 0; 1.1 root 2975: 1.1.1.3 root 2976: for (decl = DECL_ARGUMENTS (current_function_decl); 2977: decl; decl = TREE_CHAIN (decl)) 2978: { 2979: rtx parameter = DECL_INCOMING_RTL (decl); 2980: enum machine_mode mode = GET_MODE (parameter); 2981: 2982: if (GET_CODE (parameter) == REG) 2983: { 2984: if (GET_MODE_CLASS (mode) == MODE_FLOAT) 2985: { 2986: int bits; 2987: 2988: float_parms++; 2989: 2990: if (mode == SFmode) 2991: bits = 0x2; 2992: else if (mode == DFmode) 2993: bits = 0x3; 2994: else 2995: abort (); 2996: 2997: /* If only one bit will fit, don't or in this entry. */ 2998: if (next_parm_info_bit > 0) 2999: parm_info |= (bits << (next_parm_info_bit - 1)); 3000: next_parm_info_bit -= 2; 3001: } 3002: else 3003: { 3004: fixed_parms += ((GET_MODE_SIZE (mode) 3005: + (UNITS_PER_WORD - 1)) 3006: / UNITS_PER_WORD); 3007: next_parm_info_bit -= 1; 3008: } 3009: } 3010: } 3011: } 1.1 root 3012: 1.1.1.3 root 3013: /* Number of fixed point parameters. */ 3014: /* This is actually the number of words of fixed point parameters; thus 3015: an 8 byte struct counts as 2; and thus the maximum value is 8. */ 3016: fprintf (file, "%d,", fixed_parms); 3017: 3018: /* 2 bitfields: number of floating point parameters (7 bits), parameters 3019: all on stack. */ 3020: /* This is actually the number of fp registers that hold parameters; 3021: and thus the maximum value is 13. */ 3022: /* Set parameters on stack bit if parameters are not in their original 3023: registers, regardless of whether they are on the stack? Xlc 3024: seems to set the bit when not optimizing. */ 3025: fprintf (file, "%d\n", ((float_parms << 1) | (! optimize))); 3026: 3027: /* Optional fields follow. Some are variable length. */ 3028: 3029: /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float, 3030: 11 double float. */ 3031: /* There is an entry for each parameter in a register, in the order that 3032: they occur in the parameter list. Any intervening arguments on the 3033: stack are ignored. If the list overflows a long (max possible length 3034: 34 bits) then completely leave off all elements that don't fit. */ 3035: /* Only emit this long if there was at least one parameter. */ 3036: if (fixed_parms || float_parms) 3037: fprintf (file, "\t.long %d\n", parm_info); 3038: 3039: /* Offset from start of code to tb table. */ 3040: fprintf (file, "\t.long "); 3041: ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT"); 3042: RS6000_OUTPUT_BASENAME (file, fname); 3043: fprintf (file, "-."); 3044: RS6000_OUTPUT_BASENAME (file, fname); 3045: fprintf (file, "\n"); 3046: 3047: /* Interrupt handler mask. */ 3048: /* Omit this long, since we never set the interrupt handler bit 3049: above. */ 3050: 3051: /* Number of CTL (controlled storage) anchors. */ 3052: /* Omit this long, since the has_ctl bit is never set above. */ 3053: 3054: /* Displacement into stack of each CTL anchor. */ 3055: /* Omit this list of longs, because there are no CTL anchors. */ 3056: 3057: /* Length of function name. */ 3058: fprintf (file, "\t.short %d\n", strlen (fname)); 3059: 3060: /* Function name. */ 3061: assemble_string (fname, strlen (fname)); 3062: 3063: /* Register for alloca automatic storage; this is always reg 31. 3064: Only emit this if the alloca bit was set above. */ 3065: if (frame_pointer_needed) 3066: fprintf (file, "\t.byte 31\n"); 3067: } 1.1.1.4 ! root 3068: #endif /* !USING_SVR4_H */ ! 3069: ! 3070: /* Reset varargs indicator */ ! 3071: rs6000_sysv_varargs_p = 0; 1.1 root 3072: } 3073: 3074: /* Output a TOC entry. We derive the entry name from what is 3075: being written. */ 3076: 3077: void 3078: output_toc (file, x, labelno) 3079: FILE *file; 3080: rtx x; 3081: int labelno; 3082: { 3083: char buf[256]; 3084: char *name = buf; 3085: rtx base = x; 3086: int offset = 0; 3087: 1.1.1.4 ! root 3088: if (TARGET_NO_TOC) ! 3089: abort (); ! 3090: ! 3091: /* if we're going to put a double constant in the TOC, make sure it's ! 3092: aligned properly when strict alignment is on. */ ! 3093: if (GET_CODE (x) == CONST_DOUBLE ! 3094: && STRICT_ALIGNMENT ! 3095: && GET_MODE (x) == DFmode ! 3096: && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { ! 3097: ASM_OUTPUT_ALIGN (file, 3); ! 3098: } ! 3099: ! 3100: ! 3101: #ifdef USING_SVR4_H ! 3102: if (TARGET_MINIMAL_TOC) ! 3103: { ! 3104: ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC"); ! 3105: fprintf (file, "%d = .-", labelno); ! 3106: ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC"); ! 3107: fprintf (file, "1\n"); ! 3108: } ! 3109: else ! 3110: #endif /* USING_SVR4_H */ ! 3111: ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno); 1.1 root 3112: 1.1.1.2 root 3113: /* Handle FP constants specially. Note that if we have a minimal 3114: TOC, things we put here aren't actually in the TOC, so we can allow 3115: FP constants. */ 1.1 root 3116: if (GET_CODE (x) == CONST_DOUBLE 3117: && GET_MODE (x) == DFmode 1.1.1.2 root 3118: && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) 1.1 root 3119: { 1.1.1.4 ! root 3120: REAL_VALUE_TYPE r; ! 3121: long l[2]; ! 3122: ! 3123: REAL_VALUE_FROM_CONST_DOUBLE (r, x); ! 3124: REAL_VALUE_TO_TARGET_DOUBLE (r, l); 1.1.1.2 root 3125: if (TARGET_MINIMAL_TOC) 1.1.1.4 ! root 3126: fprintf (file, "\t.long %ld\n\t.long %ld\n", l[0], l[1]); 1.1.1.2 root 3127: else 1.1.1.4 ! root 3128: fprintf (file, "\t.tc FD_%lx_%lx[TC],%ld,%ld\n", ! 3129: l[0], l[1], l[0], l[1]); 1.1 root 3130: return; 3131: } 3132: else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode 1.1.1.2 root 3133: && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) 1.1 root 3134: { 3135: rtx val = operand_subword (x, 0, 0, SFmode); 3136: 3137: if (val == 0 || GET_CODE (val) != CONST_INT) 3138: abort (); 3139: 1.1.1.2 root 3140: if (TARGET_MINIMAL_TOC) 3141: fprintf (file, "\t.long %d\n", INTVAL (val)); 3142: else 3143: fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val)); 1.1 root 3144: return; 3145: } 3146: 3147: if (GET_CODE (x) == CONST) 3148: { 3149: base = XEXP (XEXP (x, 0), 0); 3150: offset = INTVAL (XEXP (XEXP (x, 0), 1)); 3151: } 3152: 3153: if (GET_CODE (base) == SYMBOL_REF) 3154: name = XSTR (base, 0); 3155: else if (GET_CODE (base) == LABEL_REF) 3156: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0))); 3157: else if (GET_CODE (base) == CODE_LABEL) 3158: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base)); 3159: else 3160: abort (); 3161: 1.1.1.2 root 3162: if (TARGET_MINIMAL_TOC) 3163: fprintf (file, "\t.long "); 3164: else 3165: { 3166: fprintf (file, "\t.tc "); 3167: RS6000_OUTPUT_BASENAME (file, name); 1.1 root 3168: 1.1.1.2 root 3169: if (offset < 0) 3170: fprintf (file, ".N%d", - offset); 3171: else if (offset) 3172: fprintf (file, ".P%d", offset); 1.1 root 3173: 1.1.1.2 root 3174: fprintf (file, "[TC],"); 3175: } 1.1 root 3176: output_addr_const (file, x); 3177: fprintf (file, "\n"); 3178: } 3179: 3180: /* Output an assembler pseudo-op to write an ASCII string of N characters 3181: starting at P to FILE. 3182: 3183: On the RS/6000, we have to do this using the .byte operation and 3184: write out special characters outside the quoted string. 3185: Also, the assembler is broken; very long strings are truncated, 3186: so we must artificially break them up early. */ 3187: 3188: void 3189: output_ascii (file, p, n) 3190: FILE *file; 3191: char *p; 3192: int n; 3193: { 3194: char c; 3195: int i, count_string; 3196: char *for_string = "\t.byte \""; 3197: char *for_decimal = "\t.byte "; 3198: char *to_close = NULL; 3199: 3200: count_string = 0; 3201: for (i = 0; i < n; i++) 3202: { 3203: c = *p++; 3204: if (c >= ' ' && c < 0177) 3205: { 3206: if (for_string) 3207: fputs (for_string, file); 3208: putc (c, file); 3209: 3210: /* Write two quotes to get one. */ 3211: if (c == '"') 3212: { 3213: putc (c, file); 3214: ++count_string; 3215: } 3216: 3217: for_string = NULL; 3218: for_decimal = "\"\n\t.byte "; 3219: to_close = "\"\n"; 3220: ++count_string; 3221: 3222: if (count_string >= 512) 3223: { 3224: fputs (to_close, file); 3225: 3226: for_string = "\t.byte \""; 3227: for_decimal = "\t.byte "; 3228: to_close = NULL; 3229: count_string = 0; 3230: } 3231: } 3232: else 3233: { 3234: if (for_decimal) 3235: fputs (for_decimal, file); 3236: fprintf (file, "%d", c); 3237: 3238: for_string = "\n\t.byte \""; 3239: for_decimal = ", "; 3240: to_close = "\n"; 3241: count_string = 0; 3242: } 3243: } 3244: 3245: /* Now close the string if we have written one. Then end the line. */ 3246: if (to_close) 3247: fprintf (file, to_close); 3248: } 3249: 3250: /* Generate a unique section name for FILENAME for a section type 3251: represented by SECTION_DESC. Output goes into BUF. 3252: 3253: SECTION_DESC can be any string, as long as it is different for each 3254: possible section type. 3255: 3256: We name the section in the same manner as xlc. The name begins with an 3257: underscore followed by the filename (after stripping any leading directory 3258: names) with the last period replaced by the string SECTION_DESC. If 3259: FILENAME does not contain a period, SECTION_DESC is appended to the end of 3260: the name. */ 3261: 3262: void 3263: rs6000_gen_section_name (buf, filename, section_desc) 3264: char **buf; 3265: char *filename; 3266: char *section_desc; 3267: { 3268: char *q, *after_last_slash, *last_period; 3269: char *p; 3270: int len; 3271: 3272: after_last_slash = filename; 3273: for (q = filename; *q; q++) 3274: { 3275: if (*q == '/') 3276: after_last_slash = q + 1; 3277: else if (*q == '.') 3278: last_period = q; 3279: } 3280: 3281: len = strlen (after_last_slash) + strlen (section_desc) + 2; 3282: *buf = (char *) permalloc (len); 3283: 3284: p = *buf; 3285: *p++ = '_'; 3286: 3287: for (q = after_last_slash; *q; q++) 3288: { 3289: if (q == last_period) 3290: { 3291: strcpy (p, section_desc); 3292: p += strlen (section_desc); 3293: } 3294: 3295: else if (isalnum (*q)) 3296: *p++ = *q; 3297: } 3298: 3299: if (last_period == 0) 3300: strcpy (p, section_desc); 3301: else 3302: *p = '\0'; 3303: } 3304: 3305: /* Write function profiler code. */ 3306: 3307: void 3308: output_function_profiler (file, labelno) 3309: FILE *file; 3310: int labelno; 3311: { 1.1.1.4 ! root 3312: #ifdef USING_SVR4_H ! 3313: abort (); ! 3314: #else 1.1 root 3315: /* The last used parameter register. */ 3316: int last_parm_reg; 3317: int i, j; 1.1.1.3 root 3318: char buf[100]; 1.1 root 3319: 3320: /* Set up a TOC entry for the profiler label. */ 3321: toc_section (); 1.1.1.3 root 3322: ASM_OUTPUT_INTERNAL_LABEL (file, "LPC", labelno); 3323: ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 1.1.1.2 root 3324: if (TARGET_MINIMAL_TOC) 1.1.1.3 root 3325: { 3326: fprintf (file, "\t.long "); 3327: assemble_name (file, buf); 3328: fprintf (file, "\n"); 3329: } 1.1.1.2 root 3330: else 1.1.1.3 root 3331: { 3332: fprintf (file, "\t.tc\t"); 3333: assemble_name (file, buf); 3334: fprintf (file, "[TC],"); 3335: assemble_name (file, buf); 3336: fprintf (file, "\n"); 3337: } 1.1 root 3338: text_section (); 3339: 3340: /* Figure out last used parameter register. The proper thing to do is 3341: to walk incoming args of the function. A function might have live 3342: parameter registers even if it has no incoming args. */ 3343: 3344: for (last_parm_reg = 10; 3345: last_parm_reg > 2 && ! regs_ever_live [last_parm_reg]; 3346: last_parm_reg--) 3347: ; 3348: 3349: /* Save parameter registers in regs 23-30. Don't overwrite reg 31, since 3350: it might be set up as the frame pointer. */ 3351: 3352: for (i = 3, j = 30; i <= last_parm_reg; i++, j--) 3353: fprintf (file, "\tai %d,%d,0\n", j, i); 3354: 3355: /* Load location address into r3, and call mcount. */ 3356: 1.1.1.3 root 3357: ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno); 3358: fprintf (file, "\tl 3,"); 3359: assemble_name (file, buf); 3360: fprintf (file, "(2)\n\tbl .mcount\n"); 1.1 root 3361: 3362: /* Restore parameter registers. */ 3363: 3364: for (i = 3, j = 30; i <= last_parm_reg; i++, j--) 3365: fprintf (file, "\tai %d,%d,0\n", i, j); 1.1.1.4 ! root 3366: #endif 1.1 root 3367: } 1.1.1.3 root 3368: 3369: /* Adjust the cost of a scheduling dependency. Return the new cost of 3370: a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 3371: 3372: int 3373: rs6000_adjust_cost (insn, link, dep_insn, cost) 3374: rtx insn; 3375: rtx link; 3376: rtx dep_insn; 3377: int cost; 3378: { 3379: if (! recog_memoized (insn)) 3380: return 0; 3381: 3382: if (REG_NOTE_KIND (link) != 0) 3383: return 0; 3384: 3385: if (REG_NOTE_KIND (link) == 0) 3386: { 3387: /* Data dependency; DEP_INSN writes a register that INSN reads some 3388: cycles later. */ 3389: 3390: /* Tell the first scheduling pass about the latency between a mtctr 3391: and bctr (and mtlr and br/blr). The first scheduling pass will not 3392: know about this latency since the mtctr instruction, which has the 3393: latency associated to it, will be generated by reload. */ 3394: if (get_attr_type (insn) == TYPE_JMPREG) 3395: return TARGET_POWER ? 5 : 4; 3396: 3397: /* Fall out to return default cost. */ 3398: } 3399: 3400: return cost; 3401: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.