Annotation of GNUtools/cc/config/a29k/a29k.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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