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

1.1     ! root        1: /* Subroutines used for code generation on IBM RS/6000.
        !             2:    Copyright (C) 1991 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: 
        !            37: #define min(A,B)       ((A) < (B) ? (A) : (B))
        !            38: #define max(A,B)       ((A) > (B) ? (A) : (B))
        !            39: 
        !            40: /* Names of bss and data sections.  These should be unique names for each
        !            41:    compilation unit.  */
        !            42: 
        !            43: char *rs6000_bss_section_name;
        !            44: char *rs6000_private_data_section_name;
        !            45: char *rs6000_read_only_section_name;
        !            46: 
        !            47: /* Set to non-zero by "fix" operation to indicate that itrunc and
        !            48:    uitrunc must be defined.  */
        !            49: 
        !            50: int rs6000_trunc_used;
        !            51: 
        !            52: /* Set to non-zero once they have been defined.  */
        !            53: 
        !            54: static int trunc_defined;
        !            55: 
        !            56: /* Save information from a "cmpxx" operation until the branch or scc is
        !            57:    emitted.  */
        !            58: 
        !            59: rtx rs6000_compare_op0, rs6000_compare_op1;
        !            60: int rs6000_compare_fp_p;
        !            61: 
        !            62: /* Return non-zero if this function is known to have a null epilogue.  */
        !            63: 
        !            64: int
        !            65: direct_return ()
        !            66: {
        !            67:   return (reload_completed
        !            68:          && first_reg_to_save () == 32
        !            69:          && first_fp_reg_to_save () == 64
        !            70:          && ! regs_ever_live[65]
        !            71:          && ! rs6000_pushes_stack ());
        !            72: }
        !            73: 
        !            74: /* Returns 1 always.  */
        !            75: 
        !            76: int
        !            77: any_operand (op, mode)
        !            78:      register rtx op;
        !            79:      enum machine_mode mode;
        !            80: {
        !            81:   return 1;
        !            82: }
        !            83: 
        !            84: /* Return 1 if OP is a constant that can fit in a D field.  */
        !            85: 
        !            86: int
        !            87: short_cint_operand (op, mode)
        !            88:      register rtx op;
        !            89:      enum machine_mode mode;
        !            90: {
        !            91:   return (GET_CODE (op) == CONST_INT
        !            92:          && (unsigned) (INTVAL (op) + 0x8000) < 0x10000);
        !            93: }
        !            94: 
        !            95: /* Similar for a unsigned D field.  */
        !            96: 
        !            97: int
        !            98: u_short_cint_operand (op, mode)
        !            99:      register rtx op;
        !           100:      enum machine_mode mode;
        !           101: {
        !           102:   return (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0);
        !           103: }
        !           104: 
        !           105: /* Returns 1 if OP is a register that is not special (i.e., not MQ,
        !           106:    ctr, or lr).  */
        !           107: 
        !           108: int
        !           109: gen_reg_operand (op, mode)
        !           110:      register rtx op;
        !           111:      enum machine_mode mode;
        !           112: {
        !           113:   return (register_operand (op, mode)
        !           114:          && (GET_CODE (op) != REG || REGNO (op) >= 67 || REGNO (op) < 64));
        !           115: }
        !           116: 
        !           117: /* Returns 1 if OP is either a pseudo-register or a register denoting a
        !           118:    CR field.  */
        !           119: 
        !           120: int
        !           121: cc_reg_operand (op, mode)
        !           122:      register rtx op;
        !           123:      enum machine_mode mode;
        !           124: {
        !           125:   return (register_operand (op, mode)
        !           126:          && (GET_CODE (op) != REG
        !           127:              || REGNO (op) >= FIRST_PSEUDO_REGISTER
        !           128:              || CR_REGNO_P (REGNO (op))));
        !           129: }
        !           130: 
        !           131: /* Returns 1 if OP is either a constant integer valid for a D-field or a
        !           132:    non-special register.  If a register, it must be in the proper mode unless
        !           133:    MODE is VOIDmode.  */
        !           134: 
        !           135: int
        !           136: reg_or_short_operand (op, mode)
        !           137:       register rtx op;
        !           138:       enum machine_mode mode;
        !           139: {
        !           140:   if (GET_CODE (op) == CONST_INT)
        !           141:     return short_cint_operand (op, mode);
        !           142: 
        !           143:   return gen_reg_operand (op, mode);
        !           144: }
        !           145: 
        !           146: /* Similar, except check if the negation of the constant would be valid for
        !           147:    a D-field.  */
        !           148: 
        !           149: int
        !           150: reg_or_neg_short_operand (op, mode)
        !           151:       register rtx op;
        !           152:       enum machine_mode mode;
        !           153: {
        !           154:   if (GET_CODE (op) == CONST_INT)
        !           155:     return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
        !           156: 
        !           157:   return gen_reg_operand (op, mode);
        !           158: }
        !           159: 
        !           160: /* Return 1 if the operand is either a register or an integer whose high-order
        !           161:    16 bits are zero.  */
        !           162: 
        !           163: int
        !           164: reg_or_u_short_operand (op, mode)
        !           165:      register rtx op;
        !           166:      enum machine_mode mode;
        !           167: {
        !           168:   if (GET_CODE (op) == CONST_INT
        !           169:       && (INTVAL (op) & 0xffff0000) == 0)
        !           170:     return 1;
        !           171: 
        !           172:   return gen_reg_operand (op, mode);
        !           173: }
        !           174: 
        !           175: /* Return 1 is the operand is either a non-special register or ANY
        !           176:    constant integer.  */
        !           177: 
        !           178: int
        !           179: reg_or_cint_operand (op, mode)
        !           180:     register rtx op;
        !           181:     enum machine_mode mode;
        !           182: {
        !           183:      return GET_CODE (op) == CONST_INT || gen_reg_operand (op, mode);
        !           184: }
        !           185: 
        !           186: /* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
        !           187:    register with one instruction per word.  For SFmode, this means  that
        !           188:    the low 16-bits are zero.  For DFmode, it means the low 16-bits of
        !           189:    the first word are zero and the high 16 bits of the second word
        !           190:    are zero (usually all bits in the low-order word will be zero).
        !           191: 
        !           192:    We only do this if we can safely read CONST_DOUBLE_{LOW,HIGH}.  */
        !           193: 
        !           194: int
        !           195: easy_fp_constant (op, mode)
        !           196:      register rtx op;
        !           197:      register enum machine_mode mode;
        !           198: {
        !           199:   rtx low, high;
        !           200: 
        !           201:   if (GET_CODE (op) != CONST_DOUBLE
        !           202:       || GET_MODE (op) != mode
        !           203:       || GET_MODE_CLASS (mode) != MODE_FLOAT)
        !           204:     return 0;
        !           205: 
        !           206:   high = operand_subword (op, 0, 0, mode);
        !           207:   low = operand_subword (op, 1, 0, mode);
        !           208: 
        !           209:   if (high == 0 || GET_CODE (high) != CONST_INT || (INTVAL (high) & 0xffff))
        !           210:     return 0;
        !           211: 
        !           212:   return (mode == SFmode
        !           213:          || (low != 0 && GET_CODE (low) == CONST_INT
        !           214:              && (INTVAL (low) & 0xffff0000) == 0));
        !           215: }
        !           216:       
        !           217: /* Return 1 if the operand is either a floating-point register, a pseudo
        !           218:    register, or memory.  */
        !           219: 
        !           220: int
        !           221: fp_reg_or_mem_operand (op, mode)
        !           222:      register rtx op;
        !           223:      enum machine_mode mode;
        !           224: {
        !           225:   return (memory_operand (op, mode)
        !           226:          || (register_operand (op, mode)
        !           227:              && (GET_CODE (op) != REG
        !           228:                  || REGNO (op) >= FIRST_PSEUDO_REGISTER
        !           229:                  || FP_REGNO_P (REGNO (op)))));
        !           230: }
        !           231: 
        !           232: /* Return 1 if the operand is either an easy FP constant (see above) or
        !           233:    memory.  */
        !           234: 
        !           235: int
        !           236: mem_or_easy_const_operand (op, mode)
        !           237:      register rtx op;
        !           238:      enum machine_mode mode;
        !           239: {
        !           240:   return memory_operand (op, mode) || easy_fp_constant (op, mode);
        !           241: }
        !           242: 
        !           243: /* Return 1 if the operand is either a non-special register or an item
        !           244:    that can be used as the operand of an SI add insn.  */
        !           245: 
        !           246: int
        !           247: add_operand (op, mode)
        !           248:     register rtx op;
        !           249:     enum machine_mode mode;
        !           250: {
        !           251:   return (reg_or_short_operand (op, mode)
        !           252:          || (GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff) == 0));
        !           253: }
        !           254: 
        !           255: /* Return 1 if the operand is a non-special register or a constant that
        !           256:    can be used as the operand of an OR or XOR insn on the RS/6000.  */
        !           257: 
        !           258: int
        !           259: logical_operand (op, mode)
        !           260:      register rtx op;
        !           261:      enum machine_mode mode;
        !           262: {
        !           263:   return (gen_reg_operand (op, mode)
        !           264:          || (GET_CODE (op) == CONST_INT
        !           265:              && ((INTVAL (op) & 0xffff0000) == 0
        !           266:                  || (INTVAL (op) & 0xffff) == 0)));
        !           267: }
        !           268: 
        !           269: /* Return 1 if C is a constant that can be encoded in a mask on the
        !           270:    RS/6000.  It is if there are no more than two 1->0 or 0->1 transitions.
        !           271:    Reject all ones and all zeros, since these should have been optimized
        !           272:    away and confuse the making of MB and ME.  */
        !           273: 
        !           274: int
        !           275: mask_constant (c)
        !           276:      register int c;
        !           277: {
        !           278:   int i;
        !           279:   int last_bit_value;
        !           280:   int transitions = 0;
        !           281: 
        !           282:   if (c == 0 || c == ~0)
        !           283:     return 0;
        !           284: 
        !           285:   last_bit_value = c & 1;
        !           286: 
        !           287:   for (i = 1; i < 32; i++)
        !           288:     if (((c >>= 1) & 1) != last_bit_value)
        !           289:       last_bit_value ^= 1, transitions++;
        !           290: 
        !           291:   return transitions <= 2;
        !           292: }
        !           293: 
        !           294: /* Return 1 if the operand is a constant that is a mask on the RS/6000. */
        !           295: 
        !           296: int
        !           297: mask_operand (op, mode)
        !           298:      register rtx op;
        !           299:      enum machine_mode mode;
        !           300: {
        !           301:   return GET_CODE (op) == CONST_INT && mask_constant (INTVAL (op));
        !           302: }
        !           303: 
        !           304: /* Return 1 if the operand is either a non-special register or a
        !           305:    constant that can be used as the operand of an RS/6000 logical AND insn.  */
        !           306: 
        !           307: int
        !           308: and_operand (op, mode)
        !           309:     register rtx op;
        !           310:     enum machine_mode mode;
        !           311: {
        !           312:   return (reg_or_short_operand (op, mode)
        !           313:          || logical_operand (op, mode)
        !           314:          || mask_operand (op, mode));
        !           315: }
        !           316: 
        !           317: /* Return 1 if the operand is a general register or memory operand.  */
        !           318: 
        !           319: int
        !           320: reg_or_mem_operand (op, mode)
        !           321:      register rtx op;
        !           322:      register enum machine_mode mode;
        !           323: {
        !           324:   return gen_reg_operand (op, mode) || memory_operand (op, mode);
        !           325: }
        !           326: 
        !           327: /* Return 1 if the operand, used inside a MEM, is a valid first argument
        !           328:    to CALL.  This is a SYMBOL_REF or a pseudo-register, which will be
        !           329:    forced to lr.  */
        !           330: 
        !           331: int
        !           332: call_operand (op, mode)
        !           333:      register rtx op;
        !           334:      enum machine_mode mode;
        !           335: {
        !           336:   if (mode != VOIDmode && GET_MODE (op) != mode)
        !           337:     return 0;
        !           338: 
        !           339:   return (GET_CODE (op) == SYMBOL_REF
        !           340:          || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER));
        !           341: }
        !           342: 
        !           343: /* Return 1 if this operand is a valid input for a move insn.  */
        !           344: 
        !           345: int
        !           346: input_operand (op, mode)
        !           347:      register rtx op;
        !           348:      enum machine_mode mode;
        !           349: {
        !           350:   if (memory_operand (op, mode))
        !           351:     return 1;
        !           352: 
        !           353:   /* For floating-point or multi-word mode, only register or memory
        !           354:      is valid.  */
        !           355:   if (GET_MODE_CLASS (mode) == MODE_FLOAT
        !           356:       || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
        !           357:     return gen_reg_operand (op, mode);
        !           358: 
        !           359:   /* For SImode, we can also load from a special register, so any register
        !           360:      is valid.  */
        !           361:   if (mode == SImode && register_operand (op, mode))
        !           362:     return 1;
        !           363: 
        !           364:   /* For HImode and QImode, any constant is valid along with any
        !           365:      non-special register.  */
        !           366:   if (mode == HImode || mode == QImode)
        !           367:     return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
        !           368: 
        !           369:   /* Otherwise, we will be doing this SET with an add, so anything valid
        !           370:      for an add will be valid.  */
        !           371:   return add_operand (op, mode);
        !           372: }
        !           373: 
        !           374: /* Return 1 if OP is a load multiple operation.  It is known to be a
        !           375:    PARALLEL and the first section will be tested.  */
        !           376: 
        !           377: int
        !           378: load_multiple_operation (op, mode)
        !           379:      rtx op;
        !           380:      enum machine_mode mode;
        !           381: {
        !           382:   int count = XVECLEN (op, 0);
        !           383:   int dest_regno;
        !           384:   rtx src_addr;
        !           385:   int i;
        !           386: 
        !           387:   /* Perform a quick check so we don't blow up below.  */
        !           388:   if (count <= 1
        !           389:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
        !           390:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
        !           391:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
        !           392:     return 0;
        !           393: 
        !           394:   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
        !           395:   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
        !           396: 
        !           397:   for (i = 1; i < count; i++)
        !           398:     {
        !           399:       rtx elt = XVECEXP (op, 0, i);
        !           400: 
        !           401:       if (GET_CODE (elt) != SET
        !           402:          || GET_CODE (SET_DEST (elt)) != REG
        !           403:          || GET_MODE (SET_DEST (elt)) != SImode
        !           404:          || REGNO (SET_DEST (elt)) != dest_regno + i
        !           405:          || GET_CODE (SET_SRC (elt)) != MEM
        !           406:          || GET_MODE (SET_SRC (elt)) != SImode
        !           407:          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
        !           408:          || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
        !           409:          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
        !           410:          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
        !           411:        return 0;
        !           412:     }
        !           413: 
        !           414:   return 1;
        !           415: }
        !           416: 
        !           417: /* Similar, but tests for store multiple.  Here, the second vector element
        !           418:    is a CLOBBER.  It will be tested later.  */
        !           419: 
        !           420: int
        !           421: store_multiple_operation (op, mode)
        !           422:      rtx op;
        !           423:      enum machine_mode mode;
        !           424: {
        !           425:   int count = XVECLEN (op, 0) - 1;
        !           426:   int src_regno;
        !           427:   rtx dest_addr;
        !           428:   int i;
        !           429: 
        !           430:   /* Perform a quick check so we don't blow up below.  */
        !           431:   if (count <= 1
        !           432:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
        !           433:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
        !           434:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
        !           435:     return 0;
        !           436: 
        !           437:   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
        !           438:   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
        !           439: 
        !           440:   for (i = 1; i < count; i++)
        !           441:     {
        !           442:       rtx elt = XVECEXP (op, 0, i + 1);
        !           443: 
        !           444:       if (GET_CODE (elt) != SET
        !           445:          || GET_CODE (SET_SRC (elt)) != REG
        !           446:          || GET_MODE (SET_SRC (elt)) != SImode
        !           447:          || REGNO (SET_SRC (elt)) != src_regno + i
        !           448:          || GET_CODE (SET_DEST (elt)) != MEM
        !           449:          || GET_MODE (SET_DEST (elt)) != SImode
        !           450:          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
        !           451:          || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
        !           452:          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
        !           453:          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
        !           454:        return 0;
        !           455:     }
        !           456: 
        !           457:   return 1;
        !           458: }
        !           459: 
        !           460: /* Return 1 if OP is a comparison operation that is valid for a branch insn.
        !           461:    We only check the opcode against the mode of the CC value here.  */
        !           462: 
        !           463: int
        !           464: branch_comparison_operator (op, mode)
        !           465:      register rtx op;
        !           466:      enum machine_mode mode;
        !           467: {
        !           468:   enum rtx_code code = GET_CODE (op);
        !           469:   enum machine_mode cc_mode;
        !           470: 
        !           471:   if (GET_RTX_CLASS (code) != '<')
        !           472:     return 0;
        !           473: 
        !           474:   cc_mode = GET_MODE (XEXP (op, 0));
        !           475:   if (GET_MODE_CLASS (cc_mode) != MODE_CC)
        !           476:     return 0;
        !           477: 
        !           478:   if ((code == GT || code == LT || code == GE || code == LE)
        !           479:       && cc_mode == CCUNSmode)
        !           480:     return 0;
        !           481: 
        !           482:   if ((code == GTU || code == LTU || code == GEU || code == LEU)
        !           483:       && (cc_mode != CCUNSmode))
        !           484:     return 0;
        !           485: 
        !           486:   return 1;
        !           487: }
        !           488: 
        !           489: /* Return 1 if OP is a comparison operation that is valid for an scc insn.
        !           490:    We check the opcode against the mode of the CC value and disallow EQ or
        !           491:    NE comparisons for integers.  */
        !           492: 
        !           493: int
        !           494: scc_comparison_operator (op, mode)
        !           495:      register rtx op;
        !           496:      enum machine_mode mode;
        !           497: {
        !           498:   enum rtx_code code = GET_CODE (op);
        !           499:   enum machine_mode cc_mode;
        !           500: 
        !           501:   if (GET_MODE (op) != mode && mode != VOIDmode)
        !           502:     return 0;
        !           503: 
        !           504:   if (GET_RTX_CLASS (code) != '<')
        !           505:     return 0;
        !           506: 
        !           507:   cc_mode = GET_MODE (XEXP (op, 0));
        !           508:   if (GET_MODE_CLASS (cc_mode) != MODE_CC)
        !           509:     return 0;
        !           510: 
        !           511:   if (code == NE && cc_mode != CCFPmode)
        !           512:     return 0;
        !           513: 
        !           514:   if ((code == GT || code == LT || code == GE || code == LE)
        !           515:       && cc_mode == CCUNSmode)
        !           516:     return 0;
        !           517: 
        !           518:   if ((code == GTU || code == LTU || code == GEU || code == LEU)
        !           519:       && (cc_mode != CCUNSmode))
        !           520:     return 0;
        !           521: 
        !           522:   return 1;
        !           523: }
        !           524: 
        !           525: /* Return 1 if ANDOP is a mask that has no bits on that are not in the
        !           526:    mask required to convert the result of a rotate insn into a shift
        !           527:    left insn of SHIFTOP bits.  Both are known to be CONST_INT.  */
        !           528: 
        !           529: int
        !           530: includes_lshift_p (shiftop, andop)
        !           531:      register rtx shiftop;
        !           532:      register rtx andop;
        !           533: {
        !           534:   int shift_mask = (~0 << INTVAL (shiftop));
        !           535: 
        !           536:   return (INTVAL (andop) & ~shift_mask) == 0;
        !           537: }
        !           538: 
        !           539: /* Similar, but for right shift.  */
        !           540: 
        !           541: int
        !           542: includes_rshift_p (shiftop, andop)
        !           543:      register rtx shiftop;
        !           544:      register rtx andop;
        !           545: {
        !           546:   unsigned shift_mask = ~0;
        !           547: 
        !           548:   shift_mask >>= INTVAL (shiftop);
        !           549: 
        !           550:   return (INTVAL (andop) & ~ shift_mask) == 0;
        !           551: }
        !           552: 
        !           553: /* Return the register class of a scratch register needed to copy IN into
        !           554:    or out of a register in CLASS in MODE.  If it can be done directly,
        !           555:    NO_REGS is returned.  */
        !           556: 
        !           557: enum reg_class
        !           558: secondary_reload_class (class, mode, in)
        !           559:      enum reg_class class;
        !           560:      enum machine_mode mode;
        !           561:      rtx in;
        !           562: {
        !           563:   int regno = true_regnum (in);
        !           564: 
        !           565:   if (regno >= FIRST_PSEUDO_REGISTER)
        !           566:     regno = -1;
        !           567: 
        !           568:   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
        !           569:      into anything.  */
        !           570:   if (class == GENERAL_REGS || class == BASE_REGS
        !           571:       || (regno >= 0 && INT_REGNO_P (regno)))
        !           572:     return NO_REGS;
        !           573: 
        !           574:   /* Constants, memory, and FP registers can go into FP registers.  */
        !           575:   if ((regno == -1 || FP_REGNO_P (regno))
        !           576:       && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
        !           577:     return NO_REGS;
        !           578: 
        !           579:   /* We can copy among the CR registers.  */
        !           580:   if ((class == CR_REGS || class == CR0_REGS)
        !           581:       && regno >= 0 && CR_REGNO_P (regno))
        !           582:     return NO_REGS;
        !           583: 
        !           584:   /* Otherwise, we need GENERAL_REGS.  */
        !           585:   return GENERAL_REGS;
        !           586: }
        !           587: 
        !           588: /* Given a comparison operation, return the bit number in CCR to test.  We
        !           589:    know this is a valid comparison.  
        !           590: 
        !           591:    SCC_P is 1 if this is for an scc.  That means that %D will have been
        !           592:    used instead of %C, so the bits will be in different places.
        !           593: 
        !           594:    Return -1 if OP isn't a valid compaison for some reason.  */
        !           595: 
        !           596: int
        !           597: ccr_bit (op, scc_p)
        !           598:      register rtx op;
        !           599:      int scc_p;
        !           600: {
        !           601:   enum rtx_code code = GET_CODE (op);
        !           602:   enum machine_mode cc_mode;
        !           603:   int cc_regnum;
        !           604:   int base_bit;
        !           605: 
        !           606:   if (GET_RTX_CLASS (code) != '<')
        !           607:     return -1;
        !           608: 
        !           609:   cc_mode = GET_MODE (XEXP (op, 0));
        !           610:   cc_regnum = REGNO (XEXP (op, 0));
        !           611:   base_bit = 4 * (cc_regnum - 68);
        !           612: 
        !           613:   switch (code)
        !           614:     {
        !           615:     case NE:
        !           616:       return scc_p ? base_bit + 3 : base_bit + 2;
        !           617:     case EQ:
        !           618:       return base_bit + 2;
        !           619:     case GT:  case GTU:
        !           620:       return base_bit + 1;
        !           621:     case LT:  case LTU:
        !           622:       return base_bit;
        !           623: 
        !           624:     case GE:  case GEU:
        !           625:       /* If floating-point, we will have done a cror to put the bit in the
        !           626:         unordered position.  So test that bit.  For integer, this is ! LT
        !           627:         unless this is an scc insn.  */
        !           628:       return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit;
        !           629: 
        !           630:     case LE:  case LEU:
        !           631:       return cc_mode == CCFPmode || scc_p ? base_bit + 3 : base_bit + 1;
        !           632: 
        !           633:     default:
        !           634:       abort ();
        !           635:     }
        !           636: }
        !           637: 
        !           638: /* Print an operand.  Recognize special options, documented below.  */
        !           639: 
        !           640: void
        !           641: print_operand (file, x, code)
        !           642:     FILE *file;
        !           643:     rtx x;
        !           644:     char code;
        !           645: {
        !           646:   int i;
        !           647:   int val;
        !           648: 
        !           649:   /* These macros test for integers and extract the low-order bits.  */
        !           650: #define INT_P(X)  \
        !           651: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE)   \
        !           652:  && GET_MODE (X) == VOIDmode)
        !           653: 
        !           654: #define INT_LOWPART(X) \
        !           655:   (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
        !           656: 
        !           657:   switch (code)
        !           658:     {
        !           659:     case 'h':
        !           660:       /* If constant, output low-order six bits.  Otherwise, write normally. */
        !           661:       if (INT_P (x))
        !           662:        fprintf (file, "%d", INT_LOWPART (x) & 31);
        !           663:       else
        !           664:        print_operand (file, x, 0);
        !           665:       return;
        !           666: 
        !           667:     case 'H':
        !           668:       /* X must be a constant.  Output the low order 6 bits plus 24.  */
        !           669:       if (! INT_P (x))
        !           670:        output_operand_lossage ("invalid %%H value");
        !           671: 
        !           672:       fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31);
        !           673:       return;
        !           674: 
        !           675:     case 'b':
        !           676:       /* Low-order 16 bits of constant, unsigned.  */
        !           677:       if (! INT_P (x))
        !           678:        output_operand_lossage ("invalid %%b value");
        !           679: 
        !           680:       fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
        !           681:       return;
        !           682: 
        !           683:     case 'w':
        !           684:       /* If constant, low-order 16 bits of constant, signed.  Otherwise, write
        !           685:         normally.  */
        !           686:       if (INT_P (x))
        !           687:        fprintf (file, "%d", (INT_LOWPART (x) << 16) >> 16);
        !           688:       else
        !           689:        print_operand (file, x, 0);
        !           690:       return;
        !           691: 
        !           692:     case 'W':
        !           693:       /* If constant, low-order 16 bits of constant, unsigned.
        !           694:         Otherwise, write normally.  */
        !           695:       if (INT_P (x))
        !           696:        fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
        !           697:       else
        !           698:        print_operand (file, x, 0);
        !           699:       return;
        !           700: 
        !           701:     case 'u':
        !           702:       /* High-order 16 bits of constant.  */
        !           703:       if (! INT_P (x))
        !           704:        output_operand_lossage ("invalid %%u value");
        !           705: 
        !           706:       fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff);
        !           707:       return;
        !           708: 
        !           709:     case 's':
        !           710:       /* Low 5 bits of 32 - value */
        !           711:       if (! INT_P (x))
        !           712:        output_operand_lossage ("invalid %%s value");
        !           713: 
        !           714:       fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);
        !           715:       return;
        !           716: 
        !           717:     case 'S':
        !           718:       /* Low 5 bits of 31 - value */
        !           719:       if (! INT_P (x))
        !           720:        output_operand_lossage ("invalid %%S value");
        !           721: 
        !           722:       fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31);
        !           723:       return;
        !           724: 
        !           725:     case 'p':
        !           726:       /* X is a CONST_INT that is a power of two.  Output the logarithm.  */
        !           727:       if (! INT_P (x)
        !           728:          || (i = exact_log2 (INT_LOWPART (x))) < 0)
        !           729:        output_operand_lossage ("invalid %%p value");
        !           730: 
        !           731:       fprintf (file, "%d", i);
        !           732:       return;
        !           733: 
        !           734:     case 'm':
        !           735:       /* MB value for a mask operand.  */
        !           736:       if (! mask_operand (x, VOIDmode))
        !           737:        output_operand_lossage ("invalid %%m value");
        !           738: 
        !           739:       val = INT_LOWPART (x);
        !           740: 
        !           741:       /* If the high bit is set and the low bit is not, the value is zero.
        !           742:         If the high bit is zero, the value is the first 1 bit we find from
        !           743:         the left.  */
        !           744:       if (val < 0 && (val & 1) == 0)
        !           745:        {
        !           746:          fprintf (file, "0");
        !           747:          return;
        !           748:        }
        !           749:       else if (val >= 0)
        !           750:        {
        !           751:          for (i = 1; i < 32; i++)
        !           752:            if ((val <<= 1) < 0)
        !           753:              break;
        !           754:          fprintf (file, "%d", i);
        !           755:          return;
        !           756:        }
        !           757:          
        !           758:       /* Otherwise, look for the first 0 bit from the right.  The result is its
        !           759:         number plus 1. We know the low-order bit is one.  */
        !           760:       for (i = 0; i < 32; i++)
        !           761:        if (((val >>= 1) & 1) == 0)
        !           762:          break;
        !           763: 
        !           764:       /* If we ended in ...01, I would be 0.  The correct value is 31, so
        !           765:         we want 31 - i.  */
        !           766:       fprintf (file, "%d", 31 - i);
        !           767:       return;
        !           768: 
        !           769:     case 'M':
        !           770:       /* ME value for a mask operand.  */
        !           771:       if (! mask_operand (x, VOIDmode))
        !           772:        output_operand_lossage ("invalid %%m value");
        !           773: 
        !           774:       val = INT_LOWPART (x);
        !           775: 
        !           776:       /* If the low bit is set and the high bit is not, the value is 31.
        !           777:         If the low bit is zero, the value is the first 1 bit we find from
        !           778:         the right.  */
        !           779:       if ((val & 1) && val >= 0)
        !           780:        {
        !           781:          fprintf (file, "31");
        !           782:          return;
        !           783:        }
        !           784:       else if ((val & 1) == 0)
        !           785:        {
        !           786:          for (i = 0; i < 32; i++)
        !           787:            if ((val >>= 1) & 1)
        !           788:              break;
        !           789: 
        !           790:          /* If we had ....10, I would be 0.  The result should be
        !           791:             30, so we need 30 - i.  */
        !           792:          fprintf (file, "%d", 30 - i);
        !           793:          return;
        !           794:        }
        !           795:          
        !           796:       /* Otherwise, look for the first 0 bit from the left.  The result is its
        !           797:         number minus 1. We know the high-order bit is one.  */
        !           798:       for (i = 0; i < 32; i++)
        !           799:        if ((val <<= 1) >= 0)
        !           800:          break;
        !           801: 
        !           802:       fprintf (file, "%d", i);
        !           803:       return;
        !           804: 
        !           805:     case 'f':
        !           806:       /* X is a CR register.  Print the shift count needed to move it
        !           807:         to the high-order four bits.  */
        !           808:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           809:        output_operand_lossage ("invalid %%f value");
        !           810:       else
        !           811:        fprintf (file, "%d", 4 * (REGNO (x) - 68));
        !           812:       return;
        !           813: 
        !           814:     case 'F':
        !           815:       /* Similar, but print the count for the rotate in the opposite
        !           816:         direction.  */
        !           817:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           818:        output_operand_lossage ("invalid %%F value");
        !           819:       else
        !           820:        fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
        !           821:       return;
        !           822: 
        !           823:     case 'R':
        !           824:       /* X is a CR register.  Print the mask for `mtcrf'.  */
        !           825:       if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
        !           826:        output_operand_lossage ("invalid %%R value");
        !           827:       else
        !           828:        fprintf (file, "%d", 128 >> (REGNO (x) - 68));
        !           829:       return;
        !           830: 
        !           831:     case 'X':
        !           832:       if (GET_CODE (x) == MEM
        !           833:          && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
        !           834:        fprintf (file, "x");
        !           835:       return;
        !           836: 
        !           837:     case 'U':
        !           838:       /* Print `u' is this has an auto-increment or auto-decremement.  */
        !           839:       if (GET_CODE (x) == MEM
        !           840:          && (GET_CODE (XEXP (x, 0)) == PRE_INC
        !           841:              || GET_CODE (XEXP (x, 0)) == PRE_DEC))
        !           842:        fprintf (file, "u");
        !           843:       return;
        !           844: 
        !           845:     case 'I':
        !           846:       /* Print `i' is this is a constant, else nothing.  */
        !           847:       if (INT_P (x))
        !           848:        fprintf (file, "i");
        !           849:       return;
        !           850: 
        !           851:     case 'N':
        !           852:       /* Write the number of elements in the vector times 4.  */
        !           853:       if (GET_CODE (x) != PARALLEL)
        !           854:        output_operand_lossage ("invalid %%N value");
        !           855: 
        !           856:       fprintf (file, "%d", XVECLEN (x, 0) * 4);
        !           857:       return;
        !           858: 
        !           859:     case 'O':
        !           860:       /* Similar, but subtract 1 first.  */
        !           861:       if (GET_CODE (x) != PARALLEL)
        !           862:        output_operand_lossage ("invalid %%N value");
        !           863: 
        !           864:       fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
        !           865:       return;
        !           866: 
        !           867:     case 'P':
        !           868:       /* The operand must be an indirect memory reference.  The result
        !           869:         is the register number. */
        !           870:       if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
        !           871:          || REGNO (XEXP (x, 0)) >= 32)
        !           872:        output_operand_lossage ("invalid %%P value");
        !           873: 
        !           874:       fprintf (file, "%d", REGNO (XEXP (x, 0)));
        !           875:       return;
        !           876: 
        !           877:     case 'L':
        !           878:       /* Write second word of DImode or DFmode reference.  Works on register
        !           879:         or non-indexed memory only.  */
        !           880:       if (GET_CODE (x) == REG)
        !           881:        fprintf (file, "%d", REGNO (x) + 1);
        !           882:       else if (GET_CODE (x) == MEM)
        !           883:        {
        !           884:          /* Handle possible auto-increment.  Since it is pre-increment and
        !           885:             we have already done it, we can just use an offset of four.  */
        !           886:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !           887:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !           888:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
        !           889:          else
        !           890:            output_address (plus_constant (XEXP (x, 0), 4));
        !           891:        }
        !           892:       return;
        !           893:                            
        !           894:     case 'Y':
        !           895:       /* Similar, for third word of TImode  */
        !           896:       if (GET_CODE (x) == REG)
        !           897:        fprintf (file, "%d", REGNO (x) + 2);
        !           898:       else if (GET_CODE (x) == MEM)
        !           899:        {
        !           900:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !           901:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !           902:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
        !           903:          else
        !           904:            output_address (plus_constant (XEXP (x, 0), 8));
        !           905:        }
        !           906:       return;
        !           907:                            
        !           908:     case 'Z':
        !           909:       /* Similar, for last word of TImode.  */
        !           910:       if (GET_CODE (x) == REG)
        !           911:        fprintf (file, "%d", REGNO (x) + 3);
        !           912:       else if (GET_CODE (x) == MEM)
        !           913:        {
        !           914:          if (GET_CODE (XEXP (x, 0)) == PRE_INC
        !           915:              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !           916:            output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
        !           917:          else
        !           918:            output_address (plus_constant (XEXP (x, 0), 12));
        !           919:        }
        !           920:       return;
        !           921:                            
        !           922:     case 't':
        !           923:       /* Write 12 if this jump operation will branch if true, 4 otherwise. 
        !           924:         All floating-point operations except NE branch true and integer
        !           925:         EQ, LT, GT, LTU and GTU also branch true.  */
        !           926:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
        !           927:        output_operand_lossage ("invalid %%t value");
        !           928: 
        !           929:       else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
        !           930:                && GET_CODE (x) != NE)
        !           931:               || GET_CODE (x) == EQ
        !           932:               || GET_CODE (x) == LT || GET_CODE (x) == GT
        !           933:               || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
        !           934:        fprintf (file, "12");
        !           935:       else
        !           936:        fprintf (file, "4");
        !           937:       return;
        !           938:       
        !           939:     case 'T':
        !           940:       /* Opposite of 't': write 4 if this jump operation will branch if true,
        !           941:         12 otherwise.   */
        !           942:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
        !           943:        output_operand_lossage ("invalid %%t value");
        !           944: 
        !           945:       else if ((GET_MODE (XEXP (x, 0)) == CCFPmode
        !           946:                && GET_CODE (x) != NE)
        !           947:               || GET_CODE (x) == EQ
        !           948:               || GET_CODE (x) == LT || GET_CODE (x) == GT
        !           949:               || GET_CODE (x) == LTU || GET_CODE (x) == GTU)
        !           950:        fprintf (file, "4");
        !           951:       else
        !           952:        fprintf (file, "12");
        !           953:       return;
        !           954:       
        !           955:     case 'j':
        !           956:       /* Write the bit number in CCR for jump.  */
        !           957:       i = ccr_bit (x, 0);
        !           958:       if (i == -1)
        !           959:        output_operand_lossage ("invalid %%j code");
        !           960:       else
        !           961:        fprintf (file, "%d", i);
        !           962:       return;
        !           963: 
        !           964:     case 'J':
        !           965:       /* Similar, but add one for shift count in rlinm for scc and pass
        !           966:         scc flag to `ccr_bit'.  */
        !           967:       i = ccr_bit (x, 1);
        !           968:       if (i == -1)
        !           969:        output_operand_lossage ("invalid %%J code");
        !           970:       else
        !           971:        fprintf (file, "%d", i + 1);
        !           972:       return;
        !           973: 
        !           974:     case 'C':
        !           975:       /* This is an optional cror needed for LE or GE floating-point
        !           976:         comparisons.  Otherwise write nothing.  */
        !           977:       if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
        !           978:          && GET_MODE (XEXP (x, 0)) == CCFPmode)
        !           979:        {
        !           980:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !           981: 
        !           982:          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
        !           983:                   base_bit + 2, base_bit + (GET_CODE (x) == GE));
        !           984:        }
        !           985:       return;
        !           986: 
        !           987:     case 'D':
        !           988:       /* Similar, except that this is for an scc, so we must be able to
        !           989:         encode the test in a single bit that is one.  We do the above
        !           990:         for any LE, GE, GEU, or LEU and invert the bit for NE.  */
        !           991:       if (GET_CODE (x) == LE || GET_CODE (x) == GE
        !           992:          || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
        !           993:        {
        !           994:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !           995: 
        !           996:          fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
        !           997:                   base_bit + 2,
        !           998:                   base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
        !           999:        }
        !          1000: 
        !          1001:       else if (GET_CODE (x) == NE)
        !          1002:        {
        !          1003:          int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
        !          1004: 
        !          1005:          fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
        !          1006:                   base_bit + 2, base_bit + 2);
        !          1007:        }
        !          1008:       return;
        !          1009: 
        !          1010:     case 'z':
        !          1011:       /* X is a SYMBOL_REF.  Write out the name preceeded by a
        !          1012:         period and without any trailing data in backets.  Used for function
        !          1013:         names.  */
        !          1014:       if (GET_CODE (x) != SYMBOL_REF)
        !          1015:        abort ();
        !          1016: 
        !          1017:       fprintf (file, ".");
        !          1018:       RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
        !          1019:       return;
        !          1020: 
        !          1021:     case 0:
        !          1022:       if (GET_CODE (x) == REG)
        !          1023:        fprintf (file, "%s", reg_names[REGNO (x)]);
        !          1024:       else if (GET_CODE (x) == MEM)
        !          1025:        {
        !          1026:          /* We need to handle PRE_INC and PRE_DEC here, since we need to
        !          1027:             know the width from the mode.  */
        !          1028:          if (GET_CODE (XEXP (x, 0)) == PRE_INC)
        !          1029:            fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)),
        !          1030:                     REGNO (XEXP (XEXP (x, 0), 0)));
        !          1031:          else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
        !          1032:            fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
        !          1033:                     REGNO (XEXP (XEXP (x, 0), 0)));
        !          1034:          else
        !          1035:            output_address (XEXP (x, 0));
        !          1036:        }
        !          1037:       else
        !          1038:        output_addr_const (file, x);
        !          1039:       break;
        !          1040: 
        !          1041:     default:
        !          1042:       output_operand_lossage ("invalid %%xn code");
        !          1043:     }
        !          1044: }
        !          1045: 
        !          1046: /* Print the address of an operand.  */
        !          1047: 
        !          1048: void
        !          1049: print_operand_address (file, x)
        !          1050:      FILE *file;
        !          1051:      register rtx x;
        !          1052: {
        !          1053:   if (GET_CODE (x) == REG)
        !          1054:     fprintf (file, "0(%d)", REGNO (x));
        !          1055:   else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
        !          1056:     {
        !          1057:       output_addr_const (file, x);
        !          1058:       fprintf (file, "(2)");
        !          1059:     }
        !          1060:   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
        !          1061:     {
        !          1062:       if (REGNO (XEXP (x, 0)) == 0)
        !          1063:        fprintf (file, "%d,%d", REGNO (XEXP (x, 1)), REGNO (XEXP (x, 0)));
        !          1064:       else
        !          1065:        fprintf (file, "%d,%d", REGNO (XEXP (x, 0)), REGNO (XEXP (x, 1)));
        !          1066:     }
        !          1067:   else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
        !          1068:     fprintf (file, "%d(%d)", INTVAL (XEXP (x, 1)), REGNO (XEXP (x, 0)));
        !          1069:   else
        !          1070:     abort ();
        !          1071: }
        !          1072: 
        !          1073: /* This page contains routines that are used to determine what the function
        !          1074:    prologue and epilogue code will do and write them out.  */
        !          1075: 
        !          1076: /*  Return the first fixed-point register that is required to be saved. 32 if
        !          1077:     none.  */
        !          1078: 
        !          1079: int
        !          1080: first_reg_to_save ()
        !          1081: {
        !          1082:   int first_reg;
        !          1083: 
        !          1084:   /* Find lowest numbered live register.  */
        !          1085:   for (first_reg = 13; first_reg <= 31; first_reg++)
        !          1086:     if (regs_ever_live[first_reg])
        !          1087:       break;
        !          1088: 
        !          1089:   return first_reg;
        !          1090: }
        !          1091: 
        !          1092: /* Similar, for FP regs.  */
        !          1093: 
        !          1094: int
        !          1095: first_fp_reg_to_save ()
        !          1096: {
        !          1097:   int first_reg;
        !          1098: 
        !          1099:   /* Find lowest numbered live register.  */
        !          1100:   for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
        !          1101:     if (regs_ever_live[first_reg])
        !          1102:       break;
        !          1103: 
        !          1104:   return first_reg;
        !          1105: }
        !          1106: 
        !          1107: /* Return 1 if we need to save CR.  */
        !          1108: 
        !          1109: int
        !          1110: must_save_cr ()
        !          1111: {
        !          1112:   return regs_ever_live[70] || regs_ever_live[71] || regs_ever_live[72];
        !          1113: }
        !          1114: 
        !          1115: /* Compute the size of the save area in the stack, including the space for
        !          1116:    the fixed area.  */
        !          1117: 
        !          1118: int
        !          1119: rs6000_sa_size ()
        !          1120: {
        !          1121:   int size;
        !          1122:   int i;
        !          1123: 
        !          1124:   /* We have the six fixed words, plus the size of the register save 
        !          1125:      areas, rounded to a double-word.  */
        !          1126:   size = 6 + (32 - first_reg_to_save ()) + (64 - first_fp_reg_to_save ()) * 2;
        !          1127:   if (size & 1)
        !          1128:     size++;
        !          1129: 
        !          1130:   return size * 4;
        !          1131: }
        !          1132: 
        !          1133: /* Return non-zero if this function makes calls.  */
        !          1134: 
        !          1135: int
        !          1136: rs6000_makes_calls ()
        !          1137: {
        !          1138:   rtx insn;
        !          1139: 
        !          1140:   for (insn = get_insns (); insn; insn = next_insn (insn))
        !          1141:     if (GET_CODE (insn) == CALL_INSN)
        !          1142:       return 1;
        !          1143: 
        !          1144:   return 0;
        !          1145: }
        !          1146: 
        !          1147: /* Return non-zero if this function needs to push space on the stack.  */
        !          1148: 
        !          1149: int
        !          1150: rs6000_pushes_stack ()
        !          1151: {
        !          1152:   int total_size = (rs6000_sa_size () + get_frame_size ()
        !          1153:                    + current_function_outgoing_args_size);
        !          1154: 
        !          1155:   /* We need to push the stack if a frame pointer is needed (because the
        !          1156:      stack might be dynamically adjusted), if we are debugging, if the
        !          1157:      total stack size is more than 220 bytes, or if we make calls.  */
        !          1158: 
        !          1159:   return (frame_pointer_needed || write_symbols != NO_DEBUG
        !          1160:          || total_size > 220
        !          1161:          || rs6000_makes_calls ());
        !          1162: }
        !          1163: 
        !          1164: /* Write function prologue.  */
        !          1165: 
        !          1166: void
        !          1167: output_prolog (file, size)
        !          1168:      FILE *file;
        !          1169:      int size;
        !          1170: {
        !          1171:   int first_reg = first_reg_to_save ();
        !          1172:   int must_push = rs6000_pushes_stack ();
        !          1173:   int first_fp_reg = first_fp_reg_to_save ();
        !          1174:   int basic_size = rs6000_sa_size ();
        !          1175:   int total_size = (basic_size + size + current_function_outgoing_args_size);
        !          1176: 
        !          1177:   /* Round size to multiple of 8 bytes.  */
        !          1178:   total_size = (total_size + 7) & ~7;
        !          1179: 
        !          1180:   /* Write .extern for any function we will call to save and restore fp
        !          1181:      values.  */
        !          1182:   if (first_fp_reg < 62)
        !          1183:     fprintf (file, "\t.extern ._savef%d\n\t.extern ._restf%d\n",
        !          1184:             first_fp_reg - 32, first_fp_reg - 32);
        !          1185: 
        !          1186:   /* Write .extern for truncation routines, if needed.  */
        !          1187:   if (rs6000_trunc_used && ! trunc_defined)
        !          1188:     {
        !          1189:       fprintf (file, "\t.extern .itrunc\n\t.extern .uitrunc\n");
        !          1190:       trunc_defined = 1;
        !          1191:     }
        !          1192: 
        !          1193:   /* If we have to call a function to save fpr's, we will be using LR.  */
        !          1194:   if (first_fp_reg < 62)
        !          1195:     regs_ever_live[65] = 1;
        !          1196: 
        !          1197:   /* If we use the link register, get it into r0.  */
        !          1198:   if (regs_ever_live[65])
        !          1199:     fprintf (file, "\tmflr 0\n");
        !          1200: 
        !          1201:   /* If we need to save CR, put it into r12.  */
        !          1202:   if (must_save_cr ())
        !          1203:     fprintf (file, "\tmfcr 12\n");
        !          1204: 
        !          1205:   /* Do any required saving of fpr's.  If only one or two to save, do it
        !          1206:      ourself.  Otherwise, call function.  */
        !          1207:   if (first_fp_reg == 62)
        !          1208:     fprintf (file, "\tstfd 30,-16(1)\n\tstfd 31,-8(1)\n");
        !          1209:   else if (first_fp_reg == 63)
        !          1210:     fprintf (file, "\tstfd 31,-8(1)\n");
        !          1211:   else if (first_fp_reg != 64)
        !          1212:     fprintf (file, "\tbl ._savef%d\n\tcror 15,15,15\n", first_fp_reg - 32);
        !          1213: 
        !          1214:   /* Now save gpr's.  */
        !          1215:   if (first_reg == 31)
        !          1216:     fprintf (file, "\tst 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8);
        !          1217:   else if (first_reg != 32)
        !          1218:     fprintf (file, "\tstm %d,%d(1)\n", first_reg,
        !          1219:             - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
        !          1220: 
        !          1221:   /* Save lr if we used it.  */
        !          1222:   if (regs_ever_live[65])
        !          1223:     fprintf (file, "\tst 0,8(1)\n");
        !          1224: 
        !          1225:   /* Save CR if we use any that must be preserved.  */
        !          1226:   if (must_save_cr ())
        !          1227:     fprintf (file, "\tst 12,4(1)\n");
        !          1228: 
        !          1229:   /* Update stack and set back pointer.  */
        !          1230:   if (must_push)
        !          1231:     {
        !          1232:       if (total_size < 32767)
        !          1233:        fprintf (file, "\tstu 1,%d(1)\n", - total_size);
        !          1234:       else
        !          1235:        {
        !          1236:          fprintf (file, "\tcau 0,0,%d\n\toril 0,0,%d\n",
        !          1237:                   (total_size >> 16) & 0xffff, total_size & 0xffff);
        !          1238:          fprintf (file, "\tsf 12,0,1\n\tst 1,0(12)\n\toril 1,12,0\n");
        !          1239:        }
        !          1240:     }
        !          1241: 
        !          1242:   /* Set frame pointer, if needed.  */
        !          1243:   if (frame_pointer_needed)
        !          1244:     fprintf (file, "\toril 31,1,0\n");
        !          1245: }
        !          1246: 
        !          1247: /* Write function epilogue.  */
        !          1248: 
        !          1249: void
        !          1250: output_epilog (file, size)
        !          1251:      FILE *file;
        !          1252:      int size;
        !          1253: {
        !          1254:   int first_reg = first_reg_to_save ();
        !          1255:   int must_push = rs6000_pushes_stack ();
        !          1256:   int first_fp_reg = first_fp_reg_to_save ();
        !          1257:   int basic_size = rs6000_sa_size ();
        !          1258:   int total_size = (basic_size + size + current_function_outgoing_args_size);
        !          1259:   rtx insn = get_last_insn ();
        !          1260: 
        !          1261:   /* Round size to multiple of 8 bytes.  */
        !          1262:   total_size = (total_size + 7) & ~7;
        !          1263: 
        !          1264:   /* If the last insn was a BARRIER, we don't have to write anything except
        !          1265:      the trace table.  */
        !          1266:   if (GET_CODE (insn) == NOTE)
        !          1267:     insn = prev_nonnote_insn (insn);
        !          1268:   if (insn == 0 ||  GET_CODE (insn) != BARRIER)
        !          1269:     {
        !          1270:       /* If we have a frame pointer, a call to alloca,  or a large stack
        !          1271:         frame, restore the old stack pointer using the backchain.  Otherwise,
        !          1272:         we know what size to update it with.  */
        !          1273:       if (frame_pointer_needed || current_function_calls_alloca
        !          1274:          || total_size > 32767)
        !          1275:        fprintf (file, "\tl 1,0(1)\n");
        !          1276:       else if (must_push)
        !          1277:        fprintf (file, "\tai 1,1,%d\n", total_size);
        !          1278: 
        !          1279:       /* Get the old lr if we saved it.  To speed things up, copy it into
        !          1280:         lr here if we don't have to save more than 2 fp regs.  */
        !          1281:       if (regs_ever_live[65])
        !          1282:        {
        !          1283:          fprintf (file, "\tl 0,8(1)\n");
        !          1284:          if (first_fp_reg >= 62)
        !          1285:            fprintf (file, "\tmtlr 0\n");
        !          1286:        }
        !          1287: 
        !          1288:       /* Get the old cr if we saved it.  */
        !          1289:       if (must_save_cr ())
        !          1290:        fprintf (file, "\tl 12,4(1)\n");
        !          1291: 
        !          1292:       /* Restore gpr's.  */
        !          1293:       if (first_reg == 31)
        !          1294:        fprintf (file, "\tl 31,%d(1)\n", -4 - (64 - first_fp_reg) * 8);
        !          1295:       else if (first_reg != 32)
        !          1296:        fprintf (file, "\tlm %d,%d(1)\n", first_reg,
        !          1297:                 - (32 - first_reg) * 4 - (64 - first_fp_reg) * 8);
        !          1298: 
        !          1299:       /* Restore fpr's.  */
        !          1300:       if (first_fp_reg == 62)
        !          1301:        fprintf (file, "\tlfd 30,-16(1)\n\tlfd 31,-8(1)\n");
        !          1302:       else if (first_fp_reg == 63)
        !          1303:        fprintf (file, "\tlfd 31,-8(1)\n");
        !          1304:       else if (first_fp_reg != 64)
        !          1305:        fprintf (file, "\tbl ._restf%d\n\tcror 15,15,15\n", first_fp_reg - 32);
        !          1306: 
        !          1307:       /* If we used the link register, get it from r0 if we haven't
        !          1308:         already.  */
        !          1309:       if (regs_ever_live[65] && first_fp_reg < 62)
        !          1310:        fprintf (file, "\tmtlr 0\n");
        !          1311: 
        !          1312:       /* If we saved cr, restore it here.  Just set cr2, cr3, and cr4.  */
        !          1313:       if (must_save_cr ())
        !          1314:        fprintf (file, "\tmtcrf 0x38,12\n");
        !          1315: 
        !          1316:       fprintf (file, "\tbr\n");
        !          1317:     }
        !          1318: }
        !          1319: 
        !          1320: /* Output a TOC entry.  We derive the entry name from what is
        !          1321:    being written.  */
        !          1322: 
        !          1323: void
        !          1324: output_toc (file, x, labelno)
        !          1325:      FILE *file;
        !          1326:      rtx x;
        !          1327:      int labelno;
        !          1328: {
        !          1329:   char buf[256];
        !          1330:   char *name = buf;
        !          1331:   rtx base = x;
        !          1332:   int offset = 0;
        !          1333: 
        !          1334:   ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
        !          1335: 
        !          1336:   /* Handle FP constants specially.  */
        !          1337:   if (GET_CODE (x) == CONST_DOUBLE
        !          1338:       && GET_MODE (x) == DFmode
        !          1339:       && TARGET_FLOAT_FORMAT == HOST_FLOAT_FORMAT
        !          1340:       && BITS_PER_WORD == HOST_BITS_PER_INT
        !          1341:       && TARGET_FP_IN_TOC)
        !          1342:     {
        !          1343:       fprintf (file, "\t.tc FD_%x_%x[TC],%d,%d\n",
        !          1344:               CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
        !          1345:               CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
        !          1346:       return;
        !          1347:     }
        !          1348:   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode
        !          1349:           && TARGET_FP_IN_TOC)
        !          1350:     {
        !          1351:       rtx val = operand_subword (x, 0, 0, SFmode);
        !          1352: 
        !          1353:       if (val == 0 || GET_CODE (val) != CONST_INT)
        !          1354:        abort ();
        !          1355: 
        !          1356:       fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val));
        !          1357:       return;
        !          1358:     }
        !          1359: 
        !          1360:   if (GET_CODE (x) == CONST)
        !          1361:     {
        !          1362:       base = XEXP (XEXP (x, 0), 0);
        !          1363:       offset = INTVAL (XEXP (XEXP (x, 0), 1));
        !          1364:     }
        !          1365:   
        !          1366:   if (GET_CODE (base) == SYMBOL_REF)
        !          1367:     name = XSTR (base, 0);
        !          1368:   else if (GET_CODE (base) == LABEL_REF)
        !          1369:     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
        !          1370:   else if (GET_CODE (base) == CODE_LABEL)
        !          1371:     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
        !          1372:   else
        !          1373:     abort ();
        !          1374: 
        !          1375:   fprintf (file, "\t.tc ");
        !          1376:   RS6000_OUTPUT_BASENAME (file, name);
        !          1377: 
        !          1378:   if (offset < 0)
        !          1379:     fprintf (file, "P.N.%d", - offset);
        !          1380:   else if (offset)
        !          1381:     fprintf (file, ".P.%d", offset);
        !          1382: 
        !          1383:   fprintf (file, "[TC],");
        !          1384:   output_addr_const (file, x);
        !          1385:   fprintf (file, "\n");
        !          1386: }
        !          1387: 
        !          1388: /* Output an assembler pseudo-op to write an ASCII string of N characters
        !          1389:    starting at P to FILE.
        !          1390: 
        !          1391:    On the RS/6000, we have to do this using the .byte operation and
        !          1392:    write out special characters outside the quoted string.
        !          1393:    Also, the assembler is broken; very long strings are truncated,
        !          1394:    so we must artificially break them up early. */
        !          1395: 
        !          1396: void
        !          1397: output_ascii (file, p, n)
        !          1398:      FILE *file;
        !          1399:      char *p;
        !          1400:      int n;
        !          1401: {
        !          1402:   char c;
        !          1403:   int i, count_string;
        !          1404:   char *for_string = "\t.byte \"";
        !          1405:   char *for_decimal = "\t.byte ";
        !          1406:   char *to_close = NULL;
        !          1407: 
        !          1408:   count_string = 0;
        !          1409:   for (i = 0; i < n; i++)
        !          1410:     {
        !          1411:       c = *p++;
        !          1412:       if (c >= ' ' && c < 0177)
        !          1413:        {
        !          1414:          if (for_string)
        !          1415:            fputs (for_string, file);
        !          1416:          putc (c, file);
        !          1417: 
        !          1418:          /* Write two quotes to get one.  */
        !          1419:          if (c == '"')
        !          1420:            {
        !          1421:              putc (c, file);
        !          1422:              ++count_string;
        !          1423:            }
        !          1424: 
        !          1425:          for_string = NULL;
        !          1426:          for_decimal = "\"\n\t.byte ";
        !          1427:          to_close = "\"\n";
        !          1428:          ++count_string;
        !          1429: 
        !          1430:          if (count_string >= 512)
        !          1431:            {
        !          1432:              fputs (to_close, file);
        !          1433: 
        !          1434:              for_string = "\t.byte \"";
        !          1435:              for_decimal = "\t.byte ";
        !          1436:              to_close = NULL;
        !          1437:              count_string = 0;
        !          1438:            }
        !          1439:        }
        !          1440:       else
        !          1441:        {
        !          1442:          if (for_decimal)
        !          1443:            fputs (for_decimal, file);
        !          1444:          fprintf (file, "%d", c);
        !          1445: 
        !          1446:          for_string = "\n\t.byte \"";
        !          1447:          for_decimal = ", ";
        !          1448:          to_close = "\n";
        !          1449:          count_string = 0;
        !          1450:        }
        !          1451:     }
        !          1452: 
        !          1453:   /* Now close the string if we have written one.  Then end the line.  */
        !          1454:   if (to_close)
        !          1455:     fprintf (file, to_close);
        !          1456: }
        !          1457: 
        !          1458: /* Generate a unique section name for FILENAME for a section type
        !          1459:    represented by SECTION_DESC.  Output goes into BUF.
        !          1460: 
        !          1461:    SECTION_DESC can be any string, as long as it is different for each
        !          1462:    possible section type.
        !          1463: 
        !          1464:    We name the section in the same manner as xlc.  The name begins with an
        !          1465:    underscore followed by the filename (after stripping any leading directory
        !          1466:    names) with the period replaced by the string SECTION_DESC.  If FILENAME
        !          1467:    does not contain a period, SECTION_DESC is appended at the end of the
        !          1468:    name.  */
        !          1469: 
        !          1470: void
        !          1471: rs6000_gen_section_name (buf, filename, section_desc)
        !          1472:      char **buf;
        !          1473:      char *filename;
        !          1474:      char *section_desc;
        !          1475: {
        !          1476:   char *q, *after_last_slash;
        !          1477:   char *p;
        !          1478:   int len;
        !          1479:   int used_desc = 0;
        !          1480: 
        !          1481:   after_last_slash = filename;
        !          1482:   for (q = filename; *q; q++)
        !          1483:     if (*q == '/')
        !          1484:       after_last_slash = q + 1;
        !          1485: 
        !          1486:   len = strlen (filename) + strlen (section_desc) + 2;
        !          1487:   *buf = (char *) permalloc (len);
        !          1488: 
        !          1489:   p = *buf;
        !          1490:   *p++ = '_';
        !          1491: 
        !          1492:   for (q = after_last_slash; *q; q++)
        !          1493:     {
        !          1494:       if (*q == '.')
        !          1495:         {
        !          1496:          strcpy (p, section_desc);
        !          1497:          p += strlen (section_desc);
        !          1498:          used_desc = 1;
        !          1499:         }
        !          1500: 
        !          1501:       else if (isalnum (*q))
        !          1502:         *p++ = *q;
        !          1503:     }
        !          1504: 
        !          1505:   if (! used_desc)
        !          1506:     strcpy (p, section_desc);
        !          1507:   else
        !          1508:     *p = '\0';
        !          1509: }

unix.superglobalmegacorp.com

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