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

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

unix.superglobalmegacorp.com

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