Annotation of gcc/config/rs6000/rs6000.c, revision 1.1.1.4

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.