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

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

unix.superglobalmegacorp.com

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