/* Register to Stack convert for GNU compiler.
   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

/* This pass converts stack-like registers from the "flat register
   file" model that gcc uses, to a stack convention that the 387 uses.

   * The form of the input:

   On input, the function consists of insn that have had their
   registers fully allocated to a set of "virtual" registers.  Note that
   the word "virtual" is used differently here than elsewhere in gcc: for
   each virtual stack reg, there is a hard reg, but the mapping between
   them is not known until this pass is run.  On output, hard register
   numbers have been substituted, and various pop and exchange insns have
   been emitted.  The hard register numbers and the virtual register
   numbers completely overlap - before this pass, all stack register
   numbers are virtual, and afterward they are all hard.

   The virtual registers can be manipulated normally by gcc, and their
   semantics are the same as for normal registers.  After the hard
   register numbers are substituted, the semantics of an insn containing
   stack-like regs are not the same as for an insn with normal regs: for
   instance, it is not safe to delete an insn that appears to be a no-op
   move.  In general, no insn containing hard regs should be changed
   after this pass is done.

   * The form of the output:

   After this pass, hard register numbers represent the distance from
   the current top of stack to the desired register.  A reference to
   FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1,
   represents the register just below that, and so forth.  Also, REG_DEAD
   notes indicate whether or not a stack register should be popped.

   A "swap" insn looks like a parallel of two patterns, where each
   pattern is a SET: one sets A to B, the other B to A.

   A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG
   and whose SET_DEST is REG or MEM.  Any other SET_DEST, such as PLUS,
   will replace the existing stack top, not push a new value.

   A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose
   SET_SRC is REG or MEM.

   The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG
   appears ambiguous.  As a special case, the presence of a REG_DEAD note
   for FIRST_STACK_REG differentiates between a load insn and a pop.

   If a REG_DEAD is present, the insn represents a "pop" that discards
   the top of the register stack.  If there is no REG_DEAD note, then the
   insn represents a "dup" or a push of the current top of stack onto the
   stack.

   * Methodology:

   Existing REG_DEAD and REG_UNUSED notes for stack registers are
   deleted and recreated from scratch.  REG_DEAD is never created for a
   SET_DEST, only REG_UNUSED.

   Before life analysis, the mode of each insn is set based on whether
   or not any stack registers are mentioned within that insn.  VOIDmode
   means that no regs are mentioned anyway, and QImode means that at
   least one pattern within the insn mentions stack registers.  This
   information is valid until after reg_to_stack returns, and is used
   from jump_optimize.

   * asm_operands:

   There are several rules on the usage of stack-like regs in
   asm_operands insns.  These rules apply only to the operands that are
   stack-like regs:

   1. Given a set of input regs that die in an asm_operands, it is
      necessary to know which are implicitly popped by the asm, and
      which must be explicitly popped by gcc.

	An input reg that is implicitly popped by the asm must be
	explicitly clobbered, unless it is constrained to match an
	output operand.

   2. For any input reg that is implicitly popped by an asm, it is
      necessary to know how to adjust the stack to compensate for the pop.
      If any non-popped input is closer to the top of the reg-stack than
      the implicitly popped reg, it would not be possible to know what the
      stack looked like - it's not clear how the rest of the stack "slides
      up".

	All implicitly popped input regs must be closer to the top of
	the reg-stack than any input that is not implicitly popped.

   3. It is possible that if an input dies in an insn, reload might
      use the input reg for an output reload.  Consider this example:

		asm ("foo" : "=t" (a) : "f" (b));

      This asm says that input B is not popped by the asm, and that
      the asm pushes a result onto the reg-stack, ie, the stack is one
      deeper after the asm than it was before.  But, it is possible that
      reload will think that it can use the same reg for both the input and
      the output, if input B dies in this insn.

	If any input operand uses the "f" constraint, all output reg
	constraints must use the "&" earlyclobber.

      The asm above would be written as

		asm ("foo" : "=&t" (a) : "f" (b));

   4. Some operands need to be in particular places on the stack.  All
      output operands fall in this category - there is no other way to
      know which regs the outputs appear in unless the user indicates
      this in the constraints.

	Output operands must specifically indicate which reg an output
	appears in after an asm.  "=f" is not allowed: the operand
	constraints must select a class with a single reg.

   5. Output operands may not be "inserted" between existing stack regs.
      Since no 387 opcode uses a read/write operand, all output operands
      are dead before the asm_operands, and are pushed by the asm_operands.
      It makes no sense to push anywhere but the top of the reg-stack.

	Output operands must start at the top of the reg-stack: output
	operands may not "skip" a reg.

   6. Some asm statements may need extra stack space for internal
      calculations.  This can be guaranteed by clobbering stack registers
      unrelated to the inputs and outputs.

   Here are a couple of reasonable asms to want to write.  This asm
   takes one input, which is internally popped, and produces two outputs.

	asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));

   This asm takes two inputs, which are popped by the fyl2xp1 opcode,
   and replaces them with one output.  The user must code the "st(1)"
   clobber for reg-stack.c to know that fyl2xp1 pops both inputs.

	asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");

   */

#include <stdio.h>
#include "config.h"
#include "tree.h"
#include "rtl.h"
#include "insn-config.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-flags.h"

#ifdef STACK_REGS

#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)

/* This is the basic stack record.  TOP is an index into REG[] such
   that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.

   If TOP is -2, REG[] is not yet initialized.  Stack initialization
   consists of placing each live reg in array `reg' and setting `top'
   appropriately.

   REG_SET indicates which registers are live.  */

typedef struct stack_def
{
  int top;			/* index to top stack element */
  HARD_REG_SET reg_set;		/* set of live registers */
  char reg[REG_STACK_SIZE];	/* register - stack mapping */
} *stack;

/* highest instruction uid */
static int max_uid = 0;

/* Number of basic blocks in the current function.  */
static int blocks;

/* Element N is first insn in basic block N.
   This info lasts until we finish compiling the function.  */
static rtx *block_begin;

/* Element N is last insn in basic block N.
   This info lasts until we finish compiling the function.  */
static rtx *block_end;

/* Element N is nonzero if control can drop into basic block N */
static char *block_drops_in;

/* Element N says all about the stack at entry block N */
static stack block_stack_in;

/* Element N says all about the stack life at the end of block N */
static HARD_REG_SET *block_out_reg_set;

/* This is where the BLOCK_NUM values are really stored.  This is set
   up by find_blocks and used there and in life_analysis.  It can be used
   later, but only to look up an insn that is the head or tail of some
   block.  life_analysis and the stack register conversion process can
   add insns within a block.  */
static int *block_number;

/* This is the register file for all register after conversion */
static rtx
  FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];

#define FP_MODE_REG(regno,mode)	\
  (FP_mode_reg[(regno)-FIRST_STACK_REG][(int)(mode)])

/* Get the basic block number of an insn.  See note at block_number
   definition are validity of this information.  */

#define BLOCK_NUM(INSN)  \
  ((INSN_UID (INSN) > max_uid)	\
   ? (abort() , -1) : block_number[INSN_UID (INSN)])

extern rtx forced_labels;

/* Forward declarations */

static void mark_regs_pat		PROTO((rtx, HARD_REG_SET *));
static void straighten_stack		PROTO((rtx, stack));
static void record_label_references	PROTO((rtx, rtx));
static rtx *get_true_reg		PROTO((rtx *));
static int constrain_asm_operands	PROTO((int, rtx *, char **, int *,
					       enum reg_class *));

static void record_asm_reg_life		PROTO((rtx,stack, rtx *, char **,
					       int, int));
static void record_reg_life_pat		PROTO((rtx, HARD_REG_SET *,
					       HARD_REG_SET *, int));
static void get_asm_operand_length	PROTO((rtx, int, int *, int *));
static void record_reg_life		PROTO((rtx, int, stack));
static void find_blocks			PROTO((rtx));
static int uses_reg_or_mem		PROTO((rtx));
static rtx stack_result			PROTO((tree));
static void stack_reg_life_analysis	PROTO((rtx, HARD_REG_SET *));
static void replace_reg			PROTO((rtx *, int));
static void remove_regno_note		PROTO((rtx, enum reg_note, int));
static int get_hard_regnum		PROTO((stack, rtx));
static void delete_insn_for_stacker	PROTO((rtx));
static rtx emit_pop_insn		PROTO((rtx, stack, rtx, rtx (*) ()));
static void emit_swap_insn		PROTO((rtx, stack, rtx));
static void move_for_stack_reg		PROTO((rtx, stack, rtx));
static void swap_rtx_condition		PROTO((rtx));
static void compare_for_stack_reg	PROTO((rtx, stack, rtx));
static void subst_stack_regs_pat	PROTO((rtx, stack, rtx));
static void subst_asm_stack_regs	PROTO((rtx, stack, rtx *, rtx **,
					       char **, int, int));
static void subst_stack_regs		PROTO((rtx, stack));
static void change_stack		PROTO((rtx, stack, stack, rtx (*) ()));

static void goto_block_pat		PROTO((rtx, stack, rtx));
static void convert_regs		PROTO((void));
static void print_blocks		PROTO((FILE *, rtx, rtx));
static void dump_stack_info		PROTO((FILE *));

/* Mark all registers needed for this pattern.  */

static void
mark_regs_pat (pat, set)
     rtx pat;
     HARD_REG_SET *set;
{
  enum machine_mode mode;
  register int regno;
  register int count;

  if (GET_CODE (pat) == SUBREG)
   {
     mode = GET_MODE (pat);
     regno = SUBREG_WORD (pat);
     regno += REGNO (SUBREG_REG (pat));
   }
  else
     regno = REGNO (pat), mode = GET_MODE (pat);

  for (count = HARD_REGNO_NREGS (regno, mode);
       count; count--, regno++)
     SET_HARD_REG_BIT (*set, regno);
}

/* Reorganise the stack into ascending numbers,
   after this insn.  */

static void
straighten_stack (insn, regstack)
     rtx insn;
     stack regstack;
{
  struct stack_def temp_stack;
  int top;

  temp_stack.reg_set = regstack->reg_set;

  for (top = temp_stack.top = regstack->top; top >= 0; top--)
     temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
  
  change_stack (insn, regstack, &temp_stack, emit_insn_after);
}

/* Return non-zero if any stack register is mentioned somewhere within PAT.  */

int
stack_regs_mentioned_p (pat)
     rtx pat;
{
  register char *fmt;
  register int i;

  if (STACK_REG_P (pat))
    return 1;

  fmt = GET_RTX_FORMAT (GET_CODE (pat));
  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'E')
	{
	  register int j;

	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
	    if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
	      return 1;
	}
      else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
	return 1;
    }

  return 0;
}

/* Convert register usage from "flat" register file usage to a "stack
   register file.  FIRST is the first insn in the function, FILE is the
   dump file, if used.

   First compute the beginning and end of each basic block.  Do a
   register life analysis on the stack registers, recording the result
   for the head and tail of each basic block.  The convert each insn one
   by one.  Run a last jump_optimize() pass, if optimizing, to eliminate
   any cross-jumping created when the converter inserts pop insns.*/

void
reg_to_stack (first, file)
     rtx first;
     FILE *file;
{
  register rtx insn;
  register int i;
  int stack_reg_seen = 0;
  enum machine_mode mode;
  HARD_REG_SET stackentry;

  CLEAR_HARD_REG_SET (stackentry);

   {
     static initialised;
     if (!initialised)
      {
#if 0
	initialised = 1;	/* This array can not have been previously
				   initialised, because the rtx's are
				   thrown away between compilations of
				   functions.  */
#endif
        for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
         {
           for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
               mode = GET_MODE_WIDER_MODE (mode))
              FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i);
           for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT); mode != VOIDmode;
               mode = GET_MODE_WIDER_MODE (mode))
              FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i);
         }
      }
   }

  /* Count the basic blocks.  Also find maximum insn uid.  */
  {
    register RTX_CODE prev_code = BARRIER;
    register RTX_CODE code;
    register before_function_beg = 1;

    max_uid = 0;
    blocks = 0;
    for (insn = first; insn; insn = NEXT_INSN (insn))
      {
	/* Note that this loop must select the same block boundaries
	   as code in find_blocks.  Also note that this code is not the
	   same as that used in flow.c.  */

	if (INSN_UID (insn) > max_uid)
	  max_uid = INSN_UID (insn);

	code = GET_CODE (insn);

	if (code == CODE_LABEL
	    || (prev_code != INSN
		&& prev_code != CALL_INSN
		&& prev_code != CODE_LABEL
		&& GET_RTX_CLASS (code) == 'i'))
	  blocks++;

	if (code == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
	   before_function_beg = 0;

	/* Remember whether or not this insn mentions an FP regs.
	   Check JUMP_INSNs too, in case someone creates a funny PARALLEL.  */

	if (GET_RTX_CLASS (code) == 'i'
	    && stack_regs_mentioned_p (PATTERN (insn)))
	  {
	    stack_reg_seen = 1;
	    PUT_MODE (insn, QImode);

	    /* Note any register passing parameters.  */

	    if (before_function_beg && code == INSN
	        && GET_CODE (PATTERN (insn)) == USE)
              record_reg_life_pat (PATTERN (insn), (HARD_REG_SET *) 0,
				   &stackentry, 1);
	  }
	else
	  PUT_MODE (insn, VOIDmode);

	if (code == CODE_LABEL)
	  LABEL_REFS (insn) = insn; /* delete old chain */

	if (code != NOTE)
	  prev_code = code;
      }
  }

  /* If no stack register reference exists in this insn, there isn't
     anything to convert.  */

  if (! stack_reg_seen)
    return;

  /* If there are stack registers, there must be at least one block.  */

  if (! blocks)
    abort ();

  /* Allocate some tables that last till end of compiling this function
     and some needed only in find_blocks and life_analysis.  */

  block_begin = (rtx *) alloca (blocks * sizeof (rtx));
  block_end = (rtx *) alloca (blocks * sizeof (rtx));
  block_drops_in = (char *) alloca (blocks);

  block_stack_in = (stack) alloca (blocks * sizeof (struct stack_def));
  block_out_reg_set = (HARD_REG_SET *) alloca (blocks * sizeof (HARD_REG_SET));
  bzero ((char *) block_stack_in, blocks * sizeof (struct stack_def));
  bzero ((char *) block_out_reg_set, blocks * sizeof (HARD_REG_SET));

  block_number = (int *) alloca ((max_uid + 1) * sizeof (int));

  find_blocks (first);
  stack_reg_life_analysis (first, &stackentry);

  /* Dump the life analysis debug information before jump
     optimization, as that will destroy the LABEL_REFS we keep the
     information in.  */

  if (file)
    dump_stack_info (file);

  convert_regs ();

  if (optimize)
    jump_optimize (first, 2, 0, 0);
}

/* Check PAT, which is in INSN, for LABEL_REFs.  Add INSN to the
   label's chain of references, and note which insn contains each
   reference.  */

static void
record_label_references (insn, pat)
     rtx insn, pat;
{
  register enum rtx_code code = GET_CODE (pat);
  register int i;
  register char *fmt;

  if (code == LABEL_REF)
    {
      register rtx label = XEXP (pat, 0);
      register rtx ref;

      if (GET_CODE (label) != CODE_LABEL)
	abort ();

      /* If this is an undefined label, LABEL_REFS (label) contains
         garbage.  */
      if (INSN_UID (label) == 0)
	return;

      /* Don't make a duplicate in the code_label's chain.  */

      for (ref = LABEL_REFS (label);
	   ref && ref != label;
	   ref = LABEL_NEXTREF (ref))
	if (CONTAINING_INSN (ref) == insn)
	  return;

      CONTAINING_INSN (pat) = insn;
      LABEL_NEXTREF (pat) = LABEL_REFS (label);
      LABEL_REFS (label) = pat;

      return;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	record_label_references (insn, XEXP (pat, i));
      if (fmt[i] == 'E')
	{
	  register int j;
	  for (j = 0; j < XVECLEN (pat, i); j++)
	    record_label_references (insn, XVECEXP (pat, i, j));
	}
    }
}

/* Return a pointer to the REG expression within PAT.  If PAT is not a
   REG, possible enclosed by a conversion rtx, return the inner part of
   PAT that stopped the search.  */

static rtx *
get_true_reg (pat)
     rtx *pat;
{
  for (;;)
     switch (GET_CODE (*pat))
      {
	case SUBREG:
		/* eliminate FP subregister accesses in favour of the
		   actual FP register in use.  */
	 {
	   rtx subreg;
	   if (FP_REG_P (subreg = SUBREG_REG (*pat)))
	    {
	      *pat = FP_MODE_REG (REGNO (subreg) + SUBREG_WORD (*pat),
				  GET_MODE (subreg));
	default:
	      return pat;
	    }
	 }
	case FLOAT:
	case FIX:
	case FLOAT_EXTEND:
	   pat = & XEXP (*pat, 0);
      }
}

/* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands.
   N_OPERANDS is the total number of operands.  Return which alternative
   matched, or -1 is no alternative matches.

   OPERAND_MATCHES is an array which indicates which operand this
   operand matches due to the constraints, or -1 if no match is required.
   If two operands match by coincidence, but are not required to match by
   the constraints, -1 is returned.

   OPERAND_CLASS is an array which indicates the smallest class
   required by the constraints.  If the alternative that matches calls
   for some class `class', and the operand matches a subclass of `class',
   OPERAND_CLASS is set to `class' as required by the constraints, not to
   the subclass. If an alternative allows more than one class,
   OPERAND_CLASS is set to the smallest class that is a union of the
   allowed classes.  */

static int
constrain_asm_operands (n_operands, operands, operand_constraints,
			operand_matches, operand_class)
     int n_operands;
     rtx *operands;
     char **operand_constraints;
     int *operand_matches;
     enum reg_class *operand_class;
{
  char **constraints = (char **) alloca (n_operands * sizeof (char *));
  char *q;
  int this_alternative, this_operand;
  int n_alternatives;
  int j;

  for (j = 0; j < n_operands; j++)
    constraints[j] = operand_constraints[j];

  /* Compute the number of alternatives in the operands.  reload has
     already guaranteed that all operands have the same number of
     alternatives.  */

  n_alternatives = 1;
  for (q = constraints[0]; *q; q++)
    n_alternatives += (*q == ',');

  this_alternative = 0;
  while (this_alternative < n_alternatives)
    {
      int lose = 0;
      int i;

      /* No operands match, no narrow class requirements yet.  */
      for (i = 0; i < n_operands; i++)
	{
	  operand_matches[i] = -1;
	  operand_class[i] = NO_REGS;
	}

      for (this_operand = 0; this_operand < n_operands; this_operand++)
	{
	  rtx op = operands[this_operand];
	  enum machine_mode mode = GET_MODE (op);
	  char *p = constraints[this_operand];
	  int offset = 0;
	  int win = 0;
	  int c;

	  if (GET_CODE (op) == SUBREG)
	    {
	      if (GET_CODE (SUBREG_REG (op)) == REG
		  && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
		offset = SUBREG_WORD (op);
	      op = SUBREG_REG (op);
	    }

	  /* An empty constraint or empty alternative
	     allows anything which matched the pattern.  */
	  if (*p == 0 || *p == ',')
	    win = 1;

	  while (*p && (c = *p++) != ',')
	    switch (c)
	      {
	      case '=':
	      case '+':
	      case '?':
	      case '&':
	      case '!':
	      case '*':
	      case '%':
		/* Ignore these.  */
		break;

	      case '#':
		/* Ignore rest of this alternative.  */
		while (*p && *p != ',') p++;
		break;

	      case '0':
	      case '1':
	      case '2':
	      case '3':
	      case '4':
	      case '5':
		/* This operand must be the same as a previous one.
		   This kind of constraint is used for instructions such
		   as add when they take only two operands.

		   Note that the lower-numbered operand is passed first.  */

		if (operands_match_p (operands[c - '0'],
				      operands[this_operand]))
		  {
		    operand_matches[this_operand] = c - '0';
		    win = 1;
		  }
		break;

	      case 'p':
		/* p is used for address_operands.  Since this is an asm,
		   just to make sure that the operand is valid for Pmode.  */

		if (strict_memory_address_p (Pmode, op))
		  win = 1;
		break;

	      case 'g':
		/* Anything goes unless it is a REG and really has a hard reg
		   but the hard reg is not in the class GENERAL_REGS.  */
		if (GENERAL_REGS == ALL_REGS
		    || GET_CODE (op) != REG
		    || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
		  {
		    if (GET_CODE (op) == REG)
		      operand_class[this_operand]
			= reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
		    win = 1;
		  }
		break;

	      case 'r':
		if (GET_CODE (op) == REG
		    && (GENERAL_REGS == ALL_REGS
			|| reg_fits_class_p (op, GENERAL_REGS, offset, mode)))
		  {
		    operand_class[this_operand]
		      = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
		    win = 1;
		  }
		break;

	      case 'X':
		/* This is used for a MATCH_SCRATCH in the cases when we
		   don't actually need anything.  So anything goes any time.  */
		win = 1;
		break;

	      case 'm':
		if (GET_CODE (op) == MEM)
		  win = 1;
		break;

	      case '<':
		if (GET_CODE (op) == MEM
		    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
			|| GET_CODE (XEXP (op, 0)) == POST_DEC))
		  win = 1;
		break;

	      case '>':
		if (GET_CODE (op) == MEM
		    && (GET_CODE (XEXP (op, 0)) == PRE_INC
			|| GET_CODE (XEXP (op, 0)) == POST_INC))
		  win = 1;
		break;

	      case 'E':
		/* Match any CONST_DOUBLE, but only if
		   we can examine the bits of it reliably.  */
		if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
		     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
		    && GET_CODE (op) != VOIDmode && ! flag_pretend_float)
		  break;
		if (GET_CODE (op) == CONST_DOUBLE)
		  win = 1;
		break;

	      case 'F':
		if (GET_CODE (op) == CONST_DOUBLE)
		  win = 1;
		break;

	      case 'G':
	      case 'H':
		if (GET_CODE (op) == CONST_DOUBLE
		    && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
		  win = 1;
		break;

	      case 's':
		if (GET_CODE (op) == CONST_INT
		    || (GET_CODE (op) == CONST_DOUBLE
			&& GET_MODE (op) == VOIDmode))
		  break;
		/* Fall through */
	      case 'i':
		if (CONSTANT_P (op))
		  win = 1;
		break;

	      case 'n':
		if (GET_CODE (op) == CONST_INT
		    || (GET_CODE (op) == CONST_DOUBLE
			&& GET_MODE (op) == VOIDmode))
		  win = 1;
		break;

	      case 'I':
	      case 'J':
	      case 'K':
	      case 'L':
	      case 'M':
	      case 'N':
	      case 'O':
	      case 'P':
		if (GET_CODE (op) == CONST_INT
		    && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
		  win = 1;
		break;

#ifdef EXTRA_CONSTRAINT
              case 'Q':
              case 'R':
              case 'S':
              case 'T':
              case 'U':
		if (EXTRA_CONSTRAINT (op, c))
		  win = 1;
		break;
#endif

	      case 'V':
		if (GET_CODE (op) == MEM && ! offsettable_memref_p (op))
		  win = 1;
		break;

	      case 'o':
		if (offsettable_memref_p (op))
		  win = 1;
		break;

	      default:
		if (GET_CODE (op) == REG
		    && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
					 offset, mode))
		  {
		    operand_class[this_operand]
		      = reg_class_subunion[(int)operand_class[this_operand]][(int) REG_CLASS_FROM_LETTER (c)];
		    win = 1;
		  }
	      }

	  constraints[this_operand] = p;
	  /* If this operand did not win somehow,
	     this alternative loses.  */
	  if (! win)
	    lose = 1;
	}
      /* This alternative won; the operands are ok.
	 Change whichever operands this alternative says to change.  */
      if (! lose)
	break;

      this_alternative++;
    }

  /* For operands constrained to match another operand, copy the other
     operand's class to this operand's class.  */
  for (j = 0; j < n_operands; j++)
    if (operand_matches[j] >= 0)
      operand_class[j] = operand_class[operand_matches[j]];

  return this_alternative == n_alternatives ? -1 : this_alternative;
}

/* Record the life info of each stack reg in INSN, updating REGSTACK.
   N_INPUTS is the number of inputs; N_OUTPUTS the outputs.  CONSTRAINTS
   is an array of the constraint strings used in the asm statement.
   OPERANDS is an array of all operands for the insn, and is assumed to
   contain all output operands, then all inputs operands.

   There are many rules that an asm statement for stack-like regs must
   follow.  Those rules are explained at the top of this file: the rule
   numbers below refer to that explanation.  */

static void
record_asm_reg_life (insn, regstack, operands, constraints,
		     n_inputs, n_outputs)
     rtx insn;
     stack regstack;
     rtx *operands;
     char **constraints;
     int n_inputs, n_outputs;
{
  int i;
  int n_operands = n_inputs + n_outputs;
  int first_input = n_outputs;
  int n_clobbers;
  int malformed_asm = 0;
  rtx body = PATTERN (insn);

  int *operand_matches = (int *) alloca (n_operands * sizeof (int *));

  enum reg_class *operand_class 
    = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));

  int reg_used_as_output[FIRST_PSEUDO_REGISTER];
  int implicitly_dies[FIRST_PSEUDO_REGISTER];

  rtx *clobber_reg;

  /* Find out what the constraints require.  If no constraint
     alternative matches, this asm is malformed.  */
  i = constrain_asm_operands (n_operands, operands, constraints,
			      operand_matches, operand_class);
  if (i < 0)
    malformed_asm = 1;

  /* Strip SUBREGs here to make the following code simpler.  */
  for (i = 0; i < n_operands; i++)
    if (GET_CODE (operands[i]) == SUBREG
	&& GET_CODE (SUBREG_REG (operands[i])) == REG)
      operands[i] = SUBREG_REG (operands[i]);

  /* Set up CLOBBER_REG.  */

  n_clobbers = 0;

  if (GET_CODE (body) == PARALLEL)
    {
      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));

      for (i = 0; i < XVECLEN (body, 0); i++)
	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
	  {
	    rtx clobber = XVECEXP (body, 0, i);
	    rtx reg = XEXP (clobber, 0);

	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
	      reg = SUBREG_REG (reg);

	    if (STACK_REG_P (reg))
	      {
		clobber_reg[n_clobbers] = reg;
		n_clobbers++;
	      }
	  }
    }

  /* Enforce rule #4: Output operands must specifically indicate which
     reg an output appears in after an asm.  "=f" is not allowed: the
     operand constraints must select a class with a single reg.

     Also enforce rule #5: Output operands must start at the top of
     the reg-stack: output operands may not "skip" a reg.  */

  bzero ((char *) reg_used_as_output, sizeof (reg_used_as_output));
  for (i = 0; i < n_outputs; i++)
    if (STACK_REG_P (operands[i]))
      if (reg_class_size[(int) operand_class[i]] != 1)
	{
	  error_for_asm
	    (insn, "Output constraint %d must specify a single register", i);
	  malformed_asm = 1;
	}
      else
	reg_used_as_output[REGNO (operands[i])] = 1;


  /* Search for first non-popped reg.  */
  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
    if (! reg_used_as_output[i])
      break;

  /* If there are any other popped regs, that's an error.  */
  for (; i < LAST_STACK_REG + 1; i++)
    if (reg_used_as_output[i])
      break;

  if (i != LAST_STACK_REG + 1)
    {
      error_for_asm (insn, "Output regs must be grouped at top of stack");
      malformed_asm = 1;
    }

  /* Enforce rule #2: All implicitly popped input regs must be closer
     to the top of the reg-stack than any input that is not implicitly
     popped.  */

  bzero ((char *) implicitly_dies, sizeof (implicitly_dies));
  for (i = first_input; i < first_input + n_inputs; i++)
    if (STACK_REG_P (operands[i]))
      {
	/* An input reg is implicitly popped if it is tied to an
	   output, or if there is a CLOBBER for it.  */
	int j;

	for (j = 0; j < n_clobbers; j++)
	  if (operands_match_p (clobber_reg[j], operands[i]))
	    break;

	if (j < n_clobbers || operand_matches[i] >= 0)
	  implicitly_dies[REGNO (operands[i])] = 1;
      }

  /* Search for first non-popped reg.  */
  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
    if (! implicitly_dies[i])
      break;

  /* If there are any other popped regs, that's an error.  */
  for (; i < LAST_STACK_REG + 1; i++)
    if (implicitly_dies[i])
      break;

  if (i != LAST_STACK_REG + 1)
    {
      error_for_asm (insn,
		     "Implicitly popped regs must be grouped at top of stack");
      malformed_asm = 1;
    }

  /* Enfore rule #3: If any input operand uses the "f" constraint, all
     output constraints must use the "&" earlyclobber.

     ???  Detect this more deterministically by having constraint_asm_operands
     record any earlyclobber.  */

  for (i = first_input; i < first_input + n_inputs; i++)
    if (operand_matches[i] == -1)
      {
	int j;

	for (j = 0; j < n_outputs; j++)
	  if (operands_match_p (operands[j], operands[i]))
	    {
	      error_for_asm (insn,
			     "Output operand %d must use `&' constraint", j);
	      malformed_asm = 1;
	    }
      }

  if (malformed_asm)
    {
      /* Avoid further trouble with this insn.  */
      PATTERN (insn) = gen_rtx (USE, VOIDmode, const0_rtx);
      PUT_MODE (insn, VOIDmode);
      return;
    }

  /* Process all outputs */
  for (i = 0; i < n_outputs; i++)
    {
      rtx op = operands[i];

      if (! STACK_REG_P (op))
	if (stack_regs_mentioned_p (op))
	  abort ();
	else
	  continue;

      /* Each destination is dead before this insn.  If the
	 destination is not used after this insn, record this with
	 REG_UNUSED.  */

      if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (op)))
	REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, op,
				    REG_NOTES (insn));

      CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (op));
    }

  /* Process all inputs */
  for (i = first_input; i < first_input + n_inputs; i++)
    {
      if (! STACK_REG_P (operands[i]))
	if (stack_regs_mentioned_p (operands[i]))
	  abort ();
	else
	  continue;

      /* If an input is dead after the insn, record a death note.
	 But don't record a death note if there is already a death note,
	 or if the input is also an output.  */

      if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]))
	  && operand_matches[i] == -1
	  && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) == NULL_RTX)
	REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, operands[i],
				    REG_NOTES (insn));

      SET_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]));
    }
}

/* Scan PAT, which is part of INSN, and record registers appearing in
   a SET_DEST in DEST, and other registers in SRC.

   This function does not know about SET_DESTs that are both input and
   output (such as ZERO_EXTRACT) - this cannot happen on a 387.  */

static void
record_reg_life_pat (pat, src, dest, douse)
     rtx pat;
     HARD_REG_SET *src, *dest;
     int douse;
{
  register char *fmt;
  register int i;

  if (STACK_REG_P (pat)
      || (GET_CODE (pat) == SUBREG && STACK_REG_P (SUBREG_REG (pat))))
    {
      if (src)
	 mark_regs_pat (pat, src);

      if (dest)
	 mark_regs_pat (pat, dest);

      return;
    }

  if (GET_CODE (pat) == SET)
    {
      record_reg_life_pat (XEXP (pat, 0), NULL_PTR, dest, 0);
      record_reg_life_pat (XEXP (pat, 1), src, NULL_PTR, 0);
      return;
    }

  /* We don't need to consider either of these cases.  */
  if (GET_CODE (pat) == USE && !douse || GET_CODE (pat) == CLOBBER)
    return;

  fmt = GET_RTX_FORMAT (GET_CODE (pat));
  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'E')
	{
	  register int j;

	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
	    record_reg_life_pat (XVECEXP (pat, i, j), src, dest, 0);
	}
      else if (fmt[i] == 'e')
	record_reg_life_pat (XEXP (pat, i), src, dest, 0);
    }
}

/* Calculate the number of inputs and outputs in BODY, an
   asm_operands.  N_OPERANDS is the total number of operands, and
   N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
   placed.  */

static void
get_asm_operand_lengths (body, n_operands, n_inputs, n_outputs)
     rtx body;
     int n_operands;
     int *n_inputs, *n_outputs;
{
  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));

  else if (GET_CODE (body) == ASM_OPERANDS)
    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (body);

  else if (GET_CODE (body) == PARALLEL
	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));

  else if (GET_CODE (body) == PARALLEL
	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
  else
    abort ();

  *n_outputs = n_operands - *n_inputs;
}

/* Scan INSN, which is in BLOCK, and record the life & death of stack
   registers in REGSTACK.  This function is called to process insns from
   the last insn in a block to the first.  The actual scanning is done in
   record_reg_life_pat.

   If a register is live after a CALL_INSN, but is not a value return
   register for that CALL_INSN, then code is emitted to initialize that
   register.  The block_end[] data is kept accurate.

   Existing death and unset notes for stack registers are deleted
   before processing the insn.  */

static void
record_reg_life (insn, block, regstack)
     rtx insn;
     int block;
     stack regstack;
{
  rtx note, *note_link;
  int n_operands;

  if ((GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
      || INSN_DELETED_P (insn))
    return;

  /* Strip death notes for stack regs from this insn */

  note_link = &REG_NOTES(insn);
  for (note = *note_link; note; note = XEXP (note, 1))
    if (STACK_REG_P (XEXP (note, 0))
	&& (REG_NOTE_KIND (note) == REG_DEAD
	    || REG_NOTE_KIND (note) == REG_UNUSED))
      *note_link = XEXP (note, 1);
    else
      note_link = &XEXP (note, 1);

  /* Process all patterns in the insn.  */

  n_operands = asm_noperands (PATTERN (insn));
  if (n_operands >= 0)
    {
      /* This insn is an `asm' with operands.  Decode the operands,
	 decide how many are inputs, and record the life information.  */

      rtx operands[MAX_RECOG_OPERANDS];
      rtx body = PATTERN (insn);
      int n_inputs, n_outputs;
      char **constraints = (char **) alloca (n_operands * sizeof (char *));

      decode_asm_operands (body, operands, NULL_PTR, constraints, NULL_PTR);
      get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
      record_asm_reg_life (insn, regstack, operands, constraints,
			   n_inputs, n_outputs);
      return;
    }

    {
      HARD_REG_SET src, dest;
      int regno;

      CLEAR_HARD_REG_SET (src);
      CLEAR_HARD_REG_SET (dest);

      if (GET_CODE (insn) == CALL_INSN)
	 for (note = CALL_INSN_FUNCTION_USAGE (insn);
	      note;
	      note = XEXP (note, 1))
	   if (GET_CODE (XEXP (note, 0)) == USE)
	     record_reg_life_pat (SET_DEST (XEXP (note, 0)), &src, NULL_PTR, 0);

      record_reg_life_pat (PATTERN (insn), &src, &dest, 0);
      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
	if (! TEST_HARD_REG_BIT (regstack->reg_set, regno))
	  {
	    if (TEST_HARD_REG_BIT (src, regno)
		&& ! TEST_HARD_REG_BIT (dest, regno))
	      REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
					  FP_MODE_REG (regno, DFmode),
					  REG_NOTES (insn));
	    else if (TEST_HARD_REG_BIT (dest, regno))
	      REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED,
					  FP_MODE_REG (regno, DFmode),
					  REG_NOTES (insn));
	  }

      if (GET_CODE (insn) == CALL_INSN)
        {
	  int reg;

          /* There might be a reg that is live after a function call.
             Initialize it to zero so that the program does not crash.  See
	     comment towards the end of stack_reg_life_analysis().  */

          for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
	    if (! TEST_HARD_REG_BIT (dest, reg)
	        && TEST_HARD_REG_BIT (regstack->reg_set, reg))
	      {
	        rtx init, pat;

	        /* The insn will use virtual register numbers, and so
	           convert_regs is expected to process these.  But BLOCK_NUM
	           cannot be used on these insns, because they do not appear in
	           block_number[].  */

	        pat = gen_rtx (SET, VOIDmode, FP_MODE_REG (reg, DFmode),
			       CONST0_RTX (DFmode));
	        init = emit_insn_after (pat, insn);
	        PUT_MODE (init, QImode);

	        CLEAR_HARD_REG_BIT (regstack->reg_set, reg);

	        /* If the CALL_INSN was the end of a block, move the
	           block_end to point to the new insn.  */

	        if (block_end[block] == insn)
	          block_end[block] = init;
	      }

	  /* Some regs do not survive a CALL */
          AND_COMPL_HARD_REG_SET (regstack->reg_set, call_used_reg_set);
	}

      AND_COMPL_HARD_REG_SET (regstack->reg_set, dest);
      IOR_HARD_REG_SET (regstack->reg_set, src);
    }
}

/* Find all basic blocks of the function, which starts with FIRST.
   For each JUMP_INSN, build the chain of LABEL_REFS on each CODE_LABEL.  */

static void
find_blocks (first)
     rtx first;
{
  register rtx insn;
  register int block;
  register RTX_CODE prev_code = BARRIER;
  register RTX_CODE code;
  rtx label_value_list = 0;

  /* Record where all the blocks start and end.
     Record which basic blocks control can drop in to.  */

  block = -1;
  for (insn = first; insn; insn = NEXT_INSN (insn))
    {
      /* Note that this loop must select the same block boundaries
	 as code in reg_to_stack, but that these are not the same
	 as those selected in flow.c.  */

      code = GET_CODE (insn);

      if (code == CODE_LABEL
	  || (prev_code != INSN
	      && prev_code != CALL_INSN
	      && prev_code != CODE_LABEL
	      && GET_RTX_CLASS (code) == 'i'))
	{
	  block_begin[++block] = insn;
	  block_end[block] = insn;
	  block_drops_in[block] = prev_code != BARRIER;
	}
      else if (GET_RTX_CLASS (code) == 'i')
	block_end[block] = insn;

      if (GET_RTX_CLASS (code) == 'i')
	{
	  rtx note;

	  /* Make a list of all labels referred to other than by jumps.  */
	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
	    if (REG_NOTE_KIND (note) == REG_LABEL)
	      label_value_list = gen_rtx (EXPR_LIST, VOIDmode, XEXP (note, 0),
					  label_value_list);
	}

      block_number[INSN_UID (insn)] = block;

      if (code != NOTE)
	prev_code = code;
    }

  if (block + 1 != blocks)
    abort ();

  /* generate all label references to the corresponding jump insn */
  for (block = 0; block < blocks; block++)
    {
      insn = block_end[block];

      if (GET_CODE (insn) == JUMP_INSN)
	{
	  rtx pat = PATTERN (insn);
	  int computed_jump = 0;
	  rtx x;

	  if (GET_CODE (pat) == PARALLEL)
	    {
	      int len = XVECLEN (pat, 0);
	      int has_use_labelref = 0;
	      int i;

	      for (i = len - 1; i >= 0; i--)
		if (GET_CODE (XVECEXP (pat, 0, i)) == USE
		    && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF)
		  has_use_labelref = 1;

	      if (! has_use_labelref)
		for (i = len - 1; i >= 0; i--)
		  if (GET_CODE (XVECEXP (pat, 0, i)) == SET
		      && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
		      && uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
		    computed_jump = 1;
	    }
	  else if (GET_CODE (pat) == SET
		   && SET_DEST (pat) == pc_rtx
		   && uses_reg_or_mem (SET_SRC (pat)))
	    computed_jump = 1;
		    
	  if (computed_jump)
	    {
	      for (x = label_value_list; x; x = XEXP (x, 1))
		record_label_references (insn,
					 gen_rtx (LABEL_REF, VOIDmode,
						  XEXP (x, 0)));

	      for (x = forced_labels; x; x = XEXP (x, 1))
		record_label_references (insn,
					 gen_rtx (LABEL_REF, VOIDmode,
						  XEXP (x, 0)));
	    }

	  record_label_references (insn, pat);
	}
    }
}

/* Return 1 if X contain a REG or MEM that is not in the constant pool.  */

static int
uses_reg_or_mem (x)
     rtx x;
{
  enum rtx_code code = GET_CODE (x);
  int i, j;
  char *fmt;

  if (code == REG
      || (code == MEM
	  && ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
		&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))))
    return 1;

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e'
	  && uses_reg_or_mem (XEXP (x, i)))
	return 1;

      if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  if (uses_reg_or_mem (XVECEXP (x, i, j)))
	    return 1;
    }

  return 0;
}

/* If current function returns its result in an fp stack register,
   return the REG.  Otherwise, return 0.  */

static rtx
stack_result (decl)
     tree decl;
{
  rtx result = DECL_RTL (DECL_RESULT (decl));

  if (result != 0
      && ! (GET_CODE (result) == REG
	    && REGNO (result) < FIRST_PSEUDO_REGISTER))
    {
#ifdef FUNCTION_OUTGOING_VALUE
      result
        = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
#else
      result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
#endif
    }

  return result != 0 && STACK_REG_P (result) ? result : 0;
}

/* Determine the which registers are live at the start of each basic
   block of the function whose first insn is FIRST.

   First, if the function returns a real_type, mark the function
   return type as live at each return point, as the RTL may not give any
   hint that the register is live.

   Then, start with the last block and work back to the first block.
   Similarly, work backwards within each block, insn by insn, recording
   which regs are dead and which are used (and therefore live) in the
   hard reg set of block_stack_in[].

   After processing each basic block, if there is a label at the start
   of the block, propagate the live registers to all jumps to this block.

   As a special case, if there are regs live in this block, that are
   not live in a block containing a jump to this label, and the block
   containing the jump has already been processed, we must propagate this
   block's entry register life back to the block containing the jump, and
   restart life analysis from there.

   In the worst case, this function may traverse the insns
   REG_STACK_SIZE times.  This is necessary, since a jump towards the end
   of the insns may not know that a reg is live at a target that is early
   in the insns.  So we back up and start over with the new reg live.

   If there are registers that are live at the start of the function,
   insns are emitted to initialize these registers.  Something similar is
   done after CALL_INSNs in record_reg_life.  */

static void
stack_reg_life_analysis (first, stackentry)
     rtx first;
     HARD_REG_SET *stackentry;
{
  int reg, block;
  struct stack_def regstack;

   {
     rtx retvalue;

     if (retvalue = stack_result (current_function_decl))
      {
        /* Find all RETURN insns and mark them.  */

        for (block = blocks - 1; --block >= 0;)
	   if (GET_CODE (block_end[block]) == JUMP_INSN
	     && GET_CODE (PATTERN (block_end[block])) == RETURN)
	      mark_regs_pat (retvalue, block_out_reg_set+block);

        /* Mark off the end of last block if we "fall off" the end of the
	   function into the epilogue.  */

        if (GET_CODE (block_end[blocks-1]) != JUMP_INSN
	    || GET_CODE (PATTERN (block_end[blocks-1])) == RETURN)
	  mark_regs_pat (retvalue, block_out_reg_set+blocks-1);
      }
   }

  /* now scan all blocks backward for stack register use */

  block = blocks - 1;
  while (block >= 0)
    {
      register rtx insn, prev;

      /* current register status at last instruction */

      COPY_HARD_REG_SET (regstack.reg_set, block_out_reg_set[block]);

      prev = block_end[block];
      do
	{
	  insn = prev;
	  prev = PREV_INSN (insn);

	  /* If the insn is a CALL_INSN, we need to ensure that
	     everything dies.  But otherwise don't process unless there
	     are some stack regs present.  */

	  if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
	    record_reg_life (insn, block, &regstack);

	} while (insn != block_begin[block]);

      /* Set the state at the start of the block.  Mark that no
	 register mapping information known yet.  */

      COPY_HARD_REG_SET (block_stack_in[block].reg_set, regstack.reg_set);
      block_stack_in[block].top = -2;

      /* If there is a label, propagate our register life to all jumps
	 to this label.  */

      if (GET_CODE (insn) == CODE_LABEL)
	{
	  register rtx label;
	  int must_restart = 0;

	  for (label = LABEL_REFS (insn); label != insn;
	       label = LABEL_NEXTREF (label))
	    {
	      int jump_block = BLOCK_NUM (CONTAINING_INSN (label));

	      if (jump_block < block)
		IOR_HARD_REG_SET (block_out_reg_set[jump_block],
				  block_stack_in[block].reg_set);
	      else
		{
		  /* The block containing the jump has already been
		     processed.  If there are registers that were not known
		     to be live then, but are live now, we must back up
		     and restart life analysis from that point with the new
		     life information.  */

		  GO_IF_HARD_REG_SUBSET (block_stack_in[block].reg_set,
					 block_out_reg_set[jump_block],
					 win);

		  IOR_HARD_REG_SET (block_out_reg_set[jump_block],
				    block_stack_in[block].reg_set);

		  block = jump_block;
		  must_restart = 1;

		win:
		  ;
		}
	    }
	  if (must_restart)
	    continue;
	}

      if (block_drops_in[block])
	IOR_HARD_REG_SET (block_out_reg_set[block-1],
			  block_stack_in[block].reg_set);

      block -= 1;
    }

    /* If any reg is live at the start of the first block of a
       function, then we must guarantee that the reg holds some value by
       generating our own "load" of that register.  Otherwise a 387 would
       fault trying to access an empty register.  */

  /* Load zero into each live register.  The fact that a register
     appears live at the function start necessarily implies an error
     in the user program: it means that (unless the offending code is *never*
     executed) this program is using uninitialised floating point
     variables.  In order to keep broken code like this happy, we initialise
     those variables with zero.

     Note that we are inserting virtual register references here:
     these insns must be processed by convert_regs later.  Also, these
     insns will not be in block_number, so BLOCK_NUM() will fail for them.  */

  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
    if (TEST_HARD_REG_BIT (block_stack_in[0].reg_set, reg)
        && ! TEST_HARD_REG_BIT (*stackentry, reg))
      {
	rtx init_rtx;

	init_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG(reg, DFmode),
			    CONST0_RTX (DFmode));
	block_begin[0] = emit_insn_after (init_rtx, first);
	PUT_MODE (block_begin[0], QImode);

	CLEAR_HARD_REG_BIT (block_stack_in[0].reg_set, reg);
      }
}

/*****************************************************************************
   This section deals with stack register substitution, and forms the second
   pass over the RTL.
 *****************************************************************************/

/* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
   the desired hard REGNO.  */

static void
replace_reg (reg, regno)
     rtx *reg;
     int regno;
{
  if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG
      || ! STACK_REG_P (*reg))
    abort ();

  switch (GET_MODE_CLASS (GET_MODE (*reg)))
   {
     default: abort ();
     case MODE_FLOAT:
     case MODE_COMPLEX_FLOAT:;
   }

  *reg = FP_MODE_REG (regno, GET_MODE (*reg));
}

/* Remove a note of type NOTE, which must be found, for register
   number REGNO from INSN.  Remove only one such note.  */

static void
remove_regno_note (insn, note, regno)
     rtx insn;
     enum reg_note note;
     int regno;
{
  register rtx *note_link, this;

  note_link = &REG_NOTES(insn);
  for (this = *note_link; this; this = XEXP (this, 1))
    if (REG_NOTE_KIND (this) == note
	&& REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
      {
	*note_link = XEXP (this, 1);
	return;
      }
    else
      note_link = &XEXP (this, 1);

  abort ();
}

/* Find the hard register number of virtual register REG in REGSTACK.
   The hard register number is relative to the top of the stack.  -1 is
   returned if the register is not found.  */

static int
get_hard_regnum (regstack, reg)
     stack regstack;
     rtx reg;
{
  int i;

  if (! STACK_REG_P (reg))
    abort ();

  for (i = regstack->top; i >= 0; i--)
    if (regstack->reg[i] == REGNO (reg))
      break;

  return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
}

/* Delete INSN from the RTL.  Mark the insn, but don't remove it from
   the chain of insns.  Doing so could confuse block_begin and block_end
   if this were the only insn in the block.  */

static void
delete_insn_for_stacker (insn)
     rtx insn;
{
  PUT_CODE (insn, NOTE);
  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  NOTE_SOURCE_FILE (insn) = 0;
}

/* Emit an insn to pop virtual register REG before or after INSN.
   REGSTACK is the stack state after INSN and is updated to reflect this
   pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
   is represented as a SET whose destination is the register to be popped
   and source is the top of stack.  A death note for the top of stack
   cases the movdf pattern to pop.  */

static rtx
emit_pop_insn (insn, regstack, reg, when)
     rtx insn;
     stack regstack;
     rtx reg;
     rtx (*when)();
{
  rtx pop_insn, pop_rtx;
  int hard_regno;

  hard_regno = get_hard_regnum (regstack, reg);

  if (hard_regno < FIRST_STACK_REG)
    abort ();

  pop_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG (hard_regno, DFmode),
		     FP_MODE_REG (FIRST_STACK_REG, DFmode));

  pop_insn = (*when) (pop_rtx, insn);
  /* ??? This used to be VOIDmode, but that seems wrong.  */
  PUT_MODE (pop_insn, QImode);

  REG_NOTES (pop_insn) = gen_rtx (EXPR_LIST, REG_DEAD,
				  FP_MODE_REG (FIRST_STACK_REG, DFmode),
				  REG_NOTES (pop_insn));

  regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
    = regstack->reg[regstack->top];
  regstack->top -= 1;
  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));

  return pop_insn;
}

/* Emit an insn before or after INSN to swap virtual register REG with the
   top of stack.  WHEN should be `emit_insn_before' or `emit_insn_before'
   REGSTACK is the stack state before the swap, and is updated to reflect
   the swap.  A swap insn is represented as a PARALLEL of two patterns:
   each pattern moves one reg to the other.

   If REG is already at the top of the stack, no insn is emitted.  */

static void
emit_swap_insn (insn, regstack, reg)
     rtx insn;
     stack regstack;
     rtx reg;
{
  int hard_regno;
  rtx gen_swapdf();
  rtx swap_rtx, swap_insn;
  int tmp, other_reg;		/* swap regno temps */
  rtx i1;			/* the stack-reg insn prior to INSN */
  rtx i1set = NULL_RTX;		/* the SET rtx within I1 */

  hard_regno = get_hard_regnum (regstack, reg);

  if (hard_regno < FIRST_STACK_REG)
    abort ();
  if (hard_regno == FIRST_STACK_REG)
    return;

  other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);

  tmp = regstack->reg[other_reg];
  regstack->reg[other_reg] = regstack->reg[regstack->top];
  regstack->reg[regstack->top] = tmp;

  /* Find the previous insn involving stack regs, but don't go past
     any labels, calls or jumps.  */
  i1 = prev_nonnote_insn (insn);
  while (i1 && GET_CODE (i1) == INSN && GET_MODE (i1) != QImode)
    i1 = prev_nonnote_insn (i1);

  if (i1)
    i1set = single_set (i1);

  if (i1set)
    {
      rtx i2;			/* the stack-reg insn prior to I1 */
      rtx i1src = *get_true_reg (&SET_SRC (i1set));
      rtx i1dest = *get_true_reg (&SET_DEST (i1set));

      /* If the previous register stack push was from the reg we are to
	 swap with, omit the swap.  */

      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG
	  && GET_CODE (i1src) == REG && REGNO (i1src) == hard_regno - 1
	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
	return;

      /* If the previous insn wrote to the reg we are to swap with,
	 omit the swap.  */

      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == hard_regno
	  && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG
	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
	return;
    }

  if (GET_RTX_CLASS (GET_CODE (i1)) == 'i' && sets_cc0_p (PATTERN (i1)))
    {
      i1 = next_nonnote_insn (i1);
      if (i1 == insn)
	abort ();
    }

  swap_rtx = gen_swapdf (FP_MODE_REG (hard_regno, DFmode),
			 FP_MODE_REG (FIRST_STACK_REG, DFmode));
  swap_insn = emit_insn_after (swap_rtx, i1);
  /* ??? This used to be VOIDmode, but that seems wrong.  */
  PUT_MODE (swap_insn, QImode);
}

/* Handle a move to or from a stack register in PAT, which is in INSN.
   REGSTACK is the current stack.  */

static void
move_for_stack_reg (insn, regstack, pat)
     rtx insn;
     stack regstack;
     rtx pat;
{
  rtx *psrc =  get_true_reg (&SET_SRC (pat));
  rtx *pdest = get_true_reg (&SET_DEST (pat));
  rtx src, dest;
  rtx note;

  src = *psrc; dest = *pdest;

  if (STACK_REG_P (src) && STACK_REG_P (dest))
    {
      /* Write from one stack reg to another.  If SRC dies here, then
	 just change the register mapping and delete the insn.  */

      note = find_regno_note (insn, REG_DEAD, REGNO (src));
      if (note)
	{
	  int i;

	  /* If this is a no-op move, there must not be a REG_DEAD note.  */
	  if (REGNO (src) == REGNO (dest))
	    abort ();

	  for (i = regstack->top; i >= 0; i--)
	    if (regstack->reg[i] == REGNO (src))
	      break;

	  /* The source must be live, and the dest must be dead.  */
	  if (i < 0 || get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
	    abort ();

	  /* It is possible that the dest is unused after this insn.
	     If so, just pop the src.  */

	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
	    {
	      emit_pop_insn (insn, regstack, src, emit_insn_after);

	      delete_insn_for_stacker (insn);
	      return;
	    }

	  regstack->reg[i] = REGNO (dest);

	  SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));

	  delete_insn_for_stacker (insn);

	  return;
	}

      /* The source reg does not die.  */

      /* If this appears to be a no-op move, delete it, or else it
	 will confuse the machine description output patterns. But if
	 it is REG_UNUSED, we must pop the reg now, as per-insn processing
	 for REG_UNUSED will not work for deleted insns.  */

      if (REGNO (src) == REGNO (dest))
	{
	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
	    emit_pop_insn (insn, regstack, dest, emit_insn_after);

	  delete_insn_for_stacker (insn);
	  return;
	}

      /* The destination ought to be dead */
      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
	abort ();

      replace_reg (psrc, get_hard_regnum (regstack, src));

      regstack->reg[++regstack->top] = REGNO (dest);
      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
      replace_reg (pdest, FIRST_STACK_REG);
    }
  else if (STACK_REG_P (src))
    {
      /* Save from a stack reg to MEM, or possibly integer reg.  Since
	 only top of stack may be saved, emit an exchange first if
	 needs be.  */

      emit_swap_insn (insn, regstack, src);

      note = find_regno_note (insn, REG_DEAD, REGNO (src));
      if (note)
	{
	  replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
	  regstack->top--;
	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
	}
      else if (GET_MODE (src) == XFmode && regstack->top < REG_STACK_SIZE - 1)
	{
	  /* A 387 cannot write an XFmode value to a MEM without
	     clobbering the source reg.  The output code can handle
	     this by reading back the value from the MEM.
	     But it is more efficient to use a temp register if one is
	     available.  Push the source value here if the register
	     stack is not full, and then write the value to memory via
	     a pop.  */
	  rtx push_rtx, push_insn;
	  rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, XFmode);

	  push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
	  push_insn = emit_insn_before (push_rtx, insn);
	  PUT_MODE (push_insn, QImode);
	  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, top_stack_reg,
				      REG_NOTES (insn));
	}

      replace_reg (psrc, FIRST_STACK_REG);
    }
  else if (STACK_REG_P (dest))
    {
      /* Load from MEM, or possibly integer REG or constant, into the
	 stack regs.  The actual target is always the top of the
	 stack. The stack mapping is changed to reflect that DEST is
	 now at top of stack.  */

      /* The destination ought to be dead */
      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
	abort ();

      if (regstack->top >= REG_STACK_SIZE)
	abort ();

      regstack->reg[++regstack->top] = REGNO (dest);
      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
      replace_reg (pdest, FIRST_STACK_REG);
    }
  else
    abort ();
}

static void
swap_rtx_condition (pat)
     rtx pat;
{
  register char *fmt;
  register int i;

  if (GET_RTX_CLASS (GET_CODE (pat)) == '<')
    {
      PUT_CODE (pat, swap_condition (GET_CODE (pat)));
      return;
    }

  fmt = GET_RTX_FORMAT (GET_CODE (pat));
  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'E')
	{
	  register int j;

	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
	    swap_rtx_condition (XVECEXP (pat, i, j));
	}
      else if (fmt[i] == 'e')
	swap_rtx_condition (XEXP (pat, i));
    }
}

/* Handle a comparison.  Special care needs to be taken to avoid
   causing comparisons that a 387 cannot do correctly, such as EQ.

   Also, a pop insn may need to be emitted.  The 387 does have an
   `fcompp' insn that can pop two regs, but it is sometimes too expensive
   to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
   set up.  */

static void
compare_for_stack_reg (insn, regstack, pat)
     rtx insn;
     stack regstack;
     rtx pat;
{
  rtx *src1, *src2;
  rtx src1_note, src2_note;
  rtx cc0_user;

  src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
  src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
  cc0_user = next_cc0_user (insn);

  /* If the insn that uses cc0 is a conditional move, then the destination
     must be the top of stack */
  if (GET_CODE (PATTERN (cc0_user)) == SET
      && SET_DEST (PATTERN (cc0_user)) != pc_rtx
      && GET_CODE (SET_SRC (PATTERN (cc0_user))) == IF_THEN_ELSE)
    {
      rtx *dest, src_note;
      
      dest = get_true_reg (&SET_DEST (PATTERN (cc0_user)));
      if (REGNO (*dest) != regstack->reg[regstack->top])
	{
	  emit_swap_insn (insn, regstack, *dest);	
	}
    }

  /* ??? If fxch turns out to be cheaper than fstp, give priority to
     registers that die in this insn - move those to stack top first.  */
  if (! STACK_REG_P (*src1)
      || (STACK_REG_P (*src2)
	  && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
    {
      rtx temp, next;

      temp = XEXP (SET_SRC (pat), 0);
      XEXP (SET_SRC (pat), 0) = XEXP (SET_SRC (pat), 1);
      XEXP (SET_SRC (pat), 1) = temp;

      src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
      src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));

      next = next_cc0_user (insn);
      if (next == NULL_RTX)
	abort ();

      swap_rtx_condition (PATTERN (next));
      INSN_CODE (next) = -1;
      INSN_CODE (insn) = -1;
    }

  /* We will fix any death note later.  */

  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));

  if (STACK_REG_P (*src2))
    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
  else
    src2_note = NULL_RTX;

  emit_swap_insn (insn, regstack, *src1);

  replace_reg (src1, FIRST_STACK_REG);

  if (STACK_REG_P (*src2))
    replace_reg (src2, get_hard_regnum (regstack, *src2));

  if (src1_note)
    {
      CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src1_note, 0)));
      replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
      regstack->top--;
    }

  /* If the second operand dies, handle that.  But if the operands are
     the same stack register, don't bother, because only one death is
     needed, and it was just handled.  */

  if (src2_note
      && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
	    && REGNO (*src1) == REGNO (*src2)))
    {
      /* As a special case, two regs may die in this insn if src2 is
	 next to top of stack and the top of stack also dies.  Since
	 we have already popped src1, "next to top of stack" is really
	 at top (FIRST_STACK_REG) now.  */

      if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
	  && src1_note)
	{
	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src2_note, 0)));
	  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
	  regstack->top--;
	}
      else
	{
	  /* The 386 can only represent death of the first operand in
	     the case handled above.  In all other cases, emit a separate
	     pop and remove the death note from here.  */

	  link_cc0_insns (insn);

	  remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));

	  emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
			 emit_insn_after);
	}
    }
}

/* Substitute new registers in PAT, which is part of INSN.  REGSTACK
   is the current register layout.  */

static void
subst_stack_regs_pat (insn, regstack, pat)
     rtx insn;
     stack regstack;
     rtx pat;
{
  rtx *dest, *src;
  rtx *src1 = (rtx *) NULL_PTR, *src2;
  rtx src1_note, src2_note;

  if (GET_CODE (pat) != SET)
    return;

  dest = get_true_reg (&SET_DEST (pat));
  src  = get_true_reg (&SET_SRC (pat));

  /* See if this is a `movM' pattern, and handle elsewhere if so.  */

  if (*dest != cc0_rtx
      && (STACK_REG_P (*src)
	  || (STACK_REG_P (*dest)
	      && (GET_CODE (*src) == REG || GET_CODE (*src) == MEM
		  || GET_CODE (*src) == CONST_DOUBLE))))
    move_for_stack_reg (insn, regstack, pat);
  else
    switch (GET_CODE (SET_SRC (pat)))
      {
      case COMPARE:
	compare_for_stack_reg (insn, regstack, pat);
	break;

      case CALL:
	 {
	   int count;
	   for (count = HARD_REGNO_NREGS (REGNO (*dest), GET_MODE (*dest));
              --count >= 0;)
	    {
	      regstack->reg[++regstack->top] = REGNO (*dest) + count;
	      SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count);
	    }
	 }
	replace_reg (dest, FIRST_STACK_REG);
	break;

      case REG:
	/* This is a `tstM2' case.  */
	if (*dest != cc0_rtx)
	  abort ();

	src1 = src;

	/* Fall through.  */

      case FLOAT_TRUNCATE:
      case SQRT:
      case ABS:
      case NEG:
	/* These insns only operate on the top of the stack. DEST might
	   be cc0_rtx if we're processing a tstM pattern. Also, it's
	   possible that the tstM case results in a REG_DEAD note on the
	   source.  */

	if (src1 == 0)
	  src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));

	emit_swap_insn (insn, regstack, *src1);

	src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));

	if (STACK_REG_P (*dest))
	  replace_reg (dest, FIRST_STACK_REG);

	if (src1_note)
	  {
	    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
	    regstack->top--;
	    CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
	  }

	replace_reg (src1, FIRST_STACK_REG);

	break;

      case MINUS:
      case DIV:
	/* On i386, reversed forms of subM3 and divM3 exist for
	   MODE_FLOAT, so the same code that works for addM3 and mulM3
	   can be used.  */
      case MULT:
      case PLUS:
	/* These insns can accept the top of stack as a destination
	   from a stack reg or mem, or can use the top of stack as a
	   source and some other stack register (possibly top of stack)
	   as a destination.  */

	src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
	src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));

	/* We will fix any death note later.  */

	if (STACK_REG_P (*src1))
	  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
	else
	  src1_note = NULL_RTX;
	if (STACK_REG_P (*src2))
	  src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
	else
	  src2_note = NULL_RTX;

	/* If either operand is not a stack register, then the dest
	   must be top of stack.  */

	if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
	  emit_swap_insn (insn, regstack, *dest);
	else
	  {
	    /* Both operands are REG.  If neither operand is already
	       at the top of stack, choose to make the one that is the dest
	       the new top of stack.  */

	    int src1_hard_regnum, src2_hard_regnum;

	    src1_hard_regnum = get_hard_regnum (regstack, *src1);
	    src2_hard_regnum = get_hard_regnum (regstack, *src2);
	    if (src1_hard_regnum == -1 || src2_hard_regnum == -1)
	      abort ();

	    if (src1_hard_regnum != FIRST_STACK_REG
		&& src2_hard_regnum != FIRST_STACK_REG)
	      emit_swap_insn (insn, regstack, *dest);
	  }

	if (STACK_REG_P (*src1))
	  replace_reg (src1, get_hard_regnum (regstack, *src1));
	if (STACK_REG_P (*src2))
	  replace_reg (src2, get_hard_regnum (regstack, *src2));

	if (src1_note)
	  {
	    /* If the register that dies is at the top of stack, then
	       the destination is somewhere else - merely substitute it.
	       But if the reg that dies is not at top of stack, then
	       move the top of stack to the dead reg, as though we had
	       done the insn and then a store-with-pop.  */

	    if (REGNO (XEXP (src1_note, 0)) == regstack->reg[regstack->top])
	      {
		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
		replace_reg (dest, get_hard_regnum (regstack, *dest));
	      }
	    else
	      {
		int regno = get_hard_regnum (regstack, XEXP (src1_note, 0));

		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
		replace_reg (dest, regno);

		regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
		  = regstack->reg[regstack->top];
	      }

	    CLEAR_HARD_REG_BIT (regstack->reg_set,
				REGNO (XEXP (src1_note, 0)));
	    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
	    regstack->top--;
	  }
	else if (src2_note)
	  {
	    if (REGNO (XEXP (src2_note, 0)) == regstack->reg[regstack->top])
	      {
		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
		replace_reg (dest, get_hard_regnum (regstack, *dest));
	      }
	    else
	      {
		int regno = get_hard_regnum (regstack, XEXP (src2_note, 0));

		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
		replace_reg (dest, regno);

		regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
		  = regstack->reg[regstack->top];
	      }

	    CLEAR_HARD_REG_BIT (regstack->reg_set,
				REGNO (XEXP (src2_note, 0)));
	    replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
	    regstack->top--;
	  }
	else
	  {
	    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
	    replace_reg (dest, get_hard_regnum (regstack, *dest));
	  }

	break;

      case UNSPEC:
	switch (XINT (SET_SRC (pat), 1))
	  {
	  case 1: /* sin */
	  case 2: /* cos */
	    /* These insns only operate on the top of the stack.  */

	    src1 = get_true_reg (&XVECEXP (SET_SRC (pat), 0, 0));

	    emit_swap_insn (insn, regstack, *src1);

	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));

	    if (STACK_REG_P (*dest))
	      replace_reg (dest, FIRST_STACK_REG);

	    if (src1_note)
	      {
		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
		regstack->top--;
		CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
	      }

	    replace_reg (src1, FIRST_STACK_REG);

	    break;

	  default:
	    abort ();
	  }
	break;

      case IF_THEN_ELSE:
	/* This insn requires the top of stack to be the destination. */

	src1 = get_true_reg (&XEXP (SET_SRC (pat), 1));
	src2 = get_true_reg (&XEXP (SET_SRC (pat), 2));

	src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
	src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));

	{
	  rtx src_note [3];
	  int i;

	  src_note[0] = 0;
	  src_note[1] = src1_note;
	  src_note[2] = src2_note;

	  if (STACK_REG_P (*src1))
	    replace_reg (src1, get_hard_regnum (regstack, *src1));
	  if (STACK_REG_P (*src2))
	    replace_reg (src2, get_hard_regnum (regstack, *src2));

	  for (i = 1; i <= 2; i++)
	    if (src_note [i])
	      {
		int regno = get_hard_regnum (regstack, XEXP (src_note [i], 0));

		/* If the register that dies is not at the top of stack, then
		   move the top of stack to the dead reg */
		if (REGNO (XEXP (src_note[i], 0))
		    != regstack->reg[regstack->top])
		  {
		    remove_regno_note (insn, REG_DEAD,
				       REGNO (XEXP (src_note [i], 0)));
		    emit_pop_insn (insn, regstack, XEXP (src_note[i], 0),
				   emit_insn_after);
		  }
		else
		  {
		    CLEAR_HARD_REG_BIT (regstack->reg_set,
					REGNO (XEXP (src_note[i], 0)));
		    replace_reg (&XEXP (src_note[i], 0), FIRST_STACK_REG);
		    regstack->top--;
		  }
		
	      }

	  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
	  replace_reg (dest, FIRST_STACK_REG);
	}

	break;

      default:
	abort ();
      }
}

/* Substitute hard regnums for any stack regs in INSN, which has
   N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
   before the insn, and is updated with changes made here.  CONSTRAINTS is
   an array of the constraint strings used in the asm statement.

   OPERANDS is an array of the operands, and OPERANDS_LOC is a
   parallel array of where the operands were found.  The output operands
   all precede the input operands.

   There are several requirements and assumptions about the use of
   stack-like regs in asm statements.  These rules are enforced by
   record_asm_stack_regs; see comments there for details.  Any
   asm_operands left in the RTL at this point may be assume to meet the
   requirements, since record_asm_stack_regs removes any problem asm.  */

static void
subst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
		      n_inputs, n_outputs)
     rtx insn;
     stack regstack;
     rtx *operands, **operands_loc;
     char **constraints;
     int n_inputs, n_outputs;
{
  int n_operands = n_inputs + n_outputs;
  int first_input = n_outputs;
  rtx body = PATTERN (insn);

  int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
  enum reg_class *operand_class 
    = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));

  rtx *note_reg;		/* Array of note contents */
  rtx **note_loc;		/* Address of REG field of each note */
  enum reg_note *note_kind;	/* The type of each note */

  rtx *clobber_reg;
  rtx **clobber_loc;

  struct stack_def temp_stack;
  int n_notes;
  int n_clobbers;
  rtx note;
  int i;

  /* Find out what the constraints required.  If no constraint
     alternative matches, that is a compiler bug: we should have caught
     such an insn during the life analysis pass (and reload should have
     caught it regardless).  */

  i = constrain_asm_operands (n_operands, operands, constraints,
			      operand_matches, operand_class);
  if (i < 0)
    abort ();

  /* Strip SUBREGs here to make the following code simpler.  */
  for (i = 0; i < n_operands; i++)
    if (GET_CODE (operands[i]) == SUBREG
	&& GET_CODE (SUBREG_REG (operands[i])) == REG)
      {
	operands_loc[i] = & SUBREG_REG (operands[i]);
	operands[i] = SUBREG_REG (operands[i]);
      }

  /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND.  */

  for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
    i++;

  note_reg = (rtx *) alloca (i * sizeof (rtx));
  note_loc = (rtx **) alloca (i * sizeof (rtx *));
  note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note));

  n_notes = 0;
  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    {
      rtx reg = XEXP (note, 0);
      rtx *loc = & XEXP (note, 0);

      if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
	{
	  loc = & SUBREG_REG (reg);
	  reg = SUBREG_REG (reg);
	}

      if (STACK_REG_P (reg)
	  && (REG_NOTE_KIND (note) == REG_DEAD
	      || REG_NOTE_KIND (note) == REG_UNUSED))
	{
	  note_reg[n_notes] = reg;
	  note_loc[n_notes] = loc;
	  note_kind[n_notes] = REG_NOTE_KIND (note);
	  n_notes++;
	}
    }

  /* Set up CLOBBER_REG and CLOBBER_LOC.  */

  n_clobbers = 0;

  if (GET_CODE (body) == PARALLEL)
    {
      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
      clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx **));

      for (i = 0; i < XVECLEN (body, 0); i++)
	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
	  {
	    rtx clobber = XVECEXP (body, 0, i);
	    rtx reg = XEXP (clobber, 0);
	    rtx *loc = & XEXP (clobber, 0);

	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
	      {
		loc = & SUBREG_REG (reg);
		reg = SUBREG_REG (reg);
	      }

	    if (STACK_REG_P (reg))
	      {
		clobber_reg[n_clobbers] = reg;
		clobber_loc[n_clobbers] = loc;
		n_clobbers++;
	      }
	  }
    }

  bcopy ((char *) regstack, (char *) &temp_stack, sizeof (temp_stack));

  /* Put the input regs into the desired place in TEMP_STACK.  */

  for (i = first_input; i < first_input + n_inputs; i++)
    if (STACK_REG_P (operands[i])
	&& reg_class_subset_p (operand_class[i], FLOAT_REGS)
	&& operand_class[i] != FLOAT_REGS)
      {
	/* If an operand needs to be in a particular reg in
	   FLOAT_REGS, the constraint was either 't' or 'u'.  Since
	   these constraints are for single register classes, and reload
	   guaranteed that operand[i] is already in that class, we can
	   just use REGNO (operands[i]) to know which actual reg this
	   operand needs to be in.  */

	int regno = get_hard_regnum (&temp_stack, operands[i]);

	if (regno < 0)
	  abort ();

	if (regno != REGNO (operands[i]))
	  {
	    /* operands[i] is not in the right place.  Find it
	       and swap it with whatever is already in I's place.
	       K is where operands[i] is now.  J is where it should
	       be.  */
	    int j, k, temp;

	    k = temp_stack.top - (regno - FIRST_STACK_REG);
	    j = (temp_stack.top
		 - (REGNO (operands[i]) - FIRST_STACK_REG));

	    temp = temp_stack.reg[k];
	    temp_stack.reg[k] = temp_stack.reg[j];
	    temp_stack.reg[j] = temp;
	  }
      }

  /* emit insns before INSN to make sure the reg-stack is in the right
     order.  */

  change_stack (insn, regstack, &temp_stack, emit_insn_before);

  /* Make the needed input register substitutions.  Do death notes and
     clobbers too, because these are for inputs, not outputs.  */

  for (i = first_input; i < first_input + n_inputs; i++)
    if (STACK_REG_P (operands[i]))
      {
	int regnum = get_hard_regnum (regstack, operands[i]);

	if (regnum < 0)
	  abort ();

	replace_reg (operands_loc[i], regnum);
      }

  for (i = 0; i < n_notes; i++)
    if (note_kind[i] == REG_DEAD)
      {
	int regnum = get_hard_regnum (regstack, note_reg[i]);

	if (regnum < 0)
	  abort ();

	replace_reg (note_loc[i], regnum);
      }

  for (i = 0; i < n_clobbers; i++)
    {
      /* It's OK for a CLOBBER to reference a reg that is not live.
         Don't try to replace it in that case.  */
      int regnum = get_hard_regnum (regstack, clobber_reg[i]);

      if (regnum >= 0)
	{
	  /* Sigh - clobbers always have QImode.  But replace_reg knows
	     that these regs can't be MODE_INT and will abort.  Just put
	     the right reg there without calling replace_reg.  */

	  *clobber_loc[i] = FP_MODE_REG (regnum, DFmode);
	}
    }

  /* Now remove from REGSTACK any inputs that the asm implicitly popped.  */

  for (i = first_input; i < first_input + n_inputs; i++)
    if (STACK_REG_P (operands[i]))
      {
	/* An input reg is implicitly popped if it is tied to an
	   output, or if there is a CLOBBER for it.  */
	int j;

	for (j = 0; j < n_clobbers; j++)
	  if (operands_match_p (clobber_reg[j], operands[i]))
	    break;

	if (j < n_clobbers || operand_matches[i] >= 0)
	  {
	    /* operands[i] might not be at the top of stack.  But that's OK,
	       because all we need to do is pop the right number of regs
	       off of the top of the reg-stack.  record_asm_stack_regs
	       guaranteed that all implicitly popped regs were grouped
	       at the top of the reg-stack.  */

	    CLEAR_HARD_REG_BIT (regstack->reg_set,
				regstack->reg[regstack->top]);
	    regstack->top--;
	  }
      }

  /* Now add to REGSTACK any outputs that the asm implicitly pushed.
     Note that there isn't any need to substitute register numbers.
     ???  Explain why this is true.  */

  for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
    {
      /* See if there is an output for this hard reg.  */
      int j;

      for (j = 0; j < n_outputs; j++)
	if (STACK_REG_P (operands[j]) && REGNO (operands[j]) == i)
	  {
	    regstack->reg[++regstack->top] = i;
	    SET_HARD_REG_BIT (regstack->reg_set, i);
	    break;
	  }
    }

  /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
     input that the asm didn't implicitly pop.  If the asm didn't
     implicitly pop an input reg, that reg will still be live.

     Note that we can't use find_regno_note here: the register numbers
     in the death notes have already been substituted.  */

  for (i = 0; i < n_outputs; i++)
    if (STACK_REG_P (operands[i]))
      {
	int j;

	for (j = 0; j < n_notes; j++)
	  if (REGNO (operands[i]) == REGNO (note_reg[j])
	      && note_kind[j] == REG_UNUSED)
	    {
	      insn = emit_pop_insn (insn, regstack, operands[i],
				    emit_insn_after);
	      break;
	    }
      }

  for (i = first_input; i < first_input + n_inputs; i++)
    if (STACK_REG_P (operands[i]))
      {
	int j;

	for (j = 0; j < n_notes; j++)
	  if (REGNO (operands[i]) == REGNO (note_reg[j])
	      && note_kind[j] == REG_DEAD
	      && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])))
	    {
	      insn = emit_pop_insn (insn, regstack, operands[i],
				    emit_insn_after);
	      break;
	    }
      }
}

/* Substitute stack hard reg numbers for stack virtual registers in
   INSN.  Non-stack register numbers are not changed.  REGSTACK is the
   current stack content.  Insns may be emitted as needed to arrange the
   stack for the 387 based on the contents of the insn.  */

static void
subst_stack_regs (insn, regstack)
     rtx insn;
     stack regstack;
{
  register rtx *note_link, note;
  register int i;
  int n_operands;

  if (GET_CODE (insn) == CALL_INSN)
   {
     int top = regstack->top;

     /* If there are any floating point parameters to be passed in
	registers for this call, make sure they are in the right
	order.  */

     if (top >= 0)
      {
	straighten_stack (PREV_INSN (insn), regstack);

	/* Now mark the arguments as dead after the call.  */

        while (regstack->top >= 0)
         {
           CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top);
	   regstack->top--;
         }
      }
   }

  /* Do the actual substitution if any stack regs are mentioned.
     Since we only record whether entire insn mentions stack regs, and
     subst_stack_regs_pat only works for patterns that contain stack regs,
     we must check each pattern in a parallel here.  A call_value_pop could
     fail otherwise.  */

  if (GET_MODE (insn) == QImode)
    {
      n_operands = asm_noperands (PATTERN (insn));
      if (n_operands >= 0)
	{
	  /* This insn is an `asm' with operands.  Decode the operands,
	     decide how many are inputs, and do register substitution.
	     Any REG_UNUSED notes will be handled by subst_asm_stack_regs.  */

	  rtx operands[MAX_RECOG_OPERANDS];
	  rtx *operands_loc[MAX_RECOG_OPERANDS];
	  rtx body = PATTERN (insn);
	  int n_inputs, n_outputs;
	  char **constraints
	    = (char **) alloca (n_operands * sizeof (char *));

	  decode_asm_operands (body, operands, operands_loc,
			       constraints, NULL_PTR);
	  get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
	  subst_asm_stack_regs (insn, regstack, operands, operands_loc,
				constraints, n_inputs, n_outputs);
	  return;
	}

      if (GET_CODE (PATTERN (insn)) == PARALLEL)
	for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
	  {
	    if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
	      subst_stack_regs_pat (insn, regstack,
				    XVECEXP (PATTERN (insn), 0, i));
	  }
      else
	subst_stack_regs_pat (insn, regstack, PATTERN (insn));
    }

  /* subst_stack_regs_pat may have deleted a no-op insn.  If so, any
     REG_UNUSED will already have been dealt with, so just return.  */

  if (GET_CODE (insn) == NOTE)
    return;

  /* If there is a REG_UNUSED note on a stack register on this insn,
     the indicated reg must be popped.  The REG_UNUSED note is removed,
     since the form of the newly emitted pop insn references the reg,
     making it no longer `unset'.  */

  note_link = &REG_NOTES(insn);
  for (note = *note_link; note; note = XEXP (note, 1))
    if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
      {
	*note_link = XEXP (note, 1);
	insn = emit_pop_insn (insn, regstack, XEXP (note, 0), emit_insn_after);
      }
    else
      note_link = &XEXP (note, 1);
}

/* Change the organization of the stack so that it fits a new basic
   block.  Some registers might have to be popped, but there can never be
   a register live in the new block that is not now live.

   Insert any needed insns before or after INSN.  WHEN is emit_insn_before
   or emit_insn_after. OLD is the original stack layout, and NEW is
   the desired form.  OLD is updated to reflect the code emitted, ie, it
   will be the same as NEW upon return.

   This function will not preserve block_end[].  But that information
   is no longer needed once this has executed.  */

static void
change_stack (insn, old, new, when)
     rtx insn;
     stack old;
     stack new;
     rtx (*when)();
{
  int reg;

  /* We will be inserting new insns "backwards", by calling emit_insn_before.
     If we are to insert after INSN, find the next insn, and insert before
     it.  */

  if (when == emit_insn_after)
    insn = NEXT_INSN (insn);

  /* Pop any registers that are not needed in the new block.  */

  for (reg = old->top; reg >= 0; reg--)
    if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
      emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
		     emit_insn_before);

  if (new->top == -2)
    {
      /* If the new block has never been processed, then it can inherit
	 the old stack order.  */

      new->top = old->top;
      bcopy (old->reg, new->reg, sizeof (new->reg));
    }
  else
    {
      /* This block has been entered before, and we must match the
	 previously selected stack order.  */

      /* By now, the only difference should be the order of the stack,
	 not their depth or liveliness.  */

      GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win);

      abort ();

    win:

      if (old->top != new->top)
	abort ();

      /* Loop here emitting swaps until the stack is correct.  The
	 worst case number of swaps emitted is N + 2, where N is the
	 depth of the stack.  In some cases, the reg at the top of
	 stack may be correct, but swapped anyway in order to fix
	 other regs.  But since we never swap any other reg away from
	 its correct slot, this algorithm will converge.  */

      do
	{
	  /* Swap the reg at top of stack into the position it is
	     supposed to be in, until the correct top of stack appears.  */

	  while (old->reg[old->top] != new->reg[new->top])
	    {
	      for (reg = new->top; reg >= 0; reg--)
		if (new->reg[reg] == old->reg[old->top])
		  break;

	      if (reg == -1)
		abort ();

	      emit_swap_insn (insn, old,
			      FP_MODE_REG (old->reg[reg], DFmode));
	    }

	  /* See if any regs remain incorrect.  If so, bring an
	     incorrect reg to the top of stack, and let the while loop
	     above fix it.  */

	  for (reg = new->top; reg >= 0; reg--)
	    if (new->reg[reg] != old->reg[reg])
	      {
		emit_swap_insn (insn, old,
				FP_MODE_REG (old->reg[reg], DFmode));
		break;
	      }
	} while (reg >= 0);

      /* At this point there must be no differences.  */

      for (reg = old->top; reg >= 0; reg--)
	if (old->reg[reg] != new->reg[reg])
	  abort ();
    }
}

/* Check PAT, which points to RTL in INSN, for a LABEL_REF.  If it is
   found, ensure that a jump from INSN to the code_label to which the
   label_ref points ends up with the same stack as that at the
   code_label.  Do this by inserting insns just before the code_label to
   pop and rotate the stack until it is in the correct order.  REGSTACK
   is the order of the register stack in INSN.

   Any code that is emitted here must not be later processed as part
   of any block, as it will already contain hard register numbers.  */

static void
goto_block_pat (insn, regstack, pat)
     rtx insn;
     stack regstack;
     rtx pat;
{
  rtx label;
  rtx new_jump, new_label, new_barrier;
  rtx *ref;
  stack label_stack;
  struct stack_def temp_stack;
  int reg;

  switch (GET_CODE (pat))
   {
     case RETURN:
	straighten_stack (PREV_INSN (insn), regstack);
	return;
     default:
     {
      int i, j;
      char *fmt = GET_RTX_FORMAT (GET_CODE (pat));

      for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
	{
	  if (fmt[i] == 'e')
	    goto_block_pat (insn, regstack, XEXP (pat, i));
	  if (fmt[i] == 'E')
	    for (j = 0; j < XVECLEN (pat, i); j++)
	      goto_block_pat (insn, regstack, XVECEXP (pat, i, j));
	}
      return;
     }
     case LABEL_REF:;
   }

  label = XEXP (pat, 0);
  if (GET_CODE (label) != CODE_LABEL)
    abort ();

  /* First, see if in fact anything needs to be done to the stack at all.  */
  if (INSN_UID (label) <= 0)
    return;

  label_stack = &block_stack_in[BLOCK_NUM (label)];

  if (label_stack->top == -2)
    {
      /* If the target block hasn't had a stack order selected, then
	 we need merely ensure that no pops are needed.  */

      for (reg = regstack->top; reg >= 0; reg--)
	if (! TEST_HARD_REG_BIT (label_stack->reg_set, regstack->reg[reg]))
	  break;

      if (reg == -1)
	{
	  /* change_stack will not emit any code in this case.  */

	  change_stack (label, regstack, label_stack, emit_insn_after);
	  return;
	}
    }
  else if (label_stack->top == regstack->top)
    {
      for (reg = label_stack->top; reg >= 0; reg--)
	if (label_stack->reg[reg] != regstack->reg[reg])
	  break;

      if (reg == -1)
	return;
    }

  /* At least one insn will need to be inserted before label.  Insert
     a jump around the code we are about to emit.  Emit a label for the new
     code, and point the original insn at this new label. We can't use
     redirect_jump here, because we're using fld[4] of the code labels as
     LABEL_REF chains, no NUSES counters.  */

  new_jump = emit_jump_insn_before (gen_jump (label), label);
  record_label_references (new_jump, PATTERN (new_jump));
  JUMP_LABEL (new_jump) = label;

  new_barrier = emit_barrier_after (new_jump);

  new_label = gen_label_rtx ();
  emit_label_after (new_label, new_barrier);
  LABEL_REFS (new_label) = new_label;

  /* The old label_ref will no longer point to the code_label if now uses,
     so strip the label_ref from the code_label's chain of references.  */

  for (ref = &LABEL_REFS (label); *ref != label; ref = &LABEL_NEXTREF (*ref))
    if (*ref == pat)
      break;

  if (*ref == label)
    abort ();

  *ref = LABEL_NEXTREF (*ref);

  XEXP (pat, 0) = new_label;
  record_label_references (insn, PATTERN (insn));

  if (JUMP_LABEL (insn) == label)
    JUMP_LABEL (insn) = new_label;

  /* Now emit the needed code.  */

  temp_stack = *regstack;

  change_stack (new_label, &temp_stack, label_stack, emit_insn_after);
}

/* Traverse all basic blocks in a function, converting the register
   references in each insn from the "flat" register file that gcc uses, to
   the stack-like registers the 387 uses.  */

static void
convert_regs ()
{
  register int block, reg;
  register rtx insn, next;
  struct stack_def regstack;

  for (block = 0; block < blocks; block++)
    {
      if (block_stack_in[block].top == -2)
	{
	  /* This block has not been previously encountered.  Choose a
	     default mapping for any stack regs live on entry */

	  block_stack_in[block].top = -1;

	  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
	    if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, reg))
	      block_stack_in[block].reg[++block_stack_in[block].top] = reg;
	}

      /* Process all insns in this block.  Keep track of `next' here,
	 so that we don't process any insns emitted while making
	 substitutions in INSN.  */

      next = block_begin[block];
      regstack = block_stack_in[block];
      do
	{
	  insn = next;
	  next = NEXT_INSN (insn);

	  /* Don't bother processing unless there is a stack reg
	     mentioned or if it's a CALL_INSN (register passing of
	     floating point values).  */

	  if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
	    subst_stack_regs (insn, &regstack);

	} while (insn != block_end[block]);

      /* Something failed if the stack life doesn't match.  */

      GO_IF_HARD_REG_EQUAL (regstack.reg_set, block_out_reg_set[block], win);

      abort ();

    win:

      /* Adjust the stack of this block on exit to match the stack of
	 the target block, or copy stack information into stack of
	 jump target if the target block's stack order hasn't been set
	 yet.  */

      if (GET_CODE (insn) == JUMP_INSN)
	goto_block_pat (insn, &regstack, PATTERN (insn));

      /* Likewise handle the case where we fall into the next block.  */

      if ((block < blocks - 1) && block_drops_in[block+1])
	change_stack (insn, &regstack, &block_stack_in[block+1],
		      emit_insn_after);
    }

  /* If the last basic block is the end of a loop, and that loop has
     regs live at its start, then the last basic block will have regs live
     at its end that need to be popped before the function returns.  */

   {
     int value_reg_low, value_reg_high;
     value_reg_low = value_reg_high = -1;
      {
        rtx retvalue;
        if (retvalue = stack_result (current_function_decl))
	 {
	   value_reg_low = REGNO (retvalue);
	   value_reg_high = value_reg_low +
	    HARD_REGNO_NREGS (value_reg_low, GET_MODE (retvalue)) - 1;
	 }

      }
     for (reg = regstack.top; reg >= 0; reg--)
        if (regstack.reg[reg] < value_reg_low
	    || regstack.reg[reg] > value_reg_high)
           insn = emit_pop_insn (insn, &regstack,
			    FP_MODE_REG (regstack.reg[reg], DFmode),
			    emit_insn_after);
   }
  straighten_stack (insn, &regstack);
}

/* Check expression PAT, which is in INSN, for label references.  if
   one is found, print the block number of destination to FILE.  */

static void
print_blocks (file, insn, pat)
     FILE *file;
     rtx insn, pat;
{
  register RTX_CODE code = GET_CODE (pat);
  register int i;
  register char *fmt;

  if (code == LABEL_REF)
    {
      register rtx label = XEXP (pat, 0);

      if (GET_CODE (label) != CODE_LABEL)
	abort ();

      fprintf (file, " %d", BLOCK_NUM (label));

      return;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	print_blocks (file, insn, XEXP (pat, i));
      if (fmt[i] == 'E')
	{
	  register int j;
	  for (j = 0; j < XVECLEN (pat, i); j++)
	    print_blocks (file, insn, XVECEXP (pat, i, j));
	}
    }
}

/* Write information about stack registers and stack blocks into FILE.
   This is part of making a debugging dump.  */

static void
dump_stack_info (file)
     FILE *file;
{
  register int block;

  fprintf (file, "\n%d stack blocks.\n", blocks);
  for (block = 0; block < blocks; block++)
    {
      register rtx head, jump, end;
      register int regno;

      fprintf (file, "\nStack block %d: first insn %d, last %d.\n",
	       block, INSN_UID (block_begin[block]),
	       INSN_UID (block_end[block]));

      head = block_begin[block];

      fprintf (file, "Reached from blocks: ");
      if (GET_CODE (head) == CODE_LABEL)
	for (jump = LABEL_REFS (head);
	     jump != head;
	     jump = LABEL_NEXTREF (jump))
	  {
	    register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
	    fprintf (file, " %d", from_block);
	  }
      if (block_drops_in[block])
	fprintf (file, " previous");

      fprintf (file, "\nlive stack registers on block entry: ");
      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
	{
	  if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, regno))
	    fprintf (file, "%d ", regno);
	}

      fprintf (file, "\nlive stack registers on block exit: ");
      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
	{
	  if (TEST_HARD_REG_BIT (block_out_reg_set[block], regno))
	    fprintf (file, "%d ", regno);
	}

      end = block_end[block];

      fprintf (file, "\nJumps to blocks: ");
      if (GET_CODE (end) == JUMP_INSN)
	print_blocks (file, end, PATTERN (end));

      if (block + 1 < blocks && block_drops_in[block+1])
	fprintf (file, " next");
      else if (block + 1 == blocks
	       || (GET_CODE (end) == JUMP_INSN
		   && GET_CODE (PATTERN (end)) == RETURN))
	fprintf (file, " return");

      fprintf (file, "\n");
    }
}
#endif /* STACK_REGS */
