118334Speter/* Register to Stack convert for GNU compiler.
2132718Skan   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3169689Skan   2000, 2001, 2002, 2003, 2004, 2005 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
19169689Skan   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan   02110-1301, 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
108169689Skan      the asm pushes a result onto the reg-stack, i.e., 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"
156132718Skan#include "coretypes.h"
157132718Skan#include "tm.h"
15818334Speter#include "tree.h"
15918334Speter#include "rtl.h"
16090075Sobrien#include "tm_p.h"
16190075Sobrien#include "function.h"
16218334Speter#include "insn-config.h"
16318334Speter#include "regs.h"
16418334Speter#include "hard-reg-set.h"
16518334Speter#include "flags.h"
16690075Sobrien#include "toplev.h"
16752284Sobrien#include "recog.h"
16890075Sobrien#include "output.h"
16990075Sobrien#include "basic-block.h"
17052284Sobrien#include "varray.h"
17190075Sobrien#include "reload.h"
172117395Skan#include "ggc.h"
173169689Skan#include "timevar.h"
174169689Skan#include "tree-pass.h"
175169689Skan#include "target.h"
176169689Skan#include "vecprim.h"
17718334Speter
178169689Skan#ifdef STACK_REGS
179169689Skan
180117395Skan/* We use this array to cache info about insns, because otherwise we
181117395Skan   spend too much time in stack_regs_mentioned_p.
182117395Skan
183117395Skan   Indexed by insn UIDs.  A value of zero is uninitialized, one indicates
184117395Skan   the insn uses stack registers, two indicates the insn does not use
185117395Skan   stack registers.  */
186169689Skanstatic VEC(char,heap) *stack_regs_mentioned_data;
187117395Skan
18818334Speter#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
18918334Speter
190169689Skanint regstack_completed = 0;
191169689Skan
19218334Speter/* This is the basic stack record.  TOP is an index into REG[] such
19318334Speter   that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.
19418334Speter
19518334Speter   If TOP is -2, REG[] is not yet initialized.  Stack initialization
19618334Speter   consists of placing each live reg in array `reg' and setting `top'
19718334Speter   appropriately.
19818334Speter
19918334Speter   REG_SET indicates which registers are live.  */
20018334Speter
20118334Spetertypedef struct stack_def
20218334Speter{
20318334Speter  int top;			/* index to top stack element */
20418334Speter  HARD_REG_SET reg_set;		/* set of live registers */
20590075Sobrien  unsigned char reg[REG_STACK_SIZE];/* register - stack mapping */
20618334Speter} *stack;
20718334Speter
208117395Skan/* This is used to carry information about basic blocks.  It is
20990075Sobrien   attached to the AUX field of the standard CFG block.  */
21018334Speter
21190075Sobrientypedef struct block_info_def
21290075Sobrien{
21390075Sobrien  struct stack_def stack_in;	/* Input stack configuration.  */
21490075Sobrien  struct stack_def stack_out;	/* Output stack configuration.  */
21590075Sobrien  HARD_REG_SET out_reg_set;	/* Stack regs live on output.  */
21690075Sobrien  int done;			/* True if block already converted.  */
217169689Skan  int predecessors;		/* Number of predecessors that need
21890075Sobrien				   to be visited.  */
21990075Sobrien} *block_info;
22018334Speter
22190075Sobrien#define BLOCK_INFO(B)	((block_info) (B)->aux)
22218334Speter
22390075Sobrien/* Passed to change_stack to indicate where to emit insns.  */
22490075Sobrienenum emit_where
22590075Sobrien{
22690075Sobrien  EMIT_AFTER,
22790075Sobrien  EMIT_BEFORE
22890075Sobrien};
22918334Speter
23090075Sobrien/* The block we're currently working on.  */
23190075Sobrienstatic basic_block current_block;
23290075Sobrien
233169689Skan/* In the current_block, whether we're processing the first register
234169689Skan   stack or call instruction, i.e. the regstack is currently the
235169689Skan   same as BLOCK_INFO(current_block)->stack_in.  */
236169689Skanstatic bool starting_stack_p;
237169689Skan
238117395Skan/* This is the register file for all register after conversion.  */
23918334Speterstatic rtx
24018334Speter  FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
24118334Speter
24218334Speter#define FP_MODE_REG(regno,mode)	\
24390075Sobrien  (FP_mode_reg[(regno)-FIRST_STACK_REG][(int) (mode)])
24418334Speter
24590075Sobrien/* Used to initialize uninitialized registers.  */
246169689Skanstatic rtx not_a_num;
24718334Speter
24818334Speter/* Forward declarations */
24918334Speter
250132718Skanstatic int stack_regs_mentioned_p (rtx pat);
251132718Skanstatic void pop_stack (stack, int);
252132718Skanstatic rtx *get_true_reg (rtx *);
25350397Sobrien
254132718Skanstatic int check_asm_stack_operands (rtx);
255132718Skanstatic int get_asm_operand_n_inputs (rtx);
256132718Skanstatic rtx stack_result (tree);
257132718Skanstatic void replace_reg (rtx *, int);
258132718Skanstatic void remove_regno_note (rtx, enum reg_note, unsigned int);
259132718Skanstatic int get_hard_regnum (stack, rtx);
260132718Skanstatic rtx emit_pop_insn (rtx, stack, rtx, enum emit_where);
261169689Skanstatic void swap_to_top(rtx, stack, rtx, rtx);
262132718Skanstatic bool move_for_stack_reg (rtx, stack, rtx);
263169689Skanstatic bool move_nan_for_stack_reg (rtx, stack, rtx);
264132718Skanstatic int swap_rtx_condition_1 (rtx);
265132718Skanstatic int swap_rtx_condition (rtx);
266132718Skanstatic void compare_for_stack_reg (rtx, stack, rtx);
267132718Skanstatic bool subst_stack_regs_pat (rtx, stack, rtx);
268132718Skanstatic void subst_asm_stack_regs (rtx, stack);
269132718Skanstatic bool subst_stack_regs (rtx, stack);
270132718Skanstatic void change_stack (rtx, stack, stack, enum emit_where);
271132718Skanstatic void print_stack (FILE *, stack);
272132718Skanstatic rtx next_flags_user (rtx);
27318334Speter
274117395Skan/* Return nonzero if any stack register is mentioned somewhere within PAT.  */
27552284Sobrien
27652284Sobrienstatic int
277132718Skanstack_regs_mentioned_p (rtx pat)
27852284Sobrien{
27990075Sobrien  const char *fmt;
28090075Sobrien  int i;
28190075Sobrien
28290075Sobrien  if (STACK_REG_P (pat))
28390075Sobrien    return 1;
28490075Sobrien
28590075Sobrien  fmt = GET_RTX_FORMAT (GET_CODE (pat));
28690075Sobrien  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
28752284Sobrien    {
28890075Sobrien      if (fmt[i] == 'E')
28990075Sobrien	{
29090075Sobrien	  int j;
29190075Sobrien
29290075Sobrien	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
29390075Sobrien	    if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
29490075Sobrien	      return 1;
29590075Sobrien	}
29690075Sobrien      else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
29790075Sobrien	return 1;
29852284Sobrien    }
29990075Sobrien
30052284Sobrien  return 0;
30152284Sobrien}
30252284Sobrien
30390075Sobrien/* Return nonzero if INSN mentions stacked registers, else return zero.  */
30452284Sobrien
30552284Sobrienint
306132718Skanstack_regs_mentioned (rtx insn)
30752284Sobrien{
30890075Sobrien  unsigned int uid, max;
30990075Sobrien  int test;
31090075Sobrien
31190075Sobrien  if (! INSN_P (insn) || !stack_regs_mentioned_data)
31252284Sobrien    return 0;
31390075Sobrien
31452284Sobrien  uid = INSN_UID (insn);
315169689Skan  max = VEC_length (char, stack_regs_mentioned_data);
31690075Sobrien  if (uid >= max)
31790075Sobrien    {
318169689Skan      char *p;
319169689Skan      unsigned int old_max = max;
320169689Skan
32190075Sobrien      /* Allocate some extra size to avoid too many reallocs, but
32290075Sobrien	 do not grow too quickly.  */
323169689Skan      max = uid + uid / 20 + 1;
324169689Skan      VEC_safe_grow (char, heap, stack_regs_mentioned_data, max);
325169689Skan      p = VEC_address (char, stack_regs_mentioned_data);
326169689Skan      memset (&p[old_max], 0,
327169689Skan	      sizeof (char) * (max - old_max));
32890075Sobrien    }
32990075Sobrien
330169689Skan  test = VEC_index (char, stack_regs_mentioned_data, uid);
33190075Sobrien  if (test == 0)
33290075Sobrien    {
33390075Sobrien      /* This insn has yet to be examined.  Do so now.  */
33490075Sobrien      test = stack_regs_mentioned_p (PATTERN (insn)) ? 1 : 2;
335169689Skan      VEC_replace (char, stack_regs_mentioned_data, uid, test);
33690075Sobrien    }
33790075Sobrien
33890075Sobrien  return test == 1;
33952284Sobrien}
34052284Sobrien
34190075Sobrienstatic rtx ix86_flags_rtx;
34218334Speter
34390075Sobrienstatic rtx
344132718Skannext_flags_user (rtx insn)
34518334Speter{
346117395Skan  /* Search forward looking for the first use of this value.
34790075Sobrien     Stop at block boundaries.  */
34818334Speter
349132718Skan  while (insn != BB_END (current_block))
35090075Sobrien    {
35190075Sobrien      insn = NEXT_INSN (insn);
35218334Speter
35390075Sobrien      if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
354117395Skan	return insn;
35590075Sobrien
356169689Skan      if (CALL_P (insn))
35790075Sobrien	return NULL_RTX;
35890075Sobrien    }
35990075Sobrien  return NULL_RTX;
36018334Speter}
36118334Speter
362169689Skan/* Reorganize the stack into ascending numbers, before this insn.  */
36318334Speter
36418334Speterstatic void
365132718Skanstraighten_stack (rtx insn, stack regstack)
36618334Speter{
36718334Speter  struct stack_def temp_stack;
36818334Speter  int top;
36918334Speter
37050397Sobrien  /* If there is only a single register on the stack, then the stack is
37150397Sobrien     already in increasing order and no reorganization is needed.
37250397Sobrien
37350397Sobrien     Similarly if the stack is empty.  */
37450397Sobrien  if (regstack->top <= 0)
37550397Sobrien    return;
37650397Sobrien
37790075Sobrien  COPY_HARD_REG_SET (temp_stack.reg_set, regstack->reg_set);
37818334Speter
37918334Speter  for (top = temp_stack.top = regstack->top; top >= 0; top--)
38090075Sobrien    temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
381117395Skan
382169689Skan  change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
38318334Speter}
38450397Sobrien
385117395Skan/* Pop a register from the stack.  */
38650397Sobrien
38750397Sobrienstatic void
388132718Skanpop_stack (stack regstack, int regno)
38950397Sobrien{
39050397Sobrien  int top = regstack->top;
39150397Sobrien
39250397Sobrien  CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
39350397Sobrien  regstack->top--;
394117395Skan  /* If regno was not at the top of stack then adjust stack.  */
39550397Sobrien  if (regstack->reg [top] != regno)
39650397Sobrien    {
39750397Sobrien      int i;
39850397Sobrien      for (i = regstack->top; i >= 0; i--)
39950397Sobrien	if (regstack->reg [i] == regno)
40050397Sobrien	  {
40150397Sobrien	    int j;
40250397Sobrien	    for (j = i; j < top; j++)
40350397Sobrien	      regstack->reg [j] = regstack->reg [j + 1];
40450397Sobrien	    break;
40550397Sobrien	  }
40650397Sobrien    }
40750397Sobrien}
40818334Speter
40918334Speter/* Return a pointer to the REG expression within PAT.  If PAT is not a
41018334Speter   REG, possible enclosed by a conversion rtx, return the inner part of
41150397Sobrien   PAT that stopped the search.  */
41218334Speter
41318334Speterstatic rtx *
414132718Skanget_true_reg (rtx *pat)
41518334Speter{
41618334Speter  for (;;)
41790075Sobrien    switch (GET_CODE (*pat))
41818334Speter      {
41990075Sobrien      case SUBREG:
420117395Skan	/* Eliminate FP subregister accesses in favor of the
42190075Sobrien	   actual FP register in use.  */
42290075Sobrien	{
42390075Sobrien	  rtx subreg;
42490075Sobrien	  if (FP_REG_P (subreg = SUBREG_REG (*pat)))
42518334Speter	    {
42690075Sobrien	      int regno_off = subreg_regno_offset (REGNO (subreg),
42790075Sobrien						   GET_MODE (subreg),
42890075Sobrien						   SUBREG_BYTE (*pat),
42990075Sobrien						   GET_MODE (*pat));
43090075Sobrien	      *pat = FP_MODE_REG (REGNO (subreg) + regno_off,
43118334Speter				  GET_MODE (subreg));
43290075Sobrien	    default:
43318334Speter	      return pat;
43418334Speter	    }
43590075Sobrien	}
43690075Sobrien      case FLOAT:
43790075Sobrien      case FIX:
43890075Sobrien      case FLOAT_EXTEND:
43990075Sobrien	pat = & XEXP (*pat, 0);
440169689Skan	break;
441169689Skan
442169689Skan      case FLOAT_TRUNCATE:
443169689Skan	if (!flag_unsafe_math_optimizations)
444169689Skan	  return pat;
445169689Skan	pat = & XEXP (*pat, 0);
446169689Skan	break;
44718334Speter      }
44818334Speter}
44918334Speter
450117395Skan/* Set if we find any malformed asms in a block.  */
451117395Skanstatic bool any_malformed_asm;
452117395Skan
45390075Sobrien/* There are many rules that an asm statement for stack-like regs must
45418334Speter   follow.  Those rules are explained at the top of this file: the rule
45550397Sobrien   numbers below refer to that explanation.  */
45618334Speter
45790075Sobrienstatic int
458132718Skancheck_asm_stack_operands (rtx insn)
45918334Speter{
46018334Speter  int i;
46118334Speter  int n_clobbers;
46218334Speter  int malformed_asm = 0;
46318334Speter  rtx body = PATTERN (insn);
46418334Speter
46590075Sobrien  char reg_used_as_output[FIRST_PSEUDO_REGISTER];
46690075Sobrien  char implicitly_dies[FIRST_PSEUDO_REGISTER];
46752284Sobrien  int alt;
46818334Speter
46990075Sobrien  rtx *clobber_reg = 0;
47052284Sobrien  int n_inputs, n_outputs;
47118334Speter
47218334Speter  /* Find out what the constraints require.  If no constraint
47318334Speter     alternative matches, this asm is malformed.  */
47452284Sobrien  extract_insn (insn);
47552284Sobrien  constrain_operands (1);
47652284Sobrien  alt = which_alternative;
47718334Speter
47852284Sobrien  preprocess_constraints ();
47952284Sobrien
48052284Sobrien  n_inputs = get_asm_operand_n_inputs (body);
48190075Sobrien  n_outputs = recog_data.n_operands - n_inputs;
48252284Sobrien
48352284Sobrien  if (alt < 0)
48452284Sobrien    {
48552284Sobrien      malformed_asm = 1;
48652284Sobrien      /* Avoid further trouble with this insn.  */
48752284Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
48890075Sobrien      return 0;
48952284Sobrien    }
49052284Sobrien
49150397Sobrien  /* Strip SUBREGs here to make the following code simpler.  */
49290075Sobrien  for (i = 0; i < recog_data.n_operands; i++)
49390075Sobrien    if (GET_CODE (recog_data.operand[i]) == SUBREG
494169689Skan	&& REG_P (SUBREG_REG (recog_data.operand[i])))
49590075Sobrien      recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
49618334Speter
49718334Speter  /* Set up CLOBBER_REG.  */
49818334Speter
49918334Speter  n_clobbers = 0;
50018334Speter
50118334Speter  if (GET_CODE (body) == PARALLEL)
50218334Speter    {
503132718Skan      clobber_reg = alloca (XVECLEN (body, 0) * sizeof (rtx));
50418334Speter
50518334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
50618334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
50718334Speter	  {
50818334Speter	    rtx clobber = XVECEXP (body, 0, i);
50918334Speter	    rtx reg = XEXP (clobber, 0);
51018334Speter
511169689Skan	    if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
51218334Speter	      reg = SUBREG_REG (reg);
51318334Speter
51418334Speter	    if (STACK_REG_P (reg))
51518334Speter	      {
51618334Speter		clobber_reg[n_clobbers] = reg;
51718334Speter		n_clobbers++;
51818334Speter	      }
51918334Speter	  }
52018334Speter    }
52118334Speter
52218334Speter  /* Enforce rule #4: Output operands must specifically indicate which
52318334Speter     reg an output appears in after an asm.  "=f" is not allowed: the
52418334Speter     operand constraints must select a class with a single reg.
52518334Speter
52618334Speter     Also enforce rule #5: Output operands must start at the top of
52750397Sobrien     the reg-stack: output operands may not "skip" a reg.  */
52818334Speter
52990075Sobrien  memset (reg_used_as_output, 0, sizeof (reg_used_as_output));
53018334Speter  for (i = 0; i < n_outputs; i++)
53190075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
53250397Sobrien      {
533169689Skan	if (reg_class_size[(int) recog_op_alt[i][alt].cl] != 1)
53450397Sobrien	  {
53590075Sobrien	    error_for_asm (insn, "output constraint %d must specify a single register", i);
53650397Sobrien	    malformed_asm = 1;
53750397Sobrien	  }
538117395Skan	else
53990075Sobrien	  {
54090075Sobrien	    int j;
54190075Sobrien
54290075Sobrien	    for (j = 0; j < n_clobbers; j++)
54390075Sobrien	      if (REGNO (recog_data.operand[i]) == REGNO (clobber_reg[j]))
54490075Sobrien		{
54590075Sobrien		  error_for_asm (insn, "output constraint %d cannot be specified together with \"%s\" clobber",
54690075Sobrien				 i, reg_names [REGNO (clobber_reg[j])]);
54790075Sobrien		  malformed_asm = 1;
54890075Sobrien		  break;
54990075Sobrien		}
55090075Sobrien	    if (j == n_clobbers)
55190075Sobrien	      reg_used_as_output[REGNO (recog_data.operand[i])] = 1;
55290075Sobrien	  }
55350397Sobrien      }
55418334Speter
55518334Speter
55618334Speter  /* Search for first non-popped reg.  */
55718334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
55818334Speter    if (! reg_used_as_output[i])
55918334Speter      break;
56018334Speter
56118334Speter  /* If there are any other popped regs, that's an error.  */
56218334Speter  for (; i < LAST_STACK_REG + 1; i++)
56318334Speter    if (reg_used_as_output[i])
56418334Speter      break;
56518334Speter
56618334Speter  if (i != LAST_STACK_REG + 1)
56718334Speter    {
56890075Sobrien      error_for_asm (insn, "output regs must be grouped at top of stack");
56918334Speter      malformed_asm = 1;
57018334Speter    }
57118334Speter
57218334Speter  /* Enforce rule #2: All implicitly popped input regs must be closer
57318334Speter     to the top of the reg-stack than any input that is not implicitly
57450397Sobrien     popped.  */
57518334Speter
57690075Sobrien  memset (implicitly_dies, 0, sizeof (implicitly_dies));
57752284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
57890075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
57918334Speter      {
58018334Speter	/* An input reg is implicitly popped if it is tied to an
58150397Sobrien	   output, or if there is a CLOBBER for it.  */
58218334Speter	int j;
58318334Speter
58418334Speter	for (j = 0; j < n_clobbers; j++)
58590075Sobrien	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
58618334Speter	    break;
58718334Speter
58852284Sobrien	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
58990075Sobrien	  implicitly_dies[REGNO (recog_data.operand[i])] = 1;
59018334Speter      }
59118334Speter
59218334Speter  /* Search for first non-popped reg.  */
59318334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
59418334Speter    if (! implicitly_dies[i])
59518334Speter      break;
59618334Speter
59718334Speter  /* If there are any other popped regs, that's an error.  */
59818334Speter  for (; i < LAST_STACK_REG + 1; i++)
59918334Speter    if (implicitly_dies[i])
60018334Speter      break;
60118334Speter
60218334Speter  if (i != LAST_STACK_REG + 1)
60318334Speter    {
60418334Speter      error_for_asm (insn,
60590075Sobrien		     "implicitly popped regs must be grouped at top of stack");
60618334Speter      malformed_asm = 1;
60718334Speter    }
60818334Speter
609132718Skan  /* Enforce rule #3: If any input operand uses the "f" constraint, all
61018334Speter     output constraints must use the "&" earlyclobber.
61118334Speter
61290075Sobrien     ??? Detect this more deterministically by having constrain_asm_operands
61350397Sobrien     record any earlyclobber.  */
61418334Speter
61552284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
61652284Sobrien    if (recog_op_alt[i][alt].matches == -1)
61718334Speter      {
61818334Speter	int j;
61918334Speter
62018334Speter	for (j = 0; j < n_outputs; j++)
62190075Sobrien	  if (operands_match_p (recog_data.operand[j], recog_data.operand[i]))
62218334Speter	    {
62318334Speter	      error_for_asm (insn,
624169689Skan			     "output operand %d must use %<&%> constraint", j);
62518334Speter	      malformed_asm = 1;
62618334Speter	    }
62718334Speter      }
62818334Speter
62918334Speter  if (malformed_asm)
63018334Speter    {
63118334Speter      /* Avoid further trouble with this insn.  */
63250397Sobrien      PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
633117395Skan      any_malformed_asm = true;
63490075Sobrien      return 0;
63518334Speter    }
63618334Speter
63790075Sobrien  return 1;
63818334Speter}
63918334Speter
64018334Speter/* Calculate the number of inputs and outputs in BODY, an
64118334Speter   asm_operands.  N_OPERANDS is the total number of operands, and
64218334Speter   N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
64350397Sobrien   placed.  */
64418334Speter
64552284Sobrienstatic int
646132718Skanget_asm_operand_n_inputs (rtx body)
64718334Speter{
648169689Skan  switch (GET_CODE (body))
649169689Skan    {
650169689Skan    case SET:
651169689Skan      gcc_assert (GET_CODE (SET_SRC (body)) == ASM_OPERANDS);
652169689Skan      return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
653169689Skan
654169689Skan    case ASM_OPERANDS:
655169689Skan      return ASM_OPERANDS_INPUT_LENGTH (body);
656169689Skan
657169689Skan    case PARALLEL:
658169689Skan      return get_asm_operand_n_inputs (XVECEXP (body, 0, 0));
659169689Skan
660169689Skan    default:
661169689Skan      gcc_unreachable ();
662169689Skan    }
66318334Speter}
66418334Speter
66518334Speter/* If current function returns its result in an fp stack register,
66618334Speter   return the REG.  Otherwise, return 0.  */
66718334Speter
66818334Speterstatic rtx
669132718Skanstack_result (tree decl)
67018334Speter{
67152750Sobrien  rtx result;
67218334Speter
67352750Sobrien  /* If the value is supposed to be returned in memory, then clearly
67452750Sobrien     it is not returned in a stack register.  */
675132718Skan  if (aggregate_value_p (DECL_RESULT (decl), decl))
67652750Sobrien    return 0;
67752750Sobrien
67890075Sobrien  result = DECL_RTL_IF_SET (DECL_RESULT (decl));
67990075Sobrien  if (result != 0)
680169689Skan    result = targetm.calls.function_value (TREE_TYPE (DECL_RESULT (decl)),
681169689Skan					   decl, true);
68218334Speter
68318334Speter  return result != 0 && STACK_REG_P (result) ? result : 0;
68418334Speter}
68518334Speter
68618334Speter
68790075Sobrien/*
68890075Sobrien * This section deals with stack register substitution, and forms the second
68990075Sobrien * pass over the RTL.
69090075Sobrien */
69118334Speter
69218334Speter/* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
69350397Sobrien   the desired hard REGNO.  */
69418334Speter
69518334Speterstatic void
696132718Skanreplace_reg (rtx *reg, int regno)
69718334Speter{
698169689Skan  gcc_assert (regno >= FIRST_STACK_REG);
699169689Skan  gcc_assert (regno <= LAST_STACK_REG);
700169689Skan  gcc_assert (STACK_REG_P (*reg));
70118334Speter
702169689Skan  gcc_assert (SCALAR_FLOAT_MODE_P (GET_MODE (*reg))
703169689Skan	      || GET_MODE_CLASS (GET_MODE (*reg)) == MODE_COMPLEX_FLOAT);
70418334Speter
70518334Speter  *reg = FP_MODE_REG (regno, GET_MODE (*reg));
70618334Speter}
70718334Speter
70818334Speter/* Remove a note of type NOTE, which must be found, for register
70950397Sobrien   number REGNO from INSN.  Remove only one such note.  */
71018334Speter
71118334Speterstatic void
712132718Skanremove_regno_note (rtx insn, enum reg_note note, unsigned int regno)
71318334Speter{
71490075Sobrien  rtx *note_link, this;
71518334Speter
71690075Sobrien  note_link = &REG_NOTES (insn);
71718334Speter  for (this = *note_link; this; this = XEXP (this, 1))
71818334Speter    if (REG_NOTE_KIND (this) == note
71918334Speter	&& REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
72018334Speter      {
72118334Speter	*note_link = XEXP (this, 1);
72218334Speter	return;
72318334Speter      }
72418334Speter    else
72518334Speter      note_link = &XEXP (this, 1);
72618334Speter
727169689Skan  gcc_unreachable ();
72818334Speter}
72918334Speter
73018334Speter/* Find the hard register number of virtual register REG in REGSTACK.
73118334Speter   The hard register number is relative to the top of the stack.  -1 is
73250397Sobrien   returned if the register is not found.  */
73318334Speter
73418334Speterstatic int
735132718Skanget_hard_regnum (stack regstack, rtx reg)
73618334Speter{
73718334Speter  int i;
73818334Speter
739169689Skan  gcc_assert (STACK_REG_P (reg));
74018334Speter
74118334Speter  for (i = regstack->top; i >= 0; i--)
74218334Speter    if (regstack->reg[i] == REGNO (reg))
74318334Speter      break;
74418334Speter
74518334Speter  return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
74618334Speter}
74718334Speter
74818334Speter/* Emit an insn to pop virtual register REG before or after INSN.
74918334Speter   REGSTACK is the stack state after INSN and is updated to reflect this
75090075Sobrien   pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
75190075Sobrien   is represented as a SET whose destination is the register to be popped
75290075Sobrien   and source is the top of stack.  A death note for the top of stack
75350397Sobrien   cases the movdf pattern to pop.  */
75418334Speter
75518334Speterstatic rtx
756132718Skanemit_pop_insn (rtx insn, stack regstack, rtx reg, enum emit_where where)
75718334Speter{
75818334Speter  rtx pop_insn, pop_rtx;
75918334Speter  int hard_regno;
76018334Speter
76190075Sobrien  /* For complex types take care to pop both halves.  These may survive in
76290075Sobrien     CLOBBER and USE expressions.  */
76390075Sobrien  if (COMPLEX_MODE_P (GET_MODE (reg)))
76490075Sobrien    {
76590075Sobrien      rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode);
76690075Sobrien      rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode);
76790075Sobrien
76890075Sobrien      pop_insn = NULL_RTX;
76990075Sobrien      if (get_hard_regnum (regstack, reg1) >= 0)
770117395Skan	pop_insn = emit_pop_insn (insn, regstack, reg1, where);
77190075Sobrien      if (get_hard_regnum (regstack, reg2) >= 0)
772117395Skan	pop_insn = emit_pop_insn (insn, regstack, reg2, where);
773169689Skan      gcc_assert (pop_insn);
77490075Sobrien      return pop_insn;
77590075Sobrien    }
77690075Sobrien
77718334Speter  hard_regno = get_hard_regnum (regstack, reg);
77818334Speter
779169689Skan  gcc_assert (hard_regno >= FIRST_STACK_REG);
78018334Speter
78190075Sobrien  pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode),
78290075Sobrien			 FP_MODE_REG (FIRST_STACK_REG, DFmode));
78318334Speter
78490075Sobrien  if (where == EMIT_AFTER)
78590075Sobrien    pop_insn = emit_insn_after (pop_rtx, insn);
78690075Sobrien  else
78790075Sobrien    pop_insn = emit_insn_before (pop_rtx, insn);
78818334Speter
78990075Sobrien  REG_NOTES (pop_insn)
79090075Sobrien    = gen_rtx_EXPR_LIST (REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, DFmode),
79190075Sobrien			 REG_NOTES (pop_insn));
79218334Speter
79318334Speter  regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
79418334Speter    = regstack->reg[regstack->top];
79518334Speter  regstack->top -= 1;
79618334Speter  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));
79718334Speter
79818334Speter  return pop_insn;
79918334Speter}
80018334Speter
80190075Sobrien/* Emit an insn before or after INSN to swap virtual register REG with
80290075Sobrien   the top of stack.  REGSTACK is the stack state before the swap, and
80390075Sobrien   is updated to reflect the swap.  A swap insn is represented as a
80490075Sobrien   PARALLEL of two patterns: each pattern moves one reg to the other.
80518334Speter
80650397Sobrien   If REG is already at the top of the stack, no insn is emitted.  */
80718334Speter
80818334Speterstatic void
809132718Skanemit_swap_insn (rtx insn, stack regstack, rtx reg)
81018334Speter{
81118334Speter  int hard_regno;
81290075Sobrien  rtx swap_rtx;
81318334Speter  int tmp, other_reg;		/* swap regno temps */
81418334Speter  rtx i1;			/* the stack-reg insn prior to INSN */
81518334Speter  rtx i1set = NULL_RTX;		/* the SET rtx within I1 */
81618334Speter
81718334Speter  hard_regno = get_hard_regnum (regstack, reg);
81818334Speter
81918334Speter  if (hard_regno == FIRST_STACK_REG)
82018334Speter    return;
821169689Skan  if (hard_regno == -1)
822169689Skan    {
823169689Skan      /* Something failed if the register wasn't on the stack.  If we had
824169689Skan	 malformed asms, we zapped the instruction itself, but that didn't
825169689Skan	 produce the same pattern of register sets as before.  To prevent
826169689Skan	 further failure, adjust REGSTACK to include REG at TOP.  */
827169689Skan      gcc_assert (any_malformed_asm);
828169689Skan      regstack->reg[++regstack->top] = REGNO (reg);
829169689Skan      return;
830169689Skan    }
831169689Skan  gcc_assert (hard_regno >= FIRST_STACK_REG);
83218334Speter
83318334Speter  other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);
83418334Speter
83518334Speter  tmp = regstack->reg[other_reg];
83618334Speter  regstack->reg[other_reg] = regstack->reg[regstack->top];
83718334Speter  regstack->reg[regstack->top] = tmp;
83818334Speter
83990075Sobrien  /* Find the previous insn involving stack regs, but don't pass a
84090075Sobrien     block boundary.  */
84190075Sobrien  i1 = NULL;
842132718Skan  if (current_block && insn != BB_HEAD (current_block))
84390075Sobrien    {
84490075Sobrien      rtx tmp = PREV_INSN (insn);
845132718Skan      rtx limit = PREV_INSN (BB_HEAD (current_block));
84690075Sobrien      while (tmp != limit)
84790075Sobrien	{
848169689Skan	  if (LABEL_P (tmp)
849169689Skan	      || CALL_P (tmp)
85090075Sobrien	      || NOTE_INSN_BASIC_BLOCK_P (tmp)
851169689Skan	      || (NONJUMP_INSN_P (tmp)
85290075Sobrien		  && stack_regs_mentioned (tmp)))
85390075Sobrien	    {
85490075Sobrien	      i1 = tmp;
85590075Sobrien	      break;
85690075Sobrien	    }
85790075Sobrien	  tmp = PREV_INSN (tmp);
85890075Sobrien	}
85990075Sobrien    }
86018334Speter
86190075Sobrien  if (i1 != NULL_RTX
86290075Sobrien      && (i1set = single_set (i1)) != NULL_RTX)
86318334Speter    {
86418334Speter      rtx i1src = *get_true_reg (&SET_SRC (i1set));
86518334Speter      rtx i1dest = *get_true_reg (&SET_DEST (i1set));
86618334Speter
86718334Speter      /* If the previous register stack push was from the reg we are to
86850397Sobrien	 swap with, omit the swap.  */
86918334Speter
870169689Skan      if (REG_P (i1dest) && REGNO (i1dest) == FIRST_STACK_REG
871169689Skan	  && REG_P (i1src)
87290075Sobrien	  && REGNO (i1src) == (unsigned) hard_regno - 1
87318334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
87418334Speter	return;
87518334Speter
87618334Speter      /* If the previous insn wrote to the reg we are to swap with,
87718334Speter	 omit the swap.  */
87818334Speter
879169689Skan      if (REG_P (i1dest) && REGNO (i1dest) == (unsigned) hard_regno
880169689Skan	  && REG_P (i1src) && REGNO (i1src) == FIRST_STACK_REG
88118334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
88218334Speter	return;
88318334Speter    }
88418334Speter
885169689Skan  /* Avoid emitting the swap if this is the first register stack insn
886169689Skan     of the current_block.  Instead update the current_block's stack_in
887169689Skan     and let compensate edges take care of this for us.  */
888169689Skan  if (current_block && starting_stack_p)
889169689Skan    {
890169689Skan      BLOCK_INFO (current_block)->stack_in = *regstack;
891169689Skan      starting_stack_p = false;
892169689Skan      return;
893169689Skan    }
894169689Skan
89590075Sobrien  swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode),
89690075Sobrien			 FP_MODE_REG (FIRST_STACK_REG, XFmode));
89718334Speter
89890075Sobrien  if (i1)
89990075Sobrien    emit_insn_after (swap_rtx, i1);
90090075Sobrien  else if (current_block)
901132718Skan    emit_insn_before (swap_rtx, BB_HEAD (current_block));
90290075Sobrien  else
90390075Sobrien    emit_insn_before (swap_rtx, insn);
90418334Speter}
90518334Speter
906169689Skan/* Emit an insns before INSN to swap virtual register SRC1 with
907169689Skan   the top of stack and virtual register SRC2 with second stack
908169689Skan   slot. REGSTACK is the stack state before the swaps, and
909169689Skan   is updated to reflect the swaps.  A swap insn is represented as a
910169689Skan   PARALLEL of two patterns: each pattern moves one reg to the other.
911169689Skan
912169689Skan   If SRC1 and/or SRC2 are already at the right place, no swap insn
913169689Skan   is emitted.  */
914169689Skan
915169689Skanstatic void
916169689Skanswap_to_top (rtx insn, stack regstack, rtx src1, rtx src2)
917169689Skan{
918169689Skan  struct stack_def temp_stack;
919169689Skan  int regno, j, k, temp;
920169689Skan
921169689Skan  temp_stack = *regstack;
922169689Skan
923169689Skan  /* Place operand 1 at the top of stack.  */
924169689Skan  regno = get_hard_regnum (&temp_stack, src1);
925169689Skan  gcc_assert (regno >= 0);
926169689Skan  if (regno != FIRST_STACK_REG)
927169689Skan    {
928169689Skan      k = temp_stack.top - (regno - FIRST_STACK_REG);
929169689Skan      j = temp_stack.top;
930169689Skan
931169689Skan      temp = temp_stack.reg[k];
932169689Skan      temp_stack.reg[k] = temp_stack.reg[j];
933169689Skan      temp_stack.reg[j] = temp;
934169689Skan    }
935169689Skan
936169689Skan  /* Place operand 2 next on the stack.  */
937169689Skan  regno = get_hard_regnum (&temp_stack, src2);
938169689Skan  gcc_assert (regno >= 0);
939169689Skan  if (regno != FIRST_STACK_REG + 1)
940169689Skan    {
941169689Skan      k = temp_stack.top - (regno - FIRST_STACK_REG);
942169689Skan      j = temp_stack.top - 1;
943169689Skan
944169689Skan      temp = temp_stack.reg[k];
945169689Skan      temp_stack.reg[k] = temp_stack.reg[j];
946169689Skan      temp_stack.reg[j] = temp;
947169689Skan    }
948169689Skan
949169689Skan  change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
950169689Skan}
951169689Skan
95218334Speter/* Handle a move to or from a stack register in PAT, which is in INSN.
953132718Skan   REGSTACK is the current stack.  Return whether a control flow insn
954132718Skan   was deleted in the process.  */
95518334Speter
956132718Skanstatic bool
957132718Skanmove_for_stack_reg (rtx insn, stack regstack, rtx pat)
95818334Speter{
95918334Speter  rtx *psrc =  get_true_reg (&SET_SRC (pat));
96018334Speter  rtx *pdest = get_true_reg (&SET_DEST (pat));
96118334Speter  rtx src, dest;
96218334Speter  rtx note;
963132718Skan  bool control_flow_insn_deleted = false;
96418334Speter
96518334Speter  src = *psrc; dest = *pdest;
96618334Speter
96718334Speter  if (STACK_REG_P (src) && STACK_REG_P (dest))
96818334Speter    {
96918334Speter      /* Write from one stack reg to another.  If SRC dies here, then
97050397Sobrien	 just change the register mapping and delete the insn.  */
97118334Speter
97218334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
97318334Speter      if (note)
97418334Speter	{
97518334Speter	  int i;
97618334Speter
97750397Sobrien	  /* If this is a no-op move, there must not be a REG_DEAD note.  */
978169689Skan	  gcc_assert (REGNO (src) != REGNO (dest));
97918334Speter
98018334Speter	  for (i = regstack->top; i >= 0; i--)
98118334Speter	    if (regstack->reg[i] == REGNO (src))
98218334Speter	      break;
98318334Speter
984146895Skan	  /* The destination must be dead, or life analysis is borked.  */
985169689Skan	  gcc_assert (get_hard_regnum (regstack, dest) < FIRST_STACK_REG);
98618334Speter
987146895Skan	  /* If the source is not live, this is yet another case of
988146895Skan	     uninitialized variables.  Load up a NaN instead.  */
989146895Skan	  if (i < 0)
990169689Skan	    return move_nan_for_stack_reg (insn, regstack, dest);
991146895Skan
99218334Speter	  /* It is possible that the dest is unused after this insn.
99350397Sobrien	     If so, just pop the src.  */
99418334Speter
99518334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
996132718Skan	    emit_pop_insn (insn, regstack, src, EMIT_AFTER);
997132718Skan	  else
99818334Speter	    {
999132718Skan	      regstack->reg[i] = REGNO (dest);
1000132718Skan	      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
1001132718Skan	      CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
100218334Speter	    }
100318334Speter
1004132718Skan	  control_flow_insn_deleted |= control_flow_insn_p (insn);
100590075Sobrien	  delete_insn (insn);
1006132718Skan	  return control_flow_insn_deleted;
100718334Speter	}
100818334Speter
100950397Sobrien      /* The source reg does not die.  */
101018334Speter
101118334Speter      /* If this appears to be a no-op move, delete it, or else it
101218334Speter	 will confuse the machine description output patterns. But if
101318334Speter	 it is REG_UNUSED, we must pop the reg now, as per-insn processing
101450397Sobrien	 for REG_UNUSED will not work for deleted insns.  */
101518334Speter
101618334Speter      if (REGNO (src) == REGNO (dest))
101718334Speter	{
101818334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
101990075Sobrien	    emit_pop_insn (insn, regstack, dest, EMIT_AFTER);
102018334Speter
1021132718Skan	  control_flow_insn_deleted |= control_flow_insn_p (insn);
102290075Sobrien	  delete_insn (insn);
1023132718Skan	  return control_flow_insn_deleted;
102418334Speter	}
102518334Speter
1026117395Skan      /* The destination ought to be dead.  */
1027169689Skan      gcc_assert (get_hard_regnum (regstack, dest) < FIRST_STACK_REG);
102818334Speter
102918334Speter      replace_reg (psrc, get_hard_regnum (regstack, src));
103018334Speter
103118334Speter      regstack->reg[++regstack->top] = REGNO (dest);
103218334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
103318334Speter      replace_reg (pdest, FIRST_STACK_REG);
103418334Speter    }
103518334Speter  else if (STACK_REG_P (src))
103618334Speter    {
103718334Speter      /* Save from a stack reg to MEM, or possibly integer reg.  Since
103818334Speter	 only top of stack may be saved, emit an exchange first if
103950397Sobrien	 needs be.  */
104018334Speter
104118334Speter      emit_swap_insn (insn, regstack, src);
104218334Speter
104318334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
104418334Speter      if (note)
104518334Speter	{
104618334Speter	  replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
104718334Speter	  regstack->top--;
104818334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
104918334Speter	}
1050132718Skan      else if ((GET_MODE (src) == XFmode)
105190075Sobrien	       && regstack->top < REG_STACK_SIZE - 1)
105218334Speter	{
105318334Speter	  /* A 387 cannot write an XFmode value to a MEM without
105418334Speter	     clobbering the source reg.  The output code can handle
105518334Speter	     this by reading back the value from the MEM.
105618334Speter	     But it is more efficient to use a temp register if one is
105718334Speter	     available.  Push the source value here if the register
105818334Speter	     stack is not full, and then write the value to memory via
105918334Speter	     a pop.  */
1060169689Skan	  rtx push_rtx;
106190075Sobrien	  rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src));
106218334Speter
1063132718Skan	  push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
1064169689Skan	  emit_insn_before (push_rtx, insn);
106550397Sobrien	  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg,
106650397Sobrien						REG_NOTES (insn));
106718334Speter	}
106818334Speter
106918334Speter      replace_reg (psrc, FIRST_STACK_REG);
107018334Speter    }
1071169689Skan  else
107218334Speter    {
1073169689Skan      gcc_assert (STACK_REG_P (dest));
1074169689Skan
107518334Speter      /* Load from MEM, or possibly integer REG or constant, into the
107618334Speter	 stack regs.  The actual target is always the top of the
107718334Speter	 stack. The stack mapping is changed to reflect that DEST is
107818334Speter	 now at top of stack.  */
107918334Speter
1080117395Skan      /* The destination ought to be dead.  */
1081169689Skan      gcc_assert (get_hard_regnum (regstack, dest) < FIRST_STACK_REG);
108218334Speter
1083169689Skan      gcc_assert (regstack->top < REG_STACK_SIZE);
108418334Speter
108518334Speter      regstack->reg[++regstack->top] = REGNO (dest);
108618334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
108718334Speter      replace_reg (pdest, FIRST_STACK_REG);
108818334Speter    }
1089132718Skan
1090132718Skan  return control_flow_insn_deleted;
109118334Speter}
1092169689Skan
1093169689Skan/* A helper function which replaces INSN with a pattern that loads up
1094169689Skan   a NaN into DEST, then invokes move_for_stack_reg.  */
1095169689Skan
1096169689Skanstatic bool
1097169689Skanmove_nan_for_stack_reg (rtx insn, stack regstack, rtx dest)
1098169689Skan{
1099169689Skan  rtx pat;
1100169689Skan
1101169689Skan  dest = FP_MODE_REG (REGNO (dest), SFmode);
1102169689Skan  pat = gen_rtx_SET (VOIDmode, dest, not_a_num);
1103169689Skan  PATTERN (insn) = pat;
1104169689Skan  INSN_CODE (insn) = -1;
1105169689Skan
1106169689Skan  return move_for_stack_reg (insn, regstack, pat);
1107169689Skan}
110818334Speter
110990075Sobrien/* Swap the condition on a branch, if there is one.  Return true if we
111090075Sobrien   found a condition to swap.  False if the condition was not used as
111190075Sobrien   such.  */
111290075Sobrien
111390075Sobrienstatic int
1114132718Skanswap_rtx_condition_1 (rtx pat)
111518334Speter{
111690075Sobrien  const char *fmt;
111790075Sobrien  int i, r = 0;
111818334Speter
1119169689Skan  if (COMPARISON_P (pat))
112018334Speter    {
112118334Speter      PUT_CODE (pat, swap_condition (GET_CODE (pat)));
112290075Sobrien      r = 1;
112318334Speter    }
112490075Sobrien  else
112590075Sobrien    {
112690075Sobrien      fmt = GET_RTX_FORMAT (GET_CODE (pat));
112790075Sobrien      for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
112890075Sobrien	{
112990075Sobrien	  if (fmt[i] == 'E')
113090075Sobrien	    {
113190075Sobrien	      int j;
113218334Speter
113390075Sobrien	      for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
113490075Sobrien		r |= swap_rtx_condition_1 (XVECEXP (pat, i, j));
113590075Sobrien	    }
113690075Sobrien	  else if (fmt[i] == 'e')
113790075Sobrien	    r |= swap_rtx_condition_1 (XEXP (pat, i));
113890075Sobrien	}
113990075Sobrien    }
114090075Sobrien
114190075Sobrien  return r;
114290075Sobrien}
114390075Sobrien
114490075Sobrienstatic int
1145132718Skanswap_rtx_condition (rtx insn)
114690075Sobrien{
114790075Sobrien  rtx pat = PATTERN (insn);
114890075Sobrien
114990075Sobrien  /* We're looking for a single set to cc0 or an HImode temporary.  */
115090075Sobrien
115190075Sobrien  if (GET_CODE (pat) == SET
1152169689Skan      && REG_P (SET_DEST (pat))
115390075Sobrien      && REGNO (SET_DEST (pat)) == FLAGS_REG)
115418334Speter    {
115590075Sobrien      insn = next_flags_user (insn);
115690075Sobrien      if (insn == NULL_RTX)
115790075Sobrien	return 0;
115890075Sobrien      pat = PATTERN (insn);
115990075Sobrien    }
116090075Sobrien
1161161651Skan  /* See if this is, or ends in, a fnstsw.  If so, we're not doing anything
1162161651Skan     with the cc value right now.  We may be able to search for one
1163161651Skan     though.  */
116490075Sobrien
116590075Sobrien  if (GET_CODE (pat) == SET
116690075Sobrien      && GET_CODE (SET_SRC (pat)) == UNSPEC
1167117395Skan      && XINT (SET_SRC (pat), 1) == UNSPEC_FNSTSW)
116890075Sobrien    {
116990075Sobrien      rtx dest = SET_DEST (pat);
117090075Sobrien
1171117395Skan      /* Search forward looking for the first use of this value.
117290075Sobrien	 Stop at block boundaries.  */
1173132718Skan      while (insn != BB_END (current_block))
117418334Speter	{
117590075Sobrien	  insn = NEXT_INSN (insn);
117690075Sobrien	  if (INSN_P (insn) && reg_mentioned_p (dest, insn))
117790075Sobrien	    break;
1178169689Skan	  if (CALL_P (insn))
117990075Sobrien	    return 0;
118090075Sobrien	}
118118334Speter
1182161651Skan      /* We haven't found it.  */
1183161651Skan      if (insn == BB_END (current_block))
1184161651Skan	return 0;
1185161651Skan
118690075Sobrien      /* So we've found the insn using this value.  If it is anything
1187161651Skan	 other than sahf or the value does not die (meaning we'd have
1188161651Skan	 to search further), then we must give up.  */
118990075Sobrien      pat = PATTERN (insn);
119090075Sobrien      if (GET_CODE (pat) != SET
119190075Sobrien	  || GET_CODE (SET_SRC (pat)) != UNSPEC
1192117395Skan	  || XINT (SET_SRC (pat), 1) != UNSPEC_SAHF
119390075Sobrien	  || ! dead_or_set_p (insn, dest))
119490075Sobrien	return 0;
119590075Sobrien
119690075Sobrien      /* Now we are prepared to handle this as a normal cc0 setter.  */
119790075Sobrien      insn = next_flags_user (insn);
119890075Sobrien      if (insn == NULL_RTX)
119990075Sobrien	return 0;
120090075Sobrien      pat = PATTERN (insn);
120190075Sobrien    }
120290075Sobrien
120390075Sobrien  if (swap_rtx_condition_1 (pat))
120490075Sobrien    {
120590075Sobrien      int fail = 0;
120690075Sobrien      INSN_CODE (insn) = -1;
120790075Sobrien      if (recog_memoized (insn) == -1)
120890075Sobrien	fail = 1;
120990075Sobrien      /* In case the flags don't die here, recurse to try fix
121090075Sobrien         following user too.  */
121190075Sobrien      else if (! dead_or_set_p (insn, ix86_flags_rtx))
121290075Sobrien	{
121390075Sobrien	  insn = next_flags_user (insn);
121490075Sobrien	  if (!insn || !swap_rtx_condition (insn))
121590075Sobrien	    fail = 1;
121618334Speter	}
121790075Sobrien      if (fail)
121890075Sobrien	{
121990075Sobrien	  swap_rtx_condition_1 (pat);
122090075Sobrien	  return 0;
122190075Sobrien	}
122290075Sobrien      return 1;
122318334Speter    }
122490075Sobrien  return 0;
122518334Speter}
122618334Speter
122718334Speter/* Handle a comparison.  Special care needs to be taken to avoid
122818334Speter   causing comparisons that a 387 cannot do correctly, such as EQ.
122918334Speter
123090075Sobrien   Also, a pop insn may need to be emitted.  The 387 does have an
123118334Speter   `fcompp' insn that can pop two regs, but it is sometimes too expensive
123218334Speter   to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
123390075Sobrien   set up.  */
123418334Speter
123518334Speterstatic void
1236132718Skancompare_for_stack_reg (rtx insn, stack regstack, rtx pat_src)
123718334Speter{
123818334Speter  rtx *src1, *src2;
123918334Speter  rtx src1_note, src2_note;
124018334Speter
124190075Sobrien  src1 = get_true_reg (&XEXP (pat_src, 0));
124290075Sobrien  src2 = get_true_reg (&XEXP (pat_src, 1));
124318334Speter
124418334Speter  /* ??? If fxch turns out to be cheaper than fstp, give priority to
124550397Sobrien     registers that die in this insn - move those to stack top first.  */
124690075Sobrien  if ((! STACK_REG_P (*src1)
124790075Sobrien       || (STACK_REG_P (*src2)
124890075Sobrien	   && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
124990075Sobrien      && swap_rtx_condition (insn))
125018334Speter    {
125190075Sobrien      rtx temp;
125290075Sobrien      temp = XEXP (pat_src, 0);
125390075Sobrien      XEXP (pat_src, 0) = XEXP (pat_src, 1);
125490075Sobrien      XEXP (pat_src, 1) = temp;
125518334Speter
125690075Sobrien      src1 = get_true_reg (&XEXP (pat_src, 0));
125790075Sobrien      src2 = get_true_reg (&XEXP (pat_src, 1));
125818334Speter
125918334Speter      INSN_CODE (insn) = -1;
126018334Speter    }
126118334Speter
126250397Sobrien  /* We will fix any death note later.  */
126318334Speter
126418334Speter  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
126518334Speter
126618334Speter  if (STACK_REG_P (*src2))
126718334Speter    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
126818334Speter  else
126918334Speter    src2_note = NULL_RTX;
127018334Speter
127190075Sobrien  emit_swap_insn (insn, regstack, *src1);
127218334Speter
127318334Speter  replace_reg (src1, FIRST_STACK_REG);
127418334Speter
127518334Speter  if (STACK_REG_P (*src2))
127690075Sobrien    replace_reg (src2, get_hard_regnum (regstack, *src2));
127718334Speter
127818334Speter  if (src1_note)
127918334Speter    {
128050397Sobrien      pop_stack (regstack, REGNO (XEXP (src1_note, 0)));
128118334Speter      replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
128218334Speter    }
128318334Speter
128418334Speter  /* If the second operand dies, handle that.  But if the operands are
128518334Speter     the same stack register, don't bother, because only one death is
128650397Sobrien     needed, and it was just handled.  */
128718334Speter
128818334Speter  if (src2_note
128918334Speter      && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
129018334Speter	    && REGNO (*src1) == REGNO (*src2)))
129118334Speter    {
129218334Speter      /* As a special case, two regs may die in this insn if src2 is
129318334Speter	 next to top of stack and the top of stack also dies.  Since
129418334Speter	 we have already popped src1, "next to top of stack" is really
129550397Sobrien	 at top (FIRST_STACK_REG) now.  */
129618334Speter
129718334Speter      if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
129818334Speter	  && src1_note)
129918334Speter	{
130050397Sobrien	  pop_stack (regstack, REGNO (XEXP (src2_note, 0)));
130118334Speter	  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
130218334Speter	}
130318334Speter      else
130418334Speter	{
130590075Sobrien	  /* The 386 can only represent death of the first operand in
130690075Sobrien	     the case handled above.  In all other cases, emit a separate
130790075Sobrien	     pop and remove the death note from here.  */
130818334Speter
130990075Sobrien	  /* link_cc0_insns (insn); */
131090075Sobrien
131190075Sobrien	  remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
131290075Sobrien
131390075Sobrien	  emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
131490075Sobrien			 EMIT_AFTER);
131518334Speter	}
131618334Speter    }
131718334Speter}
131818334Speter
131918334Speter/* Substitute new registers in PAT, which is part of INSN.  REGSTACK
1320132718Skan   is the current register layout.  Return whether a control flow insn
1321132718Skan   was deleted in the process.  */
132218334Speter
1323132718Skanstatic bool
1324132718Skansubst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
132518334Speter{
132618334Speter  rtx *dest, *src;
1327132718Skan  bool control_flow_insn_deleted = false;
132818334Speter
132990075Sobrien  switch (GET_CODE (pat))
133090075Sobrien    {
133190075Sobrien    case USE:
133290075Sobrien      /* Deaths in USE insns can happen in non optimizing compilation.
133390075Sobrien	 Handle them by popping the dying register.  */
133490075Sobrien      src = get_true_reg (&XEXP (pat, 0));
1335117395Skan      if (STACK_REG_P (*src)
1336117395Skan	  && find_regno_note (insn, REG_DEAD, REGNO (*src)))
1337117395Skan	{
1338117395Skan	  emit_pop_insn (insn, regstack, *src, EMIT_AFTER);
1339132718Skan	  return control_flow_insn_deleted;
1340117395Skan	}
134190075Sobrien      /* ??? Uninitialized USE should not happen.  */
1342169689Skan      else
1343169689Skan	gcc_assert (get_hard_regnum (regstack, *src) != -1);
134490075Sobrien      break;
134518334Speter
134690075Sobrien    case CLOBBER:
134790075Sobrien      {
134890075Sobrien	rtx note;
134918334Speter
135090075Sobrien	dest = get_true_reg (&XEXP (pat, 0));
135190075Sobrien	if (STACK_REG_P (*dest))
135290075Sobrien	  {
135390075Sobrien	    note = find_reg_note (insn, REG_DEAD, *dest);
135418334Speter
135590075Sobrien	    if (pat != PATTERN (insn))
135690075Sobrien	      {
135790075Sobrien		/* The fix_truncdi_1 pattern wants to be able to allocate
1358169689Skan		   its own scratch register.  It does this by clobbering
135990075Sobrien		   an fp reg so that it is assured of an empty reg-stack
1360117395Skan		   register.  If the register is live, kill it now.
136190075Sobrien		   Remove the DEAD/UNUSED note so we don't try to kill it
136290075Sobrien		   later too.  */
136390075Sobrien
136490075Sobrien		if (note)
136590075Sobrien		  emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
136690075Sobrien		else
136790075Sobrien		  {
136890075Sobrien		    note = find_reg_note (insn, REG_UNUSED, *dest);
1369169689Skan		    gcc_assert (note);
137090075Sobrien		  }
137190075Sobrien		remove_note (insn, note);
1372132718Skan		replace_reg (dest, FIRST_STACK_REG + 1);
137390075Sobrien	      }
137490075Sobrien	    else
137590075Sobrien	      {
137690075Sobrien		/* A top-level clobber with no REG_DEAD, and no hard-regnum
137790075Sobrien		   indicates an uninitialized value.  Because reload removed
1378117395Skan		   all other clobbers, this must be due to a function
137990075Sobrien		   returning without a value.  Load up a NaN.  */
138090075Sobrien
1381169689Skan		if (!note)
138290075Sobrien		  {
1383169689Skan		    rtx t = *dest;
1384169689Skan		    if (COMPLEX_MODE_P (GET_MODE (t)))
1385169689Skan		      {
1386169689Skan			rtx u = FP_MODE_REG (REGNO (t) + 1, SFmode);
1387169689Skan			if (get_hard_regnum (regstack, u) == -1)
1388169689Skan			  {
1389169689Skan			    rtx pat2 = gen_rtx_CLOBBER (VOIDmode, u);
1390169689Skan			    rtx insn2 = emit_insn_before (pat2, insn);
1391169689Skan			    control_flow_insn_deleted
1392169689Skan			      |= move_nan_for_stack_reg (insn2, regstack, u);
1393169689Skan			  }
1394169689Skan		      }
1395169689Skan		    if (get_hard_regnum (regstack, t) == -1)
1396169689Skan		      control_flow_insn_deleted
1397169689Skan			|= move_nan_for_stack_reg (insn, regstack, t);
139890075Sobrien		  }
139990075Sobrien	      }
140090075Sobrien	  }
140118334Speter	break;
140290075Sobrien      }
140318334Speter
140490075Sobrien    case SET:
140590075Sobrien      {
140690075Sobrien	rtx *src1 = (rtx *) 0, *src2;
140790075Sobrien	rtx src1_note, src2_note;
140890075Sobrien	rtx pat_src;
140990075Sobrien
141090075Sobrien	dest = get_true_reg (&SET_DEST (pat));
141190075Sobrien	src  = get_true_reg (&SET_SRC (pat));
141290075Sobrien	pat_src = SET_SRC (pat);
141390075Sobrien
141490075Sobrien	/* See if this is a `movM' pattern, and handle elsewhere if so.  */
141590075Sobrien	if (STACK_REG_P (*src)
141690075Sobrien	    || (STACK_REG_P (*dest)
1417169689Skan		&& (REG_P (*src) || MEM_P (*src)
141890075Sobrien		    || GET_CODE (*src) == CONST_DOUBLE)))
141990075Sobrien	  {
1420132718Skan	    control_flow_insn_deleted |= move_for_stack_reg (insn, regstack, pat);
142190075Sobrien	    break;
142290075Sobrien	  }
142390075Sobrien
142490075Sobrien	switch (GET_CODE (pat_src))
142590075Sobrien	  {
142690075Sobrien	  case COMPARE:
142790075Sobrien	    compare_for_stack_reg (insn, regstack, pat_src);
142890075Sobrien	    break;
142990075Sobrien
143090075Sobrien	  case CALL:
143118334Speter	    {
143290075Sobrien	      int count;
1433169689Skan	      for (count = hard_regno_nregs[REGNO (*dest)][GET_MODE (*dest)];
143490075Sobrien		   --count >= 0;)
143590075Sobrien		{
143690075Sobrien		  regstack->reg[++regstack->top] = REGNO (*dest) + count;
143790075Sobrien		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count);
143890075Sobrien		}
143918334Speter	    }
144090075Sobrien	    replace_reg (dest, FIRST_STACK_REG);
144190075Sobrien	    break;
144218334Speter
144390075Sobrien	  case REG:
144490075Sobrien	    /* This is a `tstM2' case.  */
1445169689Skan	    gcc_assert (*dest == cc0_rtx);
144690075Sobrien	    src1 = src;
144718334Speter
144890075Sobrien	    /* Fall through.  */
144918334Speter
145090075Sobrien	  case FLOAT_TRUNCATE:
145190075Sobrien	  case SQRT:
145290075Sobrien	  case ABS:
145390075Sobrien	  case NEG:
145490075Sobrien	    /* These insns only operate on the top of the stack. DEST might
145590075Sobrien	       be cc0_rtx if we're processing a tstM pattern. Also, it's
145690075Sobrien	       possible that the tstM case results in a REG_DEAD note on the
145790075Sobrien	       source.  */
145818334Speter
145990075Sobrien	    if (src1 == 0)
146090075Sobrien	      src1 = get_true_reg (&XEXP (pat_src, 0));
146118334Speter
146290075Sobrien	    emit_swap_insn (insn, regstack, *src1);
146318334Speter
146490075Sobrien	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
146518334Speter
146690075Sobrien	    if (STACK_REG_P (*dest))
146790075Sobrien	      replace_reg (dest, FIRST_STACK_REG);
146818334Speter
146990075Sobrien	    if (src1_note)
147090075Sobrien	      {
147190075Sobrien		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
147290075Sobrien		regstack->top--;
147390075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
147490075Sobrien	      }
147518334Speter
147690075Sobrien	    replace_reg (src1, FIRST_STACK_REG);
147790075Sobrien	    break;
147818334Speter
147990075Sobrien	  case MINUS:
148090075Sobrien	  case DIV:
148190075Sobrien	    /* On i386, reversed forms of subM3 and divM3 exist for
148290075Sobrien	       MODE_FLOAT, so the same code that works for addM3 and mulM3
148390075Sobrien	       can be used.  */
148490075Sobrien	  case MULT:
148590075Sobrien	  case PLUS:
148690075Sobrien	    /* These insns can accept the top of stack as a destination
148790075Sobrien	       from a stack reg or mem, or can use the top of stack as a
148890075Sobrien	       source and some other stack register (possibly top of stack)
148990075Sobrien	       as a destination.  */
149018334Speter
149190075Sobrien	    src1 = get_true_reg (&XEXP (pat_src, 0));
149290075Sobrien	    src2 = get_true_reg (&XEXP (pat_src, 1));
149318334Speter
149490075Sobrien	    /* We will fix any death note later.  */
149518334Speter
149690075Sobrien	    if (STACK_REG_P (*src1))
149790075Sobrien	      src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
149890075Sobrien	    else
149990075Sobrien	      src1_note = NULL_RTX;
150090075Sobrien	    if (STACK_REG_P (*src2))
150190075Sobrien	      src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
150290075Sobrien	    else
150390075Sobrien	      src2_note = NULL_RTX;
150418334Speter
150590075Sobrien	    /* If either operand is not a stack register, then the dest
150690075Sobrien	       must be top of stack.  */
150718334Speter
150890075Sobrien	    if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
150990075Sobrien	      emit_swap_insn (insn, regstack, *dest);
151090075Sobrien	    else
151190075Sobrien	      {
151290075Sobrien		/* Both operands are REG.  If neither operand is already
151390075Sobrien		   at the top of stack, choose to make the one that is the dest
151490075Sobrien		   the new top of stack.  */
151518334Speter
151690075Sobrien		int src1_hard_regnum, src2_hard_regnum;
151718334Speter
151890075Sobrien		src1_hard_regnum = get_hard_regnum (regstack, *src1);
151990075Sobrien		src2_hard_regnum = get_hard_regnum (regstack, *src2);
1520169689Skan		gcc_assert (src1_hard_regnum != -1);
1521169689Skan		gcc_assert (src2_hard_regnum != -1);
152218334Speter
152390075Sobrien		if (src1_hard_regnum != FIRST_STACK_REG
152490075Sobrien		    && src2_hard_regnum != FIRST_STACK_REG)
152590075Sobrien		  emit_swap_insn (insn, regstack, *dest);
152690075Sobrien	      }
152718334Speter
152890075Sobrien	    if (STACK_REG_P (*src1))
152990075Sobrien	      replace_reg (src1, get_hard_regnum (regstack, *src1));
153090075Sobrien	    if (STACK_REG_P (*src2))
153190075Sobrien	      replace_reg (src2, get_hard_regnum (regstack, *src2));
153218334Speter
153390075Sobrien	    if (src1_note)
153490075Sobrien	      {
153590075Sobrien		rtx src1_reg = XEXP (src1_note, 0);
153618334Speter
153790075Sobrien		/* If the register that dies is at the top of stack, then
153890075Sobrien		   the destination is somewhere else - merely substitute it.
153990075Sobrien		   But if the reg that dies is not at top of stack, then
154090075Sobrien		   move the top of stack to the dead reg, as though we had
154190075Sobrien		   done the insn and then a store-with-pop.  */
154218334Speter
154390075Sobrien		if (REGNO (src1_reg) == regstack->reg[regstack->top])
154490075Sobrien		  {
154590075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
154690075Sobrien		    replace_reg (dest, get_hard_regnum (regstack, *dest));
154790075Sobrien		  }
154890075Sobrien		else
154990075Sobrien		  {
155090075Sobrien		    int regno = get_hard_regnum (regstack, src1_reg);
155118334Speter
155290075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
155390075Sobrien		    replace_reg (dest, regno);
155490075Sobrien
155590075Sobrien		    regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
155690075Sobrien		      = regstack->reg[regstack->top];
155790075Sobrien		  }
155890075Sobrien
155990075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set,
156090075Sobrien				    REGNO (XEXP (src1_note, 0)));
156190075Sobrien		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
156290075Sobrien		regstack->top--;
156318334Speter	      }
156490075Sobrien	    else if (src2_note)
156518334Speter	      {
156690075Sobrien		rtx src2_reg = XEXP (src2_note, 0);
156790075Sobrien		if (REGNO (src2_reg) == regstack->reg[regstack->top])
156890075Sobrien		  {
156990075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
157090075Sobrien		    replace_reg (dest, get_hard_regnum (regstack, *dest));
157190075Sobrien		  }
157290075Sobrien		else
157390075Sobrien		  {
157490075Sobrien		    int regno = get_hard_regnum (regstack, src2_reg);
157518334Speter
157690075Sobrien		    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
157790075Sobrien		    replace_reg (dest, regno);
157818334Speter
157990075Sobrien		    regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
158090075Sobrien		      = regstack->reg[regstack->top];
158190075Sobrien		  }
158290075Sobrien
158390075Sobrien		CLEAR_HARD_REG_BIT (regstack->reg_set,
158490075Sobrien				    REGNO (XEXP (src2_note, 0)));
158590075Sobrien		replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
158690075Sobrien		regstack->top--;
158718334Speter	      }
158890075Sobrien	    else
158918334Speter	      {
159018334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
159118334Speter		replace_reg (dest, get_hard_regnum (regstack, *dest));
159218334Speter	      }
159390075Sobrien
1594132718Skan	    /* Keep operand 1 matching with destination.  */
1595169689Skan	    if (COMMUTATIVE_ARITH_P (pat_src)
159690075Sobrien		&& REG_P (*src1) && REG_P (*src2)
159790075Sobrien		&& REGNO (*src1) != REGNO (*dest))
159890075Sobrien	     {
159990075Sobrien		int tmp = REGNO (*src1);
160090075Sobrien		replace_reg (src1, REGNO (*src2));
160190075Sobrien		replace_reg (src2, tmp);
160290075Sobrien	     }
160390075Sobrien	    break;
160490075Sobrien
160590075Sobrien	  case UNSPEC:
160690075Sobrien	    switch (XINT (pat_src, 1))
160718334Speter	      {
1608169689Skan	      case UNSPEC_FIST:
1609169689Skan
1610169689Skan	      case UNSPEC_FIST_FLOOR:
1611169689Skan	      case UNSPEC_FIST_CEIL:
1612169689Skan
161390075Sobrien		/* These insns only operate on the top of the stack.  */
161418334Speter
161590075Sobrien		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
161690075Sobrien		emit_swap_insn (insn, regstack, *src1);
161718334Speter
161890075Sobrien		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
161918334Speter
162090075Sobrien		if (STACK_REG_P (*dest))
162190075Sobrien		  replace_reg (dest, FIRST_STACK_REG);
162218334Speter
162390075Sobrien		if (src1_note)
162490075Sobrien		  {
162590075Sobrien		    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
162690075Sobrien		    regstack->top--;
162790075Sobrien		    CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
162890075Sobrien		  }
162918334Speter
163090075Sobrien		replace_reg (src1, FIRST_STACK_REG);
163190075Sobrien		break;
163218334Speter
1633169689Skan	      case UNSPEC_SIN:
1634169689Skan	      case UNSPEC_COS:
1635169689Skan	      case UNSPEC_FRNDINT:
1636169689Skan	      case UNSPEC_F2XM1:
1637169689Skan
1638169689Skan	      case UNSPEC_FRNDINT_FLOOR:
1639169689Skan	      case UNSPEC_FRNDINT_CEIL:
1640169689Skan	      case UNSPEC_FRNDINT_TRUNC:
1641169689Skan	      case UNSPEC_FRNDINT_MASK_PM:
1642169689Skan
1643169689Skan		/* These insns only operate on the top of the stack.  */
1644169689Skan
1645169689Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1646169689Skan
1647169689Skan		emit_swap_insn (insn, regstack, *src1);
1648169689Skan
1649169689Skan		/* Input should never die, it is
1650169689Skan		   replaced with output.  */
1651169689Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1652169689Skan		gcc_assert (!src1_note);
1653169689Skan
1654169689Skan		if (STACK_REG_P (*dest))
1655169689Skan		  replace_reg (dest, FIRST_STACK_REG);
1656169689Skan
1657169689Skan		replace_reg (src1, FIRST_STACK_REG);
1658169689Skan		break;
1659169689Skan
1660132718Skan	      case UNSPEC_FPATAN:
1661132718Skan	      case UNSPEC_FYL2X:
1662169689Skan	      case UNSPEC_FYL2XP1:
1663132718Skan		/* These insns operate on the top two stack slots.  */
1664132718Skan
1665132718Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1666132718Skan		src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
1667132718Skan
1668132718Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1669132718Skan		src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
1670132718Skan
1671169689Skan		swap_to_top (insn, regstack, *src1, *src2);
1672132718Skan
1673132718Skan		replace_reg (src1, FIRST_STACK_REG);
1674132718Skan		replace_reg (src2, FIRST_STACK_REG + 1);
1675132718Skan
1676132718Skan		if (src1_note)
1677132718Skan		  replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
1678132718Skan		if (src2_note)
1679132718Skan		  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
1680132718Skan
1681132718Skan		/* Pop both input operands from the stack.  */
1682132718Skan		CLEAR_HARD_REG_BIT (regstack->reg_set,
1683132718Skan				    regstack->reg[regstack->top]);
1684132718Skan		CLEAR_HARD_REG_BIT (regstack->reg_set,
1685132718Skan				    regstack->reg[regstack->top - 1]);
1686132718Skan		regstack->top -= 2;
1687132718Skan
1688132718Skan		/* Push the result back onto the stack.  */
1689132718Skan		regstack->reg[++regstack->top] = REGNO (*dest);
1690132718Skan		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
1691132718Skan		replace_reg (dest, FIRST_STACK_REG);
1692132718Skan		break;
1693132718Skan
1694169689Skan	      case UNSPEC_FSCALE_FRACT:
1695169689Skan	      case UNSPEC_FPREM_F:
1696169689Skan	      case UNSPEC_FPREM1_F:
1697169689Skan		/* These insns operate on the top two stack slots.
1698169689Skan		   first part of double input, double output insn.  */
1699169689Skan
1700169689Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1701169689Skan		src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
1702169689Skan
1703169689Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1704169689Skan		src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
1705169689Skan
1706169689Skan		/* Inputs should never die, they are
1707169689Skan		   replaced with outputs.  */
1708169689Skan		gcc_assert (!src1_note);
1709169689Skan		gcc_assert (!src2_note);
1710169689Skan
1711169689Skan		swap_to_top (insn, regstack, *src1, *src2);
1712169689Skan
1713169689Skan		/* Push the result back onto stack. Empty stack slot
1714169689Skan		   will be filled in second part of insn.  */
1715169689Skan		if (STACK_REG_P (*dest)) {
1716169689Skan		  regstack->reg[regstack->top] = REGNO (*dest);
1717169689Skan		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
1718169689Skan		  replace_reg (dest, FIRST_STACK_REG);
1719169689Skan		}
1720169689Skan
1721169689Skan		replace_reg (src1, FIRST_STACK_REG);
1722169689Skan		replace_reg (src2, FIRST_STACK_REG + 1);
1723169689Skan		break;
1724169689Skan
1725169689Skan	      case UNSPEC_FSCALE_EXP:
1726169689Skan	      case UNSPEC_FPREM_U:
1727169689Skan	      case UNSPEC_FPREM1_U:
1728169689Skan		/* These insns operate on the top two stack slots./
1729169689Skan		   second part of double input, double output insn.  */
1730169689Skan
1731169689Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1732169689Skan		src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
1733169689Skan
1734169689Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1735169689Skan		src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
1736169689Skan
1737169689Skan		/* Inputs should never die, they are
1738169689Skan		   replaced with outputs.  */
1739169689Skan		gcc_assert (!src1_note);
1740169689Skan		gcc_assert (!src2_note);
1741169689Skan
1742169689Skan		swap_to_top (insn, regstack, *src1, *src2);
1743169689Skan
1744169689Skan		/* Push the result back onto stack. Fill empty slot from
1745169689Skan		   first part of insn and fix top of stack pointer.  */
1746169689Skan		if (STACK_REG_P (*dest)) {
1747169689Skan		  regstack->reg[regstack->top - 1] = REGNO (*dest);
1748169689Skan		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
1749169689Skan		  replace_reg (dest, FIRST_STACK_REG + 1);
1750169689Skan		}
1751169689Skan
1752169689Skan		replace_reg (src1, FIRST_STACK_REG);
1753169689Skan		replace_reg (src2, FIRST_STACK_REG + 1);
1754169689Skan		break;
1755169689Skan
1756169689Skan	      case UNSPEC_SINCOS_COS:
1757169689Skan	      case UNSPEC_TAN_ONE:
1758169689Skan	      case UNSPEC_XTRACT_FRACT:
1759169689Skan		/* These insns operate on the top two stack slots,
1760169689Skan		   first part of one input, double output insn.  */
1761169689Skan
1762169689Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1763169689Skan
1764169689Skan		emit_swap_insn (insn, regstack, *src1);
1765169689Skan
1766169689Skan		/* Input should never die, it is
1767169689Skan		   replaced with output.  */
1768169689Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1769169689Skan		gcc_assert (!src1_note);
1770169689Skan
1771169689Skan		/* Push the result back onto stack. Empty stack slot
1772169689Skan		   will be filled in second part of insn.  */
1773169689Skan		if (STACK_REG_P (*dest)) {
1774169689Skan		  regstack->reg[regstack->top + 1] = REGNO (*dest);
1775169689Skan		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
1776169689Skan		  replace_reg (dest, FIRST_STACK_REG);
1777169689Skan		}
1778169689Skan
1779169689Skan		replace_reg (src1, FIRST_STACK_REG);
1780169689Skan		break;
1781169689Skan
1782169689Skan	      case UNSPEC_SINCOS_SIN:
1783169689Skan	      case UNSPEC_TAN_TAN:
1784169689Skan	      case UNSPEC_XTRACT_EXP:
1785169689Skan		/* These insns operate on the top two stack slots,
1786169689Skan		   second part of one input, double output insn.  */
1787169689Skan
1788169689Skan		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
1789169689Skan
1790169689Skan		emit_swap_insn (insn, regstack, *src1);
1791169689Skan
1792169689Skan		/* Input should never die, it is
1793169689Skan		   replaced with output.  */
1794169689Skan		src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
1795169689Skan		gcc_assert (!src1_note);
1796169689Skan
1797169689Skan		/* Push the result back onto stack. Fill empty slot from
1798169689Skan		   first part of insn and fix top of stack pointer.  */
1799169689Skan		if (STACK_REG_P (*dest)) {
1800169689Skan		  regstack->reg[regstack->top] = REGNO (*dest);
1801169689Skan		  SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
1802169689Skan		  replace_reg (dest, FIRST_STACK_REG + 1);
1803169689Skan
1804169689Skan		  regstack->top++;
1805169689Skan		}
1806169689Skan
1807169689Skan		replace_reg (src1, FIRST_STACK_REG);
1808169689Skan		break;
1809169689Skan
1810117395Skan	      case UNSPEC_SAHF:
1811117395Skan		/* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
1812117395Skan		   The combination matches the PPRO fcomi instruction.  */
181318334Speter
181490075Sobrien		pat_src = XVECEXP (pat_src, 0, 0);
1815169689Skan		gcc_assert (GET_CODE (pat_src) == UNSPEC);
1816169689Skan		gcc_assert (XINT (pat_src, 1) == UNSPEC_FNSTSW);
1817132718Skan		/* Fall through.  */
181818334Speter
1819117395Skan	      case UNSPEC_FNSTSW:
182090075Sobrien		/* Combined fcomp+fnstsw generated for doing well with
182190075Sobrien		   CSE.  When optimizing this would have been broken
182290075Sobrien		   up before now.  */
182318334Speter
182490075Sobrien		pat_src = XVECEXP (pat_src, 0, 0);
1825169689Skan		gcc_assert (GET_CODE (pat_src) == COMPARE);
182618334Speter
182790075Sobrien		compare_for_stack_reg (insn, regstack, pat_src);
182890075Sobrien		break;
182918334Speter
183090075Sobrien	      default:
1831169689Skan		gcc_unreachable ();
183290075Sobrien	      }
183318334Speter	    break;
183418334Speter
183590075Sobrien	  case IF_THEN_ELSE:
183690075Sobrien	    /* This insn requires the top of stack to be the destination.  */
183718334Speter
183890075Sobrien	    src1 = get_true_reg (&XEXP (pat_src, 1));
183990075Sobrien	    src2 = get_true_reg (&XEXP (pat_src, 2));
184050397Sobrien
184190075Sobrien	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
184290075Sobrien	    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
184350397Sobrien
184490075Sobrien	    /* If the comparison operator is an FP comparison operator,
184590075Sobrien	       it is handled correctly by compare_for_stack_reg () who
184690075Sobrien	       will move the destination to the top of stack. But if the
184790075Sobrien	       comparison operator is not an FP comparison operator, we
184890075Sobrien	       have to handle it here.  */
184990075Sobrien	    if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
185090075Sobrien		&& REGNO (*dest) != regstack->reg[regstack->top])
185190075Sobrien	      {
185290075Sobrien		/* In case one of operands is the top of stack and the operands
1853117395Skan		   dies, it is safe to make it the destination operand by
1854117395Skan		   reversing the direction of cmove and avoid fxch.  */
185590075Sobrien		if ((REGNO (*src1) == regstack->reg[regstack->top]
185690075Sobrien		     && src1_note)
185790075Sobrien		    || (REGNO (*src2) == regstack->reg[regstack->top]
185890075Sobrien			&& src2_note))
185990075Sobrien		  {
186090075Sobrien		    int idx1 = (get_hard_regnum (regstack, *src1)
186190075Sobrien				- FIRST_STACK_REG);
186290075Sobrien		    int idx2 = (get_hard_regnum (regstack, *src2)
186390075Sobrien				- FIRST_STACK_REG);
186450397Sobrien
186590075Sobrien		    /* Make reg-stack believe that the operands are already
186690075Sobrien		       swapped on the stack */
186790075Sobrien		    regstack->reg[regstack->top - idx1] = REGNO (*src2);
186890075Sobrien		    regstack->reg[regstack->top - idx2] = REGNO (*src1);
186950397Sobrien
187090075Sobrien		    /* Reverse condition to compensate the operand swap.
187190075Sobrien		       i386 do have comparison always reversible.  */
187290075Sobrien		    PUT_CODE (XEXP (pat_src, 0),
187390075Sobrien			      reversed_comparison_code (XEXP (pat_src, 0), insn));
187490075Sobrien		  }
187590075Sobrien		else
1876117395Skan	          emit_swap_insn (insn, regstack, *dest);
187790075Sobrien	      }
187850397Sobrien
187990075Sobrien	    {
188090075Sobrien	      rtx src_note [3];
188190075Sobrien	      int i;
188250397Sobrien
188390075Sobrien	      src_note[0] = 0;
188490075Sobrien	      src_note[1] = src1_note;
188590075Sobrien	      src_note[2] = src2_note;
188650397Sobrien
188790075Sobrien	      if (STACK_REG_P (*src1))
188890075Sobrien		replace_reg (src1, get_hard_regnum (regstack, *src1));
188990075Sobrien	      if (STACK_REG_P (*src2))
189090075Sobrien		replace_reg (src2, get_hard_regnum (regstack, *src2));
189150397Sobrien
189290075Sobrien	      for (i = 1; i <= 2; i++)
189390075Sobrien		if (src_note [i])
189450397Sobrien		  {
189590075Sobrien		    int regno = REGNO (XEXP (src_note[i], 0));
189690075Sobrien
189790075Sobrien		    /* If the register that dies is not at the top of
1898169689Skan		       stack, then move the top of stack to the dead reg.
1899169689Skan		       Top of stack should never die, as it is the
1900169689Skan		       destination.  */
1901169689Skan		    gcc_assert (regno != regstack->reg[regstack->top]);
1902169689Skan		    remove_regno_note (insn, REG_DEAD, regno);
1903169689Skan		    emit_pop_insn (insn, regstack, XEXP (src_note[i], 0),
1904169689Skan				    EMIT_AFTER);
190550397Sobrien		  }
190690075Sobrien	    }
190750397Sobrien
190890075Sobrien	    /* Make dest the top of stack.  Add dest to regstack if
190990075Sobrien	       not present.  */
191090075Sobrien	    if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
1911117395Skan	      regstack->reg[++regstack->top] = REGNO (*dest);
191290075Sobrien	    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
191390075Sobrien	    replace_reg (dest, FIRST_STACK_REG);
191490075Sobrien	    break;
191550397Sobrien
191690075Sobrien	  default:
1917169689Skan	    gcc_unreachable ();
191890075Sobrien	  }
191950397Sobrien	break;
192090075Sobrien      }
192150397Sobrien
192290075Sobrien    default:
192390075Sobrien      break;
192490075Sobrien    }
1925132718Skan
1926132718Skan  return control_flow_insn_deleted;
192718334Speter}
192818334Speter
192918334Speter/* Substitute hard regnums for any stack regs in INSN, which has
193018334Speter   N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
193152284Sobrien   before the insn, and is updated with changes made here.
193218334Speter
193318334Speter   There are several requirements and assumptions about the use of
193418334Speter   stack-like regs in asm statements.  These rules are enforced by
193518334Speter   record_asm_stack_regs; see comments there for details.  Any
193618334Speter   asm_operands left in the RTL at this point may be assume to meet the
193718334Speter   requirements, since record_asm_stack_regs removes any problem asm.  */
193818334Speter
193918334Speterstatic void
1940132718Skansubst_asm_stack_regs (rtx insn, stack regstack)
194118334Speter{
194218334Speter  rtx body = PATTERN (insn);
194352284Sobrien  int alt;
194418334Speter
194518334Speter  rtx *note_reg;		/* Array of note contents */
194618334Speter  rtx **note_loc;		/* Address of REG field of each note */
194718334Speter  enum reg_note *note_kind;	/* The type of each note */
194818334Speter
194990075Sobrien  rtx *clobber_reg = 0;
195090075Sobrien  rtx **clobber_loc = 0;
195118334Speter
195218334Speter  struct stack_def temp_stack;
195318334Speter  int n_notes;
195418334Speter  int n_clobbers;
195518334Speter  rtx note;
195618334Speter  int i;
195752284Sobrien  int n_inputs, n_outputs;
195818334Speter
195990075Sobrien  if (! check_asm_stack_operands (insn))
196090075Sobrien    return;
196190075Sobrien
196218334Speter  /* Find out what the constraints required.  If no constraint
196318334Speter     alternative matches, that is a compiler bug: we should have caught
196490075Sobrien     such an insn in check_asm_stack_operands.  */
196552284Sobrien  extract_insn (insn);
196652284Sobrien  constrain_operands (1);
196752284Sobrien  alt = which_alternative;
196818334Speter
196952284Sobrien  preprocess_constraints ();
197052284Sobrien
197152284Sobrien  n_inputs = get_asm_operand_n_inputs (body);
197290075Sobrien  n_outputs = recog_data.n_operands - n_inputs;
1973117395Skan
1974169689Skan  gcc_assert (alt >= 0);
197518334Speter
197650397Sobrien  /* Strip SUBREGs here to make the following code simpler.  */
197790075Sobrien  for (i = 0; i < recog_data.n_operands; i++)
197890075Sobrien    if (GET_CODE (recog_data.operand[i]) == SUBREG
1979169689Skan	&& REG_P (SUBREG_REG (recog_data.operand[i])))
198018334Speter      {
198190075Sobrien	recog_data.operand_loc[i] = & SUBREG_REG (recog_data.operand[i]);
198290075Sobrien	recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
198318334Speter      }
198418334Speter
198518334Speter  /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND.  */
198618334Speter
198718334Speter  for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
198818334Speter    i++;
198918334Speter
1990132718Skan  note_reg = alloca (i * sizeof (rtx));
1991132718Skan  note_loc = alloca (i * sizeof (rtx *));
1992132718Skan  note_kind = alloca (i * sizeof (enum reg_note));
199318334Speter
199418334Speter  n_notes = 0;
199518334Speter  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
199618334Speter    {
199718334Speter      rtx reg = XEXP (note, 0);
199818334Speter      rtx *loc = & XEXP (note, 0);
199918334Speter
2000169689Skan      if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
200118334Speter	{
200218334Speter	  loc = & SUBREG_REG (reg);
200318334Speter	  reg = SUBREG_REG (reg);
200418334Speter	}
200518334Speter
200618334Speter      if (STACK_REG_P (reg)
200718334Speter	  && (REG_NOTE_KIND (note) == REG_DEAD
200818334Speter	      || REG_NOTE_KIND (note) == REG_UNUSED))
200918334Speter	{
201018334Speter	  note_reg[n_notes] = reg;
201118334Speter	  note_loc[n_notes] = loc;
201218334Speter	  note_kind[n_notes] = REG_NOTE_KIND (note);
201318334Speter	  n_notes++;
201418334Speter	}
201518334Speter    }
201618334Speter
201718334Speter  /* Set up CLOBBER_REG and CLOBBER_LOC.  */
201818334Speter
201918334Speter  n_clobbers = 0;
202018334Speter
202118334Speter  if (GET_CODE (body) == PARALLEL)
202218334Speter    {
2023132718Skan      clobber_reg = alloca (XVECLEN (body, 0) * sizeof (rtx));
2024132718Skan      clobber_loc = alloca (XVECLEN (body, 0) * sizeof (rtx *));
202518334Speter
202618334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
202718334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
202818334Speter	  {
202918334Speter	    rtx clobber = XVECEXP (body, 0, i);
203018334Speter	    rtx reg = XEXP (clobber, 0);
203118334Speter	    rtx *loc = & XEXP (clobber, 0);
203218334Speter
2033169689Skan	    if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
203418334Speter	      {
203518334Speter		loc = & SUBREG_REG (reg);
203618334Speter		reg = SUBREG_REG (reg);
203718334Speter	      }
203818334Speter
203918334Speter	    if (STACK_REG_P (reg))
204018334Speter	      {
204118334Speter		clobber_reg[n_clobbers] = reg;
204218334Speter		clobber_loc[n_clobbers] = loc;
204318334Speter		n_clobbers++;
204418334Speter	      }
204518334Speter	  }
204618334Speter    }
204718334Speter
204890075Sobrien  temp_stack = *regstack;
204918334Speter
205018334Speter  /* Put the input regs into the desired place in TEMP_STACK.  */
205118334Speter
205252284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
205390075Sobrien    if (STACK_REG_P (recog_data.operand[i])
2054169689Skan	&& reg_class_subset_p (recog_op_alt[i][alt].cl,
205552284Sobrien			       FLOAT_REGS)
2056169689Skan	&& recog_op_alt[i][alt].cl != FLOAT_REGS)
205718334Speter      {
205818334Speter	/* If an operand needs to be in a particular reg in
205918334Speter	   FLOAT_REGS, the constraint was either 't' or 'u'.  Since
206090075Sobrien	   these constraints are for single register classes, and
206190075Sobrien	   reload guaranteed that operand[i] is already in that class,
206290075Sobrien	   we can just use REGNO (recog_data.operand[i]) to know which
206390075Sobrien	   actual reg this operand needs to be in.  */
206418334Speter
206590075Sobrien	int regno = get_hard_regnum (&temp_stack, recog_data.operand[i]);
206618334Speter
2067169689Skan	gcc_assert (regno >= 0);
206818334Speter
206990075Sobrien	if ((unsigned int) regno != REGNO (recog_data.operand[i]))
207018334Speter	  {
207190075Sobrien	    /* recog_data.operand[i] is not in the right place.  Find
207290075Sobrien	       it and swap it with whatever is already in I's place.
207390075Sobrien	       K is where recog_data.operand[i] is now.  J is where it
207490075Sobrien	       should be.  */
207518334Speter	    int j, k, temp;
207618334Speter
207718334Speter	    k = temp_stack.top - (regno - FIRST_STACK_REG);
207818334Speter	    j = (temp_stack.top
207990075Sobrien		 - (REGNO (recog_data.operand[i]) - FIRST_STACK_REG));
208018334Speter
208118334Speter	    temp = temp_stack.reg[k];
208218334Speter	    temp_stack.reg[k] = temp_stack.reg[j];
208318334Speter	    temp_stack.reg[j] = temp;
208418334Speter	  }
208518334Speter      }
208618334Speter
208790075Sobrien  /* Emit insns before INSN to make sure the reg-stack is in the right
208818334Speter     order.  */
208918334Speter
209090075Sobrien  change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
209118334Speter
209218334Speter  /* Make the needed input register substitutions.  Do death notes and
209350397Sobrien     clobbers too, because these are for inputs, not outputs.  */
209418334Speter
209552284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
209690075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
209718334Speter      {
209890075Sobrien	int regnum = get_hard_regnum (regstack, recog_data.operand[i]);
209918334Speter
2100169689Skan	gcc_assert (regnum >= 0);
210118334Speter
210290075Sobrien	replace_reg (recog_data.operand_loc[i], regnum);
210318334Speter      }
210418334Speter
210518334Speter  for (i = 0; i < n_notes; i++)
210618334Speter    if (note_kind[i] == REG_DEAD)
210718334Speter      {
210818334Speter	int regnum = get_hard_regnum (regstack, note_reg[i]);
210918334Speter
2110169689Skan	gcc_assert (regnum >= 0);
211118334Speter
211218334Speter	replace_reg (note_loc[i], regnum);
211318334Speter      }
211418334Speter
211518334Speter  for (i = 0; i < n_clobbers; i++)
211618334Speter    {
211718334Speter      /* It's OK for a CLOBBER to reference a reg that is not live.
211818334Speter         Don't try to replace it in that case.  */
211918334Speter      int regnum = get_hard_regnum (regstack, clobber_reg[i]);
212018334Speter
212118334Speter      if (regnum >= 0)
212218334Speter	{
212318334Speter	  /* Sigh - clobbers always have QImode.  But replace_reg knows
2124169689Skan	     that these regs can't be MODE_INT and will assert.  Just put
212518334Speter	     the right reg there without calling replace_reg.  */
212618334Speter
212718334Speter	  *clobber_loc[i] = FP_MODE_REG (regnum, DFmode);
212818334Speter	}
212918334Speter    }
213018334Speter
213150397Sobrien  /* Now remove from REGSTACK any inputs that the asm implicitly popped.  */
213218334Speter
213352284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
213490075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
213518334Speter      {
213618334Speter	/* An input reg is implicitly popped if it is tied to an
213750397Sobrien	   output, or if there is a CLOBBER for it.  */
213818334Speter	int j;
213918334Speter
214018334Speter	for (j = 0; j < n_clobbers; j++)
214190075Sobrien	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
214218334Speter	    break;
214318334Speter
214452284Sobrien	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
214518334Speter	  {
214690075Sobrien	    /* recog_data.operand[i] might not be at the top of stack.
214790075Sobrien	       But that's OK, because all we need to do is pop the
214890075Sobrien	       right number of regs off of the top of the reg-stack.
214990075Sobrien	       record_asm_stack_regs guaranteed that all implicitly
215090075Sobrien	       popped regs were grouped at the top of the reg-stack.  */
215118334Speter
215218334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set,
215318334Speter				regstack->reg[regstack->top]);
215418334Speter	    regstack->top--;
215518334Speter	  }
215618334Speter      }
215718334Speter
215818334Speter  /* Now add to REGSTACK any outputs that the asm implicitly pushed.
215918334Speter     Note that there isn't any need to substitute register numbers.
216050397Sobrien     ???  Explain why this is true.  */
216118334Speter
216218334Speter  for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
216318334Speter    {
216418334Speter      /* See if there is an output for this hard reg.  */
216518334Speter      int j;
216618334Speter
216718334Speter      for (j = 0; j < n_outputs; j++)
216890075Sobrien	if (STACK_REG_P (recog_data.operand[j])
216990075Sobrien	    && REGNO (recog_data.operand[j]) == (unsigned) i)
217018334Speter	  {
217118334Speter	    regstack->reg[++regstack->top] = i;
217218334Speter	    SET_HARD_REG_BIT (regstack->reg_set, i);
217318334Speter	    break;
217418334Speter	  }
217518334Speter    }
217618334Speter
217718334Speter  /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
217818334Speter     input that the asm didn't implicitly pop.  If the asm didn't
217918334Speter     implicitly pop an input reg, that reg will still be live.
218018334Speter
218118334Speter     Note that we can't use find_regno_note here: the register numbers
218218334Speter     in the death notes have already been substituted.  */
218318334Speter
218418334Speter  for (i = 0; i < n_outputs; i++)
218590075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
218618334Speter      {
218718334Speter	int j;
218818334Speter
218918334Speter	for (j = 0; j < n_notes; j++)
219090075Sobrien	  if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
219118334Speter	      && note_kind[j] == REG_UNUSED)
219218334Speter	    {
219390075Sobrien	      insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
219490075Sobrien				    EMIT_AFTER);
219518334Speter	      break;
219618334Speter	    }
219718334Speter      }
219818334Speter
219952284Sobrien  for (i = n_outputs; i < n_outputs + n_inputs; i++)
220090075Sobrien    if (STACK_REG_P (recog_data.operand[i]))
220118334Speter      {
220218334Speter	int j;
220318334Speter
220418334Speter	for (j = 0; j < n_notes; j++)
220590075Sobrien	  if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
220618334Speter	      && note_kind[j] == REG_DEAD
220752284Sobrien	      && TEST_HARD_REG_BIT (regstack->reg_set,
220890075Sobrien				    REGNO (recog_data.operand[i])))
220918334Speter	    {
221090075Sobrien	      insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
221190075Sobrien				    EMIT_AFTER);
221218334Speter	      break;
221318334Speter	    }
221418334Speter      }
221518334Speter}
221618334Speter
221718334Speter/* Substitute stack hard reg numbers for stack virtual registers in
221818334Speter   INSN.  Non-stack register numbers are not changed.  REGSTACK is the
221918334Speter   current stack content.  Insns may be emitted as needed to arrange the
2220132718Skan   stack for the 387 based on the contents of the insn.  Return whether
2221132718Skan   a control flow insn was deleted in the process.  */
222218334Speter
2223132718Skanstatic bool
2224132718Skansubst_stack_regs (rtx insn, stack regstack)
222518334Speter{
222690075Sobrien  rtx *note_link, note;
2227132718Skan  bool control_flow_insn_deleted = false;
222890075Sobrien  int i;
222918334Speter
2230169689Skan  if (CALL_P (insn))
223190075Sobrien    {
223290075Sobrien      int top = regstack->top;
223318334Speter
223490075Sobrien      /* If there are any floating point parameters to be passed in
223590075Sobrien	 registers for this call, make sure they are in the right
223690075Sobrien	 order.  */
223718334Speter
223890075Sobrien      if (top >= 0)
223990075Sobrien	{
2240169689Skan	  straighten_stack (insn, regstack);
224118334Speter
224290075Sobrien	  /* Now mark the arguments as dead after the call.  */
224318334Speter
224490075Sobrien	  while (regstack->top >= 0)
224590075Sobrien	    {
224690075Sobrien	      CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top);
224790075Sobrien	      regstack->top--;
224890075Sobrien	    }
224990075Sobrien	}
225090075Sobrien    }
225118334Speter
225218334Speter  /* Do the actual substitution if any stack regs are mentioned.
225318334Speter     Since we only record whether entire insn mentions stack regs, and
225418334Speter     subst_stack_regs_pat only works for patterns that contain stack regs,
225518334Speter     we must check each pattern in a parallel here.  A call_value_pop could
225650397Sobrien     fail otherwise.  */
225718334Speter
225852284Sobrien  if (stack_regs_mentioned (insn))
225918334Speter    {
226052284Sobrien      int n_operands = asm_noperands (PATTERN (insn));
226118334Speter      if (n_operands >= 0)
226218334Speter	{
226318334Speter	  /* This insn is an `asm' with operands.  Decode the operands,
226418334Speter	     decide how many are inputs, and do register substitution.
226550397Sobrien	     Any REG_UNUSED notes will be handled by subst_asm_stack_regs.  */
226618334Speter
226752284Sobrien	  subst_asm_stack_regs (insn, regstack);
2268132718Skan	  return control_flow_insn_deleted;
226918334Speter	}
227018334Speter
227118334Speter      if (GET_CODE (PATTERN (insn)) == PARALLEL)
227218334Speter	for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
227318334Speter	  {
227418334Speter	    if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
2275169689Skan	      {
2276169689Skan	        if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
2277169689Skan	           XVECEXP (PATTERN (insn), 0, i)
2278169689Skan		     = shallow_copy_rtx (XVECEXP (PATTERN (insn), 0, i));
2279169689Skan		control_flow_insn_deleted
2280169689Skan		  |= subst_stack_regs_pat (insn, regstack,
2281169689Skan					   XVECEXP (PATTERN (insn), 0, i));
2282169689Skan	      }
228318334Speter	  }
228418334Speter      else
2285132718Skan	control_flow_insn_deleted
2286132718Skan	  |= subst_stack_regs_pat (insn, regstack, PATTERN (insn));
228718334Speter    }
228818334Speter
228918334Speter  /* subst_stack_regs_pat may have deleted a no-op insn.  If so, any
229050397Sobrien     REG_UNUSED will already have been dealt with, so just return.  */
229118334Speter
2292169689Skan  if (NOTE_P (insn) || INSN_DELETED_P (insn))
2293132718Skan    return control_flow_insn_deleted;
229418334Speter
2295169689Skan  /* If this a noreturn call, we can't insert pop insns after it.
2296169689Skan     Instead, reset the stack state to empty.  */
2297169689Skan  if (CALL_P (insn)
2298169689Skan      && find_reg_note (insn, REG_NORETURN, NULL))
2299169689Skan    {
2300169689Skan      regstack->top = -1;
2301169689Skan      CLEAR_HARD_REG_SET (regstack->reg_set);
2302169689Skan      return control_flow_insn_deleted;
2303169689Skan    }
2304169689Skan
230518334Speter  /* If there is a REG_UNUSED note on a stack register on this insn,
230618334Speter     the indicated reg must be popped.  The REG_UNUSED note is removed,
230718334Speter     since the form of the newly emitted pop insn references the reg,
230850397Sobrien     making it no longer `unset'.  */
230918334Speter
231090075Sobrien  note_link = &REG_NOTES (insn);
231118334Speter  for (note = *note_link; note; note = XEXP (note, 1))
231218334Speter    if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
231318334Speter      {
231418334Speter	*note_link = XEXP (note, 1);
231590075Sobrien	insn = emit_pop_insn (insn, regstack, XEXP (note, 0), EMIT_AFTER);
231618334Speter      }
231718334Speter    else
231818334Speter      note_link = &XEXP (note, 1);
2319132718Skan
2320132718Skan  return control_flow_insn_deleted;
232118334Speter}
232218334Speter
232318334Speter/* Change the organization of the stack so that it fits a new basic
232418334Speter   block.  Some registers might have to be popped, but there can never be
232518334Speter   a register live in the new block that is not now live.
232618334Speter
232790075Sobrien   Insert any needed insns before or after INSN, as indicated by
232890075Sobrien   WHERE.  OLD is the original stack layout, and NEW is the desired
2329169689Skan   form.  OLD is updated to reflect the code emitted, i.e., it will be
233090075Sobrien   the same as NEW upon return.
233118334Speter
233218334Speter   This function will not preserve block_end[].  But that information
233350397Sobrien   is no longer needed once this has executed.  */
233418334Speter
233518334Speterstatic void
2336132718Skanchange_stack (rtx insn, stack old, stack new, enum emit_where where)
233718334Speter{
233818334Speter  int reg;
233990075Sobrien  int update_end = 0;
234018334Speter
2341169689Skan  /* Stack adjustments for the first insn in a block update the
2342169689Skan     current_block's stack_in instead of inserting insns directly.
2343169689Skan     compensate_edges will add the necessary code later.  */
2344169689Skan  if (current_block
2345169689Skan      && starting_stack_p
2346169689Skan      && where == EMIT_BEFORE)
2347169689Skan    {
2348169689Skan      BLOCK_INFO (current_block)->stack_in = *new;
2349169689Skan      starting_stack_p = false;
2350169689Skan      *old = *new;
2351169689Skan      return;
2352169689Skan    }
2353169689Skan
235490075Sobrien  /* We will be inserting new insns "backwards".  If we are to insert
235590075Sobrien     after INSN, find the next insn, and insert before it.  */
235618334Speter
235790075Sobrien  if (where == EMIT_AFTER)
235890075Sobrien    {
2359132718Skan      if (current_block && BB_END (current_block) == insn)
236090075Sobrien	update_end = 1;
236190075Sobrien      insn = NEXT_INSN (insn);
236290075Sobrien    }
236318334Speter
236450397Sobrien  /* Pop any registers that are not needed in the new block.  */
236518334Speter
2366169689Skan  /* If the destination block's stack already has a specified layout
2367169689Skan     and contains two or more registers, use a more intelligent algorithm
2368169689Skan     to pop registers that minimizes the number number of fxchs below.  */
2369169689Skan  if (new->top > 0)
2370169689Skan    {
2371169689Skan      bool slots[REG_STACK_SIZE];
2372169689Skan      int pops[REG_STACK_SIZE];
2373169689Skan      int next, dest, topsrc;
237418334Speter
2375169689Skan      /* First pass to determine the free slots.  */
2376169689Skan      for (reg = 0; reg <= new->top; reg++)
2377169689Skan	slots[reg] = TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]);
2378169689Skan
2379169689Skan      /* Second pass to allocate preferred slots.  */
2380169689Skan      topsrc = -1;
2381169689Skan      for (reg = old->top; reg > new->top; reg--)
2382169689Skan	if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
2383169689Skan	  {
2384169689Skan	    dest = -1;
2385169689Skan	    for (next = 0; next <= new->top; next++)
2386169689Skan	      if (!slots[next] && new->reg[next] == old->reg[reg])
2387169689Skan		{
2388169689Skan		  /* If this is a preference for the new top of stack, record
2389169689Skan		     the fact by remembering it's old->reg in topsrc.  */
2390169689Skan                  if (next == new->top)
2391169689Skan		    topsrc = reg;
2392169689Skan		  slots[next] = true;
2393169689Skan		  dest = next;
2394169689Skan		  break;
2395169689Skan		}
2396169689Skan	    pops[reg] = dest;
2397169689Skan	  }
2398169689Skan	else
2399169689Skan	  pops[reg] = reg;
2400169689Skan
2401169689Skan      /* Intentionally, avoid placing the top of stack in it's correct
2402169689Skan	 location, if we still need to permute the stack below and we
2403169689Skan	 can usefully place it somewhere else.  This is the case if any
2404169689Skan	 slot is still unallocated, in which case we should place the
2405169689Skan	 top of stack there.  */
2406169689Skan      if (topsrc != -1)
2407169689Skan	for (reg = 0; reg < new->top; reg++)
2408169689Skan	  if (!slots[reg])
2409169689Skan	    {
2410169689Skan	      pops[topsrc] = reg;
2411169689Skan	      slots[new->top] = false;
2412169689Skan	      slots[reg] = true;
2413169689Skan	      break;
2414169689Skan	    }
2415169689Skan
2416169689Skan      /* Third pass allocates remaining slots and emits pop insns.  */
2417169689Skan      next = new->top;
2418169689Skan      for (reg = old->top; reg > new->top; reg--)
2419169689Skan	{
2420169689Skan	  dest = pops[reg];
2421169689Skan	  if (dest == -1)
2422169689Skan	    {
2423169689Skan	      /* Find next free slot.  */
2424169689Skan	      while (slots[next])
2425169689Skan		next--;
2426169689Skan	      dest = next--;
2427169689Skan	    }
2428169689Skan	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], DFmode),
2429169689Skan			 EMIT_BEFORE);
2430169689Skan	}
2431169689Skan    }
2432169689Skan  else
2433169689Skan    {
2434169689Skan      /* The following loop attempts to maximize the number of times we
2435169689Skan	 pop the top of the stack, as this permits the use of the faster
2436169689Skan	 ffreep instruction on platforms that support it.  */
2437169689Skan      int live, next;
2438169689Skan
2439169689Skan      live = 0;
2440169689Skan      for (reg = 0; reg <= old->top; reg++)
2441169689Skan        if (TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
2442169689Skan          live++;
2443169689Skan
2444169689Skan      next = live;
2445169689Skan      while (old->top >= live)
2446169689Skan        if (TEST_HARD_REG_BIT (new->reg_set, old->reg[old->top]))
2447169689Skan	  {
2448169689Skan	    while (TEST_HARD_REG_BIT (new->reg_set, old->reg[next]))
2449169689Skan	      next--;
2450169689Skan	    emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], DFmode),
2451169689Skan			   EMIT_BEFORE);
2452169689Skan	  }
2453169689Skan	else
2454169689Skan	  emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], DFmode),
2455169689Skan			 EMIT_BEFORE);
2456169689Skan    }
2457169689Skan
245818334Speter  if (new->top == -2)
245918334Speter    {
246018334Speter      /* If the new block has never been processed, then it can inherit
246150397Sobrien	 the old stack order.  */
246218334Speter
246318334Speter      new->top = old->top;
246490075Sobrien      memcpy (new->reg, old->reg, sizeof (new->reg));
246518334Speter    }
246618334Speter  else
246718334Speter    {
246818334Speter      /* This block has been entered before, and we must match the
246950397Sobrien	 previously selected stack order.  */
247018334Speter
247118334Speter      /* By now, the only difference should be the order of the stack,
247250397Sobrien	 not their depth or liveliness.  */
247318334Speter
247418334Speter      GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win);
2475169689Skan      gcc_unreachable ();
247618334Speter    win:
2477169689Skan      gcc_assert (old->top == new->top);
247818334Speter
247952284Sobrien      /* If the stack is not empty (new->top != -1), loop here emitting
2480117395Skan	 swaps until the stack is correct.
248152284Sobrien
248252284Sobrien	 The worst case number of swaps emitted is N + 2, where N is the
248318334Speter	 depth of the stack.  In some cases, the reg at the top of
248418334Speter	 stack may be correct, but swapped anyway in order to fix
248518334Speter	 other regs.  But since we never swap any other reg away from
248650397Sobrien	 its correct slot, this algorithm will converge.  */
248718334Speter
248852284Sobrien      if (new->top != -1)
248952284Sobrien	do
249052284Sobrien	  {
249152284Sobrien	    /* Swap the reg at top of stack into the position it is
249252284Sobrien	       supposed to be in, until the correct top of stack appears.  */
249318334Speter
249452284Sobrien	    while (old->reg[old->top] != new->reg[new->top])
249552284Sobrien	      {
249652284Sobrien		for (reg = new->top; reg >= 0; reg--)
249752284Sobrien		  if (new->reg[reg] == old->reg[old->top])
249852284Sobrien		    break;
249918334Speter
2500169689Skan		gcc_assert (reg != -1);
250118334Speter
250252284Sobrien		emit_swap_insn (insn, old,
250352284Sobrien				FP_MODE_REG (old->reg[reg], DFmode));
250452284Sobrien	      }
250518334Speter
250652284Sobrien	    /* See if any regs remain incorrect.  If so, bring an
250718334Speter	     incorrect reg to the top of stack, and let the while loop
250850397Sobrien	     above fix it.  */
250918334Speter
251052284Sobrien	    for (reg = new->top; reg >= 0; reg--)
251152284Sobrien	      if (new->reg[reg] != old->reg[reg])
251252284Sobrien		{
251352284Sobrien		  emit_swap_insn (insn, old,
251452284Sobrien				  FP_MODE_REG (old->reg[reg], DFmode));
251552284Sobrien		  break;
251652284Sobrien		}
251752284Sobrien	  } while (reg >= 0);
251818334Speter
251950397Sobrien      /* At this point there must be no differences.  */
252018334Speter
252118334Speter      for (reg = old->top; reg >= 0; reg--)
2522169689Skan	gcc_assert (old->reg[reg] == new->reg[reg]);
252318334Speter    }
252490075Sobrien
252590075Sobrien  if (update_end)
2526132718Skan    BB_END (current_block) = PREV_INSN (insn);
252718334Speter}
252818334Speter
252990075Sobrien/* Print stack configuration.  */
253018334Speter
253118334Speterstatic void
2532132718Skanprint_stack (FILE *file, stack s)
253318334Speter{
253490075Sobrien  if (! file)
253590075Sobrien    return;
253618334Speter
253790075Sobrien  if (s->top == -2)
253890075Sobrien    fprintf (file, "uninitialized\n");
253990075Sobrien  else if (s->top == -1)
254090075Sobrien    fprintf (file, "empty\n");
254190075Sobrien  else
254290075Sobrien    {
254390075Sobrien      int i;
254490075Sobrien      fputs ("[ ", file);
254590075Sobrien      for (i = 0; i <= s->top; ++i)
254690075Sobrien	fprintf (file, "%d ", s->reg[i]);
254790075Sobrien      fputs ("]\n", file);
254890075Sobrien    }
254990075Sobrien}
255090075Sobrien
255190075Sobrien/* This function was doing life analysis.  We now let the regular live
2552117395Skan   code do it's job, so we only need to check some extra invariants
255390075Sobrien   that reg-stack expects.  Primary among these being that all registers
255490075Sobrien   are initialized before use.
255518334Speter
255690075Sobrien   The function returns true when code was emitted to CFG edges and
255790075Sobrien   commit_edge_insertions needs to be called.  */
255890075Sobrien
255990075Sobrienstatic int
2560132718Skanconvert_regs_entry (void)
256190075Sobrien{
2562117395Skan  int inserted = 0;
256390075Sobrien  edge e;
2564169689Skan  edge_iterator ei;
256590075Sobrien
2566117395Skan  /* Load something into each stack register live at function entry.
256790075Sobrien     Such live registers can be caused by uninitialized variables or
2568117395Skan     functions not returning values on all paths.  In order to keep
256990075Sobrien     the push/pop code happy, and to not scrog the register stack, we
2570117395Skan     must put something in these registers.  Use a QNaN.
257118334Speter
2572132718Skan     Note that we are inserting converted code here.  This code is
257390075Sobrien     never seen by the convert_regs pass.  */
257418334Speter
2575169689Skan  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
257690075Sobrien    {
257790075Sobrien      basic_block block = e->dest;
257890075Sobrien      block_info bi = BLOCK_INFO (block);
257990075Sobrien      int reg, top = -1;
258018334Speter
258190075Sobrien      for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
258290075Sobrien	if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
258390075Sobrien	  {
258490075Sobrien	    rtx init;
258590075Sobrien
258690075Sobrien	    bi->stack_in.reg[++top] = reg;
258790075Sobrien
258890075Sobrien	    init = gen_rtx_SET (VOIDmode,
258990075Sobrien				FP_MODE_REG (FIRST_STACK_REG, SFmode),
2590169689Skan				not_a_num);
259190075Sobrien	    insert_insn_on_edge (init, e);
259290075Sobrien	    inserted = 1;
259390075Sobrien	  }
259490075Sobrien
259590075Sobrien      bi->stack_in.top = top;
259690075Sobrien    }
259790075Sobrien
259890075Sobrien  return inserted;
259990075Sobrien}
260090075Sobrien
260190075Sobrien/* Construct the desired stack for function exit.  This will either
260290075Sobrien   be `empty', or the function return value at top-of-stack.  */
260390075Sobrien
260490075Sobrienstatic void
2605132718Skanconvert_regs_exit (void)
260690075Sobrien{
260790075Sobrien  int value_reg_low, value_reg_high;
260890075Sobrien  stack output_stack;
260990075Sobrien  rtx retvalue;
261090075Sobrien
261190075Sobrien  retvalue = stack_result (current_function_decl);
261290075Sobrien  value_reg_low = value_reg_high = -1;
261390075Sobrien  if (retvalue)
261418334Speter    {
261590075Sobrien      value_reg_low = REGNO (retvalue);
261690075Sobrien      value_reg_high = value_reg_low
2617169689Skan	+ hard_regno_nregs[value_reg_low][GET_MODE (retvalue)] - 1;
261890075Sobrien    }
261918334Speter
262090075Sobrien  output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR)->stack_in;
262190075Sobrien  if (value_reg_low == -1)
262290075Sobrien    output_stack->top = -1;
262390075Sobrien  else
262490075Sobrien    {
262590075Sobrien      int reg;
262690075Sobrien
262790075Sobrien      output_stack->top = value_reg_high - value_reg_low;
262890075Sobrien      for (reg = value_reg_low; reg <= value_reg_high; ++reg)
262990075Sobrien	{
2630102780Skan	  output_stack->reg[value_reg_high - reg] = reg;
263190075Sobrien	  SET_HARD_REG_BIT (output_stack->reg_set, reg);
263290075Sobrien	}
263390075Sobrien    }
263490075Sobrien}
263590075Sobrien
2636169689Skan/* Copy the stack info from the end of edge E's source block to the
2637169689Skan   start of E's destination block.  */
2638169689Skan
2639169689Skanstatic void
2640169689Skanpropagate_stack (edge e)
2641169689Skan{
2642169689Skan  stack src_stack = &BLOCK_INFO (e->src)->stack_out;
2643169689Skan  stack dest_stack = &BLOCK_INFO (e->dest)->stack_in;
2644169689Skan  int reg;
2645169689Skan
2646169689Skan  /* Preserve the order of the original stack, but check whether
2647169689Skan     any pops are needed.  */
2648169689Skan  dest_stack->top = -1;
2649169689Skan  for (reg = 0; reg <= src_stack->top; ++reg)
2650169689Skan    if (TEST_HARD_REG_BIT (dest_stack->reg_set, src_stack->reg[reg]))
2651169689Skan      dest_stack->reg[++dest_stack->top] = src_stack->reg[reg];
2652169689Skan}
2653169689Skan
2654169689Skan
2655169689Skan/* Adjust the stack of edge E's source block on exit to match the stack
2656169689Skan   of it's target block upon input.  The stack layouts of both blocks
2657169689Skan   should have been defined by now.  */
2658169689Skan
265990075Sobrienstatic bool
2660169689Skancompensate_edge (edge e)
266190075Sobrien{
2662169689Skan  basic_block source = e->src, target = e->dest;
266390075Sobrien  stack target_stack = &BLOCK_INFO (target)->stack_in;
2664169689Skan  stack source_stack = &BLOCK_INFO (source)->stack_out;
2665169689Skan  struct stack_def regstack;
266690075Sobrien  int reg;
266790075Sobrien
2668169689Skan  if (dump_file)
2669169689Skan    fprintf (dump_file, "Edge %d->%d: ", source->index, target->index);
267090075Sobrien
2671169689Skan  gcc_assert (target_stack->top != -2);
2672169689Skan
2673169689Skan  /* Check whether stacks are identical.  */
2674169689Skan  if (target_stack->top == source_stack->top)
267590075Sobrien    {
2676169689Skan      for (reg = target_stack->top; reg >= 0; --reg)
2677169689Skan	if (target_stack->reg[reg] != source_stack->reg[reg])
267818334Speter	  break;
267918334Speter
268018334Speter      if (reg == -1)
268118334Speter	{
2682169689Skan	  if (dump_file)
2683169689Skan	    fprintf (dump_file, "no changes needed\n");
2684117395Skan	  return false;
268518334Speter	}
2686169689Skan    }
268790075Sobrien
2688169689Skan  if (dump_file)
268918334Speter    {
2690169689Skan      fprintf (dump_file, "correcting stack to ");
2691169689Skan      print_stack (dump_file, target_stack);
269218334Speter    }
269318334Speter
2694169689Skan  /* Abnormal calls may appear to have values live in st(0), but the
269590075Sobrien     abnormal return path will not have actually loaded the values.  */
2696169689Skan  if (e->flags & EDGE_ABNORMAL_CALL)
269790075Sobrien    {
269890075Sobrien      /* Assert that the lifetimes are as we expect -- one value
269990075Sobrien         live at st(0) on the end of the source block, and no
2700169689Skan         values live at the beginning of the destination block.
2701117395Skan	 For complex return values, we may have st(1) live as well.  */
2702169689Skan      gcc_assert (source_stack->top == 0 || source_stack->top == 1);
2703169689Skan      gcc_assert (target_stack->top == -1);
2704169689Skan      return false;
2705169689Skan    }
270618334Speter
2707169689Skan  /* Handle non-call EH edges specially.  The normal return path have
2708169689Skan     values in registers.  These will be popped en masse by the unwind
2709169689Skan     library.  */
2710169689Skan  if (e->flags & EDGE_EH)
2711169689Skan    {
2712169689Skan      gcc_assert (target_stack->top == -1);
2713169689Skan      return false;
271490075Sobrien    }
271518334Speter
2716169689Skan  /* We don't support abnormal edges.  Global takes care to
2717169689Skan     avoid any live register across them, so we should never
2718169689Skan     have to insert instructions on such edges.  */
2719169689Skan  gcc_assert (! (e->flags & EDGE_ABNORMAL));
2720169689Skan
2721169689Skan  /* Make a copy of source_stack as change_stack is destructive.  */
2722169689Skan  regstack = *source_stack;
2723169689Skan
272490075Sobrien  /* It is better to output directly to the end of the block
272590075Sobrien     instead of to the edge, because emit_swap can do minimal
272690075Sobrien     insn scheduling.  We can do this when there is only one
272790075Sobrien     edge out, and it is not abnormal.  */
2728169689Skan  if (EDGE_COUNT (source->succs) == 1)
272990075Sobrien    {
2730169689Skan      current_block = source;
2731169689Skan      change_stack (BB_END (source), &regstack, target_stack,
2732169689Skan		    (JUMP_P (BB_END (source)) ? EMIT_BEFORE : EMIT_AFTER));
273390075Sobrien    }
273490075Sobrien  else
273590075Sobrien    {
273690075Sobrien      rtx seq, after;
273718334Speter
273890075Sobrien      current_block = NULL;
273990075Sobrien      start_sequence ();
274018334Speter
2741117395Skan      /* ??? change_stack needs some point to emit insns after.  */
2742132718Skan      after = emit_note (NOTE_INSN_DELETED);
274318334Speter
2744169689Skan      change_stack (after, &regstack, target_stack, EMIT_BEFORE);
274518334Speter
2746117395Skan      seq = get_insns ();
274790075Sobrien      end_sequence ();
274818334Speter
274990075Sobrien      insert_insn_on_edge (seq, e);
275090075Sobrien      return true;
275190075Sobrien    }
275290075Sobrien  return false;
275318334Speter}
275418334Speter
2755169689Skan/* Traverse all non-entry edges in the CFG, and emit the necessary
2756169689Skan   edge compensation code to change the stack from stack_out of the
2757169689Skan   source block to the stack_in of the destination block.  */
2758169689Skan
2759169689Skanstatic bool
2760169689Skancompensate_edges (void)
2761169689Skan{
2762169689Skan  bool inserted = false;
2763169689Skan  basic_block bb;
2764169689Skan
2765169689Skan  starting_stack_p = false;
2766169689Skan
2767169689Skan  FOR_EACH_BB (bb)
2768169689Skan    if (bb != ENTRY_BLOCK_PTR)
2769169689Skan      {
2770169689Skan        edge e;
2771169689Skan        edge_iterator ei;
2772169689Skan
2773169689Skan        FOR_EACH_EDGE (e, ei, bb->succs)
2774169689Skan	  inserted |= compensate_edge (e);
2775169689Skan      }
2776169689Skan  return inserted;
2777169689Skan}
2778169689Skan
2779169689Skan/* Select the better of two edges E1 and E2 to use to determine the
2780169689Skan   stack layout for their shared destination basic block.  This is
2781169689Skan   typically the more frequently executed.  The edge E1 may be NULL
2782169689Skan   (in which case E2 is returned), but E2 is always non-NULL.  */
2783169689Skan
2784169689Skanstatic edge
2785169689Skanbetter_edge (edge e1, edge e2)
2786169689Skan{
2787169689Skan  if (!e1)
2788169689Skan    return e2;
2789169689Skan
2790169689Skan  if (EDGE_FREQUENCY (e1) > EDGE_FREQUENCY (e2))
2791169689Skan    return e1;
2792169689Skan  if (EDGE_FREQUENCY (e1) < EDGE_FREQUENCY (e2))
2793169689Skan    return e2;
2794169689Skan
2795169689Skan  if (e1->count > e2->count)
2796169689Skan    return e1;
2797169689Skan  if (e1->count < e2->count)
2798169689Skan    return e2;
2799169689Skan
2800169689Skan  /* Prefer critical edges to minimize inserting compensation code on
2801169689Skan     critical edges.  */
2802169689Skan
2803169689Skan  if (EDGE_CRITICAL_P (e1) != EDGE_CRITICAL_P (e2))
2804169689Skan    return EDGE_CRITICAL_P (e1) ? e1 : e2;
2805169689Skan
2806169689Skan  /* Avoid non-deterministic behavior.  */
2807169689Skan  return (e1->src->index < e2->src->index) ? e1 : e2;
2808169689Skan}
2809169689Skan
281090075Sobrien/* Convert stack register references in one block.  */
281190075Sobrien
2812169689Skanstatic void
2813169689Skanconvert_regs_1 (basic_block block)
281418334Speter{
281518334Speter  struct stack_def regstack;
281690075Sobrien  block_info bi = BLOCK_INFO (block);
2817169689Skan  int reg;
281890075Sobrien  rtx insn, next;
2819132718Skan  bool control_flow_insn_deleted = false;
282018334Speter
2821117395Skan  any_malformed_asm = false;
282290075Sobrien
2823169689Skan  /* Choose an initial stack layout, if one hasn't already been chosen.  */
2824169689Skan  if (bi->stack_in.top == -2)
282518334Speter    {
2826169689Skan      edge e, beste = NULL;
2827169689Skan      edge_iterator ei;
282818334Speter
2829169689Skan      /* Select the best incoming edge (typically the most frequent) to
2830169689Skan	 use as a template for this basic block.  */
2831169689Skan      FOR_EACH_EDGE (e, ei, block->preds)
2832169689Skan	if (BLOCK_INFO (e->src)->done)
2833169689Skan	  beste = better_edge (beste, e);
2834169689Skan
2835122180Skan      if (beste)
2836169689Skan	propagate_stack (beste);
2837122180Skan      else
2838122180Skan	{
2839122180Skan	  /* No predecessors.  Create an arbitrary input stack.  */
2840122180Skan	  bi->stack_in.top = -1;
2841122180Skan	  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
2842122180Skan	    if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
2843122180Skan	      bi->stack_in.reg[++bi->stack_in.top] = reg;
2844122180Skan	}
2845122180Skan    }
2846117395Skan
2847169689Skan  if (dump_file)
284890075Sobrien    {
2849169689Skan      fprintf (dump_file, "\nBasic block %d\nInput stack: ", block->index);
2850169689Skan      print_stack (dump_file, &bi->stack_in);
285190075Sobrien    }
285218334Speter
285390075Sobrien  /* Process all insns in this block.  Keep track of NEXT so that we
285490075Sobrien     don't process insns emitted while substituting in INSN.  */
2855169689Skan  current_block = block;
2856132718Skan  next = BB_HEAD (block);
285790075Sobrien  regstack = bi->stack_in;
2858169689Skan  starting_stack_p = true;
2859169689Skan
286090075Sobrien  do
286190075Sobrien    {
286290075Sobrien      insn = next;
286390075Sobrien      next = NEXT_INSN (insn);
286418334Speter
286590075Sobrien      /* Ensure we have not missed a block boundary.  */
2866169689Skan      gcc_assert (next);
2867132718Skan      if (insn == BB_END (block))
286890075Sobrien	next = NULL;
286918334Speter
287090075Sobrien      /* Don't bother processing unless there is a stack reg
287190075Sobrien	 mentioned or if it's a CALL_INSN.  */
287290075Sobrien      if (stack_regs_mentioned (insn)
2873169689Skan	  || CALL_P (insn))
287490075Sobrien	{
2875169689Skan	  if (dump_file)
287690075Sobrien	    {
2877169689Skan	      fprintf (dump_file, "  insn %d input stack: ",
287890075Sobrien		       INSN_UID (insn));
2879169689Skan	      print_stack (dump_file, &regstack);
288090075Sobrien	    }
2881132718Skan	  control_flow_insn_deleted |= subst_stack_regs (insn, &regstack);
2882169689Skan	  starting_stack_p = false;
288390075Sobrien	}
288490075Sobrien    }
288590075Sobrien  while (next);
288650397Sobrien
2887169689Skan  if (dump_file)
288890075Sobrien    {
2889169689Skan      fprintf (dump_file, "Expected live registers [");
289090075Sobrien      for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
289190075Sobrien	if (TEST_HARD_REG_BIT (bi->out_reg_set, reg))
2892169689Skan	  fprintf (dump_file, " %d", reg);
2893169689Skan      fprintf (dump_file, " ]\nOutput stack: ");
2894169689Skan      print_stack (dump_file, &regstack);
289590075Sobrien    }
289618334Speter
2897132718Skan  insn = BB_END (block);
2898169689Skan  if (JUMP_P (insn))
289990075Sobrien    insn = PREV_INSN (insn);
290018334Speter
290190075Sobrien  /* If the function is declared to return a value, but it returns one
290290075Sobrien     in only some cases, some registers might come live here.  Emit
290390075Sobrien     necessary moves for them.  */
290418334Speter
290590075Sobrien  for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
290690075Sobrien    {
290790075Sobrien      if (TEST_HARD_REG_BIT (bi->out_reg_set, reg)
290890075Sobrien	  && ! TEST_HARD_REG_BIT (regstack.reg_set, reg))
290990075Sobrien	{
291090075Sobrien	  rtx set;
291118334Speter
2912169689Skan	  if (dump_file)
2913169689Skan	    fprintf (dump_file, "Emitting insn initializing reg %d\n", reg);
291418334Speter
2915169689Skan	  set = gen_rtx_SET (VOIDmode, FP_MODE_REG (reg, SFmode), not_a_num);
291690075Sobrien	  insn = emit_insn_after (set, insn);
2917132718Skan	  control_flow_insn_deleted |= subst_stack_regs (insn, &regstack);
291890075Sobrien	}
291918334Speter    }
2920122180Skan
2921122180Skan  /* Amongst the insns possibly deleted during the substitution process above,
2922122180Skan     might have been the only trapping insn in the block.  We purge the now
2923122180Skan     possibly dead EH edges here to avoid an ICE from fixup_abnormal_edges,
2924122180Skan     called at the end of convert_regs.  The order in which we process the
2925122180Skan     blocks ensures that we never delete an already processed edge.
292618334Speter
2927132718Skan     Note that, at this point, the CFG may have been damaged by the emission
2928132718Skan     of instructions after an abnormal call, which moves the basic block end
2929132718Skan     (and is the reason why we call fixup_abnormal_edges later).  So we must
2930132718Skan     be sure that the trapping insn has been deleted before trying to purge
2931132718Skan     dead edges, otherwise we risk purging valid edges.
2932132718Skan
2933122180Skan     ??? We are normally supposed not to delete trapping insns, so we pretend
2934122180Skan     that the insns deleted above don't actually trap.  It would have been
2935122180Skan     better to detect this earlier and avoid creating the EH edge in the first
2936122180Skan     place, still, but we don't have enough information at that time.  */
2937122180Skan
2938132718Skan  if (control_flow_insn_deleted)
2939122180Skan    purge_dead_edges (block);
2940122180Skan
2941117395Skan  /* Something failed if the stack lives don't match.  If we had malformed
2942117395Skan     asms, we zapped the instruction itself, but that didn't produce the
2943117395Skan     same pattern of register kills as before.  */
294490075Sobrien  GO_IF_HARD_REG_EQUAL (regstack.reg_set, bi->out_reg_set, win);
2945169689Skan  gcc_assert (any_malformed_asm);
294690075Sobrien win:
294790075Sobrien  bi->stack_out = regstack;
2948169689Skan  bi->done = true;
294918334Speter}
295018334Speter
295190075Sobrien/* Convert registers in all blocks reachable from BLOCK.  */
295290075Sobrien
2953169689Skanstatic void
2954169689Skanconvert_regs_2 (basic_block block)
295518334Speter{
295690075Sobrien  basic_block *stack, *sp;
295718334Speter
2958122180Skan  /* We process the blocks in a top-down manner, in a way such that one block
2959122180Skan     is only processed after all its predecessors.  The number of predecessors
2960122180Skan     of every block has already been computed.  */
2961122180Skan
2962169689Skan  stack = XNEWVEC (basic_block, n_basic_blocks);
296390075Sobrien  sp = stack;
296490075Sobrien
296590075Sobrien  *sp++ = block;
296690075Sobrien
296790075Sobrien  do
296818334Speter    {
296990075Sobrien      edge e;
2970169689Skan      edge_iterator ei;
297118334Speter
297290075Sobrien      block = *--sp;
297318334Speter
2974122180Skan      /* Processing BLOCK is achieved by convert_regs_1, which may purge
2975122180Skan	 some dead EH outgoing edge after the deletion of the trapping
2976122180Skan	 insn inside the block.  Since the number of predecessors of
2977122180Skan	 BLOCK's successors was computed based on the initial edge set,
2978122180Skan	 we check the necessity to process some of these successors
2979122180Skan	 before such an edge deletion may happen.  However, there is
2980122180Skan	 a pitfall: if BLOCK is the only predecessor of a successor and
2981122180Skan	 the edge between them happens to be deleted, the successor
2982122180Skan	 becomes unreachable and should not be processed.  The problem
2983122180Skan	 is that there is no way to preventively detect this case so we
2984122180Skan	 stack the successor in all cases and hand over the task of
2985122180Skan	 fixing up the discrepancy to convert_regs_1.  */
2986122180Skan
2987169689Skan      FOR_EACH_EDGE (e, ei, block->succs)
298890075Sobrien	if (! (e->flags & EDGE_DFS_BACK))
298990075Sobrien	  {
299090075Sobrien	    BLOCK_INFO (e->dest)->predecessors--;
299190075Sobrien	    if (!BLOCK_INFO (e->dest)->predecessors)
2992169689Skan	      *sp++ = e->dest;
299390075Sobrien	  }
2994122180Skan
2995169689Skan      convert_regs_1 (block);
299618334Speter    }
299790075Sobrien  while (sp != stack);
299818334Speter
2999169689Skan  free (stack);
300018334Speter}
300150397Sobrien
300290075Sobrien/* Traverse all basic blocks in a function, converting the register
300390075Sobrien   references in each insn from the "flat" register file that gcc uses,
300490075Sobrien   to the stack-like registers the 387 uses.  */
300590075Sobrien
3006169689Skanstatic void
3007169689Skanconvert_regs (void)
300818334Speter{
3009117395Skan  int inserted;
3010117395Skan  basic_block b;
301190075Sobrien  edge e;
3012169689Skan  edge_iterator ei;
301318334Speter
301490075Sobrien  /* Initialize uninitialized registers on function entry.  */
301590075Sobrien  inserted = convert_regs_entry ();
301618334Speter
301790075Sobrien  /* Construct the desired stack for function exit.  */
301890075Sobrien  convert_regs_exit ();
301990075Sobrien  BLOCK_INFO (EXIT_BLOCK_PTR)->done = 1;
302018334Speter
302190075Sobrien  /* ??? Future: process inner loops first, and give them arbitrary
302290075Sobrien     initial stacks which emit_swap_insn can modify.  This ought to
3023169689Skan     prevent double fxch that often appears at the head of a loop.  */
302418334Speter
302590075Sobrien  /* Process all blocks reachable from all entry points.  */
3026169689Skan  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
3027169689Skan    convert_regs_2 (e->dest);
3028117395Skan
3029117395Skan  /* ??? Process all unreachable blocks.  Though there's no excuse
303090075Sobrien     for keeping these even when not optimizing.  */
3031117395Skan  FOR_EACH_BB (b)
303290075Sobrien    {
303390075Sobrien      block_info bi = BLOCK_INFO (b);
303418334Speter
303590075Sobrien      if (! bi->done)
3036169689Skan	convert_regs_2 (b);
303790075Sobrien    }
3038169689Skan
3039169689Skan  inserted |= compensate_edges ();
3040169689Skan
3041117395Skan  clear_aux_for_blocks ();
304218334Speter
304396263Sobrien  fixup_abnormal_edges ();
304490075Sobrien  if (inserted)
304590075Sobrien    commit_edge_insertions ();
304618334Speter
3047169689Skan  if (dump_file)
3048169689Skan    fputc ('\n', dump_file);
3049169689Skan}
3050169689Skan
3051169689Skan/* Convert register usage from "flat" register file usage to a "stack
3052169689Skan   register file.  FILE is the dump file, if used.
305318334Speter
3054169689Skan   Construct a CFG and run life analysis.  Then convert each insn one
3055169689Skan   by one.  Run a last cleanup_cfg pass, if optimizing, to eliminate
3056169689Skan   code duplication created when the converter inserts pop insns on
3057169689Skan   the edges.  */
3058169689Skan
3059169689Skanstatic bool
3060169689Skanreg_to_stack (void)
3061169689Skan{
3062169689Skan  basic_block bb;
3063169689Skan  int i;
3064169689Skan  int max_uid;
3065169689Skan
3066169689Skan  /* Clean up previous run.  */
3067169689Skan  if (stack_regs_mentioned_data != NULL)
3068169689Skan    VEC_free (char, heap, stack_regs_mentioned_data);
3069169689Skan
3070169689Skan  /* See if there is something to do.  Flow analysis is quite
3071169689Skan     expensive so we might save some compilation time.  */
3072169689Skan  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
3073169689Skan    if (regs_ever_live[i])
3074169689Skan      break;
3075169689Skan  if (i > LAST_STACK_REG)
3076169689Skan    return false;
3077169689Skan
3078169689Skan  /* Ok, floating point instructions exist.  If not optimizing,
3079169689Skan     build the CFG and run life analysis.
3080169689Skan     Also need to rebuild life when superblock scheduling is done
3081169689Skan     as it don't update liveness yet.  */
3082169689Skan  if (!optimize
3083169689Skan      || ((flag_sched2_use_superblocks || flag_sched2_use_traces)
3084169689Skan	  && flag_schedule_insns_after_reload))
3085169689Skan    {
3086169689Skan      count_or_remove_death_notes (NULL, 1);
3087169689Skan      life_analysis (PROP_DEATH_NOTES);
3088169689Skan    }
3089169689Skan  mark_dfs_back_edges ();
3090169689Skan
3091169689Skan  /* Set up block info for each basic block.  */
3092169689Skan  alloc_aux_for_blocks (sizeof (struct block_info_def));
3093169689Skan  FOR_EACH_BB (bb)
3094169689Skan    {
3095169689Skan      block_info bi = BLOCK_INFO (bb);
3096169689Skan      edge_iterator ei;
3097169689Skan      edge e;
3098169689Skan      int reg;
3099169689Skan
3100169689Skan      FOR_EACH_EDGE (e, ei, bb->preds)
3101169689Skan	if (!(e->flags & EDGE_DFS_BACK)
3102169689Skan	    && e->src != ENTRY_BLOCK_PTR)
3103169689Skan	  bi->predecessors++;
3104169689Skan
3105169689Skan      /* Set current register status at last instruction `uninitialized'.  */
3106169689Skan      bi->stack_in.top = -2;
3107169689Skan
3108169689Skan      /* Copy live_at_end and live_at_start into temporaries.  */
3109169689Skan      for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
3110169689Skan	{
3111169689Skan	  if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_end, reg))
3112169689Skan	    SET_HARD_REG_BIT (bi->out_reg_set, reg);
3113169689Skan	  if (REGNO_REG_SET_P (bb->il.rtl->global_live_at_start, reg))
3114169689Skan	    SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
3115169689Skan	}
3116169689Skan    }
3117169689Skan
3118169689Skan  /* Create the replacement registers up front.  */
3119169689Skan  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
3120169689Skan    {
3121169689Skan      enum machine_mode mode;
3122169689Skan      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
3123169689Skan	   mode != VOIDmode;
3124169689Skan	   mode = GET_MODE_WIDER_MODE (mode))
3125169689Skan	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
3126169689Skan      for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
3127169689Skan	   mode != VOIDmode;
3128169689Skan	   mode = GET_MODE_WIDER_MODE (mode))
3129169689Skan	FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
3130169689Skan    }
3131169689Skan
3132169689Skan  ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
3133169689Skan
3134169689Skan  /* A QNaN for initializing uninitialized variables.
3135169689Skan
3136169689Skan     ??? We can't load from constant memory in PIC mode, because
3137169689Skan     we're inserting these instructions before the prologue and
3138169689Skan     the PIC register hasn't been set up.  In that case, fall back
3139169689Skan     on zero, which we can get from `ldz'.  */
3140169689Skan
3141169689Skan  if (flag_pic)
3142169689Skan    not_a_num = CONST0_RTX (SFmode);
3143169689Skan  else
3144169689Skan    {
3145169689Skan      not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
3146169689Skan      not_a_num = force_const_mem (SFmode, not_a_num);
3147169689Skan    }
3148169689Skan
3149169689Skan  /* Allocate a cache for stack_regs_mentioned.  */
3150169689Skan  max_uid = get_max_uid ();
3151169689Skan  stack_regs_mentioned_data = VEC_alloc (char, heap, max_uid + 1);
3152169689Skan  memset (VEC_address (char, stack_regs_mentioned_data),
3153169689Skan	  0, sizeof (char) * max_uid + 1);
3154169689Skan
3155169689Skan  convert_regs ();
3156169689Skan
3157169689Skan  free_aux_for_blocks ();
3158169689Skan  return true;
315918334Speter}
316018334Speter#endif /* STACK_REGS */
3161169689Skan
3162169689Skanstatic bool
3163169689Skangate_handle_stack_regs (void)
3164169689Skan{
3165169689Skan#ifdef STACK_REGS
3166169689Skan  return 1;
3167169689Skan#else
3168169689Skan  return 0;
3169169689Skan#endif
3170169689Skan}
3171117395Skan
3172169689Skan/* Convert register usage from flat register file usage to a stack
3173169689Skan   register file.  */
3174169689Skanstatic unsigned int
3175169689Skanrest_of_handle_stack_regs (void)
3176169689Skan{
3177169689Skan#ifdef STACK_REGS
3178169689Skan  if (reg_to_stack () && optimize)
3179169689Skan    {
3180169689Skan      regstack_completed = 1;
3181169689Skan      if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
3182169689Skan                       | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
3183169689Skan          && (flag_reorder_blocks || flag_reorder_blocks_and_partition))
3184169689Skan        {
3185169689Skan          reorder_basic_blocks (0);
3186169689Skan          cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
3187169689Skan        }
3188169689Skan    }
3189169689Skan  else
3190169689Skan    regstack_completed = 1;
3191169689Skan#endif
3192169689Skan  return 0;
3193169689Skan}
3194169689Skan
3195169689Skanstruct tree_opt_pass pass_stack_regs =
3196169689Skan{
3197169689Skan  "stack",                              /* name */
3198169689Skan  gate_handle_stack_regs,               /* gate */
3199169689Skan  rest_of_handle_stack_regs,            /* execute */
3200169689Skan  NULL,                                 /* sub */
3201169689Skan  NULL,                                 /* next */
3202169689Skan  0,                                    /* static_pass_number */
3203169689Skan  TV_REG_STACK,                         /* tv_id */
3204169689Skan  0,                                    /* properties_required */
3205169689Skan  0,                                    /* properties_provided */
3206169689Skan  0,                                    /* properties_destroyed */
3207169689Skan  0,                                    /* todo_flags_start */
3208169689Skan  TODO_dump_func |
3209169689Skan  TODO_ggc_collect,                     /* todo_flags_finish */
3210169689Skan  'k'                                   /* letter */
3211169689Skan};
3212