reg-stack.c revision 102780
118334Speter/* Register to Stack convert for GNU compiler.
290075Sobrien   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
390075Sobrien   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
418334Speter
590075Sobrien   This file is part of GCC.
618334Speter
790075Sobrien   GCC is free software; you can redistribute it and/or modify it
890075Sobrien   under the terms of the GNU General Public License as published by
990075Sobrien   the Free Software Foundation; either version 2, or (at your option)
1090075Sobrien   any later version.
1118334Speter
1290075Sobrien   GCC is distributed in the hope that it will be useful, but WITHOUT
1390075Sobrien   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1490075Sobrien   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1590075Sobrien   License for more details.
1618334Speter
1790075Sobrien   You should have received a copy of the GNU General Public License
1890075Sobrien   along with GCC; see the file COPYING.  If not, write to the Free
1990075Sobrien   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2090075Sobrien   02111-1307, USA.  */
2118334Speter
2218334Speter/* This pass converts stack-like registers from the "flat register
2318334Speter   file" model that gcc uses, to a stack convention that the 387 uses.
2418334Speter
2518334Speter   * The form of the input:
2618334Speter
2718334Speter   On input, the function consists of insn that have had their
2818334Speter   registers fully allocated to a set of "virtual" registers.  Note that
2918334Speter   the word "virtual" is used differently here than elsewhere in gcc: for
3018334Speter   each virtual stack reg, there is a hard reg, but the mapping between
3118334Speter   them is not known until this pass is run.  On output, hard register
3218334Speter   numbers have been substituted, and various pop and exchange insns have
3318334Speter   been emitted.  The hard register numbers and the virtual register
3418334Speter   numbers completely overlap - before this pass, all stack register
3518334Speter   numbers are virtual, and afterward they are all hard.
3618334Speter
3718334Speter   The virtual registers can be manipulated normally by gcc, and their
3818334Speter   semantics are the same as for normal registers.  After the hard
3918334Speter   register numbers are substituted, the semantics of an insn containing
4018334Speter   stack-like regs are not the same as for an insn with normal regs: for
4118334Speter   instance, it is not safe to delete an insn that appears to be a no-op
4218334Speter   move.  In general, no insn containing hard regs should be changed
4318334Speter   after this pass is done.
4418334Speter
4518334Speter   * The form of the output:
4618334Speter
4718334Speter   After this pass, hard register numbers represent the distance from
4818334Speter   the current top of stack to the desired register.  A reference to
4918334Speter   FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1,
5018334Speter   represents the register just below that, and so forth.  Also, REG_DEAD
5118334Speter   notes indicate whether or not a stack register should be popped.
5218334Speter
5318334Speter   A "swap" insn looks like a parallel of two patterns, where each
5418334Speter   pattern is a SET: one sets A to B, the other B to A.
5518334Speter
5618334Speter   A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG
5718334Speter   and whose SET_DEST is REG or MEM.  Any other SET_DEST, such as PLUS,
5818334Speter   will replace the existing stack top, not push a new value.
5918334Speter
6018334Speter   A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose
6118334Speter   SET_SRC is REG or MEM.
6218334Speter
6318334Speter   The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG
6418334Speter   appears ambiguous.  As a special case, the presence of a REG_DEAD note
6518334Speter   for FIRST_STACK_REG differentiates between a load insn and a pop.
6618334Speter
6718334Speter   If a REG_DEAD is present, the insn represents a "pop" that discards
6818334Speter   the top of the register stack.  If there is no REG_DEAD note, then the
6918334Speter   insn represents a "dup" or a push of the current top of stack onto the
7018334Speter   stack.
7118334Speter
7218334Speter   * Methodology:
7318334Speter
7418334Speter   Existing REG_DEAD and REG_UNUSED notes for stack registers are
7518334Speter   deleted and recreated from scratch.  REG_DEAD is never created for a
7618334Speter   SET_DEST, only REG_UNUSED.
7718334Speter
7818334Speter   * asm_operands:
7918334Speter
8018334Speter   There are several rules on the usage of stack-like regs in
8118334Speter   asm_operands insns.  These rules apply only to the operands that are
8218334Speter   stack-like regs:
8318334Speter
8418334Speter   1. Given a set of input regs that die in an asm_operands, it is
8518334Speter      necessary to know which are implicitly popped by the asm, and
8618334Speter      which must be explicitly popped by gcc.
8718334Speter
8818334Speter	An input reg that is implicitly popped by the asm must be
8918334Speter	explicitly clobbered, unless it is constrained to match an
9018334Speter	output operand.
9118334Speter
9218334Speter   2. For any input reg that is implicitly popped by an asm, it is
9318334Speter      necessary to know how to adjust the stack to compensate for the pop.
9418334Speter      If any non-popped input is closer to the top of the reg-stack than
9518334Speter      the implicitly popped reg, it would not be possible to know what the
9618334Speter      stack looked like - it's not clear how the rest of the stack "slides
9718334Speter      up".
9818334Speter
9918334Speter	All implicitly popped input regs must be closer to the top of
10018334Speter	the reg-stack than any input that is not implicitly popped.
10118334Speter
10218334Speter   3. It is possible that if an input dies in an insn, reload might
10318334Speter      use the input reg for an output reload.  Consider this example:
10418334Speter
10518334Speter		asm ("foo" : "=t" (a) : "f" (b));
10618334Speter
10718334Speter      This asm says that input B is not popped by the asm, and that
10818334Speter      the asm pushes a result onto the reg-stack, ie, the stack is one
10918334Speter      deeper after the asm than it was before.  But, it is possible that
11018334Speter      reload will think that it can use the same reg for both the input and
11118334Speter      the output, if input B dies in this insn.
11218334Speter
11318334Speter	If any input operand uses the "f" constraint, all output reg
11418334Speter	constraints must use the "&" earlyclobber.
11518334Speter
11618334Speter      The asm above would be written as
11718334Speter
11818334Speter		asm ("foo" : "=&t" (a) : "f" (b));
11918334Speter
12018334Speter   4. Some operands need to be in particular places on the stack.  All
12118334Speter      output operands fall in this category - there is no other way to
12218334Speter      know which regs the outputs appear in unless the user indicates
12318334Speter      this in the constraints.
12418334Speter
12518334Speter	Output operands must specifically indicate which reg an output
12618334Speter	appears in after an asm.  "=f" is not allowed: the operand
12718334Speter	constraints must select a class with a single reg.
12818334Speter
12918334Speter   5. Output operands may not be "inserted" between existing stack regs.
13018334Speter      Since no 387 opcode uses a read/write operand, all output operands
13118334Speter      are dead before the asm_operands, and are pushed by the asm_operands.
13218334Speter      It makes no sense to push anywhere but the top of the reg-stack.
13318334Speter
13418334Speter	Output operands must start at the top of the reg-stack: output
13518334Speter	operands may not "skip" a reg.
13618334Speter
13718334Speter   6. Some asm statements may need extra stack space for internal
13818334Speter      calculations.  This can be guaranteed by clobbering stack registers
13918334Speter      unrelated to the inputs and outputs.
14018334Speter
14118334Speter   Here are a couple of reasonable asms to want to write.  This asm
14218334Speter   takes one input, which is internally popped, and produces two outputs.
14318334Speter
14418334Speter	asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));
14518334Speter
14618334Speter   This asm takes two inputs, which are popped by the fyl2xp1 opcode,
14718334Speter   and replaces them with one output.  The user must code the "st(1)"
14818334Speter   clobber for reg-stack.c to know that fyl2xp1 pops both inputs.
14918334Speter
15018334Speter	asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
15118334Speter
15290075Sobrien*/
15318334Speter
15418334Speter#include "config.h"
15550397Sobrien#include "system.h"
15618334Speter#include "tree.h"
15718334Speter#include "rtl.h"
15890075Sobrien#include "tm_p.h"
15990075Sobrien#include "function.h"
16018334Speter#include "insn-config.h"
16118334Speter#include "regs.h"
16218334Speter#include "hard-reg-set.h"
16318334Speter#include "flags.h"
16490075Sobrien#include "toplev.h"
16552284Sobrien#include "recog.h"
16690075Sobrien#include "output.h"
16790075Sobrien#include "basic-block.h"
16852284Sobrien#include "varray.h"
16990075Sobrien#include "reload.h"
17018334Speter
17118334Speter#ifdef STACK_REGS
17218334Speter
17318334Speter#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
17418334Speter
17518334Speter/* This is the basic stack record.  TOP is an index into REG[] such
17618334Speter   that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.
17718334Speter
17818334Speter   If TOP is -2, REG[] is not yet initialized.  Stack initialization
17918334Speter   consists of placing each live reg in array `reg' and setting `top'
18018334Speter   appropriately.
18118334Speter
18218334Speter   REG_SET indicates which registers are live.  */
18318334Speter
18418334Spetertypedef struct stack_def
18518334Speter{
18618334Speter  int top;			/* index to top stack element */
18718334Speter  HARD_REG_SET reg_set;		/* set of live registers */
18890075Sobrien  unsigned char reg[REG_STACK_SIZE];/* register - stack mapping */
18918334Speter} *stack;
19018334Speter
19190075Sobrien/* This is used to carry information about basic blocks.  It is
19290075Sobrien   attached to the AUX field of the standard CFG block.  */
19318334Speter
19490075Sobrientypedef struct block_info_def
19590075Sobrien{
19690075Sobrien  struct stack_def stack_in;	/* Input stack configuration.  */
19790075Sobrien  struct stack_def stack_out;	/* Output stack configuration.  */
19890075Sobrien  HARD_REG_SET out_reg_set;	/* Stack regs live on output.  */
19990075Sobrien  int done;			/* True if block already converted.  */
20090075Sobrien  int predecessors;		/* Number of predecessors that needs
20190075Sobrien				   to be visited.  */
20290075Sobrien} *block_info;
20318334Speter
20490075Sobrien#define BLOCK_INFO(B)	((block_info) (B)->aux)
20518334Speter
20690075Sobrien/* Passed to change_stack to indicate where to emit insns.  */
20790075Sobrienenum emit_where
20890075Sobrien{
20990075Sobrien  EMIT_AFTER,
21090075Sobrien  EMIT_BEFORE
21190075Sobrien};
21218334Speter
21352284Sobrien/* We use this array to cache info about insns, because otherwise we
21452284Sobrien   spend too much time in stack_regs_mentioned_p.
21552284Sobrien
21652284Sobrien   Indexed by insn UIDs.  A value of zero is uninitialized, one indicates
21752284Sobrien   the insn uses stack registers, two indicates the insn does not use
21852284Sobrien   stack registers.  */
21952284Sobrienstatic varray_type stack_regs_mentioned_data;
22052284Sobrien
22190075Sobrien/* The block we're currently working on.  */
22290075Sobrienstatic basic_block current_block;
22390075Sobrien
22418334Speter/* This is the register file for all register after conversion */
22518334Speterstatic rtx
22618334Speter  FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
22718334Speter
22818334Speter#define FP_MODE_REG(regno,mode)	\
22990075Sobrien  (FP_mode_reg[(regno)-FIRST_STACK_REG][(int) (mode)])
23018334Speter
23190075Sobrien/* Used to initialize uninitialized registers.  */
23290075Sobrienstatic rtx nan;
23318334Speter
23418334Speter/* Forward declarations */
23518334Speter
23690075Sobrienstatic int stack_regs_mentioned_p	PARAMS ((rtx pat));
23790075Sobrienstatic void straighten_stack		PARAMS ((rtx, stack));
23890075Sobrienstatic void pop_stack			PARAMS ((stack, int));
23990075Sobrienstatic rtx *get_true_reg		PARAMS ((rtx *));
24050397Sobrien
24190075Sobrienstatic int check_asm_stack_operands	PARAMS ((rtx));
24290075Sobrienstatic int get_asm_operand_n_inputs	PARAMS ((rtx));
24390075Sobrienstatic rtx stack_result			PARAMS ((tree));
24490075Sobrienstatic void replace_reg			PARAMS ((rtx *, int));
24590075Sobrienstatic void remove_regno_note		PARAMS ((rtx, enum reg_note,
24690075Sobrien						 unsigned int));
24790075Sobrienstatic int get_hard_regnum		PARAMS ((stack, rtx));
24890075Sobrienstatic rtx emit_pop_insn		PARAMS ((rtx, stack, rtx,
24990075Sobrien					       enum emit_where));
25090075Sobrienstatic void emit_swap_insn		PARAMS ((rtx, stack, rtx));
25190075Sobrienstatic void move_for_stack_reg		PARAMS ((rtx, stack, rtx));
25290075Sobrienstatic int swap_rtx_condition_1		PARAMS ((rtx));
25390075Sobrienstatic int swap_rtx_condition		PARAMS ((rtx));
25490075Sobrienstatic void compare_for_stack_reg	PARAMS ((rtx, stack, rtx));
25590075Sobrienstatic void subst_stack_regs_pat	PARAMS ((rtx, stack, rtx));
25690075Sobrienstatic void subst_asm_stack_regs	PARAMS ((rtx, stack));
25790075Sobrienstatic void subst_stack_regs		PARAMS ((rtx, stack));
25890075Sobrienstatic void change_stack		PARAMS ((rtx, stack, stack,
25990075Sobrien					       enum emit_where));
26090075Sobrienstatic int convert_regs_entry		PARAMS ((void));
26190075Sobrienstatic void convert_regs_exit		PARAMS ((void));
26290075Sobrienstatic int convert_regs_1		PARAMS ((FILE *, basic_block));
26390075Sobrienstatic int convert_regs_2		PARAMS ((FILE *, basic_block));
26490075Sobrienstatic int convert_regs			PARAMS ((FILE *));
26590075Sobrienstatic void print_stack 		PARAMS ((FILE *, stack));
26690075Sobrienstatic rtx next_flags_user 		PARAMS ((rtx));
26790075Sobrienstatic void record_label_references	PARAMS ((rtx, rtx));
26890075Sobrienstatic bool compensate_edge		PARAMS ((edge, FILE *));
26918334Speter
27090075Sobrien/* Return non-zero if any stack register is mentioned somewhere within PAT.  */
27152284Sobrien
27252284Sobrienstatic int
27390075Sobrienstack_regs_mentioned_p (pat)
27490075Sobrien     rtx pat;
27552284Sobrien{
27690075Sobrien  const char *fmt;
27790075Sobrien  int i;
27890075Sobrien
27990075Sobrien  if (STACK_REG_P (pat))
28090075Sobrien    return 1;
28190075Sobrien
28290075Sobrien  fmt = GET_RTX_FORMAT (GET_CODE (pat));
28390075Sobrien  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
28452284Sobrien    {
28590075Sobrien      if (fmt[i] == 'E')
28690075Sobrien	{
28790075Sobrien	  int j;
28890075Sobrien
28990075Sobrien	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
29090075Sobrien	    if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
29190075Sobrien	      return 1;
29290075Sobrien	}
29390075Sobrien      else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
29490075Sobrien	return 1;
29552284Sobrien    }
29690075Sobrien
29752284Sobrien  return 0;
29852284Sobrien}
29952284Sobrien
30090075Sobrien/* Return nonzero if INSN mentions stacked registers, else return zero.  */
30152284Sobrien
30252284Sobrienint
30352284Sobrienstack_regs_mentioned (insn)
30452284Sobrien     rtx insn;
30552284Sobrien{
30690075Sobrien  unsigned int uid, max;
30790075Sobrien  int test;
30890075Sobrien
30990075Sobrien  if (! INSN_P (insn) || !stack_regs_mentioned_data)
31052284Sobrien    return 0;
31190075Sobrien
31252284Sobrien  uid = INSN_UID (insn);
31390075Sobrien  max = VARRAY_SIZE (stack_regs_mentioned_data);
31490075Sobrien  if (uid >= max)
31590075Sobrien    {
31690075Sobrien      /* Allocate some extra size to avoid too many reallocs, but
31790075Sobrien	 do not grow too quickly.  */
31890075Sobrien      max = uid + uid / 20;
31990075Sobrien      VARRAY_GROW (stack_regs_mentioned_data, max);
32090075Sobrien    }
32190075Sobrien
32290075Sobrien  test = VARRAY_CHAR (stack_regs_mentioned_data, uid);
32390075Sobrien  if (test == 0)
32490075Sobrien    {
32590075Sobrien      /* This insn has yet to be examined.  Do so now.  */
32690075Sobrien      test = stack_regs_mentioned_p (PATTERN (insn)) ? 1 : 2;
32790075Sobrien      VARRAY_CHAR (stack_regs_mentioned_data, uid) = test;
32890075Sobrien    }
32990075Sobrien
33090075Sobrien  return test == 1;
33152284Sobrien}
33252284Sobrien
33390075Sobrienstatic rtx ix86_flags_rtx;
33418334Speter
33590075Sobrienstatic rtx
33690075Sobriennext_flags_user (insn)
33790075Sobrien     rtx insn;
33818334Speter{
33990075Sobrien  /* Search forward looking for the first use of this value.
34090075Sobrien     Stop at block boundaries.  */
34118334Speter
34290075Sobrien  while (insn != current_block->end)
34390075Sobrien    {
34490075Sobrien      insn = NEXT_INSN (insn);
34518334Speter
34690075Sobrien      if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
34790075Sobrien        return insn;
34890075Sobrien
34990075Sobrien      if (GET_CODE (insn) == CALL_INSN)
35090075Sobrien	return NULL_RTX;
35190075Sobrien    }
35290075Sobrien  return NULL_RTX;
35318334Speter}
35418334Speter
35518334Speter/* Reorganise the stack into ascending numbers,
35618334Speter   after this insn.  */
35718334Speter
35818334Speterstatic void
35918334Speterstraighten_stack (insn, regstack)
36018334Speter     rtx insn;
36118334Speter     stack regstack;
36218334Speter{
36318334Speter  struct stack_def temp_stack;
36418334Speter  int top;
36518334Speter
36650397Sobrien  /* If there is only a single register on the stack, then the stack is
36750397Sobrien     already in increasing order and no reorganization is needed.
36850397Sobrien
36950397Sobrien     Similarly if the stack is empty.  */
37050397Sobrien  if (regstack->top <= 0)
37150397Sobrien    return;
37250397Sobrien
37390075Sobrien  COPY_HARD_REG_SET (temp_stack.reg_set, regstack->reg_set);
37418334Speter
37518334Speter  for (top = temp_stack.top = regstack->top; top >= 0; top--)
37690075Sobrien    temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
37718334Speter
37890075Sobrien  change_stack (insn, regstack, &temp_stack, EMIT_AFTER);
37918334Speter}
38050397Sobrien
38150397Sobrien/* Pop a register from the stack */
38250397Sobrien
38350397Sobrienstatic void
38450397Sobrienpop_stack (regstack, regno)
38550397Sobrien     stack regstack;
38650397Sobrien     int   regno;
38750397Sobrien{
38850397Sobrien  int top = regstack->top;
38950397Sobrien
39050397Sobrien  CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
39150397Sobrien  regstack->top--;
39250397Sobrien  /* If regno was not at the top of stack then adjust stack */
39350397Sobrien  if (regstack->reg [top] != regno)
39450397Sobrien    {
39550397Sobrien      int i;
39650397Sobrien      for (i = regstack->top; i >= 0; i--)
39750397Sobrien	if (regstack->reg [i] == regno)
39850397Sobrien	  {
39950397Sobrien	    int j;
40050397Sobrien	    for (j = i; j < top; j++)
40150397Sobrien	      regstack->reg [j] = regstack->reg [j + 1];
40250397Sobrien	    break;
40350397Sobrien	  }
40450397Sobrien    }
40550397Sobrien}
40618334Speter
40718334Speter/* Convert register usage from "flat" register file usage to a "stack
40818334Speter   register file.  FIRST is the first insn in the function, FILE is the
40918334Speter   dump file, if used.
41018334Speter
41190075Sobrien   Construct a CFG and run life analysis.  Then convert each insn one
41290075Sobrien   by one.  Run a last cleanup_cfg pass, if optimizing, to eliminate
41390075Sobrien   code duplication created when the converter inserts pop insns on
41490075Sobrien   the edges.  */
41518334Speter
41618334Spetervoid
41718334Speterreg_to_stack (first, file)
41818334Speter     rtx first;
41918334Speter     FILE *file;
42018334Speter{
42190075Sobrien  int i;
42290075Sobrien  int max_uid;
42318334Speter
42490075Sobrien  /* Clean up previous run.  */
42590075Sobrien  if (stack_regs_mentioned_data)
42652284Sobrien    {
42752284Sobrien      VARRAY_FREE (stack_regs_mentioned_data);
42890075Sobrien      stack_regs_mentioned_data = 0;
42952284Sobrien    }
43018334Speter
43190075Sobrien  if (!optimize)
43290075Sobrien    split_all_insns (0);
43318334Speter
43490075Sobrien  /* See if there is something to do.  Flow analysis is quite
43590075Sobrien     expensive so we might save some compilation time.  */
43690075Sobrien  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
43790075Sobrien    if (regs_ever_live[i])
43890075Sobrien      break;
43990075Sobrien  if (i > LAST_STACK_REG)
44090075Sobrien    return;
44118334Speter
44290075Sobrien  /* Ok, floating point instructions exist.  If not optimizing,
44390075Sobrien     build the CFG and run life analysis.  */
44490075Sobrien  if (!optimize)
44590075Sobrien    {
44690075Sobrien      find_basic_blocks (first, max_reg_num (), file);
44790075Sobrien      count_or_remove_death_notes (NULL, 1);
44890075Sobrien      life_analysis (first, file, PROP_DEATH_NOTES);
44990075Sobrien    }
45090075Sobrien  mark_dfs_back_edges ();
45118334Speter
45290075Sobrien  /* Set up block info for each basic block.  */
45390075Sobrien  alloc_aux_for_blocks (sizeof (struct block_info_def));
45490075Sobrien  for (i = n_basic_blocks - 1; i >= 0; --i)
45590075Sobrien    {
45690075Sobrien      edge e;
45790075Sobrien      basic_block bb = BASIC_BLOCK (i);
45890075Sobrien      for (e = bb->pred; e; e=e->pred_next)
45990075Sobrien	if (!(e->flags & EDGE_DFS_BACK)
46090075Sobrien	    && e->src != ENTRY_BLOCK_PTR)
46190075Sobrien	  BLOCK_INFO (bb)->predecessors++;
46290075Sobrien    }
46318334Speter
46490075Sobrien  /* Create the replacement registers up front.  */
46590075Sobrien  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
46690075Sobrien    {
46790075Sobrien      enum machine_mode mode;
46890075Sobrien      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
46990075Sobrien	   mode != VOIDmode;
47090075Sobrien	   mode = GET_MODE_WIDER_MODE (mode))
47190075Sobrien	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
47290075Sobrien      for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
47390075Sobrien	   mode != VOIDmode;
47490075Sobrien	   mode = GET_MODE_WIDER_MODE (mode))
47590075Sobrien	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
47690075Sobrien    }
47718334Speter
47890075Sobrien  ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
47918334Speter
48090075Sobrien  /* A QNaN for initializing uninitialized variables.
48118334Speter
48290075Sobrien     ??? We can't load from constant memory in PIC mode, because
48390075Sobrien     we're insertting these instructions before the prologue and
48490075Sobrien     the PIC register hasn't been set up.  In that case, fall back
48590075Sobrien     on zero, which we can get from `ldz'.  */
48618334Speter
48790075Sobrien  if (flag_pic)
48890075Sobrien    nan = CONST0_RTX (SFmode);
48990075Sobrien  else
49090075Sobrien    {
49190075Sobrien      nan = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
49290075Sobrien      nan = force_const_mem (SFmode, nan);
49390075Sobrien    }
49418334Speter
49590075Sobrien  /* Allocate a cache for stack_regs_mentioned.  */
49690075Sobrien  max_uid = get_max_uid ();
49790075Sobrien  VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
49890075Sobrien		    "stack_regs_mentioned cache");
49918334Speter
50090075Sobrien  convert_regs (file);
50152284Sobrien
50290075Sobrien  free_aux_for_blocks ();
50318334Speter}
50418334Speter
50518334Speter/* Check PAT, which is in INSN, for LABEL_REFs.  Add INSN to the
50618334Speter   label's chain of references, and note which insn contains each
50750397Sobrien   reference.  */
50818334Speter
50918334Speterstatic void
51018334Speterrecord_label_references (insn, pat)
51118334Speter     rtx insn, pat;
51218334Speter{
51390075Sobrien  enum rtx_code code = GET_CODE (pat);
51490075Sobrien  int i;
51590075Sobrien  const char *fmt;
51618334Speter
51718334Speter  if (code == LABEL_REF)
51818334Speter    {
51990075Sobrien      rtx label = XEXP (pat, 0);
52090075Sobrien      rtx ref;
52118334Speter
52218334Speter      if (GET_CODE (label) != CODE_LABEL)
52318334Speter	abort ();
52418334Speter
52550397Sobrien      /* If this is an undefined label, LABEL_REFS (label) contains
52650397Sobrien         garbage.  */
52750397Sobrien      if (INSN_UID (label) == 0)
52850397Sobrien	return;
52918334Speter
53050397Sobrien      /* Don't make a duplicate in the code_label's chain.  */
53150397Sobrien
53218334Speter      for (ref = LABEL_REFS (label);
53318334Speter	   ref && ref != label;
53418334Speter	   ref = LABEL_NEXTREF (ref))
53518334Speter	if (CONTAINING_INSN (ref) == insn)
53618334Speter	  return;
53718334Speter
53818334Speter      CONTAINING_INSN (pat) = insn;
53918334Speter      LABEL_NEXTREF (pat) = LABEL_REFS (label);
54018334Speter      LABEL_REFS (label) = pat;
54118334Speter
54218334Speter      return;
54318334Speter    }
54418334Speter
54518334Speter  fmt = GET_RTX_FORMAT (code);
54618334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
54718334Speter    {
54818334Speter      if (fmt[i] == 'e')
54918334Speter	record_label_references (insn, XEXP (pat, i));
55018334Speter      if (fmt[i] == 'E')
55118334Speter	{
55290075Sobrien	  int j;
55318334Speter	  for (j = 0; j < XVECLEN (pat, i); j++)
55418334Speter	    record_label_references (insn, XVECEXP (pat, i, j));
55518334Speter	}
55618334Speter    }
55718334Speter}
55818334Speter
55918334Speter/* Return a pointer to the REG expression within PAT.  If PAT is not a
56018334Speter   REG, possible enclosed by a conversion rtx, return the inner part of
56150397Sobrien   PAT that stopped the search.  */
56218334Speter
56318334Speterstatic rtx *
56418334Speterget_true_reg (pat)
56518334Speter     rtx *pat;
56618334Speter{
56718334Speter  for (;;)
56890075Sobrien    switch (GET_CODE (*pat))
56918334Speter      {
57090075Sobrien      case SUBREG:
57190075Sobrien	/* Eliminate FP subregister accesses in favour of the
57290075Sobrien	   actual FP register in use.  */
57390075Sobrien	{
57490075Sobrien	  rtx subreg;
57590075Sobrien	  if (FP_REG_P (subreg = SUBREG_REG (*pat)))
57618334Speter	    {
57790075Sobrien	      int regno_off = subreg_regno_offset (REGNO (subreg),
57890075Sobrien						   GET_MODE (subreg),
57990075Sobrien						   SUBREG_BYTE (*pat),
58090075Sobrien						   GET_MODE (*pat));
58190075Sobrien	      *pat = FP_MODE_REG (REGNO (subreg) + regno_off,
58218334Speter				  GET_MODE (subreg));
58390075Sobrien	    default:
58418334Speter	      return pat;
58518334Speter	    }
58690075Sobrien	}
58790075Sobrien      case FLOAT:
58890075Sobrien      case FIX:
58990075Sobrien      case FLOAT_EXTEND:
59090075Sobrien	pat = & XEXP (*pat, 0);
59118334Speter      }
59218334Speter}
59318334Speter
59490075Sobrien/* There are many rules that an asm statement for stack-like regs must
59518334Speter   follow.  Those rules are explained at the top of this file: the rule
59650397Sobrien   numbers below refer to that explanation.  */
59718334Speter
59890075Sobrienstatic int
59990075Sobriencheck_asm_stack_operands (insn)
60018334Speter     rtx insn;
60118334Speter{
60218334Speter  int i;
60318334Speter  int n_clobbers;
60418334Speter  int malformed_asm = 0;
60518334Speter  rtx body = PATTERN (insn);
60618334Speter
60790075Sobrien  char reg_used_as_output[FIRST_PSEUDO_REGISTER];
60890075Sobrien  char implicitly_dies[FIRST_PSEUDO_REGISTER];
60952284Sobrien  int alt;
61018334Speter
61190075Sobrien  rtx *clobber_reg = 0;
61252284Sobrien  int n_inputs, n_outputs;
61318334Speter
61418334Speter  /* Find out what the constraints require.  If no constraint
61518334Speter     alternative matches, this asm is malformed.  */
61652284Sobrien  extract_insn (insn);
61752284Sobrien  constrain_operands (1);
61852284Sobrien  alt = which_alternative;
61918334Speter
62052284Sobrien  preprocess_constraints ();
62152284Sobrien
62252284Sobrien  n_inputs = get_asm_operand_n_inputs (body);
62390075Sobrien  n_outputs = recog_data.n_operands - n_inputs;
62452284Sobrien
62552284Sobrien  if (alt < 0)
62652284Sobrien    {
62752284Sobrien      malformed_asm = 1;
62852284Sobrien      /* Avoid further trouble with this insn.  */
62952284Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
63090075Sobrien      return 0;
63152284Sobrien    }
63252284Sobrien
63350397Sobrien  /* Strip SUBREGs here to make the following code simpler.  */
63490075Sobrien  for (i = 0; i < recog_data.n_operands; i++)
63590075Sobrien    if (GET_CODE (recog_data.operand[i]) == SUBREG
63690075Sobrien	&& GET_CODE (SUBREG_REG (recog_data.operand[i])) == REG)
63790075Sobrien      recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
63818334Speter
63918334Speter  /* Set up CLOBBER_REG.  */
64018334Speter
64118334Speter  n_clobbers = 0;
64218334Speter
64318334Speter  if (GET_CODE (body) == PARALLEL)
64418334Speter    {
64552284Sobrien      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
64618334Speter
64718334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
64818334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
64918334Speter	  {
65018334Speter	    rtx clobber = XVECEXP (body, 0, i);
65118334Speter	    rtx reg = XEXP (clobber, 0);
65218334Speter
65318334Speter	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
65418334Speter	      reg = SUBREG_REG (reg);
65518334Speter
65618334Speter	    if (STACK_REG_P (reg))
65718334Speter	      {
65818334Speter		clobber_reg[n_clobbers] = reg;
65918334Speter		n_clobbers++;
66018334Speter	      }
66118334Speter	  }
66218334Speter    }
66318334Speter
66418334Speter  /* Enforce rule #4: Output operands must specifically indicate which
66518334Speter     reg an output appears in after an asm.  "=f" is not allowed: the
66618334Speter     operand constraints must select a class with a single reg.
66718334Speter
66818334Speter     Also enforce rule #5: Output operands must start at the top of
66950397Sobrien     the reg-stack: output operands may not "skip" a reg.  */
67018334Speter
67190075Sobrien  memset (reg_used_as_output, 0, sizeof (reg_used_as_output));
67218334Speter  for (i = 0; i < n_outputs; i++)
67390075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
67450397Sobrien      {
67552284Sobrien	if (reg_class_size[(int) recog_op_alt[i][alt].class] != 1)
67650397Sobrien	  {
67790075Sobrien	    error_for_asm (insn, "output constraint %d must specify a single register", i);
67850397Sobrien	    malformed_asm = 1;
67950397Sobrien	  }
68050397Sobrien        else
68190075Sobrien	  {
68290075Sobrien	    int j;
68390075Sobrien
68490075Sobrien	    for (j = 0; j < n_clobbers; j++)
68590075Sobrien	      if (REGNO (recog_data.operand[i]) == REGNO (clobber_reg[j]))
68690075Sobrien		{
68790075Sobrien		  error_for_asm (insn, "output constraint %d cannot be specified together with \"%s\" clobber",
68890075Sobrien				 i, reg_names [REGNO (clobber_reg[j])]);
68990075Sobrien		  malformed_asm = 1;
69090075Sobrien		  break;
69190075Sobrien		}
69290075Sobrien	    if (j == n_clobbers)
69390075Sobrien	      reg_used_as_output[REGNO (recog_data.operand[i])] = 1;
69490075Sobrien	  }
69550397Sobrien      }
69618334Speter
69718334Speter
69818334Speter  /* Search for first non-popped reg.  */
69918334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
70018334Speter    if (! reg_used_as_output[i])
70118334Speter      break;
70218334Speter
70318334Speter  /* If there are any other popped regs, that's an error.  */
70418334Speter  for (; i < LAST_STACK_REG + 1; i++)
70518334Speter    if (reg_used_as_output[i])
70618334Speter      break;
70718334Speter
70818334Speter  if (i != LAST_STACK_REG + 1)
70918334Speter    {
71090075Sobrien      error_for_asm (insn, "output regs must be grouped at top of stack");
71118334Speter      malformed_asm = 1;
71218334Speter    }
71318334Speter
71418334Speter  /* Enforce rule #2: All implicitly popped input regs must be closer
71518334Speter     to the top of the reg-stack than any input that is not implicitly
71650397Sobrien     popped.  */
71718334Speter
71890075Sobrien  memset (implicitly_dies, 0, sizeof (implicitly_dies));
71952284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
72090075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
72118334Speter      {
72218334Speter	/* An input reg is implicitly popped if it is tied to an
72350397Sobrien	   output, or if there is a CLOBBER for it.  */
72418334Speter	int j;
72518334Speter
72618334Speter	for (j = 0; j < n_clobbers; j++)
72790075Sobrien	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
72818334Speter	    break;
72918334Speter
73052284Sobrien	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
73190075Sobrien	  implicitly_dies[REGNO (recog_data.operand[i])] = 1;
73218334Speter      }
73318334Speter
73418334Speter  /* Search for first non-popped reg.  */
73518334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
73618334Speter    if (! implicitly_dies[i])
73718334Speter      break;
73818334Speter
73918334Speter  /* If there are any other popped regs, that's an error.  */
74018334Speter  for (; i < LAST_STACK_REG + 1; i++)
74118334Speter    if (implicitly_dies[i])
74218334Speter      break;
74318334Speter
74418334Speter  if (i != LAST_STACK_REG + 1)
74518334Speter    {
74618334Speter      error_for_asm (insn,
74790075Sobrien		     "implicitly popped regs must be grouped at top of stack");
74818334Speter      malformed_asm = 1;
74918334Speter    }
75018334Speter
75118334Speter  /* Enfore rule #3: If any input operand uses the "f" constraint, all
75218334Speter     output constraints must use the "&" earlyclobber.
75318334Speter
75490075Sobrien     ??? Detect this more deterministically by having constrain_asm_operands
75550397Sobrien     record any earlyclobber.  */
75618334Speter
75752284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
75852284Sobrien    if (recog_op_alt[i][alt].matches == -1)
75918334Speter      {
76018334Speter	int j;
76118334Speter
76218334Speter	for (j = 0; j < n_outputs; j++)
76390075Sobrien	  if (operands_match_p (recog_data.operand[j], recog_data.operand[i]))
76418334Speter	    {
76518334Speter	      error_for_asm (insn,
76690075Sobrien			     "output operand %d must use `&' constraint", j);
76718334Speter	      malformed_asm = 1;
76818334Speter	    }
76918334Speter      }
77018334Speter
77118334Speter  if (malformed_asm)
77218334Speter    {
77318334Speter      /* Avoid further trouble with this insn.  */
77450397Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
77590075Sobrien      return 0;
77618334Speter    }
77718334Speter
77890075Sobrien  return 1;
77918334Speter}
78018334Speter
78118334Speter/* Calculate the number of inputs and outputs in BODY, an
78218334Speter   asm_operands.  N_OPERANDS is the total number of operands, and
78318334Speter   N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
78450397Sobrien   placed.  */
78518334Speter
78652284Sobrienstatic int
78752284Sobrienget_asm_operand_n_inputs (body)
78818334Speter     rtx body;
78918334Speter{
79018334Speter  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
79152284Sobrien    return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
79218334Speter
79318334Speter  else if (GET_CODE (body) == ASM_OPERANDS)
79452284Sobrien    return ASM_OPERANDS_INPUT_LENGTH (body);
79518334Speter
79618334Speter  else if (GET_CODE (body) == PARALLEL
79718334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
79852284Sobrien    return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));
79918334Speter
80018334Speter  else if (GET_CODE (body) == PARALLEL
80118334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
80252284Sobrien    return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
80318334Speter
80452284Sobrien  abort ();
80518334Speter}
80618334Speter
80718334Speter/* If current function returns its result in an fp stack register,
80818334Speter   return the REG.  Otherwise, return 0.  */
80918334Speter
81018334Speterstatic rtx
81118334Speterstack_result (decl)
81218334Speter     tree decl;
81318334Speter{
81452750Sobrien  rtx result;
81518334Speter
81652750Sobrien  /* If the value is supposed to be returned in memory, then clearly
81752750Sobrien     it is not returned in a stack register.  */
81852750Sobrien  if (aggregate_value_p (DECL_RESULT (decl)))
81952750Sobrien    return 0;
82052750Sobrien
82190075Sobrien  result = DECL_RTL_IF_SET (DECL_RESULT (decl));
82290075Sobrien  if (result != 0)
82318334Speter    {
82418334Speter#ifdef FUNCTION_OUTGOING_VALUE
82518334Speter      result
82618334Speter        = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
82718334Speter#else
82818334Speter      result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
82918334Speter#endif
83018334Speter    }
83118334Speter
83218334Speter  return result != 0 && STACK_REG_P (result) ? result : 0;
83318334Speter}
83418334Speter
83518334Speter
83690075Sobrien/*
83790075Sobrien * This section deals with stack register substitution, and forms the second
83890075Sobrien * pass over the RTL.
83990075Sobrien */
84018334Speter
84118334Speter/* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
84250397Sobrien   the desired hard REGNO.  */
84318334Speter
84418334Speterstatic void
84518334Speterreplace_reg (reg, regno)
84618334Speter     rtx *reg;
84718334Speter     int regno;
84818334Speter{
84918334Speter  if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG
85018334Speter      || ! STACK_REG_P (*reg))
85118334Speter    abort ();
85218334Speter
85318334Speter  switch (GET_MODE_CLASS (GET_MODE (*reg)))
85490075Sobrien    {
85590075Sobrien    default: abort ();
85690075Sobrien    case MODE_FLOAT:
85790075Sobrien    case MODE_COMPLEX_FLOAT:;
85890075Sobrien    }
85918334Speter
86018334Speter  *reg = FP_MODE_REG (regno, GET_MODE (*reg));
86118334Speter}
86218334Speter
86318334Speter/* Remove a note of type NOTE, which must be found, for register
86450397Sobrien   number REGNO from INSN.  Remove only one such note.  */
86518334Speter
86618334Speterstatic void
86718334Speterremove_regno_note (insn, note, regno)
86818334Speter     rtx insn;
86918334Speter     enum reg_note note;
87090075Sobrien     unsigned int regno;
87118334Speter{
87290075Sobrien  rtx *note_link, this;
87318334Speter
87490075Sobrien  note_link = &REG_NOTES (insn);
87518334Speter  for (this = *note_link; this; this = XEXP (this, 1))
87618334Speter    if (REG_NOTE_KIND (this) == note
87718334Speter	&& REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
87818334Speter      {
87918334Speter	*note_link = XEXP (this, 1);
88018334Speter	return;
88118334Speter      }
88218334Speter    else
88318334Speter      note_link = &XEXP (this, 1);
88418334Speter
88518334Speter  abort ();
88618334Speter}
88718334Speter
88818334Speter/* Find the hard register number of virtual register REG in REGSTACK.
88918334Speter   The hard register number is relative to the top of the stack.  -1 is
89050397Sobrien   returned if the register is not found.  */
89118334Speter
89218334Speterstatic int
89318334Speterget_hard_regnum (regstack, reg)
89418334Speter     stack regstack;
89518334Speter     rtx reg;
89618334Speter{
89718334Speter  int i;
89818334Speter
89918334Speter  if (! STACK_REG_P (reg))
90018334Speter    abort ();
90118334Speter
90218334Speter  for (i = regstack->top; i >= 0; i--)
90318334Speter    if (regstack->reg[i] == REGNO (reg))
90418334Speter      break;
90518334Speter
90618334Speter  return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
90718334Speter}
90818334Speter
90918334Speter/* Emit an insn to pop virtual register REG before or after INSN.
91018334Speter   REGSTACK is the stack state after INSN and is updated to reflect this
91190075Sobrien   pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
91290075Sobrien   is represented as a SET whose destination is the register to be popped
91390075Sobrien   and source is the top of stack.  A death note for the top of stack
91450397Sobrien   cases the movdf pattern to pop.  */
91518334Speter
91618334Speterstatic rtx
91790075Sobrienemit_pop_insn (insn, regstack, reg, where)
91818334Speter     rtx insn;
91918334Speter     stack regstack;
92018334Speter     rtx reg;
92190075Sobrien     enum emit_where where;
92218334Speter{
92318334Speter  rtx pop_insn, pop_rtx;
92418334Speter  int hard_regno;
92518334Speter
92690075Sobrien  /* For complex types take care to pop both halves.  These may survive in
92790075Sobrien     CLOBBER and USE expressions.  */
92890075Sobrien  if (COMPLEX_MODE_P (GET_MODE (reg)))
92990075Sobrien    {
93090075Sobrien      rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode);
93190075Sobrien      rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode);
93290075Sobrien
93390075Sobrien      pop_insn = NULL_RTX;
93490075Sobrien      if (get_hard_regnum (regstack, reg1) >= 0)
93590075Sobrien         pop_insn = emit_pop_insn (insn, regstack, reg1, where);
93690075Sobrien      if (get_hard_regnum (regstack, reg2) >= 0)
93790075Sobrien         pop_insn = emit_pop_insn (insn, regstack, reg2, where);
93890075Sobrien      if (!pop_insn)
93990075Sobrien	abort ();
94090075Sobrien      return pop_insn;
94190075Sobrien    }
94290075Sobrien
94318334Speter  hard_regno = get_hard_regnum (regstack, reg);
94418334Speter
94518334Speter  if (hard_regno < FIRST_STACK_REG)
94618334Speter    abort ();
94718334Speter
94890075Sobrien  pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode),
94990075Sobrien			 FP_MODE_REG (FIRST_STACK_REG, DFmode));
95018334Speter
95190075Sobrien  if (where == EMIT_AFTER)
95290075Sobrien    pop_insn = emit_insn_after (pop_rtx, insn);
95390075Sobrien  else
95490075Sobrien    pop_insn = emit_insn_before (pop_rtx, insn);
95518334Speter
95690075Sobrien  REG_NOTES (pop_insn)
95790075Sobrien    = gen_rtx_EXPR_LIST (REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode),
95890075Sobrien			 REG_NOTES (pop_insn));
95918334Speter
96018334Speter  regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
96118334Speter    = regstack->reg[regstack->top];
96218334Speter  regstack->top -= 1;
96318334Speter  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));
96418334Speter
96518334Speter  return pop_insn;
96618334Speter}
96718334Speter
96890075Sobrien/* Emit an insn before or after INSN to swap virtual register REG with
96990075Sobrien   the top of stack.  REGSTACK is the stack state before the swap, and
97090075Sobrien   is updated to reflect the swap.  A swap insn is represented as a
97190075Sobrien   PARALLEL of two patterns: each pattern moves one reg to the other.
97218334Speter
97350397Sobrien   If REG is already at the top of the stack, no insn is emitted.  */
97418334Speter
97518334Speterstatic void
97618334Speteremit_swap_insn (insn, regstack, reg)
97718334Speter     rtx insn;
97818334Speter     stack regstack;
97918334Speter     rtx reg;
98018334Speter{
98118334Speter  int hard_regno;
98290075Sobrien  rtx swap_rtx;
98318334Speter  int tmp, other_reg;		/* swap regno temps */
98418334Speter  rtx i1;			/* the stack-reg insn prior to INSN */
98518334Speter  rtx i1set = NULL_RTX;		/* the SET rtx within I1 */
98618334Speter
98718334Speter  hard_regno = get_hard_regnum (regstack, reg);
98818334Speter
98918334Speter  if (hard_regno < FIRST_STACK_REG)
99018334Speter    abort ();
99118334Speter  if (hard_regno == FIRST_STACK_REG)
99218334Speter    return;
99318334Speter
99418334Speter  other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);
99518334Speter
99618334Speter  tmp = regstack->reg[other_reg];
99718334Speter  regstack->reg[other_reg] = regstack->reg[regstack->top];
99818334Speter  regstack->reg[regstack->top] = tmp;
99918334Speter
100090075Sobrien  /* Find the previous insn involving stack regs, but don't pass a
100190075Sobrien     block boundary.  */
100290075Sobrien  i1 = NULL;
100390075Sobrien  if (current_block && insn != current_block->head)
100490075Sobrien    {
100590075Sobrien      rtx tmp = PREV_INSN (insn);
100690075Sobrien      rtx limit = PREV_INSN (current_block->head);
100790075Sobrien      while (tmp != limit)
100890075Sobrien	{
100990075Sobrien	  if (GET_CODE (tmp) == CODE_LABEL
101090075Sobrien	      || GET_CODE (tmp) == CALL_INSN
101190075Sobrien	      || NOTE_INSN_BASIC_BLOCK_P (tmp)
101290075Sobrien	      || (GET_CODE (tmp) == INSN
101390075Sobrien		  && stack_regs_mentioned (tmp)))
101490075Sobrien	    {
101590075Sobrien	      i1 = tmp;
101690075Sobrien	      break;
101790075Sobrien	    }
101890075Sobrien	  tmp = PREV_INSN (tmp);
101990075Sobrien	}
102090075Sobrien    }
102118334Speter
102290075Sobrien  if (i1 != NULL_RTX
102390075Sobrien      && (i1set = single_set (i1)) != NULL_RTX)
102418334Speter    {
102518334Speter      rtx i1src = *get_true_reg (&SET_SRC (i1set));
102618334Speter      rtx i1dest = *get_true_reg (&SET_DEST (i1set));
102718334Speter
102818334Speter      /* If the previous register stack push was from the reg we are to
102950397Sobrien	 swap with, omit the swap.  */
103018334Speter
103118334Speter      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG
103290075Sobrien	  && GET_CODE (i1src) == REG
103390075Sobrien	  && REGNO (i1src) == (unsigned) hard_regno - 1
103418334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
103518334Speter	return;
103618334Speter
103718334Speter      /* If the previous insn wrote to the reg we are to swap with,
103818334Speter	 omit the swap.  */
103918334Speter
104090075Sobrien      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == (unsigned) hard_regno
104118334Speter	  && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG
104218334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
104318334Speter	return;
104418334Speter    }
104518334Speter
104690075Sobrien  swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode),
104790075Sobrien			 FP_MODE_REG (FIRST_STACK_REG, XFmode));
104818334Speter
104990075Sobrien  if (i1)
105090075Sobrien    emit_insn_after (swap_rtx, i1);
105190075Sobrien  else if (current_block)
105290075Sobrien    emit_insn_before (swap_rtx, current_block->head);
105390075Sobrien  else
105490075Sobrien    emit_insn_before (swap_rtx, insn);
105518334Speter}
105618334Speter
105718334Speter/* Handle a move to or from a stack register in PAT, which is in INSN.
105850397Sobrien   REGSTACK is the current stack.  */
105918334Speter
106018334Speterstatic void
106118334Spetermove_for_stack_reg (insn, regstack, pat)
106218334Speter     rtx insn;
106318334Speter     stack regstack;
106418334Speter     rtx pat;
106518334Speter{
106618334Speter  rtx *psrc =  get_true_reg (&SET_SRC (pat));
106718334Speter  rtx *pdest = get_true_reg (&SET_DEST (pat));
106818334Speter  rtx src, dest;
106918334Speter  rtx note;
107018334Speter
107118334Speter  src = *psrc; dest = *pdest;
107218334Speter
107318334Speter  if (STACK_REG_P (src) && STACK_REG_P (dest))
107418334Speter    {
107518334Speter      /* Write from one stack reg to another.  If SRC dies here, then
107650397Sobrien	 just change the register mapping and delete the insn.  */
107718334Speter
107818334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
107918334Speter      if (note)
108018334Speter	{
108118334Speter	  int i;
108218334Speter
108350397Sobrien	  /* If this is a no-op move, there must not be a REG_DEAD note.  */
108418334Speter	  if (REGNO (src) == REGNO (dest))
108518334Speter	    abort ();
108618334Speter
108718334Speter	  for (i = regstack->top; i >= 0; i--)
108818334Speter	    if (regstack->reg[i] == REGNO (src))
108918334Speter	      break;
109018334Speter
109150397Sobrien	  /* The source must be live, and the dest must be dead.  */
109218334Speter	  if (i < 0 || get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
109318334Speter	    abort ();
109418334Speter
109518334Speter	  /* It is possible that the dest is unused after this insn.
109650397Sobrien	     If so, just pop the src.  */
109718334Speter
109818334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
109918334Speter	    {
110090075Sobrien	      emit_pop_insn (insn, regstack, src, EMIT_AFTER);
110118334Speter
110290075Sobrien	      delete_insn (insn);
110318334Speter	      return;
110418334Speter	    }
110518334Speter
110618334Speter	  regstack->reg[i] = REGNO (dest);
110718334Speter
110818334Speter	  SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
110918334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
111018334Speter
111190075Sobrien	  delete_insn (insn);
111218334Speter
111318334Speter	  return;
111418334Speter	}
111518334Speter
111650397Sobrien      /* The source reg does not die.  */
111718334Speter
111818334Speter      /* If this appears to be a no-op move, delete it, or else it
111918334Speter	 will confuse the machine description output patterns. But if
112018334Speter	 it is REG_UNUSED, we must pop the reg now, as per-insn processing
112150397Sobrien	 for REG_UNUSED will not work for deleted insns.  */
112218334Speter
112318334Speter      if (REGNO (src) == REGNO (dest))
112418334Speter	{
112518334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
112690075Sobrien	    emit_pop_insn (insn, regstack, dest, EMIT_AFTER);
112718334Speter
112890075Sobrien	  delete_insn (insn);
112918334Speter	  return;
113018334Speter	}
113118334Speter
113218334Speter      /* The destination ought to be dead */
113318334Speter      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
113418334Speter	abort ();
113518334Speter
113618334Speter      replace_reg (psrc, get_hard_regnum (regstack, src));
113718334Speter
113818334Speter      regstack->reg[++regstack->top] = REGNO (dest);
113918334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
114018334Speter      replace_reg (pdest, FIRST_STACK_REG);
114118334Speter    }
114218334Speter  else if (STACK_REG_P (src))
114318334Speter    {
114418334Speter      /* Save from a stack reg to MEM, or possibly integer reg.  Since
114518334Speter	 only top of stack may be saved, emit an exchange first if
114650397Sobrien	 needs be.  */
114718334Speter
114818334Speter      emit_swap_insn (insn, regstack, src);
114918334Speter
115018334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
115118334Speter      if (note)
115218334Speter	{
115318334Speter	  replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
115418334Speter	  regstack->top--;
115518334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
115618334Speter	}
115790075Sobrien      else if ((GET_MODE (src) == XFmode || GET_MODE (src) == TFmode)
115890075Sobrien	       && regstack->top < REG_STACK_SIZE - 1)
115918334Speter	{
116018334Speter	  /* A 387 cannot write an XFmode value to a MEM without
116118334Speter	     clobbering the source reg.  The output code can handle
116218334Speter	     this by reading back the value from the MEM.
116318334Speter	     But it is more efficient to use a temp register if one is
116418334Speter	     available.  Push the source value here if the register
116518334Speter	     stack is not full, and then write the value to memory via
116618334Speter	     a pop.  */
116718334Speter	  rtx push_rtx, push_insn;
116890075Sobrien	  rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src));
116918334Speter
117090075Sobrien	  if (GET_MODE (src) == TFmode)
117190075Sobrien	    push_rtx = gen_movtf (top_stack_reg, top_stack_reg);
117290075Sobrien	  else
117390075Sobrien	    push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
117418334Speter	  push_insn = emit_insn_before (push_rtx, insn);
117550397Sobrien	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg,
117650397Sobrien						REG_NOTES (insn));
117718334Speter	}
117818334Speter
117918334Speter      replace_reg (psrc, FIRST_STACK_REG);
118018334Speter    }
118118334Speter  else if (STACK_REG_P (dest))
118218334Speter    {
118318334Speter      /* Load from MEM, or possibly integer REG or constant, into the
118418334Speter	 stack regs.  The actual target is always the top of the
118518334Speter	 stack. The stack mapping is changed to reflect that DEST is
118618334Speter	 now at top of stack.  */
118718334Speter
118818334Speter      /* The destination ought to be dead */
118918334Speter      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
119018334Speter	abort ();
119118334Speter
119218334Speter      if (regstack->top >= REG_STACK_SIZE)
119318334Speter	abort ();
119418334Speter
119518334Speter      regstack->reg[++regstack->top] = REGNO (dest);
119618334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
119718334Speter      replace_reg (pdest, FIRST_STACK_REG);
119818334Speter    }
119918334Speter  else
120018334Speter    abort ();
120118334Speter}
120218334Speter
120390075Sobrien/* Swap the condition on a branch, if there is one.  Return true if we
120490075Sobrien   found a condition to swap.  False if the condition was not used as
120590075Sobrien   such.  */
120690075Sobrien
120790075Sobrienstatic int
120890075Sobrienswap_rtx_condition_1 (pat)
120918334Speter     rtx pat;
121018334Speter{
121190075Sobrien  const char *fmt;
121290075Sobrien  int i, r = 0;
121318334Speter
121418334Speter  if (GET_RTX_CLASS (GET_CODE (pat)) == '<')
121518334Speter    {
121618334Speter      PUT_CODE (pat, swap_condition (GET_CODE (pat)));
121790075Sobrien      r = 1;
121818334Speter    }
121990075Sobrien  else
122090075Sobrien    {
122190075Sobrien      fmt = GET_RTX_FORMAT (GET_CODE (pat));
122290075Sobrien      for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
122390075Sobrien	{
122490075Sobrien	  if (fmt[i] == 'E')
122590075Sobrien	    {
122690075Sobrien	      int j;
122718334Speter
122890075Sobrien	      for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
122990075Sobrien		r |= swap_rtx_condition_1 (XVECEXP (pat, i, j));
123090075Sobrien	    }
123190075Sobrien	  else if (fmt[i] == 'e')
123290075Sobrien	    r |= swap_rtx_condition_1 (XEXP (pat, i));
123390075Sobrien	}
123490075Sobrien    }
123590075Sobrien
123690075Sobrien  return r;
123790075Sobrien}
123890075Sobrien
123990075Sobrienstatic int
124090075Sobrienswap_rtx_condition (insn)
124190075Sobrien     rtx insn;
124290075Sobrien{
124390075Sobrien  rtx pat = PATTERN (insn);
124490075Sobrien
124590075Sobrien  /* We're looking for a single set to cc0 or an HImode temporary.  */
124690075Sobrien
124790075Sobrien  if (GET_CODE (pat) == SET
124890075Sobrien      && GET_CODE (SET_DEST (pat)) == REG
124990075Sobrien      && REGNO (SET_DEST (pat)) == FLAGS_REG)
125018334Speter    {
125190075Sobrien      insn = next_flags_user (insn);
125290075Sobrien      if (insn == NULL_RTX)
125390075Sobrien	return 0;
125490075Sobrien      pat = PATTERN (insn);
125590075Sobrien    }
125690075Sobrien
125790075Sobrien  /* See if this is, or ends in, a fnstsw, aka unspec 9.  If so, we're
125890075Sobrien     not doing anything with the cc value right now.  We may be able to
125990075Sobrien     search for one though.  */
126090075Sobrien
126190075Sobrien  if (GET_CODE (pat) == SET
126290075Sobrien      && GET_CODE (SET_SRC (pat)) == UNSPEC
126390075Sobrien      && XINT (SET_SRC (pat), 1) == 9)
126490075Sobrien    {
126590075Sobrien      rtx dest = SET_DEST (pat);
126690075Sobrien
126790075Sobrien      /* Search forward looking for the first use of this value.
126890075Sobrien	 Stop at block boundaries.  */
126990075Sobrien      while (insn != current_block->end)
127018334Speter	{
127190075Sobrien	  insn = NEXT_INSN (insn);
127290075Sobrien	  if (INSN_P (insn) && reg_mentioned_p (dest, insn))
127390075Sobrien	    break;
127490075Sobrien	  if (GET_CODE (insn) == CALL_INSN)
127590075Sobrien	    return 0;
127690075Sobrien	}
127718334Speter
127890075Sobrien      /* So we've found the insn using this value.  If it is anything
127990075Sobrien	 other than sahf, aka unspec 10, or the value does not die
128090075Sobrien	 (meaning we'd have to search further), then we must give up.  */
128190075Sobrien      pat = PATTERN (insn);
128290075Sobrien      if (GET_CODE (pat) != SET
128390075Sobrien	  || GET_CODE (SET_SRC (pat)) != UNSPEC
128490075Sobrien	  || XINT (SET_SRC (pat), 1) != 10
128590075Sobrien	  || ! dead_or_set_p (insn, dest))
128690075Sobrien	return 0;
128790075Sobrien
128890075Sobrien      /* Now we are prepared to handle this as a normal cc0 setter.  */
128990075Sobrien      insn = next_flags_user (insn);
129090075Sobrien      if (insn == NULL_RTX)
129190075Sobrien	return 0;
129290075Sobrien      pat = PATTERN (insn);
129390075Sobrien    }
129490075Sobrien
129590075Sobrien  if (swap_rtx_condition_1 (pat))
129690075Sobrien    {
129790075Sobrien      int fail = 0;
129890075Sobrien      INSN_CODE (insn) = -1;
129990075Sobrien      if (recog_memoized (insn) == -1)
130090075Sobrien	fail = 1;
130190075Sobrien      /* In case the flags don't die here, recurse to try fix
130290075Sobrien         following user too.  */
130390075Sobrien      else if (! dead_or_set_p (insn, ix86_flags_rtx))
130490075Sobrien	{
130590075Sobrien	  insn = next_flags_user (insn);
130690075Sobrien	  if (!insn || !swap_rtx_condition (insn))
130790075Sobrien	    fail = 1;
130818334Speter	}
130990075Sobrien      if (fail)
131090075Sobrien	{
131190075Sobrien	  swap_rtx_condition_1 (pat);
131290075Sobrien	  return 0;
131390075Sobrien	}
131490075Sobrien      return 1;
131518334Speter    }
131690075Sobrien  return 0;
131718334Speter}
131818334Speter
131918334Speter/* Handle a comparison.  Special care needs to be taken to avoid
132018334Speter   causing comparisons that a 387 cannot do correctly, such as EQ.
132118334Speter
132290075Sobrien   Also, a pop insn may need to be emitted.  The 387 does have an
132318334Speter   `fcompp' insn that can pop two regs, but it is sometimes too expensive
132418334Speter   to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
132590075Sobrien   set up.  */
132618334Speter
132718334Speterstatic void
132890075Sobriencompare_for_stack_reg (insn, regstack, pat_src)
132918334Speter     rtx insn;
133018334Speter     stack regstack;
133190075Sobrien     rtx pat_src;
133218334Speter{
133318334Speter  rtx *src1, *src2;
133418334Speter  rtx src1_note, src2_note;
133590075Sobrien  rtx flags_user;
133618334Speter
133790075Sobrien  src1 = get_true_reg (&XEXP (pat_src, 0));
133890075Sobrien  src2 = get_true_reg (&XEXP (pat_src, 1));
133990075Sobrien  flags_user = next_flags_user (insn);
134018334Speter
134118334Speter  /* ??? If fxch turns out to be cheaper than fstp, give priority to
134250397Sobrien     registers that die in this insn - move those to stack top first.  */
134390075Sobrien  if ((! STACK_REG_P (*src1)
134490075Sobrien       || (STACK_REG_P (*src2)
134590075Sobrien	   && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
134690075Sobrien      && swap_rtx_condition (insn))
134718334Speter    {
134890075Sobrien      rtx temp;
134990075Sobrien      temp = XEXP (pat_src, 0);
135090075Sobrien      XEXP (pat_src, 0) = XEXP (pat_src, 1);
135190075Sobrien      XEXP (pat_src, 1) = temp;
135218334Speter
135390075Sobrien      src1 = get_true_reg (&XEXP (pat_src, 0));
135490075Sobrien      src2 = get_true_reg (&XEXP (pat_src, 1));
135518334Speter
135618334Speter      INSN_CODE (insn) = -1;
135718334Speter    }
135818334Speter
135950397Sobrien  /* We will fix any death note later.  */
136018334Speter
136118334Speter  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
136218334Speter
136318334Speter  if (STACK_REG_P (*src2))
136418334Speter    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
136518334Speter  else
136618334Speter    src2_note = NULL_RTX;
136718334Speter
136890075Sobrien  emit_swap_insn (insn, regstack, *src1);
136918334Speter
137018334Speter  replace_reg (src1, FIRST_STACK_REG);
137118334Speter
137218334Speter  if (STACK_REG_P (*src2))
137390075Sobrien    replace_reg (src2, get_hard_regnum (regstack, *src2));
137418334Speter
137518334Speter  if (src1_note)
137618334Speter    {
137750397Sobrien      pop_stack (regstack, REGNO (XEXP (src1_note, 0)));
137818334Speter      replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
137918334Speter    }
138018334Speter
138118334Speter  /* If the second operand dies, handle that.  But if the operands are
138218334Speter     the same stack register, don't bother, because only one death is
138350397Sobrien     needed, and it was just handled.  */
138418334Speter
138518334Speter  if (src2_note
138618334Speter      && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
138718334Speter	    && REGNO (*src1) == REGNO (*src2)))
138818334Speter    {
138918334Speter      /* As a special case, two regs may die in this insn if src2 is
139018334Speter	 next to top of stack and the top of stack also dies.  Since
139118334Speter	 we have already popped src1, "next to top of stack" is really
139250397Sobrien	 at top (FIRST_STACK_REG) now.  */
139318334Speter
139418334Speter      if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
139518334Speter	  && src1_note)
139618334Speter	{
139750397Sobrien	  pop_stack (regstack, REGNO (XEXP (src2_note, 0)));
139818334Speter	  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
139918334Speter	}
140018334Speter      else
140118334Speter	{
140290075Sobrien	  /* The 386 can only represent death of the first operand in
140390075Sobrien	     the case handled above.  In all other cases, emit a separate
140490075Sobrien	     pop and remove the death note from here.  */
140518334Speter
140690075Sobrien	  /* link_cc0_insns (insn); */
140790075Sobrien
140890075Sobrien	  remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
140990075Sobrien
141090075Sobrien	  emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
141190075Sobrien			 EMIT_AFTER);
141218334Speter	}
141318334Speter    }
141418334Speter}
141518334Speter
141618334Speter/* Substitute new registers in PAT, which is part of INSN.  REGSTACK
141750397Sobrien   is the current register layout.  */
141818334Speter
141918334Speterstatic void
142018334Spetersubst_stack_regs_pat (insn, regstack, pat)
142118334Speter     rtx insn;
142218334Speter     stack regstack;
142318334Speter     rtx pat;
142418334Speter{
142518334Speter  rtx *dest, *src;
142618334Speter
142790075Sobrien  switch (GET_CODE (pat))
142890075Sobrien    {
142990075Sobrien    case USE:
143090075Sobrien      /* Deaths in USE insns can happen in non optimizing compilation.
143190075Sobrien	 Handle them by popping the dying register.  */
143290075Sobrien      src = get_true_reg (&XEXP (pat, 0));
143390075Sobrien      if (STACK_REG_P (*src)
143490075Sobrien          && find_regno_note (insn, REG_DEAD, REGNO (*src)))
143590075Sobrien        {
143690075Sobrien	   emit_pop_insn (insn, regstack, *src, EMIT_AFTER);
143790075Sobrien	   return;
143890075Sobrien        }
143990075Sobrien      /* ??? Uninitialized USE should not happen.  */
144090075Sobrien      else if (get_hard_regnum (regstack, *src) == -1)
144190075Sobrien	abort ();
144290075Sobrien      break;
144318334Speter
144490075Sobrien    case CLOBBER:
144590075Sobrien      {
144690075Sobrien	rtx note;
144718334Speter
144890075Sobrien	dest = get_true_reg (&XEXP (pat, 0));
144990075Sobrien	if (STACK_REG_P (*dest))
145090075Sobrien	  {
145190075Sobrien	    note = find_reg_note (insn, REG_DEAD, *dest);
145218334Speter
145390075Sobrien	    if (pat != PATTERN (insn))
145490075Sobrien	      {
145590075Sobrien		/* The fix_truncdi_1 pattern wants to be able to allocate
145690075Sobrien		   it's own scratch register.  It does this by clobbering
145790075Sobrien		   an fp reg so that it is assured of an empty reg-stack
145890075Sobrien		   register.  If the register is live, kill it now.
145990075Sobrien		   Remove the DEAD/UNUSED note so we don't try to kill it
146090075Sobrien		   later too.  */
146190075Sobrien
146290075Sobrien		if (note)
146390075Sobrien		  emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
146490075Sobrien		else
146590075Sobrien		  {
146690075Sobrien		    note = find_reg_note (insn, REG_UNUSED, *dest);
146790075Sobrien		    if (!note)
146890075Sobrien		      abort ();
146990075Sobrien		  }
147090075Sobrien		remove_note (insn, note);
147190075Sobrien		replace_reg (dest, LAST_STACK_REG);
147290075Sobrien	      }
147390075Sobrien	    else
147490075Sobrien	      {
147590075Sobrien		/* A top-level clobber with no REG_DEAD, and no hard-regnum
147690075Sobrien		   indicates an uninitialized value.  Because reload removed
147790075Sobrien		   all other clobbers, this must be due to a function
147890075Sobrien		   returning without a value.  Load up a NaN.  */
147990075Sobrien
148090075Sobrien		if (! note
148190075Sobrien		    && get_hard_regnum (regstack, *dest) == -1)
148290075Sobrien		  {
148390075Sobrien		    pat = gen_rtx_SET (VOIDmode,
148490075Sobrien				       FP_MODE_REG (REGNO (*dest), SFmode),
148590075Sobrien				       nan);
148690075Sobrien		    PATTERN (insn) = pat;
148790075Sobrien		    move_for_stack_reg (insn, regstack, pat);
148890075Sobrien		  }
148990075Sobrien		if (! note && COMPLEX_MODE_P (GET_MODE (*dest))
149090075Sobrien		    && get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest), DFmode)) == -1)
149190075Sobrien		  {
149290075Sobrien		    pat = gen_rtx_SET (VOIDmode,
149390075Sobrien				       FP_MODE_REG (REGNO (*dest) + 1, SFmode),
149490075Sobrien				       nan);
149590075Sobrien		    PATTERN (insn) = pat;
149690075Sobrien		    move_for_stack_reg (insn, regstack, pat);
149790075Sobrien		  }
149890075Sobrien	      }
149990075Sobrien	  }
150018334Speter	break;
150190075Sobrien      }
150218334Speter
150390075Sobrien    case SET:
150490075Sobrien      {
150590075Sobrien	rtx *src1 = (rtx *) 0, *src2;
150690075Sobrien	rtx src1_note, src2_note;
150790075Sobrien	rtx pat_src;
150890075Sobrien
150990075Sobrien	dest = get_true_reg (&SET_DEST (pat));
151090075Sobrien	src  = get_true_reg (&SET_SRC (pat));
151190075Sobrien	pat_src = SET_SRC (pat);
151290075Sobrien
151390075Sobrien	/* See if this is a `movM' pattern, and handle elsewhere if so.  */
151490075Sobrien	if (STACK_REG_P (*src)
151590075Sobrien	    || (STACK_REG_P (*dest)
151690075Sobrien		&& (GET_CODE (*src) == REG || GET_CODE (*src) == MEM
151790075Sobrien		    || GET_CODE (*src) == CONST_DOUBLE)))
151890075Sobrien	  {
151990075Sobrien	    move_for_stack_reg (insn, regstack, pat);
152090075Sobrien	    break;
152190075Sobrien	  }
152290075Sobrien
152390075Sobrien	switch (GET_CODE (pat_src))
152490075Sobrien	  {
152590075Sobrien	  case COMPARE:
152690075Sobrien	    compare_for_stack_reg (insn, regstack, pat_src);
152790075Sobrien	    break;
152890075Sobrien
152990075Sobrien	  case CALL:
153018334Speter	    {
153190075Sobrien	      int count;
153290075Sobrien	      for (count = HARD_REGNO_NREGS (REGNO (*dest), GET_MODE (*dest));
153390075Sobrien		   --count >= 0;)
153490075Sobrien		{
153590075Sobrien		  regstack->reg[++regstack->top] = REGNO (*dest) + count;
153690075Sobrien		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count);
153790075Sobrien		}
153818334Speter	    }
153990075Sobrien	    replace_reg (dest, FIRST_STACK_REG);
154090075Sobrien	    break;
154118334Speter
154290075Sobrien	  case REG:
154390075Sobrien	    /* This is a `tstM2' case.  */
154490075Sobrien	    if (*dest != cc0_rtx)
154590075Sobrien	      abort ();
154690075Sobrien	    src1 = src;
154718334Speter
154890075Sobrien	    /* Fall through.  */
154918334Speter
155090075Sobrien	  case FLOAT_TRUNCATE:
155190075Sobrien	  case SQRT:
155290075Sobrien	  case ABS:
155390075Sobrien	  case NEG:
155490075Sobrien	    /* These insns only operate on the top of the stack. DEST might
155590075Sobrien	       be cc0_rtx if we're processing a tstM pattern. Also, it's
155690075Sobrien	       possible that the tstM case results in a REG_DEAD note on the
155790075Sobrien	       source.  */
155818334Speter
155990075Sobrien	    if (src1 == 0)
156090075Sobrien	      src1 = get_true_reg (&XEXP (pat_src, 0));
156118334Speter
156290075Sobrien	    emit_swap_insn (insn, regstack, *src1);
156318334Speter
156490075Sobrien	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
156518334Speter
156690075Sobrien	    if (STACK_REG_P (*dest))
156790075Sobrien	      replace_reg (dest, FIRST_STACK_REG);
156818334Speter
156990075Sobrien	    if (src1_note)
157090075Sobrien	      {
157190075Sobrien		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
157290075Sobrien		regstack->top--;
157390075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
157490075Sobrien	      }
157518334Speter
157690075Sobrien	    replace_reg (src1, FIRST_STACK_REG);
157790075Sobrien	    break;
157818334Speter
157990075Sobrien	  case MINUS:
158090075Sobrien	  case DIV:
158190075Sobrien	    /* On i386, reversed forms of subM3 and divM3 exist for
158290075Sobrien	       MODE_FLOAT, so the same code that works for addM3 and mulM3
158390075Sobrien	       can be used.  */
158490075Sobrien	  case MULT:
158590075Sobrien	  case PLUS:
158690075Sobrien	    /* These insns can accept the top of stack as a destination
158790075Sobrien	       from a stack reg or mem, or can use the top of stack as a
158890075Sobrien	       source and some other stack register (possibly top of stack)
158990075Sobrien	       as a destination.  */
159018334Speter
159190075Sobrien	    src1 = get_true_reg (&XEXP (pat_src, 0));
159290075Sobrien	    src2 = get_true_reg (&XEXP (pat_src, 1));
159318334Speter
159490075Sobrien	    /* We will fix any death note later.  */
159518334Speter
159690075Sobrien	    if (STACK_REG_P (*src1))
159790075Sobrien	      src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
159890075Sobrien	    else
159990075Sobrien	      src1_note = NULL_RTX;
160090075Sobrien	    if (STACK_REG_P (*src2))
160190075Sobrien	      src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
160290075Sobrien	    else
160390075Sobrien	      src2_note = NULL_RTX;
160418334Speter
160590075Sobrien	    /* If either operand is not a stack register, then the dest
160690075Sobrien	       must be top of stack.  */
160718334Speter
160890075Sobrien	    if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
160990075Sobrien	      emit_swap_insn (insn, regstack, *dest);
161090075Sobrien	    else
161190075Sobrien	      {
161290075Sobrien		/* Both operands are REG.  If neither operand is already
161390075Sobrien		   at the top of stack, choose to make the one that is the dest
161490075Sobrien		   the new top of stack.  */
161518334Speter
161690075Sobrien		int src1_hard_regnum, src2_hard_regnum;
161718334Speter
161890075Sobrien		src1_hard_regnum = get_hard_regnum (regstack, *src1);
161990075Sobrien		src2_hard_regnum = get_hard_regnum (regstack, *src2);
162090075Sobrien		if (src1_hard_regnum == -1 || src2_hard_regnum == -1)
162190075Sobrien		  abort ();
162218334Speter
162390075Sobrien		if (src1_hard_regnum != FIRST_STACK_REG
162490075Sobrien		    && src2_hard_regnum != FIRST_STACK_REG)
162590075Sobrien		  emit_swap_insn (insn, regstack, *dest);
162690075Sobrien	      }
162718334Speter
162890075Sobrien	    if (STACK_REG_P (*src1))
162990075Sobrien	      replace_reg (src1, get_hard_regnum (regstack, *src1));
163090075Sobrien	    if (STACK_REG_P (*src2))
163190075Sobrien	      replace_reg (src2, get_hard_regnum (regstack, *src2));
163218334Speter
163390075Sobrien	    if (src1_note)
163490075Sobrien	      {
163590075Sobrien		rtx src1_reg = XEXP (src1_note, 0);
163618334Speter
163790075Sobrien		/* If the register that dies is at the top of stack, then
163890075Sobrien		   the destination is somewhere else - merely substitute it.
163990075Sobrien		   But if the reg that dies is not at top of stack, then
164090075Sobrien		   move the top of stack to the dead reg, as though we had
164190075Sobrien		   done the insn and then a store-with-pop.  */
164218334Speter
164390075Sobrien		if (REGNO (src1_reg) == regstack->reg[regstack->top])
164490075Sobrien		  {
164590075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
164690075Sobrien		    replace_reg (dest, get_hard_regnum (regstack, *dest));
164790075Sobrien		  }
164890075Sobrien		else
164990075Sobrien		  {
165090075Sobrien		    int regno = get_hard_regnum (regstack, src1_reg);
165118334Speter
165290075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
165390075Sobrien		    replace_reg (dest, regno);
165490075Sobrien
165590075Sobrien		    regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
165690075Sobrien		      = regstack->reg[regstack->top];
165790075Sobrien		  }
165890075Sobrien
165990075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set,
166090075Sobrien				    REGNO (XEXP (src1_note, 0)));
166190075Sobrien		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
166290075Sobrien		regstack->top--;
166318334Speter	      }
166490075Sobrien	    else if (src2_note)
166518334Speter	      {
166690075Sobrien		rtx src2_reg = XEXP (src2_note, 0);
166790075Sobrien		if (REGNO (src2_reg) == regstack->reg[regstack->top])
166890075Sobrien		  {
166990075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
167090075Sobrien		    replace_reg (dest, get_hard_regnum (regstack, *dest));
167190075Sobrien		  }
167290075Sobrien		else
167390075Sobrien		  {
167490075Sobrien		    int regno = get_hard_regnum (regstack, src2_reg);
167518334Speter
167690075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
167790075Sobrien		    replace_reg (dest, regno);
167818334Speter
167990075Sobrien		    regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
168090075Sobrien		      = regstack->reg[regstack->top];
168190075Sobrien		  }
168290075Sobrien
168390075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set,
168490075Sobrien				    REGNO (XEXP (src2_note, 0)));
168590075Sobrien		replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
168690075Sobrien		regstack->top--;
168718334Speter	      }
168890075Sobrien	    else
168918334Speter	      {
169018334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
169118334Speter		replace_reg (dest, get_hard_regnum (regstack, *dest));
169218334Speter	      }
169390075Sobrien
169490075Sobrien	    /* Keep operand 1 maching with destination.  */
169590075Sobrien	    if (GET_RTX_CLASS (GET_CODE (pat_src)) == 'c'
169690075Sobrien		&& REG_P (*src1) && REG_P (*src2)
169790075Sobrien		&& REGNO (*src1) != REGNO (*dest))
169890075Sobrien	     {
169990075Sobrien		int tmp = REGNO (*src1);
170090075Sobrien		replace_reg (src1, REGNO (*src2));
170190075Sobrien		replace_reg (src2, tmp);
170290075Sobrien	     }
170390075Sobrien	    break;
170490075Sobrien
170590075Sobrien	  case UNSPEC:
170690075Sobrien	    switch (XINT (pat_src, 1))
170718334Speter	      {
170890075Sobrien	      case 1: /* sin */
170990075Sobrien	      case 2: /* cos */
171090075Sobrien		/* These insns only operate on the top of the stack.  */
171118334Speter
171290075Sobrien		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
171318334Speter
171490075Sobrien		emit_swap_insn (insn, regstack, *src1);
171518334Speter
171690075Sobrien		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
171718334Speter
171890075Sobrien		if (STACK_REG_P (*dest))
171990075Sobrien		  replace_reg (dest, FIRST_STACK_REG);
172018334Speter
172190075Sobrien		if (src1_note)
172290075Sobrien		  {
172390075Sobrien		    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
172490075Sobrien		    regstack->top--;
172590075Sobrien		    CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
172690075Sobrien		  }
172718334Speter
172890075Sobrien		replace_reg (src1, FIRST_STACK_REG);
172990075Sobrien		break;
173018334Speter
173190075Sobrien	      case 10:
173290075Sobrien		/* (unspec [(unspec [(compare ..)] 9)] 10)
173390075Sobrien		   Unspec 9 is fnstsw; unspec 10 is sahf.  The combination
173490075Sobrien		   matches the PPRO fcomi instruction.  */
173518334Speter
173690075Sobrien		pat_src = XVECEXP (pat_src, 0, 0);
173790075Sobrien		if (GET_CODE (pat_src) != UNSPEC
173890075Sobrien		    || XINT (pat_src, 1) != 9)
173990075Sobrien		  abort ();
174090075Sobrien		/* FALLTHRU */
174118334Speter
174290075Sobrien	      case 9:
174390075Sobrien		/* (unspec [(compare ..)] 9) */
174490075Sobrien		/* Combined fcomp+fnstsw generated for doing well with
174590075Sobrien		   CSE.  When optimizing this would have been broken
174690075Sobrien		   up before now.  */
174718334Speter
174890075Sobrien		pat_src = XVECEXP (pat_src, 0, 0);
174990075Sobrien		if (GET_CODE (pat_src) != COMPARE)
175090075Sobrien		  abort ();
175118334Speter
175290075Sobrien		compare_for_stack_reg (insn, regstack, pat_src);
175390075Sobrien		break;
175418334Speter
175590075Sobrien	      default:
175690075Sobrien		abort ();
175790075Sobrien	      }
175818334Speter	    break;
175918334Speter
176090075Sobrien	  case IF_THEN_ELSE:
176190075Sobrien	    /* This insn requires the top of stack to be the destination.  */
176218334Speter
176390075Sobrien	    src1 = get_true_reg (&XEXP (pat_src, 1));
176490075Sobrien	    src2 = get_true_reg (&XEXP (pat_src, 2));
176550397Sobrien
176690075Sobrien	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
176790075Sobrien	    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
176850397Sobrien
176990075Sobrien	    /* If the comparison operator is an FP comparison operator,
177090075Sobrien	       it is handled correctly by compare_for_stack_reg () who
177190075Sobrien	       will move the destination to the top of stack. But if the
177290075Sobrien	       comparison operator is not an FP comparison operator, we
177390075Sobrien	       have to handle it here.  */
177490075Sobrien	    if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
177590075Sobrien		&& REGNO (*dest) != regstack->reg[regstack->top])
177690075Sobrien	      {
177790075Sobrien		/* In case one of operands is the top of stack and the operands
177890075Sobrien		   dies, it is safe to make it the destination operand by reversing
177990075Sobrien		   the direction of cmove and avoid fxch.  */
178090075Sobrien		if ((REGNO (*src1) == regstack->reg[regstack->top]
178190075Sobrien		     && src1_note)
178290075Sobrien		    || (REGNO (*src2) == regstack->reg[regstack->top]
178390075Sobrien			&& src2_note))
178490075Sobrien		  {
178590075Sobrien		    int idx1 = (get_hard_regnum (regstack, *src1)
178690075Sobrien				- FIRST_STACK_REG);
178790075Sobrien		    int idx2 = (get_hard_regnum (regstack, *src2)
178890075Sobrien				- FIRST_STACK_REG);
178950397Sobrien
179090075Sobrien		    /* Make reg-stack believe that the operands are already
179190075Sobrien		       swapped on the stack */
179290075Sobrien		    regstack->reg[regstack->top - idx1] = REGNO (*src2);
179390075Sobrien		    regstack->reg[regstack->top - idx2] = REGNO (*src1);
179450397Sobrien
179590075Sobrien		    /* Reverse condition to compensate the operand swap.
179690075Sobrien		       i386 do have comparison always reversible.  */
179790075Sobrien		    PUT_CODE (XEXP (pat_src, 0),
179890075Sobrien			      reversed_comparison_code (XEXP (pat_src, 0), insn));
179990075Sobrien		  }
180090075Sobrien		else
180190075Sobrien	          emit_swap_insn (insn, regstack, *dest);
180290075Sobrien	      }
180350397Sobrien
180490075Sobrien	    {
180590075Sobrien	      rtx src_note [3];
180690075Sobrien	      int i;
180750397Sobrien
180890075Sobrien	      src_note[0] = 0;
180990075Sobrien	      src_note[1] = src1_note;
181090075Sobrien	      src_note[2] = src2_note;
181150397Sobrien
181290075Sobrien	      if (STACK_REG_P (*src1))
181390075Sobrien		replace_reg (src1, get_hard_regnum (regstack, *src1));
181490075Sobrien	      if (STACK_REG_P (*src2))
181590075Sobrien		replace_reg (src2, get_hard_regnum (regstack, *src2));
181650397Sobrien
181790075Sobrien	      for (i = 1; i <= 2; i++)
181890075Sobrien		if (src_note [i])
181950397Sobrien		  {
182090075Sobrien		    int regno = REGNO (XEXP (src_note[i], 0));
182190075Sobrien
182290075Sobrien		    /* If the register that dies is not at the top of
182390075Sobrien		       stack, then move the top of stack to the dead reg */
182490075Sobrien		    if (regno != regstack->reg[regstack->top])
182590075Sobrien		      {
182690075Sobrien			remove_regno_note (insn, REG_DEAD, regno);
182790075Sobrien			emit_pop_insn (insn, regstack, XEXP (src_note[i], 0),
182890075Sobrien				       EMIT_AFTER);
182990075Sobrien		      }
183090075Sobrien		    else
183190075Sobrien		      /* Top of stack never dies, as it is the
183290075Sobrien			 destination.  */
183390075Sobrien		      abort ();
183450397Sobrien		  }
183590075Sobrien	    }
183650397Sobrien
183790075Sobrien	    /* Make dest the top of stack.  Add dest to regstack if
183890075Sobrien	       not present.  */
183990075Sobrien	    if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
184090075Sobrien	      regstack->reg[++regstack->top] = REGNO (*dest);
184190075Sobrien	    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
184290075Sobrien	    replace_reg (dest, FIRST_STACK_REG);
184390075Sobrien	    break;
184450397Sobrien
184590075Sobrien	  default:
184690075Sobrien	    abort ();
184790075Sobrien	  }
184850397Sobrien	break;
184990075Sobrien      }
185050397Sobrien
185190075Sobrien    default:
185290075Sobrien      break;
185390075Sobrien    }
185418334Speter}
185518334Speter
185618334Speter/* Substitute hard regnums for any stack regs in INSN, which has
185718334Speter   N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
185852284Sobrien   before the insn, and is updated with changes made here.
185918334Speter
186018334Speter   There are several requirements and assumptions about the use of
186118334Speter   stack-like regs in asm statements.  These rules are enforced by
186218334Speter   record_asm_stack_regs; see comments there for details.  Any
186318334Speter   asm_operands left in the RTL at this point may be assume to meet the
186418334Speter   requirements, since record_asm_stack_regs removes any problem asm.  */
186518334Speter
186618334Speterstatic void
186752284Sobriensubst_asm_stack_regs (insn, regstack)
186818334Speter     rtx insn;
186918334Speter     stack regstack;
187018334Speter{
187118334Speter  rtx body = PATTERN (insn);
187252284Sobrien  int alt;
187318334Speter
187418334Speter  rtx *note_reg;		/* Array of note contents */
187518334Speter  rtx **note_loc;		/* Address of REG field of each note */
187618334Speter  enum reg_note *note_kind;	/* The type of each note */
187718334Speter
187890075Sobrien  rtx *clobber_reg = 0;
187990075Sobrien  rtx **clobber_loc = 0;
188018334Speter
188118334Speter  struct stack_def temp_stack;
188218334Speter  int n_notes;
188318334Speter  int n_clobbers;
188418334Speter  rtx note;
188518334Speter  int i;
188652284Sobrien  int n_inputs, n_outputs;
188718334Speter
188890075Sobrien  if (! check_asm_stack_operands (insn))
188990075Sobrien    return;
189090075Sobrien
189118334Speter  /* Find out what the constraints required.  If no constraint
189218334Speter     alternative matches, that is a compiler bug: we should have caught
189390075Sobrien     such an insn in check_asm_stack_operands.  */
189452284Sobrien  extract_insn (insn);
189552284Sobrien  constrain_operands (1);
189652284Sobrien  alt = which_alternative;
189718334Speter
189852284Sobrien  preprocess_constraints ();
189952284Sobrien
190052284Sobrien  n_inputs = get_asm_operand_n_inputs (body);
190190075Sobrien  n_outputs = recog_data.n_operands - n_inputs;
190252284Sobrien
190352284Sobrien  if (alt < 0)
190418334Speter    abort ();
190518334Speter
190650397Sobrien  /* Strip SUBREGs here to make the following code simpler.  */
190790075Sobrien  for (i = 0; i < recog_data.n_operands; i++)
190890075Sobrien    if (GET_CODE (recog_data.operand[i]) == SUBREG
190990075Sobrien	&& GET_CODE (SUBREG_REG (recog_data.operand[i])) == REG)
191018334Speter      {
191190075Sobrien	recog_data.operand_loc[i] = & SUBREG_REG (recog_data.operand[i]);
191290075Sobrien	recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
191318334Speter      }
191418334Speter
191518334Speter  /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND.  */
191618334Speter
191718334Speter  for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
191818334Speter    i++;
191918334Speter
192018334Speter  note_reg = (rtx *) alloca (i * sizeof (rtx));
192118334Speter  note_loc = (rtx **) alloca (i * sizeof (rtx *));
192218334Speter  note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note));
192318334Speter
192418334Speter  n_notes = 0;
192518334Speter  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
192618334Speter    {
192718334Speter      rtx reg = XEXP (note, 0);
192818334Speter      rtx *loc = & XEXP (note, 0);
192918334Speter
193018334Speter      if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
193118334Speter	{
193218334Speter	  loc = & SUBREG_REG (reg);
193318334Speter	  reg = SUBREG_REG (reg);
193418334Speter	}
193518334Speter
193618334Speter      if (STACK_REG_P (reg)
193718334Speter	  && (REG_NOTE_KIND (note) == REG_DEAD
193818334Speter	      || REG_NOTE_KIND (note) == REG_UNUSED))
193918334Speter	{
194018334Speter	  note_reg[n_notes] = reg;
194118334Speter	  note_loc[n_notes] = loc;
194218334Speter	  note_kind[n_notes] = REG_NOTE_KIND (note);
194318334Speter	  n_notes++;
194418334Speter	}
194518334Speter    }
194618334Speter
194718334Speter  /* Set up CLOBBER_REG and CLOBBER_LOC.  */
194818334Speter
194918334Speter  n_clobbers = 0;
195018334Speter
195118334Speter  if (GET_CODE (body) == PARALLEL)
195218334Speter    {
195352284Sobrien      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
195452284Sobrien      clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx *));
195518334Speter
195618334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
195718334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
195818334Speter	  {
195918334Speter	    rtx clobber = XVECEXP (body, 0, i);
196018334Speter	    rtx reg = XEXP (clobber, 0);
196118334Speter	    rtx *loc = & XEXP (clobber, 0);
196218334Speter
196318334Speter	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
196418334Speter	      {
196518334Speter		loc = & SUBREG_REG (reg);
196618334Speter		reg = SUBREG_REG (reg);
196718334Speter	      }
196818334Speter
196918334Speter	    if (STACK_REG_P (reg))
197018334Speter	      {
197118334Speter		clobber_reg[n_clobbers] = reg;
197218334Speter		clobber_loc[n_clobbers] = loc;
197318334Speter		n_clobbers++;
197418334Speter	      }
197518334Speter	  }
197618334Speter    }
197718334Speter
197890075Sobrien  temp_stack = *regstack;
197918334Speter
198018334Speter  /* Put the input regs into the desired place in TEMP_STACK.  */
198118334Speter
198252284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
198390075Sobrien    if (STACK_REG_P (recog_data.operand[i])
198452284Sobrien	&& reg_class_subset_p (recog_op_alt[i][alt].class,
198552284Sobrien			       FLOAT_REGS)
198652284Sobrien	&& recog_op_alt[i][alt].class != FLOAT_REGS)
198718334Speter      {
198818334Speter	/* If an operand needs to be in a particular reg in
198918334Speter	   FLOAT_REGS, the constraint was either 't' or 'u'.  Since
199090075Sobrien	   these constraints are for single register classes, and
199190075Sobrien	   reload guaranteed that operand[i] is already in that class,
199290075Sobrien	   we can just use REGNO (recog_data.operand[i]) to know which
199390075Sobrien	   actual reg this operand needs to be in.  */
199418334Speter
199590075Sobrien	int regno = get_hard_regnum (&temp_stack, recog_data.operand[i]);
199618334Speter
199718334Speter	if (regno < 0)
199818334Speter	  abort ();
199918334Speter
200090075Sobrien	if ((unsigned int) regno != REGNO (recog_data.operand[i]))
200118334Speter	  {
200290075Sobrien	    /* recog_data.operand[i] is not in the right place.  Find
200390075Sobrien	       it and swap it with whatever is already in I's place.
200490075Sobrien	       K is where recog_data.operand[i] is now.  J is where it
200590075Sobrien	       should be.  */
200618334Speter	    int j, k, temp;
200718334Speter
200818334Speter	    k = temp_stack.top - (regno - FIRST_STACK_REG);
200918334Speter	    j = (temp_stack.top
201090075Sobrien		 - (REGNO (recog_data.operand[i]) - FIRST_STACK_REG));
201118334Speter
201218334Speter	    temp = temp_stack.reg[k];
201318334Speter	    temp_stack.reg[k] = temp_stack.reg[j];
201418334Speter	    temp_stack.reg[j] = temp;
201518334Speter	  }
201618334Speter      }
201718334Speter
201890075Sobrien  /* Emit insns before INSN to make sure the reg-stack is in the right
201918334Speter     order.  */
202018334Speter
202190075Sobrien  change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
202218334Speter
202318334Speter  /* Make the needed input register substitutions.  Do death notes and
202450397Sobrien     clobbers too, because these are for inputs, not outputs.  */
202518334Speter
202652284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
202790075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
202818334Speter      {
202990075Sobrien	int regnum = get_hard_regnum (regstack, recog_data.operand[i]);
203018334Speter
203118334Speter	if (regnum < 0)
203218334Speter	  abort ();
203318334Speter
203490075Sobrien	replace_reg (recog_data.operand_loc[i], regnum);
203518334Speter      }
203618334Speter
203718334Speter  for (i = 0; i < n_notes; i++)
203818334Speter    if (note_kind[i] == REG_DEAD)
203918334Speter      {
204018334Speter	int regnum = get_hard_regnum (regstack, note_reg[i]);
204118334Speter
204218334Speter	if (regnum < 0)
204318334Speter	  abort ();
204418334Speter
204518334Speter	replace_reg (note_loc[i], regnum);
204618334Speter      }
204718334Speter
204818334Speter  for (i = 0; i < n_clobbers; i++)
204918334Speter    {
205018334Speter      /* It's OK for a CLOBBER to reference a reg that is not live.
205118334Speter         Don't try to replace it in that case.  */
205218334Speter      int regnum = get_hard_regnum (regstack, clobber_reg[i]);
205318334Speter
205418334Speter      if (regnum >= 0)
205518334Speter	{
205618334Speter	  /* Sigh - clobbers always have QImode.  But replace_reg knows
205718334Speter	     that these regs can't be MODE_INT and will abort.  Just put
205818334Speter	     the right reg there without calling replace_reg.  */
205918334Speter
206018334Speter	  *clobber_loc[i] = FP_MODE_REG (regnum, DFmode);
206118334Speter	}
206218334Speter    }
206318334Speter
206450397Sobrien  /* Now remove from REGSTACK any inputs that the asm implicitly popped.  */
206518334Speter
206652284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
206790075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
206818334Speter      {
206918334Speter	/* An input reg is implicitly popped if it is tied to an
207050397Sobrien	   output, or if there is a CLOBBER for it.  */
207118334Speter	int j;
207218334Speter
207318334Speter	for (j = 0; j < n_clobbers; j++)
207490075Sobrien	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
207518334Speter	    break;
207618334Speter
207752284Sobrien	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
207818334Speter	  {
207990075Sobrien	    /* recog_data.operand[i] might not be at the top of stack.
208090075Sobrien	       But that's OK, because all we need to do is pop the
208190075Sobrien	       right number of regs off of the top of the reg-stack.
208290075Sobrien	       record_asm_stack_regs guaranteed that all implicitly
208390075Sobrien	       popped regs were grouped at the top of the reg-stack.  */
208418334Speter
208518334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set,
208618334Speter				regstack->reg[regstack->top]);
208718334Speter	    regstack->top--;
208818334Speter	  }
208918334Speter      }
209018334Speter
209118334Speter  /* Now add to REGSTACK any outputs that the asm implicitly pushed.
209218334Speter     Note that there isn't any need to substitute register numbers.
209350397Sobrien     ???  Explain why this is true.  */
209418334Speter
209518334Speter  for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
209618334Speter    {
209718334Speter      /* See if there is an output for this hard reg.  */
209818334Speter      int j;
209918334Speter
210018334Speter      for (j = 0; j < n_outputs; j++)
210190075Sobrien	if (STACK_REG_P (recog_data.operand[j])
210290075Sobrien	    && REGNO (recog_data.operand[j]) == (unsigned) i)
210318334Speter	  {
210418334Speter	    regstack->reg[++regstack->top] = i;
210518334Speter	    SET_HARD_REG_BIT (regstack->reg_set, i);
210618334Speter	    break;
210718334Speter	  }
210818334Speter    }
210918334Speter
211018334Speter  /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
211118334Speter     input that the asm didn't implicitly pop.  If the asm didn't
211218334Speter     implicitly pop an input reg, that reg will still be live.
211318334Speter
211418334Speter     Note that we can't use find_regno_note here: the register numbers
211518334Speter     in the death notes have already been substituted.  */
211618334Speter
211718334Speter  for (i = 0; i < n_outputs; i++)
211890075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
211918334Speter      {
212018334Speter	int j;
212118334Speter
212218334Speter	for (j = 0; j < n_notes; j++)
212390075Sobrien	  if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
212418334Speter	      && note_kind[j] == REG_UNUSED)
212518334Speter	    {
212690075Sobrien	      insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
212790075Sobrien				    EMIT_AFTER);
212818334Speter	      break;
212918334Speter	    }
213018334Speter      }
213118334Speter
213252284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
213390075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
213418334Speter      {
213518334Speter	int j;
213618334Speter
213718334Speter	for (j = 0; j < n_notes; j++)
213890075Sobrien	  if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
213918334Speter	      && note_kind[j] == REG_DEAD
214052284Sobrien	      && TEST_HARD_REG_BIT (regstack->reg_set,
214190075Sobrien				    REGNO (recog_data.operand[i])))
214218334Speter	    {
214390075Sobrien	      insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
214490075Sobrien				    EMIT_AFTER);
214518334Speter	      break;
214618334Speter	    }
214718334Speter      }
214818334Speter}
214918334Speter
215018334Speter/* Substitute stack hard reg numbers for stack virtual registers in
215118334Speter   INSN.  Non-stack register numbers are not changed.  REGSTACK is the
215218334Speter   current stack content.  Insns may be emitted as needed to arrange the
215350397Sobrien   stack for the 387 based on the contents of the insn.  */
215418334Speter
215518334Speterstatic void
215618334Spetersubst_stack_regs (insn, regstack)
215718334Speter     rtx insn;
215818334Speter     stack regstack;
215918334Speter{
216090075Sobrien  rtx *note_link, note;
216190075Sobrien  int i;
216218334Speter
216318334Speter  if (GET_CODE (insn) == CALL_INSN)
216490075Sobrien    {
216590075Sobrien      int top = regstack->top;
216618334Speter
216790075Sobrien      /* If there are any floating point parameters to be passed in
216890075Sobrien	 registers for this call, make sure they are in the right
216990075Sobrien	 order.  */
217018334Speter
217190075Sobrien      if (top >= 0)
217290075Sobrien	{
217390075Sobrien	  straighten_stack (PREV_INSN (insn), regstack);
217418334Speter
217590075Sobrien	  /* Now mark the arguments as dead after the call.  */
217618334Speter
217790075Sobrien	  while (regstack->top >= 0)
217890075Sobrien	    {
217990075Sobrien	      CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top);
218090075Sobrien	      regstack->top--;
218190075Sobrien	    }
218290075Sobrien	}
218390075Sobrien    }
218418334Speter
218518334Speter  /* Do the actual substitution if any stack regs are mentioned.
218618334Speter     Since we only record whether entire insn mentions stack regs, and
218718334Speter     subst_stack_regs_pat only works for patterns that contain stack regs,
218818334Speter     we must check each pattern in a parallel here.  A call_value_pop could
218950397Sobrien     fail otherwise.  */
219018334Speter
219152284Sobrien  if (stack_regs_mentioned (insn))
219218334Speter    {
219352284Sobrien      int n_operands = asm_noperands (PATTERN (insn));
219418334Speter      if (n_operands >= 0)
219518334Speter	{
219618334Speter	  /* This insn is an `asm' with operands.  Decode the operands,
219718334Speter	     decide how many are inputs, and do register substitution.
219850397Sobrien	     Any REG_UNUSED notes will be handled by subst_asm_stack_regs.  */
219918334Speter
220052284Sobrien	  subst_asm_stack_regs (insn, regstack);
220118334Speter	  return;
220218334Speter	}
220318334Speter
220418334Speter      if (GET_CODE (PATTERN (insn)) == PARALLEL)
220518334Speter	for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
220618334Speter	  {
220718334Speter	    if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
220890075Sobrien	      subst_stack_regs_pat (insn, regstack,
220990075Sobrien				    XVECEXP (PATTERN (insn), 0, i));
221018334Speter	  }
221118334Speter      else
221218334Speter	subst_stack_regs_pat (insn, regstack, PATTERN (insn));
221318334Speter    }
221418334Speter
221518334Speter  /* subst_stack_regs_pat may have deleted a no-op insn.  If so, any
221650397Sobrien     REG_UNUSED will already have been dealt with, so just return.  */
221718334Speter
221890075Sobrien  if (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn))
221918334Speter    return;
222018334Speter
222118334Speter  /* If there is a REG_UNUSED note on a stack register on this insn,
222218334Speter     the indicated reg must be popped.  The REG_UNUSED note is removed,
222318334Speter     since the form of the newly emitted pop insn references the reg,
222450397Sobrien     making it no longer `unset'.  */
222518334Speter
222690075Sobrien  note_link = &REG_NOTES (insn);
222718334Speter  for (note = *note_link; note; note = XEXP (note, 1))
222818334Speter    if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
222918334Speter      {
223018334Speter	*note_link = XEXP (note, 1);
223190075Sobrien	insn = emit_pop_insn (insn, regstack, XEXP (note, 0), EMIT_AFTER);
223218334Speter      }
223318334Speter    else
223418334Speter      note_link = &XEXP (note, 1);
223518334Speter}
223618334Speter
223718334Speter/* Change the organization of the stack so that it fits a new basic
223818334Speter   block.  Some registers might have to be popped, but there can never be
223918334Speter   a register live in the new block that is not now live.
224018334Speter
224190075Sobrien   Insert any needed insns before or after INSN, as indicated by
224290075Sobrien   WHERE.  OLD is the original stack layout, and NEW is the desired
224390075Sobrien   form.  OLD is updated to reflect the code emitted, ie, it will be
224490075Sobrien   the same as NEW upon return.
224518334Speter
224618334Speter   This function will not preserve block_end[].  But that information
224750397Sobrien   is no longer needed once this has executed.  */
224818334Speter
224918334Speterstatic void
225090075Sobrienchange_stack (insn, old, new, where)
225118334Speter     rtx insn;
225218334Speter     stack old;
225318334Speter     stack new;
225490075Sobrien     enum emit_where where;
225518334Speter{
225618334Speter  int reg;
225790075Sobrien  int update_end = 0;
225818334Speter
225990075Sobrien  /* We will be inserting new insns "backwards".  If we are to insert
226090075Sobrien     after INSN, find the next insn, and insert before it.  */
226118334Speter
226290075Sobrien  if (where == EMIT_AFTER)
226390075Sobrien    {
226490075Sobrien      if (current_block && current_block->end == insn)
226590075Sobrien	update_end = 1;
226690075Sobrien      insn = NEXT_INSN (insn);
226790075Sobrien    }
226818334Speter
226950397Sobrien  /* Pop any registers that are not needed in the new block.  */
227018334Speter
227118334Speter  for (reg = old->top; reg >= 0; reg--)
227218334Speter    if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
227318334Speter      emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
227490075Sobrien		     EMIT_BEFORE);
227518334Speter
227618334Speter  if (new->top == -2)
227718334Speter    {
227818334Speter      /* If the new block has never been processed, then it can inherit
227950397Sobrien	 the old stack order.  */
228018334Speter
228118334Speter      new->top = old->top;
228290075Sobrien      memcpy (new->reg, old->reg, sizeof (new->reg));
228318334Speter    }
228418334Speter  else
228518334Speter    {
228618334Speter      /* This block has been entered before, and we must match the
228750397Sobrien	 previously selected stack order.  */
228818334Speter
228918334Speter      /* By now, the only difference should be the order of the stack,
229050397Sobrien	 not their depth or liveliness.  */
229118334Speter
229218334Speter      GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win);
229318334Speter      abort ();
229418334Speter    win:
229518334Speter      if (old->top != new->top)
229618334Speter	abort ();
229718334Speter
229852284Sobrien      /* If the stack is not empty (new->top != -1), loop here emitting
229952284Sobrien	 swaps until the stack is correct.
230052284Sobrien
230152284Sobrien	 The worst case number of swaps emitted is N + 2, where N is the
230218334Speter	 depth of the stack.  In some cases, the reg at the top of
230318334Speter	 stack may be correct, but swapped anyway in order to fix
230418334Speter	 other regs.  But since we never swap any other reg away from
230550397Sobrien	 its correct slot, this algorithm will converge.  */
230618334Speter
230752284Sobrien      if (new->top != -1)
230852284Sobrien	do
230952284Sobrien	  {
231052284Sobrien	    /* Swap the reg at top of stack into the position it is
231152284Sobrien	       supposed to be in, until the correct top of stack appears.  */
231218334Speter
231352284Sobrien	    while (old->reg[old->top] != new->reg[new->top])
231452284Sobrien	      {
231552284Sobrien		for (reg = new->top; reg >= 0; reg--)
231652284Sobrien		  if (new->reg[reg] == old->reg[old->top])
231752284Sobrien		    break;
231818334Speter
231952284Sobrien		if (reg == -1)
232052284Sobrien		  abort ();
232118334Speter
232252284Sobrien		emit_swap_insn (insn, old,
232352284Sobrien				FP_MODE_REG (old->reg[reg], DFmode));
232452284Sobrien	      }
232518334Speter
232652284Sobrien	    /* See if any regs remain incorrect.  If so, bring an
232718334Speter	     incorrect reg to the top of stack, and let the while loop
232850397Sobrien	     above fix it.  */
232918334Speter
233052284Sobrien	    for (reg = new->top; reg >= 0; reg--)
233152284Sobrien	      if (new->reg[reg] != old->reg[reg])
233252284Sobrien		{
233352284Sobrien		  emit_swap_insn (insn, old,
233452284Sobrien				  FP_MODE_REG (old->reg[reg], DFmode));
233552284Sobrien		  break;
233652284Sobrien		}
233752284Sobrien	  } while (reg >= 0);
233818334Speter
233950397Sobrien      /* At this point there must be no differences.  */
234018334Speter
234118334Speter      for (reg = old->top; reg >= 0; reg--)
234218334Speter	if (old->reg[reg] != new->reg[reg])
234318334Speter	  abort ();
234418334Speter    }
234590075Sobrien
234690075Sobrien  if (update_end)
234790075Sobrien    current_block->end = PREV_INSN (insn);
234818334Speter}
234918334Speter
235090075Sobrien/* Print stack configuration.  */
235118334Speter
235218334Speterstatic void
235390075Sobrienprint_stack (file, s)
235490075Sobrien     FILE *file;
235590075Sobrien     stack s;
235618334Speter{
235790075Sobrien  if (! file)
235890075Sobrien    return;
235918334Speter
236090075Sobrien  if (s->top == -2)
236190075Sobrien    fprintf (file, "uninitialized\n");
236290075Sobrien  else if (s->top == -1)
236390075Sobrien    fprintf (file, "empty\n");
236490075Sobrien  else
236590075Sobrien    {
236690075Sobrien      int i;
236790075Sobrien      fputs ("[ ", file);
236890075Sobrien      for (i = 0; i <= s->top; ++i)
236990075Sobrien	fprintf (file, "%d ", s->reg[i]);
237090075Sobrien      fputs ("]\n", file);
237190075Sobrien    }
237290075Sobrien}
237390075Sobrien
237490075Sobrien/* This function was doing life analysis.  We now let the regular live
237590075Sobrien   code do it's job, so we only need to check some extra invariants
237690075Sobrien   that reg-stack expects.  Primary among these being that all registers
237790075Sobrien   are initialized before use.
237818334Speter
237990075Sobrien   The function returns true when code was emitted to CFG edges and
238090075Sobrien   commit_edge_insertions needs to be called.  */
238190075Sobrien
238290075Sobrienstatic int
238390075Sobrienconvert_regs_entry ()
238490075Sobrien{
238590075Sobrien  int inserted = 0, i;
238690075Sobrien  edge e;
238790075Sobrien
238890075Sobrien  for (i = n_basic_blocks - 1; i >= 0; --i)
238990075Sobrien    {
239090075Sobrien      basic_block block = BASIC_BLOCK (i);
239190075Sobrien      block_info bi = BLOCK_INFO (block);
239290075Sobrien      int reg;
239390075Sobrien
239490075Sobrien      /* Set current register status at last instruction `uninitialized'.  */
239590075Sobrien      bi->stack_in.top = -2;
239690075Sobrien
239790075Sobrien      /* Copy live_at_end and live_at_start into temporaries.  */
239890075Sobrien      for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
239918334Speter	{
240090075Sobrien	  if (REGNO_REG_SET_P (block->global_live_at_end, reg))
240190075Sobrien	    SET_HARD_REG_BIT (bi->out_reg_set, reg);
240290075Sobrien	  if (REGNO_REG_SET_P (block->global_live_at_start, reg))
240390075Sobrien	    SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
240418334Speter	}
240590075Sobrien    }
240618334Speter
240790075Sobrien  /* Load something into each stack register live at function entry.
240890075Sobrien     Such live registers can be caused by uninitialized variables or
240990075Sobrien     functions not returning values on all paths.  In order to keep
241090075Sobrien     the push/pop code happy, and to not scrog the register stack, we
241190075Sobrien     must put something in these registers.  Use a QNaN.
241218334Speter
241390075Sobrien     Note that we are insertting converted code here.  This code is
241490075Sobrien     never seen by the convert_regs pass.  */
241518334Speter
241690075Sobrien  for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
241790075Sobrien    {
241890075Sobrien      basic_block block = e->dest;
241990075Sobrien      block_info bi = BLOCK_INFO (block);
242090075Sobrien      int reg, top = -1;
242118334Speter
242290075Sobrien      for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
242390075Sobrien	if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
242490075Sobrien	  {
242590075Sobrien	    rtx init;
242690075Sobrien
242790075Sobrien	    bi->stack_in.reg[++top] = reg;
242890075Sobrien
242990075Sobrien	    init = gen_rtx_SET (VOIDmode,
243090075Sobrien				FP_MODE_REG (FIRST_STACK_REG, SFmode),
243190075Sobrien				nan);
243290075Sobrien	    insert_insn_on_edge (init, e);
243390075Sobrien	    inserted = 1;
243490075Sobrien	  }
243590075Sobrien
243690075Sobrien      bi->stack_in.top = top;
243790075Sobrien    }
243890075Sobrien
243990075Sobrien  return inserted;
244090075Sobrien}
244190075Sobrien
244290075Sobrien/* Construct the desired stack for function exit.  This will either
244390075Sobrien   be `empty', or the function return value at top-of-stack.  */
244490075Sobrien
244590075Sobrienstatic void
244690075Sobrienconvert_regs_exit ()
244790075Sobrien{
244890075Sobrien  int value_reg_low, value_reg_high;
244990075Sobrien  stack output_stack;
245090075Sobrien  rtx retvalue;
245190075Sobrien
245290075Sobrien  retvalue = stack_result (current_function_decl);
245390075Sobrien  value_reg_low = value_reg_high = -1;
245490075Sobrien  if (retvalue)
245518334Speter    {
245690075Sobrien      value_reg_low = REGNO (retvalue);
245790075Sobrien      value_reg_high = value_reg_low
245890075Sobrien	+ HARD_REGNO_NREGS (value_reg_low, GET_MODE (retvalue)) - 1;
245990075Sobrien    }
246018334Speter
246190075Sobrien  output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR)->stack_in;
246290075Sobrien  if (value_reg_low == -1)
246390075Sobrien    output_stack->top = -1;
246490075Sobrien  else
246590075Sobrien    {
246690075Sobrien      int reg;
246790075Sobrien
246890075Sobrien      output_stack->top = value_reg_high - value_reg_low;
246990075Sobrien      for (reg = value_reg_low; reg <= value_reg_high; ++reg)
247090075Sobrien	{
2471102780Skan	  output_stack->reg[value_reg_high - reg] = reg;
247290075Sobrien	  SET_HARD_REG_BIT (output_stack->reg_set, reg);
247390075Sobrien	}
247490075Sobrien    }
247590075Sobrien}
247690075Sobrien
247790075Sobrien/* Adjust the stack of this block on exit to match the stack of the
247890075Sobrien   target block, or copy stack info into the stack of the successor
247990075Sobrien   of the successor hasn't been processed yet.  */
248090075Sobrienstatic bool
248190075Sobriencompensate_edge (e, file)
248290075Sobrien    edge e;
248390075Sobrien    FILE *file;
248490075Sobrien{
248590075Sobrien  basic_block block = e->src, target = e->dest;
248690075Sobrien  block_info bi = BLOCK_INFO (block);
248790075Sobrien  struct stack_def regstack, tmpstack;
248890075Sobrien  stack target_stack = &BLOCK_INFO (target)->stack_in;
248990075Sobrien  int reg;
249090075Sobrien
249190075Sobrien  current_block = block;
249290075Sobrien  regstack = bi->stack_out;
249390075Sobrien  if (file)
249490075Sobrien    fprintf (file, "Edge %d->%d: ", block->index, target->index);
249590075Sobrien
249690075Sobrien  if (target_stack->top == -2)
249790075Sobrien    {
249890075Sobrien      /* The target block hasn't had a stack order selected.
249990075Sobrien         We need merely ensure that no pops are needed.  */
250090075Sobrien      for (reg = regstack.top; reg >= 0; --reg)
250190075Sobrien	if (!TEST_HARD_REG_BIT (target_stack->reg_set, regstack.reg[reg]))
250218334Speter	  break;
250318334Speter
250418334Speter      if (reg == -1)
250518334Speter	{
250690075Sobrien	  if (file)
250790075Sobrien	    fprintf (file, "new block; copying stack position\n");
250818334Speter
250990075Sobrien	  /* change_stack kills values in regstack.  */
251090075Sobrien	  tmpstack = regstack;
251190075Sobrien
251290075Sobrien	  change_stack (block->end, &tmpstack, target_stack, EMIT_AFTER);
251390075Sobrien          return false;
251418334Speter	}
251590075Sobrien
251690075Sobrien      if (file)
251790075Sobrien	fprintf (file, "new block; pops needed\n");
251818334Speter    }
251990075Sobrien  else
252018334Speter    {
252190075Sobrien      if (target_stack->top == regstack.top)
252290075Sobrien	{
252390075Sobrien	  for (reg = target_stack->top; reg >= 0; --reg)
252490075Sobrien	    if (target_stack->reg[reg] != regstack.reg[reg])
252590075Sobrien	      break;
252618334Speter
252790075Sobrien	  if (reg == -1)
252890075Sobrien	    {
252990075Sobrien	      if (file)
253090075Sobrien		fprintf (file, "no changes needed\n");
253190075Sobrien	      return false;
253290075Sobrien	    }
253390075Sobrien	}
253490075Sobrien
253590075Sobrien      if (file)
253690075Sobrien	{
253790075Sobrien	  fprintf (file, "correcting stack to ");
253890075Sobrien	  print_stack (file, target_stack);
253990075Sobrien	}
254018334Speter    }
254118334Speter
254290075Sobrien  /* Care for non-call EH edges specially.  The normal return path have
254390075Sobrien     values in registers.  These will be popped en masse by the unwind
254490075Sobrien     library.  */
254590075Sobrien  if ((e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) == EDGE_EH)
254690075Sobrien    target_stack->top = -1;
254718334Speter
254890075Sobrien  /* Other calls may appear to have values live in st(0), but the
254990075Sobrien     abnormal return path will not have actually loaded the values.  */
255090075Sobrien  else if (e->flags & EDGE_ABNORMAL_CALL)
255190075Sobrien    {
255290075Sobrien      /* Assert that the lifetimes are as we expect -- one value
255390075Sobrien         live at st(0) on the end of the source block, and no
255490075Sobrien         values live at the beginning of the destination block.  */
255590075Sobrien      HARD_REG_SET tmp;
255618334Speter
255790075Sobrien      CLEAR_HARD_REG_SET (tmp);
255890075Sobrien      GO_IF_HARD_REG_EQUAL (target_stack->reg_set, tmp, eh1);
255990075Sobrien      abort ();
256090075Sobrien    eh1:
256118334Speter
256290075Sobrien      SET_HARD_REG_BIT (tmp, FIRST_STACK_REG);
256390075Sobrien      GO_IF_HARD_REG_EQUAL (regstack.reg_set, tmp, eh2);
256490075Sobrien      abort ();
256590075Sobrien    eh2:
256618334Speter
256790075Sobrien      target_stack->top = -1;
256890075Sobrien    }
256918334Speter
257090075Sobrien  /* It is better to output directly to the end of the block
257190075Sobrien     instead of to the edge, because emit_swap can do minimal
257290075Sobrien     insn scheduling.  We can do this when there is only one
257390075Sobrien     edge out, and it is not abnormal.  */
257490075Sobrien  else if (block->succ->succ_next == NULL && !(e->flags & EDGE_ABNORMAL))
257590075Sobrien    {
257690075Sobrien      /* change_stack kills values in regstack.  */
257790075Sobrien      tmpstack = regstack;
257818334Speter
257990075Sobrien      change_stack (block->end, &tmpstack, target_stack,
258090075Sobrien		    (GET_CODE (block->end) == JUMP_INSN
258190075Sobrien		     ? EMIT_BEFORE : EMIT_AFTER));
258290075Sobrien    }
258390075Sobrien  else
258490075Sobrien    {
258590075Sobrien      rtx seq, after;
258618334Speter
258790075Sobrien      /* We don't support abnormal edges.  Global takes care to
258890075Sobrien         avoid any live register across them, so we should never
258990075Sobrien         have to insert instructions on such edges.  */
259090075Sobrien      if (e->flags & EDGE_ABNORMAL)
259190075Sobrien	abort ();
259218334Speter
259390075Sobrien      current_block = NULL;
259490075Sobrien      start_sequence ();
259518334Speter
259690075Sobrien      /* ??? change_stack needs some point to emit insns after.
259790075Sobrien         Also needed to keep gen_sequence from returning a
259890075Sobrien         pattern as opposed to a sequence, which would lose
259990075Sobrien         REG_DEAD notes.  */
260090075Sobrien      after = emit_note (NULL, NOTE_INSN_DELETED);
260118334Speter
260290075Sobrien      tmpstack = regstack;
260390075Sobrien      change_stack (after, &tmpstack, target_stack, EMIT_BEFORE);
260418334Speter
260590075Sobrien      seq = gen_sequence ();
260690075Sobrien      end_sequence ();
260718334Speter
260890075Sobrien      insert_insn_on_edge (seq, e);
260990075Sobrien      return true;
261090075Sobrien    }
261190075Sobrien  return false;
261218334Speter}
261318334Speter
261490075Sobrien/* Convert stack register references in one block.  */
261590075Sobrien
261690075Sobrienstatic int
261790075Sobrienconvert_regs_1 (file, block)
261890075Sobrien     FILE *file;
261990075Sobrien     basic_block block;
262018334Speter{
262118334Speter  struct stack_def regstack;
262290075Sobrien  block_info bi = BLOCK_INFO (block);
262390075Sobrien  int inserted, reg;
262490075Sobrien  rtx insn, next;
262590075Sobrien  edge e, beste = NULL;
262618334Speter
262790075Sobrien  inserted = 0;
262890075Sobrien
262990075Sobrien  /* Find the edge we will copy stack from.  It should be the most frequent
263090075Sobrien     one as it will get cheapest after compensation code is generated,
263190075Sobrien     if multiple such exists, take one with largest count, prefer critical
263290075Sobrien     one (as splitting critical edges is more expensive), or one with lowest
263390075Sobrien     index, to avoid random changes with different orders of the edges.  */
263490075Sobrien  for (e = block->pred; e ; e = e->pred_next)
263518334Speter    {
263690075Sobrien      if (e->flags & EDGE_DFS_BACK)
263790075Sobrien	;
263890075Sobrien      else if (! beste)
263990075Sobrien	beste = e;
264090075Sobrien      else if (EDGE_FREQUENCY (beste) < EDGE_FREQUENCY (e))
264190075Sobrien	beste = e;
264290075Sobrien      else if (EDGE_FREQUENCY (beste) > EDGE_FREQUENCY (e))
264390075Sobrien	;
264490075Sobrien      else if (beste->count < e->count)
264590075Sobrien	beste = e;
264690075Sobrien      else if (beste->count > e->count)
264790075Sobrien	;
264890075Sobrien      else if ((EDGE_CRITICAL_P (e) != 0)
264990075Sobrien	       != (EDGE_CRITICAL_P (beste) != 0))
265018334Speter	{
265190075Sobrien	  if (EDGE_CRITICAL_P (e))
265290075Sobrien	    beste = e;
265318334Speter	}
265490075Sobrien      else if (e->src->index < beste->src->index)
265590075Sobrien	beste = e;
265690075Sobrien    }
265718334Speter
265890075Sobrien  /* Entry block does have stack already initialized.  */
265990075Sobrien  if (bi->stack_in.top == -2)
266090075Sobrien    inserted |= compensate_edge (beste, file);
266190075Sobrien  else
266290075Sobrien    beste = NULL;
266390075Sobrien
266490075Sobrien  current_block = block;
266518334Speter
266690075Sobrien  if (file)
266790075Sobrien    {
266890075Sobrien      fprintf (file, "\nBasic block %d\nInput stack: ", block->index);
266990075Sobrien      print_stack (file, &bi->stack_in);
267090075Sobrien    }
267118334Speter
267290075Sobrien  /* Process all insns in this block.  Keep track of NEXT so that we
267390075Sobrien     don't process insns emitted while substituting in INSN.  */
267490075Sobrien  next = block->head;
267590075Sobrien  regstack = bi->stack_in;
267690075Sobrien  do
267790075Sobrien    {
267890075Sobrien      insn = next;
267990075Sobrien      next = NEXT_INSN (insn);
268018334Speter
268190075Sobrien      /* Ensure we have not missed a block boundary.  */
268290075Sobrien      if (next == NULL)
268350397Sobrien	abort ();
268490075Sobrien      if (insn == block->end)
268590075Sobrien	next = NULL;
268618334Speter
268790075Sobrien      /* Don't bother processing unless there is a stack reg
268890075Sobrien	 mentioned or if it's a CALL_INSN.  */
268990075Sobrien      if (stack_regs_mentioned (insn)
269090075Sobrien	  || GET_CODE (insn) == CALL_INSN)
269190075Sobrien	{
269290075Sobrien	  if (file)
269390075Sobrien	    {
269490075Sobrien	      fprintf (file, "  insn %d input stack: ",
269590075Sobrien		       INSN_UID (insn));
269690075Sobrien	      print_stack (file, &regstack);
269790075Sobrien	    }
269890075Sobrien	  subst_stack_regs (insn, &regstack);
269990075Sobrien	}
270090075Sobrien    }
270190075Sobrien  while (next);
270250397Sobrien
270390075Sobrien  if (file)
270490075Sobrien    {
270590075Sobrien      fprintf (file, "Expected live registers [");
270690075Sobrien      for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
270790075Sobrien	if (TEST_HARD_REG_BIT (bi->out_reg_set, reg))
270890075Sobrien	  fprintf (file, " %d", reg);
270990075Sobrien      fprintf (file, " ]\nOutput stack: ");
271090075Sobrien      print_stack (file, &regstack);
271190075Sobrien    }
271218334Speter
271390075Sobrien  insn = block->end;
271490075Sobrien  if (GET_CODE (insn) == JUMP_INSN)
271590075Sobrien    insn = PREV_INSN (insn);
271618334Speter
271790075Sobrien  /* If the function is declared to return a value, but it returns one
271890075Sobrien     in only some cases, some registers might come live here.  Emit
271990075Sobrien     necessary moves for them.  */
272018334Speter
272190075Sobrien  for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
272290075Sobrien    {
272390075Sobrien      if (TEST_HARD_REG_BIT (bi->out_reg_set, reg)
272490075Sobrien	  && ! TEST_HARD_REG_BIT (regstack.reg_set, reg))
272590075Sobrien	{
272690075Sobrien	  rtx set;
272718334Speter
272890075Sobrien	  if (file)
272990075Sobrien	    {
273090075Sobrien	      fprintf (file, "Emitting insn initializing reg %d\n",
273190075Sobrien		       reg);
273290075Sobrien	    }
273318334Speter
273490075Sobrien	  set = gen_rtx_SET (VOIDmode, FP_MODE_REG (reg, SFmode),
273590075Sobrien			     nan);
273690075Sobrien	  insn = emit_insn_after (set, insn);
273790075Sobrien	  subst_stack_regs (insn, &regstack);
273890075Sobrien	}
273918334Speter    }
274018334Speter
274190075Sobrien  /* Something failed if the stack lives don't match.  */
274290075Sobrien  GO_IF_HARD_REG_EQUAL (regstack.reg_set, bi->out_reg_set, win);
274390075Sobrien  abort ();
274490075Sobrien win:
274590075Sobrien  bi->stack_out = regstack;
274618334Speter
274790075Sobrien  /* Compensate the back edges, as those wasn't visited yet.  */
274890075Sobrien  for (e = block->succ; e ; e = e->succ_next)
274990075Sobrien    {
275090075Sobrien      if (e->flags & EDGE_DFS_BACK
275190075Sobrien	  || (e->dest == EXIT_BLOCK_PTR))
275290075Sobrien	{
275390075Sobrien	  if (!BLOCK_INFO (e->dest)->done
275490075Sobrien	      && e->dest != block)
275590075Sobrien	    abort ();
275690075Sobrien          inserted |= compensate_edge (e, file);
275790075Sobrien	}
275890075Sobrien    }
275990075Sobrien  for (e = block->pred; e ; e = e->pred_next)
276090075Sobrien    {
276190075Sobrien      if (e != beste && !(e->flags & EDGE_DFS_BACK)
276290075Sobrien	  && e->src != ENTRY_BLOCK_PTR)
276390075Sobrien	{
276490075Sobrien	  if (!BLOCK_INFO (e->src)->done)
276590075Sobrien	    abort ();
276690075Sobrien          inserted |= compensate_edge (e, file);
276790075Sobrien	}
276890075Sobrien    }
276918334Speter
277090075Sobrien  return inserted;
277118334Speter}
277218334Speter
277390075Sobrien/* Convert registers in all blocks reachable from BLOCK.  */
277490075Sobrien
277590075Sobrienstatic int
277690075Sobrienconvert_regs_2 (file, block)
277718334Speter     FILE *file;
277890075Sobrien     basic_block block;
277918334Speter{
278090075Sobrien  basic_block *stack, *sp;
278190075Sobrien  int inserted;
278218334Speter
278390075Sobrien  stack = (basic_block *) xmalloc (sizeof (*stack) * n_basic_blocks);
278490075Sobrien  sp = stack;
278590075Sobrien
278690075Sobrien  *sp++ = block;
278790075Sobrien
278890075Sobrien  inserted = 0;
278990075Sobrien  do
279018334Speter    {
279190075Sobrien      edge e;
279218334Speter
279390075Sobrien      block = *--sp;
279490075Sobrien      inserted |= convert_regs_1 (file, block);
279590075Sobrien      BLOCK_INFO (block)->done = 1;
279618334Speter
279790075Sobrien      for (e = block->succ; e ; e = e->succ_next)
279890075Sobrien	if (! (e->flags & EDGE_DFS_BACK))
279990075Sobrien	  {
280090075Sobrien	    BLOCK_INFO (e->dest)->predecessors--;
280190075Sobrien	    if (!BLOCK_INFO (e->dest)->predecessors)
280290075Sobrien	       *sp++ = e->dest;
280390075Sobrien	  }
280418334Speter    }
280590075Sobrien  while (sp != stack);
280618334Speter
280790075Sobrien  return inserted;
280818334Speter}
280950397Sobrien
281090075Sobrien/* Traverse all basic blocks in a function, converting the register
281190075Sobrien   references in each insn from the "flat" register file that gcc uses,
281290075Sobrien   to the stack-like registers the 387 uses.  */
281390075Sobrien
281490075Sobrienstatic int
281590075Sobrienconvert_regs (file)
281618334Speter     FILE *file;
281718334Speter{
281890075Sobrien  int inserted, i;
281990075Sobrien  edge e;
282018334Speter
282190075Sobrien  /* Initialize uninitialized registers on function entry.  */
282290075Sobrien  inserted = convert_regs_entry ();
282318334Speter
282490075Sobrien  /* Construct the desired stack for function exit.  */
282590075Sobrien  convert_regs_exit ();
282690075Sobrien  BLOCK_INFO (EXIT_BLOCK_PTR)->done = 1;
282718334Speter
282890075Sobrien  /* ??? Future: process inner loops first, and give them arbitrary
282990075Sobrien     initial stacks which emit_swap_insn can modify.  This ought to
283090075Sobrien     prevent double fxch that aften appears at the head of a loop.  */
283118334Speter
283290075Sobrien  /* Process all blocks reachable from all entry points.  */
283390075Sobrien  for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
283490075Sobrien    inserted |= convert_regs_2 (file, e->dest);
283590075Sobrien
283690075Sobrien  /* ??? Process all unreachable blocks.  Though there's no excuse
283790075Sobrien     for keeping these even when not optimizing.  */
283890075Sobrien  for (i = 0; i < n_basic_blocks; ++i)
283990075Sobrien    {
284090075Sobrien      basic_block b = BASIC_BLOCK (i);
284190075Sobrien      block_info bi = BLOCK_INFO (b);
284218334Speter
284390075Sobrien      if (! bi->done)
284418334Speter	{
284590075Sobrien	  int reg;
284618334Speter
284790075Sobrien	  /* Create an arbitrary input stack.  */
284890075Sobrien	  bi->stack_in.top = -1;
284990075Sobrien	  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
285090075Sobrien	    if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
285190075Sobrien	      bi->stack_in.reg[++bi->stack_in.top] = reg;
285290075Sobrien
285390075Sobrien	  inserted |= convert_regs_2 (file, b);
285418334Speter	}
285590075Sobrien    }
285618334Speter
285796263Sobrien  fixup_abnormal_edges ();
285890075Sobrien  if (inserted)
285990075Sobrien    commit_edge_insertions ();
286018334Speter
286190075Sobrien  if (file)
286290075Sobrien    fputc ('\n', file);
286318334Speter
286490075Sobrien  return inserted;
286518334Speter}
286618334Speter#endif /* STACK_REGS */
2867