/* Register to Stack convert for GNU compiler.
   Copyright (C) 1992, 93, 94, 95, 96, 1997 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);
	  rtx x;

	  if (computed_jump_p (insn))
	    {
	      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;
  int have_cmove; 

  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)));

      have_cmove = 1;
      if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
	  && REGNO (*dest) != regstack->reg[regstack->top])
	{
	  emit_swap_insn (insn, regstack, *dest);	
	}
    }
  else
    have_cmove = 0;

  /* ??? 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;

  if (! have_cmove)
     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])
	      {
		/* 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--;
		  }
	      }
	}

	/* Make dest the top of stack.  Add dest to regstack if not present. */
	if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
	  regstack->reg[++regstack->top] = REGNO (*dest);	
	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;
  rtx head, jump, pat, cipat;
  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 we are reached by a computed goto which sets this same stack register,
     then pop this stack register, but maintain regstack. */

  pat = single_set (insn);
  if (pat != 0
      && INSN_UID (insn) <= max_uid
      && GET_CODE (block_begin[BLOCK_NUM(insn)]) == CODE_LABEL
      && GET_CODE (pat) == SET && STACK_REG_P (SET_DEST (pat)))
    for (head = block_begin[BLOCK_NUM(insn)], jump = LABEL_REFS (head);
	 jump != head;
	 jump = LABEL_NEXTREF (jump))
      {
	cipat = single_set (CONTAINING_INSN (jump));
	if (cipat != 0
	    && GET_CODE (cipat) == SET
	    && SET_DEST (cipat) == pc_rtx
	    && uses_reg_or_mem (SET_SRC (cipat))
	    && INSN_UID (CONTAINING_INSN (jump)) <= max_uid)
	  {
	    int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
	    if (TEST_HARD_REG_BIT (block_out_reg_set[from_block],
				   REGNO (SET_DEST (pat))))
	      {
		struct stack_def old;
		bcopy (regstack->reg, old.reg, sizeof (old.reg));
		emit_pop_insn (insn, regstack, SET_DEST (pat), emit_insn_before);
		regstack->top += 1;
		bcopy (old.reg, regstack->reg, sizeof (old.reg));
		SET_HARD_REG_BIT (regstack->reg_set, REGNO (SET_DEST (pat)));
	      }
	  }
      }

  /* 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 */
