Annotation of gcc/config/alpha/alpha.c, revision 1.1.1.3

1.1       root        1: /* Subroutines used for code generation on the DEC Alpha.
1.1.1.3 ! root        2:    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
        !             3:    Contributed by Richard Kenner ([email protected])
1.1       root        4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: 
                     22: #include <stdio.h>
                     23: #include "config.h"
                     24: #include "rtl.h"
                     25: #include "regs.h"
                     26: #include "hard-reg-set.h"
                     27: #include "real.h"
                     28: #include "insn-config.h"
                     29: #include "conditions.h"
                     30: #include "insn-flags.h"
                     31: #include "output.h"
                     32: #include "insn-attr.h"
                     33: #include "flags.h"
                     34: #include "recog.h"
                     35: #include "reload.h"
                     36: #include "expr.h"
                     37: #include "obstack.h"
                     38: #include "tree.h"
                     39: 
                     40: /* Save information from a "cmpxx" operation until the branch or scc is
                     41:    emitted.  */
                     42: 
                     43: rtx alpha_compare_op0, alpha_compare_op1;
                     44: int alpha_compare_fp_p;
                     45: 
                     46: /* Save the name of the current function as used by the assembler.  This
                     47:    is used by the epilogue.  */
                     48: 
                     49: char *alpha_function_name;
                     50: 
1.1.1.2   root       51: /* Non-zero if inside of a function, because the Alpha asm can't
                     52:    handle .files inside of functions.  */
                     53: 
                     54: static int inside_function = FALSE;
                     55: 
1.1       root       56: /* Nonzero if the current function needs gp.  */
                     57: 
                     58: int alpha_function_needs_gp;
                     59: 
                     60: extern char *version_string;
1.1.1.3 ! root       61: 
        !            62: /* Declarations of static functions.  */
        !            63: static void alpha_set_memflags_1  PROTO((rtx, int, int, int));
        !            64: static void add_long_const     PROTO((FILE *, HOST_WIDE_INT, int, int, int));
1.1       root       65: 
                     66: /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
                     67: 
                     68: int
                     69: zap_mask (value)
                     70:      HOST_WIDE_INT value;
                     71: {
                     72:   int i;
                     73: 
                     74:   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
                     75:        i++, value >>= 8)
                     76:     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
                     77:       return 0;
                     78: 
                     79:   return 1;
                     80: }
                     81: 
                     82: /* Returns 1 if OP is either the constant zero or a register.  If a
                     83:    register, it must be in the proper mode unless MODE is VOIDmode.  */
                     84: 
                     85: int
                     86: reg_or_0_operand (op, mode)
                     87:       register rtx op;
                     88:       enum machine_mode mode;
                     89: {
                     90:   return op == const0_rtx || register_operand (op, mode);
                     91: }
                     92: 
1.1.1.2   root       93: /* Return 1 if OP is a constant in the range of 0-63 (for a shift) or
                     94:    any register.  */
                     95: 
                     96: int
                     97: reg_or_6bit_operand (op, mode)
                     98:      register rtx op;
                     99:      enum machine_mode mode;
                    100: {
                    101:   return ((GET_CODE (op) == CONST_INT
                    102:           && (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
                    103:          || register_operand (op, mode));
                    104: }
                    105: 
                    106: 
1.1       root      107: /* Return 1 if OP is an 8-bit constant or any register.  */
                    108: 
                    109: int
                    110: reg_or_8bit_operand (op, mode)
                    111:      register rtx op;
                    112:      enum machine_mode mode;
                    113: {
                    114:   return ((GET_CODE (op) == CONST_INT
                    115:           && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
                    116:          || register_operand (op, mode));
                    117: }
                    118: 
1.1.1.3 ! root      119: /* Return 1 if OP is an 8-bit constant.  */
        !           120: 
        !           121: int
        !           122: cint8_operand (op, mode)
        !           123:      register rtx op;
        !           124:      enum machine_mode mode;
        !           125: {
        !           126:   return (GET_CODE (op) == CONST_INT
        !           127:          && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100);
        !           128: }
        !           129: 
1.1       root      130: /* Return 1 if the operand is a valid second operand to an add insn.  */
                    131: 
                    132: int
                    133: add_operand (op, mode)
                    134:      register rtx op;
                    135:      enum machine_mode mode;
                    136: {
                    137:   if (GET_CODE (op) == CONST_INT)
                    138:     return ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) < 0x10000
                    139:            || ((INTVAL (op) & 0xffff) == 0
                    140:                && (INTVAL (op) >> 31 == -1
                    141:                    || INTVAL (op) >> 31 == 0)));
                    142: 
                    143:   return register_operand (op, mode);
                    144: }
                    145: 
                    146: /* Return 1 if the operand is a valid second operand to a sign-extending
                    147:    add insn.  */
                    148: 
                    149: int
                    150: sext_add_operand (op, mode)
                    151:      register rtx op;
                    152:      enum machine_mode mode;
                    153: {
                    154:   if (GET_CODE (op) == CONST_INT)
                    155:     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255
                    156:            || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255);
                    157: 
                    158:   return register_operand (op, mode);
                    159: }
                    160: 
                    161: /* Return 1 if OP is the constant 4 or 8.  */
                    162: 
                    163: int
                    164: const48_operand (op, mode)
                    165:      register rtx op;
                    166:      enum machine_mode mode;
                    167: {
                    168:   return (GET_CODE (op) == CONST_INT
                    169:          && (INTVAL (op) == 4 || INTVAL (op) == 8));
                    170: }
                    171: 
                    172: /* Return 1 if OP is a valid first operand to an AND insn.  */
                    173: 
                    174: int
                    175: and_operand (op, mode)
                    176:      register rtx op;
                    177:      enum machine_mode mode;
                    178: {
                    179:   if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
                    180:     return (zap_mask (CONST_DOUBLE_LOW (op))
                    181:            && zap_mask (CONST_DOUBLE_HIGH (op)));
                    182: 
                    183:   if (GET_CODE (op) == CONST_INT)
                    184:     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
                    185:            || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
                    186:            || zap_mask (INTVAL (op)));
                    187: 
                    188:   return register_operand (op, mode);
                    189: }
                    190: 
1.1.1.3 ! root      191: /* Return 1 if OP is a valid first operand to an IOR or XOR insn.  */
        !           192: 
        !           193: int
        !           194: or_operand (op, mode)
        !           195:      register rtx op;
        !           196:      enum machine_mode mode;
        !           197: {
        !           198:   if (GET_CODE (op) == CONST_INT)
        !           199:     return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
        !           200:            || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100);
        !           201: 
        !           202:   return register_operand (op, mode);
        !           203: }
        !           204: 
1.1       root      205: /* Return 1 if OP is a constant that is the width, in bits, of an integral
                    206:    mode smaller than DImode.  */
                    207: 
                    208: int
                    209: mode_width_operand (op, mode)
                    210:      register rtx op;
                    211:      enum machine_mode mode;
                    212: {
                    213:   return (GET_CODE (op) == CONST_INT
                    214:          && (INTVAL (op) == 8 || INTVAL (op) == 16 || INTVAL (op) == 32));
                    215: }
                    216: 
                    217: /* Return 1 if OP is a constant that is the width of an integral machine mode
                    218:    smaller than an integer.  */
                    219: 
                    220: int
                    221: mode_mask_operand (op, mode)
                    222:      register rtx op;
                    223:      enum machine_mode mode;
                    224: {
                    225: #if HOST_BITS_PER_WIDE_INT == 32
                    226:   if (GET_CODE (op) == CONST_DOUBLE)
                    227:     return CONST_DOUBLE_HIGH (op) == 0 && CONST_DOUBLE_LOW (op) == -1;
                    228: #endif
                    229: 
1.1.1.3 ! root      230:   return (GET_CODE (op) == CONST_INT
        !           231:          && (INTVAL (op) == 0xff
        !           232:              || INTVAL (op) == 0xffff
1.1       root      233: #if HOST_BITS_PER_WIDE_INT == 64
1.1.1.3 ! root      234:              || INTVAL (op) == 0xffffffff
1.1       root      235: #endif
1.1.1.3 ! root      236:              ));
1.1       root      237: }
                    238: 
                    239: /* Return 1 if OP is a multiple of 8 less than 64.  */
                    240: 
                    241: int
                    242: mul8_operand (op, mode)
                    243:      register rtx op;
                    244:      enum machine_mode mode;
                    245: {
                    246:   return (GET_CODE (op) == CONST_INT
                    247:          && (unsigned HOST_WIDE_INT) INTVAL (op) < 64
                    248:          && (INTVAL (op) & 7) == 0);
                    249: }
                    250: 
                    251: /* Return 1 if OP is the constant zero in floating-point.  */
                    252: 
                    253: int
                    254: fp0_operand (op, mode)
                    255:      register rtx op;
                    256:      enum machine_mode mode;
                    257: {
                    258:   return (GET_MODE (op) == mode
                    259:          && GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode));
                    260: }
                    261: 
                    262: /* Return 1 if OP is the floating-point constant zero or a register.  */
                    263: 
                    264: int
                    265: reg_or_fp0_operand (op, mode)
                    266:      register rtx op;
                    267:      enum machine_mode mode;
                    268: {
                    269:   return fp0_operand (op, mode) || register_operand (op, mode);
                    270: }
                    271: 
                    272: /* Return 1 if OP is a register or a constant integer.  */
                    273: 
                    274: 
                    275: int
                    276: reg_or_cint_operand (op, mode)
                    277:     register rtx op;
                    278:     enum machine_mode mode;
                    279: {
                    280:      return GET_CODE (op) == CONST_INT || register_operand (op, mode);
                    281: }
                    282: 
1.1.1.3 ! root      283: /* Return 1 if OP is something that can be reloaded into a register;
        !           284:    if it is a MEM, it need not be valid.  */
        !           285: 
        !           286: int
        !           287: some_operand (op, mode)
        !           288:      register rtx op;
        !           289:      enum machine_mode mode;
        !           290: {
        !           291:   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
        !           292:     return 0;
        !           293: 
        !           294:   switch (GET_CODE (op))
        !           295:     {
        !           296:     case REG:  case MEM:  case CONST_DOUBLE:
        !           297:     case CONST_INT:  case LABEL_REF:  case SYMBOL_REF:  case CONST:
        !           298:       return 1;
        !           299: 
        !           300:     case SUBREG:
        !           301:       return some_operand (SUBREG_REG (op), VOIDmode);
        !           302:     }
        !           303: 
        !           304:   return 0;
        !           305: }
        !           306: 
1.1       root      307: /* Return 1 if OP is a valid operand for the source of a move insn.  */
                    308: 
                    309: int
                    310: input_operand (op, mode)
                    311:      register rtx op;
                    312:      enum machine_mode mode;
                    313: {
                    314:   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
                    315:     return 0;
                    316: 
                    317:   if (GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE (op) != mode)
                    318:     return 0;
                    319: 
                    320:   switch (GET_CODE (op))
                    321:     {
                    322:     case LABEL_REF:
                    323:     case SYMBOL_REF:
                    324:     case CONST:
                    325:       return mode == DImode;
                    326: 
                    327:     case REG:
                    328:       return 1;
                    329: 
                    330:     case SUBREG:
                    331:       if (register_operand (op, mode))
                    332:        return 1;
                    333:       /* ... fall through ... */
                    334:     case MEM:
                    335:       return mode != HImode && mode != QImode && general_operand (op, mode);
                    336: 
                    337:     case CONST_DOUBLE:
                    338:       return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
                    339: 
                    340:     case CONST_INT:
                    341:       return mode == QImode || mode == HImode || add_operand (op, mode);
                    342:     }
                    343: 
                    344:   return 0;
                    345: }
                    346: 
                    347: /* Return 1 if OP is a SYMBOL_REF for a function known to be in this
                    348:    file.  */
                    349: 
                    350: int
                    351: current_file_function_operand (op, mode)
                    352:      rtx op;
                    353:      enum machine_mode mode;
                    354: {
                    355:   return (GET_CODE (op) == SYMBOL_REF
                    356:          && (SYMBOL_REF_FLAG (op)
                    357:              || op == XEXP (DECL_RTL (current_function_decl), 0)));
                    358: }
                    359: 
1.1.1.3 ! root      360: /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
        !           361: 
        !           362: int
        !           363: call_operand (op, mode)
        !           364:      rtx op;
        !           365:      enum machine_mode mode;
        !           366: {
        !           367:   if (mode != Pmode)
        !           368:     return 0;
        !           369: 
        !           370:   return (GET_CODE (op) == SYMBOL_REF
        !           371:          || (GET_CODE (op) == REG && REGNO (op) == 27));
        !           372: }
        !           373: 
1.1       root      374: /* Return 1 if OP is a valid Alpha comparison operator.  Here we know which
                    375:    comparisons are valid in which insn.  */
                    376: 
                    377: int
                    378: alpha_comparison_operator (op, mode)
                    379:      register rtx op;
                    380:      enum machine_mode mode;
                    381: {
                    382:   enum rtx_code code = GET_CODE (op);
                    383: 
                    384:   if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<')
                    385:     return 0;
                    386: 
                    387:   return (code == EQ || code == LE || code == LT
                    388:          || (mode == DImode && (code == LEU || code == LTU)));
                    389: }
                    390: 
                    391: /* Return 1 if OP is a signed comparison operation.  */
                    392: 
                    393: int
                    394: signed_comparison_operator (op, mode)
                    395:      register rtx op;
                    396:      enum machine_mode mode;
                    397: {
                    398:   switch (GET_CODE (op))
                    399:     {
                    400:     case EQ:  case NE:  case LE:  case LT:  case GE:   case GT:
                    401:       return 1;
                    402:     }
                    403: 
                    404:   return 0;
                    405: }
                    406: 
                    407: /* Return 1 if this is a divide or modulus operator.  */
                    408: 
                    409: int
                    410: divmod_operator (op, mode)
                    411:      register rtx op;
                    412:      enum machine_mode mode;
                    413: {
                    414:   switch (GET_CODE (op))
                    415:     {
                    416:     case DIV:  case MOD:  case UDIV:  case UMOD:
                    417:       return 1;
                    418:     }
                    419: 
                    420:   return 0;
                    421: }
                    422: 
                    423: /* Return 1 if this memory address is a known aligned register plus
                    424:    a constant.  It must be a valid address.  This means that we can do
                    425:    this as an aligned reference plus some offset.
                    426: 
                    427:    Take into account what reload will do.
                    428: 
                    429:    We could say that out-of-range stack slots are alignable, but that would
                    430:    complicate get_aligned_mem and it isn't worth the trouble since few
                    431:    functions have large stack space.  */
                    432: 
                    433: int
                    434: aligned_memory_operand (op, mode)
                    435:      register rtx op;
                    436:      enum machine_mode mode;
                    437: {
                    438:   if (GET_CODE (op) == SUBREG)
                    439:     {
                    440:       if (GET_MODE (op) != mode)
                    441:        return 0;
                    442:       op = SUBREG_REG (op);
                    443:       mode = GET_MODE (op);
                    444:     }
                    445: 
                    446:   if (reload_in_progress && GET_CODE (op) == REG
                    447:       && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                    448:     op = reg_equiv_mem[REGNO (op)];
                    449: 
                    450:   if (GET_CODE (op) != MEM || GET_MODE (op) != mode
                    451:       || ! memory_address_p (mode, XEXP (op, 0)))
                    452:     return 0;
                    453: 
                    454:   op = XEXP (op, 0);
                    455: 
                    456:   if (GET_CODE (op) == PLUS)
                    457:     op = XEXP (op, 0);
                    458: 
                    459:   return (GET_CODE (op) == REG
1.1.1.3 ! root      460:          && (REGNO (op) == STACK_POINTER_REGNUM
        !           461:              || op == hard_frame_pointer_rtx
1.1       root      462:              || (REGNO (op) >= FIRST_VIRTUAL_REGISTER
                    463:                  && REGNO (op) <= LAST_VIRTUAL_REGISTER)));
                    464: }
                    465: 
                    466: /* Similar, but return 1 if OP is a MEM which is not alignable.  */
                    467: 
                    468: int
                    469: unaligned_memory_operand (op, mode)
                    470:      register rtx op;
                    471:      enum machine_mode mode;
                    472: {
                    473:   if (GET_CODE (op) == SUBREG)
                    474:     {
                    475:       if (GET_MODE (op) != mode)
                    476:        return 0;
                    477:       op = SUBREG_REG (op);
                    478:       mode = GET_MODE (op);
                    479:     }
                    480: 
                    481:   if (reload_in_progress && GET_CODE (op) == REG
                    482:       && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                    483:     op = reg_equiv_mem[REGNO (op)];
                    484: 
                    485:   if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
                    486:     return 0;
                    487: 
                    488:   op = XEXP (op, 0);
                    489: 
                    490:   if (! memory_address_p (mode, op))
                    491:     return 1;
                    492: 
                    493:   if (GET_CODE (op) == PLUS)
                    494:     op = XEXP (op, 0);
                    495: 
                    496:   return (GET_CODE (op) != REG
1.1.1.3 ! root      497:          || (REGNO (op) != STACK_POINTER_REGNUM
        !           498:              && op != hard_frame_pointer_rtx
1.1       root      499:              && (REGNO (op) < FIRST_VIRTUAL_REGISTER
                    500:                  || REGNO (op) > LAST_VIRTUAL_REGISTER)));
                    501: }
                    502: 
                    503: /* Return 1 if OP is any memory location.  During reload a pseudo matches.  */
                    504: 
                    505: int
                    506: any_memory_operand (op, mode)
                    507:      register rtx op;
                    508:      enum machine_mode mode;
                    509: {
                    510:   return (GET_CODE (op) == MEM
                    511:          || (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
                    512:          || (reload_in_progress && GET_CODE (op) == REG
                    513:              && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                    514:          || (reload_in_progress && GET_CODE (op) == SUBREG
                    515:              && GET_CODE (SUBREG_REG (op)) == REG
                    516:              && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER));
                    517: }
                    518: 
                    519: /* REF is an alignable memory location.  Place an aligned SImode
                    520:    reference into *PALIGNED_MEM and the number of bits to shift into
                    521:    *PBITNUM.  */
                    522: 
                    523: void
                    524: get_aligned_mem (ref, paligned_mem, pbitnum)
                    525:      rtx ref;
                    526:      rtx *paligned_mem, *pbitnum;
                    527: {
                    528:   rtx base;
                    529:   HOST_WIDE_INT offset = 0;
                    530: 
                    531:   if (GET_CODE (ref) == SUBREG)
                    532:     {
                    533:       offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
                    534:       if (BYTES_BIG_ENDIAN)
                    535:        offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
                    536:                   - MIN (UNITS_PER_WORD,
                    537:                          GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
                    538:       ref = SUBREG_REG (ref);
                    539:     }
                    540: 
                    541:   if (GET_CODE (ref) == REG)
                    542:     ref = reg_equiv_mem[REGNO (ref)];
                    543: 
                    544:   if (reload_in_progress)
                    545:     base = find_replacement (&XEXP (ref, 0));
                    546:   else
                    547:     base = XEXP (ref, 0);
                    548: 
                    549:   if (GET_CODE (base) == PLUS)
                    550:     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
                    551: 
                    552:   *paligned_mem = gen_rtx (MEM, SImode,
                    553:                           plus_constant (base, offset & ~3));
                    554:   MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref);
                    555:   MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref);
                    556:   RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref);
                    557: 
                    558:   *pbitnum = GEN_INT ((offset & 3) * 8);
                    559: }
                    560: 
                    561: /* Similar, but just get the address.  Handle the two reload cases.  */
                    562: 
                    563: rtx
                    564: get_unaligned_address (ref)
                    565:      rtx ref;
                    566: {
                    567:   rtx base;
                    568:   HOST_WIDE_INT offset = 0;
                    569: 
                    570:   if (GET_CODE (ref) == SUBREG)
                    571:     {
                    572:       offset = SUBREG_WORD (ref) * UNITS_PER_WORD;
                    573:       if (BYTES_BIG_ENDIAN)
                    574:        offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref)))
                    575:                   - MIN (UNITS_PER_WORD,
                    576:                          GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref)))));
                    577:       ref = SUBREG_REG (ref);
                    578:     }
                    579: 
                    580:   if (GET_CODE (ref) == REG)
                    581:     ref = reg_equiv_mem[REGNO (ref)];
                    582: 
                    583:   if (reload_in_progress)
                    584:     base = find_replacement (&XEXP (ref, 0));
                    585:   else
                    586:     base = XEXP (ref, 0);
                    587: 
                    588:   if (GET_CODE (base) == PLUS)
                    589:     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
                    590: 
                    591:   return plus_constant (base, offset);
                    592: }
                    593: 
                    594: /* Subfunction of the following function.  Update the flags of any MEM
                    595:    found in part of X.  */
                    596: 
                    597: static void
                    598: alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
                    599:      rtx x;
                    600:      int in_struct_p, volatile_p, unchanging_p;
                    601: {
                    602:   int i;
                    603: 
                    604:   switch (GET_CODE (x))
                    605:     {
                    606:     case SEQUENCE:
                    607:     case PARALLEL:
                    608:       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
                    609:        alpha_set_memflags_1 (XVECEXP (x, 0, i), in_struct_p, volatile_p,
                    610:                              unchanging_p);
                    611:       break;
                    612: 
                    613:     case INSN:
                    614:       alpha_set_memflags_1 (PATTERN (x), in_struct_p, volatile_p,
                    615:                            unchanging_p);
                    616:       break;
                    617: 
                    618:     case SET:
                    619:       alpha_set_memflags_1 (SET_DEST (x), in_struct_p, volatile_p,
                    620:                            unchanging_p);
                    621:       alpha_set_memflags_1 (SET_SRC (x), in_struct_p, volatile_p,
                    622:                            unchanging_p);
                    623:       break;
                    624: 
                    625:     case MEM:
                    626:       MEM_IN_STRUCT_P (x) = in_struct_p;
                    627:       MEM_VOLATILE_P (x) = volatile_p;
                    628:       RTX_UNCHANGING_P (x) = unchanging_p;
                    629:       break;
                    630:     }
                    631: }
                    632: 
                    633: /* Given INSN, which is either an INSN or a SEQUENCE generated to
                    634:    perform a memory operation, look for any MEMs in either a SET_DEST or
                    635:    a SET_SRC and copy the in-struct, unchanging, and volatile flags from
                    636:    REF into each of the MEMs found.  If REF is not a MEM, don't do
                    637:    anything.  */
                    638: 
                    639: void
                    640: alpha_set_memflags (insn, ref)
                    641:      rtx insn;
                    642:      rtx ref;
                    643: {
                    644:   /* Note that it is always safe to get these flags, though they won't
                    645:      be what we think if REF is not a MEM.  */
                    646:   int in_struct_p = MEM_IN_STRUCT_P (ref);
                    647:   int volatile_p = MEM_VOLATILE_P (ref);
                    648:   int unchanging_p = RTX_UNCHANGING_P (ref);
                    649: 
                    650:   if (GET_CODE (ref) != MEM
                    651:       || (! in_struct_p && ! volatile_p && ! unchanging_p))
                    652:     return;
                    653: 
                    654:   alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
                    655: }
                    656: 
                    657: /* Try to output insns to set TARGET equal to the constant C if it can be
                    658:    done in less than N insns.  Returns 1 if it can be done and the
                    659:    insns have been emitted.  If it would take more than N insns, zero is
                    660:    returned and no insns and emitted.  */
                    661: 
                    662: int
                    663: alpha_emit_set_const (target, c, n)
                    664:      rtx target;
                    665:      HOST_WIDE_INT c;
                    666:      int n;
                    667: {
                    668:   HOST_WIDE_INT new = c;
                    669:   int i, bits;
                    670: 
                    671: #if HOST_BITS_PER_WIDE_INT == 64
                    672:   /* We are only called for SImode and DImode.  If this is SImode, ensure that
                    673:      we are sign extended to a full word.  This does not make any sense when
                    674:      cross-compiling on a narrow machine.  */
                    675: 
                    676:   if (GET_MODE (target) == SImode)
                    677:     c = (c & 0xffffffff) - 2 * (c & 0x80000000);
                    678: #endif
                    679: 
                    680:   /* If this is a sign-extended 32-bit constant, we can do this in at most
                    681:      three insns, so do it if we have enough insns left.  We always have
                    682:      a sign-extended 32-bit constant when compiling on a narrow machine.  */
                    683: 
                    684:   if (HOST_BITS_PER_WIDE_INT != 64
                    685:       || c >> 31 == -1 || c >> 31 == 0)
                    686:     {
                    687:       HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
                    688:       HOST_WIDE_INT tmp1 = c - low;
                    689:       HOST_WIDE_INT high
                    690:        = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
                    691:       HOST_WIDE_INT extra = 0;
                    692: 
                    693:       /* If HIGH will be interpreted as negative but the constant is
                    694:         positive, we must adjust it to do two ldha insns.  */
                    695: 
                    696:       if ((high & 0x8000) != 0 && c >= 0)
                    697:        {
                    698:          extra = 0x4000;
                    699:          tmp1 -= 0x40000000;
                    700:          high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
                    701:        }
                    702: 
                    703:       if (c == low || (low == 0 && extra == 0))
                    704:        {
                    705:          emit_move_insn (target, GEN_INT (c));
                    706:          return 1;
                    707:        }
                    708:       else if (n >= 2 + (extra != 0))
                    709:        {
                    710:          emit_move_insn (target, GEN_INT (low));
                    711:          if (extra != 0)
                    712:            emit_insn (gen_add2_insn (target, GEN_INT (extra << 16)));
                    713: 
                    714:          emit_insn (gen_add2_insn (target, GEN_INT (high << 16)));
                    715:          return 1;
                    716:        }
                    717:     }
                    718: 
                    719:   /* If we couldn't do it that way, try some other methods (that depend on
                    720:      being able to compute in the target's word size).  But if we have no
                    721:      instructions left, don't bother.  Also, don't even try if this is 
                    722:      SImode (in which case we should have already done something, but
                    723:      do a sanity check here).  */
                    724: 
                    725:   if (n == 1 || HOST_BITS_PER_WIDE_INT < 64 || GET_MODE (target) != DImode)
                    726:     return 0;
                    727: 
                    728:   /* First, see if can load a value into the target that is the same as the
                    729:      constant except that all bytes that are 0 are changed to be 0xff.  If we
                    730:      can, then we can do a ZAPNOT to obtain the desired constant.  */
                    731: 
                    732:   for (i = 0; i < 64; i += 8)
                    733:     if ((new & ((HOST_WIDE_INT) 0xff << i)) == 0)
                    734:       new |= (HOST_WIDE_INT) 0xff << i;
                    735: 
                    736:   if (alpha_emit_set_const (target, new, n - 1))
                    737:     {
                    738:       emit_insn (gen_anddi3 (target, target, GEN_INT (c | ~ new)));
                    739:       return 1;
                    740:     }
                    741: 
                    742:   /* Find, see if we can load a related constant and then shift and possibly
                    743:      negate it to get the constant we want.  Try this once each increasing
                    744:      numbers of insns.  */
                    745: 
                    746:   for (i = 1; i < n; i++)
                    747:     {
                    748:       /* First try complementing.  */
                    749:       if (alpha_emit_set_const (target, ~ c, i))
                    750:        {
                    751:          emit_insn (gen_one_cmpldi2 (target, target));
                    752:          return 1;
                    753:        }
                    754: 
                    755:       /* First try to form a constant and do a left shift.  We can do this
                    756:         if some low-order bits are zero; the exact_log2 call below tells
                    757:         us that information.  The bits we are shifting out could be any
                    758:         value, but here we'll just try the 0- and sign-extended forms of
                    759:         the constant.  To try to increase the chance of having the same
                    760:         constant in more than one insn, start at the highest number of
                    761:         bits to shift, but try all possibilities in case a ZAPNOT will
                    762:         be useful.  */
                    763: 
                    764:       if ((bits = exact_log2 (c & - c)) > 0)
                    765:        for (; bits > 0; bits--)
                    766:          if (alpha_emit_set_const (target, c >> bits, i)
                    767:              || alpha_emit_set_const (target,
                    768:                                       ((unsigned HOST_WIDE_INT) c) >> bits,
                    769:                                       i))
                    770:            {
                    771:              emit_insn (gen_ashldi3 (target, target, GEN_INT (bits)));
                    772:              return 1;
                    773:            }
                    774: 
                    775:       /* Now try high-order zero bits.  Here we try the shifted-in bits as
                    776:         all zero and all ones.  */
                    777: 
                    778:       if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (c) - 1) > 0)
                    779:        for (; bits > 0; bits--)
                    780:          if (alpha_emit_set_const (target, c << bits, i)
                    781:              || alpha_emit_set_const (target,
                    782:                                       ((c << bits)
                    783:                                        | (((HOST_WIDE_INT) 1 << bits) - 1)),
                    784:                                       i))
                    785:            {
                    786:              emit_insn (gen_lshrdi3 (target, target, GEN_INT (bits)));
                    787:              return 1;
                    788:            }
                    789: 
                    790:       /* Now try high-order 1 bits.  We get that with a sign-extension.
                    791:         But one bit isn't enough here.  */
                    792:       
                    793:       if ((bits = HOST_BITS_PER_WIDE_INT - floor_log2 (~ c) - 2) > 0)
                    794:        for (; bits > 0; bits--)
                    795:          if (alpha_emit_set_const (target, c << bits, i)
                    796:              || alpha_emit_set_const (target,
                    797:                                       ((c << bits)
                    798:                                        | (((HOST_WIDE_INT) 1 << bits) - 1)),
                    799:                                       i))
                    800:            {
                    801:              emit_insn (gen_ashrdi3 (target, target, GEN_INT (bits)));
                    802:              return 1;
                    803:            }
                    804:     }
                    805: 
                    806:   return 0;
                    807: }
                    808: 
                    809: /* Adjust the cost of a scheduling dependency.  Return the new cost of
                    810:    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
                    811: 
                    812: int
                    813: alpha_adjust_cost (insn, link, dep_insn, cost)
                    814:      rtx insn;
                    815:      rtx link;
                    816:      rtx dep_insn;
                    817:      int cost;
                    818: {
                    819:   rtx set;
                    820: 
                    821:   /* If the dependence is an anti-dependence, there is no cost.  For an
                    822:      output dependence, there is sometimes a cost, but it doesn't seem
                    823:      worth handling those few cases.  */
                    824: 
                    825:   if (REG_NOTE_KIND (link) != 0)
                    826:     return 0;
                    827: 
                    828:   /* If INSN is a store insn and DEP_INSN is setting the data being stored,
                    829:      we can sometimes lower the cost.  */
                    830: 
                    831:   if (recog_memoized (insn) >= 0 && get_attr_type (insn) == TYPE_ST
                    832:       && (set = single_set (dep_insn)) != 0
                    833:       && GET_CODE (PATTERN (insn)) == SET
                    834:       && rtx_equal_p (SET_DEST (set), SET_SRC (PATTERN (insn))))
                    835:     switch (get_attr_type (dep_insn))
                    836:       {
                    837:       case TYPE_LD:
                    838:        /* No savings here.  */
                    839:        return cost;
                    840: 
                    841:       case TYPE_IMULL:
                    842:       case TYPE_IMULQ:
                    843:        /* In these cases, we save one cycle.  */
                    844:        return cost - 2;
                    845: 
                    846:       default:
                    847:        /* In all other cases, we save two cycles.  */
                    848:        return MAX (0, cost - 4);
                    849:       }
                    850: 
                    851:   /* Another case that needs adjustment is an arithmetic or logical
                    852:      operation.  It's cost is usually one cycle, but we default it to
                    853:      two in the MD file.  The only case that it is actually two is
                    854:      for the address in loads and stores.  */
                    855: 
                    856:   if (recog_memoized (dep_insn) >= 0
                    857:       && get_attr_type (dep_insn) == TYPE_IADDLOG)
                    858:     switch (get_attr_type (insn))
                    859:       {
                    860:       case TYPE_LD:
                    861:       case TYPE_ST:
                    862:        return cost;
                    863: 
                    864:       default:
                    865:        return 2;
                    866:       }
                    867: 
                    868:   /* The final case is when a compare feeds into an integer branch.  The cost
                    869:      is only one cycle in that case.  */
                    870: 
                    871:   if (recog_memoized (dep_insn) >= 0
                    872:       && get_attr_type (dep_insn) == TYPE_ICMP
                    873:       && recog_memoized (insn) >= 0
                    874:       && get_attr_type (insn) == TYPE_IBR)
                    875:     return 2;
                    876: 
                    877:   /* Otherwise, return the default cost. */
                    878: 
                    879:   return cost;
                    880: }
                    881: 
                    882: /* Print an operand.  Recognize special options, documented below.  */
                    883: 
                    884: void
                    885: print_operand (file, x, code)
                    886:     FILE *file;
                    887:     rtx x;
                    888:     char code;
                    889: {
                    890:   int i;
                    891: 
                    892:   switch (code)
                    893:     {
                    894:     case 'r':
                    895:       /* If this operand is the constant zero, write it as "$31".  */
                    896:       if (GET_CODE (x) == REG)
                    897:        fprintf (file, "%s", reg_names[REGNO (x)]);
                    898:       else if (x == CONST0_RTX (GET_MODE (x)))
                    899:        fprintf (file, "$31");
                    900:       else
                    901:        output_operand_lossage ("invalid %%r value");
                    902: 
                    903:       break;
                    904: 
                    905:     case 'R':
                    906:       /* Similar, but for floating-point.  */
                    907:       if (GET_CODE (x) == REG)
                    908:        fprintf (file, "%s", reg_names[REGNO (x)]);
                    909:       else if (x == CONST0_RTX (GET_MODE (x)))
                    910:        fprintf (file, "$f31");
                    911:       else
                    912:        output_operand_lossage ("invalid %%R value");
                    913: 
                    914:       break;
                    915: 
                    916:     case 'N':
                    917:       /* Write the 1's complement of a constant.  */
                    918:       if (GET_CODE (x) != CONST_INT)
                    919:        output_operand_lossage ("invalid %%N value");
                    920: 
                    921:       fprintf (file, "%ld", ~ INTVAL (x));
                    922:       break;
                    923: 
                    924:     case 'P':
                    925:       /* Write 1 << C, for a constant C.  */
                    926:       if (GET_CODE (x) != CONST_INT)
                    927:        output_operand_lossage ("invalid %%P value");
                    928: 
                    929:       fprintf (file, "%ld", (HOST_WIDE_INT) 1 << INTVAL (x));
                    930:       break;
                    931: 
                    932:     case 'h':
                    933:       /* Write the high-order 16 bits of a constant, sign-extended.  */
                    934:       if (GET_CODE (x) != CONST_INT)
                    935:        output_operand_lossage ("invalid %%h value");
                    936: 
                    937:       fprintf (file, "%ld", INTVAL (x) >> 16);
                    938:       break;
                    939: 
                    940:     case 'L':
                    941:       /* Write the low-order 16 bits of a constant, sign-extended.  */
                    942:       if (GET_CODE (x) != CONST_INT)
                    943:        output_operand_lossage ("invalid %%L value");
                    944: 
                    945:       fprintf (file, "%ld", (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
                    946:       break;
                    947: 
                    948:     case 'm':
                    949:       /* Write mask for ZAP insn.  */
                    950:       if (GET_CODE (x) == CONST_DOUBLE)
                    951:        {
                    952:          HOST_WIDE_INT mask = 0;
                    953:          HOST_WIDE_INT value;
                    954: 
                    955:          value = CONST_DOUBLE_LOW (x);
                    956:          for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
                    957:               i++, value >>= 8)
                    958:            if (value & 0xff)
                    959:              mask |= (1 << i);
                    960: 
                    961:          value = CONST_DOUBLE_HIGH (x);
                    962:          for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
                    963:               i++, value >>= 8)
                    964:            if (value & 0xff)
                    965:              mask |= (1 << (i + sizeof (int)));
                    966: 
                    967:          fprintf (file, "%ld", mask & 0xff);
                    968:        }
                    969: 
                    970:       else if (GET_CODE (x) == CONST_INT)
                    971:        {
                    972:          HOST_WIDE_INT mask = 0, value = INTVAL (x);
                    973: 
                    974:          for (i = 0; i < 8; i++, value >>= 8)
                    975:            if (value & 0xff)
                    976:              mask |= (1 << i);
                    977: 
                    978:          fprintf (file, "%ld", mask);
                    979:        }
                    980:       else
                    981:        output_operand_lossage ("invalid %%m value");
                    982:       break;
                    983: 
                    984:     case 'M':
                    985:       /* 'b', 'w', or 'l' as the value of the constant.  */
                    986:       if (GET_CODE (x) != CONST_INT
                    987:          || (INTVAL (x) != 8 && INTVAL (x) != 16 && INTVAL (x) != 32))
                    988:        output_operand_lossage ("invalid %%M value");
                    989: 
                    990:       fprintf (file, "%s",
                    991:               INTVAL (x) == 8 ? "b" : INTVAL (x) == 16 ? "w" : "l");
                    992:       break;
                    993: 
                    994:     case 'U':
                    995:       /* Similar, except do it from the mask.  */
                    996:       if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xff)
                    997:        fprintf (file, "b");
                    998:       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffff)
                    999:        fprintf (file, "w");
                   1000: #if HOST_BITS_PER_WIDE_INT == 32
                   1001:       else if (GET_CODE (x) == CONST_DOUBLE
                   1002:               && CONST_DOUBLE_HIGH (x) == 0
                   1003:               && CONST_DOUBLE_LOW (x) == -1)
                   1004:        fprintf (file, "l");
                   1005: #else
                   1006:       else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffff)
                   1007:        fprintf (file, "l");
                   1008: #endif
                   1009:       else
                   1010:        output_operand_lossage ("invalid %%U value");
                   1011:       break;
                   1012: 
                   1013:     case 's':
                   1014:       /* Write the constant value divided by 8.  */
                   1015:       if (GET_CODE (x) != CONST_INT
                   1016:          && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
                   1017:          && (INTVAL (x) & 7) != 8)
                   1018:        output_operand_lossage ("invalid %%s value");
                   1019: 
                   1020:       fprintf (file, "%ld", INTVAL (x) / 8);
                   1021:       break;
                   1022: 
                   1023:     case 'S':
                   1024:       /* Same, except compute (64 - c) / 8 */
                   1025: 
                   1026:       if (GET_CODE (x) != CONST_INT
                   1027:          && (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
                   1028:          && (INTVAL (x) & 7) != 8)
                   1029:        output_operand_lossage ("invalid %%s value");
                   1030: 
                   1031:       fprintf (file, "%ld", (64 - INTVAL (x)) / 8);
                   1032:       break;
                   1033: 
                   1034:     case 'C':
                   1035:       /* Write out comparison name.  */
                   1036:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
                   1037:        output_operand_lossage ("invalid %%C value");
                   1038: 
                   1039:       if (GET_CODE (x) == LEU)
                   1040:        fprintf (file, "ule");
                   1041:       else if (GET_CODE (x) == LTU)
                   1042:        fprintf (file, "ult");
                   1043:       else
                   1044:        fprintf (file, "%s", GET_RTX_NAME (GET_CODE (x)));
                   1045:       break;
                   1046: 
                   1047:     case 'D':
                   1048:       /* Similar, but write reversed code.  We can't get an unsigned code
                   1049:         here.  */
                   1050:       if (GET_RTX_CLASS (GET_CODE (x)) != '<')
                   1051:        output_operand_lossage ("invalid %%D value");
                   1052: 
                   1053:       fprintf (file, "%s", GET_RTX_NAME (reverse_condition (GET_CODE (x))));
                   1054:       break;
                   1055: 
                   1056:     case 'E':
                   1057:       /* Write the divide or modulus operator.  */
                   1058:       switch (GET_CODE (x))
                   1059:        {
                   1060:        case DIV:
                   1061:          fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
                   1062:          break;
                   1063:        case UDIV:
                   1064:          fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
                   1065:          break;
                   1066:        case MOD:
                   1067:          fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
                   1068:          break;
                   1069:        case UMOD:
                   1070:          fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
                   1071:          break;
                   1072:        default:
                   1073:          output_operand_lossage ("invalid %%E value");
                   1074:          break;
                   1075:        }
                   1076:       break;
                   1077: 
                   1078:     case 'A':
                   1079:       /* Write "_u" for unaligned access.  */
                   1080:       if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == AND)
                   1081:        fprintf (file, "_u");
                   1082:       break;
                   1083: 
                   1084:     case 0:
                   1085:       if (GET_CODE (x) == REG)
                   1086:        fprintf (file, "%s", reg_names[REGNO (x)]);
                   1087:       else if (GET_CODE (x) == MEM)
                   1088:        output_address (XEXP (x, 0));
                   1089:       else
                   1090:        output_addr_const (file, x);
                   1091:       break;
                   1092: 
                   1093:     default:
                   1094:       output_operand_lossage ("invalid %%xn code");
                   1095:     }
                   1096: }
                   1097: 
                   1098: /* Do what is necessary for `va_start'.  The argument is ignored;
                   1099:    We look at the current function to determine if stdarg or varargs
                   1100:    is used and fill in an initial va_list.  A pointer to this constructor
                   1101:    is returned.  */
                   1102: 
                   1103: struct rtx_def *
                   1104: alpha_builtin_saveregs (arglist)
                   1105:      tree arglist;
                   1106: {
                   1107:   rtx block, addr, argsize;
                   1108:   tree fntype = TREE_TYPE (current_function_decl);
                   1109:   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
                   1110:                && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
                   1111:                    != void_type_node));
                   1112: 
                   1113:   /* Compute the current position into the args, taking into account
1.1.1.3 ! root     1114:      both registers and memory.  Both of these are already included in
        !          1115:      current_function_args_info.  */
        !          1116: 
        !          1117:   argsize = GEN_INT (current_function_args_info * UNITS_PER_WORD);
1.1       root     1118: 
1.1.1.3 ! root     1119:   /* SETUP_INCOMING_VARARGS moves the starting address base up by 48,
        !          1120:      storing fp arg registers in the first 48 bytes, and the integer arg
        !          1121:      registers in the next 48 bytes.  This is only done, however, if any
        !          1122:      integer registers need to be stored.
        !          1123: 
        !          1124:      If no integer registers need be stored, then we must subtract 48 in
        !          1125:      order to account for the integer arg registers which are counted in
        !          1126:      argsize above, but which are not actually stored on the stack.  */
        !          1127: 
        !          1128:   addr = (current_function_args_info <= 6
        !          1129:          ? plus_constant (virtual_incoming_args_rtx, 6 * UNITS_PER_WORD)
        !          1130:          : plus_constant (virtual_incoming_args_rtx, - (6 * UNITS_PER_WORD)));
1.1       root     1131: 
                   1132:   /* Allocate the va_list constructor */
                   1133:   block = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
                   1134:   RTX_UNCHANGING_P (block) = 1;
                   1135:   RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
                   1136: 
                   1137:   /* Store the address of the first integer register in the
1.1.1.3 ! root     1138:      __va_base member.  */
        !          1139:   emit_move_insn (change_address (block, Pmode, XEXP (block, 0)),
        !          1140:                  force_operand (addr, NULL_RTX));
1.1       root     1141: 
                   1142:   /* Store the argsize as the __va_offset member.  */
                   1143:   emit_move_insn (change_address (block, Pmode,
                   1144:                                  plus_constant (XEXP (block, 0),
                   1145:                                                 UNITS_PER_WORD)),
                   1146:                  force_operand (argsize, NULL_RTX));
                   1147: 
                   1148:   /* Return the address of the va_list constructor, but don't put it in a
                   1149:      register.  Doing so would fail when not optimizing and produce worse
                   1150:      code when optimizing.  */
                   1151:   return XEXP (block, 0);
                   1152: }
                   1153: 
                   1154: /* This page contains routines that are used to determine what the function
                   1155:    prologue and epilogue code will do and write them out.  */
                   1156: 
                   1157: /* Compute the size of the save area in the stack.  */
                   1158: 
                   1159: int
                   1160: alpha_sa_size ()
                   1161: {
                   1162:   int size = 0;
                   1163:   int i;
                   1164: 
                   1165:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                   1166:     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
                   1167:       size++;
                   1168: 
                   1169:   /* If some registers were saved but not reg 26, reg 26 must also
                   1170:      be saved, so leave space for it.  */
                   1171:   if (size != 0 && ! regs_ever_live[26])
                   1172:     size++;
                   1173: 
1.1.1.3 ! root     1174:   /* Our size must be even (multiple of 16 bytes).  */
        !          1175:   if (size & 1)
        !          1176:     size ++;
        !          1177: 
1.1       root     1178:   return size * 8;
                   1179: }
                   1180: 
                   1181: /* Return 1 if this function can directly return via $26.  */
                   1182: 
                   1183: int
                   1184: direct_return ()
                   1185: {
                   1186:   return (reload_completed && alpha_sa_size () == 0
                   1187:          && get_frame_size () == 0
                   1188:          && current_function_pretend_args_size == 0);
                   1189: }
                   1190: 
                   1191: /* Write a version stamp.  Don't write anything if we are running as a
                   1192:    cross-compiler.  Otherwise, use the versions in /usr/include/stamp.h.  */
                   1193: 
                   1194: #ifndef CROSS_COMPILE
                   1195: #include <stamp.h>
                   1196: #endif
                   1197: 
                   1198: void
                   1199: alpha_write_verstamp (file)
                   1200:      FILE *file;
                   1201: {
                   1202: #ifdef MS_STAMP
                   1203:   char *p;
                   1204: 
                   1205:   fprintf (file, "\t.verstamp %d %d ", MS_STAMP, LS_STAMP);
                   1206:   for (p = version_string; *p != ' ' && *p != 0; p++)
                   1207:     fprintf (file, "%c", *p == '.' ? ' ' : *p);
                   1208:   fprintf (file, "\n");
                   1209: #endif
                   1210: }
1.1.1.2   root     1211: 
                   1212: /* Write code to add constant C to register number IN_REG (possibly 31)
1.1.1.3 ! root     1213:    and put the result into OUT_REG.  Use TEMP_REG as a scratch register;
        !          1214:    usually this will be OUT_REG, but should not be if OUT_REG is 
        !          1215:    STACK_POINTER_REGNUM, since it must be updated in a single instruction.
        !          1216:    Write the code to FILE.  */
1.1.1.2   root     1217: 
                   1218: static void
1.1.1.3 ! root     1219: add_long_const (file, c, in_reg, out_reg, temp_reg)
1.1.1.2   root     1220:      FILE *file;
1.1.1.3 ! root     1221:      HOST_WIDE_INT c;
        !          1222:      int in_reg, out_reg, temp_reg;
1.1.1.2   root     1223: {
                   1224:   HOST_WIDE_INT low = (c & 0xffff) - 2 * (c & 0x8000);
                   1225:   HOST_WIDE_INT tmp1 = c - low;
                   1226:   HOST_WIDE_INT high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
                   1227:   HOST_WIDE_INT extra = 0;
                   1228: 
                   1229:   /* We don't have code to write out constants larger than 32 bits.  */
                   1230: #if HOST_BITS_PER_LONG_INT == 64
                   1231:   if ((unsigned HOST_WIDE_INT) c >> 32 != 0)
                   1232:     abort ();
                   1233: #endif
                   1234: 
                   1235:   /* If HIGH will be interpreted as negative, we must adjust it to do two
                   1236:      ldha insns.  Note that we will never be building a negative constant
                   1237:      here.  */
                   1238: 
                   1239:   if (high & 0x8000)
                   1240:     {
                   1241:       extra = 0x4000;
                   1242:       tmp1 -= 0x40000000;
                   1243:       high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
                   1244:     }
                   1245: 
                   1246:   if (low != 0)
                   1247:     {
1.1.1.3 ! root     1248:       int result_reg = (extra == 0 && high == 0) ? out_reg : temp_reg;
        !          1249: 
1.1.1.2   root     1250:       if (low >= 0 && low < 255)
1.1.1.3 ! root     1251:        fprintf (file, "\taddq $%d,%d,$%d\n", in_reg, low, result_reg);
1.1.1.2   root     1252:       else
1.1.1.3 ! root     1253:        fprintf (file, "\tlda $%d,%d($%d)\n", result_reg, low, in_reg);
        !          1254: 
        !          1255:       in_reg = result_reg;
1.1.1.2   root     1256:     }
                   1257: 
                   1258:   if (extra)
                   1259:     {
1.1.1.3 ! root     1260:       int result_reg = (high == 0) ? out_reg : temp_reg;
        !          1261: 
        !          1262:       fprintf (file, "\tldah $%d,%d($%d)\n", result_reg, extra, in_reg);
        !          1263:       in_reg = result_reg;
1.1.1.2   root     1264:     }
                   1265: 
                   1266:   if (high)
                   1267:     fprintf (file, "\tldah $%d,%d($%d)\n", out_reg, high, in_reg);
                   1268: }
1.1       root     1269: 
                   1270: /* Write function prologue.  */
                   1271: 
                   1272: void
                   1273: output_prolog (file, size)
                   1274:      FILE *file;
                   1275:      int size;
                   1276: {
1.1.1.3 ! root     1277:   HOST_WIDE_INT out_args_size
        !          1278:     = ALPHA_ROUND (current_function_outgoing_args_size);
        !          1279:   HOST_WIDE_INT sa_size = alpha_sa_size ();
        !          1280:   HOST_WIDE_INT frame_size
        !          1281:     = (out_args_size + sa_size
        !          1282:        + ALPHA_ROUND (size + current_function_pretend_args_size));
        !          1283:   HOST_WIDE_INT reg_offset = out_args_size;
1.1.1.2   root     1284:   HOST_WIDE_INT start_reg_offset = reg_offset;
                   1285:   HOST_WIDE_INT actual_start_reg_offset = start_reg_offset;
1.1.1.3 ! root     1286:   int int_reg_save_area_size = 0;
1.1       root     1287:   rtx insn;
                   1288:   unsigned reg_mask = 0;
                   1289:   int i;
                   1290: 
1.1.1.3 ! root     1291:   /* Ecoff can handle multiple .file directives, so put out file and lineno.
1.1.1.2   root     1292:      We have to do that before the .ent directive as we cannot switch
                   1293:      files within procedures with native ecoff because line numbers are
                   1294:      linked to procedure descriptors.
                   1295:      Outputting the lineno helps debugging of one line functions as they
                   1296:      would otherwise get no line number at all. Please note that we would
                   1297:      like to put out last_linenum from final.c, but it is not accesible.  */
                   1298: 
                   1299:   if (write_symbols == SDB_DEBUG)
                   1300:     {
                   1301:       ASM_OUTPUT_SOURCE_FILENAME (file,
                   1302:                                  DECL_SOURCE_FILE (current_function_decl));
                   1303:       if (debug_info_level != DINFO_LEVEL_TERSE)
1.1.1.3 ! root     1304:         ASM_OUTPUT_SOURCE_LINE (file,
        !          1305:                                DECL_SOURCE_LINE (current_function_decl));
1.1.1.2   root     1306:     }
                   1307: 
                   1308:   /* The assembly language programmer's guide states that the second argument
                   1309:      to the .ent directive, the lex_level, is ignored by the assembler,
                   1310:      so we might as well omit it.  */
                   1311:      
                   1312:   fprintf (file, "\t.ent ");
                   1313:   assemble_name (file, alpha_function_name);
                   1314:   fprintf (file, "\n");
                   1315:   ASM_OUTPUT_LABEL (file, alpha_function_name);
                   1316:   inside_function = TRUE;
                   1317: 
                   1318:   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
                   1319: 
                   1320:   alpha_auto_offset = -frame_size + current_function_pretend_args_size;
                   1321:   alpha_arg_offset = -frame_size + 48;
                   1322: 
1.1       root     1323:   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first. 
                   1324:      Even if we are a static function, we still need to do this in case
                   1325:      our address is taken and passed to something like qsort.  */
                   1326: 
                   1327:   alpha_function_needs_gp = 0;
                   1328:   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
                   1329:     if ((GET_CODE (insn) == CALL_INSN)
                   1330:        || (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
                   1331:            && GET_CODE (PATTERN (insn)) != USE
                   1332:            && GET_CODE (PATTERN (insn)) != CLOBBER
1.1.1.2   root     1333:            && (get_attr_type (insn) == TYPE_LDSYM
                   1334:                || get_attr_type (insn) == TYPE_ISUBR)))
1.1       root     1335:       {
                   1336:        alpha_function_needs_gp = 1;
                   1337:        break;
                   1338:       }
                   1339: 
                   1340:   if (alpha_function_needs_gp)
                   1341:     fprintf (file, "\tldgp $29,0($27)\n");
                   1342: 
                   1343:   /* Put a label after the GP load so we can enter the function at it.  */
1.1.1.2   root     1344:   assemble_name (file, alpha_function_name);
                   1345:   fprintf (file, "..ng:\n");
1.1       root     1346: 
                   1347:   /* Adjust the stack by the frame size.  If the frame size is > 4096
                   1348:      bytes, we need to be sure we probe somewhere in the first and last
                   1349:      4096 bytes (we can probably get away without the latter test) and
                   1350:      every 8192 bytes in between.  If the frame size is > 32768, we
                   1351:      do this in a loop.  Otherwise, we generate the explicit probe
                   1352:      instructions. 
                   1353: 
                   1354:      Note that we are only allowed to adjust sp once in the prologue.  */
                   1355: 
                   1356:   if (frame_size < 32768)
                   1357:     {
                   1358:       if (frame_size > 4096)
                   1359:        {
                   1360:          int probed = 4096;
1.1.1.3 ! root     1361:          int regnum = 2;       /* $1 is static chain, so start with $2.  */
1.1       root     1362: 
                   1363:          fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed);
                   1364: 
                   1365:          while (probed + 8192 < frame_size)
                   1366:            fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed += 8192);
                   1367: 
1.1.1.3 ! root     1368:          /* We only have to do this probe if we aren't saving registers.  */
        !          1369:          if (sa_size == 0 && probed + 4096 < frame_size)
1.1       root     1370:            fprintf (file, "\tldq $%d,-%d($30)\n", regnum++, probed += 4096);
                   1371: 
                   1372:          if (regnum > 9)
                   1373:            abort ();
                   1374:        }
                   1375: 
                   1376:       if (frame_size != 0)
                   1377:        fprintf (file, "\tlda $30,-%d($30)\n", frame_size);
                   1378:     }
                   1379:   else
                   1380:     {
                   1381:       /* Here we generate code to set R4 to SP + 4096 and set R5 to the
                   1382:         number of 8192 byte blocks to probe.  We then probe each block
                   1383:         in the loop and then set SP to the proper location.  If the
1.1.1.3 ! root     1384:         amount remaining is > 4096, we have to do one more probe if we
        !          1385:         are not saving any registers.  */
1.1       root     1386: 
                   1387:       HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
                   1388:       HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
                   1389: 
1.1.1.3 ! root     1390:       add_long_const (file, blocks, 31, 5, 5);
1.1       root     1391: 
1.1.1.2   root     1392:       fprintf (file, "\tlda $4,4096($30)\n");
1.1       root     1393: 
1.1.1.2   root     1394:       assemble_name (file, alpha_function_name);
                   1395:       fprintf (file, "..sc:\n");
1.1       root     1396: 
                   1397:       fprintf (file, "\tldq $6,-8192($4)\n");
                   1398:       fprintf (file, "\tsubq $5,1,$5\n");
                   1399:       fprintf (file, "\tlda $4,-8192($4)\n");
1.1.1.2   root     1400: 
1.1.1.3 ! root     1401:       fprintf (file, "\tbne $5,");
1.1.1.2   root     1402:       assemble_name (file, alpha_function_name);
1.1.1.3 ! root     1403:       fprintf (file, "..sc\n");
1.1.1.2   root     1404: 
1.1       root     1405:       fprintf (file, "\tlda $30,-%d($4)\n", leftover);
                   1406: 
1.1.1.3 ! root     1407:       if (leftover > 4096 && sa_size == 0)
1.1       root     1408:        fprintf (file, "\tldq $2,%d($30)\n", leftover - 4096);
                   1409:     }
                   1410: 
                   1411:   /* Describe our frame.  */
                   1412:   fprintf (file, "\t.frame $%d,%d,$26,%d\n", 
1.1.1.3 ! root     1413:           (frame_pointer_needed
        !          1414:            ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
1.1       root     1415:           frame_size, current_function_pretend_args_size);
                   1416:     
1.1.1.3 ! root     1417:   /* Save register 26 if any other register needs to be saved.  */
        !          1418:   if (sa_size != 0)
1.1       root     1419:     {
                   1420:       reg_mask |= 1 << 26;
1.1.1.3 ! root     1421:       fprintf (file, "\tstq $26,%d($30)\n", reg_offset);
1.1       root     1422:       reg_offset += 8;
1.1.1.3 ! root     1423:       int_reg_save_area_size += 8;
1.1       root     1424:     }
                   1425: 
                   1426:   /* Now save any other used integer registers required to be saved.  */
                   1427:   for (i = 0; i < 32; i++)
                   1428:     if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i] && i != 26)
                   1429:       {
                   1430:        reg_mask |= 1 << i;
1.1.1.3 ! root     1431:        fprintf (file, "\tstq $%d,%d($30)\n", i, reg_offset);
1.1       root     1432:        reg_offset += 8;
1.1.1.3 ! root     1433:        int_reg_save_area_size += 8;
1.1       root     1434:       }
                   1435: 
                   1436:   /* Print the register mask and do floating-point saves.  */
                   1437:   if (reg_mask)
                   1438:     fprintf (file, "\t.mask 0x%x,%d\n", reg_mask,
1.1.1.2   root     1439:             actual_start_reg_offset - frame_size);
1.1       root     1440: 
                   1441:   start_reg_offset = reg_offset;
                   1442:   reg_mask = 0;
                   1443: 
                   1444:   for (i = 0; i < 32; i++)
                   1445:     if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
                   1446:        && regs_ever_live[i + 32])
                   1447:       {
                   1448:        reg_mask |= 1 << i;
1.1.1.3 ! root     1449:        fprintf (file, "\tstt $f%d,%d($30)\n", i, reg_offset);
1.1       root     1450:        reg_offset += 8;
                   1451:       }
                   1452: 
                   1453:   /* Print the floating-point mask, if we've saved any fp register.  */
                   1454:   if (reg_mask)
1.1.1.3 ! root     1455:     fprintf (file, "\t.fmask 0x%x,%d\n", reg_mask,
        !          1456:             actual_start_reg_offset - frame_size + int_reg_save_area_size);
1.1       root     1457: 
                   1458:   /* If we need a frame pointer, set it from the stack pointer.  Note that
                   1459:      this must always be the last instruction in the prologue.  */
                   1460:   if (frame_pointer_needed)
                   1461:     fprintf (file, "\tbis $30,$30,$15\n");
                   1462: 
                   1463:   /* End the prologue and say if we used gp.  */
                   1464:   fprintf (file, "\t.prologue %d\n", alpha_function_needs_gp);
                   1465: }
                   1466: 
                   1467: /* Write function epilogue.  */
                   1468: 
                   1469: void
                   1470: output_epilog (file, size)
                   1471:      FILE *file;
                   1472:      int size;
                   1473: {
                   1474:   rtx insn = get_last_insn ();
1.1.1.3 ! root     1475:   HOST_WIDE_INT out_args_size
        !          1476:     = ALPHA_ROUND (current_function_outgoing_args_size);
        !          1477:   HOST_WIDE_INT sa_size = alpha_sa_size ();
        !          1478:   HOST_WIDE_INT frame_size
        !          1479:     = (out_args_size + sa_size
        !          1480:        + ALPHA_ROUND (size + current_function_pretend_args_size));
        !          1481:   HOST_WIDE_INT reg_offset = out_args_size;
1.1.1.2   root     1482:   HOST_WIDE_INT frame_size_from_reg_save = frame_size - reg_offset;
1.1.1.3 ! root     1483:   int restore_fp
        !          1484:     = frame_pointer_needed && regs_ever_live[HARD_FRAME_POINTER_REGNUM];
1.1       root     1485:   int i;
                   1486: 
                   1487:   /* If the last insn was a BARRIER, we don't have to write anything except
                   1488:      the .end pseudo-op.  */
                   1489:   if (GET_CODE (insn) == NOTE)
                   1490:     insn = prev_nonnote_insn (insn);
                   1491:   if (insn == 0 || GET_CODE (insn) != BARRIER)
                   1492:     {
                   1493:       int fp_offset;
                   1494: 
                   1495:       /* If we have a frame pointer, restore SP from it.  */
                   1496:       if (frame_pointer_needed)
                   1497:        fprintf (file, "\tbis $15,$15,$30\n");
                   1498: 
                   1499:       /* Restore all the registers, starting with the return address
                   1500:         register.  */
1.1.1.3 ! root     1501:       if (sa_size != 0)
1.1       root     1502:        {
1.1.1.3 ! root     1503:          fprintf (file, "\tldq $26,%d($30)\n", reg_offset);
1.1       root     1504:          reg_offset += 8;
                   1505:        }
                   1506: 
                   1507:       /* Now restore any other used integer registers that that we saved,
                   1508:         except for FP if it is being used as FP, since it must be
                   1509:         restored last.  */
                   1510: 
                   1511:       for (i = 0; i < 32; i++)
                   1512:        if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i]
                   1513:            && i != 26)
                   1514:          {
1.1.1.3 ! root     1515:            if (i == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
1.1       root     1516:              fp_offset = reg_offset;
                   1517:            else
1.1.1.3 ! root     1518:              fprintf (file, "\tldq $%d,%d($30)\n", i, reg_offset);
1.1       root     1519:            reg_offset += 8;
                   1520:          }
                   1521: 
                   1522:       for (i = 0; i < 32; i++)
                   1523:        if (! fixed_regs[i + 32] && ! call_used_regs[i + 32]
                   1524:            && regs_ever_live[i + 32])
                   1525:          {
1.1.1.3 ! root     1526:            fprintf (file, "\tldt $f%d,%d($30)\n", i, reg_offset);
1.1       root     1527:            reg_offset += 8;
                   1528:          }
                   1529: 
1.1.1.3 ! root     1530:       /* If the stack size is large and we have a frame pointer, compute the
        !          1531:         size of the stack into a register because the old FP restore, stack
        !          1532:         pointer adjust, and return are required to be consecutive
        !          1533:         instructions.   */
        !          1534:       if (frame_size > 32767 && restore_fp)
        !          1535:        add_long_const (file, frame_size, 31, 1, 1);
1.1       root     1536: 
                   1537:       /* If we needed a frame pointer and we have to restore it, do it
1.1.1.2   root     1538:         now.  This must be done in one instruction immediately
                   1539:         before the SP update.  */
1.1.1.3 ! root     1540:       if (restore_fp)
        !          1541:        fprintf (file, "\tldq $15,%d($30)\n", fp_offset);
1.1       root     1542: 
1.1.1.3 ! root     1543:       /* Now update the stack pointer, if needed.  Only one instruction must
        !          1544:         modify the stack pointer.  It must be the last instruction in the
        !          1545:         sequence and must be an ADDQ or LDA instruction.  If the frame
        !          1546:         pointer was loaded above, we may only put one instruction here.  */
        !          1547: 
        !          1548:       if (frame_size > 32768 && restore_fp)
        !          1549:        fprintf  (file, "\taddq $1,$30,$30\n");
        !          1550:       else
        !          1551:        add_long_const (file, frame_size, 30, 30, 1);
1.1       root     1552: 
                   1553:       /* Finally return to the caller.  */
                   1554:       fprintf (file, "\tret $31,($26),1\n");
                   1555:     }
                   1556: 
                   1557:   /* End the function.  */
1.1.1.2   root     1558:   fprintf (file, "\t.end ");
                   1559:   assemble_name (file, alpha_function_name);
                   1560:   fprintf (file, "\n");
                   1561:   inside_function = FALSE;
1.1       root     1562: }
1.1.1.2   root     1563: 
                   1564: /* Debugging support.  */
                   1565: 
                   1566: #include "gstab.h"
                   1567: 
                   1568: /* Count the number of sdb related labels are generated (to find block
                   1569:    start and end boundaries).  */
                   1570: 
                   1571: int sdb_label_count = 0;
                   1572: 
                   1573: /* Next label # for each statement.  */
                   1574: 
                   1575: static int sym_lineno = 0;
                   1576: 
                   1577: /* Count the number of .file directives, so that .loc is up to date.  */
                   1578: 
                   1579: static int num_source_filenames = 0;
                   1580: 
                   1581: /* Name of the file containing the current function.  */
                   1582: 
                   1583: static char *current_function_file = "";
                   1584: 
                   1585: /* Offsets to alpha virtual arg/local debugging pointers.  */
                   1586: 
                   1587: long alpha_arg_offset;
                   1588: long alpha_auto_offset;
                   1589: 
                   1590: /* Emit a new filename to a stream.  */
                   1591: 
                   1592: void
                   1593: alpha_output_filename (stream, name)
                   1594:      FILE *stream;
                   1595:      char *name;
                   1596: {
                   1597:   static int first_time = TRUE;
                   1598:   char ltext_label_name[100];
                   1599: 
                   1600:   if (first_time)
                   1601:     {
                   1602:       first_time = FALSE;
                   1603:       ++num_source_filenames;
                   1604:       current_function_file = name;
                   1605:       fprintf (stream, "\t.file\t%d ", num_source_filenames);
                   1606:       output_quoted_string (stream, name);
                   1607:       fprintf (stream, "\n");
                   1608:       if (!TARGET_GAS && write_symbols == DBX_DEBUG)
                   1609:        fprintf (stream, "\t#@stabs\n");
                   1610:     }
                   1611: 
                   1612:   else if (!TARGET_GAS && write_symbols == DBX_DEBUG)
                   1613:     {
                   1614:       ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
                   1615:       fprintf (stream, "%s ", ASM_STABS_OP);
                   1616:       output_quoted_string (stream, name);
                   1617:       fprintf (stream, ",%d,0,0,%s\n", N_SOL, &ltext_label_name[1]);
                   1618:     }
                   1619: 
                   1620:   else if (name != current_function_file
                   1621:       && strcmp (name, current_function_file) != 0)
                   1622:     {
                   1623:       if (inside_function && ! TARGET_GAS)
                   1624:        fprintf (stream, "\t#.file\t%d ", num_source_filenames);
                   1625:       else
                   1626:        {
                   1627:          ++num_source_filenames;
                   1628:          current_function_file = name;
                   1629:          fprintf (stream, "\t.file\t%d ", num_source_filenames);
                   1630:        }
                   1631: 
                   1632:       output_quoted_string (stream, name);
                   1633:       fprintf (stream, "\n");
                   1634:     }
                   1635: }
                   1636: 
                   1637: /* Emit a linenumber to a stream.  */
                   1638: 
                   1639: void
                   1640: alpha_output_lineno (stream, line)
                   1641:      FILE *stream;
                   1642:      int line;
                   1643: {
                   1644:   if (! TARGET_GAS && write_symbols == DBX_DEBUG)
                   1645:     {
                   1646:       /* mips-tfile doesn't understand .stabd directives.  */
                   1647:       ++sym_lineno;
                   1648:       fprintf (stream, "$LM%d:\n\t%s %d,0,%d,$LM%d\n",
                   1649:               sym_lineno, ASM_STABN_OP, N_SLINE, line, sym_lineno);
                   1650:     }
                   1651:   else
                   1652:     fprintf (stream, "\n\t.loc\t%d %d\n", num_source_filenames, line);
                   1653: }

unix.superglobalmegacorp.com

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