Annotation of GNUtools/cc/config/rs6000/rs6000.c, revision 1.1

1.1     ! root        1: /* Subroutines used for code generation on IBM RS/6000.
        !             2:    Copyright (C) 1991, 1993 Free Software Foundation, Inc.
        !             3:    Contributed by Richard Kenner ([email protected])
        !             4: 
        !             5: This file is part of GNU CC.
        !             6: 
        !             7: GNU CC is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU General Public License as published by
        !             9: the Free Software Foundation; either version 2, or (at your option)
        !            10: any later version.
        !            11: 
        !            12: GNU CC is distributed in the hope that it will be useful,
        !            13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with GNU CC; see the file COPYING.  If not, write to
        !            19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            20: 
        !            21: #include <stdio.h>
        !            22: #include "config.h"
        !            23: #include "rtl.h"
        !            24: #include "regs.h"
        !            25: #include "hard-reg-set.h"
        !            26: #include "real.h"
        !            27: #include "insn-config.h"
        !            28: #include "conditions.h"
        !            29: #include "insn-flags.h"
        !            30: #include "output.h"
        !            31: #include "insn-attr.h"
        !            32: #include "flags.h"
        !            33: #include "recog.h"
        !            34: #include "expr.h"
        !            35: #include "obstack.h"
        !            36: #include "tree.h"
        !            37: 
        !            38: extern char *language_string;
        !            39: extern int profile_block_flag;
        !            40: 
        !            41: #define min(A,B)       ((A) < (B) ? (A) : (B))
        !            42: #define max(A,B)       ((A) > (B) ? (A) : (B))
        !            43: 
        !            44: /* Target cpu type */
        !            45: 
        !            46: enum processor_type rs6000_cpu;
        !            47: char *rs6000_cpu_string;
        !            48: 
        !            49: /* Set to non-zero by "fix" operation to indicate that itrunc and
        !            50:    uitrunc must be defined.  */
        !            51: 
        !            52: int rs6000_trunc_used;
        !            53: 
        !            54: /* Set to non-zero once they have been defined.  */
        !            55: 
        !            56: static int trunc_defined;
        !            57: 
        !            58: /* Save information from a "cmpxx" operation until the branch or scc is
        !            59:    emitted.  */
        !            60: 
        !            61: rtx rs6000_compare_op0, rs6000_compare_op1;
        !            62: int rs6000_compare_fp_p;
        !            63: 
        !            64: /* Override command line options.  Mostly we process the processor
        !            65:    type and sometimes adjust other TARGET_ options.  */
        !            66: 
        !            67: void
        !            68: rs6000_override_options ()
        !            69: {
        !            70:   int i;
        !            71: 
        !            72:   /* Simplify the entries below by making a mask for any POWER
        !            73:      variant and any PowerPC variant.  */
        !            74: 
        !            75: #define POWER_MASKS (MASK_POWER | MASK_POWER2)
        !            76: #define POWERPC_MASKS (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64)
        !            77: 
        !            78:   static struct ptt
        !            79:     {
        !            80:       char *name;              /* Canonical processor name.  */
        !            81:       enum processor_type processor; /* Processor type enum value.  */
        !            82:       int target_enable;       /* Target flags to enable.  */
        !            83:       int target_disable;      /* Target flags to disable.  */
        !            84:     } processor_target_table[]
        !            85:       = {{"all", PROCESSOR_DEFAULT, 0, POWER_MASKS | POWERPC_MASKS},
        !            86:         {"rios", PROCESSOR_RIOS1, MASK_POWER, MASK_POWER2 | POWERPC_MASKS},
        !            87:         {"rios1", PROCESSOR_RIOS1, MASK_POWER, MASK_POWER2 | POWERPC_MASKS},
        !            88:         {"rsc", PROCESSOR_PPC601, MASK_POWER, MASK_POWER2 | POWERPC_MASKS},
        !            89:         {"rsc1", PROCESSOR_PPC601, MASK_POWER, MASK_POWER2 | POWERPC_MASKS},
        !            90:         {"rios2", PROCESSOR_RIOS2, MASK_POWER | MASK_POWER2 , POWERPC_MASKS},
        !            91:         {"601", PROCESSOR_PPC601,
        !            92:            MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
        !            93:            MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64},
        !            94:         {"mpc601", PROCESSOR_PPC601,
        !            95:            MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
        !            96:            MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64},
        !            97:         {"ppc601", PROCESSOR_PPC601,
        !            98:            MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS,
        !            99:            MASK_POWER2 | MASK_POWERPCSQR | MASK_POWERPC64},
        !           100:         {"603", PROCESSOR_PPC603,
        !           101:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           102:            POWER_MASKS | MASK_POWERPC64},
        !           103:         {"mpc603", PROCESSOR_PPC603,
        !           104:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           105:            POWER_MASKS | MASK_POWERPC64},
        !           106:         {"ppc603", PROCESSOR_PPC603,
        !           107:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           108:            POWER_MASKS | MASK_POWERPC64},
        !           109:         {"604", PROCESSOR_PPC604,
        !           110:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           111:            POWER_MASKS | MASK_POWERPC64},
        !           112:         {"mpc604", PROCESSOR_PPC604,
        !           113:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           114:            POWER_MASKS | MASK_POWERPC64},
        !           115:         {"ppc604", PROCESSOR_PPC604,
        !           116:            MASK_POWERPC | MASK_POWERPCSQR | MASK_NEW_MNEMONICS,
        !           117:            POWER_MASKS | MASK_POWERPC64},
        !           118:         {"620", PROCESSOR_PPC620,
        !           119:            (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64
        !           120:             | MASK_NEW_MNEMONICS),
        !           121:              POWER_MASKS},
        !           122:         {"mpc620", PROCESSOR_PPC620,
        !           123:            (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64
        !           124:             | MASK_NEW_MNEMONICS),
        !           125:              POWER_MASKS},
        !           126:         {"ppc620", PROCESSOR_PPC620,
        !           127:            (MASK_POWERPC | MASK_POWERPCSQR | MASK_POWERPC64
        !           128:             | MASK_NEW_MNEMONICS),
        !           129:              POWER_MASKS}};
        !           130: 
        !           131:   int ptt_size = sizeof (processor_target_table) / sizeof (struct ptt);
        !           132: 
        !           133:   profile_block_flag = 0;
        !           134: 
        !           135:   /* Identify the processor type */
        !           136:   if (rs6000_cpu_string == 0)
        !           137:     rs6000_cpu = PROCESSOR_DEFAULT;
        !           138:   else
        !           139:     {
        !           140:       for (i = 0; i < ptt_size; i++)
        !           141:        if (! strcmp (rs6000_cpu_string, processor_target_table[i].name))
        !           142:          {
        !           143:            rs6000_cpu = processor_target_table[i].processor;
        !           144:            target_flags |= processor_target_table[i].target_enable;
        !           145:            target_flags &= ~processor_target_table[i].target_disable;
        !           146:            break;
        !           147:          }
        !           148: 
        !           149:       if (i == ptt_size)
        !           150:        {
        !           151:          error ("bad value (%s) for -mcpu= switch", rs6000_cpu_string);
        !           152:          rs6000_cpu_string = "default";
        !           153:          rs6000_cpu = PROCESSOR_DEFAULT;
        !           154:        }
        !           155:     }
        !           156: }
        !           157: 
        !           158: /* Return non-zero if this function is known to have a null epilogue.  */
        !           159: 
        !           160: int
        !           161: direct_return ()
        !           162: {
        !           163:   return (reload_completed
        !           164:          && first_reg_to_save () == 32
        !           165:          && first_fp_reg_to_save () == 64
        !           166:          && ! regs_ever_live[65]
        !           167:          && ! rs6000_pushes_stack ());
        !           168: }
        !           169: 
        !           170: /* Returns 1 always.  */
        !           171: 
        !           172: int
        !           173: any_operand (op, mode)
        !           174:      register rtx op;
        !           175:      enum machine_mode mode;
        !           176: {
        !           177:   return 1;
        !           178: }
        !           179: 
        !           180: /* Return 1 if OP is a constant that can fit in a D field.  */
        !           181: 
        !           182: int
        !           183: short_cint_operand (op, mode)
        !           184:      register rtx op;
        !           185:      enum machine_mode mode;
        !           186: {
        !           187:   return (GET_CODE (op) == CONST_INT
        !           188:          && (unsigned) (INTVAL (op) + 0x8000) < 0x10000);
        !           189: }
        !           190: 
        !           191: /* Similar for a unsigned D field.  */
        !           192: 
        !           193: int
        !           194: u_short_cint_operand (op, mode)
        !           195:      register rtx op;
        !           196:      enum machine_mode mode;
        !           197: {
        !           198:   return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0);
        !           199: }
        !           200: 
        !           201: /* Return 1 if OP is a CONST_INT that cannot fit in a signed D field.  */
        !           202: 
        !           203: int
        !           204: non_short_cint_operand (op, mode)
        !           205:      register rtx op;
        !           206:      enum machine_mode mode;
        !           207: {
        !           208:   return (GET_CODE (op) == CONST_INT
        !           209:          && (unsigned) (INTVAL (op) + 0x8000) >= 0x10000);
        !           210: }
        !           211: 
        !           212: /* Returns 1 if OP is a register that is not special (i.e., not MQ,
        !           213:    ctr, or lr).  */
        !           214: 
        !           215: int
        !           216: gpc_reg_operand (op, mode)
        !           217:      register rtx op;
        !           218:      enum machine_mode mode;
        !           219: {
        !           220:   return (register_operand (op, mode)
        !           221:          && (GET_CODE (op) != REG || REGNO (op) >= 67 || REGNO (op) < 64));
        !           222: }
        !           223: 
        !           224: /* Returns 1 if OP is either a pseudo-register or a register denoting a
        !           225:    CR field.  */
        !           226: 
        !           227: int
        !           228: cc_reg_operand (op, mode)
        !           229:      register rtx op;
        !           230:      enum machine_mode mode;
        !           231: {
        !           232:   return (register_operand (op, mode)
        !           233:          && (GET_CODE (op) != REG
        !           234:              || REGNO (op) >= FIRST_PSEUDO_REGISTER
        !           235:              || CR_REGNO_P (REGNO (op))));
        !           236: }
        !           237: 
        !           238: /* Returns 1 if OP is either a constant integer valid for a D-field or a
        !           239:    non-special register.  If a register, it must be in the proper mode unless
        !           240:    MODE is VOIDmode.  */
        !           241: 
        !           242: int
        !           243: reg_or_short_operand (op, mode)
        !           244:       register rtx op;
        !           245:       enum machine_mode mode;
        !           246: {
        !           247:   return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
        !           248: }
        !           249: 
        !           250: /* Similar, except check if the negation of the constant would be valid for
        !           251:    a D-field.  */
        !           252: 
        !           253: int
        !           254: reg_or_neg_short_operand (op, mode)
        !           255:       register rtx op;
        !           256:       enum machine_mode mode;
        !           257: {
        !           258:   if (GET_CODE (op) == CONST_INT)
        !           259:     return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
        !           260: 
        !           261:   return gpc_reg_operand (op, mode);
        !           262: }
        !           263: 
        !           264: /* Return 1 if the operand is either a register or an integer whose high-order
        !           265:    16 bits are zero.  */
        !           266: 
        !           267: int
        !           268: reg_or_u_short_operand (op, mode)
        !           269:      register rtx op;
        !           270:      enum machine_mode mode;
        !           271: {
        !           272:   if (GET_CODE (op) == CONST_INT
        !           273:       && (INTVAL (op) & 0xffff0000) == 0)
        !           274:     return 1;
        !           275: 
        !           276:   return gpc_reg_operand (op, mode);
        !           277: }
        !           278: 
        !           279: /* Return 1 is the operand is either a non-special register or ANY
        !           280:    constant integer.  */
        !           281: 
        !           282: int
        !           283: reg_or_cint_operand (op, mode)
        !           284:     register rtx op;
        !           285:     enum machine_mode mode;
        !           286: {
        !           287:      return GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode);
        !           288: }
        !           289: 
        !           290: /* Return 1 if the operand is a CONST_DOUBLE and it can be put into a register
        !           291:    with one instruction per word.  We only do this if we can safely read
        !           292:    CONST_DOUBLE_{LOW,HIGH}.  */
        !           293: 
        !           294: int
        !           295: easy_fp_constant (op, mode)
        !           296:      register rtx op;
        !           297:      register enum machine_mode mode;
        !           298: {
        !           299:   rtx low, high;
        !           300: 
        !           301:   if (GET_CODE (op) != CONST_DOUBLE
        !           302:       || GET_MODE (op) != mode
        !           303:       || GET_MODE_CLASS (mode) != MODE_FLOAT)
        !           304:     return 0;
        !           305: 
        !           306:   high = operand_subword (op, 0, 0, mode);
        !           307:   low = operand_subword (op, 1, 0, mode);
        !           308: 
        !           309:   if (high == 0 || ! input_operand (high, word_mode))
        !           310:     return 0;
        !           311: 
        !           312:   return (mode == SFmode
        !           313:          || (low != 0 && input_operand (low, word_mode)));
        !           314: }
        !           315:       
        !           316: /* Return 1 if the operand is either a floating-point register, a pseudo
        !           317:    register, or memory.  */
        !           318: 
        !           319: int
        !           320: fp_reg_or_mem_operand (op, mode)
        !           321:      register rtx op;
        !           322:      enum machine_mode mode;
        !           323: {
        !           324:   return (memory_operand (op, mode)
        !           325:          || (register_operand (op, mode)
        !           326:              && (GET_CODE (op) != REG
        !           327:                  || REGNO (op) >= FIRST_PSEUDO_REGISTER
        !           328:                  || FP_REGNO_P (REGNO (op)))));
        !           329: }
        !           330: 
        !           331: /* Return 1 if the operand is either an easy FP constant (see above) or
        !           332:    memory.  */
        !           333: 
        !           334: int
        !           335: mem_or_easy_const_operand (op, mode)
        !           336:      register rtx op;
        !           337:      enum machine_mode mode;
        !           338: {
        !           339:   return memory_operand (op, mode) || easy_fp_constant (op, mode);
        !           340: }
        !           341: 
        !           342: /* Return 1 if the operand is either a non-special register or an item
        !           343:    that can be used as the operand of an SI add insn.  */
        !           344: 
        !           345: int
        !           346: add_operand (op, mode)
        !           347:     register rtx op;
        !           348:     enum machine_mode mode;
        !           349: {
        !           350:   return (reg_or_short_operand (op, mode)
        !           351:          || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0));
        !           352: }
        !           353: 
        !           354: /* Return 1 if OP is a constant but not a valid add_operand.  */
        !           355: 
        !           356: int
        !           357: non_add_cint_operand (op, mode)
        !           358:      register rtx op;
        !           359:      enum machine_mode mode;
        !           360: {
        !           361:   return (GET_CODE (op) == CONST_INT
        !           362:          && (unsigned) (INTVAL (op) + 0x8000) >= 0x10000
        !           363:          && (INTVAL (op) & 0xffff) != 0);
        !           364: }
        !           365: 
        !           366: /* Return 1 if the operand is a non-special register or a constant that
        !           367:    can be used as the operand of an OR or XOR insn on the RS/6000.  */
        !           368: 
        !           369: int
        !           370: logical_operand (op, mode)
        !           371:      register rtx op;
        !           372:      enum machine_mode mode;
        !           373: {
        !           374:   return (gpc_reg_operand (op, mode)
        !           375:          || (GET_CODE (op) == CONST_INT
        !           376:              && ((INTVAL (op) & 0xffff0000) == 0
        !           377:                  || (INTVAL (op) & 0xffff) == 0)));
        !           378: }
        !           379: 
        !           380: /* Return 1 if C is a constant that is not a logical operand (as
        !           381:    above).  */
        !           382: 
        !           383: int
        !           384: non_logical_cint_operand (op, mode)
        !           385:      register rtx op;
        !           386:      enum machine_mode mode;
        !           387: {
        !           388:   return (GET_CODE (op) == CONST_INT
        !           389:          && (INTVAL (op) & 0xffff0000) != 0
        !           390:          && (INTVAL (op) & 0xffff) != 0);
        !           391: }
        !           392: 
        !           393: /* Return 1 if C is a constant that can be encoded in a mask on the
        !           394:    RS/6000.  It is if there are no more than two 1->0 or 0->1 transitions.
        !           395:    Reject all ones and all zeros, since these should have been optimized
        !           396:    away and confuse the making of MB and ME.  */
        !           397: 
        !           398: int
        !           399: mask_constant (c)
        !           400:      register int c;
        !           401: {
        !           402:   int i;
        !           403:   int last_bit_value;
        !           404:   int transitions = 0;
        !           405: 
        !           406:   if (c == 0 || c == ~0)
        !           407:     return 0;
        !           408: 
        !           409:   last_bit_value = c & 1;
        !           410: 
        !           411:   for (i = 1; i < 32; i++)
        !           412:     if (((c >>= 1) & 1) != last_bit_value)
        !           413:       last_bit_value ^= 1, transitions++;
        !           414: 
        !           415:   return transitions <= 2;
        !           416: }
        !           417: 
        !           418: /* Return 1 if the operand is a constant that is a mask on the RS/6000. */
        !           419: 
        !           420: int
        !           421: mask_operand (op, mode)
        !           422:      register rtx op;
        !           423:      enum machine_mode mode;
        !           424: {
        !           425:   return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op));
        !           426: }
        !           427: 
        !           428: /* Return 1 if the operand is either a non-special register or a
        !           429:    constant that can be used as the operand of an RS/6000 logical AND insn.  */
        !           430: 
        !           431: int
        !           432: and_operand (op, mode)
        !           433:     register rtx op;
        !           434:     enum machine_mode mode;
        !           435: {
        !           436:   return (reg_or_short_operand (op, mode)
        !           437:          || logical_operand (op, mode)
        !           438:          || mask_operand (op, mode));
        !           439: }
        !           440: 
        !           441: /* Return 1 if the operand is a constant but not a valid operand for an AND
        !           442:    insn.  */
        !           443: 
        !           444: int
        !           445: non_and_cint_operand (op, mode)
        !           446:      register rtx op;
        !           447:      enum machine_mode mode;
        !           448: {
        !           449:   return GET_CODE (op) == CONST_INT && ! and_operand (op, mode);
        !           450: }
        !           451: 
        !           452: /* Return 1 if the operand is a general register or memory operand.  */
        !           453: 
        !           454: int
        !           455: reg_or_mem_operand (op, mode)
        !           456:      register rtx op;
        !           457:      register enum machine_mode mode;
        !           458: {
        !           459:   return gpc_reg_operand (op, mode) || memory_operand (op, mode);
        !           460: }
        !           461: 
        !           462: /* Return 1 if the operand, used inside a MEM, is a valid first argument
        !           463:    to CALL.  This is a SYMBOL_REF or a pseudo-register, which will be
        !           464:    forced to lr.  */
        !           465: 
        !           466: int
        !           467: call_operand (op, mode)
        !           468:      register rtx op;
        !           469:      enum machine_mode mode;
        !           470: {
        !           471:   if (mode != VOIDmode && GET_MODE (op) != mode)
        !           472:     return 0;
        !           473: 
        !           474:   return (GET_CODE (op) == SYMBOL_REF
        !           475:          || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER));
        !           476: }
        !           477: 
        !           478: 
        !           479: /* Return 1 if the operand is a SYMBOL_REF for a function known to be in
        !           480:    this file.  */
        !           481: 
        !           482: int
        !           483: current_file_function_operand (op, mode)
        !           484:      register rtx op;
        !           485:      enum machine_mode mode;
        !           486: {
        !           487:   return (GET_CODE (op) == SYMBOL_REF
        !           488:          && (SYMBOL_REF_FLAG (op)
        !           489:              || op == XEXP (DECL_RTL (current_function_decl), 0)));
        !           490: }
        !           491: 
        !           492: 
        !           493: /* Return 1 if this operand is a valid input for a move insn.  */
        !           494: 
        !           495: int
        !           496: input_operand (op, mode)
        !           497:      register rtx op;
        !           498:      enum machine_mode mode;
        !           499: {
        !           500:   /* Memory is always valid.  */
        !           501:   if (memory_operand (op, mode))
        !           502:     return 1;
        !           503: 
        !           504:   /* For floating-point, easy constants are valid.  */
        !           505:   if (GET_MODE_CLASS (mode) == MODE_FLOAT
        !           506:       && CONSTANT_P (op)
        !           507:       && easy_fp_constant (op, mode))
        !           508:     return 1;
        !           509: 
        !           510:   /* For floating-point or multi-word mode, the only remaining valid type
        !           511:      is a register.  */
        !           512:   if (GET_MODE_CLASS (mode) == MODE_FLOAT
        !           513:       || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
        !           514:     return register_operand (op, mode);
        !           515: 
        !           516:   /* The only cases left are integral modes one word or smaller (we
        !           517:      do not get called for MODE_CC values).  These can be in any
        !           518:      register.  */
        !           519:   if (register_operand (op, mode))
        !           520:     return 1;
        !           521: 
        !           522:   /* For HImode and QImode, any constant is valid. */
        !           523:   if ((mode == HImode || mode == QImode)
        !           524:       && GET_CODE (op) == CONST_INT)
        !           525:     return 1;
        !           526: 
        !           527:   /* Otherwise, we will be doing this SET with an add, so anything valid
        !           528:      for an add will be valid.  */
        !           529:   return add_operand (op, mode);
        !           530: }
        !           531: 
        !           532: /* Return 1 if OP is a load multiple operation.  It is known to be a
        !           533:    PARALLEL and the first section will be tested.  */
        !           534: 
        !           535: int
        !           536: load_multiple_operation (op, mode)
        !           537:      rtx op;
        !           538:      enum machine_mode mode;
        !           539: {
        !           540:   int count = XVECLEN (op, 0);
        !           541:   int dest_regno;
        !           542:   rtx src_addr;
        !           543:   int i;
        !           544: 
        !           545:   /* Perform a quick check so we don't blow up below.  */
        !           546:   if (count <= 1
        !           547:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
        !           548:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
        !           549:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
        !           550:     return 0;
        !           551: 
        !           552:   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
        !           553:   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
        !           554: 
        !           555:   for (i = 1; i < count; i++)
        !           556:     {
        !           557:       rtx elt = XVECEXP (op, 0, i);
        !           558: 
        !           559:       if (GET_CODE (elt) != SET
        !           560:          || GET_CODE (SET_DEST (elt)) != REG
        !           561:          || GET_MODE (SET_DEST (elt)) != SImode
        !           562:          || REGNO (SET_DEST (elt)) != dest_regno + i
        !           563:          || GET_CODE (SET_SRC (elt)) != MEM
        !           564:          || GET_MODE (SET_SRC (elt)) != SImode
        !           565:          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
        !           566:          || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
        !           567:          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
        !           568:          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
        !           569:        return 0;
        !           570:     }
        !           571: 
        !           572:   return 1;
        !           573: }
        !           574: 
        !           575: /* Similar, but tests for store multiple.  Here, the second vector element
        !           576:    is a CLOBBER.  It will be tested later.  */
        !           577: 
        !           578: int
        !           579: store_multiple_operation (op, mode)
        !           580:      rtx op;
        !           581:      enum machine_mode mode;
        !           582: {
        !           583:   int count = XVECLEN (op, 0) - 1;
        !           584:   int src_regno;
        !           585:   rtx dest_addr;
        !           586:   int i;
        !           587: 
        !           588:   /* Perform a quick check so we don't blow up below.  */
        !           589:   if (count <= 1
        !           590:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
        !           591:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
        !           592:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
        !           593:     return 0;
        !           594: 
        !           595:   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
        !           596:   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
        !           597: 
        !           598:   for (i = 1; i < count; i++)
        !           599:     {
        !           600:       rtx elt = XVECEXP (op, 0, i + 1);
        !           601: 
        !           602:       if (GET_CODE (elt) != SET
        !           603:          || GET_CODE (SET_SRC (elt)) != REG
        !           604:          || GET_MODE (SET_SRC (elt)) != SImode
        !           605:          || REGNO (SET_SRC (elt)) != src_regno + i
        !           606:          || GET_CODE (SET_DEST (elt)) != MEM
        !           607:          || GET_MODE (SET_DEST (elt)) != SImode
        !           608:          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
        !           609:          || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
        !           610:          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
        !           611:          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
        !           612:        return 0;
        !           613:     }
        !           614: 
        !           615:   return 1;
        !           616: }
        !           617: 
        !           618: /* Return 1 if OP is a comparison operation that is valid for a branch insn.
        !           619:    We only check the opcode against the mode of the CC value here.  */
        !           620: 
        !           621: int
        !           622: branch_comparison_operator (op, mode)
        !           623:      register rtx op;
        !           624:      enum machine_mode mode;
        !           625: {
        !           626:   enum rtx_code code = GET_CODE (op);
        !           627:   enum machine_mode cc_mode;
        !           628: 
        !           629:   if (GET_RTX_CLASS (code) != '<')
        !           630:     return 0;
        !           631: 
        !           632:   cc_mode = GET_MODE (XEXP (op, 0));
        !           633:   if (GET_MODE_CLASS (cc_mode) != MODE_CC)
        !           634:     return 0;
        !           635: 
        !           636:   if ((code == GT || code == LT || code == GE || code == LE)
        !           637:       && cc_mode == CCUNSmode)
        !           638:     return 0;
        !           639: 
        !           640:   if ((code == GTU || code == LTU || code == GEU || code == LEU)
        !           641:       && (cc_mode != CCUNSmode))
        !           642:     return 0;
        !           643: 
        !           644:   return 1;
        !           645: }
        !           646: 
        !           647: /* Return 1 if OP is a comparison operation that is valid for an scc insn.
        !           648:    We check the opcode against the mode of the CC value and disallow EQ or
        !           649:    NE comparisons for integers.  */
        !           650: 
        !           651: int
        !           652: scc_comparison_operator (op, mode)
        !           653:      register rtx op;
        !           654:      enum machine_mode mode;
        !           655: {
        !           656:   enum rtx_code code = GET_CODE (op);
        !           657:   enum machine_mode cc_mode;
        !           658: 
        !           659:   if (GET_MODE (op) != mode && mode != VOIDmode)
        !           660:     return 0;
        !           661: 
        !           662:   if (GET_RTX_CLASS (code) != '<')
        !           663:     return 0;
        !           664: 
        !           665:   cc_mode = GET_MODE (XEXP (op, 0));
        !           666:   if (GET_MODE_CLASS (cc_mode) != MODE_CC)
        !           667:     return 0;
        !           668: 
        !           669:   if (code == NE && cc_mode != CCFPmode)
        !           670:     return 0;
        !           671: 
        !           672:   if ((code == GT || code == LT || code == GE || code == LE)
        !           673:       && cc_mode == CCUNSmode)
        !           674:     return 0;
        !           675: 
        !           676:   if ((code == GTU || code == LTU || code == GEU || code == LEU)
        !           677:       && (cc_mode != CCUNSmode))
        !           678:     return 0;
        !           679: 
        !           680:   if (cc_mode == CCEQmode && code != EQ && code != NE)
        !           681:     return 0;
        !           682: 
        !           683:   return 1;
        !           684: }
        !           685: 
        !           686: /* Return 1 if ANDOP is a mask that has no bits on that are not in the
        !           687:    mask required to convert the result of a rotate insn into a shift
        !           688:    left insn of SHIFTOP bits.  Both are known to be CONST_INT.  */
        !           689: 
        !           690: int
        !           691: includes_lshift_p (shiftop, andop)
        !           692:      register rtx shiftop;
        !           693:      register rtx andop;
        !           694: {
        !           695:   int shift_mask = (~0 << INTVAL (shiftop));
        !           696: 
        !           697:   return (INTVAL (andop) & ~shift_mask) == 0;
        !           698: }
        !           699: 
        !           700: /* Similar, but for right shift.  */
        !           701: 
        !           702: int
        !           703: includes_rshift_p (shiftop, andop)
        !           704:      register rtx shiftop;
        !           705:      register rtx andop;
        !           706: {
        !           707:   unsigned shift_mask = ~0;
        !           708: 
        !           709:   shift_mask >>= INTVAL (shiftop);
        !           710: 
        !           711:   return (INTVAL (andop) & ~ shift_mask) == 0;
        !           712: }
        !           713: 
        !           714: /* Return the register class of a scratch register needed to copy IN into
        !           715:    or out of a register in CLASS in MODE.  If it can be done directly,
        !           716:    NO_REGS is returned.  */
        !           717: 
        !           718: enum reg_class
        !           719: secondary_reload_class (class, mode, in)
        !           720:      enum reg_class class;
        !           721:      enum machine_mode mode;
        !           722:      rtx in;
        !           723: {
        !           724:   int regno = true_regnum (in);
        !           725: 
        !           726:   if (regno >= FIRST_PSEUDO_REGISTER)
        !           727:     regno = -1;
        !           728: 
        !           729:   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
        !           730:      into anything.  */
        !           731:   if (class == GENERAL_REGS || class == BASE_REGS
        !           732:       || (regno >= 0 && INT_REGNO_P (regno)))
        !           733:     return NO_REGS;
        !           734: 
        !           735:   /* Constants, memory, and FP registers can go into FP registers.  */
        !           736:   if ((regno == -1 || FP_REGNO_P (regno))
        !           737:       && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
        !           738:     return NO_REGS;
        !           739: 
        !           740:   /* We can copy among the CR registers.  */
        !           741:   if ((class == CR_REGS || class == CR0_REGS)
        !           742:       && regno >= 0 && CR_REGNO_P (regno))
        !           743:     return NO_REGS;
        !           744: 
        !           745:   /* Otherwise, we need GENERAL_REGS.  */
        !           746:   return GENERAL_REGS;
        !           747: }
        !           748: 
        !           749: /* Given a comparison operation, return the bit number in CCR to test.  We
        !           750:    know this is a valid comparison.  
        !           751: 
        !           752:    SCC_P is 1 if this is for an scc.  That means that %D will have been
        !           753:    used instead of %C, so the bits will be in different places.
        !           754: 
        !           755:    Return -1 if OP isn't a valid comparison for some reason.  */
        !           756: 
        !           757: int
        !           758: ccr_bit (op, scc_p)
        !           759:      register rtx op;
        !           760:      int scc_p;
        !           761: {
        !           762:   enum rtx_code code = GET_CODE (op);
        !           763:   enum machine_mode cc_mode;
        !           764:   int cc_regnum;
        !           765:   int base_bit;
        !           766: 
        !           767:   if (GET_RTX_CLASS (code) != '<')
        !           768:     return -1;
        !           769: 
        !           770:   cc_mode = GET_MODE (XEXP (op, 0));
        !           771:   cc_regnum = REGNO (XEXP (op, 0));
        !           772:   base_bit = 4 * (cc_regnum - 68);
        !           773: 
        !           774:   /* In CCEQmode cases we have made sure that the result is always in the
        !           775:      third bit of the CR field.  */
        !           776: 
        !           777:   if (cc_mode == CCEQmode)
        !           778:     return base_bit + 3;
        !           779: 
        !           780:   switch (code)
        !           781:     {
        !           782:     case NE:
        !           783:       return scc_p ? base_bit + 3 : base_bit + 2;
        !           784:     case EQ:
        !           785:       return base_bit + 2;
        !           786:     case GT:  case GTU:
        !           787:       return base_bit + 1;
        !           788:     case LT:  case LTU:
        !           789:       return base_bit;
        !           790: 
        !           791:     case GE:  case GEU:
        !           792:       /* If floating-point, we will have done a cror to put the bit in the
        !           793:         unordered position.  So test that bit.  For integer, this is ! LT
        !           794:         unless this is an scc insn.  */
        !           795:       return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit;
        !           796: 
        !           797:     case LE:  case LEU:
        !           798:       return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1;
        !           799: 
        !           800:     default:
        !           801:       abort ();
        !           802:     }
        !           803: }
        !           804: 
        !           805: /* Print an operand.  Recognize special options, documented below.  */
        !           806: 
        !           807: void
        !           808: print_operand (file, x, code)
        !           809:     FILE *file;
        !           810:     rtx x;
        !           811:     char code;
        !           812: {
        !           813:   int i;
        !           814:   int val;
        !           815: 
        !           816:   /* These macros test for integers and extract the low-order bits.  */
        !           817: #define INT_P(X)  \
        !           818: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE)   \
        !           819:  && GET_MODE (X) == VOIDmode)
        !           820: 
        !           821: #define INT_LOWPART(X) \
        !           822:   (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
        !           823: 
        !           824:   switch (code)
        !           825:     {
        !           826:     case '.':
        !           827:       /* Write out an instruction after the call which may be replaced
        !           828:         with glue code by the loader.  This depends on the AIX version.  */
        !           829:       asm_fprintf (file, RS6000_CALL_GLUE);
        !           830:       return;
        !           831: 
        !           832:     case 'A':
        !           833:       /* If X is a constant integer whose low-order 5 bits are zero,
        !           834:         write 'l'.  Otherwise, write 'r'.  This is a kludge to fix a bug
        !           835:         in the AIX assembler where "sri" with a zero shift count
        !           836:         write a trash instruction.  */
        !           837:       if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
        !           838:        putc ('l', file);
        !           839:       else
        !           840:        putc ('r', file);
        !           841:       return;
        !           842: 
        !           843:     case 'b':
        !           844:       /* Low-order 16 bits of constant, unsigned.  */
        !           845:       if (! INT_P (x))
        !           846:        output_operand_lossage ("invalid %%b value");
        !           847: 
        !           848:       fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
        !           849:       return;
        !           850: 
        !           851:     case 'C':
        !           852:       /* This is an optional cror needed for LE or GE floating-point
        !           853:         comparisons.  Otherwise write nothing.  */
        !           854:       if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
        !           855:          && GET_MODE (XEXP (x, 0)) == CCFPmode)
        !           856:        {
        !           857:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !           858: 
        !           859:          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
        !           860:                   base_bit + 2, base_bit + (GET_CODE (x) == GE));
        !           861:        }
        !           862:       return;
        !           863: 
        !           864:     case 'D':
        !           865:       /* Similar, except that this is for an scc, so we must be able to
        !           866:         encode the test in a single bit that is one.  We do the above
        !           867:         for any LE, GE, GEU, or LEU and invert the bit for NE.  */
        !           868:       if (GET_CODE (x) == LE || GET_CODE (x) == GE
        !           869:          || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
        !           870:        {
        !           871:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !           872: 
        !           873:          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
        !           874:                   base_bit + 2,
        !           875:                   base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
        !           876:        }
        !           877: 
        !           878:       else if (GET_CODE (x) == NE)
        !           879:        {
        !           880:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !           881: 
        !           882:          fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
        !           883:                   base_bit + 2, base_bit + 2);
        !           884:        }
        !           885:       return;
        !           886: 
        !           887:     case 'E':
        !           888:       /* X is a CR register.  Print the number of the third bit of the CR */
        !           889:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           890:        output_operand_lossage ("invalid %%E value");
        !           891: 
        !           892:       fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3);
        !           893:       return;
        !           894: 
        !           895:     case 'f':
        !           896:       /* X is a CR register.  Print the shift count needed to move it
        !           897:         to the high-order four bits.  */
        !           898:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           899:        output_operand_lossage ("invalid %%f value");
        !           900:       else
        !           901:        fprintf (file, "%d", 4 * (REGNO (x) - 68));
        !           902:       return;
        !           903: 
        !           904:     case 'F':
        !           905:       /* Similar, but print the count for the rotate in the opposite
        !           906:         direction.  */
        !           907:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           908:        output_operand_lossage ("invalid %%F value");
        !           909:       else
        !           910:        fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
        !           911:       return;
        !           912: 
        !           913:     case 'G':
        !           914:       /* X is a constant integer.  If it is negative, print "m",
        !           915:         otherwise print "z".  This is to make a aze or ame insn.  */
        !           916:       if (GET_CODE (x) != CONST_INT)
        !           917:        output_operand_lossage ("invalid %%G value");
        !           918:       else if (INTVAL (x) >= 0)
        !           919:        putc ('z', file);
        !           920:       else
        !           921:        putc ('m', file);
        !           922:       return;
        !           923:        
        !           924:     case 'h':
        !           925:       /* If constant, output low-order five bits.  Otherwise,
        !           926:         write normally. */
        !           927:       if (INT_P (x))
        !           928:        fprintf (file, "%d", INT_LOWPART (x) & 31);
        !           929:       else
        !           930:        print_operand (file, x, 0);
        !           931:       return;
        !           932: 
        !           933:     case 'H':
        !           934:       /* X must be a constant.  Output the low order 5 bits plus 24.  */
        !           935:       if (! INT_P (x))
        !           936:        output_operand_lossage ("invalid %%H value");
        !           937: 
        !           938:       fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31);
        !           939:       return;
        !           940: 
        !           941:     case 'I':
        !           942:       /* Print `i' if this is a constant, else nothing.  */
        !           943:       if (INT_P (x))
        !           944:        putc ('i', file);
        !           945:       return;
        !           946: 
        !           947:     case 'j':
        !           948:       /* Write the bit number in CCR for jump.  */
        !           949:       i = ccr_bit (x, 0);
        !           950:       if (i == -1)
        !           951:        output_operand_lossage ("invalid %%j code");
        !           952:       else
        !           953:        fprintf (file, "%d", i);
        !           954:       return;
        !           955: 
        !           956:     case 'J':
        !           957:       /* Similar, but add one for shift count in rlinm for scc and pass
        !           958:         scc flag to `ccr_bit'.  */
        !           959:       i = ccr_bit (x, 1);
        !           960:       if (i == -1)
        !           961:        output_operand_lossage ("invalid %%J code");
        !           962:       else
        !           963:        /* If we want bit 31, write a shift count of zero, not 32.  */
        !           964:        fprintf (file, "%d", i == 31 ? 0 : i + 1);
        !           965:       return;
        !           966: 
        !           967:     case 'k':
        !           968:       /* X must be a constant.  Write the 1's complement of the
        !           969:         constant.  */
        !           970:       if (! INT_P (x))
        !           971:        output_operand_lossage ("invalid %%k value");
        !           972: 
        !           973:       fprintf (file, "%d", ~ INT_LOWPART (x));
        !           974:       return;
        !           975: 
        !           976:     case 'L':
        !           977:       /* Write second word of DImode or DFmode reference.  Works on register
        !           978:         or non-indexed memory only.  */
        !           979:       if (GET_CODE (x) == REG)
        !           980:        fprintf (file, "%d", REGNO (x) + 1);
        !           981:       else if (GET_CODE (x) == MEM)
        !           982:        {
        !           983:          /* Handle possible auto-increment.  Since it is pre-increment and
        !           984:             we have already done it, we can just use an offset of four.  */
        !           985:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !           986:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !           987:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
        !           988:          else
        !           989:            output_address (plus_constant (XEXP (x, 0), 4));
        !           990:        }
        !           991:       return;
        !           992:                            
        !           993:     case 'm':
        !           994:       /* MB value for a mask operand.  */
        !           995:       if (! mask_operand (x, VOIDmode))
        !           996:        output_operand_lossage ("invalid %%m value");
        !           997: 
        !           998:       val = INT_LOWPART (x);
        !           999: 
        !          1000:       /* If the high bit is set and the low bit is not, the value is zero.
        !          1001:         If the high bit is zero, the value is the first 1 bit we find from
        !          1002:         the left.  */
        !          1003:       if (val < 0 && (val & 1) == 0)
        !          1004:        {
        !          1005:          fprintf (file, "0");
        !          1006:          return;
        !          1007:        }
        !          1008:       else if (val >= 0)
        !          1009:        {
        !          1010:          for (i = 1; i < 32; i++)
        !          1011:            if ((val <<= 1) < 0)
        !          1012:              break;
        !          1013:          fprintf (file, "%d", i);
        !          1014:          return;
        !          1015:        }
        !          1016:          
        !          1017:       /* Otherwise, look for the first 0 bit from the right.  The result is its
        !          1018:         number plus 1. We know the low-order bit is one.  */
        !          1019:       for (i = 0; i < 32; i++)
        !          1020:        if (((val >>= 1) & 1) == 0)
        !          1021:          break;
        !          1022: 
        !          1023:       /* If we ended in ...01, I would be 0.  The correct value is 31, so
        !          1024:         we want 31 - i.  */
        !          1025:       fprintf (file, "%d", 31 - i);
        !          1026:       return;
        !          1027: 
        !          1028:     case 'M':
        !          1029:       /* ME value for a mask operand.  */
        !          1030:       if (! mask_operand (x, VOIDmode))
        !          1031:        output_operand_lossage ("invalid %%m value");
        !          1032: 
        !          1033:       val = INT_LOWPART (x);
        !          1034: 
        !          1035:       /* If the low bit is set and the high bit is not, the value is 31.
        !          1036:         If the low bit is zero, the value is the first 1 bit we find from
        !          1037:         the right.  */
        !          1038:       if ((val & 1) && val >= 0)
        !          1039:        {
        !          1040:          fputs ("31", file);
        !          1041:          return;
        !          1042:        }
        !          1043:       else if ((val & 1) == 0)
        !          1044:        {
        !          1045:          for (i = 0; i < 32; i++)
        !          1046:            if ((val >>= 1) & 1)
        !          1047:              break;
        !          1048: 
        !          1049:          /* If we had ....10, I would be 0.  The result should be
        !          1050:             30, so we need 30 - i.  */
        !          1051:          fprintf (file, "%d", 30 - i);
        !          1052:          return;
        !          1053:        }
        !          1054:          
        !          1055:       /* Otherwise, look for the first 0 bit from the left.  The result is its
        !          1056:         number minus 1. We know the high-order bit is one.  */
        !          1057:       for (i = 0; i < 32; i++)
        !          1058:        if ((val <<= 1) >= 0)
        !          1059:          break;
        !          1060: 
        !          1061:       fprintf (file, "%d", i);
        !          1062:       return;
        !          1063: 
        !          1064:     case 'N':
        !          1065:       /* Write the number of elements in the vector times 4.  */
        !          1066:       if (GET_CODE (x) != PARALLEL)
        !          1067:        output_operand_lossage ("invalid %%N value");
        !          1068: 
        !          1069:       fprintf (file, "%d", XVECLEN (x, 0) * 4);
        !          1070:       return;
        !          1071: 
        !          1072:     case 'O':
        !          1073:       /* Similar, but subtract 1 first.  */
        !          1074:       if (GET_CODE (x) != PARALLEL)
        !          1075:        output_operand_lossage ("invalid %%N value");
        !          1076: 
        !          1077:       fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
        !          1078:       return;
        !          1079: 
        !          1080:     case 'p':
        !          1081:       /* X is a CONST_INT that is a power of two.  Output the logarithm.  */
        !          1082:       if (! INT_P (x)
        !          1083:          || (i = exact_log2 (INT_LOWPART (x))) < 0)
        !          1084:        output_operand_lossage ("invalid %%p value");
        !          1085: 
        !          1086:       fprintf (file, "%d", i);
        !          1087:       return;
        !          1088: 
        !          1089:     case 'P':
        !          1090:       /* The operand must be an indirect memory reference.  The result
        !          1091:         is the register number. */
        !          1092:       if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
        !          1093:          || REGNO (XEXP (x, 0)) >= 32)
        !          1094:        output_operand_lossage ("invalid %%P value");
        !          1095: 
        !          1096:       fprintf (file, "%d", REGNO (XEXP (x, 0)));
        !          1097:       return;
        !          1098: 
        !          1099:     case 'R':
        !          1100:       /* X is a CR register.  Print the mask for `mtcrf'.  */
        !          1101:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !          1102:        output_operand_lossage ("invalid %%R value");
        !          1103:       else
        !          1104:        fprintf (file, "%d", 128 >> (REGNO (x) - 68));
        !          1105:       return;
        !          1106: 
        !          1107:     case 's':
        !          1108:       /* Low 5 bits of 32 - value */
        !          1109:       if (! INT_P (x))
        !          1110:        output_operand_lossage ("invalid %%s value");
        !          1111: 
        !          1112:       fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);
        !          1113:       return;
        !          1114: 
        !          1115:     case 'S':
        !          1116:       /* Low 5 bits of 31 - value */
        !          1117:       if (! INT_P (x))
        !          1118:        output_operand_lossage ("invalid %%S value");
        !          1119: 
        !          1120:       fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31);
        !          1121:       return;
        !          1122: 
        !          1123:     case 't':
        !          1124:       /* Write 12 if this jump operation will branch if true, 4 otherwise. 
        !          1125:         All floating-point operations except NE branch true and integer
        !          1126:         EQ, LT, GT, LTU and GTU also branch true.  */
        !          1127:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
        !          1128:        output_operand_lossage ("invalid %%t value");
        !          1129: 
        !          1130:       else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
        !          1131:                && GET_CODE (x) != NE)
        !          1132:               || GET_CODE (x) == EQ
        !          1133:               || GET_CODE (x) == LT || GET_CODE (x) == GT
        !          1134:               || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
        !          1135:        fputs ("12", file);
        !          1136:       else
        !          1137:        putc ('4', file);
        !          1138:       return;
        !          1139:       
        !          1140:     case 'T':
        !          1141:       /* Opposite of 't': write 4 if this jump operation will branch if true,
        !          1142:         12 otherwise.   */
        !          1143:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
        !          1144:        output_operand_lossage ("invalid %%t value");
        !          1145: 
        !          1146:       else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
        !          1147:                && GET_CODE (x) != NE)
        !          1148:               || GET_CODE (x) == EQ
        !          1149:               || GET_CODE (x) == LT || GET_CODE (x) == GT
        !          1150:               || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
        !          1151:        putc ('4', file);
        !          1152:       else
        !          1153:        fputs ("12", file);
        !          1154:       return;
        !          1155:       
        !          1156:     case 'u':
        !          1157:       /* High-order 16 bits of constant.  */
        !          1158:       if (! INT_P (x))
        !          1159:        output_operand_lossage ("invalid %%u value");
        !          1160: 
        !          1161:       fprintf (file, "0x%x", (INT_LOWPART (x) >> 16) & 0xffff);
        !          1162:       return;
        !          1163: 
        !          1164:     case 'U':
        !          1165:       /* Print `u' if this has an auto-increment or auto-decrement.  */
        !          1166:       if (GET_CODE (x) == MEM
        !          1167:          && (GET_CODE (XEXP (x, 0)) == PRE_INC
        !          1168:              || GET_CODE (XEXP (x, 0)) == PRE_DEC))
        !          1169:        putc ('u', file);
        !          1170:       return;
        !          1171: 
        !          1172:     case 'w':
        !          1173:       /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
        !          1174:         normally.  */
        !          1175:       if (INT_P (x))
        !          1176:        fprintf (file, "%d",
        !          1177:                 (INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000));
        !          1178:       else
        !          1179:        print_operand (file, x, 0);
        !          1180:       return;
        !          1181: 
        !          1182:     case 'W':
        !          1183:       /* If constant, low-order 16 bits of constant, unsigned.
        !          1184:         Otherwise, write normally.  */
        !          1185:       if (INT_P (x))
        !          1186:        fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
        !          1187:       else
        !          1188:        print_operand (file, x, 0);
        !          1189:       return;
        !          1190: 
        !          1191:     case 'X':
        !          1192:       if (GET_CODE (x) == MEM
        !          1193:          && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
        !          1194:        putc ('x', file);
        !          1195:       return;
        !          1196: 
        !          1197:     case 'Y':
        !          1198:       /* Like 'L', for third word of TImode  */
        !          1199:       if (GET_CODE (x) == REG)
        !          1200:        fprintf (file, "%d", REGNO (x) + 2);
        !          1201:       else if (GET_CODE (x) == MEM)
        !          1202:        {
        !          1203:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !          1204:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !          1205:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
        !          1206:          else
        !          1207:            output_address (plus_constant (XEXP (x, 0), 8));
        !          1208:        }
        !          1209:       return;
        !          1210:                            
        !          1211:     case 'z':
        !          1212:       /* X is a SYMBOL_REF.  Write out the name preceded by a
        !          1213:         period and without any trailing data in brackets.  Used for function
        !          1214:         names.  */
        !          1215:       if (GET_CODE (x) != SYMBOL_REF)
        !          1216:        abort ();
        !          1217: 
        !          1218:       putc ('.', file);
        !          1219:       RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
        !          1220:       return;
        !          1221: 
        !          1222:     case 'Z':
        !          1223:       /* Like 'L', for last word of TImode.  */
        !          1224:       if (GET_CODE (x) == REG)
        !          1225:        fprintf (file, "%d", REGNO (x) + 3);
        !          1226:       else if (GET_CODE (x) == MEM)
        !          1227:        {
        !          1228:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !          1229:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !          1230:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
        !          1231:          else
        !          1232:            output_address (plus_constant (XEXP (x, 0), 12));
        !          1233:        }
        !          1234:       return;
        !          1235:                            
        !          1236:     case 0:
        !          1237:       if (GET_CODE (x) == REG)
        !          1238:        fprintf (file, "%s", reg_names[REGNO (x)]);
        !          1239:       else if (GET_CODE (x) == MEM)
        !          1240:        {
        !          1241:          /* We need to handle PRE_INC and PRE_DEC here, since we need to
        !          1242:             know the width from the mode.  */
        !          1243:          if (GET_CODE (XEXP (x, 0)) == PRE_INC)
        !          1244:            fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)),
        !          1245:                     REGNO (XEXP (XEXP (x, 0), 0)));
        !          1246:          else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !          1247:            fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
        !          1248:                     REGNO (XEXP (XEXP (x, 0), 0)));
        !          1249:          else
        !          1250:            output_address (XEXP (x, 0));
        !          1251:        }
        !          1252:       else
        !          1253:        output_addr_const (file, x);
        !          1254:       return;
        !          1255: 
        !          1256:     default:
        !          1257:       output_operand_lossage ("invalid %%xn code");
        !          1258:     }
        !          1259: }
        !          1260: 
        !          1261: /* Print the address of an operand.  */
        !          1262: 
        !          1263: void
        !          1264: print_operand_address (file, x)
        !          1265:      FILE *file;
        !          1266:      register rtx x;
        !          1267: {
        !          1268:   if (GET_CODE (x) == REG)
        !          1269:     fprintf (file, "0(%d)", REGNO (x));
        !          1270:   else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
        !          1271:     {
        !          1272:       output_addr_const (file, x);
        !          1273:       /* When TARGET_MINIMAL_TOC, use the indirected toc table pointer instead
        !          1274:         of the toc pointer.  */
        !          1275:       if (TARGET_MINIMAL_TOC)
        !          1276:        fprintf (file, "(30)");
        !          1277:       else
        !          1278:        fprintf (file, "(2)");
        !          1279:     }
        !          1280:   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
        !          1281:     {
        !          1282:       if (REGNO (XEXP (x, 0)) == 0)
        !          1283:        fprintf (file, "%d,%d", REGNO (XEXP (x, 1)), REGNO (XEXP (x, 0)));
        !          1284:       else
        !          1285:        fprintf (file, "%d,%d", REGNO (XEXP (x, 0)), REGNO (XEXP (x, 1)));
        !          1286:     }
        !          1287:   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
        !          1288:     fprintf (file, "%d(%d)", INTVAL (XEXP (x, 1)), REGNO (XEXP (x, 0)));
        !          1289:   else
        !          1290:     abort ();
        !          1291: }
        !          1292: 
        !          1293: /* This page contains routines that are used to determine what the function
        !          1294:    prologue and epilogue code will do and write them out.  */
        !          1295: 
        !          1296: /*  Return the first fixed-point register that is required to be saved. 32 if
        !          1297:     none.  */
        !          1298: 
        !          1299: int
        !          1300: first_reg_to_save ()
        !          1301: {
        !          1302:   int first_reg;
        !          1303: 
        !          1304:   /* Find lowest numbered live register.  */
        !          1305:   for (first_reg = 13; first_reg <= 31; first_reg++)
        !          1306:     if (regs_ever_live[first_reg])
        !          1307:       break;
        !          1308: 
        !          1309:   /* If profiling, then we must save/restore every register that contains
        !          1310:      a parameter before/after the .mcount call.  Use registers from 30 down
        !          1311:      to 23 to do this.  Don't use the frame pointer in reg 31.
        !          1312: 
        !          1313:      For now, save enough room for all of the parameter registers.  */
        !          1314:   if (profile_flag)
        !          1315:     if (first_reg > 23)
        !          1316:       first_reg = 23;
        !          1317: 
        !          1318:   return first_reg;
        !          1319: }
        !          1320: 
        !          1321: /* Similar, for FP regs.  */
        !          1322: 
        !          1323: int
        !          1324: first_fp_reg_to_save ()
        !          1325: {
        !          1326:   int first_reg;
        !          1327: 
        !          1328:   /* Find lowest numbered live register.  */
        !          1329:   for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
        !          1330:     if (regs_ever_live[first_reg])
        !          1331:       break;
        !          1332: 
        !          1333:   return first_reg;
        !          1334: }
        !          1335: 
        !          1336: /* Return 1 if we need to save CR.  */
        !          1337: 
        !          1338: int
        !          1339: must_save_cr ()
        !          1340: {
        !          1341:   return regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72];
        !          1342: }
        !          1343: 
        !          1344: /* Compute the size of the save area in the stack, including the space for
        !          1345:    the fixed area.  */
        !          1346: 
        !          1347: int
        !          1348: rs6000_sa_size ()
        !          1349: {
        !          1350:   int size;
        !          1351: 
        !          1352:   /* We have the six fixed words, plus the size of the register save 
        !          1353:      areas, rounded to a double-word.  */
        !          1354:   size = 6 + (32 - first_reg_to_save ()) + (64 - first_fp_reg_to_save ()) * 2;
        !          1355:   if (size & 1)
        !          1356:     size++;
        !          1357: 
        !          1358:   return size * 4;
        !          1359: }
        !          1360: 
        !          1361: /* Return non-zero if this function makes calls.  */
        !          1362: 
        !          1363: int
        !          1364: rs6000_makes_calls ()
        !          1365: {
        !          1366:   rtx insn;
        !          1367: 
        !          1368:   /* If we are profiling, we will be making a call to mcount.  */
        !          1369:   if (profile_flag)
        !          1370:     return 1;
        !          1371: 
        !          1372:   for (insn = get_insns (); insn; insn = next_insn (insn))
        !          1373:     if (GET_CODE (insn) == CALL_INSN)
        !          1374:       return 1;
        !          1375: 
        !          1376:   return 0;
        !          1377: }
        !          1378: 
        !          1379: /* Return non-zero if this function needs to push space on the stack.  */
        !          1380: 
        !          1381: int
        !          1382: rs6000_pushes_stack ()
        !          1383: {
        !          1384:   int total_size = (rs6000_sa_size () + get_frame_size ()
        !          1385:                    + current_function_outgoing_args_size);
        !          1386: 
        !          1387:   /* We need to push the stack if a frame pointer is needed (because the
        !          1388:      stack might be dynamically adjusted), if we are debugging, if the
        !          1389:      total stack size is more than 220 bytes, or if we make calls.  */
        !          1390: 
        !          1391:   return (frame_pointer_needed || write_symbols != NO_DEBUG
        !          1392:          || total_size > 220
        !          1393:          || rs6000_makes_calls ());
        !          1394: }
        !          1395: 
        !          1396: /* Write function prologue.  */
        !          1397: 
        !          1398: void
        !          1399: output_prolog (file, size)
        !          1400:      FILE *file;
        !          1401:      int size;
        !          1402: {
        !          1403:   int first_reg = first_reg_to_save ();
        !          1404:   int must_push = rs6000_pushes_stack ();
        !          1405:   int first_fp_reg = first_fp_reg_to_save ();
        !          1406:   int basic_size = rs6000_sa_size ();
        !          1407:   int total_size = (basic_size + size + current_function_outgoing_args_size);
        !          1408: 
        !          1409:   /* Round size to multiple of 8 bytes.  */
        !          1410:   total_size = (total_size + 7) & ~7;
        !          1411: 
        !          1412:   /* Write .extern for any function we will call to save and restore fp
        !          1413:      values.  */
        !          1414:   if (first_fp_reg < 62)
        !          1415:     fprintf (file, "\t.extern ._savef%d\n\t.extern ._restf%d\n",
        !          1416:             first_fp_reg - 32, first_fp_reg - 32);
        !          1417: 
        !          1418:   /* Write .extern for truncation routines, if needed.  */
        !          1419:   if (rs6000_trunc_used && ! trunc_defined)
        !          1420:     {
        !          1421:       fprintf (file, "\t.extern .itrunc\n\t.extern .uitrunc\n");
        !          1422:       trunc_defined = 1;
        !          1423:     }
        !          1424: 
        !          1425:   /* If we have to call a function to save fpr's, or if we are doing profiling,
        !          1426:      then we will be using LR.  */
        !          1427:   if (first_fp_reg < 62 || profile_flag)
        !          1428:     regs_ever_live[65] = 1;
        !          1429: 
        !          1430:   /* If we use the link register, get it into r0.  */
        !          1431:   if (regs_ever_live[65])
        !          1432:     asm_fprintf (file, "\tmflr 0\n");
        !          1433: 
        !          1434:   /* If we need to save CR, put it into r12.  */
        !          1435:   if (must_save_cr ())
        !          1436:     asm_fprintf (file, "\tmfcr 12\n");
        !          1437: 
        !          1438:   /* Do any required saving of fpr's.  If only one or two to save, do it
        !          1439:      ourself.  Otherwise, call function.  Note that since they are statically
        !          1440:      linked, we do not need a nop following them.  */
        !          1441:   if (first_fp_reg == 62)
        !          1442:     asm_fprintf (file, "\tstfd 30,-16(1)\n\tstfd 31,-8(1)\n");
        !          1443:   else if (first_fp_reg == 63)
        !          1444:     asm_fprintf (file, "\tstfd 31,-8(1)\n");
        !          1445:   else if (first_fp_reg != 64)
        !          1446:     asm_fprintf (file, "\tbl ._savef%d\n", first_fp_reg - 32);
        !          1447: 
        !          1448:   /* Now save gpr's.  */
        !          1449:   if (! TARGET_POWER || first_reg == 31)
        !          1450:     {
        !          1451:       int regno, loc;
        !          1452: 
        !          1453:       for (regno = first_reg,
        !          1454:           loc = - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8;
        !          1455:           regno < 32;
        !          1456:           regno++, loc += 4)
        !          1457:        asm_fprintf (file, "\t{st|stw} %d,%d(1)\n", regno, loc);
        !          1458:     }
        !          1459: 
        !          1460:   else if (first_reg != 32)
        !          1461:     asm_fprintf (file, "\t{stm|stmw} %d,%d(1)\n", first_reg,
        !          1462:             - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
        !          1463: 
        !          1464:   /* Save lr if we used it.  */
        !          1465:   if (regs_ever_live[65])
        !          1466:     asm_fprintf (file, "\t{st|stw} 0,8(1)\n");
        !          1467: 
        !          1468:   /* Save CR if we use any that must be preserved.  */
        !          1469:   if (must_save_cr ())
        !          1470:     asm_fprintf (file, "\t{st|stw} 12,4(1)\n");
        !          1471: 
        !          1472:   /* Update stack and set back pointer.  */
        !          1473:   if (must_push)
        !          1474:     {
        !          1475:       if (total_size < 32767)
        !          1476:        asm_fprintf (file, "\t{stu|stwu} 1,%d(1)\n", - total_size);
        !          1477:       else
        !          1478:        {
        !          1479:          asm_fprintf (file, "\t{cau|addis} 0,0,%d\n\t{oril|ori} 0,0,%d\n",
        !          1480:                   (total_size >> 16) & 0xffff, total_size & 0xffff);
        !          1481:          asm_fprintf (file, "\t{sf|subfc} 12,0,1\n");
        !          1482:          asm_fprintf (file, "\t{st|stw} 1,0(12)\n\t{oril|ori} 1,12,0\n");
        !          1483:        }
        !          1484:     }
        !          1485: 
        !          1486:   /* Set frame pointer, if needed.  */
        !          1487:   if (frame_pointer_needed)
        !          1488:     asm_fprintf (file, "\t{oril|ori} 31,1,0\n");
        !          1489: 
        !          1490:   /* If TARGET_MINIMAL_TOC, and the constant pool is needed, then load the
        !          1491:      TOC_TABLE address into register 30.  */
        !          1492:   if (TARGET_MINIMAL_TOC && get_pool_size () != 0)
        !          1493:     asm_fprintf (file, "\t{l|lwz} 30,LCTOC..0(2)\n");
        !          1494: }
        !          1495: 
        !          1496: /* Write function epilogue.  */
        !          1497: 
        !          1498: void
        !          1499: output_epilog (file, size)
        !          1500:      FILE *file;
        !          1501:      int size;
        !          1502: {
        !          1503:   int first_reg = first_reg_to_save ();
        !          1504:   int must_push = rs6000_pushes_stack ();
        !          1505:   int first_fp_reg = first_fp_reg_to_save ();
        !          1506:   int basic_size = rs6000_sa_size ();
        !          1507:   int total_size = (basic_size + size + current_function_outgoing_args_size);
        !          1508:   rtx insn = get_last_insn ();
        !          1509: 
        !          1510:   /* Round size to multiple of 8 bytes.  */
        !          1511:   total_size = (total_size + 7) & ~7;
        !          1512: 
        !          1513:   /* If the last insn was a BARRIER, we don't have to write anything except
        !          1514:      the trace table.  */
        !          1515:   if (GET_CODE (insn) == NOTE)
        !          1516:     insn = prev_nonnote_insn (insn);
        !          1517:   if (insn == 0 ||  GET_CODE (insn) != BARRIER)
        !          1518:     {
        !          1519:       /* If we have a frame pointer, a call to alloca,  or a large stack
        !          1520:         frame, restore the old stack pointer using the backchain.  Otherwise,
        !          1521:         we know what size to update it with.  */
        !          1522:       if (frame_pointer_needed || current_function_calls_alloca
        !          1523:          || total_size > 32767)
        !          1524:        asm_fprintf (file, "\t{l|lwz} 1,0(1)\n");
        !          1525:       else if (must_push)
        !          1526:        asm_fprintf (file, "\t{ai|addic} 1,1,%d\n", total_size);
        !          1527: 
        !          1528:       /* Get the old lr if we saved it.  */
        !          1529:       if (regs_ever_live[65])
        !          1530:        asm_fprintf (file, "\t{l|lwz} 0,8(1)\n");
        !          1531: 
        !          1532:       /* Get the old cr if we saved it.  */
        !          1533:       if (must_save_cr ())
        !          1534:        asm_fprintf (file, "\t{l|lwz} 12,4(1)\n");
        !          1535: 
        !          1536:       /* Set LR here to try to overlap restores below.  */
        !          1537:       if (regs_ever_live[65])
        !          1538:        asm_fprintf (file, "\tmtlr 0\n");
        !          1539: 
        !          1540:       /* Restore gpr's.  */
        !          1541:       if (! TARGET_POWER || first_reg == 31)
        !          1542:        {
        !          1543:          int regno, loc;
        !          1544: 
        !          1545:          for (regno = first_reg,
        !          1546:               loc = - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8;
        !          1547:               regno < 32;
        !          1548:               regno++, loc += 4)
        !          1549:            asm_fprintf (file, "\t{l|lwz} %d,%d(1)\n", regno, loc);
        !          1550:        }
        !          1551: 
        !          1552:       else if (first_reg != 32)
        !          1553:        asm_fprintf (file, "\t{lm|lmw} %d,%d(1)\n", first_reg,
        !          1554:             - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
        !          1555: 
        !          1556:       /* Restore fpr's if we can do it without calling a function.  */
        !          1557:       if (first_fp_reg == 62)
        !          1558:        asm_fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n");
        !          1559:       else if (first_fp_reg == 63)
        !          1560:        asm_fprintf (file, "\tlfd 31,-8(1)\n");
        !          1561: 
        !          1562:       /* If we saved cr, restore it here.  Just those of cr2, cr3, and cr4
        !          1563:         that were used.  */
        !          1564:       if (must_save_cr ())
        !          1565:        asm_fprintf (file, "\tmtcrf %d,12\n",
        !          1566:                     (regs_ever_live[70] != 0) * 0x20
        !          1567:                     + (regs_ever_live[71] != 0) * 0x10
        !          1568:                     + (regs_ever_live[72] != 0) * 0x8);
        !          1569: 
        !          1570:       /* If we have to restore more than two FP registers, branch to the
        !          1571:         restore function.  It will return to our caller.  */
        !          1572:       if (first_fp_reg < 62)
        !          1573:        asm_fprintf (file, "\tb ._restf%d\n", first_fp_reg - 32);
        !          1574:       else
        !          1575:        asm_fprintf (file, "\t{br|blr}\n");
        !          1576:     }
        !          1577: 
        !          1578:   /* Output a traceback table here.  See /usr/include/sys/debug.h for info
        !          1579:      on its format.  */
        !          1580:   {
        !          1581:     char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
        !          1582:     int fixed_parms, float_parms, parm_info;
        !          1583:     int i;
        !          1584: 
        !          1585:     /* Need label immediately before tbtab, so we can compute its offset
        !          1586:        from the function start.  */
        !          1587:     if (*fname == '*')
        !          1588:       ++fname;
        !          1589:     fprintf (file, "LT..");
        !          1590:     ASM_OUTPUT_LABEL (file, fname);
        !          1591: 
        !          1592:     /* The .tbtab pseudo-op can only be used for the first eight
        !          1593:        expressions, since it can't handle the possibly variable length
        !          1594:        fields that follow.  However, if you omit the optional fields,
        !          1595:        the assembler outputs zeros for all optional fields anyways, giving each
        !          1596:        variable length field is minimum length (as defined in sys/debug.h).
        !          1597:        Thus we can not use the .tbtab pseudo-op at all.  */
        !          1598: 
        !          1599:     /* An all-zero word flags the start of the tbtab, for debuggers that have
        !          1600:        to find it by searching forward from the entry point or from the
        !          1601:        current pc.  */
        !          1602:     fprintf (file, "\t.long 0\n");
        !          1603: 
        !          1604:     /* Tbtab format type.  Use format type 0.  */
        !          1605:     fprintf (file, "\t.byte 0,");
        !          1606: 
        !          1607:     /* Language type.  Unfortunately, there doesn't seem to be any official way
        !          1608:        to get this info, so we use language_string.  C is 0.  C++ is 9.
        !          1609:        No number defined for Obj-C, so use the value for C for now.  */
        !          1610:     if (! strcmp (language_string, "GNU C")
        !          1611:        || ! strcmp (language_string, "GNU Obj-C"))
        !          1612:       i = 0;
        !          1613:     else if (! strcmp (language_string, "GNU F77"))
        !          1614:       i = 1;
        !          1615:     else if (! strcmp (language_string, "GNU Ada"))
        !          1616:       i = 3;
        !          1617:     else if (! strcmp (language_string, "GNU PASCAL"))
        !          1618:       i = 2;
        !          1619:     else if (! strcmp (language_string, "GNU C++"))
        !          1620:       i = 9;
        !          1621:     else
        !          1622:       abort ();
        !          1623:     fprintf (file, "%d,", i);
        !          1624: 
        !          1625:     /* 8 single bit fields: global linkage (not set for C extern linkage,
        !          1626:        apparently a PL/I convention?), out-of-line epilogue/prologue, offset
        !          1627:        from start of procedure stored in tbtab, internal function, function
        !          1628:        has controlled storage, function has no toc, function uses fp,
        !          1629:        function logs/aborts fp operations.  */
        !          1630:     /* Assume that fp operations are used if any fp reg must be saved.  */
        !          1631:     fprintf (file, "%d,", (1 << 5) | ((first_fp_reg != 64) << 1));
        !          1632: 
        !          1633:     /* 6 bitfields: function is interrupt handler, name present in proc table,
        !          1634:        function calls alloca, on condition directives (controls stack walks,
        !          1635:        3 bits), saves condition reg, saves link reg.  */
        !          1636:     /* The `function calls alloca' bit seems to be set whenever reg 31 is
        !          1637:        set up as a frame pointer, even when there is no alloca call.  */
        !          1638:     fprintf (file, "%d,",
        !          1639:             ((1 << 6) | (frame_pointer_needed << 5)
        !          1640:              | (must_save_cr () << 1) | (regs_ever_live[65])));
        !          1641: 
        !          1642:     /* 3 bitfields: saves backchain, spare bit, number of fpr saved
        !          1643:        (6 bits).  */
        !          1644:     fprintf (file, "%d,",
        !          1645:             (must_push << 7) | (64 - first_fp_reg_to_save ()));
        !          1646: 
        !          1647:     /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits).  */
        !          1648:     fprintf (file, "%d,", (32 - first_reg_to_save ()));
        !          1649: 
        !          1650:     {
        !          1651:       /* Compute the parameter info from the function decl argument list.  */
        !          1652:       tree decl;
        !          1653:       int next_parm_info_bit;
        !          1654: 
        !          1655:       next_parm_info_bit = 31;
        !          1656:       parm_info = 0;
        !          1657:       fixed_parms = 0;
        !          1658:       float_parms = 0;
        !          1659: 
        !          1660:       for (decl = DECL_ARGUMENTS (current_function_decl);
        !          1661:           decl; decl = TREE_CHAIN (decl))
        !          1662:        {
        !          1663:          rtx parameter = DECL_INCOMING_RTL (decl);
        !          1664:          enum machine_mode mode = GET_MODE (parameter);
        !          1665: 
        !          1666:          if (GET_CODE (parameter) == REG)
        !          1667:            {
        !          1668:              if (GET_MODE_CLASS (mode) == MODE_FLOAT)
        !          1669:                {
        !          1670:                  int bits;
        !          1671: 
        !          1672:                  float_parms++;
        !          1673: 
        !          1674:                  if (mode == SFmode)
        !          1675:                    bits = 0x2;
        !          1676:                  else if (mode == DFmode)
        !          1677:                    bits = 0x3;
        !          1678:                  else
        !          1679:                    abort ();
        !          1680: 
        !          1681:                  /* If only one bit will fit, don't or in this entry.  */
        !          1682:                  if (next_parm_info_bit > 0)
        !          1683:                    parm_info |= (bits << (next_parm_info_bit - 1));
        !          1684:                  next_parm_info_bit -= 2;
        !          1685:                }
        !          1686:              else
        !          1687:                {
        !          1688:                  fixed_parms += ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1))
        !          1689:                                  / UNITS_PER_WORD);
        !          1690:                  next_parm_info_bit -= 1;
        !          1691:                }
        !          1692:            }
        !          1693:        }
        !          1694:     }
        !          1695: 
        !          1696:     /* Number of fixed point parameters.  */
        !          1697:     /* This is actually the number of words of fixed point parameters; thus
        !          1698:        an 8 byte struct counts as 2; and thus the maximum value is 8.  */
        !          1699:     fprintf (file, "%d,", fixed_parms);
        !          1700: 
        !          1701:     /* 2 bitfields: number of floating point parameters (7 bits), parameters
        !          1702:        all on stack.  */
        !          1703:     /* This is actually the number of fp registers that hold parameters;
        !          1704:        and thus the maximum value is 13.  */
        !          1705:     /* Set parameters on stack bit if parameters are not in their original
        !          1706:        registers, regardless of whether they are on the stack?  Xlc
        !          1707:        seems to set the bit when not optimizing.  */
        !          1708:     fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
        !          1709: 
        !          1710:     /* Optional fields follow.  Some are variable length.  */
        !          1711: 
        !          1712:     /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
        !          1713:        11 double float.  */
        !          1714:     /* There is an entry for each parameter in a register, in the order that
        !          1715:        they occur in the parameter list.  Any intervening arguments on the
        !          1716:        stack are ignored.  If the list overflows a long (max possible length
        !          1717:        34 bits) then completely leave off all elements that don't fit.  */
        !          1718:     /* Only emit this long if there was at least one parameter.  */
        !          1719:     if (fixed_parms || float_parms)
        !          1720:       fprintf (file, "\t.long %d\n", parm_info);
        !          1721: 
        !          1722:     /* Offset from start of code to tb table.  */
        !          1723:     fprintf (file, "\t.long LT..");
        !          1724:     RS6000_OUTPUT_BASENAME (file, fname);
        !          1725:     fprintf (file, "-.");
        !          1726:     RS6000_OUTPUT_BASENAME (file, fname);
        !          1727:     fprintf (file, "\n");
        !          1728: 
        !          1729:     /* Interrupt handler mask.  */
        !          1730:     /* Omit this long, since we never set the interrupt handler bit above.  */
        !          1731: 
        !          1732:     /* Number of CTL (controlled storage) anchors.  */
        !          1733:     /* Omit this long, since the has_ctl bit is never set above.  */
        !          1734: 
        !          1735:     /* Displacement into stack of each CTL anchor.  */
        !          1736:     /* Omit this list of longs, because there are no CTL anchors.  */
        !          1737: 
        !          1738:     /* Length of function name.  */
        !          1739:     fprintf (file, "\t.short %d\n", strlen (fname));
        !          1740: 
        !          1741:     /* Function name.  */
        !          1742:     assemble_string (fname, strlen (fname));
        !          1743: 
        !          1744:     /* Register for alloca automatic storage; this is always reg 31.
        !          1745:        Only emit this if the alloca bit was set above.  */
        !          1746:     if (frame_pointer_needed)
        !          1747:       fprintf (file, "\t.byte 31\n");
        !          1748:   }
        !          1749: }
        !          1750: 
        !          1751: /* Output a TOC entry.  We derive the entry name from what is
        !          1752:    being written.  */
        !          1753: 
        !          1754: void
        !          1755: output_toc (file, x, labelno)
        !          1756:      FILE *file;
        !          1757:      rtx x;
        !          1758:      int labelno;
        !          1759: {
        !          1760:   char buf[256];
        !          1761:   char *name = buf;
        !          1762:   rtx base = x;
        !          1763:   int offset = 0;
        !          1764: 
        !          1765:   ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
        !          1766: 
        !          1767:   /* Handle FP constants specially.  Note that if we have a minimal
        !          1768:      TOC, things we put here aren't actually in the TOC, so we can allow
        !          1769:      FP constants.  */
        !          1770:   if (GET_CODE (x) == CONST_DOUBLE
        !          1771:       && GET_MODE (x) == DFmode
        !          1772:       && TARGET_FLOAT_FORMAT == HOST_FLOAT_FORMAT
        !          1773:       && BITS_PER_WORD == HOST_BITS_PER_INT
        !          1774:       && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC))
        !          1775:     {
        !          1776:       if (TARGET_MINIMAL_TOC)
        !          1777:        fprintf (file, "\t.long %d\n\t.long %d\n",
        !          1778:                 CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
        !          1779:       else
        !          1780:        fprintf (file, "\t.tc FD_%x_%x[TC],%d,%d\n",
        !          1781:                 CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
        !          1782:                 CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
        !          1783:       return;
        !          1784:     }
        !          1785:   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode
        !          1786:           && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC))
        !          1787:     {
        !          1788:       rtx val = operand_subword (x, 0, 0, SFmode);
        !          1789: 
        !          1790:       if (val == 0 || GET_CODE (val) != CONST_INT)
        !          1791:        abort ();
        !          1792: 
        !          1793:       if (TARGET_MINIMAL_TOC)
        !          1794:        fprintf (file, "\t.long %d\n", INTVAL (val));
        !          1795:       else
        !          1796:        fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val));
        !          1797:       return;
        !          1798:     }
        !          1799: 
        !          1800:   if (GET_CODE (x) == CONST)
        !          1801:     {
        !          1802:       base = XEXP (XEXP (x, 0), 0);
        !          1803:       offset = INTVAL (XEXP (XEXP (x, 0), 1));
        !          1804:     }
        !          1805:   
        !          1806:   if (GET_CODE (base) == SYMBOL_REF)
        !          1807:     name = XSTR (base, 0);
        !          1808:   else if (GET_CODE (base) == LABEL_REF)
        !          1809:     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
        !          1810:   else if (GET_CODE (base) == CODE_LABEL)
        !          1811:     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
        !          1812:   else
        !          1813:     abort ();
        !          1814: 
        !          1815:   if (TARGET_MINIMAL_TOC)
        !          1816:     fprintf (file, "\t.long ");
        !          1817:   else
        !          1818:     {
        !          1819:       fprintf (file, "\t.tc ");
        !          1820:       RS6000_OUTPUT_BASENAME (file, name);
        !          1821: 
        !          1822:       if (offset < 0)
        !          1823:        fprintf (file, ".N%d", - offset);
        !          1824:       else if (offset)
        !          1825:        fprintf (file, ".P%d", offset);
        !          1826: 
        !          1827:       fprintf (file, "[TC],");
        !          1828:     }
        !          1829:   output_addr_const (file, x);
        !          1830:   fprintf (file, "\n");
        !          1831: }
        !          1832: 
        !          1833: /* Output an assembler pseudo-op to write an ASCII string of N characters
        !          1834:    starting at P to FILE.
        !          1835: 
        !          1836:    On the RS/6000, we have to do this using the .byte operation and
        !          1837:    write out special characters outside the quoted string.
        !          1838:    Also, the assembler is broken; very long strings are truncated,
        !          1839:    so we must artificially break them up early. */
        !          1840: 
        !          1841: void
        !          1842: output_ascii (file, p, n)
        !          1843:      FILE *file;
        !          1844:      char *p;
        !          1845:      int n;
        !          1846: {
        !          1847:   char c;
        !          1848:   int i, count_string;
        !          1849:   char *for_string = "\t.byte \"";
        !          1850:   char *for_decimal = "\t.byte ";
        !          1851:   char *to_close = NULL;
        !          1852: 
        !          1853:   count_string = 0;
        !          1854:   for (i = 0; i < n; i++)
        !          1855:     {
        !          1856:       c = *p++;
        !          1857:       if (c >= ' ' && c < 0177)
        !          1858:        {
        !          1859:          if (for_string)
        !          1860:            fputs (for_string, file);
        !          1861:          putc (c, file);
        !          1862: 
        !          1863:          /* Write two quotes to get one.  */
        !          1864:          if (c == '"')
        !          1865:            {
        !          1866:              putc (c, file);
        !          1867:              ++count_string;
        !          1868:            }
        !          1869: 
        !          1870:          for_string = NULL;
        !          1871:          for_decimal = "\"\n\t.byte ";
        !          1872:          to_close = "\"\n";
        !          1873:          ++count_string;
        !          1874: 
        !          1875:          if (count_string >= 512)
        !          1876:            {
        !          1877:              fputs (to_close, file);
        !          1878: 
        !          1879:              for_string = "\t.byte \"";
        !          1880:              for_decimal = "\t.byte ";
        !          1881:              to_close = NULL;
        !          1882:              count_string = 0;
        !          1883:            }
        !          1884:        }
        !          1885:       else
        !          1886:        {
        !          1887:          if (for_decimal)
        !          1888:            fputs (for_decimal, file);
        !          1889:          fprintf (file, "%d", c);
        !          1890: 
        !          1891:          for_string = "\n\t.byte \"";
        !          1892:          for_decimal = ", ";
        !          1893:          to_close = "\n";
        !          1894:          count_string = 0;
        !          1895:        }
        !          1896:     }
        !          1897: 
        !          1898:   /* Now close the string if we have written one.  Then end the line.  */
        !          1899:   if (to_close)
        !          1900:     fprintf (file, to_close);
        !          1901: }
        !          1902: 
        !          1903: /* Generate a unique section name for FILENAME for a section type
        !          1904:    represented by SECTION_DESC.  Output goes into BUF.
        !          1905: 
        !          1906:    SECTION_DESC can be any string, as long as it is different for each
        !          1907:    possible section type.
        !          1908: 
        !          1909:    We name the section in the same manner as xlc.  The name begins with an
        !          1910:    underscore followed by the filename (after stripping any leading directory
        !          1911:    names) with the last period replaced by the string SECTION_DESC.  If
        !          1912:    FILENAME does not contain a period, SECTION_DESC is appended to the end of
        !          1913:    the name.  */
        !          1914: 
        !          1915: void
        !          1916: rs6000_gen_section_name (buf, filename, section_desc)
        !          1917:      char **buf;
        !          1918:      char *filename;
        !          1919:      char *section_desc;
        !          1920: {
        !          1921:   char *q, *after_last_slash, *last_period;
        !          1922:   char *p;
        !          1923:   int len;
        !          1924: 
        !          1925:   after_last_slash = filename;
        !          1926:   for (q = filename; *q; q++)
        !          1927:     {
        !          1928:       if (*q == '/')
        !          1929:        after_last_slash = q + 1;
        !          1930:       else if (*q == '.')
        !          1931:        last_period = q;
        !          1932:     }
        !          1933: 
        !          1934:   len = strlen (after_last_slash) + strlen (section_desc) + 2;
        !          1935:   *buf = (char *) permalloc (len);
        !          1936: 
        !          1937:   p = *buf;
        !          1938:   *p++ = '_';
        !          1939: 
        !          1940:   for (q = after_last_slash; *q; q++)
        !          1941:     {
        !          1942:       if (q == last_period)
        !          1943:         {
        !          1944:          strcpy (p, section_desc);
        !          1945:          p += strlen (section_desc);
        !          1946:         }
        !          1947: 
        !          1948:       else if (isalnum (*q))
        !          1949:         *p++ = *q;
        !          1950:     }
        !          1951: 
        !          1952:   if (last_period == 0)
        !          1953:     strcpy (p, section_desc);
        !          1954:   else
        !          1955:     *p = '\0';
        !          1956: }
        !          1957: 
        !          1958: /* Write function profiler code. */
        !          1959: 
        !          1960: void
        !          1961: output_function_profiler (file, labelno)
        !          1962:   FILE *file;
        !          1963:   int labelno;
        !          1964: {
        !          1965:   /* The last used parameter register.  */
        !          1966:   int last_parm_reg;
        !          1967:   int i, j;
        !          1968: 
        !          1969:   /* Set up a TOC entry for the profiler label.  */
        !          1970:   toc_section ();
        !          1971:   if (TARGET_MINIMAL_TOC)
        !          1972:     fprintf (file, "LPC..%d:\n\t.long LP..%d\n", labelno, labelno);
        !          1973:   else
        !          1974:     fprintf (file, "LPC..%d:\n\t.tc\tLP..%d[TC],LP..%d\n",
        !          1975:             labelno, labelno, labelno);
        !          1976:   text_section ();
        !          1977: 
        !          1978:   /* Figure out last used parameter register.  The proper thing to do is
        !          1979:      to walk incoming args of the function.  A function might have live
        !          1980:      parameter registers even if it has no incoming args.  */
        !          1981: 
        !          1982:   for (last_parm_reg = 10;
        !          1983:        last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
        !          1984:        last_parm_reg--)
        !          1985:     ;
        !          1986: 
        !          1987:   /* Save parameter registers in regs 23-30.  Don't overwrite reg 31, since
        !          1988:      it might be set up as the frame pointer.  */
        !          1989: 
        !          1990:   for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
        !          1991:     fprintf (file, "\tai %d,%d,0\n", j, i);
        !          1992: 
        !          1993:   /* Load location address into r3, and call mcount.  */
        !          1994: 
        !          1995:   fprintf (file, "\tl 3,LPC..%d(2)\n\tbl .mcount\n", labelno);
        !          1996: 
        !          1997:   /* Restore parameter registers.  */
        !          1998: 
        !          1999:   for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
        !          2000:     fprintf (file, "\tai %d,%d,0\n", i, j);
        !          2001: }

unix.superglobalmegacorp.com

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