Annotation of gcc/config/a29k.c, revision 1.1.1.2

1.1       root        1: /* Subroutines used for code generation on AMD Am29000.
                      2:    Copyright (C) 1987, 1988, 1990, 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: #include "tree.h"
                     37: 
                     38: #define min(A,B)       ((A) < (B) ? (A) : (B))
                     39: 
                     40: /* This gives the size in words of the register stack for the current
                     41:    procedure.  */
                     42: 
                     43: static int a29k_regstack_size;
                     44: 
                     45: /* This points to the last insn of the insn prologue.  It is set when
                     46:    an insn without a filled delay slot is found near the start of the
                     47:    function.  */
                     48: 
                     49: static char *a29k_last_prologue_insn;
                     50: 
                     51: /* This points to the first insn that will be in the epilogue.  It is null if
                     52:    no epilogue is required.  */
                     53: 
                     54: static char *a29k_first_epilogue_insn;
                     55: 
                     56: /* This is nonzero if a a29k_first_epilogue_insn was put in a delay slot.  It
                     57:    indicates that an intermediate label needs to be written.  */
                     58: 
                     59: static int a29k_first_epilogue_insn_used;
                     60: 
                     61: /* Location to hold the name of the current function.  We need this prolog to
                     62:    contain the tag words prior to the declaration.  So the name must be stored
                     63:    away.  */
                     64: 
                     65: char *a29k_function_name;
                     66: 
                     67: /* Mapping of registers to debug register numbers.  The only change is
                     68:    for the frame pointer and the register numbers used for the incoming
                     69:    arguments.  */
                     70: 
                     71: int a29k_debug_reg_map[FIRST_PSEUDO_REGISTER];
                     72: 
                     73: /* Save information from a "cmpxx" operation until the branch or scc is
                     74:    emitted.  */
                     75: 
                     76: rtx a29k_compare_op0, a29k_compare_op1;
                     77: int a29k_compare_fp_p;
                     78: 
                     79: /* Gives names for registers.  */
                     80: extern char *reg_names[];
                     81: 
                     82: /* Returns 1 if OP is a 8-bit constant. */
                     83: 
                     84: int
                     85: cint_8_operand (op, mode)
                     86:      register rtx op;
                     87:      enum machine_mode mode;
                     88: {
                     89:   return GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffffff00) == 0;
                     90: }
                     91: 
                     92: /* Returns 1 if OP is a 16-bit constant.  */
                     93: 
                     94: int
                     95: cint_16_operand (op, mode)
                     96:      rtx op;
                     97:      enum machine_mode mode;
                     98: {
                     99:   return GET_CODE (op) == CONST_INT && (INTVAL (op) & 0xffff0000) == 0;
                    100: }
                    101: 
                    102: /* Returns 1 if OP cannot be moved in a single insn.  */
                    103: 
                    104: int
                    105: long_const_operand (op, mode)
                    106:      register rtx op;
                    107:      enum machine_mode mode;
                    108: {
                    109:   if (! CONSTANT_P (op))
                    110:     return 0;
                    111: 
                    112:   if (TARGET_29050 && GET_CODE (op) == CONST_INT
                    113:       && (INTVAL (op) & 0xffff) == 0)
                    114:     return 0;
                    115: 
                    116:   return (GET_CODE (op) != CONST_INT
                    117:          || ((INTVAL (op) & 0xffff0000) != 0
                    118:              && (INTVAL (op) & 0xffff0000) != 0xffff0000
                    119:              && INTVAL (op) != 0x80000000));
                    120: }
                    121: 
                    122: /* The following four functions detect constants of 0, 8, 16, and 24 used as
                    123:    a position in ZERO_EXTRACT operations.  They can either be the appropriate
                    124:    constant integer or a shift (which will be produced by combine).  */
                    125: 
                    126: static int
                    127: shift_constant_operand (op, mode, val)
                    128:      rtx op;
                    129:      enum machine_mode mode;
                    130:      int val;
                    131: {
                    132:   return ((GET_CODE (op) == CONST_INT && INTVAL (op) == val)
                    133:          || (GET_CODE (op) == ASHIFT
                    134:              && GET_CODE (XEXP (op, 0)) == CONST_INT
                    135:              && INTVAL (XEXP (op, 0)) == val / 8
                    136:              && GET_CODE (XEXP (op, 1)) == CONST_INT
                    137:              && INTVAL (XEXP (op, 1)) == 3));
                    138: }
                    139: 
                    140: int
                    141: const_0_operand (op, mode)
                    142:      rtx op;
                    143:      enum machine_mode mode;
                    144: {
                    145:   return shift_constant_operand (op, mode, 0);
                    146: }
                    147: 
                    148: int
                    149: const_8_operand (op, mode)
                    150:      rtx op;
                    151:      enum machine_mode mode;
                    152: {
                    153:   return shift_constant_operand (op, mode, 8);
                    154: }
                    155: 
                    156: int
                    157: const_16_operand (op, mode)
                    158:      rtx op;
                    159:      enum machine_mode;
                    160: {
                    161:   return shift_constant_operand (op, mode, 16);
                    162: }
                    163: 
                    164: int
                    165: const_24_operand (op, mode)
                    166:      rtx op;
                    167:      enum machine_mode;
                    168: {
                    169:   return shift_constant_operand (op, mode, 24);
                    170: }
                    171: 
                    172: /* Returns 1 if OP is a floating-point constant of the proper mode.  */
                    173: 
                    174: int
                    175: float_const_operand (op, mode)
                    176:      rtx op;
                    177:      enum machine_mode mode;
                    178: {
                    179:   return GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == mode;
                    180: }
                    181: 
                    182: /* Returns 1 if OP is a floating-point constant of the proper mode or a
                    183:    general-purpose register.  */
                    184: 
                    185: int
1.1.1.2 ! root      186: gpc_reg_or_float_constant_operand (op, mode)
1.1       root      187:      rtx op;
                    188:      enum machine_mode mode;
                    189: {
1.1.1.2 ! root      190:   return float_const_operand (op, mode) || gpc_reg_operand (op, mode);
1.1       root      191: }
                    192: 
                    193: /* Returns 1 if OP is an integer constant of the proper mode or a
                    194:    general-purpose register.  */
                    195: 
                    196: int
1.1.1.2 ! root      197: gpc_reg_or_integer_constant_operand (op, mode)
1.1       root      198:      rtx op;
                    199:      enum machine_mode mode;
                    200: {
                    201:   return ((GET_MODE (op) == VOIDmode
                    202:           && (GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE))
1.1.1.2 ! root      203:          || gpc_reg_operand (op, mode));
1.1       root      204: }
                    205:      
                    206: /* Returns 1 if OP is a special machine register.  */
                    207: 
                    208: int
                    209: spec_reg_operand (op, mode)
                    210:      rtx op;
                    211:      enum machine_mode mode;
                    212: {
                    213:   return GET_MODE (op) == SImode && GET_CODE (op) == REG
                    214:         && REGNO (op) >= R_BP && REGNO (op) <= R_EXO;
                    215: }
                    216: 
                    217: /* Returns 1 if OP is an accumulator register.  */
                    218: 
                    219: int
                    220: accum_reg_operand (op, mode)
                    221:      rtx op;
                    222:      enum machine_mode mode;
                    223: {
                    224:   return (GET_CODE (op) == REG
                    225:          && REGNO (op) >= R_ACC (0) && REGNO (op) <= R_ACC (3));
                    226: }
                    227: 
                    228: /* Returns 1 if OP is a normal data register.  */
                    229: 
                    230: int
1.1.1.2 ! root      231: gpc_reg_operand (op, mode)
1.1       root      232:      rtx op;
                    233:      enum machine_mode mode;
                    234: {
                    235:   int regno;
                    236: 
                    237:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    238:     return 0;
                    239: 
                    240:   if (GET_CODE (op) == REG)
                    241:     regno = REGNO (op);
                    242:   else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
                    243:     {
                    244:       regno = REGNO (SUBREG_REG (op));
                    245:       if (regno < FIRST_PSEUDO_REGISTER)
                    246:        regno += SUBREG_WORD (op);
                    247:     }
                    248:   else
                    249:     return 0;
                    250: 
                    251:   return regno >= FIRST_PSEUDO_REGISTER || regno < R_BP;
                    252: }
                    253: 
                    254: /* Returns 1 if OP is either an 8-bit constant integer or a general register.
                    255:    If a register, it must be in the proper mode unless MODE is VOIDmode.  */
                    256: 
                    257: int
                    258: srcb_operand (op, mode)
                    259:       register rtx op;
                    260:       enum machine_mode mode;
                    261: {
                    262:   if (GET_CODE (op) == CONST_INT
                    263:       && (mode == QImode
                    264:          || (INTVAL (op) & 0xffffff00) == 0))
                    265:     return 1;
                    266: 
                    267:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    268:     return 0;
                    269: 
1.1.1.2 ! root      270:   return gpc_reg_operand (op, mode);
1.1       root      271: }
                    272: 
                    273: /* Return 1 if OP is either an immediate or a general register.  This is used
                    274:    for the input operand of mtsr/mtrsim.  */
                    275: 
                    276: int
1.1.1.2 ! root      277: gpc_reg_or_immediate_operand (op, mode)
1.1       root      278:      rtx op;
                    279:      enum machine_mode;
                    280: {
1.1.1.2 ! root      281:   return gpc_reg_operand (op, mode) || immediate_operand (op, mode);
1.1       root      282: }
                    283: 
                    284: /* Return 1 if OP can be used as the second operand of and AND insn.  This
                    285:    includes srcb_operand and a constant whose complement fits in 8 bits.  */
                    286: 
                    287: int
                    288: and_operand (op, mode)
                    289:      rtx op;
                    290:      enum machine_mode;
                    291: {
                    292:   return (srcb_operand (op, mode)
                    293:          || (GET_CODE (op) == CONST_INT
                    294:              && ((unsigned) ((~ INTVAL (op)) & GET_MODE_MASK (mode)) < 256)));
                    295: }
                    296: 
                    297: /* Return 1 if OP can be used as the second operand of an ADD insn.
                    298:    This is the same as above, except we use negative, rather than
                    299:    complement.   */
                    300: 
                    301: int
                    302: add_operand (op, mode)
                    303:      rtx op;
                    304:      enum machine_mode;
                    305: {
                    306:   return (srcb_operand (op, mode)
                    307:          || (GET_CODE (op) == CONST_INT
                    308:              && ((unsigned) ((- INTVAL (op)) & GET_MODE_MASK (mode)) < 256)));
                    309: }
                    310: 
                    311: /* Return 1 if OP can be used as the input operand for a move insn.  */
                    312: 
                    313: int
                    314: in_operand (op, mode)
                    315:      rtx op;
                    316:      enum machine_mode mode;
                    317: {
                    318:   rtx orig_op = op;
                    319: 
                    320:   if (! general_operand (op, mode))
                    321:     return 0;
                    322: 
                    323:   while (GET_CODE (op) == SUBREG)
                    324:     op = SUBREG_REG (op);
                    325: 
                    326:   switch (GET_CODE (op))
                    327:     {
                    328:     case REG:
                    329:       return 1;
                    330: 
                    331:     case MEM:
                    332:       return (GET_MODE_SIZE (mode) >= UNITS_PER_WORD || TARGET_DW_ENABLE);
                    333: 
                    334:     case CONST_INT:
                    335:       if (GET_MODE_CLASS (mode) != MODE_INT)
                    336:        return 0;
                    337: 
                    338:       return 1;
                    339: 
                    340:     case CONST:
                    341:     case SYMBOL_REF:
                    342:     case LABEL_REF:
                    343:       return (GET_MODE (op) == mode
                    344:              || mode == SImode || mode == HImode || mode == QImode);
                    345: 
                    346:     case CONST_DOUBLE:
                    347:       return ((GET_MODE_CLASS (mode) == MODE_FLOAT
                    348:               && mode == GET_MODE (op))
                    349:              || (GET_MODE (op) == VOIDmode
                    350:                  && GET_MODE_CLASS (mode) == MODE_INT));
                    351: 
                    352:     default:
                    353:       return 0;
                    354:     }
                    355: }
                    356: 
                    357: /* Return 1 if OP can be used as the output operand for a move insn.  */
                    358: 
                    359: int
                    360: out_operand (op, mode)
                    361:      rtx op;
                    362:      enum machine_mode mode;
                    363: {
                    364:   rtx orig_op = op;
                    365: 
                    366:   if (! general_operand (op, mode))
                    367:     return 0;
                    368: 
                    369:   while (GET_CODE (op) == SUBREG)
                    370:     op = SUBREG_REG (op);
                    371: 
                    372:   if (GET_CODE (op) == REG)
1.1.1.2 ! root      373:     return (mode == SImode || gpc_reg_operand (orig_op, mode)
1.1       root      374:            || (GET_MODE_CLASS (mode) == MODE_FLOAT
                    375:                && accum_reg_operand (orig_op, mode)));
                    376: 
                    377:   else if (GET_CODE (op) == MEM)
                    378:     return mode == SImode || mode == SFmode || TARGET_DW_ENABLE;
                    379: 
                    380:   else
                    381:     return 0;
                    382: }
                    383: 
                    384: /* Return 1 if OP is some extension operator.  */
                    385: 
                    386: int
                    387: extend_operator (op, mode)
                    388:      rtx op;
                    389:      enum machine_mode mode;
                    390: {
                    391:   return ((mode == VOIDmode || GET_MODE (op) == mode)
                    392:          && (GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND));
                    393: }
                    394: 
                    395: /* Return 1 if OP is a comparison operator that we have in floating-point.  */
                    396: 
                    397: int
                    398: fp_comparison_operator (op, mode)
                    399:      rtx op;
                    400:      enum machine_mode mode;
                    401: {
                    402:   return ((mode == VOIDmode || mode == GET_MODE (op))
                    403:          && (GET_CODE (op) == EQ || GET_CODE (op) == GT ||
                    404:              GET_CODE (op) == GE));
                    405: }
                    406: 
                    407: /* Return 1 if OP is a valid branch comparison.  */
                    408: 
                    409: int
                    410: branch_operator (op, mode)
                    411:      rtx op;
                    412:      enum machine_mode mode;
                    413: {
                    414:   return ((mode == VOIDmode || mode == GET_MODE (op))
                    415:          && (GET_CODE (op) == GE || GET_CODE (op) == LT));
                    416: }
                    417: 
                    418: /* Return 1 if OP is a load multiple operation.  It is known to be a
                    419:    PARALLEL and the first three sections will be tested.  */
                    420: 
                    421: int
                    422: load_multiple_operation (op, mode)
                    423:      rtx op;
                    424:      enum machine_mode mode;
                    425: {
                    426:   int count = XVECLEN (op, 0) - 2;
                    427:   int dest_regno;
                    428:   rtx src_addr;
                    429:   int i;
                    430: 
                    431:   /* Perform a quick check so we don't blow up below.  */
                    432:   if (count <= 1
                    433:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
                    434:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
                    435:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
                    436:     return 0;
                    437: 
                    438:   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
                    439:   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
                    440: 
                    441:   for (i = 1; i < count; i++)
                    442:     {
                    443:       rtx elt = XVECEXP (op, 0, i + 2);
                    444: 
                    445:       if (GET_CODE (elt) != SET
                    446:          || GET_CODE (SET_DEST (elt)) != REG
                    447:          || GET_MODE (SET_DEST (elt)) != SImode
                    448:          || REGNO (SET_DEST (elt)) != dest_regno + i
                    449:          || GET_CODE (SET_SRC (elt)) != MEM
                    450:          || GET_MODE (SET_SRC (elt)) != SImode
                    451:          || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
                    452:          || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
                    453:          || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
                    454:          || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
                    455:        return 0;
                    456:     }
                    457: 
                    458:   return 1;
                    459: }
                    460: 
                    461: /* Similar, but tests for store multiple.  */
                    462: 
                    463: int
                    464: store_multiple_operation (op, mode)
                    465:      rtx op;
                    466:      enum machine_mode mode;
                    467: {
                    468:   int num_special = TARGET_NO_STOREM_BUG ? 2 : 1;
                    469:   int count = XVECLEN (op, 0) - num_special;
                    470:   int src_regno;
                    471:   rtx dest_addr;
                    472:   int i;
                    473: 
                    474:   /* Perform a quick check so we don't blow up below.  */
                    475:   if (count <= 1
                    476:       || GET_CODE (XVECEXP (op, 0, 0)) != SET
                    477:       || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
                    478:       || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
                    479:     return 0;
                    480: 
                    481:   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
                    482:   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
                    483: 
                    484:   for (i = 1; i < count; i++)
                    485:     {
                    486:       rtx elt = XVECEXP (op, 0, i + num_special);
                    487: 
                    488:       if (GET_CODE (elt) != SET
                    489:          || GET_CODE (SET_SRC (elt)) != REG
                    490:          || GET_MODE (SET_SRC (elt)) != SImode
                    491:          || REGNO (SET_SRC (elt)) != src_regno + i
                    492:          || GET_CODE (SET_DEST (elt)) != MEM
                    493:          || GET_MODE (SET_DEST (elt)) != SImode
                    494:          || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
                    495:          || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
                    496:          || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
                    497:          || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
                    498:        return 0;
                    499:     }
                    500: 
                    501:   return 1;
                    502: }
                    503: 
                    504: /* Given a special register REG and MASK, a value being masked against a
                    505:    quantity to which the special register is set, return 1 if the masking
                    506:    operation is built-in to the setting of that special register.  */
                    507: 
                    508: int
                    509: masks_bits_for_special (reg, mask)
                    510:      rtx reg;
                    511:      rtx mask;
                    512: {
                    513:    int needed_mask_value;
                    514: 
                    515:   if (GET_CODE (reg) != REG || GET_CODE (mask) != CONST_INT)
                    516:     abort ();
                    517: 
                    518:   switch (REGNO (reg))
                    519:     {
                    520:     case R_BP:
                    521:     case R_INT:
                    522:       needed_mask_value = 3;
                    523:       break;
                    524: 
                    525:     case R_FC:
                    526:       needed_mask_value = 31;
                    527:       break;
                    528: 
                    529:     case R_CR:
                    530:     case R_LRU:
                    531:       needed_mask_value = 255;
                    532:       break;
                    533: 
                    534:     case R_FPE:
                    535:       needed_mask_value = 511;
                    536:       break;
                    537: 
                    538:     case R_MMU:
                    539:       needed_mask_value = 0x3ff;
                    540:       break;
                    541: 
                    542:     case R_OPS:
                    543:     case R_CPS:
                    544:     case R_RBP:
                    545:     case R_FPS:
                    546:       needed_mask_value = 0xffff;
                    547:       break;
                    548: 
                    549:     case R_VAB:
                    550:       needed_mask_value = 0xffff0000;
                    551:       break;
                    552: 
                    553:     case R_Q:
                    554:     case R_CFG:
                    555:     case R_CHA:
                    556:     case R_CHD:
                    557:     case R_CHC:
                    558:     case R_TMC:
                    559:     case R_TMR:
                    560:     case R_PC0:
                    561:     case R_PC1:
                    562:     case R_PC2:
                    563:       return 0;
                    564: 
                    565:     default:
                    566:       abort ();
                    567:     }
                    568: 
                    569:    return (INTVAL (mask) & ~ needed_mask_value) == 0;
                    570: }
                    571: 
                    572: /* Return nonzero if this label is that of the return point, but there is
                    573:    a non-null epilogue.  */
                    574: 
                    575: int
                    576: epilogue_operand (op, mode)
                    577:      rtx op;
                    578:      enum machine_mode mode;
                    579: {
                    580:   return next_active_insn (op) == 0 && a29k_first_epilogue_insn != 0;
                    581: }
                    582: 
                    583: /* Return the register class of a scratch register needed to copy IN into
                    584:    or out of a register in CLASS in MODE.  If it can be done directly,
                    585:    NO_REGS is returned.  */
                    586: 
                    587: enum reg_class
                    588: secondary_reload_class (class, mode, in)
                    589:      enum reg_class class;
                    590:      enum machine_mode mode;
                    591:      rtx in;
                    592: {
                    593:   int regno = -1;
                    594: 
                    595:   if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
                    596:     regno = true_regnum (in);
                    597: 
                    598:   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
                    599:      into anything.  */
                    600:   if (class == GENERAL_REGS || (regno != -1 && regno < R_BP))
                    601:     return NO_REGS;
                    602: 
                    603:   /* We can place 16-bit constants into a special register.  */
                    604:   if (GET_CODE (in) == CONST_INT
                    605:       && (GET_MODE_BITSIZE (mode) <= 16
                    606:          || (unsigned) INTVAL (in) <= 65535)
                    607:       && (class == BP_REGS || class == Q_REGS || class == SPECIAL_REGS))
                    608:     return NO_REGS;
                    609: 
                    610:   /* Otherwise, we need GENERAL_REGS.  */
                    611:   return GENERAL_REGS;
                    612: }
                    613: 
                    614: /* START is the zero-based incoming argument register index used (0 is 160,
                    615:    i.e., the first incoming argument register) and COUNT is the number used.
                    616: 
                    617:    Mark the corresponding incoming registers as neither fixed nor call used.
                    618:    For each register used for incoming arguments, we have one less local
                    619:    register that can be used.  So also mark some high-numbered registers as
                    620:    fixed.
                    621: 
                    622:    Return the first register number to use for the argument.  */
                    623: 
                    624: int
                    625: incoming_reg (start, count)
                    626:      int start;
                    627:      int count;
                    628: {
                    629:   int i;
                    630: 
                    631:   if (! TARGET_NO_REUSE_ARGS)
                    632:     /* Mark all the used registers as not fixed and saved over calls.  */
                    633:     for (i = R_AR (start); i < R_AR (16) && i < R_AR (start + count); i++)
                    634:       {
                    635:        fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 0;
                    636:        CLEAR_HARD_REG_BIT (fixed_reg_set, i);
                    637:        CLEAR_HARD_REG_BIT (call_used_reg_set, i);
                    638:        CLEAR_HARD_REG_BIT (call_fixed_reg_set, i);
                    639:       }
                    640: 
                    641:   /* Shorten the maximum size of the frame.  */
                    642:   for (i = R_AR (0) - start - count; i < R_AR (0) - start; i++)
                    643:     {
                    644:       fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1;
                    645:       SET_HARD_REG_BIT (fixed_reg_set, i);
                    646:       SET_HARD_REG_BIT (call_used_reg_set, i);
                    647:       SET_HARD_REG_BIT (call_fixed_reg_set, i);
                    648:     }
                    649: 
                    650:   return R_AR (start);
                    651: }
                    652: 
                    653: /* These routines are used in finding insns to fill delay slots in the
                    654:    epilogue.  */
                    655: 
                    656: /* Return 1 if the current function will adjust the register stack.  */
                    657: 
                    658: int
                    659: needs_regstack_p ()
                    660: {
                    661:   int i;
                    662:   rtx insn;
                    663: 
                    664:   if (frame_pointer_needed)
                    665:     return 1;
                    666: 
                    667:   /* If any local register is used, we need to adjust the regstack.  */
                    668:   for (i = R_LR (127); i >= R_LR (0); i --)
                    669:     if (regs_ever_live[i])
                    670:       return 1;
                    671: 
                    672:   /* We need a register stack if we make any calls.  */
                    673:   for (insn = get_insns (); insn; insn = next_insn (insn))
                    674:     if (GET_CODE (insn) == CALL_INSN
                    675:        || (GET_CODE (insn) == INSN
                    676:            && GET_CODE (PATTERN (insn)) == SEQUENCE
                    677:            && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN))
                    678:       return 1;
                    679: 
                    680:   /* Otherwise, we don't.  */
                    681:   return 0;
                    682: }
                    683: 
                    684: /* Return 1 if X uses a local register.  */
                    685: 
                    686: int
                    687: uses_local_reg_p (x)
                    688:      rtx x;
                    689: {
                    690:   char *fmt;
                    691:   int i, j;
                    692: 
                    693:   switch (GET_CODE (x))
                    694:     {
                    695:     case REG:
                    696:       return REGNO (x) >= R_LR (0) && REGNO (x) <= R_FP;
                    697: 
                    698:     case CONST_INT:
                    699:     case CONST:
                    700:     case PC:
                    701:     case CC0:
                    702:     case LABEL_REF:
                    703:     case SYMBOL_REF:
                    704:       return 0;
                    705:     }
                    706: 
                    707:   fmt = GET_RTX_FORMAT (GET_CODE (x));
                    708:   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
                    709:     {
                    710:       if (fmt[i] == 'e')
                    711:        {
                    712:          if (uses_local_reg_p (XEXP (x, i)))
                    713:            return 1;
                    714:        }
                    715:       else if (fmt[i] == 'E')
                    716:        {
                    717:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    718:            if (uses_local_reg_p (XVECEXP (x, i, j)))
                    719:              return 1;
                    720:        }
                    721:     }
                    722: 
                    723:   return 0;
                    724: }
                    725: 
                    726: /* Returns 1 if this function is known to have a null epilogue.  */
                    727: 
                    728: int
                    729: null_epilogue ()
                    730: {
                    731:   return (reload_completed && ! needs_regstack_p ()
                    732:          && get_frame_size () == 0
                    733:          && current_function_pretend_args_size == 0);
                    734: }
                    735: 
                    736: /* Write out the assembler form of an operand.  Recognize the following
                    737:    special options:
                    738: 
                    739:        %N means write the low-order 8 bits of the negative of the constant
                    740:        %Q means write a QImode operand (truncate constants to 8 bits)
                    741:        %M means write the low-order 16 bits of the constant
                    742:        %C means write the low-order 8 bits of the complement of the constant
                    743:        %X means write the cntl values for LOAD with operand an extension op
                    744:        %b means write `f' is this is a reversed condition, `t' otherwise
                    745:        %B means write `t' is this is a reversed condition, `f' otherwise
                    746:        %J means write the 29k opcode part for a comparison operation
                    747:        %e means write the label with an extra `X' is this is the epilogue
                    748:                       otherwise the normal label name
                    749:        %E means write nothing if this insn has a delay slot,
                    750:                       a nop unless this is the epilogue label, in which case
                    751:                       write the first epilogue insn
                    752:        %F means write just the normal operand if the insn has a delay slot;
                    753:                       otherwise, this is a recursive call so output the
                    754:                       symbol + 4 and write the first prologue insn in the
                    755:                       delay slot.
                    756:        %L means write the register number plus one ("low order" register)
                    757:                       or the low-order part of a multi-word constant
                    758:        %O means write the register number plus two
                    759:        %P means write the register number plus three ("low order" of TImode)
                    760:        %S means write the number of words in the mode of the operand,
                    761:                       minus one (for CR)
                    762:         %V means write the number of elements in a PARALLEL minus 1
                    763:        %# means write nothing if we have a delay slot, "\n\tnop" otherwise
                    764:        %* means write the register name for TPC.  */
                    765: 
                    766: void
                    767: print_operand (file, x, code)
                    768:      FILE *file;
                    769:      rtx x;
                    770:      char code;
                    771: {
                    772:   char buf[100];
                    773: 
                    774:   /* These macros test for integers and extract the low-order bits.  */
                    775: #define INT_P(X)  \
                    776: ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE)   \
                    777:  && GET_MODE (X) == VOIDmode)
                    778: 
                    779: #define INT_LOWPART(X) \
                    780:   (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
                    781: 
                    782:   switch (code)
                    783:     {
                    784:     case 'Q':
                    785:       if (GET_CODE (x) == REG)
                    786:        break;
                    787:       else if (! INT_P (x))
                    788:        output_operand_lossage ("invalid %%Q value");
                    789:       fprintf (file, "%d", INT_LOWPART (x) & 0xff);
                    790:       return;
                    791: 
                    792:     case 'C':
                    793:       if (! INT_P (x))
                    794:        output_operand_lossage ("invalid %%C value");
                    795:       fprintf (file, "%d", (~ INT_LOWPART (x)) & 0xff);
                    796:       return;
                    797: 
                    798:     case 'N':
                    799:       if (! INT_P (x))
                    800:        output_operand_lossage ("invalid %%N value");
                    801:       fprintf (file, "%d", (- INT_LOWPART (x)) & 0xff);
                    802:       return;
                    803: 
                    804:     case 'M':
                    805:       if (! INT_P (x))
                    806:        output_operand_lossage ("invalid %%M value");
                    807:       fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
                    808:       return;
                    809: 
                    810:     case 'X':
                    811:       fprintf (file, "%d", ((GET_MODE (XEXP (x, 0)) == QImode ? 1 : 2)
                    812:                            + (GET_CODE (x) == SIGN_EXTEND ? 16 : 0)));
                    813:       return;
                    814:   
                    815:     case 'b':
                    816:       if (GET_CODE (x) == GE)
                    817:        fprintf (file, "f");
                    818:       else
                    819:        fprintf (file, "t");
                    820:       return;
                    821: 
                    822:     case 'B':
                    823:       if (GET_CODE (x) == GE)
                    824:        fprintf (file, "t");
                    825:       else
                    826:        fprintf (file, "f");
                    827:       return;
                    828: 
                    829:     case 'J':
                    830:       /* It so happens that the RTX names for the conditions are the same as
                    831:         the 29k's insns except for "ne", which requires "neq".  */
                    832:       fprintf (file, GET_RTX_NAME (GET_CODE (x)));
                    833:       if (GET_CODE (x) == NE)
                    834:        fprintf (file, "q");
                    835:       return;
                    836: 
                    837:     case 'e':
                    838:       if (optimize && flag_delayed_branch
                    839:          && a29k_last_prologue_insn == 0 && epilogue_operand (x, VOIDmode)
                    840:          && dbr_sequence_length () == 0)
                    841:        {
                    842:          /* We need to output the label number of the last label in the
                    843:             function, which is not necessarily X since there might be
                    844:             a USE insn in between.  First go forward to the last insn, then
                    845:             back up to a label.  */
                    846:          while (NEXT_INSN (x) != 0)
                    847:            x = NEXT_INSN (x);
                    848: 
                    849:          while (GET_CODE (x) != CODE_LABEL)
                    850:            x = PREV_INSN (x);
                    851: 
                    852:          ASM_GENERATE_INTERNAL_LABEL (buf, "LX", CODE_LABEL_NUMBER (x));
                    853:          assemble_name (file, buf);
                    854:        }
                    855:       else
                    856:        output_asm_label (x);
                    857:       return;
                    858: 
                    859:     case 'E':
                    860:       if (dbr_sequence_length ())
                    861:        ;
                    862:       else if (a29k_last_prologue_insn)
                    863:        {
                    864:          fprintf (file, "\n\t%s", a29k_last_prologue_insn);
                    865:          a29k_last_prologue_insn = 0;
                    866:        }
                    867:       else if (optimize && flag_delayed_branch
                    868:               && epilogue_operand (x, VOIDmode))
                    869:        {
                    870:          fprintf (file, "\n\t%s", a29k_first_epilogue_insn);
                    871:          a29k_first_epilogue_insn_used = 1;
                    872:        }
                    873:       else
                    874:        fprintf (file, "\n\tnop");
                    875:       return;
                    876:       
                    877:     case 'F':
                    878:       output_addr_const (file, x);
1.1.1.2 ! root      879:       if (dbr_sequence_length () == 0)
        !           880:        {
        !           881:          if (! strcmp (XSTR (x, 0), current_function_name))
        !           882:            fprintf (file, "+4\n\t%s,%d",
        !           883:                     a29k_regstack_size >= 64 ? "const gr121" : "sub gr1,gr1",
        !           884:                     a29k_regstack_size * 4);
        !           885:          else
        !           886:            fprintf (file, "\n\tnop");
        !           887:        }
1.1       root      888:       return;
                    889: 
                    890:     case 'L':
                    891:       if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
                    892:        {
                    893:          union real_extract u;
                    894: 
                    895:          bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
                    896:          fprintf (file, "$double1(%.20e)", u.d);
                    897:        }
                    898:       else if (GET_CODE (x) == REG)
                    899:        fprintf (file, "%s", reg_names[REGNO (x) + 1]);
                    900:       else
                    901:        output_operand_lossage ("invalid %%L value");
                    902:       return;
                    903: 
                    904:     case 'O':
                    905:       if (GET_CODE (x) != REG)
                    906:        output_operand_lossage ("invalid %%O value");
                    907:       fprintf (file, "%s", reg_names[REGNO (x) + 2]);
                    908:       return;
                    909: 
                    910:     case 'P':
                    911:       if (GET_CODE (x) != REG)
                    912:        output_operand_lossage ("invalid %%P value");
                    913:       fprintf (file, "%s", reg_names[REGNO (x) + 3]);
                    914:       return;
                    915: 
                    916:     case 'S':
                    917:       fprintf (file, "%d", (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD)-1);
                    918:       return;
                    919: 
                    920:     case 'V':
                    921:       if (GET_CODE (x) != PARALLEL)
                    922:        output_operand_lossage ("invalid %%V value");
                    923:       fprintf (file, "%d", XVECLEN (x, 0) - 2);
                    924:       return;
                    925: 
                    926:     case '#':
                    927:       if (dbr_sequence_length () == 0)
                    928:        {
                    929:          if (a29k_last_prologue_insn)
                    930:            {
                    931:              fprintf (file, "\n\t%s", a29k_last_prologue_insn);
                    932:              a29k_last_prologue_insn = 0;
                    933:            }
                    934:          else
                    935:            fprintf (file, "\n\tnop");
                    936:        }
                    937:       return;
                    938: 
                    939:     case '*':
                    940:       fprintf (file, "%s", reg_names [R_TPC]);
                    941:       return;
                    942:     }
                    943: 
                    944:   if (GET_CODE (x) == REG)
                    945:     fprintf (file, "%s", reg_names [REGNO (x)]);
                    946: 
                    947:   else if (GET_CODE (x) == MEM)
                    948:     output_address (XEXP (x, 0));
                    949: 
                    950:   else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == SUBREG
                    951:           && GET_CODE (SUBREG_REG (XEXP (x, 0))) == CONST_DOUBLE)
                    952:     {
                    953:       union real_extract u;
                    954: 
                    955:       if (GET_MODE (SUBREG_REG (XEXP (x, 0))) == SFmode)
                    956:        fprintf (file, "$float");
                    957:       else
                    958:        fprintf (file, "$double%d", SUBREG_WORD (XEXP (x, 0)));
                    959:       bcopy (&CONST_DOUBLE_LOW (SUBREG_REG (XEXP (x, 0))), &u, sizeof u);
                    960:       fprintf (file, "(%.20e)", u.d);
                    961:     }
                    962: 
                    963:   else if (GET_CODE (x) == CONST_DOUBLE
                    964:           && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
                    965:     {
                    966:       union real_extract u;
                    967: 
                    968:       bcopy (&CONST_DOUBLE_LOW (x), &u, sizeof u);
                    969:       fprintf (file, "$%s(%.20e)",
                    970:               GET_MODE (x) == SFmode ? "float" : "double0", u.d);
                    971:     }
                    972: 
                    973:   else
                    974:     output_addr_const (file, x);
                    975: }
                    976: 
                    977: /* This page contains routines to output function prolog and epilog code. */
                    978: 
                    979: /* Output function prolog code to file FILE.  Memory stack size is SIZE.
                    980: 
                    981:    Also sets register names for incoming arguments and frame pointer.  */
                    982: 
                    983: void
                    984: output_prolog (file, size)
                    985:      FILE *file;
                    986:      int size;
                    987: {
                    988:   int makes_calls = 0;
                    989:   int arg_count = 0;
                    990:   rtx insn;
                    991:   int i;
                    992:   unsigned int tag_word;
                    993: 
                    994:   /* See if we make any calls.  We need to set lr1 if so.  */
                    995:   for (insn = get_insns (); insn; insn = next_insn (insn))
                    996:     if (GET_CODE (insn) == CALL_INSN
                    997:        || (GET_CODE (insn) == INSN
                    998:            && GET_CODE (PATTERN (insn)) == SEQUENCE
                    999:            && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN))
                   1000:       {
                   1001:        makes_calls = 1;
                   1002:        break;
                   1003:       }
                   1004: 
                   1005:   /* Find the highest local register used.  */
                   1006:   for (i = R_LR (127); i >= R_LR (0); i--)
                   1007:     if (regs_ever_live[i])
                   1008:       break;
                   1009: 
                   1010:   a29k_regstack_size = i - (R_LR (0) - 1);
                   1011: 
                   1012:   /* If calling routines, ensure we count lr0 & lr1.  */
                   1013:   if (makes_calls && a29k_regstack_size < 2)
                   1014:     a29k_regstack_size = 2;
                   1015: 
                   1016:   /* Count frame pointer and align to 8 byte boundary (even number of
                   1017:      registers).  */
                   1018:   a29k_regstack_size += frame_pointer_needed;
                   1019:   if (a29k_regstack_size & 1) a29k_regstack_size++;
                   1020: 
                   1021:   /* See how many incoming arguments we have in registers.  */
                   1022:   for (i = R_AR (0); i < R_AR (16); i++)
                   1023:     if (! fixed_regs[i])
                   1024:       arg_count++;
                   1025: 
                   1026:   /* The argument count includes the caller's lr0 and lr1.  */
                   1027:   arg_count += 2;
                   1028: 
                   1029:   /* Set the names and numbers of the frame pointer and incoming argument
                   1030:      registers.  */
                   1031: 
                   1032:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                   1033:     a29k_debug_reg_map[i] = i;
                   1034: 
                   1035:   reg_names[FRAME_POINTER_REGNUM] = reg_names[R_LR (a29k_regstack_size - 1)];
                   1036:   a29k_debug_reg_map[FRAME_POINTER_REGNUM] = R_LR (a29k_regstack_size - 1);
                   1037: 
                   1038:   for (i = 0; i < 16; i++)
                   1039:     {
                   1040:       reg_names[R_AR (i)] = reg_names[R_LR (a29k_regstack_size + i + 2)];
                   1041:       a29k_debug_reg_map[R_AR (i)] = R_LR (a29k_regstack_size + i + 2);
                   1042:     }
                   1043: 
                   1044:   /* Compute memory stack size.  Add in number of bytes that the we should
                   1045:      push and pretend the caller did and the size of outgoing arguments.
                   1046:      Then round to a doubleword boundary.  */
                   1047:   size += (current_function_pretend_args_size
                   1048:           + current_function_outgoing_args_size);
                   1049:   size = (size + 7) & ~7;
                   1050: 
                   1051:   /* Write header words.  See if one or two word form.  */
                   1052:   tag_word = (frame_pointer_needed ? 0x400000 : 0) + (arg_count << 16);
                   1053: 
                   1054:   if (size / 8 > 0xff)
                   1055:     fprintf (file, "\t.word %d, 0x%0x\n", (size / 8) << 2,
                   1056:             0x800000 + tag_word);
                   1057:   else
                   1058:     fprintf (file, "\t.word 0x%0x\n", tag_word + ((size / 8) << 3));
                   1059: 
                   1060:   /* Define the function name.  */
                   1061:   assemble_name (file, a29k_function_name);
                   1062:   fprintf (file, ":\n");
                   1063: 
                   1064:   /* Push the register stack by the proper amount.  There are two possible
                   1065:      ways to do this.  */
                   1066:   if (a29k_regstack_size >= 256/4)
                   1067:     fprintf (file, "\tconst %s,%d\n\tsub gr1,gr1,%s\n",
                   1068:             reg_names[R_TAV], a29k_regstack_size * 4, reg_names[R_TAV]);
                   1069:   else if (a29k_regstack_size)
                   1070:     fprintf (file, "\tsub gr1,gr1,%d\n", a29k_regstack_size * 4);
                   1071: 
                   1072:   /* Test that the registers are available.  */
                   1073:   if (a29k_regstack_size)
                   1074:     fprintf (file, "\tasgeu V_%sSPILL,gr1,%s\n",
                   1075:             TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RAB]);
                   1076: 
                   1077:   /* Set up frame pointer, if one is needed.  */
                   1078:   if (frame_pointer_needed)
                   1079:     fprintf (file, "\tsll %s,%s,0\n", reg_names[FRAME_POINTER_REGNUM],
                   1080:             reg_names[R_MSP]);
                   1081: 
                   1082:   /* Make room for any frame space.  There are three ways to do this.  */
                   1083:   if (size >= 256)
                   1084:     {
                   1085:       fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size);
                   1086:       if (size >= 65536)
                   1087:        fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size);
                   1088:       if (TARGET_STACK_CHECK)
                   1089:        fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]);
                   1090:       fprintf (file, "\tsub %s,%s,%s\n",
                   1091:               reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]);
                   1092:     }
                   1093:   else if (size)
                   1094:     {
                   1095:       if (TARGET_STACK_CHECK)
                   1096:        fprintf (file, "\tcall %s,__msp_check\n", reg_names[R_TPC]);
                   1097:       fprintf (file, "\tsub %s,%s,%d\n",
                   1098:               reg_names[R_MSP], reg_names[R_MSP], size);
                   1099:     }
                   1100: 
                   1101:   /* If this routine will make calls, set lr1.  If we see an insn that
                   1102:      can use a delay slot before a call or jump, save this insn for that
                   1103:      slot (this condition is equivalent to seeing if we have an insn that
                   1104:      needs delay slots before an insn that has a filled delay slot).  */
                   1105:   a29k_last_prologue_insn = 0;
                   1106:   if (makes_calls)
                   1107:     {
                   1108:       i = (a29k_regstack_size + arg_count) * 4;
                   1109:       if (i >= 256)
                   1110:        fprintf (file, "\tconst %s,%d\n\tadd lr1,gr1,%s\n",
                   1111:                 reg_names[R_TAV], i, reg_names[R_TAV]);
                   1112:       else
                   1113:        {
                   1114:          if (optimize && flag_delayed_branch)
                   1115:            for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
                   1116:              {
                   1117:                if (GET_CODE (insn) == CODE_LABEL
                   1118:                    || (GET_CODE (insn) == INSN
                   1119:                        && GET_CODE (PATTERN (insn)) == SEQUENCE))
                   1120:                  break;
                   1121: 
                   1122:                if (GET_CODE (insn) == NOTE
                   1123:                    || (GET_CODE (insn) == INSN
                   1124:                        && (GET_CODE (PATTERN (insn)) == USE
                   1125:                            || GET_CODE (PATTERN (insn)) == CLOBBER)))
                   1126:                  continue;
                   1127: 
                   1128:                if (num_delay_slots (insn) > 0)
                   1129:                  {
                   1130:                    a29k_last_prologue_insn = (char *) oballoc (100);
                   1131:                    sprintf (a29k_last_prologue_insn, "add lr1,gr1,%d", i);
                   1132:                    break;
                   1133:                  }
                   1134:              }
                   1135: 
                   1136:          if (a29k_last_prologue_insn == 0)
                   1137:            fprintf (file, "\tadd lr1,gr1,%d\n", i);
                   1138:        }
                   1139:     }
                   1140: 
                   1141:   /* Compute the first insn of the epilogue.  */
                   1142:   a29k_first_epilogue_insn_used = 0;
                   1143: 
                   1144:   if (size == 0 && a29k_regstack_size == 0 && ! frame_pointer_needed)
                   1145:     a29k_first_epilogue_insn = 0;
                   1146:   else
                   1147:     a29k_first_epilogue_insn = (char *) oballoc (100);
                   1148: 
                   1149:   if (frame_pointer_needed)
                   1150:     sprintf (a29k_first_epilogue_insn, "sll %s,%s,0",
                   1151:             reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]);
                   1152:   else if (a29k_regstack_size)
                   1153:     {
                   1154:       if (a29k_regstack_size >= 256 / 4)
                   1155:        sprintf (a29k_first_epilogue_insn, "const %s,%d",
                   1156:                 reg_names[R_TAV], a29k_regstack_size * 4);
                   1157:       else
                   1158:        sprintf (a29k_first_epilogue_insn, "add gr1,gr1,%d",
                   1159:                 a29k_regstack_size * 4);
                   1160:     }
                   1161:   else if (size)
                   1162:     {
                   1163:       if (size >= 256)
                   1164:        sprintf (a29k_first_epilogue_insn, "const %s,%d",
                   1165:                 reg_names[R_TAV], size);
                   1166:       else
                   1167:        sprintf (a29k_first_epilogue_insn, "add %s,%s,%d",
                   1168:                 reg_names[R_MSP], reg_names[R_MSP], size);
                   1169:     }
                   1170: }
                   1171: 
                   1172: /* Call this after writing what might be the first instruction of the
                   1173:    epilogue.  If that first insn was used in a delay slot, an intermediate
                   1174:    label is written.  */
                   1175: 
                   1176: static void
                   1177: check_epilogue_internal_label (file)
                   1178:      FILE *file;
                   1179: {
                   1180:   rtx insn;
                   1181: 
                   1182:   if (! a29k_first_epilogue_insn_used)
                   1183:     return;
                   1184: 
                   1185:   for (insn = get_last_insn ();
                   1186:        GET_CODE (insn) != CODE_LABEL;
                   1187:        insn = PREV_INSN (insn))
                   1188:     ;
                   1189: 
                   1190:   ASM_OUTPUT_INTERNAL_LABEL (file, "LX", CODE_LABEL_NUMBER (insn));
                   1191:   a29k_first_epilogue_insn_used = 0;
                   1192: }
                   1193: 
                   1194: /* Output the epilog of the last procedure to file FILE.  SIZE is the memory
                   1195:    stack size.  The register stack size is in the variable
                   1196:    A29K_REGSTACK_SIZE.  */
                   1197: 
                   1198: void
                   1199: output_epilog (file, size)
                   1200:      FILE *file;
                   1201:      int size;
                   1202: {
                   1203:   rtx insn;
                   1204:   int locals_unavailable = 0;  /* True until after first insn
                   1205:                                   after gr1 update. */
                   1206: 
                   1207:   /* If we hit a BARRIER before a real insn or CODE_LABEL, we don't
                   1208:      need to do anything because we are never jumped to.  */
                   1209:   insn = get_last_insn ();
                   1210:   if (GET_CODE (insn) == NOTE)
                   1211:     insn = prev_nonnote_insn (insn);
                   1212: 
                   1213:   if (insn && GET_CODE (insn) == BARRIER)
                   1214:     return;
                   1215: 
                   1216:   /* If a frame pointer was needed we must restore the memory stack pointer
                   1217:      before adjusting the register stack.  */
                   1218:   if (frame_pointer_needed)
                   1219:     {
                   1220:       fprintf (file, "\tsll %s,%s,0\n",
                   1221:               reg_names[R_MSP], reg_names[FRAME_POINTER_REGNUM]);
                   1222:       check_epilogue_internal_label (file);
                   1223:     }
                   1224: 
                   1225:   /* Restore the register stack.  There are two ways to do this.  */
                   1226:   if (a29k_regstack_size)
                   1227:     {
                   1228:       if (a29k_regstack_size >= 256/4)
                   1229:        {
                   1230:          fprintf (file, "\tconst %s,%d\n",
                   1231:                   reg_names[R_TAV], a29k_regstack_size * 4);
                   1232:          check_epilogue_internal_label (file);
                   1233:          fprintf (file, "\tadd gr1,gr1,%s\n", reg_names[R_TAV]);
                   1234:        }
                   1235:       else
                   1236:        {
                   1237:          fprintf (file, "\tadd gr1,gr1,%d\n", a29k_regstack_size * 4);
                   1238:          check_epilogue_internal_label (file);
                   1239:        }
                   1240:       locals_unavailable = 1;
                   1241:     }
                   1242: 
                   1243:   /* Restore the memory stack pointer if there is no frame pointer.
                   1244:      Adjust the size to include any pretend arguments and pushed
                   1245:      arguments and round to doubleword boundary.  */
                   1246:   size += (current_function_pretend_args_size
                   1247:           + current_function_outgoing_args_size);
                   1248:   size = (size + 7) & ~7;
                   1249: 
                   1250:   if (size && ! frame_pointer_needed)
                   1251:     {
                   1252:       if (size >= 256)
                   1253:        {
                   1254:          fprintf (file, "\tconst %s,%d\n", reg_names[R_TAV], size);
                   1255:          check_epilogue_internal_label (file);
                   1256:          locals_unavailable = 0;
                   1257:          if (size >= 65536)
                   1258:            fprintf (file, "\tconsth %s,%d\n", reg_names[R_TAV], size);
                   1259:          fprintf (file, "\tadd %s,%s,%s\n",
                   1260:                   reg_names[R_MSP], reg_names[R_MSP], reg_names[R_TAV]);
                   1261:        }
                   1262:       else
                   1263:        {
                   1264:          fprintf (file, "\tadd %s,%s,%d\n",
                   1265:                   reg_names[R_MSP], reg_names[R_MSP], size);
                   1266:          check_epilogue_internal_label (file);
                   1267:          locals_unavailable = 0;
                   1268:        }
                   1269:     }
                   1270: 
                   1271:   if (locals_unavailable)
                   1272:     {
                   1273:       /* If we have an insn for this delay slot, write it.  */
                   1274:       if (current_function_epilogue_delay_list)
                   1275:        final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
                   1276:                         file, 1, -2, 1);
                   1277:       else
                   1278:        fprintf (file, "\tnop\n");
                   1279:     }
                   1280: 
                   1281:   fprintf (file, "\tjmpi lr0\n");
                   1282:   if (a29k_regstack_size)
                   1283:     fprintf (file, "\tasleu V_%sFILL,lr1,%s\n",
                   1284:             TARGET_KERNEL_REGISTERS ? "K" : "", reg_names[R_RFB]);
                   1285:   else if (current_function_epilogue_delay_list)
                   1286:     final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
                   1287:                     file, 1, -2, 1);
                   1288:   else
                   1289:     fprintf (file, "\tnop\n");
                   1290: }

unix.superglobalmegacorp.com

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