Annotation of GNUtools/cc/reg-stack.c, revision 1.1

1.1     ! root        1: /* Register to Stack convert for GNU compiler.
        !             2:    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: /* This pass converts stack-like registers from the "flat register
        !            21:    file" model that gcc uses, to a stack convention that the 387 uses.
        !            22: 
        !            23:    * The form of the input:
        !            24: 
        !            25:    On input, the function consists of insn that have had their
        !            26:    registers fully allocated to a set of "virtual" registers.  Note that
        !            27:    the word "virtual" is used differently here than elsewhere in gcc: for
        !            28:    each virtual stack reg, there is a hard reg, but the mapping between
        !            29:    them is not known until this pass is run.  On output, hard register
        !            30:    numbers have been substituted, and various pop and exchange insns have
        !            31:    been emitted.  The hard register numbers and the virtual register
        !            32:    numbers completely overlap - before this pass, all stack register
        !            33:    numbers are virtual, and afterward they are all hard.
        !            34: 
        !            35:    The virtual registers can be manipulated normally by gcc, and their
        !            36:    semantics are the same as for normal registers.  After the hard
        !            37:    register numbers are substituted, the semantics of an insn containing
        !            38:    stack-like regs are not the same as for an insn with normal regs: for
        !            39:    instance, it is not safe to delete an insn that appears to be a no-op
        !            40:    move.  In general, no insn containing hard regs should be changed
        !            41:    after this pass is done.
        !            42: 
        !            43:    * The form of the output:
        !            44: 
        !            45:    After this pass, hard register numbers represent the distance from
        !            46:    the current top of stack to the desired register.  A reference to
        !            47:    FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1,
        !            48:    represents the register just below that, and so forth.  Also, REG_DEAD
        !            49:    notes indicate whether or not a stack register should be popped.
        !            50: 
        !            51:    A "swap" insn looks like a parallel of two patterns, where each
        !            52:    pattern is a SET: one sets A to B, the other B to A.
        !            53: 
        !            54:    A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG
        !            55:    and whose SET_DEST is REG or MEM.  Any other SET_DEST, such as PLUS,
        !            56:    will replace the existing stack top, not push a new value.
        !            57: 
        !            58:    A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose
        !            59:    SET_SRC is REG or MEM.
        !            60: 
        !            61:    The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG
        !            62:    appears ambiguous.  As a special case, the presence of a REG_DEAD note
        !            63:    for FIRST_STACK_REG differentiates between a load insn and a pop.
        !            64: 
        !            65:    If a REG_DEAD is present, the insn represents a "pop" that discards
        !            66:    the top of the register stack.  If there is no REG_DEAD note, then the
        !            67:    insn represents a "dup" or a push of the current top of stack onto the
        !            68:    stack.
        !            69: 
        !            70:    * Methodology:
        !            71: 
        !            72:    Existing REG_DEAD and REG_UNUSED notes for stack registers are
        !            73:    deleted and recreated from scratch.  REG_DEAD is never created for a
        !            74:    SET_DEST, only REG_UNUSED.
        !            75: 
        !            76:    Before life analysis, the mode of each insn is set based on whether
        !            77:    or not any stack registers are mentioned within that insn.  VOIDmode
        !            78:    means that no regs are mentioned anyway, and QImode means that at
        !            79:    least one pattern within the insn mentions stack registers.  This
        !            80:    information is valid until after reg_to_stack returns, and is used
        !            81:    from jump_optimize.
        !            82: 
        !            83:    * asm_operands:
        !            84: 
        !            85:    There are several rules on the usage of stack-like regs in
        !            86:    asm_operands insns.  These rules apply only to the operands that are
        !            87:    stack-like regs:
        !            88: 
        !            89:    1. Given a set of input regs that die in an asm_operands, it is
        !            90:       necessary to know which are implicitly popped by the asm, and
        !            91:       which must be explicitly popped by gcc.
        !            92: 
        !            93:        An input reg that is implicitly popped by the asm must be
        !            94:        explicitly clobbered, unless it is constrained to match an
        !            95:        output operand.
        !            96: 
        !            97:    2. For any input reg that is implicitly popped by an asm, it is
        !            98:       necessary to know how to adjust the stack to compensate for the pop.
        !            99:       If any non-popped input is closer to the top of the reg-stack than
        !           100:       the implicitly popped reg, it would not be possible to know what the
        !           101:       stack looked like - it's not clear how the rest of the stack "slides
        !           102:       up".
        !           103: 
        !           104:        All implicitly popped input regs must be closer to the top of
        !           105:        the reg-stack than any input that is not implicitly popped.
        !           106: 
        !           107:    3. It is possible that if an input dies in an insn, reload might
        !           108:       use the input reg for an output reload.  Consider this example:
        !           109: 
        !           110:                asm ("foo" : "=t" (a) : "f" (b));
        !           111: 
        !           112:       This asm says that input B is not popped by the asm, and that
        !           113:       the asm pushes a result onto the reg-stack, ie, the stack is one
        !           114:       deeper after the asm than it was before.  But, it is possible that
        !           115:       reload will think that it can use the same reg for both the input and
        !           116:       the output, if input B dies in this insn.
        !           117: 
        !           118:        If any input operand uses the "f" constraint, all output reg
        !           119:        constraints must use the "&" earlyclobber.
        !           120: 
        !           121:       The asm above would be written as
        !           122: 
        !           123:                asm ("foo" : "=&t" (a) : "f" (b));
        !           124: 
        !           125:    4. Some operands need to be in particular places on the stack.  All
        !           126:       output operands fall in this category - there is no other way to
        !           127:       know which regs the outputs appear in unless the user indicates
        !           128:       this in the constraints.
        !           129: 
        !           130:        Output operands must specifically indicate which reg an output
        !           131:        appears in after an asm.  "=f" is not allowed: the operand
        !           132:        constraints must select a class with a single reg.
        !           133: 
        !           134:    5. Output operands may not be "inserted" between existing stack regs.
        !           135:       Since no 387 opcode uses a read/write operand, all output operands
        !           136:       are dead before the asm_operands, and are pushed by the asm_operands.
        !           137:       It makes no sense to push anywhere but the top of the reg-stack.
        !           138: 
        !           139:        Output operands must start at the top of the reg-stack: output
        !           140:        operands may not "skip" a reg.
        !           141: 
        !           142:    6. Some asm statements may need extra stack space for internal
        !           143:       calculations.  This can be guaranteed by clobbering stack registers
        !           144:       unrelated to the inputs and outputs.
        !           145: 
        !           146:    Here are a couple of reasonable asms to want to write.  This asm
        !           147:    takes one input, which is internally popped, and produces two outputs.
        !           148: 
        !           149:        asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));
        !           150: 
        !           151:    This asm takes two inputs, which are popped by the fyl2xp1 opcode,
        !           152:    and replaces them with one output.  The user must code the "st(1)"
        !           153:    clobber for reg-stack.c to know that fyl2xp1 pops both inputs.
        !           154: 
        !           155:        asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
        !           156: 
        !           157:    */
        !           158: 
        !           159: #include <stdio.h>
        !           160: #include "config.h"
        !           161: #include "tree.h"
        !           162: #include "rtl.h"
        !           163: #include "insn-config.h"
        !           164: #include "regs.h"
        !           165: #include "hard-reg-set.h"
        !           166: #include "flags.h"
        !           167: 
        !           168: #ifdef STACK_REGS
        !           169: 
        !           170: #define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
        !           171: 
        !           172: /* True if the current function returns a real value. */
        !           173: static int current_function_returns_real;
        !           174: 
        !           175: /* This is the basic stack record.  TOP is an index into REG[] such
        !           176:    that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.
        !           177: 
        !           178:    If TOP is -2, REG[] is not yet initialized.  Stack initialization
        !           179:    consists of placing each live reg in array `reg' and setting `top'
        !           180:    appropriately.
        !           181: 
        !           182:    REG_SET indicates which registers are live.  */
        !           183: 
        !           184: typedef struct stack_def
        !           185: {
        !           186:   int top;                     /* index to top stack element */
        !           187:   HARD_REG_SET reg_set;                /* set of live registers */
        !           188:   char reg[REG_STACK_SIZE];    /* register - stack mapping */
        !           189: } *stack;
        !           190: 
        !           191: /* highest instruction uid */
        !           192: static int max_uid = 0;
        !           193: 
        !           194: /* Number of basic blocks in the current function.  */
        !           195: static int blocks;
        !           196: 
        !           197: /* Element N is first insn in basic block N.
        !           198:    This info lasts until we finish compiling the function.  */
        !           199: static rtx *block_begin;
        !           200: 
        !           201: /* Element N is last insn in basic block N.
        !           202:    This info lasts until we finish compiling the function.  */
        !           203: static rtx *block_end;
        !           204: 
        !           205: /* Element N is nonzero if control can drop into basic block N */
        !           206: static char *block_drops_in;
        !           207: 
        !           208: /* Element N says all about the stack at entry block N */
        !           209: static stack block_stack_in;
        !           210: 
        !           211: /* Element N says all about the stack life at the end of block N */
        !           212: static HARD_REG_SET *block_out_reg_set;
        !           213: 
        !           214: /* This is where the BLOCK_NUM values are really stored.  This is set
        !           215:    up by find_blocks and used there and in life_analysis.  It can be used
        !           216:    later, but only to look up an insn that is the head or tail of some
        !           217:    block.  life_analysis and the stack register conversion process can
        !           218:    add insns within a block. */
        !           219: static int *block_number;
        !           220: 
        !           221: /* This is the register file for all register after conversion */
        !           222: static rtx FP_mode_reg[FIRST_PSEUDO_REGISTER][(int) MAX_MACHINE_MODE];
        !           223: 
        !           224: /* Get the basic block number of an insn.  See note at block_number
        !           225:    definition are validity of this information. */
        !           226: 
        !           227: #define BLOCK_NUM(INSN)  \
        !           228:   (((INSN_UID (INSN) > max_uid)        \
        !           229:     ? (int *)(abort() , 0)             \
        !           230:     : block_number)[INSN_UID (INSN)])
        !           231: 
        !           232: extern rtx gen_jump ();
        !           233: extern rtx gen_movdf (), gen_movxf ();
        !           234: extern rtx find_regno_note ();
        !           235: extern rtx emit_jump_insn_before ();
        !           236: extern rtx emit_label_after ();
        !           237: 
        !           238: /* Forward declarations */
        !           239: 
        !           240: static void find_blocks ();
        !           241: static void stack_reg_life_analysis ();
        !           242: static void change_stack ();
        !           243: static void convert_regs ();
        !           244: static void dump_stack_info ();
        !           245: 
        !           246: /* Return non-zero if any stack register is mentioned somewhere within PAT.  */
        !           247: 
        !           248: int
        !           249: stack_regs_mentioned_p (pat)
        !           250:      rtx pat;
        !           251: {
        !           252:   register char *fmt;
        !           253:   register int i;
        !           254: 
        !           255:   if (STACK_REG_P (pat))
        !           256:     return 1;
        !           257: 
        !           258:   fmt = GET_RTX_FORMAT (GET_CODE (pat));
        !           259:   for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
        !           260:     {
        !           261:       if (fmt[i] == 'E')
        !           262:        {
        !           263:          register int j;
        !           264: 
        !           265:          for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
        !           266:            if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
        !           267:              return 1;
        !           268:        }
        !           269:       else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
        !           270:        return 1;
        !           271:     }
        !           272: 
        !           273:   return 0;
        !           274: }
        !           275: 
        !           276: /* Convert register usage from "flat" register file usage to a "stack
        !           277:    register file.  FIRST is the first insn in the function, FILE is the
        !           278:    dump file, if used.
        !           279: 
        !           280:    First compute the beginning and end of each basic block.  Do a
        !           281:    register life analysis on the stack registers, recording the result
        !           282:    for the head and tail of each basic block.  The convert each insn one
        !           283:    by one.  Run a last jump_optimize() pass, if optimizing, to eliminate
        !           284:    any cross-jumping created when the converter inserts pop insns.*/
        !           285: 
        !           286: void
        !           287: reg_to_stack (first, file)
        !           288:      rtx first;
        !           289:      FILE *file;
        !           290: {
        !           291:   register rtx insn;
        !           292:   register int i;
        !           293:   int stack_reg_seen = 0;
        !           294:   enum machine_mode mode;
        !           295: 
        !           296:   current_function_returns_real
        !           297:     = TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) == REAL_TYPE;
        !           298: 
        !           299:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
        !           300:        mode = GET_MODE_WIDER_MODE (mode))
        !           301:     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        !           302:       FP_mode_reg[i][(int) mode] = gen_rtx (REG, mode, i);
        !           303: 
        !           304:   /* Count the basic blocks.  Also find maximum insn uid.  */
        !           305:   {
        !           306:     register RTX_CODE prev_code = JUMP_INSN;
        !           307:     register RTX_CODE code;
        !           308: 
        !           309:     max_uid = 0;
        !           310:     blocks = 0;
        !           311:     for (insn = first; insn; insn = NEXT_INSN (insn))
        !           312:       {
        !           313:        /* Note that this loop must select the same block boundaries
        !           314:           as code in find_blocks. */
        !           315: 
        !           316:        if (INSN_UID (insn) > max_uid)
        !           317:          max_uid = INSN_UID (insn);
        !           318: 
        !           319:        code = GET_CODE (insn);
        !           320: 
        !           321:        if (code == CODE_LABEL
        !           322:            || (prev_code != INSN
        !           323:                && prev_code != CALL_INSN
        !           324:                && prev_code != CODE_LABEL
        !           325:                && (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
        !           326:          blocks++;
        !           327: 
        !           328:        /* Remember whether or not this insn mentions an FP regs.
        !           329:           Check JUMP_INSNs too, in case someone creates a funny PARALLEL. */
        !           330: 
        !           331:        if ((GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
        !           332:             || GET_CODE (insn) == JUMP_INSN)
        !           333:            && stack_regs_mentioned_p (PATTERN (insn)))
        !           334:          {
        !           335:            stack_reg_seen = 1;
        !           336:            PUT_MODE (insn, QImode);
        !           337:          }
        !           338:        else
        !           339:          PUT_MODE (insn, VOIDmode);
        !           340: 
        !           341:        if (code != NOTE)
        !           342:          prev_code = code;
        !           343:       }
        !           344:   }
        !           345: 
        !           346:   /* If no stack register reference exists in this insn, there isn't
        !           347:      anything to convert.  */
        !           348: 
        !           349:   if (! stack_reg_seen)
        !           350:     return;
        !           351: 
        !           352:   /* If there are stack registers, there must be at least one block. */
        !           353: 
        !           354:   if (! blocks)
        !           355:     abort ();
        !           356: 
        !           357:   /* Allocate some tables that last till end of compiling this function
        !           358:      and some needed only in find_blocks and life_analysis. */
        !           359: 
        !           360:   block_begin = (rtx *) alloca (blocks * sizeof (rtx));
        !           361:   block_end = (rtx *) alloca (blocks * sizeof (rtx));
        !           362:   block_drops_in = (char *) alloca (blocks);
        !           363: 
        !           364:   block_stack_in = (stack) alloca (blocks * sizeof (struct stack_def));
        !           365:   block_out_reg_set = (HARD_REG_SET *) alloca (blocks * sizeof (HARD_REG_SET));
        !           366:   bzero (block_stack_in, blocks * sizeof (struct stack_def));
        !           367:   bzero (block_out_reg_set, blocks * sizeof (HARD_REG_SET));
        !           368: 
        !           369:   block_number = (int *) alloca ((max_uid + 1) * sizeof (int));
        !           370: 
        !           371:   find_blocks (first);
        !           372:   stack_reg_life_analysis (first);
        !           373: 
        !           374:   /* Dump the life analysis debug information before jump
        !           375:      optimization, as that will destroy the LABEL_REFS we keep the
        !           376:      information in. */
        !           377: 
        !           378:   if (file)
        !           379:     dump_stack_info (file);
        !           380: 
        !           381:   convert_regs ();
        !           382: 
        !           383:   if (optimize)
        !           384:     jump_optimize (first, 2, 0, 0);
        !           385: }
        !           386: 
        !           387: /* Check PAT, which is in INSN, for LABEL_REFs.  Add INSN to the
        !           388:    label's chain of references, and note which insn contains each
        !           389:    reference. */
        !           390: 
        !           391: static void
        !           392: record_label_references (insn, pat)
        !           393:      rtx insn, pat;
        !           394: {
        !           395:   register enum rtx_code code = GET_CODE (pat);
        !           396:   register int i;
        !           397:   register char *fmt;
        !           398: 
        !           399:   if (code == LABEL_REF)
        !           400:     {
        !           401:       register rtx label = XEXP (pat, 0);
        !           402:       register rtx ref;
        !           403: 
        !           404:       if (GET_CODE (label) != CODE_LABEL)
        !           405:        abort ();
        !           406: 
        !           407:       /* Don't make a duplicate in the code_label's chain. */
        !           408: 
        !           409:       for (ref = LABEL_REFS (label);
        !           410:           ref && ref != label;
        !           411:           ref = LABEL_NEXTREF (ref))
        !           412:        if (CONTAINING_INSN (ref) == insn)
        !           413:          return;
        !           414: 
        !           415:       CONTAINING_INSN (pat) = insn;
        !           416:       LABEL_NEXTREF (pat) = LABEL_REFS (label);
        !           417:       LABEL_REFS (label) = pat;
        !           418: 
        !           419:       return;
        !           420:     }
        !           421: 
        !           422:   fmt = GET_RTX_FORMAT (code);
        !           423:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !           424:     {
        !           425:       if (fmt[i] == 'e')
        !           426:        record_label_references (insn, XEXP (pat, i));
        !           427:       if (fmt[i] == 'E')
        !           428:        {
        !           429:          register int j;
        !           430:          for (j = 0; j < XVECLEN (pat, i); j++)
        !           431:            record_label_references (insn, XVECEXP (pat, i, j));
        !           432:        }
        !           433:     }
        !           434: }
        !           435: 
        !           436: /* Return a pointer to the REG expression within PAT.  If PAT is not a
        !           437:    REG, possible enclosed by a conversion rtx, return the inner part of
        !           438:    PAT that stopped the search. */
        !           439: 
        !           440: static rtx *
        !           441: get_true_reg (pat)
        !           442:      rtx *pat;
        !           443: {
        !           444:   while (GET_CODE (*pat) == SUBREG
        !           445:         || GET_CODE (*pat) == FLOAT
        !           446:         || GET_CODE (*pat) == FIX
        !           447:         || GET_CODE (*pat) == FLOAT_EXTEND)
        !           448:     pat = & XEXP (*pat, 0);
        !           449: 
        !           450:   return pat;
        !           451: }
        !           452: 
        !           453: /* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands.
        !           454:    N_OPERANDS is the total number of operands.  Return which alternative
        !           455:    matched, or -1 is no alternative matches.
        !           456: 
        !           457:    OPERAND_MATCHES is an array which indicates which operand this
        !           458:    operand matches due to the constraints, or -1 if no match is required.
        !           459:    If two operands match by coincidence, but are not required to match by
        !           460:    the constraints, -1 is returned.
        !           461: 
        !           462:    OPERAND_CLASS is an array which indicates the smallest class
        !           463:    required by the constraints.  If the alternative that matches calls
        !           464:    for some class `class', and the operand matches a subclass of `class',
        !           465:    OPERAND_CLASS is set to `class' as required by the constraints, not to
        !           466:    the subclass. If an alternative allows more than one class,
        !           467:    OPERAND_CLASS is set to the smallest class that is a union of the
        !           468:    allowed classes. */
        !           469: 
        !           470: static int
        !           471: constrain_asm_operands (n_operands, operands, operand_constraints,
        !           472:                        operand_matches, operand_class)
        !           473:      int n_operands;
        !           474:      rtx *operands;
        !           475:      char **operand_constraints;
        !           476:      int *operand_matches;
        !           477:      enum reg_class *operand_class;
        !           478: {
        !           479:   char **constraints = (char **) alloca (n_operands * sizeof (char *));
        !           480:   char *q;
        !           481:   int this_alternative, this_operand;
        !           482:   int n_alternatives;
        !           483:   int j;
        !           484: 
        !           485:   for (j = 0; j < n_operands; j++)
        !           486:     constraints[j] = operand_constraints[j];
        !           487: 
        !           488:   /* Compute the number of alternatives in the operands.  reload has
        !           489:      already guaranteed that all operands have the same number of
        !           490:      alternatives.  */
        !           491: 
        !           492:   n_alternatives = 1;
        !           493:   for (q = constraints[0]; *q; q++)
        !           494:     n_alternatives += (*q == ',');
        !           495: 
        !           496:   this_alternative = 0;
        !           497:   while (this_alternative < n_alternatives)
        !           498:     {
        !           499:       int lose = 0;
        !           500:       int i;
        !           501: 
        !           502:       /* No operands match, no narrow class requirements yet.  */
        !           503:       for (i = 0; i < n_operands; i++)
        !           504:        {
        !           505:          operand_matches[i] = -1;
        !           506:          operand_class[i] = NO_REGS;
        !           507:        }
        !           508: 
        !           509:       for (this_operand = 0; this_operand < n_operands; this_operand++)
        !           510:        {
        !           511:          rtx op = operands[this_operand];
        !           512:          enum machine_mode mode = GET_MODE (op);
        !           513:          char *p = constraints[this_operand];
        !           514:          int offset = 0;
        !           515:          int win = 0;
        !           516:          int c;
        !           517: 
        !           518:          if (GET_CODE (op) == SUBREG)
        !           519:            {
        !           520:              if (GET_CODE (SUBREG_REG (op)) == REG
        !           521:                  && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
        !           522:                offset = SUBREG_WORD (op);
        !           523:              op = SUBREG_REG (op);
        !           524:            }
        !           525: 
        !           526:          /* An empty constraint or empty alternative
        !           527:             allows anything which matched the pattern.  */
        !           528:          if (*p == 0 || *p == ',')
        !           529:            win = 1;
        !           530: 
        !           531:          while (*p && (c = *p++) != ',')
        !           532:            switch (c)
        !           533:              {
        !           534:              case '=':
        !           535:              case '+':
        !           536:              case '?':
        !           537:              case '&':
        !           538:              case '!':
        !           539:              case '*':
        !           540:              case '%':
        !           541:                /* Ignore these. */
        !           542:                break;
        !           543: 
        !           544:              case '#':
        !           545:                /* Ignore rest of this alternative. */
        !           546:                while (*p && *p != ',') p++;
        !           547:                break;
        !           548: 
        !           549:              case '0':
        !           550:              case '1':
        !           551:              case '2':
        !           552:              case '3':
        !           553:              case '4':
        !           554:              case '5':
        !           555:                /* This operand must be the same as a previous one.
        !           556:                   This kind of constraint is used for instructions such
        !           557:                   as add when they take only two operands.
        !           558: 
        !           559:                   Note that the lower-numbered operand is passed first. */
        !           560: 
        !           561:                if (operands_match_p (operands[c - '0'],
        !           562:                                      operands[this_operand]))
        !           563:                  {
        !           564:                    operand_matches[this_operand] = c - '0';
        !           565:                    win = 1;
        !           566:                  }
        !           567:                break;
        !           568: 
        !           569:              case 'p':
        !           570:                /* p is used for address_operands.  Since this is an asm,
        !           571:                   just to make sure that the operand is valid for Pmode. */
        !           572: 
        !           573:                if (strict_memory_address_p (Pmode, op))
        !           574:                  win = 1;
        !           575:                break;
        !           576: 
        !           577:              case 'g':
        !           578:                /* Anything goes unless it is a REG and really has a hard reg
        !           579:                   but the hard reg is not in the class GENERAL_REGS.  */
        !           580:                if (GENERAL_REGS == ALL_REGS
        !           581:                    || GET_CODE (op) != REG
        !           582:                    || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
        !           583:                  {
        !           584:                    if (GET_CODE (op) == REG)
        !           585:                      operand_class[this_operand]
        !           586:                        = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
        !           587:                    win = 1;
        !           588:                  }
        !           589:                break;
        !           590: 
        !           591:              case 'r':
        !           592:                if (GET_CODE (op) == REG
        !           593:                    && (GENERAL_REGS == ALL_REGS
        !           594:                        || reg_fits_class_p (op, GENERAL_REGS, offset, mode)))
        !           595:                  {
        !           596:                    operand_class[this_operand]
        !           597:                      = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
        !           598:                    win = 1;
        !           599:                  }
        !           600:                break;
        !           601: 
        !           602:              case 'X':
        !           603:                /* This is used for a MATCH_SCRATCH in the cases when we
        !           604:                   don't actually need anything.  So anything goes any time. */
        !           605:                win = 1;
        !           606:                break;
        !           607: 
        !           608:              case 'm':
        !           609:                if (GET_CODE (op) == MEM)
        !           610:                  win = 1;
        !           611:                break;
        !           612: 
        !           613:              case '<':
        !           614:                if (GET_CODE (op) == MEM
        !           615:                    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
        !           616:                        || GET_CODE (XEXP (op, 0)) == POST_DEC))
        !           617:                  win = 1;
        !           618:                break;
        !           619: 
        !           620:              case '>':
        !           621:                if (GET_CODE (op) == MEM
        !           622:                    && (GET_CODE (XEXP (op, 0)) == PRE_INC
        !           623:                        || GET_CODE (XEXP (op, 0)) == POST_INC))
        !           624:                  win = 1;
        !           625:                break;
        !           626: 
        !           627:              case 'E':
        !           628:                /* Match any CONST_DOUBLE, but only if
        !           629:                   we can examine the bits of it reliably.  */
        !           630:                if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
        !           631:                     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
        !           632:                    && GET_CODE (op) != VOIDmode && ! flag_pretend_float)
        !           633:                  break;
        !           634:                if (GET_CODE (op) == CONST_DOUBLE)
        !           635:                  win = 1;
        !           636:                break;
        !           637: 
        !           638:              case 'F':
        !           639:                if (GET_CODE (op) == CONST_DOUBLE)
        !           640:                  win = 1;
        !           641:                break;
        !           642: 
        !           643:              case 'G':
        !           644:              case 'H':
        !           645:                if (GET_CODE (op) == CONST_DOUBLE
        !           646:                    && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
        !           647:                  win = 1;
        !           648:                break;
        !           649: 
        !           650:              case 's':
        !           651:                if (GET_CODE (op) == CONST_INT
        !           652:                    || (GET_CODE (op) == CONST_DOUBLE
        !           653:                        && GET_MODE (op) == VOIDmode))
        !           654:                  break;
        !           655:                /* Fall through */
        !           656:              case 'i':
        !           657:                if (CONSTANT_P (op))
        !           658:                  win = 1;
        !           659:                break;
        !           660: 
        !           661:              case 'n':
        !           662:                if (GET_CODE (op) == CONST_INT
        !           663:                    || (GET_CODE (op) == CONST_DOUBLE
        !           664:                        && GET_MODE (op) == VOIDmode))
        !           665:                  win = 1;
        !           666:                break;
        !           667: 
        !           668:              case 'I':
        !           669:              case 'J':
        !           670:              case 'K':
        !           671:              case 'L':
        !           672:              case 'M':
        !           673:              case 'N':
        !           674:              case 'O':
        !           675:              case 'P':
        !           676:                if (GET_CODE (op) == CONST_INT
        !           677:                    && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
        !           678:                  win = 1;
        !           679:                break;
        !           680: 
        !           681: #ifdef EXTRA_CONSTRAINT
        !           682:               case 'Q':
        !           683:               case 'R':
        !           684:               case 'S':
        !           685:               case 'T':
        !           686:               case 'U':
        !           687:                if (EXTRA_CONSTRAINT (op, c))
        !           688:                  win = 1;
        !           689:                break;
        !           690: #endif
        !           691: 
        !           692:              case 'V':
        !           693:                if (GET_CODE (op) == MEM && ! offsettable_memref_p (op))
        !           694:                  win = 1;
        !           695:                break;
        !           696: 
        !           697:              case 'o':
        !           698:                if (offsettable_memref_p (op))
        !           699:                  win = 1;
        !           700:                break;
        !           701: 
        !           702:              default:
        !           703:                if (GET_CODE (op) == REG
        !           704:                    && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
        !           705:                                         offset, mode))
        !           706:                  {
        !           707:                    operand_class[this_operand]
        !           708:                      = reg_class_subunion[(int)operand_class[this_operand]][(int) REG_CLASS_FROM_LETTER (c)];
        !           709:                    win = 1;
        !           710:                  }
        !           711:              }
        !           712: 
        !           713:          constraints[this_operand] = p;
        !           714:          /* If this operand did not win somehow,
        !           715:             this alternative loses.  */
        !           716:          if (! win)
        !           717:            lose = 1;
        !           718:        }
        !           719:       /* This alternative won; the operands are ok.
        !           720:         Change whichever operands this alternative says to change.  */
        !           721:       if (! lose)
        !           722:        break;
        !           723: 
        !           724:       this_alternative++;
        !           725:     }
        !           726: 
        !           727:   /* For operands constrained to match another operand, copy the other
        !           728:      operand's class to this operand's class. */
        !           729:   for (j = 0; j < n_operands; j++)
        !           730:     if (operand_matches[j] >= 0)
        !           731:       operand_class[j] = operand_class[operand_matches[j]];
        !           732: 
        !           733:   return this_alternative == n_alternatives ? -1 : this_alternative;
        !           734: }
        !           735: 
        !           736: /* Record the life info of each stack reg in INSN, updating REGSTACK.
        !           737:    N_INPUTS is the number of inputs; N_OUTPUTS the outputs.  CONSTRAINTS
        !           738:    is an array of the constraint strings used in the asm statement.
        !           739:    OPERANDS is an array of all operands for the insn, and is assumed to
        !           740:    contain all output operands, then all inputs operands.
        !           741: 
        !           742:    There are many rules that an asm statement for stack-like regs must
        !           743:    follow.  Those rules are explained at the top of this file: the rule
        !           744:    numbers below refer to that explanation. */
        !           745: 
        !           746: static void
        !           747: record_asm_reg_life (insn, regstack, operands, constraints,
        !           748:                     n_inputs, n_outputs)
        !           749:      rtx insn;
        !           750:      stack regstack;
        !           751:      rtx *operands;
        !           752:      char **constraints;
        !           753:      int n_inputs, n_outputs;
        !           754: {
        !           755:   int i;
        !           756:   int n_operands = n_inputs + n_outputs;
        !           757:   int first_input = n_outputs;
        !           758:   int n_clobbers;
        !           759:   int malformed_asm = 0;
        !           760:   rtx body = PATTERN (insn);
        !           761: 
        !           762:   int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
        !           763: 
        !           764:   enum reg_class *operand_class 
        !           765:     = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
        !           766: 
        !           767:   int reg_used_as_output[FIRST_PSEUDO_REGISTER];
        !           768:   int implicitly_dies[FIRST_PSEUDO_REGISTER];
        !           769: 
        !           770:   rtx *clobber_reg;
        !           771: 
        !           772:   /* Find out what the constraints require.  If no constraint
        !           773:      alternative matches, this asm is malformed.  */
        !           774:   i = constrain_asm_operands (n_operands, operands, constraints,
        !           775:                              operand_matches, operand_class);
        !           776:   if (i < 0)
        !           777:     malformed_asm = 1;
        !           778: 
        !           779:   /* Strip SUBREGs here to make the following code simpler. */
        !           780:   for (i = 0; i < n_operands; i++)
        !           781:     if (GET_CODE (operands[i]) == SUBREG
        !           782:        && GET_CODE (SUBREG_REG (operands[i])) == REG)
        !           783:       operands[i] = SUBREG_REG (operands[i]);
        !           784: 
        !           785:   /* Set up CLOBBER_REG.  */
        !           786: 
        !           787:   n_clobbers = 0;
        !           788: 
        !           789:   if (GET_CODE (body) == PARALLEL)
        !           790:     {
        !           791:       clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
        !           792: 
        !           793:       for (i = 0; i < XVECLEN (body, 0); i++)
        !           794:        if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
        !           795:          {
        !           796:            rtx clobber = XVECEXP (body, 0, i);
        !           797:            rtx reg = XEXP (clobber, 0);
        !           798: 
        !           799:            if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
        !           800:              reg = SUBREG_REG (reg);
        !           801: 
        !           802:            if (STACK_REG_P (reg))
        !           803:              {
        !           804:                clobber_reg[n_clobbers] = reg;
        !           805:                n_clobbers++;
        !           806:              }
        !           807:          }
        !           808:     }
        !           809: 
        !           810:   /* Enforce rule #4: Output operands must specifically indicate which
        !           811:      reg an output appears in after an asm.  "=f" is not allowed: the
        !           812:      operand constraints must select a class with a single reg.
        !           813: 
        !           814:      Also enforce rule #5: Output operands must start at the top of
        !           815:      the reg-stack: output operands may not "skip" a reg. */
        !           816: 
        !           817:   bzero (reg_used_as_output, sizeof (reg_used_as_output));
        !           818:   for (i = 0; i < n_outputs; i++)
        !           819:     if (STACK_REG_P (operands[i]))
        !           820:       if (reg_class_size[(int) operand_class[i]] != 1)
        !           821:        {
        !           822:          error_for_asm
        !           823:            (insn, "Output constraint %d must specify a single register", i);
        !           824:          malformed_asm = 1;
        !           825:        }
        !           826:       else
        !           827:        reg_used_as_output[REGNO (operands[i])] = 1;
        !           828: 
        !           829: 
        !           830:   /* Search for first non-popped reg.  */
        !           831:   for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
        !           832:     if (! reg_used_as_output[i])
        !           833:       break;
        !           834: 
        !           835:   /* If there are any other popped regs, that's an error.  */
        !           836:   for (; i < LAST_STACK_REG + 1; i++)
        !           837:     if (reg_used_as_output[i])
        !           838:       break;
        !           839: 
        !           840:   if (i != LAST_STACK_REG + 1)
        !           841:     {
        !           842:       error_for_asm (insn, "Output regs must be grouped at top of stack");
        !           843:       malformed_asm = 1;
        !           844:     }
        !           845: 
        !           846:   /* Enforce rule #2: All implicitly popped input regs must be closer
        !           847:      to the top of the reg-stack than any input that is not implicitly
        !           848:      popped. */
        !           849: 
        !           850:   bzero (implicitly_dies, sizeof (implicitly_dies));
        !           851:   for (i = first_input; i < first_input + n_inputs; i++)
        !           852:     if (STACK_REG_P (operands[i]))
        !           853:       {
        !           854:        /* An input reg is implicitly popped if it is tied to an
        !           855:           output, or if there is a CLOBBER for it. */
        !           856:        int j;
        !           857: 
        !           858:        for (j = 0; j < n_clobbers; j++)
        !           859:          if (operands_match_p (clobber_reg[j], operands[i]))
        !           860:            break;
        !           861: 
        !           862:        if (j < n_clobbers || operand_matches[i] >= 0)
        !           863:          implicitly_dies[REGNO (operands[i])] = 1;
        !           864:       }
        !           865: 
        !           866:   /* Search for first non-popped reg.  */
        !           867:   for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
        !           868:     if (! implicitly_dies[i])
        !           869:       break;
        !           870: 
        !           871:   /* If there are any other popped regs, that's an error.  */
        !           872:   for (; i < LAST_STACK_REG + 1; i++)
        !           873:     if (implicitly_dies[i])
        !           874:       break;
        !           875: 
        !           876:   if (i != LAST_STACK_REG + 1)
        !           877:     {
        !           878:       error_for_asm (insn,
        !           879:                     "Implicitly popped regs must be grouped at top of stack");
        !           880:       malformed_asm = 1;
        !           881:     }
        !           882: 
        !           883:   /* Enfore rule #3: If any input operand uses the "f" constraint, all
        !           884:      output constraints must use the "&" earlyclobber.
        !           885: 
        !           886:      ???  Detect this more deterministically by having constraint_asm_operands
        !           887:      record any earlyclobber. */
        !           888: 
        !           889:   for (i = first_input; i < first_input + n_inputs; i++)
        !           890:     if (operand_matches[i] == -1)
        !           891:       {
        !           892:        int j;
        !           893: 
        !           894:        for (j = 0; j < n_outputs; j++)
        !           895:          if (operands_match_p (operands[j], operands[i]))
        !           896:            {
        !           897:              error_for_asm (insn,
        !           898:                             "Output operand %d must use `&' constraint", j);
        !           899:              malformed_asm = 1;
        !           900:            }
        !           901:       }
        !           902: 
        !           903:   if (malformed_asm)
        !           904:     {
        !           905:       /* Avoid further trouble with this insn.  */
        !           906:       PATTERN (insn) = gen_rtx (USE, VOIDmode, const0_rtx);
        !           907:       PUT_MODE (insn, VOIDmode);
        !           908:       return;
        !           909:     }
        !           910: 
        !           911:   /* Process all outputs */
        !           912:   for (i = 0; i < n_outputs; i++)
        !           913:     {
        !           914:       rtx op = operands[i];
        !           915: 
        !           916:       if (! STACK_REG_P (op))
        !           917:        if (stack_regs_mentioned_p (op))
        !           918:          abort ();
        !           919:        else
        !           920:          continue;
        !           921: 
        !           922:       /* Each destination is dead before this insn.  If the
        !           923:         destination is not used after this insn, record this with
        !           924:         REG_UNUSED.  */
        !           925: 
        !           926:       if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (op)))
        !           927:        REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, op,
        !           928:                                    REG_NOTES (insn));
        !           929: 
        !           930:       CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (op));
        !           931:     }
        !           932: 
        !           933:   /* Process all inputs */
        !           934:   for (i = first_input; i < first_input + n_inputs; i++)
        !           935:     {
        !           936:       if (! STACK_REG_P (operands[i]))
        !           937:        if (stack_regs_mentioned_p (operands[i]))
        !           938:          abort ();
        !           939:        else
        !           940:          continue;
        !           941: 
        !           942:       /* If an input is dead after the insn, record a death note.
        !           943:         But don't record a death note if there is already a death note,
        !           944:         or if the input is also an output.  */
        !           945: 
        !           946:       if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]))
        !           947:          && operand_matches[i] == -1
        !           948:          && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) == NULL_RTX)
        !           949:        REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, operands[i],
        !           950:                                    REG_NOTES (insn));
        !           951: 
        !           952:       SET_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]));
        !           953:     }
        !           954: }
        !           955: 
        !           956: /* Scan PAT, which is part of INSN, and record registers appearing in
        !           957:    a SET_DEST in DEST, and other registers in SRC.
        !           958: 
        !           959:    This function does not know about SET_DESTs that are both input and
        !           960:    output (such as ZERO_EXTRACT) - this cannot happen on a 387. */
        !           961: 
        !           962: void
        !           963: record_reg_life_pat (pat, src, dest)
        !           964:      rtx pat;
        !           965:      HARD_REG_SET *src, *dest;
        !           966: {
        !           967:   register char *fmt;
        !           968:   register int i;
        !           969: 
        !           970:   if (STACK_REG_P (pat))
        !           971:     {
        !           972:       if (src)
        !           973:        SET_HARD_REG_BIT (*src, REGNO (pat));
        !           974: 
        !           975:       if (dest)
        !           976:        SET_HARD_REG_BIT (*dest, REGNO (pat));
        !           977: 
        !           978:       return;
        !           979:     }
        !           980: 
        !           981:   if (GET_CODE (pat) == SET)
        !           982:     {
        !           983:       record_reg_life_pat (XEXP (pat, 0), NULL_PTR, dest);
        !           984:       record_reg_life_pat (XEXP (pat, 1), src, NULL_PTR);
        !           985:       return;
        !           986:     }
        !           987: 
        !           988:   /* We don't need to consider either of these cases. */
        !           989:   if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
        !           990:     return;
        !           991: 
        !           992:   fmt = GET_RTX_FORMAT (GET_CODE (pat));
        !           993:   for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
        !           994:     {
        !           995:       if (fmt[i] == 'E')
        !           996:        {
        !           997:          register int j;
        !           998: 
        !           999:          for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
        !          1000:            record_reg_life_pat (XVECEXP (pat, i, j), src, dest);
        !          1001:        }
        !          1002:       else if (fmt[i] == 'e')
        !          1003:        record_reg_life_pat (XEXP (pat, i), src, dest);
        !          1004:     }
        !          1005: }
        !          1006: 
        !          1007: /* Calculate the number of inputs and outputs in BODY, an
        !          1008:    asm_operands.  N_OPERANDS is the total number of operands, and
        !          1009:    N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
        !          1010:    placed. */
        !          1011: 
        !          1012: static void
        !          1013: get_asm_operand_lengths (body, n_operands, n_inputs, n_outputs)
        !          1014:      rtx body;
        !          1015:      int n_operands;
        !          1016:      int *n_inputs, *n_outputs;
        !          1017: {
        !          1018:   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
        !          1019:     *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
        !          1020: 
        !          1021:   else if (GET_CODE (body) == ASM_OPERANDS)
        !          1022:     *n_inputs = ASM_OPERANDS_INPUT_LENGTH (body);
        !          1023: 
        !          1024:   else if (GET_CODE (body) == PARALLEL
        !          1025:           && GET_CODE (XVECEXP (body, 0, 0)) == SET)
        !          1026:     *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));
        !          1027: 
        !          1028:   else if (GET_CODE (body) == PARALLEL
        !          1029:           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
        !          1030:     *n_inputs = ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
        !          1031:   else
        !          1032:     abort ();
        !          1033: 
        !          1034:   *n_outputs = n_operands - *n_inputs;
        !          1035: }
        !          1036: 
        !          1037: /* Scan INSN, which is in BLOCK, and record the life & death of stack
        !          1038:    registers in REGSTACK.  This function is called to process insns from
        !          1039:    the last insn in a block to the first.  The actual scanning is done in
        !          1040:    record_reg_life_pat.
        !          1041: 
        !          1042:    If a register is live after a CALL_INSN, but is not a value return
        !          1043:    register for that CALL_INSN, then code is emitted to initialize that
        !          1044:    register.  The block_end[] data is kept accurate.
        !          1045: 
        !          1046:    Existing death and unset notes for stack registers are deleted
        !          1047:    before processing the insn. */
        !          1048: 
        !          1049: static void
        !          1050: record_reg_life (insn, block, regstack)
        !          1051:      rtx insn;
        !          1052:      int block;
        !          1053:      stack regstack;
        !          1054: {
        !          1055:   rtx note, *note_link;
        !          1056:   int n_operands;
        !          1057: 
        !          1058:   if ((GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
        !          1059:       || INSN_DELETED_P (insn))
        !          1060:     return;
        !          1061: 
        !          1062:   /* Strip death notes for stack regs from this insn */
        !          1063: 
        !          1064:   note_link = &REG_NOTES(insn);
        !          1065:   for (note = *note_link; note; note = XEXP (note, 1))
        !          1066:     if (STACK_REG_P (XEXP (note, 0))
        !          1067:        && (REG_NOTE_KIND (note) == REG_DEAD
        !          1068:            || REG_NOTE_KIND (note) == REG_UNUSED))
        !          1069:       *note_link = XEXP (note, 1);
        !          1070:     else
        !          1071:       note_link = &XEXP (note, 1);
        !          1072: 
        !          1073:   /* Process all patterns in the insn. */
        !          1074: 
        !          1075:   n_operands = asm_noperands (PATTERN (insn));
        !          1076:   if (n_operands >= 0)
        !          1077:     {
        !          1078:       /* This insn is an `asm' with operands.  Decode the operands,
        !          1079:         decide how many are inputs, and record the life information. */
        !          1080: 
        !          1081:       rtx operands[MAX_RECOG_OPERANDS];
        !          1082:       rtx body = PATTERN (insn);
        !          1083:       int n_inputs, n_outputs;
        !          1084:       char **constraints = (char **) alloca (n_operands * sizeof (char *));
        !          1085: 
        !          1086:       decode_asm_operands (body, operands, NULL_PTR, constraints, NULL_PTR);
        !          1087:       get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
        !          1088:       record_asm_reg_life (insn, regstack, operands, constraints,
        !          1089:                           n_inputs, n_outputs);
        !          1090:       return;
        !          1091:     }
        !          1092: 
        !          1093:   /* An insn referencing a stack reg has a mode of QImode. */
        !          1094:   if (GET_MODE (insn) == QImode)
        !          1095:     {
        !          1096:       HARD_REG_SET src, dest;
        !          1097:       int regno;
        !          1098: 
        !          1099:       CLEAR_HARD_REG_SET (src);
        !          1100:       CLEAR_HARD_REG_SET (dest);
        !          1101:       record_reg_life_pat (PATTERN (insn), &src, &dest);
        !          1102: 
        !          1103:       for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
        !          1104:        if (! TEST_HARD_REG_BIT (regstack->reg_set, regno))
        !          1105:          {
        !          1106:            if (TEST_HARD_REG_BIT (src, regno)
        !          1107:                && ! TEST_HARD_REG_BIT (dest, regno))
        !          1108:              REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
        !          1109:                                          FP_mode_reg[regno][(int) DFmode],
        !          1110:                                          REG_NOTES (insn));
        !          1111:            else if (TEST_HARD_REG_BIT (dest, regno))
        !          1112:              REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED,
        !          1113:                                          FP_mode_reg[regno][(int) DFmode],
        !          1114:                                          REG_NOTES (insn));
        !          1115:          }
        !          1116: 
        !          1117:       AND_COMPL_HARD_REG_SET (regstack->reg_set, dest);
        !          1118:       IOR_HARD_REG_SET (regstack->reg_set, src);
        !          1119:     }
        !          1120: 
        !          1121:   /* There might be a reg that is live after a function call.
        !          1122:      Initialize it to zero so that the program does not crash.  See comment
        !          1123:      towards the end of stack_reg_life_analysis(). */
        !          1124: 
        !          1125:   if (GET_CODE (insn) == CALL_INSN)
        !          1126:     {
        !          1127:       int reg = FIRST_FLOAT_REG;
        !          1128: 
        !          1129:       /* If a stack reg is mentioned in a CALL_INSN, it must be as the
        !          1130:         return value.  */
        !          1131: 
        !          1132:       if (stack_regs_mentioned_p (PATTERN (insn)))
        !          1133:        reg++;
        !          1134: 
        !          1135:       for (; reg <= LAST_STACK_REG; reg++)
        !          1136:        if (TEST_HARD_REG_BIT (regstack->reg_set, reg))
        !          1137:          {
        !          1138:            rtx init, pat;
        !          1139: 
        !          1140:            /* The insn will use virtual register numbers, and so
        !          1141:               convert_regs is expected to process these.  But BLOCK_NUM
        !          1142:               cannot be used on these insns, because they do not appear in
        !          1143:               block_number[]. */
        !          1144: 
        !          1145:            pat = gen_rtx (SET, VOIDmode, FP_mode_reg[reg][(int) DFmode],
        !          1146:                           CONST0_RTX (DFmode));
        !          1147:            init = emit_insn_after (pat, insn);
        !          1148:            PUT_MODE (init, QImode);
        !          1149: 
        !          1150:            CLEAR_HARD_REG_BIT (regstack->reg_set, reg);
        !          1151: 
        !          1152:            /* If the CALL_INSN was the end of a block, move the
        !          1153:               block_end to point to the new insn. */
        !          1154: 
        !          1155:            if (block_end[block] == insn)
        !          1156:              block_end[block] = init;
        !          1157:          }
        !          1158: 
        !          1159:       /* Some regs do not survive a CALL */
        !          1160: 
        !          1161:       AND_COMPL_HARD_REG_SET (regstack->reg_set, call_used_reg_set);
        !          1162:     }
        !          1163: }
        !          1164: 
        !          1165: /* Find all basic blocks of the function, which starts with FIRST.
        !          1166:    For each JUMP_INSN, build the chain of LABEL_REFS on each CODE_LABEL. */
        !          1167: 
        !          1168: static void
        !          1169: find_blocks (first)
        !          1170:      rtx first;
        !          1171: {
        !          1172:   register rtx insn;
        !          1173:   register int block;
        !          1174:   register RTX_CODE prev_code = BARRIER;
        !          1175:   register RTX_CODE code;
        !          1176: 
        !          1177:   /* Record where all the blocks start and end.
        !          1178:      Record which basic blocks control can drop in to. */
        !          1179: 
        !          1180:   block = -1;
        !          1181:   for (insn = first; insn; insn = NEXT_INSN (insn))
        !          1182:     {
        !          1183:       /* Note that this loop must select the same block boundaries
        !          1184:         as code in reg_to_stack. */
        !          1185: 
        !          1186:       code = GET_CODE (insn);
        !          1187: 
        !          1188:       if (code == CODE_LABEL
        !          1189:          || (prev_code != INSN
        !          1190:              && prev_code != CALL_INSN
        !          1191:              && prev_code != CODE_LABEL
        !          1192:              && (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
        !          1193:        {
        !          1194:          block_begin[++block] = insn;
        !          1195:          block_end[block] = insn;
        !          1196:          block_drops_in[block] = prev_code != BARRIER;
        !          1197:        }
        !          1198:       else if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
        !          1199:        block_end[block] = insn;
        !          1200: 
        !          1201:       BLOCK_NUM (insn) = block;
        !          1202: 
        !          1203:       if (code == CODE_LABEL)
        !          1204:        LABEL_REFS (insn) = insn; /* delete old chain */
        !          1205: 
        !          1206:       if (code != NOTE)
        !          1207:        prev_code = code;
        !          1208:     }
        !          1209: 
        !          1210:   if (block + 1 != blocks)
        !          1211:     abort ();
        !          1212: 
        !          1213:   /* generate all label references to the corresponding jump insn */
        !          1214:   for (block = 0; block < blocks; block++)
        !          1215:     {
        !          1216:       insn = block_end[block];
        !          1217: 
        !          1218:       if (GET_CODE (insn) == JUMP_INSN)
        !          1219:        record_label_references (insn, PATTERN (insn));
        !          1220:     }
        !          1221: }
        !          1222: 
        !          1223: /* If current function returns its result in an fp stack register,
        !          1224:    return the register number.  Otherwise return -1.  */
        !          1225: 
        !          1226: static int
        !          1227: stack_result_p (decl)
        !          1228:      tree decl;
        !          1229: {
        !          1230:   rtx result = DECL_RTL (DECL_RESULT (decl));
        !          1231: 
        !          1232:   if (result != 0
        !          1233:       && !(GET_CODE (result) == REG
        !          1234:           && REGNO (result) < FIRST_PSEUDO_REGISTER))
        !          1235:     {
        !          1236: #ifdef FUNCTION_OUTGOING_VALUE
        !          1237:       result
        !          1238:         = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
        !          1239: #else
        !          1240:       result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
        !          1241: #endif
        !          1242:     }
        !          1243: 
        !          1244:   return STACK_REG_P (result) ? REGNO (result) : -1;
        !          1245: }
        !          1246: 
        !          1247: /* Determine the which registers are live at the start of each basic
        !          1248:    block of the function whose first insn is FIRST.
        !          1249: 
        !          1250:    First, if the function returns a real_type, mark the function
        !          1251:    return type as live at each return point, as the RTL may not give any
        !          1252:    hint that the register is live.
        !          1253: 
        !          1254:    Then, start with the last block and work back to the first block.
        !          1255:    Similarly, work backwards within each block, insn by insn, recording
        !          1256:    which regs are die and which are used (and therefore live) in the
        !          1257:    hard reg set of block_stack_in[].
        !          1258: 
        !          1259:    After processing each basic block, if there is a label at the start
        !          1260:    of the block, propagate the live registers to all jumps to this block.
        !          1261: 
        !          1262:    As a special case, if there are regs live in this block, that are
        !          1263:    not live in a block containing a jump to this label, and the block
        !          1264:    containing the jump has already been processed, we must propagate this
        !          1265:    block's entry register life back to the block containing the jump, and
        !          1266:    restart life analysis from there.
        !          1267: 
        !          1268:    In the worst case, this function may traverse the insns
        !          1269:    REG_STACK_SIZE times.  This is necessary, since a jump towards the end
        !          1270:    of the insns may not know that a reg is live at a target that is early
        !          1271:    in the insns.  So we back up and start over with the new reg live.
        !          1272: 
        !          1273:    If there are registers that are live at the start of the function,
        !          1274:    insns are emitted to initialize these registers.  Something similar is
        !          1275:    done after CALL_INSNs in record_reg_life. */
        !          1276: 
        !          1277: static void
        !          1278: stack_reg_life_analysis (first)
        !          1279:      rtx first;
        !          1280: {
        !          1281:   int reg, block;
        !          1282:   struct stack_def regstack;
        !          1283: 
        !          1284:   if (current_function_returns_real
        !          1285:       && stack_result_p (current_function_decl) >= 0)
        !          1286:     {
        !          1287:       /* Find all RETURN insns and mark them. */
        !          1288: 
        !          1289:       int value_regno = stack_result_p (current_function_decl);
        !          1290: 
        !          1291:       for (block = blocks - 1; block >= 0; block--)
        !          1292:        if (GET_CODE (block_end[block]) == JUMP_INSN
        !          1293:            && GET_CODE (PATTERN (block_end[block])) == RETURN)
        !          1294:          SET_HARD_REG_BIT (block_out_reg_set[block], value_regno);
        !          1295: 
        !          1296:       /* Mark of the end of last block if we "fall off" the end of the
        !          1297:         function into the epilogue. */
        !          1298: 
        !          1299:       if (GET_CODE (block_end[blocks-1]) != JUMP_INSN
        !          1300:          || GET_CODE (PATTERN (block_end[blocks-1])) == RETURN)
        !          1301:        SET_HARD_REG_BIT (block_out_reg_set[blocks-1], value_regno);
        !          1302:     }
        !          1303: 
        !          1304:   /* now scan all blocks backward for stack register use */
        !          1305: 
        !          1306:   block = blocks - 1;
        !          1307:   while (block >= 0)
        !          1308:     {
        !          1309:       register rtx insn, prev;
        !          1310: 
        !          1311:       /* current register status at last instruction */
        !          1312: 
        !          1313:       COPY_HARD_REG_SET (regstack.reg_set, block_out_reg_set[block]);
        !          1314: 
        !          1315:       prev = block_end[block];
        !          1316:       do
        !          1317:        {
        !          1318:          insn = prev;
        !          1319:          prev = PREV_INSN (insn);
        !          1320: 
        !          1321:          /* If the insn is a CALL_INSN, we need to ensure that
        !          1322:             everything dies.  But otherwise don't process unless there
        !          1323:             are some stack regs present. */
        !          1324: 
        !          1325:          if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
        !          1326:            record_reg_life (insn, block, &regstack);
        !          1327: 
        !          1328:        } while (insn != block_begin[block]);
        !          1329: 
        !          1330:       /* Set the state at the start of the block.  Mark that no
        !          1331:         register mapping information known yet. */
        !          1332: 
        !          1333:       COPY_HARD_REG_SET (block_stack_in[block].reg_set, regstack.reg_set);
        !          1334:       block_stack_in[block].top = -2;
        !          1335: 
        !          1336:       /* If there is a label, propagate our register life to all jumps
        !          1337:         to this label. */
        !          1338: 
        !          1339:       if (GET_CODE (insn) == CODE_LABEL)
        !          1340:        {
        !          1341:          register rtx label;
        !          1342:          int must_restart = 0;
        !          1343: 
        !          1344:          for (label = LABEL_REFS (insn); label != insn;
        !          1345:               label = LABEL_NEXTREF (label))
        !          1346:            {
        !          1347:              int jump_block = BLOCK_NUM (CONTAINING_INSN (label));
        !          1348: 
        !          1349:              if (jump_block < block)
        !          1350:                IOR_HARD_REG_SET (block_out_reg_set[jump_block],
        !          1351:                                  block_stack_in[block].reg_set);
        !          1352:              else
        !          1353:                {
        !          1354:                  /* The block containing the jump has already been
        !          1355:                     processed.  If there are registers that were not known
        !          1356:                     to be live then, but are live now, we must back up
        !          1357:                     and restart life analysis from that point with the new
        !          1358:                     life information. */
        !          1359: 
        !          1360:                  GO_IF_HARD_REG_SUBSET (block_stack_in[block].reg_set,
        !          1361:                                         block_out_reg_set[jump_block],
        !          1362:                                         win);
        !          1363: 
        !          1364:                  IOR_HARD_REG_SET (block_out_reg_set[jump_block],
        !          1365:                                    block_stack_in[block].reg_set);
        !          1366: 
        !          1367:                  block = jump_block;
        !          1368:                  must_restart = 1;
        !          1369: 
        !          1370:                win:
        !          1371:                  ;
        !          1372:                }
        !          1373:            }
        !          1374:          if (must_restart)
        !          1375:            continue;
        !          1376:        }
        !          1377: 
        !          1378:       if (block_drops_in[block])
        !          1379:        IOR_HARD_REG_SET (block_out_reg_set[block-1],
        !          1380:                          block_stack_in[block].reg_set);
        !          1381: 
        !          1382:       block -= 1;
        !          1383:     }
        !          1384: 
        !          1385:   {
        !          1386:     /* If any reg is live at the start of the first block of a
        !          1387:        function, then we must guarantee that the reg holds some value by
        !          1388:        generating our own "load" of that register.  Otherwise a 387 would
        !          1389:        fault trying to access an empty register. */
        !          1390: 
        !          1391:     HARD_REG_SET empty_regs;
        !          1392:     CLEAR_HARD_REG_SET (empty_regs);
        !          1393:     GO_IF_HARD_REG_SUBSET (block_stack_in[0].reg_set, empty_regs,
        !          1394:                           no_live_regs);
        !          1395:   }
        !          1396: 
        !          1397:   /* Load zero into each live register.  The fact that a register
        !          1398:      appears live at the function start does not necessarily imply an error
        !          1399:      in the user program: it merely means that we could not determine that
        !          1400:      there wasn't such an error, just as -Wunused sometimes gives
        !          1401:      "incorrect" warnings.  In those cases, these initializations will do
        !          1402:      no harm.
        !          1403: 
        !          1404:      Note that we are inserting virtual register references here:
        !          1405:      these insns must be processed by convert_regs later.  Also, these
        !          1406:      insns will not be in block_number, so BLOCK_NUM() will fail for them. */
        !          1407: 
        !          1408:   for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
        !          1409:     if (TEST_HARD_REG_BIT (block_stack_in[0].reg_set, reg))
        !          1410:       {
        !          1411:        rtx init_rtx;
        !          1412: 
        !          1413:        init_rtx = gen_rtx (SET, VOIDmode, FP_mode_reg[reg][(int) DFmode],
        !          1414:                            CONST0_RTX (DFmode));
        !          1415:        block_begin[0] = emit_insn_after (init_rtx, first);
        !          1416:        PUT_MODE (block_begin[0], QImode);
        !          1417: 
        !          1418:        CLEAR_HARD_REG_BIT (block_stack_in[0].reg_set, reg);
        !          1419:       }
        !          1420: 
        !          1421:  no_live_regs:
        !          1422:   ;
        !          1423: }
        !          1424: 
        !          1425: /*****************************************************************************
        !          1426:    This section deals with stack register substitution, and forms the second
        !          1427:    pass over the RTL.
        !          1428:  *****************************************************************************/
        !          1429: 
        !          1430: /* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
        !          1431:    the desired hard REGNO. */
        !          1432: 
        !          1433: static void
        !          1434: replace_reg (reg, regno)
        !          1435:      rtx *reg;
        !          1436:      int regno;
        !          1437: {
        !          1438:   if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG
        !          1439:       || ! STACK_REG_P (*reg))
        !          1440:     abort ();
        !          1441: 
        !          1442:   if (GET_MODE_CLASS (GET_MODE (*reg)) != MODE_FLOAT)
        !          1443:     abort ();
        !          1444: 
        !          1445:   *reg = FP_mode_reg[regno][(int) GET_MODE (*reg)];
        !          1446: }
        !          1447: 
        !          1448: /* Remove a note of type NOTE, which must be found, for register
        !          1449:    number REGNO from INSN.  Remove only one such note. */
        !          1450: 
        !          1451: static void
        !          1452: remove_regno_note (insn, note, regno)
        !          1453:      rtx insn;
        !          1454:      enum reg_note note;
        !          1455:      int regno;
        !          1456: {
        !          1457:   register rtx *note_link, this;
        !          1458: 
        !          1459:   note_link = &REG_NOTES(insn);
        !          1460:   for (this = *note_link; this; this = XEXP (this, 1))
        !          1461:     if (REG_NOTE_KIND (this) == note
        !          1462:        && REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
        !          1463:       {
        !          1464:        *note_link = XEXP (this, 1);
        !          1465:        return;
        !          1466:       }
        !          1467:     else
        !          1468:       note_link = &XEXP (this, 1);
        !          1469: 
        !          1470:   abort ();
        !          1471: }
        !          1472: 
        !          1473: /* Find the hard register number of virtual register REG in REGSTACK.
        !          1474:    The hard register number is relative to the top of the stack.  -1 is
        !          1475:    returned if the register is not found. */
        !          1476: 
        !          1477: static int
        !          1478: get_hard_regnum (regstack, reg)
        !          1479:      stack regstack;
        !          1480:      rtx reg;
        !          1481: {
        !          1482:   int i;
        !          1483: 
        !          1484:   if (! STACK_REG_P (reg))
        !          1485:     abort ();
        !          1486: 
        !          1487:   for (i = regstack->top; i >= 0; i--)
        !          1488:     if (regstack->reg[i] == REGNO (reg))
        !          1489:       break;
        !          1490: 
        !          1491:   return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
        !          1492: }
        !          1493: 
        !          1494: /* Delete INSN from the RTL.  Mark the insn, but don't remove it from
        !          1495:    the chain of insns.  Doing so could confuse block_begin and block_end
        !          1496:    if this were the only insn in the block. */
        !          1497: 
        !          1498: static void
        !          1499: delete_insn_for_stacker (insn)
        !          1500:      rtx insn;
        !          1501: {
        !          1502:   PUT_CODE (insn, NOTE);
        !          1503:   NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
        !          1504:   NOTE_SOURCE_FILE (insn) = 0;
        !          1505:   INSN_DELETED_P (insn) = 1;
        !          1506: }
        !          1507: 
        !          1508: /* Emit an insn to pop virtual register REG before or after INSN.
        !          1509:    REGSTACK is the stack state after INSN and is updated to reflect this
        !          1510:    pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
        !          1511:    is represented as a SET whose destination is the register to be popped
        !          1512:    and source is the top of stack.  A death note for the top of stack
        !          1513:    cases the movdf pattern to pop. */
        !          1514: 
        !          1515: static rtx
        !          1516: emit_pop_insn (insn, regstack, reg, when)
        !          1517:      rtx insn;
        !          1518:      stack regstack;
        !          1519:      rtx reg;
        !          1520:      rtx (*when)();
        !          1521: {
        !          1522:   rtx pop_insn, pop_rtx;
        !          1523:   int hard_regno;
        !          1524: 
        !          1525:   hard_regno = get_hard_regnum (regstack, reg);
        !          1526: 
        !          1527:   if (hard_regno < FIRST_STACK_REG)
        !          1528:     abort ();
        !          1529: 
        !          1530:   pop_rtx = gen_rtx (SET, VOIDmode, FP_mode_reg[hard_regno][(int) DFmode],
        !          1531:                     FP_mode_reg[FIRST_STACK_REG][(int) DFmode]);
        !          1532: 
        !          1533:   pop_insn = (*when) (pop_rtx, insn);
        !          1534:   /* ??? This used to be VOIDmode, but that seems wrong. */
        !          1535:   PUT_MODE (pop_insn, QImode);
        !          1536: 
        !          1537:   REG_NOTES (pop_insn) = gen_rtx (EXPR_LIST, REG_DEAD,
        !          1538:                                  FP_mode_reg[FIRST_STACK_REG][(int) DFmode],
        !          1539:                                  REG_NOTES (pop_insn));
        !          1540: 
        !          1541:   regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
        !          1542:     = regstack->reg[regstack->top];
        !          1543:   regstack->top -= 1;
        !          1544:   CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));
        !          1545: 
        !          1546:   return pop_insn;
        !          1547: }
        !          1548: 
        !          1549: /* Emit an insn before or after INSN to swap virtual register REG with the
        !          1550:    top of stack.  WHEN should be `emit_insn_before' or `emit_insn_before'
        !          1551:    REGSTACK is the stack state before the swap, and is updated to reflect
        !          1552:    the swap.  A swap insn is represented as a PARALLEL of two patterns:
        !          1553:    each pattern moves one reg to the other.
        !          1554: 
        !          1555:    If REG is already at the top of the stack, no insn is emitted. */
        !          1556: 
        !          1557: static void
        !          1558: emit_swap_insn (insn, regstack, reg)
        !          1559:      rtx insn;
        !          1560:      stack regstack;
        !          1561:      rtx reg;
        !          1562: {
        !          1563:   int hard_regno;
        !          1564:   rtx gen_swapdf();
        !          1565:   rtx swap_rtx, swap_insn;
        !          1566:   int tmp, other_reg;          /* swap regno temps */
        !          1567:   rtx i1;                      /* the stack-reg insn prior to INSN */
        !          1568:   rtx i1set = NULL_RTX;                /* the SET rtx within I1 */
        !          1569: 
        !          1570:   hard_regno = get_hard_regnum (regstack, reg);
        !          1571: 
        !          1572:   if (hard_regno < FIRST_STACK_REG)
        !          1573:     abort ();
        !          1574:   if (hard_regno == FIRST_STACK_REG)
        !          1575:     return;
        !          1576: 
        !          1577:   other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);
        !          1578: 
        !          1579:   tmp = regstack->reg[other_reg];
        !          1580:   regstack->reg[other_reg] = regstack->reg[regstack->top];
        !          1581:   regstack->reg[regstack->top] = tmp;
        !          1582: 
        !          1583:   /* Find the previous insn involving stack regs, but don't go past
        !          1584:      any labels, calls or jumps.  */
        !          1585:   i1 = prev_nonnote_insn (insn);
        !          1586:   while (i1 && GET_CODE (i1) == INSN && GET_MODE (i1) != QImode)
        !          1587:     i1 = prev_nonnote_insn (i1);
        !          1588: 
        !          1589:   if (i1)
        !          1590:     i1set = single_set (i1);
        !          1591: 
        !          1592:   if (i1set)
        !          1593:     {
        !          1594:       rtx i2;                  /* the stack-reg insn prior to I1 */
        !          1595:       rtx i1src = *get_true_reg (&SET_SRC (i1set));
        !          1596:       rtx i1dest = *get_true_reg (&SET_DEST (i1set));
        !          1597: 
        !          1598:       /* If the previous register stack push was from the reg we are to
        !          1599:         swap with, omit the swap. */
        !          1600: 
        !          1601:       if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG
        !          1602:          && GET_CODE (i1src) == REG && REGNO (i1src) == hard_regno - 1
        !          1603:          && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
        !          1604:        return;
        !          1605: 
        !          1606:       /* If the previous insn wrote to the reg we are to swap with,
        !          1607:         omit the swap.  */
        !          1608: 
        !          1609:       if (GET_CODE (i1dest) == REG && REGNO (i1dest) == hard_regno
        !          1610:          && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG
        !          1611:          && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
        !          1612:        return;
        !          1613:     }
        !          1614: 
        !          1615:   if (GET_RTX_CLASS (GET_CODE (i1)) == 'i' && sets_cc0_p (PATTERN (i1)))
        !          1616:     {
        !          1617:       i1 = next_nonnote_insn (i1);
        !          1618:       if (i1 == insn)
        !          1619:        abort ();
        !          1620:     }
        !          1621: 
        !          1622:   swap_rtx = gen_swapdf (FP_mode_reg[hard_regno][(int) DFmode],
        !          1623:                         FP_mode_reg[FIRST_STACK_REG][(int) DFmode]);
        !          1624:   swap_insn = emit_insn_after (swap_rtx, i1);
        !          1625:   /* ??? This used to be VOIDmode, but that seems wrong. */
        !          1626:   PUT_MODE (swap_insn, QImode);
        !          1627: }
        !          1628: 
        !          1629: /* Handle a move to or from a stack register in PAT, which is in INSN.
        !          1630:    REGSTACK is the current stack. */
        !          1631: 
        !          1632: static void
        !          1633: move_for_stack_reg (insn, regstack, pat)
        !          1634:      rtx insn;
        !          1635:      stack regstack;
        !          1636:      rtx pat;
        !          1637: {
        !          1638:   rtx *src =  get_true_reg (&SET_SRC (pat));
        !          1639:   rtx *dest = get_true_reg (&SET_DEST (pat));
        !          1640:   rtx note;
        !          1641: 
        !          1642:   if (STACK_REG_P (*src) && STACK_REG_P (*dest))
        !          1643:     {
        !          1644:       /* Write from one stack reg to another.  If SRC dies here, then
        !          1645:         just change the register mapping and delete the insn. */
        !          1646: 
        !          1647:       note = find_regno_note (insn, REG_DEAD, REGNO (*src));
        !          1648:       if (note)
        !          1649:        {
        !          1650:          int i;
        !          1651: 
        !          1652:          /* If this is a no-op move, there must not be a REG_DEAD note. */
        !          1653:          if (REGNO (*src) == REGNO (*dest))
        !          1654:            abort ();
        !          1655: 
        !          1656:          for (i = regstack->top; i >= 0; i--)
        !          1657:            if (regstack->reg[i] == REGNO (*src))
        !          1658:              break;
        !          1659: 
        !          1660:          /* The source must be live, and the dest must be dead. */
        !          1661:          if (i < 0 || get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG)
        !          1662:            abort ();
        !          1663: 
        !          1664:          /* It is possible that the dest is unused after this insn.
        !          1665:             If so, just pop the src. */
        !          1666: 
        !          1667:          if (find_regno_note (insn, REG_UNUSED, REGNO (*dest)))
        !          1668:            {
        !          1669:              emit_pop_insn (insn, regstack, *src, emit_insn_after);
        !          1670: 
        !          1671:              delete_insn_for_stacker (insn);
        !          1672:              return;
        !          1673:            }
        !          1674: 
        !          1675:          regstack->reg[i] = REGNO (*dest);
        !          1676: 
        !          1677:          SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          1678:          CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src));
        !          1679: 
        !          1680:          delete_insn_for_stacker (insn);
        !          1681: 
        !          1682:          return;
        !          1683:        }
        !          1684: 
        !          1685:       /* The source reg does not die. */
        !          1686: 
        !          1687:       /* If this appears to be a no-op move, delete it, or else it
        !          1688:         will confuse the machine description output patterns. But if
        !          1689:         it is REG_UNUSED, we must pop the reg now, as per-insn processing
        !          1690:         for REG_UNUSED will not work for deleted insns. */
        !          1691: 
        !          1692:       if (REGNO (*src) == REGNO (*dest))
        !          1693:        {
        !          1694:          if (find_regno_note (insn, REG_UNUSED, REGNO (*dest)))
        !          1695:            emit_pop_insn (insn, regstack, *dest, emit_insn_after);
        !          1696: 
        !          1697:          delete_insn_for_stacker (insn);
        !          1698:          return;
        !          1699:        }
        !          1700: 
        !          1701:       /* The destination ought to be dead */
        !          1702:       if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG)
        !          1703:        abort ();
        !          1704: 
        !          1705:       replace_reg (src, get_hard_regnum (regstack, *src));
        !          1706: 
        !          1707:       regstack->reg[++regstack->top] = REGNO (*dest);
        !          1708:       SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          1709:       replace_reg (dest, FIRST_STACK_REG);
        !          1710:     }
        !          1711:   else if (STACK_REG_P (*src))
        !          1712:     {
        !          1713:       /* Save from a stack reg to MEM, or possibly integer reg.  Since
        !          1714:         only top of stack may be saved, emit an exchange first if
        !          1715:         needs be. */
        !          1716: 
        !          1717:       emit_swap_insn (insn, regstack, *src);
        !          1718: 
        !          1719:       note = find_regno_note (insn, REG_DEAD, REGNO (*src));
        !          1720:       if (note)
        !          1721:        {
        !          1722:          replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
        !          1723:          regstack->top--;
        !          1724:          CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src));
        !          1725:        }
        !          1726:       else if (GET_MODE (*src) == XFmode && regstack->top != REG_STACK_SIZE)
        !          1727:        {
        !          1728:          /* A 387 cannot write an XFmode value to a MEM without
        !          1729:             clobbering the source reg.  The output code can handle
        !          1730:             this by reading back the value from the MEM.
        !          1731:             But it is more efficient to use a temp register if one is
        !          1732:             available.  Push the source value here if the register
        !          1733:             stack is not full, and then write the value to memory via
        !          1734:             a pop.  */
        !          1735:          rtx push_rtx, push_insn;
        !          1736:          rtx top_stack_reg = FP_mode_reg[FIRST_STACK_REG][(int) XFmode];
        !          1737: 
        !          1738:          push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
        !          1739:          push_insn = emit_insn_before (push_rtx, insn);
        !          1740:          PUT_MODE (push_insn, QImode);
        !          1741:          REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, top_stack_reg,
        !          1742:                                      REG_NOTES (insn));
        !          1743:        }
        !          1744: 
        !          1745:       replace_reg (src, FIRST_STACK_REG);
        !          1746:     }
        !          1747:   else if (STACK_REG_P (*dest))
        !          1748:     {
        !          1749:       /* Load from MEM, or possibly integer REG or constant, into the
        !          1750:         stack regs.  The actual target is always the top of the
        !          1751:         stack. The stack mapping is changed to reflect that DEST is
        !          1752:         now at top of stack.  */
        !          1753: 
        !          1754:       /* The destination ought to be dead */
        !          1755:       if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG)
        !          1756:        abort ();
        !          1757: 
        !          1758:       if (regstack->top >= REG_STACK_SIZE)
        !          1759:        abort ();
        !          1760: 
        !          1761:       regstack->reg[++regstack->top] = REGNO (*dest);
        !          1762:       SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          1763:       replace_reg (dest, FIRST_STACK_REG);
        !          1764:     }
        !          1765:   else
        !          1766:     abort ();
        !          1767: }
        !          1768: 
        !          1769: void
        !          1770: swap_rtx_condition (pat)
        !          1771:      rtx pat;
        !          1772: {
        !          1773:   register char *fmt;
        !          1774:   register int i;
        !          1775: 
        !          1776:   if (GET_RTX_CLASS (GET_CODE (pat)) == '<')
        !          1777:     {
        !          1778:       PUT_CODE (pat, swap_condition (GET_CODE (pat)));
        !          1779:       return;
        !          1780:     }
        !          1781: 
        !          1782:   fmt = GET_RTX_FORMAT (GET_CODE (pat));
        !          1783:   for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
        !          1784:     {
        !          1785:       if (fmt[i] == 'E')
        !          1786:        {
        !          1787:          register int j;
        !          1788: 
        !          1789:          for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
        !          1790:            swap_rtx_condition (XVECEXP (pat, i, j));
        !          1791:        }
        !          1792:       else if (fmt[i] == 'e')
        !          1793:        swap_rtx_condition (XEXP (pat, i));
        !          1794:     }
        !          1795: }
        !          1796: 
        !          1797: /* Handle a comparison.  Special care needs to be taken to avoid
        !          1798:    causing comparisons that a 387 cannot do correctly, such as EQ.
        !          1799: 
        !          1800:    Also, a pop insn may need to be emitted.  The 387 does have an
        !          1801:    `fcompp' insn that can pop two regs, but it is sometimes too expensive
        !          1802:    to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
        !          1803:    set up. */
        !          1804: 
        !          1805: static void
        !          1806: compare_for_stack_reg (insn, regstack, pat)
        !          1807:      rtx insn;
        !          1808:      stack regstack;
        !          1809:      rtx pat;
        !          1810: {
        !          1811:   rtx *src1, *src2;
        !          1812:   rtx src1_note, src2_note;
        !          1813: 
        !          1814:   src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
        !          1815:   src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
        !          1816: 
        !          1817:   /* ??? If fxch turns out to be cheaper than fstp, give priority to
        !          1818:      registers that die in this insn - move those to stack top first. */
        !          1819:   if (! STACK_REG_P (*src1)
        !          1820:       || (STACK_REG_P (*src2)
        !          1821:          && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
        !          1822:     {
        !          1823:       rtx temp, next;
        !          1824: 
        !          1825:       temp = XEXP (SET_SRC (pat), 0);
        !          1826:       XEXP (SET_SRC (pat), 0) = XEXP (SET_SRC (pat), 1);
        !          1827:       XEXP (SET_SRC (pat), 1) = temp;
        !          1828: 
        !          1829:       src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
        !          1830:       src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
        !          1831: 
        !          1832:       next = next_cc0_user (insn);
        !          1833:       if (next == NULL_RTX)
        !          1834:        abort ();
        !          1835: 
        !          1836:       swap_rtx_condition (PATTERN (next));
        !          1837:       INSN_CODE (next) = -1;
        !          1838:       INSN_CODE (insn) = -1;
        !          1839:     }
        !          1840: 
        !          1841:   /* We will fix any death note later. */
        !          1842: 
        !          1843:   src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        !          1844: 
        !          1845:   if (STACK_REG_P (*src2))
        !          1846:     src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
        !          1847:   else
        !          1848:     src2_note = NULL_RTX;
        !          1849: 
        !          1850:   emit_swap_insn (insn, regstack, *src1);
        !          1851: 
        !          1852:   replace_reg (src1, FIRST_STACK_REG);
        !          1853: 
        !          1854:   if (STACK_REG_P (*src2))
        !          1855:     replace_reg (src2, get_hard_regnum (regstack, *src2));
        !          1856: 
        !          1857:   if (src1_note)
        !          1858:     {
        !          1859:       CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src1_note, 0)));
        !          1860:       replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
        !          1861:       regstack->top--;
        !          1862:     }
        !          1863: 
        !          1864:   /* If the second operand dies, handle that.  But if the operands are
        !          1865:      the same stack register, don't bother, because only one death is
        !          1866:      needed, and it was just handled. */
        !          1867: 
        !          1868:   if (src2_note
        !          1869:       && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
        !          1870:            && REGNO (*src1) == REGNO (*src2)))
        !          1871:     {
        !          1872:       /* As a special case, two regs may die in this insn if src2 is
        !          1873:         next to top of stack and the top of stack also dies.  Since
        !          1874:         we have already popped src1, "next to top of stack" is really
        !          1875:         at top (FIRST_STACK_REG) now. */
        !          1876: 
        !          1877:       if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
        !          1878:          && src1_note)
        !          1879:        {
        !          1880:          CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src2_note, 0)));
        !          1881:          replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
        !          1882:          regstack->top--;
        !          1883:        }
        !          1884:       else
        !          1885:        {
        !          1886:          /* The 386 can only represent death of the first operand in
        !          1887:             the case handled above.  In all other cases, emit a separate
        !          1888:             pop and remove the death note from here. */
        !          1889: 
        !          1890:          link_cc0_insns (insn);
        !          1891: 
        !          1892:          remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
        !          1893: 
        !          1894:          emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
        !          1895:                         emit_insn_after);
        !          1896:        }
        !          1897:     }
        !          1898: }
        !          1899: 
        !          1900: /* Substitute new registers in PAT, which is part of INSN.  REGSTACK
        !          1901:    is the current register layout. */
        !          1902: 
        !          1903: static void
        !          1904: subst_stack_regs_pat (insn, regstack, pat)
        !          1905:      rtx insn;
        !          1906:      stack regstack;
        !          1907:      rtx pat;
        !          1908: {
        !          1909:   rtx *dest, *src;
        !          1910:   rtx *src1 = (rtx *) NULL_PTR, *src2;
        !          1911:   rtx src1_note, src2_note;
        !          1912: 
        !          1913:   if (GET_CODE (pat) != SET)
        !          1914:     return;
        !          1915: 
        !          1916:   dest = get_true_reg (&SET_DEST (pat));
        !          1917:   src  = get_true_reg (&SET_SRC (pat));
        !          1918: 
        !          1919:   /* See if this is a `movM' pattern, and handle elsewhere if so. */
        !          1920: 
        !          1921:   if (*dest != cc0_rtx
        !          1922:       && (STACK_REG_P (*src)
        !          1923:          || (STACK_REG_P (*dest)
        !          1924:              && (GET_CODE (*src) == REG || GET_CODE (*src) == MEM
        !          1925:                  || GET_CODE (*src) == CONST_DOUBLE))))
        !          1926:     move_for_stack_reg (insn, regstack, pat);
        !          1927:   else
        !          1928:     switch (GET_CODE (SET_SRC (pat)))
        !          1929:       {
        !          1930:       case COMPARE:
        !          1931:        compare_for_stack_reg (insn, regstack, pat);
        !          1932:        break;
        !          1933: 
        !          1934:       case CALL:
        !          1935:        regstack->reg[++regstack->top] = REGNO (*dest);
        !          1936:        SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          1937:        replace_reg (dest, FIRST_STACK_REG);
        !          1938:        break;
        !          1939: 
        !          1940:       case REG:
        !          1941:        /* This is a `tstM2' case. */
        !          1942:        if (*dest != cc0_rtx)
        !          1943:          abort ();
        !          1944: 
        !          1945:        src1 = src;
        !          1946: 
        !          1947:        /* Fall through. */
        !          1948: 
        !          1949:       case FLOAT_TRUNCATE:
        !          1950:       case SQRT:
        !          1951:       case ABS:
        !          1952:       case NEG:
        !          1953:        /* These insns only operate on the top of the stack. DEST might
        !          1954:           be cc0_rtx if we're processing a tstM pattern. Also, it's
        !          1955:           possible that the tstM case results in a REG_DEAD note on the
        !          1956:           source.  */
        !          1957: 
        !          1958:        if (src1 == 0)
        !          1959:          src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
        !          1960: 
        !          1961:        emit_swap_insn (insn, regstack, *src1);
        !          1962: 
        !          1963:        src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        !          1964: 
        !          1965:        if (STACK_REG_P (*dest))
        !          1966:          replace_reg (dest, FIRST_STACK_REG);
        !          1967: 
        !          1968:        if (src1_note)
        !          1969:          {
        !          1970:            replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
        !          1971:            regstack->top--;
        !          1972:            CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
        !          1973:          }
        !          1974: 
        !          1975:        replace_reg (src1, FIRST_STACK_REG);
        !          1976: 
        !          1977:        break;
        !          1978: 
        !          1979:       case MINUS:
        !          1980:       case DIV:
        !          1981:        /* On i386, reversed forms of subM3 and divM3 exist for
        !          1982:           MODE_FLOAT, so the same code that works for addM3 and mulM3
        !          1983:           can be used. */
        !          1984:       case MULT:
        !          1985:       case PLUS:
        !          1986:        /* These insns can accept the top of stack as a destination
        !          1987:           from a stack reg or mem, or can use the top of stack as a
        !          1988:           source and some other stack register (possibly top of stack)
        !          1989:           as a destination. */
        !          1990: 
        !          1991:        src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
        !          1992:        src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
        !          1993: 
        !          1994:        /* We will fix any death note later. */
        !          1995: 
        !          1996:        if (STACK_REG_P (*src1))
        !          1997:          src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        !          1998:        else
        !          1999:          src1_note = NULL_RTX;
        !          2000:        if (STACK_REG_P (*src2))
        !          2001:          src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
        !          2002:        else
        !          2003:          src2_note = NULL_RTX;
        !          2004: 
        !          2005:        /* If either operand is not a stack register, then the dest
        !          2006:           must be top of stack. */
        !          2007: 
        !          2008:        if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
        !          2009:          emit_swap_insn (insn, regstack, *dest);
        !          2010:        else
        !          2011:          {
        !          2012:            /* Both operands are REG.  If neither operand is already
        !          2013:               at the top of stack, choose to make the one that is the dest
        !          2014:               the new top of stack.  */
        !          2015: 
        !          2016:            int src1_hard_regnum, src2_hard_regnum;
        !          2017: 
        !          2018:            src1_hard_regnum = get_hard_regnum (regstack, *src1);
        !          2019:            src2_hard_regnum = get_hard_regnum (regstack, *src2);
        !          2020:            if (src1_hard_regnum == -1 || src2_hard_regnum == -1)
        !          2021:              abort ();
        !          2022: 
        !          2023:            if (src1_hard_regnum != FIRST_STACK_REG
        !          2024:                && src2_hard_regnum != FIRST_STACK_REG)
        !          2025:              emit_swap_insn (insn, regstack, *dest);
        !          2026:          }
        !          2027: 
        !          2028:        if (STACK_REG_P (*src1))
        !          2029:          replace_reg (src1, get_hard_regnum (regstack, *src1));
        !          2030:        if (STACK_REG_P (*src2))
        !          2031:          replace_reg (src2, get_hard_regnum (regstack, *src2));
        !          2032: 
        !          2033:        if (src1_note)
        !          2034:          {
        !          2035:            /* If the register that dies is at the top of stack, then
        !          2036:               the destination is somewhere else - merely substitute it.
        !          2037:               But if the reg that dies is not at top of stack, then
        !          2038:               move the top of stack to the dead reg, as though we had
        !          2039:               done the insn and then a store-with-pop. */
        !          2040: 
        !          2041:            if (REGNO (XEXP (src1_note, 0)) == regstack->reg[regstack->top])
        !          2042:              {
        !          2043:                SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          2044:                replace_reg (dest, get_hard_regnum (regstack, *dest));
        !          2045:              }
        !          2046:            else
        !          2047:              {
        !          2048:                int regno = get_hard_regnum (regstack, XEXP (src1_note, 0));
        !          2049: 
        !          2050:                SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          2051:                replace_reg (dest, regno);
        !          2052: 
        !          2053:                regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
        !          2054:                  = regstack->reg[regstack->top];
        !          2055:              }
        !          2056: 
        !          2057:            CLEAR_HARD_REG_BIT (regstack->reg_set,
        !          2058:                                REGNO (XEXP (src1_note, 0)));
        !          2059:            replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
        !          2060:            regstack->top--;
        !          2061:          }
        !          2062:        else if (src2_note)
        !          2063:          {
        !          2064:            if (REGNO (XEXP (src2_note, 0)) == regstack->reg[regstack->top])
        !          2065:              {
        !          2066:                SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          2067:                replace_reg (dest, get_hard_regnum (regstack, *dest));
        !          2068:              }
        !          2069:            else
        !          2070:              {
        !          2071:                int regno = get_hard_regnum (regstack, XEXP (src2_note, 0));
        !          2072: 
        !          2073:                SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          2074:                replace_reg (dest, regno);
        !          2075: 
        !          2076:                regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
        !          2077:                  = regstack->reg[regstack->top];
        !          2078:              }
        !          2079: 
        !          2080:            CLEAR_HARD_REG_BIT (regstack->reg_set,
        !          2081:                                REGNO (XEXP (src2_note, 0)));
        !          2082:            replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
        !          2083:            regstack->top--;
        !          2084:          }
        !          2085:        else
        !          2086:          {
        !          2087:            SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
        !          2088:            replace_reg (dest, get_hard_regnum (regstack, *dest));
        !          2089:          }
        !          2090: 
        !          2091:        break;
        !          2092: 
        !          2093:       case UNSPEC:
        !          2094:        switch (XINT (SET_SRC (pat), 1))
        !          2095:          {
        !          2096:          case 1: /* sin */
        !          2097:          case 2: /* cos */
        !          2098:            /* These insns only operate on the top of the stack.  */
        !          2099: 
        !          2100:            src1 = get_true_reg (&XVECEXP (SET_SRC (pat), 0, 0));
        !          2101: 
        !          2102:            emit_swap_insn (insn, regstack, *src1);
        !          2103: 
        !          2104:            src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        !          2105: 
        !          2106:            if (STACK_REG_P (*dest))
        !          2107:              replace_reg (dest, FIRST_STACK_REG);
        !          2108: 
        !          2109:            if (src1_note)
        !          2110:              {
        !          2111:                replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
        !          2112:                regstack->top--;
        !          2113:                CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
        !          2114:              }
        !          2115: 
        !          2116:            replace_reg (src1, FIRST_STACK_REG);
        !          2117: 
        !          2118:            break;
        !          2119: 
        !          2120:          default:
        !          2121:            abort ();
        !          2122:          }
        !          2123:        break;
        !          2124: 
        !          2125:       default:
        !          2126:        abort ();
        !          2127:       }
        !          2128: }
        !          2129: 
        !          2130: /* Substitute hard regnums for any stack regs in INSN, which has
        !          2131:    N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
        !          2132:    before the insn, and is updated with changes made here.  CONSTRAINTS is
        !          2133:    an array of the constraint strings used in the asm statement.
        !          2134: 
        !          2135:    OPERANDS is an array of the operands, and OPERANDS_LOC is a
        !          2136:    parallel array of where the operands were found.  The output operands
        !          2137:    all precede the input operands.
        !          2138: 
        !          2139:    There are several requirements and assumptions about the use of
        !          2140:    stack-like regs in asm statements.  These rules are enforced by
        !          2141:    record_asm_stack_regs; see comments there for details.  Any
        !          2142:    asm_operands left in the RTL at this point may be assume to meet the
        !          2143:    requirements, since record_asm_stack_regs removes any problem asm.  */
        !          2144: 
        !          2145: static void
        !          2146: subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
        !          2147:                      n_inputs, n_outputs)
        !          2148:      rtx insn;
        !          2149:      stack regstack;
        !          2150:      rtx *operands, **operands_loc;
        !          2151:      char **constraints;
        !          2152:      int n_inputs, n_outputs;
        !          2153: {
        !          2154:   int n_operands = n_inputs + n_outputs;
        !          2155:   int first_input = n_outputs;
        !          2156:   rtx body = PATTERN (insn);
        !          2157: 
        !          2158:   int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
        !          2159:   enum reg_class *operand_class 
        !          2160:     = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
        !          2161: 
        !          2162:   rtx *note_reg;               /* Array of note contents */
        !          2163:   rtx **note_loc;              /* Address of REG field of each note */
        !          2164:   enum reg_note *note_kind;    /* The type of each note */
        !          2165: 
        !          2166:   rtx *clobber_reg;
        !          2167:   rtx **clobber_loc;
        !          2168: 
        !          2169:   struct stack_def temp_stack;
        !          2170:   int n_notes;
        !          2171:   int n_clobbers;
        !          2172:   rtx note;
        !          2173:   int i;
        !          2174: 
        !          2175:   /* Find out what the constraints required.  If no constraint
        !          2176:      alternative matches, that is a compiler bug: we should have caught
        !          2177:      such an insn during the life analysis pass (and reload should have
        !          2178:      caught it regardless). */
        !          2179: 
        !          2180:   i = constrain_asm_operands (n_operands, operands, constraints,
        !          2181:                              operand_matches, operand_class);
        !          2182:   if (i < 0)
        !          2183:     abort ();
        !          2184: 
        !          2185:   /* Strip SUBREGs here to make the following code simpler. */
        !          2186:   for (i = 0; i < n_operands; i++)
        !          2187:     if (GET_CODE (operands[i]) == SUBREG
        !          2188:        && GET_CODE (SUBREG_REG (operands[i])) == REG)
        !          2189:       {
        !          2190:        operands_loc[i] = & SUBREG_REG (operands[i]);
        !          2191:        operands[i] = SUBREG_REG (operands[i]);
        !          2192:       }
        !          2193: 
        !          2194:   /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND.  */
        !          2195: 
        !          2196:   for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
        !          2197:     i++;
        !          2198: 
        !          2199:   note_reg = (rtx *) alloca (i * sizeof (rtx));
        !          2200:   note_loc = (rtx **) alloca (i * sizeof (rtx *));
        !          2201:   note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note));
        !          2202: 
        !          2203:   n_notes = 0;
        !          2204:   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
        !          2205:     {
        !          2206:       rtx reg = XEXP (note, 0);
        !          2207:       rtx *loc = & XEXP (note, 0);
        !          2208: 
        !          2209:       if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
        !          2210:        {
        !          2211:          loc = & SUBREG_REG (reg);
        !          2212:          reg = SUBREG_REG (reg);
        !          2213:        }
        !          2214: 
        !          2215:       if (STACK_REG_P (reg)
        !          2216:          && (REG_NOTE_KIND (note) == REG_DEAD
        !          2217:              || REG_NOTE_KIND (note) == REG_UNUSED))
        !          2218:        {
        !          2219:          note_reg[n_notes] = reg;
        !          2220:          note_loc[n_notes] = loc;
        !          2221:          note_kind[n_notes] = REG_NOTE_KIND (note);
        !          2222:          n_notes++;
        !          2223:        }
        !          2224:     }
        !          2225: 
        !          2226:   /* Set up CLOBBER_REG and CLOBBER_LOC.  */
        !          2227: 
        !          2228:   n_clobbers = 0;
        !          2229: 
        !          2230:   if (GET_CODE (body) == PARALLEL)
        !          2231:     {
        !          2232:       clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
        !          2233:       clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx **));
        !          2234: 
        !          2235:       for (i = 0; i < XVECLEN (body, 0); i++)
        !          2236:        if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
        !          2237:          {
        !          2238:            rtx clobber = XVECEXP (body, 0, i);
        !          2239:            rtx reg = XEXP (clobber, 0);
        !          2240:            rtx *loc = & XEXP (clobber, 0);
        !          2241: 
        !          2242:            if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
        !          2243:              {
        !          2244:                loc = & SUBREG_REG (reg);
        !          2245:                reg = SUBREG_REG (reg);
        !          2246:              }
        !          2247: 
        !          2248:            if (STACK_REG_P (reg))
        !          2249:              {
        !          2250:                clobber_reg[n_clobbers] = reg;
        !          2251:                clobber_loc[n_clobbers] = loc;
        !          2252:                n_clobbers++;
        !          2253:              }
        !          2254:          }
        !          2255:     }
        !          2256: 
        !          2257:   bcopy (regstack, &temp_stack, sizeof (temp_stack));
        !          2258: 
        !          2259:   /* Put the input regs into the desired place in TEMP_STACK.  */
        !          2260: 
        !          2261:   for (i = first_input; i < first_input + n_inputs; i++)
        !          2262:     if (STACK_REG_P (operands[i])
        !          2263:        && reg_class_subset_p (operand_class[i], FLOAT_REGS)
        !          2264:        && operand_class[i] != FLOAT_REGS)
        !          2265:       {
        !          2266:        /* If an operand needs to be in a particular reg in
        !          2267:           FLOAT_REGS, the constraint was either 't' or 'u'.  Since
        !          2268:           these constraints are for single register classes, and reload
        !          2269:           guaranteed that operand[i] is already in that class, we can
        !          2270:           just use REGNO (operands[i]) to know which actual reg this
        !          2271:           operand needs to be in. */
        !          2272: 
        !          2273:        int regno = get_hard_regnum (&temp_stack, operands[i]);
        !          2274: 
        !          2275:        if (regno < 0)
        !          2276:          abort ();
        !          2277: 
        !          2278:        if (regno != REGNO (operands[i]))
        !          2279:          {
        !          2280:            /* operands[i] is not in the right place.  Find it
        !          2281:               and swap it with whatever is already in I's place.
        !          2282:               K is where operands[i] is now.  J is where it should
        !          2283:               be. */
        !          2284:            int j, k, temp;
        !          2285: 
        !          2286:            k = temp_stack.top - (regno - FIRST_STACK_REG);
        !          2287:            j = (temp_stack.top
        !          2288:                 - (REGNO (operands[i]) - FIRST_STACK_REG));
        !          2289: 
        !          2290:            temp = temp_stack.reg[k];
        !          2291:            temp_stack.reg[k] = temp_stack.reg[j];
        !          2292:            temp_stack.reg[j] = temp;
        !          2293:          }
        !          2294:       }
        !          2295: 
        !          2296:   /* emit insns before INSN to make sure the reg-stack is in the right
        !          2297:      order.  */
        !          2298: 
        !          2299:   change_stack (insn, regstack, &temp_stack, emit_insn_before);
        !          2300: 
        !          2301:   /* Make the needed input register substitutions.  Do death notes and
        !          2302:      clobbers too, because these are for inputs, not outputs. */
        !          2303: 
        !          2304:   for (i = first_input; i < first_input + n_inputs; i++)
        !          2305:     if (STACK_REG_P (operands[i]))
        !          2306:       {
        !          2307:        int regnum = get_hard_regnum (regstack, operands[i]);
        !          2308: 
        !          2309:        if (regnum < 0)
        !          2310:          abort ();
        !          2311: 
        !          2312:        replace_reg (operands_loc[i], regnum);
        !          2313:       }
        !          2314: 
        !          2315:   for (i = 0; i < n_notes; i++)
        !          2316:     if (note_kind[i] == REG_DEAD)
        !          2317:       {
        !          2318:        int regnum = get_hard_regnum (regstack, note_reg[i]);
        !          2319: 
        !          2320:        if (regnum < 0)
        !          2321:          abort ();
        !          2322: 
        !          2323:        replace_reg (note_loc[i], regnum);
        !          2324:       }
        !          2325: 
        !          2326:   for (i = 0; i < n_clobbers; i++)
        !          2327:     {
        !          2328:       /* It's OK for a CLOBBER to reference a reg that is not live.
        !          2329:          Don't try to replace it in that case.  */
        !          2330:       int regnum = get_hard_regnum (regstack, clobber_reg[i]);
        !          2331: 
        !          2332:       if (regnum >= 0)
        !          2333:        {
        !          2334:          /* Sigh - clobbers always have QImode.  But replace_reg knows
        !          2335:             that these regs can't be MODE_INT and will abort.  Just put
        !          2336:             the right reg there without calling replace_reg.  */
        !          2337: 
        !          2338:          *clobber_loc[i] = FP_mode_reg[regnum][(int) DFmode];
        !          2339:        }
        !          2340:     }
        !          2341: 
        !          2342:   /* Now remove from REGSTACK any inputs that the asm implicitly popped. */
        !          2343: 
        !          2344:   for (i = first_input; i < first_input + n_inputs; i++)
        !          2345:     if (STACK_REG_P (operands[i]))
        !          2346:       {
        !          2347:        /* An input reg is implicitly popped if it is tied to an
        !          2348:           output, or if there is a CLOBBER for it. */
        !          2349:        int j;
        !          2350: 
        !          2351:        for (j = 0; j < n_clobbers; j++)
        !          2352:          if (operands_match_p (clobber_reg[j], operands[i]))
        !          2353:            break;
        !          2354: 
        !          2355:        if (j < n_clobbers || operand_matches[i] >= 0)
        !          2356:          {
        !          2357:            /* operands[i] might not be at the top of stack.  But that's OK,
        !          2358:               because all we need to do is pop the right number of regs
        !          2359:               off of the top of the reg-stack.  record_asm_stack_regs
        !          2360:               guaranteed that all implicitly popped regs were grouped
        !          2361:               at the top of the reg-stack.  */
        !          2362: 
        !          2363:            CLEAR_HARD_REG_BIT (regstack->reg_set,
        !          2364:                                regstack->reg[regstack->top]);
        !          2365:            regstack->top--;
        !          2366:          }
        !          2367:       }
        !          2368: 
        !          2369:   /* Now add to REGSTACK any outputs that the asm implicitly pushed.
        !          2370:      Note that there isn't any need to substitute register numbers.
        !          2371:      ???  Explain why this is true. */
        !          2372: 
        !          2373:   for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
        !          2374:     {
        !          2375:       /* See if there is an output for this hard reg.  */
        !          2376:       int j;
        !          2377: 
        !          2378:       for (j = 0; j < n_outputs; j++)
        !          2379:        if (STACK_REG_P (operands[j]) && REGNO (operands[j]) == i)
        !          2380:          {
        !          2381:            regstack->reg[++regstack->top] = i;
        !          2382:            SET_HARD_REG_BIT (regstack->reg_set, i);
        !          2383:            break;
        !          2384:          }
        !          2385:     }
        !          2386: 
        !          2387:   /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
        !          2388:      input that the asm didn't implicitly pop.  If the asm didn't
        !          2389:      implicitly pop an input reg, that reg will still be live.
        !          2390: 
        !          2391:      Note that we can't use find_regno_note here: the register numbers
        !          2392:      in the death notes have already been substituted.  */
        !          2393: 
        !          2394:   for (i = 0; i < n_outputs; i++)
        !          2395:     if (STACK_REG_P (operands[i]))
        !          2396:       {
        !          2397:        int j;
        !          2398: 
        !          2399:        for (j = 0; j < n_notes; j++)
        !          2400:          if (REGNO (operands[i]) == REGNO (note_reg[j])
        !          2401:              && note_kind[j] == REG_UNUSED)
        !          2402:            {
        !          2403:              insn = emit_pop_insn (insn, regstack, operands[i],
        !          2404:                                    emit_insn_after);
        !          2405:              break;
        !          2406:            }
        !          2407:       }
        !          2408: 
        !          2409:   for (i = first_input; i < first_input + n_inputs; i++)
        !          2410:     if (STACK_REG_P (operands[i]))
        !          2411:       {
        !          2412:        int j;
        !          2413: 
        !          2414:        for (j = 0; j < n_notes; j++)
        !          2415:          if (REGNO (operands[i]) == REGNO (note_reg[j])
        !          2416:              && note_kind[j] == REG_DEAD
        !          2417:              && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])))
        !          2418:            {
        !          2419:              insn = emit_pop_insn (insn, regstack, operands[i],
        !          2420:                                    emit_insn_after);
        !          2421:              break;
        !          2422:            }
        !          2423:       }
        !          2424: }
        !          2425: 
        !          2426: /* Substitute stack hard reg numbers for stack virtual registers in
        !          2427:    INSN.  Non-stack register numbers are not changed.  REGSTACK is the
        !          2428:    current stack content.  Insns may be emitted as needed to arrange the
        !          2429:    stack for the 387 based on the contents of the insn. */
        !          2430: 
        !          2431: static void
        !          2432: subst_stack_regs (insn, regstack)
        !          2433:      rtx insn;
        !          2434:      stack regstack;
        !          2435: {
        !          2436:   register rtx *note_link, note;
        !          2437:   register int i;
        !          2438:   int n_operands;
        !          2439: 
        !          2440:   if ((GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
        !          2441:       || INSN_DELETED_P (insn))
        !          2442:     return;
        !          2443: 
        !          2444:   /* The stack should be empty at a call. */
        !          2445: 
        !          2446:   if (GET_CODE (insn) == CALL_INSN)
        !          2447:     for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
        !          2448:       if (TEST_HARD_REG_BIT (regstack->reg_set, i))
        !          2449:        abort ();
        !          2450: 
        !          2451:   /* Do the actual substitution if any stack regs are mentioned.
        !          2452:      Since we only record whether entire insn mentions stack regs, and
        !          2453:      subst_stack_regs_pat only works for patterns that contain stack regs,
        !          2454:      we must check each pattern in a parallel here.  A call_value_pop could
        !          2455:      fail otherwise. */
        !          2456: 
        !          2457:   if (GET_MODE (insn) == QImode)
        !          2458:     {
        !          2459:       n_operands = asm_noperands (PATTERN (insn));
        !          2460:       if (n_operands >= 0)
        !          2461:        {
        !          2462:          /* This insn is an `asm' with operands.  Decode the operands,
        !          2463:             decide how many are inputs, and do register substitution.
        !          2464:             Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */
        !          2465: 
        !          2466:          rtx operands[MAX_RECOG_OPERANDS];
        !          2467:          rtx *operands_loc[MAX_RECOG_OPERANDS];
        !          2468:          rtx body = PATTERN (insn);
        !          2469:          int n_inputs, n_outputs;
        !          2470:          char **constraints
        !          2471:            = (char **) alloca (n_operands * sizeof (char *));
        !          2472: 
        !          2473:          decode_asm_operands (body, operands, operands_loc,
        !          2474:                               constraints, NULL_PTR);
        !          2475:          get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
        !          2476:          subst_asm_stack_regs (insn, regstack, operands, operands_loc,
        !          2477:                                constraints, n_inputs, n_outputs);
        !          2478:          return;
        !          2479:        }
        !          2480: 
        !          2481:       if (GET_CODE (PATTERN (insn)) == PARALLEL)
        !          2482:        for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
        !          2483:          {
        !          2484:            if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
        !          2485:              subst_stack_regs_pat (insn, regstack,
        !          2486:                                    XVECEXP (PATTERN (insn), 0, i));
        !          2487:          }
        !          2488:       else
        !          2489:        subst_stack_regs_pat (insn, regstack, PATTERN (insn));
        !          2490:     }
        !          2491: 
        !          2492:   /* subst_stack_regs_pat may have deleted a no-op insn.  If so, any
        !          2493:      REG_UNUSED will already have been dealt with, so just return. */
        !          2494: 
        !          2495:   if (INSN_DELETED_P (insn))
        !          2496:     return;
        !          2497: 
        !          2498:   /* If there is a REG_UNUSED note on a stack register on this insn,
        !          2499:      the indicated reg must be popped.  The REG_UNUSED note is removed,
        !          2500:      since the form of the newly emitted pop insn references the reg,
        !          2501:      making it no longer `unset'. */
        !          2502: 
        !          2503:   note_link = &REG_NOTES(insn);
        !          2504:   for (note = *note_link; note; note = XEXP (note, 1))
        !          2505:     if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
        !          2506:       {
        !          2507:        *note_link = XEXP (note, 1);
        !          2508:        insn = emit_pop_insn (insn, regstack, XEXP (note, 0), emit_insn_after);
        !          2509:       }
        !          2510:     else
        !          2511:       note_link = &XEXP (note, 1);
        !          2512: }
        !          2513: 
        !          2514: /* Change the organization of the stack so that it fits a new basic
        !          2515:    block.  Some registers might have to be popped, but there can never be
        !          2516:    a register live in the new block that is not now live.
        !          2517: 
        !          2518:    Insert any needed insns before or after INSN.  WHEN is emit_insn_before
        !          2519:    or emit_insn_after. OLD is the original stack layout, and NEW is
        !          2520:    the desired form.  OLD is updated to reflect the code emitted, ie, it
        !          2521:    will be the same as NEW upon return.
        !          2522: 
        !          2523:    This function will not preserve block_end[].  But that information
        !          2524:    is no longer needed once this has executed. */
        !          2525: 
        !          2526: static void
        !          2527: change_stack (insn, old, new, when)
        !          2528:      rtx insn;
        !          2529:      stack old;
        !          2530:      stack new;
        !          2531:      rtx (*when)();
        !          2532: {
        !          2533:   int reg;
        !          2534: 
        !          2535:   /* We will be inserting new insns "backwards", by calling emit_insn_before.
        !          2536:      If we are to insert after INSN, find the next insn, and insert before
        !          2537:      it.  */
        !          2538: 
        !          2539:   if (when == emit_insn_after)
        !          2540:     insn = NEXT_INSN (insn);
        !          2541: 
        !          2542:   /* Pop any registers that are not needed in the new block. */
        !          2543: 
        !          2544:   for (reg = old->top; reg >= 0; reg--)
        !          2545:     if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
        !          2546:       emit_pop_insn (insn, old, FP_mode_reg[old->reg[reg]][(int) DFmode],
        !          2547:                     emit_insn_before);
        !          2548: 
        !          2549:   if (new->top == -2)
        !          2550:     {
        !          2551:       /* If the new block has never been processed, then it can inherit
        !          2552:         the old stack order. */
        !          2553: 
        !          2554:       new->top = old->top;
        !          2555:       bcopy (old->reg, new->reg, sizeof (new->reg));
        !          2556:     }
        !          2557:   else
        !          2558:     {
        !          2559:       /* This block has been entered before, and we must match the
        !          2560:         previously selected stack order. */
        !          2561: 
        !          2562:       /* By now, the only difference should be the order of the stack,
        !          2563:         not their depth or liveliness. */
        !          2564: 
        !          2565:       GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win);
        !          2566: 
        !          2567:       abort ();
        !          2568: 
        !          2569:     win:
        !          2570: 
        !          2571:       if (old->top != new->top)
        !          2572:        abort ();
        !          2573: 
        !          2574:       /* Loop here emitting swaps until the stack is correct.  The
        !          2575:         worst case number of swaps emitted is N + 2, where N is the
        !          2576:         depth of the stack.  In some cases, the reg at the top of
        !          2577:         stack may be correct, but swapped anyway in order to fix
        !          2578:         other regs.  But since we never swap any other reg away from
        !          2579:         its correct slot, this algorithm will converge. */
        !          2580: 
        !          2581:       do
        !          2582:        {
        !          2583:          /* Swap the reg at top of stack into the position it is
        !          2584:             supposed to be in, until the correct top of stack appears. */
        !          2585: 
        !          2586:          while (old->reg[old->top] != new->reg[new->top])
        !          2587:            {
        !          2588:              for (reg = new->top; reg >= 0; reg--)
        !          2589:                if (new->reg[reg] == old->reg[old->top])
        !          2590:                  break;
        !          2591: 
        !          2592:              if (reg == -1)
        !          2593:                abort ();
        !          2594: 
        !          2595:              emit_swap_insn (insn, old,
        !          2596:                              FP_mode_reg[old->reg[reg]][(int) DFmode]);
        !          2597:            }
        !          2598: 
        !          2599:          /* See if any regs remain incorrect.  If so, bring an
        !          2600:             incorrect reg to the top of stack, and let the while loop
        !          2601:             above fix it. */
        !          2602: 
        !          2603:          for (reg = new->top; reg >= 0; reg--)
        !          2604:            if (new->reg[reg] != old->reg[reg])
        !          2605:              {
        !          2606:                emit_swap_insn (insn, old,
        !          2607:                                FP_mode_reg[old->reg[reg]][(int) DFmode]);
        !          2608:                break;
        !          2609:              }
        !          2610:        } while (reg >= 0);
        !          2611: 
        !          2612:       /* At this point there must be no differences. */
        !          2613: 
        !          2614:       for (reg = old->top; reg >= 0; reg--)
        !          2615:        if (old->reg[reg] != new->reg[reg])
        !          2616:          abort ();
        !          2617:     }
        !          2618: }
        !          2619: 
        !          2620: /* Check PAT, which points to RTL in INSN, for a LABEL_REF.  If it is
        !          2621:    found, ensure that a jump from INSN to the code_label to which the
        !          2622:    label_ref points ends up with the same stack as that at the
        !          2623:    code_label.  Do this by inserting insns just before the code_label to
        !          2624:    pop and rotate the stack until it is in the correct order.  REGSTACK
        !          2625:    is the order of the register stack in INSN.
        !          2626: 
        !          2627:    Any code that is emitted here must not be later processed as part
        !          2628:    of any block, as it will already contain hard register numbers. */
        !          2629: 
        !          2630: static void
        !          2631: goto_block_pat (insn, regstack, pat)
        !          2632:      rtx insn;
        !          2633:      stack regstack;
        !          2634:      rtx pat;
        !          2635: {
        !          2636:   rtx label;
        !          2637:   rtx new_jump, new_label, new_barrier;
        !          2638:   rtx *ref;
        !          2639:   stack label_stack;
        !          2640:   struct stack_def temp_stack;
        !          2641:   int reg;
        !          2642: 
        !          2643:   if (GET_CODE (pat) != LABEL_REF)
        !          2644:     {
        !          2645:       int i, j;
        !          2646:       char *fmt = GET_RTX_FORMAT (GET_CODE (pat));
        !          2647: 
        !          2648:       for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
        !          2649:        {
        !          2650:          if (fmt[i] == 'e')
        !          2651:            goto_block_pat (insn, regstack, XEXP (pat, i));
        !          2652:          if (fmt[i] == 'E')
        !          2653:            for (j = 0; j < XVECLEN (pat, i); j++)
        !          2654:              goto_block_pat (insn, regstack, XVECEXP (pat, i, j));
        !          2655:        }
        !          2656:       return;
        !          2657:     }
        !          2658: 
        !          2659:   label = XEXP (pat, 0);
        !          2660:   if (GET_CODE (label) != CODE_LABEL)
        !          2661:     abort ();
        !          2662: 
        !          2663:   /* First, see if in fact anything needs to be done to the stack at all. */
        !          2664: 
        !          2665:   label_stack = &block_stack_in[BLOCK_NUM (label)];
        !          2666: 
        !          2667:   if (label_stack->top == -2)
        !          2668:     {
        !          2669:       /* If the target block hasn't had a stack order selected, then
        !          2670:         we need merely ensure that no pops are needed. */
        !          2671: 
        !          2672:       for (reg = regstack->top; reg >= 0; reg--)
        !          2673:        if (! TEST_HARD_REG_BIT (label_stack->reg_set, regstack->reg[reg]))
        !          2674:          break;
        !          2675: 
        !          2676:       if (reg == -1)
        !          2677:        {
        !          2678:          /* change_stack will not emit any code in this case. */
        !          2679: 
        !          2680:          change_stack (label, regstack, label_stack, emit_insn_after);
        !          2681:          return;
        !          2682:        }
        !          2683:     }
        !          2684:   else if (label_stack->top == regstack->top)
        !          2685:     {
        !          2686:       for (reg = label_stack->top; reg >= 0; reg--)
        !          2687:        if (label_stack->reg[reg] != regstack->reg[reg])
        !          2688:          break;
        !          2689: 
        !          2690:       if (reg == -1)
        !          2691:        return;
        !          2692:     }
        !          2693: 
        !          2694:   /* At least one insn will need to be inserted before label.  Insert
        !          2695:      a jump around the code we are about to emit.  Emit a label for the new
        !          2696:      code, and point the original insn at this new label. We can't use
        !          2697:      redirect_jump here, because we're using fld[4] of the code labels as
        !          2698:      LABEL_REF chains, no NUSES counters. */
        !          2699: 
        !          2700:   new_jump = emit_jump_insn_before (gen_jump (label), label);
        !          2701:   record_label_references (new_jump, PATTERN (new_jump));
        !          2702:   JUMP_LABEL (new_jump) = label;
        !          2703: 
        !          2704:   new_barrier = emit_barrier_after (new_jump);
        !          2705: 
        !          2706:   new_label = gen_label_rtx ();
        !          2707:   emit_label_after (new_label, new_barrier);
        !          2708:   LABEL_REFS (new_label) = new_label;
        !          2709: 
        !          2710:   /* The old label_ref will no longer point to the code_label if now uses,
        !          2711:      so strip the label_ref from the code_label's chain of references. */
        !          2712: 
        !          2713:   for (ref = &LABEL_REFS (label); *ref != label; ref = &LABEL_NEXTREF (*ref))
        !          2714:     if (*ref == pat)
        !          2715:       break;
        !          2716: 
        !          2717:   if (*ref == label)
        !          2718:     abort ();
        !          2719: 
        !          2720:   *ref = LABEL_NEXTREF (*ref);
        !          2721: 
        !          2722:   XEXP (pat, 0) = new_label;
        !          2723:   record_label_references (insn, PATTERN (insn));
        !          2724: 
        !          2725:   if (JUMP_LABEL (insn) == label)
        !          2726:     JUMP_LABEL (insn) = new_label;
        !          2727: 
        !          2728:   /* Now emit the needed code. */
        !          2729: 
        !          2730:   temp_stack = *regstack;
        !          2731: 
        !          2732:   change_stack (new_label, &temp_stack, label_stack, emit_insn_after);
        !          2733: }
        !          2734: 
        !          2735: /* Traverse all basic blocks in a function, converting the register
        !          2736:    references in each insn from the "flat" register file that gcc uses, to
        !          2737:    the stack-like registers the 387 uses. */
        !          2738: 
        !          2739: static void
        !          2740: convert_regs ()
        !          2741: {
        !          2742:   register int block, reg;
        !          2743:   register rtx insn, next;
        !          2744:   struct stack_def regstack;
        !          2745: 
        !          2746:   for (block = 0; block < blocks; block++)
        !          2747:     {
        !          2748:       if (block_stack_in[block].top == -2)
        !          2749:        {
        !          2750:          /* This block has not been previously encountered.  Choose a
        !          2751:             default mapping for any stack regs live on entry */
        !          2752: 
        !          2753:          block_stack_in[block].top = -1;
        !          2754: 
        !          2755:          for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
        !          2756:            if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, reg))
        !          2757:              block_stack_in[block].reg[++block_stack_in[block].top] = reg;
        !          2758:        }
        !          2759: 
        !          2760:       /* Process all insns in this block.  Keep track of `next' here,
        !          2761:         so that we don't process any insns emitted while making
        !          2762:         substitutions in INSN. */
        !          2763: 
        !          2764:       next = block_begin[block];
        !          2765:       regstack = block_stack_in[block];
        !          2766:       do
        !          2767:        {
        !          2768:          insn = next;
        !          2769:          next = NEXT_INSN (insn);
        !          2770: 
        !          2771:          /* Don't bother processing unless there is a stack reg
        !          2772:             mentioned.
        !          2773: 
        !          2774:             ??? For now, process CALL_INSNs too to make sure that the
        !          2775:             stack regs are dead after a call.  Remove this eventually. */
        !          2776: 
        !          2777:          if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
        !          2778:            subst_stack_regs (insn, &regstack);
        !          2779: 
        !          2780:        } while (insn != block_end[block]);
        !          2781: 
        !          2782:       /* Something failed if the stack life doesn't match. */
        !          2783: 
        !          2784:       GO_IF_HARD_REG_EQUAL (regstack.reg_set, block_out_reg_set[block], win);
        !          2785: 
        !          2786:       abort ();
        !          2787: 
        !          2788:     win:
        !          2789: 
        !          2790:       /* Adjust the stack of this block on exit to match the stack of
        !          2791:         the target block, or copy stack information into stack of
        !          2792:         jump target if the target block's stack order hasn't been set
        !          2793:         yet. */
        !          2794: 
        !          2795:       if (GET_CODE (insn) == JUMP_INSN)
        !          2796:        goto_block_pat (insn, &regstack, PATTERN (insn));
        !          2797: 
        !          2798:       /* Likewise handle the case where we fall into the next block. */
        !          2799: 
        !          2800:       if ((block < blocks - 1) && block_drops_in[block+1])
        !          2801:        change_stack (insn, &regstack, &block_stack_in[block+1],
        !          2802:                      emit_insn_after);
        !          2803:     }
        !          2804: 
        !          2805:   /* If the last basic block is the end of a loop, and that loop has
        !          2806:      regs live at its start, then the last basic block will have regs live
        !          2807:      at its end that need to be popped before the function returns. */
        !          2808: 
        !          2809:   for (reg = regstack.top; reg >= 0; reg--)
        !          2810:     if (! current_function_returns_real
        !          2811:        || regstack.reg[reg] != FIRST_STACK_REG)
        !          2812:       insn = emit_pop_insn (insn, &regstack,
        !          2813:                            FP_mode_reg[regstack.reg[reg]][(int) DFmode],
        !          2814:                            emit_insn_after);
        !          2815: }
        !          2816: 
        !          2817: /* Check expression PAT, which is in INSN, for label references.  if
        !          2818:    one is found, print the block number of destination to FILE. */
        !          2819: 
        !          2820: static void
        !          2821: print_blocks (file, insn, pat)
        !          2822:      FILE *file;
        !          2823:      rtx insn, pat;
        !          2824: {
        !          2825:   register RTX_CODE code = GET_CODE (pat);
        !          2826:   register int i;
        !          2827:   register char *fmt;
        !          2828: 
        !          2829:   if (code == LABEL_REF)
        !          2830:     {
        !          2831:       register rtx label = XEXP (pat, 0);
        !          2832: 
        !          2833:       if (GET_CODE (label) != CODE_LABEL)
        !          2834:        abort ();
        !          2835: 
        !          2836:       fprintf (file, " %d", BLOCK_NUM (label));
        !          2837: 
        !          2838:       return;
        !          2839:     }
        !          2840: 
        !          2841:   fmt = GET_RTX_FORMAT (code);
        !          2842:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          2843:     {
        !          2844:       if (fmt[i] == 'e')
        !          2845:        print_blocks (file, insn, XEXP (pat, i));
        !          2846:       if (fmt[i] == 'E')
        !          2847:        {
        !          2848:          register int j;
        !          2849:          for (j = 0; j < XVECLEN (pat, i); j++)
        !          2850:            print_blocks (file, insn, XVECEXP (pat, i, j));
        !          2851:        }
        !          2852:     }
        !          2853: }
        !          2854: 
        !          2855: /* Write information about stack registers and stack blocks into FILE.
        !          2856:    This is part of making a debugging dump.  */
        !          2857: static void
        !          2858: dump_stack_info (file)
        !          2859:      FILE *file;
        !          2860: {
        !          2861:   register int block;
        !          2862: 
        !          2863:   fprintf (file, "\n%d stack blocks.\n", blocks);
        !          2864:   for (block = 0; block < blocks; block++)
        !          2865:     {
        !          2866:       register rtx head, jump, end;
        !          2867:       register int regno;
        !          2868: 
        !          2869:       fprintf (file, "\nStack block %d: first insn %d, last %d.\n",
        !          2870:               block, INSN_UID (block_begin[block]),
        !          2871:               INSN_UID (block_end[block]));
        !          2872: 
        !          2873:       head = block_begin[block];
        !          2874: 
        !          2875:       fprintf (file, "Reached from blocks: ");
        !          2876:       if (GET_CODE (head) == CODE_LABEL)
        !          2877:        for (jump = LABEL_REFS (head);
        !          2878:             jump != head;
        !          2879:             jump = LABEL_NEXTREF (jump))
        !          2880:          {
        !          2881:            register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
        !          2882:            fprintf (file, " %d", from_block);
        !          2883:          }
        !          2884:       if (block_drops_in[block])
        !          2885:        fprintf (file, " previous");
        !          2886: 
        !          2887:       fprintf (file, "\nlive stack registers on block entry: ");
        !          2888:       for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG ; regno++)
        !          2889:        {
        !          2890:          if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, regno))
        !          2891:            fprintf (file, "%d ", regno);
        !          2892:        }
        !          2893: 
        !          2894:       fprintf (file, "\nlive stack registers on block exit: ");
        !          2895:       for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG ; regno++)
        !          2896:        {
        !          2897:          if (TEST_HARD_REG_BIT (block_out_reg_set[block], regno))
        !          2898:            fprintf (file, "%d ", regno);
        !          2899:        }
        !          2900: 
        !          2901:       end = block_end[block];
        !          2902: 
        !          2903:       fprintf (file, "\nJumps to blocks: ");
        !          2904:       if (GET_CODE (end) == JUMP_INSN)
        !          2905:        print_blocks (file, end, PATTERN (end));
        !          2906: 
        !          2907:       if (block + 1 < blocks && block_drops_in[block+1])
        !          2908:        fprintf (file, " next");
        !          2909:       else if (block + 1 == blocks
        !          2910:               || (GET_CODE (end) == JUMP_INSN
        !          2911:                   && GET_CODE (PATTERN (end)) == RETURN))
        !          2912:        fprintf (file, " return");
        !          2913: 
        !          2914:       fprintf (file, "\n");
        !          2915:     }
        !          2916: }
        !          2917: #endif /* STACK_REGS */

unix.superglobalmegacorp.com

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