Annotation of gcc/reg-stack.c, revision 1.1

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