reg-stack.c revision 18334
118334Speter/* Register to Stack convert for GNU compiler.
218334Speter   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
318334Speter
418334SpeterThis file is part of GNU CC.
518334Speter
618334SpeterGNU CC is free software; you can redistribute it and/or modify
718334Speterit under the terms of the GNU General Public License as published by
818334Speterthe Free Software Foundation; either version 2, or (at your option)
918334Speterany later version.
1018334Speter
1118334SpeterGNU CC is distributed in the hope that it will be useful,
1218334Speterbut WITHOUT ANY WARRANTY; without even the implied warranty of
1318334SpeterMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1418334SpeterGNU General Public License for more details.
1518334Speter
1618334SpeterYou should have received a copy of the GNU General Public License
1718334Speteralong with GNU CC; see the file COPYING.  If not, write to
1818334Speterthe Free Software Foundation, 59 Temple Place - Suite 330,
1918334SpeterBoston, MA 02111-1307, USA.  */
2018334Speter
2118334Speter/* This pass converts stack-like registers from the "flat register
2218334Speter   file" model that gcc uses, to a stack convention that the 387 uses.
2318334Speter
2418334Speter   * The form of the input:
2518334Speter
2618334Speter   On input, the function consists of insn that have had their
2718334Speter   registers fully allocated to a set of "virtual" registers.  Note that
2818334Speter   the word "virtual" is used differently here than elsewhere in gcc: for
2918334Speter   each virtual stack reg, there is a hard reg, but the mapping between
3018334Speter   them is not known until this pass is run.  On output, hard register
3118334Speter   numbers have been substituted, and various pop and exchange insns have
3218334Speter   been emitted.  The hard register numbers and the virtual register
3318334Speter   numbers completely overlap - before this pass, all stack register
3418334Speter   numbers are virtual, and afterward they are all hard.
3518334Speter
3618334Speter   The virtual registers can be manipulated normally by gcc, and their
3718334Speter   semantics are the same as for normal registers.  After the hard
3818334Speter   register numbers are substituted, the semantics of an insn containing
3918334Speter   stack-like regs are not the same as for an insn with normal regs: for
4018334Speter   instance, it is not safe to delete an insn that appears to be a no-op
4118334Speter   move.  In general, no insn containing hard regs should be changed
4218334Speter   after this pass is done.
4318334Speter
4418334Speter   * The form of the output:
4518334Speter
4618334Speter   After this pass, hard register numbers represent the distance from
4718334Speter   the current top of stack to the desired register.  A reference to
4818334Speter   FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1,
4918334Speter   represents the register just below that, and so forth.  Also, REG_DEAD
5018334Speter   notes indicate whether or not a stack register should be popped.
5118334Speter
5218334Speter   A "swap" insn looks like a parallel of two patterns, where each
5318334Speter   pattern is a SET: one sets A to B, the other B to A.
5418334Speter
5518334Speter   A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG
5618334Speter   and whose SET_DEST is REG or MEM.  Any other SET_DEST, such as PLUS,
5718334Speter   will replace the existing stack top, not push a new value.
5818334Speter
5918334Speter   A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose
6018334Speter   SET_SRC is REG or MEM.
6118334Speter
6218334Speter   The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG
6318334Speter   appears ambiguous.  As a special case, the presence of a REG_DEAD note
6418334Speter   for FIRST_STACK_REG differentiates between a load insn and a pop.
6518334Speter
6618334Speter   If a REG_DEAD is present, the insn represents a "pop" that discards
6718334Speter   the top of the register stack.  If there is no REG_DEAD note, then the
6818334Speter   insn represents a "dup" or a push of the current top of stack onto the
6918334Speter   stack.
7018334Speter
7118334Speter   * Methodology:
7218334Speter
7318334Speter   Existing REG_DEAD and REG_UNUSED notes for stack registers are
7418334Speter   deleted and recreated from scratch.  REG_DEAD is never created for a
7518334Speter   SET_DEST, only REG_UNUSED.
7618334Speter
7718334Speter   Before life analysis, the mode of each insn is set based on whether
7818334Speter   or not any stack registers are mentioned within that insn.  VOIDmode
7918334Speter   means that no regs are mentioned anyway, and QImode means that at
8018334Speter   least one pattern within the insn mentions stack registers.  This
8118334Speter   information is valid until after reg_to_stack returns, and is used
8218334Speter   from jump_optimize.
8318334Speter
8418334Speter   * asm_operands:
8518334Speter
8618334Speter   There are several rules on the usage of stack-like regs in
8718334Speter   asm_operands insns.  These rules apply only to the operands that are
8818334Speter   stack-like regs:
8918334Speter
9018334Speter   1. Given a set of input regs that die in an asm_operands, it is
9118334Speter      necessary to know which are implicitly popped by the asm, and
9218334Speter      which must be explicitly popped by gcc.
9318334Speter
9418334Speter	An input reg that is implicitly popped by the asm must be
9518334Speter	explicitly clobbered, unless it is constrained to match an
9618334Speter	output operand.
9718334Speter
9818334Speter   2. For any input reg that is implicitly popped by an asm, it is
9918334Speter      necessary to know how to adjust the stack to compensate for the pop.
10018334Speter      If any non-popped input is closer to the top of the reg-stack than
10118334Speter      the implicitly popped reg, it would not be possible to know what the
10218334Speter      stack looked like - it's not clear how the rest of the stack "slides
10318334Speter      up".
10418334Speter
10518334Speter	All implicitly popped input regs must be closer to the top of
10618334Speter	the reg-stack than any input that is not implicitly popped.
10718334Speter
10818334Speter   3. It is possible that if an input dies in an insn, reload might
10918334Speter      use the input reg for an output reload.  Consider this example:
11018334Speter
11118334Speter		asm ("foo" : "=t" (a) : "f" (b));
11218334Speter
11318334Speter      This asm says that input B is not popped by the asm, and that
11418334Speter      the asm pushes a result onto the reg-stack, ie, the stack is one
11518334Speter      deeper after the asm than it was before.  But, it is possible that
11618334Speter      reload will think that it can use the same reg for both the input and
11718334Speter      the output, if input B dies in this insn.
11818334Speter
11918334Speter	If any input operand uses the "f" constraint, all output reg
12018334Speter	constraints must use the "&" earlyclobber.
12118334Speter
12218334Speter      The asm above would be written as
12318334Speter
12418334Speter		asm ("foo" : "=&t" (a) : "f" (b));
12518334Speter
12618334Speter   4. Some operands need to be in particular places on the stack.  All
12718334Speter      output operands fall in this category - there is no other way to
12818334Speter      know which regs the outputs appear in unless the user indicates
12918334Speter      this in the constraints.
13018334Speter
13118334Speter	Output operands must specifically indicate which reg an output
13218334Speter	appears in after an asm.  "=f" is not allowed: the operand
13318334Speter	constraints must select a class with a single reg.
13418334Speter
13518334Speter   5. Output operands may not be "inserted" between existing stack regs.
13618334Speter      Since no 387 opcode uses a read/write operand, all output operands
13718334Speter      are dead before the asm_operands, and are pushed by the asm_operands.
13818334Speter      It makes no sense to push anywhere but the top of the reg-stack.
13918334Speter
14018334Speter	Output operands must start at the top of the reg-stack: output
14118334Speter	operands may not "skip" a reg.
14218334Speter
14318334Speter   6. Some asm statements may need extra stack space for internal
14418334Speter      calculations.  This can be guaranteed by clobbering stack registers
14518334Speter      unrelated to the inputs and outputs.
14618334Speter
14718334Speter   Here are a couple of reasonable asms to want to write.  This asm
14818334Speter   takes one input, which is internally popped, and produces two outputs.
14918334Speter
15018334Speter	asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));
15118334Speter
15218334Speter   This asm takes two inputs, which are popped by the fyl2xp1 opcode,
15318334Speter   and replaces them with one output.  The user must code the "st(1)"
15418334Speter   clobber for reg-stack.c to know that fyl2xp1 pops both inputs.
15518334Speter
15618334Speter	asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
15718334Speter
15818334Speter   */
15918334Speter
16018334Speter#include <stdio.h>
16118334Speter#include "config.h"
16218334Speter#include "tree.h"
16318334Speter#include "rtl.h"
16418334Speter#include "insn-config.h"
16518334Speter#include "regs.h"
16618334Speter#include "hard-reg-set.h"
16718334Speter#include "flags.h"
16818334Speter
16918334Speter#ifdef STACK_REGS
17018334Speter
17118334Speter#define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
17218334Speter
17318334Speter/* This is the basic stack record.  TOP is an index into REG[] such
17418334Speter   that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.
17518334Speter
17618334Speter   If TOP is -2, REG[] is not yet initialized.  Stack initialization
17718334Speter   consists of placing each live reg in array `reg' and setting `top'
17818334Speter   appropriately.
17918334Speter
18018334Speter   REG_SET indicates which registers are live.  */
18118334Speter
18218334Spetertypedef struct stack_def
18318334Speter{
18418334Speter  int top;			/* index to top stack element */
18518334Speter  HARD_REG_SET reg_set;		/* set of live registers */
18618334Speter  char reg[REG_STACK_SIZE];	/* register - stack mapping */
18718334Speter} *stack;
18818334Speter
18918334Speter/* highest instruction uid */
19018334Speterstatic int max_uid = 0;
19118334Speter
19218334Speter/* Number of basic blocks in the current function.  */
19318334Speterstatic int blocks;
19418334Speter
19518334Speter/* Element N is first insn in basic block N.
19618334Speter   This info lasts until we finish compiling the function.  */
19718334Speterstatic rtx *block_begin;
19818334Speter
19918334Speter/* Element N is last insn in basic block N.
20018334Speter   This info lasts until we finish compiling the function.  */
20118334Speterstatic rtx *block_end;
20218334Speter
20318334Speter/* Element N is nonzero if control can drop into basic block N */
20418334Speterstatic char *block_drops_in;
20518334Speter
20618334Speter/* Element N says all about the stack at entry block N */
20718334Speterstatic stack block_stack_in;
20818334Speter
20918334Speter/* Element N says all about the stack life at the end of block N */
21018334Speterstatic HARD_REG_SET *block_out_reg_set;
21118334Speter
21218334Speter/* This is where the BLOCK_NUM values are really stored.  This is set
21318334Speter   up by find_blocks and used there and in life_analysis.  It can be used
21418334Speter   later, but only to look up an insn that is the head or tail of some
21518334Speter   block.  life_analysis and the stack register conversion process can
21618334Speter   add insns within a block. */
21718334Speterstatic int *block_number;
21818334Speter
21918334Speter/* This is the register file for all register after conversion */
22018334Speterstatic rtx
22118334Speter  FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
22218334Speter
22318334Speter#define FP_MODE_REG(regno,mode)	\
22418334Speter  (FP_mode_reg[(regno)-FIRST_STACK_REG][(int)(mode)])
22518334Speter
22618334Speter/* Get the basic block number of an insn.  See note at block_number
22718334Speter   definition are validity of this information. */
22818334Speter
22918334Speter#define BLOCK_NUM(INSN)  \
23018334Speter  ((INSN_UID (INSN) > max_uid)	\
23118334Speter   ? (abort() , -1) : block_number[INSN_UID (INSN)])
23218334Speter
23318334Speterextern rtx forced_labels;
23418334Speterextern rtx gen_jump ();
23518334Speterextern rtx gen_movdf (), gen_movxf ();
23618334Speterextern rtx find_regno_note ();
23718334Speterextern rtx emit_jump_insn_before ();
23818334Speterextern rtx emit_label_after ();
23918334Speter
24018334Speter/* Forward declarations */
24118334Speter
24218334Speterstatic void find_blocks ();
24318334Speterstatic uses_reg_or_mem ();
24418334Speterstatic void stack_reg_life_analysis ();
24518334Speterstatic void record_reg_life_pat ();
24618334Speterstatic void change_stack ();
24718334Speterstatic void convert_regs ();
24818334Speterstatic void dump_stack_info ();
24918334Speter
25018334Speter/* Mark all registers needed for this pattern.  */
25118334Speter
25218334Speterstatic void
25318334Spetermark_regs_pat (pat, set)
25418334Speter     rtx pat;
25518334Speter     HARD_REG_SET *set;
25618334Speter{
25718334Speter  enum machine_mode mode;
25818334Speter  register int regno;
25918334Speter  register int count;
26018334Speter
26118334Speter  if (GET_CODE (pat) == SUBREG)
26218334Speter   {
26318334Speter     mode = GET_MODE (pat);
26418334Speter     regno = SUBREG_WORD (pat);
26518334Speter     regno += REGNO (SUBREG_REG (pat));
26618334Speter   }
26718334Speter  else
26818334Speter     regno = REGNO (pat), mode = GET_MODE (pat);
26918334Speter
27018334Speter  for (count = HARD_REGNO_NREGS (regno, mode);
27118334Speter       count; count--, regno++)
27218334Speter     SET_HARD_REG_BIT (*set, regno);
27318334Speter}
27418334Speter
27518334Speter/* Reorganise the stack into ascending numbers,
27618334Speter   after this insn.  */
27718334Speter
27818334Speterstatic void
27918334Speterstraighten_stack (insn, regstack)
28018334Speter     rtx insn;
28118334Speter     stack regstack;
28218334Speter{
28318334Speter  struct stack_def temp_stack;
28418334Speter  int top;
28518334Speter
28618334Speter  temp_stack.reg_set = regstack->reg_set;
28718334Speter
28818334Speter  for (top = temp_stack.top = regstack->top; top >= 0; top--)
28918334Speter     temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
29018334Speter
29118334Speter  change_stack (insn, regstack, &temp_stack, emit_insn_after);
29218334Speter}
29318334Speter
29418334Speter/* Return non-zero if any stack register is mentioned somewhere within PAT.  */
29518334Speter
29618334Speterint
29718334Speterstack_regs_mentioned_p (pat)
29818334Speter     rtx pat;
29918334Speter{
30018334Speter  register char *fmt;
30118334Speter  register int i;
30218334Speter
30318334Speter  if (STACK_REG_P (pat))
30418334Speter    return 1;
30518334Speter
30618334Speter  fmt = GET_RTX_FORMAT (GET_CODE (pat));
30718334Speter  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
30818334Speter    {
30918334Speter      if (fmt[i] == 'E')
31018334Speter	{
31118334Speter	  register int j;
31218334Speter
31318334Speter	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
31418334Speter	    if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
31518334Speter	      return 1;
31618334Speter	}
31718334Speter      else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
31818334Speter	return 1;
31918334Speter    }
32018334Speter
32118334Speter  return 0;
32218334Speter}
32318334Speter
32418334Speter/* Convert register usage from "flat" register file usage to a "stack
32518334Speter   register file.  FIRST is the first insn in the function, FILE is the
32618334Speter   dump file, if used.
32718334Speter
32818334Speter   First compute the beginning and end of each basic block.  Do a
32918334Speter   register life analysis on the stack registers, recording the result
33018334Speter   for the head and tail of each basic block.  The convert each insn one
33118334Speter   by one.  Run a last jump_optimize() pass, if optimizing, to eliminate
33218334Speter   any cross-jumping created when the converter inserts pop insns.*/
33318334Speter
33418334Spetervoid
33518334Speterreg_to_stack (first, file)
33618334Speter     rtx first;
33718334Speter     FILE *file;
33818334Speter{
33918334Speter  register rtx insn;
34018334Speter  register int i;
34118334Speter  int stack_reg_seen = 0;
34218334Speter  enum machine_mode mode;
34318334Speter  HARD_REG_SET stackentry;
34418334Speter
34518334Speter  CLEAR_HARD_REG_SET (stackentry);
34618334Speter
34718334Speter   {
34818334Speter     static initialised;
34918334Speter     if (!initialised)
35018334Speter      {
35118334Speter#if 0
35218334Speter	initialised = 1;	/* This array can not have been previously
35318334Speter				   initialised, because the rtx's are
35418334Speter				   thrown away between compilations of
35518334Speter				   functions.  */
35618334Speter#endif
35718334Speter        for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
35818334Speter         {
35918334Speter           for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
36018334Speter               mode = GET_MODE_WIDER_MODE (mode))
36118334Speter              FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i);
36218334Speter           for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT); mode != VOIDmode;
36318334Speter               mode = GET_MODE_WIDER_MODE (mode))
36418334Speter              FP_MODE_REG (i, mode) = gen_rtx (REG, mode, i);
36518334Speter         }
36618334Speter      }
36718334Speter   }
36818334Speter
36918334Speter  /* Count the basic blocks.  Also find maximum insn uid.  */
37018334Speter  {
37118334Speter    register RTX_CODE prev_code = BARRIER;
37218334Speter    register RTX_CODE code;
37318334Speter    register before_function_beg = 1;
37418334Speter
37518334Speter    max_uid = 0;
37618334Speter    blocks = 0;
37718334Speter    for (insn = first; insn; insn = NEXT_INSN (insn))
37818334Speter      {
37918334Speter	/* Note that this loop must select the same block boundaries
38018334Speter	   as code in find_blocks.  Also note that this code is not the
38118334Speter	   same as that used in flow.c.  */
38218334Speter
38318334Speter	if (INSN_UID (insn) > max_uid)
38418334Speter	  max_uid = INSN_UID (insn);
38518334Speter
38618334Speter	code = GET_CODE (insn);
38718334Speter
38818334Speter	if (code == CODE_LABEL
38918334Speter	    || (prev_code != INSN
39018334Speter		&& prev_code != CALL_INSN
39118334Speter		&& prev_code != CODE_LABEL
39218334Speter		&& GET_RTX_CLASS (code) == 'i'))
39318334Speter	  blocks++;
39418334Speter
39518334Speter	if (code == NOTE && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG)
39618334Speter	   before_function_beg = 0;
39718334Speter
39818334Speter	/* Remember whether or not this insn mentions an FP regs.
39918334Speter	   Check JUMP_INSNs too, in case someone creates a funny PARALLEL. */
40018334Speter
40118334Speter	if (GET_RTX_CLASS (code) == 'i'
40218334Speter	    && stack_regs_mentioned_p (PATTERN (insn)))
40318334Speter	  {
40418334Speter	    stack_reg_seen = 1;
40518334Speter	    PUT_MODE (insn, QImode);
40618334Speter
40718334Speter	    /* Note any register passing parameters.  */
40818334Speter
40918334Speter	    if (before_function_beg && code == INSN
41018334Speter	        && GET_CODE (PATTERN (insn)) == USE)
41118334Speter              record_reg_life_pat (PATTERN (insn), (HARD_REG_SET*) 0,
41218334Speter				   &stackentry, 1);
41318334Speter	  }
41418334Speter	else
41518334Speter	  PUT_MODE (insn, VOIDmode);
41618334Speter
41718334Speter	if (code == CODE_LABEL)
41818334Speter	  LABEL_REFS (insn) = insn; /* delete old chain */
41918334Speter
42018334Speter	if (code != NOTE)
42118334Speter	  prev_code = code;
42218334Speter      }
42318334Speter  }
42418334Speter
42518334Speter  /* If no stack register reference exists in this insn, there isn't
42618334Speter     anything to convert.  */
42718334Speter
42818334Speter  if (! stack_reg_seen)
42918334Speter    return;
43018334Speter
43118334Speter  /* If there are stack registers, there must be at least one block. */
43218334Speter
43318334Speter  if (! blocks)
43418334Speter    abort ();
43518334Speter
43618334Speter  /* Allocate some tables that last till end of compiling this function
43718334Speter     and some needed only in find_blocks and life_analysis. */
43818334Speter
43918334Speter  block_begin = (rtx *) alloca (blocks * sizeof (rtx));
44018334Speter  block_end = (rtx *) alloca (blocks * sizeof (rtx));
44118334Speter  block_drops_in = (char *) alloca (blocks);
44218334Speter
44318334Speter  block_stack_in = (stack) alloca (blocks * sizeof (struct stack_def));
44418334Speter  block_out_reg_set = (HARD_REG_SET *) alloca (blocks * sizeof (HARD_REG_SET));
44518334Speter  bzero ((char *) block_stack_in, blocks * sizeof (struct stack_def));
44618334Speter  bzero ((char *) block_out_reg_set, blocks * sizeof (HARD_REG_SET));
44718334Speter
44818334Speter  block_number = (int *) alloca ((max_uid + 1) * sizeof (int));
44918334Speter
45018334Speter  find_blocks (first);
45118334Speter  stack_reg_life_analysis (first, &stackentry);
45218334Speter
45318334Speter  /* Dump the life analysis debug information before jump
45418334Speter     optimization, as that will destroy the LABEL_REFS we keep the
45518334Speter     information in. */
45618334Speter
45718334Speter  if (file)
45818334Speter    dump_stack_info (file);
45918334Speter
46018334Speter  convert_regs ();
46118334Speter
46218334Speter  if (optimize)
46318334Speter    jump_optimize (first, 2, 0, 0);
46418334Speter}
46518334Speter
46618334Speter/* Check PAT, which is in INSN, for LABEL_REFs.  Add INSN to the
46718334Speter   label's chain of references, and note which insn contains each
46818334Speter   reference. */
46918334Speter
47018334Speterstatic void
47118334Speterrecord_label_references (insn, pat)
47218334Speter     rtx insn, pat;
47318334Speter{
47418334Speter  register enum rtx_code code = GET_CODE (pat);
47518334Speter  register int i;
47618334Speter  register char *fmt;
47718334Speter
47818334Speter  if (code == LABEL_REF)
47918334Speter    {
48018334Speter      register rtx label = XEXP (pat, 0);
48118334Speter      register rtx ref;
48218334Speter
48318334Speter      if (GET_CODE (label) != CODE_LABEL)
48418334Speter	abort ();
48518334Speter
48618334Speter      /* Don't make a duplicate in the code_label's chain. */
48718334Speter
48818334Speter      for (ref = LABEL_REFS (label);
48918334Speter	   ref && ref != label;
49018334Speter	   ref = LABEL_NEXTREF (ref))
49118334Speter	if (CONTAINING_INSN (ref) == insn)
49218334Speter	  return;
49318334Speter
49418334Speter      CONTAINING_INSN (pat) = insn;
49518334Speter      LABEL_NEXTREF (pat) = LABEL_REFS (label);
49618334Speter      LABEL_REFS (label) = pat;
49718334Speter
49818334Speter      return;
49918334Speter    }
50018334Speter
50118334Speter  fmt = GET_RTX_FORMAT (code);
50218334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
50318334Speter    {
50418334Speter      if (fmt[i] == 'e')
50518334Speter	record_label_references (insn, XEXP (pat, i));
50618334Speter      if (fmt[i] == 'E')
50718334Speter	{
50818334Speter	  register int j;
50918334Speter	  for (j = 0; j < XVECLEN (pat, i); j++)
51018334Speter	    record_label_references (insn, XVECEXP (pat, i, j));
51118334Speter	}
51218334Speter    }
51318334Speter}
51418334Speter
51518334Speter/* Return a pointer to the REG expression within PAT.  If PAT is not a
51618334Speter   REG, possible enclosed by a conversion rtx, return the inner part of
51718334Speter   PAT that stopped the search. */
51818334Speter
51918334Speterstatic rtx *
52018334Speterget_true_reg (pat)
52118334Speter     rtx *pat;
52218334Speter{
52318334Speter  for (;;)
52418334Speter     switch (GET_CODE (*pat))
52518334Speter      {
52618334Speter	case SUBREG:
52718334Speter		/* eliminate FP subregister accesses in favour of the
52818334Speter		   actual FP register in use. */
52918334Speter	 {
53018334Speter	   rtx subreg;
53118334Speter	   if (FP_REG_P (subreg = SUBREG_REG (*pat)))
53218334Speter	    {
53318334Speter	      *pat = FP_MODE_REG (REGNO (subreg) + SUBREG_WORD (*pat),
53418334Speter				  GET_MODE (subreg));
53518334Speter	default:
53618334Speter	      return pat;
53718334Speter	    }
53818334Speter	 }
53918334Speter	case FLOAT:
54018334Speter	case FIX:
54118334Speter	case FLOAT_EXTEND:
54218334Speter	   pat = & XEXP (*pat, 0);
54318334Speter      }
54418334Speter}
54518334Speter
54618334Speter/* Scan the OPERANDS and OPERAND_CONSTRAINTS of an asm_operands.
54718334Speter   N_OPERANDS is the total number of operands.  Return which alternative
54818334Speter   matched, or -1 is no alternative matches.
54918334Speter
55018334Speter   OPERAND_MATCHES is an array which indicates which operand this
55118334Speter   operand matches due to the constraints, or -1 if no match is required.
55218334Speter   If two operands match by coincidence, but are not required to match by
55318334Speter   the constraints, -1 is returned.
55418334Speter
55518334Speter   OPERAND_CLASS is an array which indicates the smallest class
55618334Speter   required by the constraints.  If the alternative that matches calls
55718334Speter   for some class `class', and the operand matches a subclass of `class',
55818334Speter   OPERAND_CLASS is set to `class' as required by the constraints, not to
55918334Speter   the subclass. If an alternative allows more than one class,
56018334Speter   OPERAND_CLASS is set to the smallest class that is a union of the
56118334Speter   allowed classes. */
56218334Speter
56318334Speterstatic int
56418334Speterconstrain_asm_operands (n_operands, operands, operand_constraints,
56518334Speter			operand_matches, operand_class)
56618334Speter     int n_operands;
56718334Speter     rtx *operands;
56818334Speter     char **operand_constraints;
56918334Speter     int *operand_matches;
57018334Speter     enum reg_class *operand_class;
57118334Speter{
57218334Speter  char **constraints = (char **) alloca (n_operands * sizeof (char *));
57318334Speter  char *q;
57418334Speter  int this_alternative, this_operand;
57518334Speter  int n_alternatives;
57618334Speter  int j;
57718334Speter
57818334Speter  for (j = 0; j < n_operands; j++)
57918334Speter    constraints[j] = operand_constraints[j];
58018334Speter
58118334Speter  /* Compute the number of alternatives in the operands.  reload has
58218334Speter     already guaranteed that all operands have the same number of
58318334Speter     alternatives.  */
58418334Speter
58518334Speter  n_alternatives = 1;
58618334Speter  for (q = constraints[0]; *q; q++)
58718334Speter    n_alternatives += (*q == ',');
58818334Speter
58918334Speter  this_alternative = 0;
59018334Speter  while (this_alternative < n_alternatives)
59118334Speter    {
59218334Speter      int lose = 0;
59318334Speter      int i;
59418334Speter
59518334Speter      /* No operands match, no narrow class requirements yet.  */
59618334Speter      for (i = 0; i < n_operands; i++)
59718334Speter	{
59818334Speter	  operand_matches[i] = -1;
59918334Speter	  operand_class[i] = NO_REGS;
60018334Speter	}
60118334Speter
60218334Speter      for (this_operand = 0; this_operand < n_operands; this_operand++)
60318334Speter	{
60418334Speter	  rtx op = operands[this_operand];
60518334Speter	  enum machine_mode mode = GET_MODE (op);
60618334Speter	  char *p = constraints[this_operand];
60718334Speter	  int offset = 0;
60818334Speter	  int win = 0;
60918334Speter	  int c;
61018334Speter
61118334Speter	  if (GET_CODE (op) == SUBREG)
61218334Speter	    {
61318334Speter	      if (GET_CODE (SUBREG_REG (op)) == REG
61418334Speter		  && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
61518334Speter		offset = SUBREG_WORD (op);
61618334Speter	      op = SUBREG_REG (op);
61718334Speter	    }
61818334Speter
61918334Speter	  /* An empty constraint or empty alternative
62018334Speter	     allows anything which matched the pattern.  */
62118334Speter	  if (*p == 0 || *p == ',')
62218334Speter	    win = 1;
62318334Speter
62418334Speter	  while (*p && (c = *p++) != ',')
62518334Speter	    switch (c)
62618334Speter	      {
62718334Speter	      case '=':
62818334Speter	      case '+':
62918334Speter	      case '?':
63018334Speter	      case '&':
63118334Speter	      case '!':
63218334Speter	      case '*':
63318334Speter	      case '%':
63418334Speter		/* Ignore these. */
63518334Speter		break;
63618334Speter
63718334Speter	      case '#':
63818334Speter		/* Ignore rest of this alternative. */
63918334Speter		while (*p && *p != ',') p++;
64018334Speter		break;
64118334Speter
64218334Speter	      case '0':
64318334Speter	      case '1':
64418334Speter	      case '2':
64518334Speter	      case '3':
64618334Speter	      case '4':
64718334Speter	      case '5':
64818334Speter		/* This operand must be the same as a previous one.
64918334Speter		   This kind of constraint is used for instructions such
65018334Speter		   as add when they take only two operands.
65118334Speter
65218334Speter		   Note that the lower-numbered operand is passed first. */
65318334Speter
65418334Speter		if (operands_match_p (operands[c - '0'],
65518334Speter				      operands[this_operand]))
65618334Speter		  {
65718334Speter		    operand_matches[this_operand] = c - '0';
65818334Speter		    win = 1;
65918334Speter		  }
66018334Speter		break;
66118334Speter
66218334Speter	      case 'p':
66318334Speter		/* p is used for address_operands.  Since this is an asm,
66418334Speter		   just to make sure that the operand is valid for Pmode. */
66518334Speter
66618334Speter		if (strict_memory_address_p (Pmode, op))
66718334Speter		  win = 1;
66818334Speter		break;
66918334Speter
67018334Speter	      case 'g':
67118334Speter		/* Anything goes unless it is a REG and really has a hard reg
67218334Speter		   but the hard reg is not in the class GENERAL_REGS.  */
67318334Speter		if (GENERAL_REGS == ALL_REGS
67418334Speter		    || GET_CODE (op) != REG
67518334Speter		    || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
67618334Speter		  {
67718334Speter		    if (GET_CODE (op) == REG)
67818334Speter		      operand_class[this_operand]
67918334Speter			= reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
68018334Speter		    win = 1;
68118334Speter		  }
68218334Speter		break;
68318334Speter
68418334Speter	      case 'r':
68518334Speter		if (GET_CODE (op) == REG
68618334Speter		    && (GENERAL_REGS == ALL_REGS
68718334Speter			|| reg_fits_class_p (op, GENERAL_REGS, offset, mode)))
68818334Speter		  {
68918334Speter		    operand_class[this_operand]
69018334Speter		      = reg_class_subunion[(int) operand_class[this_operand]][(int) GENERAL_REGS];
69118334Speter		    win = 1;
69218334Speter		  }
69318334Speter		break;
69418334Speter
69518334Speter	      case 'X':
69618334Speter		/* This is used for a MATCH_SCRATCH in the cases when we
69718334Speter		   don't actually need anything.  So anything goes any time. */
69818334Speter		win = 1;
69918334Speter		break;
70018334Speter
70118334Speter	      case 'm':
70218334Speter		if (GET_CODE (op) == MEM)
70318334Speter		  win = 1;
70418334Speter		break;
70518334Speter
70618334Speter	      case '<':
70718334Speter		if (GET_CODE (op) == MEM
70818334Speter		    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
70918334Speter			|| GET_CODE (XEXP (op, 0)) == POST_DEC))
71018334Speter		  win = 1;
71118334Speter		break;
71218334Speter
71318334Speter	      case '>':
71418334Speter		if (GET_CODE (op) == MEM
71518334Speter		    && (GET_CODE (XEXP (op, 0)) == PRE_INC
71618334Speter			|| GET_CODE (XEXP (op, 0)) == POST_INC))
71718334Speter		  win = 1;
71818334Speter		break;
71918334Speter
72018334Speter	      case 'E':
72118334Speter		/* Match any CONST_DOUBLE, but only if
72218334Speter		   we can examine the bits of it reliably.  */
72318334Speter		if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
72418334Speter		     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
72518334Speter		    && GET_CODE (op) != VOIDmode && ! flag_pretend_float)
72618334Speter		  break;
72718334Speter		if (GET_CODE (op) == CONST_DOUBLE)
72818334Speter		  win = 1;
72918334Speter		break;
73018334Speter
73118334Speter	      case 'F':
73218334Speter		if (GET_CODE (op) == CONST_DOUBLE)
73318334Speter		  win = 1;
73418334Speter		break;
73518334Speter
73618334Speter	      case 'G':
73718334Speter	      case 'H':
73818334Speter		if (GET_CODE (op) == CONST_DOUBLE
73918334Speter		    && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
74018334Speter		  win = 1;
74118334Speter		break;
74218334Speter
74318334Speter	      case 's':
74418334Speter		if (GET_CODE (op) == CONST_INT
74518334Speter		    || (GET_CODE (op) == CONST_DOUBLE
74618334Speter			&& GET_MODE (op) == VOIDmode))
74718334Speter		  break;
74818334Speter		/* Fall through */
74918334Speter	      case 'i':
75018334Speter		if (CONSTANT_P (op))
75118334Speter		  win = 1;
75218334Speter		break;
75318334Speter
75418334Speter	      case 'n':
75518334Speter		if (GET_CODE (op) == CONST_INT
75618334Speter		    || (GET_CODE (op) == CONST_DOUBLE
75718334Speter			&& GET_MODE (op) == VOIDmode))
75818334Speter		  win = 1;
75918334Speter		break;
76018334Speter
76118334Speter	      case 'I':
76218334Speter	      case 'J':
76318334Speter	      case 'K':
76418334Speter	      case 'L':
76518334Speter	      case 'M':
76618334Speter	      case 'N':
76718334Speter	      case 'O':
76818334Speter	      case 'P':
76918334Speter		if (GET_CODE (op) == CONST_INT
77018334Speter		    && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
77118334Speter		  win = 1;
77218334Speter		break;
77318334Speter
77418334Speter#ifdef EXTRA_CONSTRAINT
77518334Speter              case 'Q':
77618334Speter              case 'R':
77718334Speter              case 'S':
77818334Speter              case 'T':
77918334Speter              case 'U':
78018334Speter		if (EXTRA_CONSTRAINT (op, c))
78118334Speter		  win = 1;
78218334Speter		break;
78318334Speter#endif
78418334Speter
78518334Speter	      case 'V':
78618334Speter		if (GET_CODE (op) == MEM && ! offsettable_memref_p (op))
78718334Speter		  win = 1;
78818334Speter		break;
78918334Speter
79018334Speter	      case 'o':
79118334Speter		if (offsettable_memref_p (op))
79218334Speter		  win = 1;
79318334Speter		break;
79418334Speter
79518334Speter	      default:
79618334Speter		if (GET_CODE (op) == REG
79718334Speter		    && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
79818334Speter					 offset, mode))
79918334Speter		  {
80018334Speter		    operand_class[this_operand]
80118334Speter		      = reg_class_subunion[(int)operand_class[this_operand]][(int) REG_CLASS_FROM_LETTER (c)];
80218334Speter		    win = 1;
80318334Speter		  }
80418334Speter	      }
80518334Speter
80618334Speter	  constraints[this_operand] = p;
80718334Speter	  /* If this operand did not win somehow,
80818334Speter	     this alternative loses.  */
80918334Speter	  if (! win)
81018334Speter	    lose = 1;
81118334Speter	}
81218334Speter      /* This alternative won; the operands are ok.
81318334Speter	 Change whichever operands this alternative says to change.  */
81418334Speter      if (! lose)
81518334Speter	break;
81618334Speter
81718334Speter      this_alternative++;
81818334Speter    }
81918334Speter
82018334Speter  /* For operands constrained to match another operand, copy the other
82118334Speter     operand's class to this operand's class. */
82218334Speter  for (j = 0; j < n_operands; j++)
82318334Speter    if (operand_matches[j] >= 0)
82418334Speter      operand_class[j] = operand_class[operand_matches[j]];
82518334Speter
82618334Speter  return this_alternative == n_alternatives ? -1 : this_alternative;
82718334Speter}
82818334Speter
82918334Speter/* Record the life info of each stack reg in INSN, updating REGSTACK.
83018334Speter   N_INPUTS is the number of inputs; N_OUTPUTS the outputs.  CONSTRAINTS
83118334Speter   is an array of the constraint strings used in the asm statement.
83218334Speter   OPERANDS is an array of all operands for the insn, and is assumed to
83318334Speter   contain all output operands, then all inputs operands.
83418334Speter
83518334Speter   There are many rules that an asm statement for stack-like regs must
83618334Speter   follow.  Those rules are explained at the top of this file: the rule
83718334Speter   numbers below refer to that explanation. */
83818334Speter
83918334Speterstatic void
84018334Speterrecord_asm_reg_life (insn, regstack, operands, constraints,
84118334Speter		     n_inputs, n_outputs)
84218334Speter     rtx insn;
84318334Speter     stack regstack;
84418334Speter     rtx *operands;
84518334Speter     char **constraints;
84618334Speter     int n_inputs, n_outputs;
84718334Speter{
84818334Speter  int i;
84918334Speter  int n_operands = n_inputs + n_outputs;
85018334Speter  int first_input = n_outputs;
85118334Speter  int n_clobbers;
85218334Speter  int malformed_asm = 0;
85318334Speter  rtx body = PATTERN (insn);
85418334Speter
85518334Speter  int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
85618334Speter
85718334Speter  enum reg_class *operand_class
85818334Speter    = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
85918334Speter
86018334Speter  int reg_used_as_output[FIRST_PSEUDO_REGISTER];
86118334Speter  int implicitly_dies[FIRST_PSEUDO_REGISTER];
86218334Speter
86318334Speter  rtx *clobber_reg;
86418334Speter
86518334Speter  /* Find out what the constraints require.  If no constraint
86618334Speter     alternative matches, this asm is malformed.  */
86718334Speter  i = constrain_asm_operands (n_operands, operands, constraints,
86818334Speter			      operand_matches, operand_class);
86918334Speter  if (i < 0)
87018334Speter    malformed_asm = 1;
87118334Speter
87218334Speter  /* Strip SUBREGs here to make the following code simpler. */
87318334Speter  for (i = 0; i < n_operands; i++)
87418334Speter    if (GET_CODE (operands[i]) == SUBREG
87518334Speter	&& GET_CODE (SUBREG_REG (operands[i])) == REG)
87618334Speter      operands[i] = SUBREG_REG (operands[i]);
87718334Speter
87818334Speter  /* Set up CLOBBER_REG.  */
87918334Speter
88018334Speter  n_clobbers = 0;
88118334Speter
88218334Speter  if (GET_CODE (body) == PARALLEL)
88318334Speter    {
88418334Speter      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
88518334Speter
88618334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
88718334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
88818334Speter	  {
88918334Speter	    rtx clobber = XVECEXP (body, 0, i);
89018334Speter	    rtx reg = XEXP (clobber, 0);
89118334Speter
89218334Speter	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
89318334Speter	      reg = SUBREG_REG (reg);
89418334Speter
89518334Speter	    if (STACK_REG_P (reg))
89618334Speter	      {
89718334Speter		clobber_reg[n_clobbers] = reg;
89818334Speter		n_clobbers++;
89918334Speter	      }
90018334Speter	  }
90118334Speter    }
90218334Speter
90318334Speter  /* Enforce rule #4: Output operands must specifically indicate which
90418334Speter     reg an output appears in after an asm.  "=f" is not allowed: the
90518334Speter     operand constraints must select a class with a single reg.
90618334Speter
90718334Speter     Also enforce rule #5: Output operands must start at the top of
90818334Speter     the reg-stack: output operands may not "skip" a reg. */
90918334Speter
91018334Speter  bzero ((char *) reg_used_as_output, sizeof (reg_used_as_output));
91118334Speter  for (i = 0; i < n_outputs; i++)
91218334Speter    if (STACK_REG_P (operands[i]))
91318334Speter      if (reg_class_size[(int) operand_class[i]] != 1)
91418334Speter	{
91518334Speter	  error_for_asm
91618334Speter	    (insn, "Output constraint %d must specify a single register", i);
91718334Speter	  malformed_asm = 1;
91818334Speter	}
91918334Speter      else
92018334Speter	reg_used_as_output[REGNO (operands[i])] = 1;
92118334Speter
92218334Speter
92318334Speter  /* Search for first non-popped reg.  */
92418334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
92518334Speter    if (! reg_used_as_output[i])
92618334Speter      break;
92718334Speter
92818334Speter  /* If there are any other popped regs, that's an error.  */
92918334Speter  for (; i < LAST_STACK_REG + 1; i++)
93018334Speter    if (reg_used_as_output[i])
93118334Speter      break;
93218334Speter
93318334Speter  if (i != LAST_STACK_REG + 1)
93418334Speter    {
93518334Speter      error_for_asm (insn, "Output regs must be grouped at top of stack");
93618334Speter      malformed_asm = 1;
93718334Speter    }
93818334Speter
93918334Speter  /* Enforce rule #2: All implicitly popped input regs must be closer
94018334Speter     to the top of the reg-stack than any input that is not implicitly
94118334Speter     popped. */
94218334Speter
94318334Speter  bzero ((char *) implicitly_dies, sizeof (implicitly_dies));
94418334Speter  for (i = first_input; i < first_input + n_inputs; i++)
94518334Speter    if (STACK_REG_P (operands[i]))
94618334Speter      {
94718334Speter	/* An input reg is implicitly popped if it is tied to an
94818334Speter	   output, or if there is a CLOBBER for it. */
94918334Speter	int j;
95018334Speter
95118334Speter	for (j = 0; j < n_clobbers; j++)
95218334Speter	  if (operands_match_p (clobber_reg[j], operands[i]))
95318334Speter	    break;
95418334Speter
95518334Speter	if (j < n_clobbers || operand_matches[i] >= 0)
95618334Speter	  implicitly_dies[REGNO (operands[i])] = 1;
95718334Speter      }
95818334Speter
95918334Speter  /* Search for first non-popped reg.  */
96018334Speter  for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
96118334Speter    if (! implicitly_dies[i])
96218334Speter      break;
96318334Speter
96418334Speter  /* If there are any other popped regs, that's an error.  */
96518334Speter  for (; i < LAST_STACK_REG + 1; i++)
96618334Speter    if (implicitly_dies[i])
96718334Speter      break;
96818334Speter
96918334Speter  if (i != LAST_STACK_REG + 1)
97018334Speter    {
97118334Speter      error_for_asm (insn,
97218334Speter		     "Implicitly popped regs must be grouped at top of stack");
97318334Speter      malformed_asm = 1;
97418334Speter    }
97518334Speter
97618334Speter  /* Enfore rule #3: If any input operand uses the "f" constraint, all
97718334Speter     output constraints must use the "&" earlyclobber.
97818334Speter
97918334Speter     ???  Detect this more deterministically by having constraint_asm_operands
98018334Speter     record any earlyclobber. */
98118334Speter
98218334Speter  for (i = first_input; i < first_input + n_inputs; i++)
98318334Speter    if (operand_matches[i] == -1)
98418334Speter      {
98518334Speter	int j;
98618334Speter
98718334Speter	for (j = 0; j < n_outputs; j++)
98818334Speter	  if (operands_match_p (operands[j], operands[i]))
98918334Speter	    {
99018334Speter	      error_for_asm (insn,
99118334Speter			     "Output operand %d must use `&' constraint", j);
99218334Speter	      malformed_asm = 1;
99318334Speter	    }
99418334Speter      }
99518334Speter
99618334Speter  if (malformed_asm)
99718334Speter    {
99818334Speter      /* Avoid further trouble with this insn.  */
99918334Speter      PATTERN (insn) = gen_rtx (USE, VOIDmode, const0_rtx);
100018334Speter      PUT_MODE (insn, VOIDmode);
100118334Speter      return;
100218334Speter    }
100318334Speter
100418334Speter  /* Process all outputs */
100518334Speter  for (i = 0; i < n_outputs; i++)
100618334Speter    {
100718334Speter      rtx op = operands[i];
100818334Speter
100918334Speter      if (! STACK_REG_P (op))
101018334Speter	if (stack_regs_mentioned_p (op))
101118334Speter	  abort ();
101218334Speter	else
101318334Speter	  continue;
101418334Speter
101518334Speter      /* Each destination is dead before this insn.  If the
101618334Speter	 destination is not used after this insn, record this with
101718334Speter	 REG_UNUSED.  */
101818334Speter
101918334Speter      if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (op)))
102018334Speter	REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED, op,
102118334Speter				    REG_NOTES (insn));
102218334Speter
102318334Speter      CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (op));
102418334Speter    }
102518334Speter
102618334Speter  /* Process all inputs */
102718334Speter  for (i = first_input; i < first_input + n_inputs; i++)
102818334Speter    {
102918334Speter      if (! STACK_REG_P (operands[i]))
103018334Speter	if (stack_regs_mentioned_p (operands[i]))
103118334Speter	  abort ();
103218334Speter	else
103318334Speter	  continue;
103418334Speter
103518334Speter      /* If an input is dead after the insn, record a death note.
103618334Speter	 But don't record a death note if there is already a death note,
103718334Speter	 or if the input is also an output.  */
103818334Speter
103918334Speter      if (! TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]))
104018334Speter	  && operand_matches[i] == -1
104118334Speter	  && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) == NULL_RTX)
104218334Speter	REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, operands[i],
104318334Speter				    REG_NOTES (insn));
104418334Speter
104518334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i]));
104618334Speter    }
104718334Speter}
104818334Speter
104918334Speter/* Scan PAT, which is part of INSN, and record registers appearing in
105018334Speter   a SET_DEST in DEST, and other registers in SRC.
105118334Speter
105218334Speter   This function does not know about SET_DESTs that are both input and
105318334Speter   output (such as ZERO_EXTRACT) - this cannot happen on a 387. */
105418334Speter
105518334Speterstatic void
105618334Speterrecord_reg_life_pat (pat, src, dest, douse)
105718334Speter     rtx pat;
105818334Speter     HARD_REG_SET *src, *dest;
105918334Speter     int douse;
106018334Speter{
106118334Speter  register char *fmt;
106218334Speter  register int i;
106318334Speter
106418334Speter  if (STACK_REG_P (pat)
106518334Speter      || GET_CODE (pat) == SUBREG && STACK_REG_P (SUBREG_REG (pat)))
106618334Speter    {
106718334Speter      if (src)
106818334Speter	 mark_regs_pat (pat, src);
106918334Speter
107018334Speter      if (dest)
107118334Speter	 mark_regs_pat (pat, dest);
107218334Speter
107318334Speter      return;
107418334Speter    }
107518334Speter
107618334Speter  if (GET_CODE (pat) == SET)
107718334Speter    {
107818334Speter      record_reg_life_pat (XEXP (pat, 0), NULL_PTR, dest, 0);
107918334Speter      record_reg_life_pat (XEXP (pat, 1), src, NULL_PTR, 0);
108018334Speter      return;
108118334Speter    }
108218334Speter
108318334Speter  /* We don't need to consider either of these cases. */
108418334Speter  if (GET_CODE (pat) == USE && !douse || GET_CODE (pat) == CLOBBER)
108518334Speter    return;
108618334Speter
108718334Speter  fmt = GET_RTX_FORMAT (GET_CODE (pat));
108818334Speter  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
108918334Speter    {
109018334Speter      if (fmt[i] == 'E')
109118334Speter	{
109218334Speter	  register int j;
109318334Speter
109418334Speter	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
109518334Speter	    record_reg_life_pat (XVECEXP (pat, i, j), src, dest, 0);
109618334Speter	}
109718334Speter      else if (fmt[i] == 'e')
109818334Speter	record_reg_life_pat (XEXP (pat, i), src, dest, 0);
109918334Speter    }
110018334Speter}
110118334Speter
110218334Speter/* Calculate the number of inputs and outputs in BODY, an
110318334Speter   asm_operands.  N_OPERANDS is the total number of operands, and
110418334Speter   N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
110518334Speter   placed. */
110618334Speter
110718334Speterstatic void
110818334Speterget_asm_operand_lengths (body, n_operands, n_inputs, n_outputs)
110918334Speter     rtx body;
111018334Speter     int n_operands;
111118334Speter     int *n_inputs, *n_outputs;
111218334Speter{
111318334Speter  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
111418334Speter    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
111518334Speter
111618334Speter  else if (GET_CODE (body) == ASM_OPERANDS)
111718334Speter    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (body);
111818334Speter
111918334Speter  else if (GET_CODE (body) == PARALLEL
112018334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
112118334Speter    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)));
112218334Speter
112318334Speter  else if (GET_CODE (body) == PARALLEL
112418334Speter	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
112518334Speter    *n_inputs = ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
112618334Speter  else
112718334Speter    abort ();
112818334Speter
112918334Speter  *n_outputs = n_operands - *n_inputs;
113018334Speter}
113118334Speter
113218334Speter/* Scan INSN, which is in BLOCK, and record the life & death of stack
113318334Speter   registers in REGSTACK.  This function is called to process insns from
113418334Speter   the last insn in a block to the first.  The actual scanning is done in
113518334Speter   record_reg_life_pat.
113618334Speter
113718334Speter   If a register is live after a CALL_INSN, but is not a value return
113818334Speter   register for that CALL_INSN, then code is emitted to initialize that
113918334Speter   register.  The block_end[] data is kept accurate.
114018334Speter
114118334Speter   Existing death and unset notes for stack registers are deleted
114218334Speter   before processing the insn. */
114318334Speter
114418334Speterstatic void
114518334Speterrecord_reg_life (insn, block, regstack)
114618334Speter     rtx insn;
114718334Speter     int block;
114818334Speter     stack regstack;
114918334Speter{
115018334Speter  rtx note, *note_link;
115118334Speter  int n_operands;
115218334Speter
115318334Speter  if ((GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
115418334Speter      || INSN_DELETED_P (insn))
115518334Speter    return;
115618334Speter
115718334Speter  /* Strip death notes for stack regs from this insn */
115818334Speter
115918334Speter  note_link = &REG_NOTES(insn);
116018334Speter  for (note = *note_link; note; note = XEXP (note, 1))
116118334Speter    if (STACK_REG_P (XEXP (note, 0))
116218334Speter	&& (REG_NOTE_KIND (note) == REG_DEAD
116318334Speter	    || REG_NOTE_KIND (note) == REG_UNUSED))
116418334Speter      *note_link = XEXP (note, 1);
116518334Speter    else
116618334Speter      note_link = &XEXP (note, 1);
116718334Speter
116818334Speter  /* Process all patterns in the insn. */
116918334Speter
117018334Speter  n_operands = asm_noperands (PATTERN (insn));
117118334Speter  if (n_operands >= 0)
117218334Speter    {
117318334Speter      /* This insn is an `asm' with operands.  Decode the operands,
117418334Speter	 decide how many are inputs, and record the life information. */
117518334Speter
117618334Speter      rtx operands[MAX_RECOG_OPERANDS];
117718334Speter      rtx body = PATTERN (insn);
117818334Speter      int n_inputs, n_outputs;
117918334Speter      char **constraints = (char **) alloca (n_operands * sizeof (char *));
118018334Speter
118118334Speter      decode_asm_operands (body, operands, NULL_PTR, constraints, NULL_PTR);
118218334Speter      get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
118318334Speter      record_asm_reg_life (insn, regstack, operands, constraints,
118418334Speter			   n_inputs, n_outputs);
118518334Speter      return;
118618334Speter    }
118718334Speter
118818334Speter    {
118918334Speter      HARD_REG_SET src, dest;
119018334Speter      int regno;
119118334Speter
119218334Speter      CLEAR_HARD_REG_SET (src);
119318334Speter      CLEAR_HARD_REG_SET (dest);
119418334Speter
119518334Speter      if (GET_CODE (insn) == CALL_INSN)
119618334Speter	 for (note = CALL_INSN_FUNCTION_USAGE (insn);
119718334Speter	      note;
119818334Speter	      note = XEXP (note, 1))
119918334Speter	   if (GET_CODE (XEXP (note, 0)) == USE)
120018334Speter	     record_reg_life_pat (SET_DEST (XEXP (note, 0)), &src, NULL_PTR, 0);
120118334Speter
120218334Speter      record_reg_life_pat (PATTERN (insn), &src, &dest, 0);
120318334Speter      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
120418334Speter	if (! TEST_HARD_REG_BIT (regstack->reg_set, regno))
120518334Speter	  {
120618334Speter	    if (TEST_HARD_REG_BIT (src, regno)
120718334Speter		&& ! TEST_HARD_REG_BIT (dest, regno))
120818334Speter	      REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD,
120918334Speter					  FP_MODE_REG (regno, DFmode),
121018334Speter					  REG_NOTES (insn));
121118334Speter	    else if (TEST_HARD_REG_BIT (dest, regno))
121218334Speter	      REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_UNUSED,
121318334Speter					  FP_MODE_REG (regno, DFmode),
121418334Speter					  REG_NOTES (insn));
121518334Speter	  }
121618334Speter
121718334Speter      if (GET_CODE (insn) == CALL_INSN)
121818334Speter        {
121918334Speter	  int reg;
122018334Speter
122118334Speter          /* There might be a reg that is live after a function call.
122218334Speter             Initialize it to zero so that the program does not crash.  See
122318334Speter	     comment towards the end of stack_reg_life_analysis(). */
122418334Speter
122518334Speter          for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
122618334Speter	    if (! TEST_HARD_REG_BIT (dest, reg)
122718334Speter	        && TEST_HARD_REG_BIT (regstack->reg_set, reg))
122818334Speter	      {
122918334Speter	        rtx init, pat;
123018334Speter
123118334Speter	        /* The insn will use virtual register numbers, and so
123218334Speter	           convert_regs is expected to process these.  But BLOCK_NUM
123318334Speter	           cannot be used on these insns, because they do not appear in
123418334Speter	           block_number[]. */
123518334Speter
123618334Speter	        pat = gen_rtx (SET, VOIDmode, FP_MODE_REG (reg, DFmode),
123718334Speter			       CONST0_RTX (DFmode));
123818334Speter	        init = emit_insn_after (pat, insn);
123918334Speter	        PUT_MODE (init, QImode);
124018334Speter
124118334Speter	        CLEAR_HARD_REG_BIT (regstack->reg_set, reg);
124218334Speter
124318334Speter	        /* If the CALL_INSN was the end of a block, move the
124418334Speter	           block_end to point to the new insn. */
124518334Speter
124618334Speter	        if (block_end[block] == insn)
124718334Speter	          block_end[block] = init;
124818334Speter	      }
124918334Speter
125018334Speter	  /* Some regs do not survive a CALL */
125118334Speter          AND_COMPL_HARD_REG_SET (regstack->reg_set, call_used_reg_set);
125218334Speter	}
125318334Speter
125418334Speter      AND_COMPL_HARD_REG_SET (regstack->reg_set, dest);
125518334Speter      IOR_HARD_REG_SET (regstack->reg_set, src);
125618334Speter    }
125718334Speter}
125818334Speter
125918334Speter/* Find all basic blocks of the function, which starts with FIRST.
126018334Speter   For each JUMP_INSN, build the chain of LABEL_REFS on each CODE_LABEL. */
126118334Speter
126218334Speterstatic void
126318334Speterfind_blocks (first)
126418334Speter     rtx first;
126518334Speter{
126618334Speter  register rtx insn;
126718334Speter  register int block;
126818334Speter  register RTX_CODE prev_code = BARRIER;
126918334Speter  register RTX_CODE code;
127018334Speter  rtx label_value_list = 0;
127118334Speter
127218334Speter  /* Record where all the blocks start and end.
127318334Speter     Record which basic blocks control can drop in to. */
127418334Speter
127518334Speter  block = -1;
127618334Speter  for (insn = first; insn; insn = NEXT_INSN (insn))
127718334Speter    {
127818334Speter      /* Note that this loop must select the same block boundaries
127918334Speter	 as code in reg_to_stack, but that these are not the same
128018334Speter	 as those selected in flow.c.  */
128118334Speter
128218334Speter      code = GET_CODE (insn);
128318334Speter
128418334Speter      if (code == CODE_LABEL
128518334Speter	  || (prev_code != INSN
128618334Speter	      && prev_code != CALL_INSN
128718334Speter	      && prev_code != CODE_LABEL
128818334Speter	      && GET_RTX_CLASS (code) == 'i'))
128918334Speter	{
129018334Speter	  block_begin[++block] = insn;
129118334Speter	  block_end[block] = insn;
129218334Speter	  block_drops_in[block] = prev_code != BARRIER;
129318334Speter	}
129418334Speter      else if (GET_RTX_CLASS (code) == 'i')
129518334Speter	block_end[block] = insn;
129618334Speter
129718334Speter      if (GET_RTX_CLASS (code) == 'i')
129818334Speter	{
129918334Speter	  rtx note;
130018334Speter
130118334Speter	  /* Make a list of all labels referred to other than by jumps.  */
130218334Speter	  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
130318334Speter	    if (REG_NOTE_KIND (note) == REG_LABEL)
130418334Speter	      label_value_list = gen_rtx (EXPR_LIST, VOIDmode, XEXP (note, 0),
130518334Speter					  label_value_list);
130618334Speter	}
130718334Speter
130818334Speter      block_number[INSN_UID (insn)] = block;
130918334Speter
131018334Speter      if (code != NOTE)
131118334Speter	prev_code = code;
131218334Speter    }
131318334Speter
131418334Speter  if (block + 1 != blocks)
131518334Speter    abort ();
131618334Speter
131718334Speter  /* generate all label references to the corresponding jump insn */
131818334Speter  for (block = 0; block < blocks; block++)
131918334Speter    {
132018334Speter      insn = block_end[block];
132118334Speter
132218334Speter      if (GET_CODE (insn) == JUMP_INSN)
132318334Speter	{
132418334Speter	  rtx pat = PATTERN (insn);
132518334Speter	  int computed_jump = 0;
132618334Speter	  rtx x;
132718334Speter
132818334Speter	  if (GET_CODE (pat) == PARALLEL)
132918334Speter	    {
133018334Speter	      int len = XVECLEN (pat, 0);
133118334Speter	      int has_use_labelref = 0;
133218334Speter	      int i;
133318334Speter
133418334Speter	      for (i = len - 1; i >= 0; i--)
133518334Speter		if (GET_CODE (XVECEXP (pat, 0, i)) == USE
133618334Speter		    && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF)
133718334Speter		  has_use_labelref = 1;
133818334Speter
133918334Speter	      if (! has_use_labelref)
134018334Speter		for (i = len - 1; i >= 0; i--)
134118334Speter		  if (GET_CODE (XVECEXP (pat, 0, i)) == SET
134218334Speter		      && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
134318334Speter		      && uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
134418334Speter		    computed_jump = 1;
134518334Speter	    }
134618334Speter	  else if (GET_CODE (pat) == SET
134718334Speter		   && SET_DEST (pat) == pc_rtx
134818334Speter		   && uses_reg_or_mem (SET_SRC (pat)))
134918334Speter	    computed_jump = 1;
135018334Speter
135118334Speter	  if (computed_jump)
135218334Speter	    {
135318334Speter	      for (x = label_value_list; x; x = XEXP (x, 1))
135418334Speter		record_label_references (insn,
135518334Speter					 gen_rtx (LABEL_REF, VOIDmode,
135618334Speter						  XEXP (x, 0)));
135718334Speter
135818334Speter	      for (x = forced_labels; x; x = XEXP (x, 1))
135918334Speter		record_label_references (insn,
136018334Speter					 gen_rtx (LABEL_REF, VOIDmode,
136118334Speter						  XEXP (x, 0)));
136218334Speter	    }
136318334Speter
136418334Speter	  record_label_references (insn, pat);
136518334Speter	}
136618334Speter    }
136718334Speter}
136818334Speter
136918334Speter/* Return 1 if X contain a REG or MEM that is not in the constant pool.  */
137018334Speter
137118334Speterstatic int
137218334Speteruses_reg_or_mem (x)
137318334Speter     rtx x;
137418334Speter{
137518334Speter  enum rtx_code code = GET_CODE (x);
137618334Speter  int i, j;
137718334Speter  char *fmt;
137818334Speter
137918334Speter  if (code == REG
138018334Speter      || (code == MEM
138118334Speter	  && ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
138218334Speter		&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))))
138318334Speter    return 1;
138418334Speter
138518334Speter  fmt = GET_RTX_FORMAT (code);
138618334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
138718334Speter    {
138818334Speter      if (fmt[i] == 'e'
138918334Speter	  && uses_reg_or_mem (XEXP (x, i)))
139018334Speter	return 1;
139118334Speter
139218334Speter      if (fmt[i] == 'E')
139318334Speter	for (j = 0; j < XVECLEN (x, i); j++)
139418334Speter	  if (uses_reg_or_mem (XVECEXP (x, i, j)))
139518334Speter	    return 1;
139618334Speter    }
139718334Speter
139818334Speter  return 0;
139918334Speter}
140018334Speter
140118334Speter/* If current function returns its result in an fp stack register,
140218334Speter   return the REG.  Otherwise, return 0.  */
140318334Speter
140418334Speterstatic rtx
140518334Speterstack_result (decl)
140618334Speter     tree decl;
140718334Speter{
140818334Speter  rtx result = DECL_RTL (DECL_RESULT (decl));
140918334Speter
141018334Speter  if (result != 0
141118334Speter      && ! (GET_CODE (result) == REG
141218334Speter	    && REGNO (result) < FIRST_PSEUDO_REGISTER))
141318334Speter    {
141418334Speter#ifdef FUNCTION_OUTGOING_VALUE
141518334Speter      result
141618334Speter        = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
141718334Speter#else
141818334Speter      result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
141918334Speter#endif
142018334Speter    }
142118334Speter
142218334Speter  return result != 0 && STACK_REG_P (result) ? result : 0;
142318334Speter}
142418334Speter
142518334Speter/* Determine the which registers are live at the start of each basic
142618334Speter   block of the function whose first insn is FIRST.
142718334Speter
142818334Speter   First, if the function returns a real_type, mark the function
142918334Speter   return type as live at each return point, as the RTL may not give any
143018334Speter   hint that the register is live.
143118334Speter
143218334Speter   Then, start with the last block and work back to the first block.
143318334Speter   Similarly, work backwards within each block, insn by insn, recording
143418334Speter   which regs are dead and which are used (and therefore live) in the
143518334Speter   hard reg set of block_stack_in[].
143618334Speter
143718334Speter   After processing each basic block, if there is a label at the start
143818334Speter   of the block, propagate the live registers to all jumps to this block.
143918334Speter
144018334Speter   As a special case, if there are regs live in this block, that are
144118334Speter   not live in a block containing a jump to this label, and the block
144218334Speter   containing the jump has already been processed, we must propagate this
144318334Speter   block's entry register life back to the block containing the jump, and
144418334Speter   restart life analysis from there.
144518334Speter
144618334Speter   In the worst case, this function may traverse the insns
144718334Speter   REG_STACK_SIZE times.  This is necessary, since a jump towards the end
144818334Speter   of the insns may not know that a reg is live at a target that is early
144918334Speter   in the insns.  So we back up and start over with the new reg live.
145018334Speter
145118334Speter   If there are registers that are live at the start of the function,
145218334Speter   insns are emitted to initialize these registers.  Something similar is
145318334Speter   done after CALL_INSNs in record_reg_life. */
145418334Speter
145518334Speterstatic void
145618334Speterstack_reg_life_analysis (first, stackentry)
145718334Speter     rtx first;
145818334Speter     HARD_REG_SET *stackentry;
145918334Speter{
146018334Speter  int reg, block;
146118334Speter  struct stack_def regstack;
146218334Speter
146318334Speter   {
146418334Speter     rtx retvalue;
146518334Speter
146618334Speter     if (retvalue = stack_result (current_function_decl))
146718334Speter      {
146818334Speter        /* Find all RETURN insns and mark them. */
146918334Speter
147018334Speter        for (block = blocks - 1; --block >= 0;)
147118334Speter	   if (GET_CODE (block_end[block]) == JUMP_INSN
147218334Speter	     && GET_CODE (PATTERN (block_end[block])) == RETURN)
147318334Speter	      mark_regs_pat (retvalue, block_out_reg_set+block);
147418334Speter
147518334Speter        /* Mark off the end of last block if we "fall off" the end of the
147618334Speter	   function into the epilogue. */
147718334Speter
147818334Speter        if (GET_CODE (block_end[blocks-1]) != JUMP_INSN
147918334Speter	    || GET_CODE (PATTERN (block_end[blocks-1])) == RETURN)
148018334Speter	  mark_regs_pat (retvalue, block_out_reg_set+blocks-1);
148118334Speter      }
148218334Speter   }
148318334Speter
148418334Speter  /* now scan all blocks backward for stack register use */
148518334Speter
148618334Speter  block = blocks - 1;
148718334Speter  while (block >= 0)
148818334Speter    {
148918334Speter      register rtx insn, prev;
149018334Speter
149118334Speter      /* current register status at last instruction */
149218334Speter
149318334Speter      COPY_HARD_REG_SET (regstack.reg_set, block_out_reg_set[block]);
149418334Speter
149518334Speter      prev = block_end[block];
149618334Speter      do
149718334Speter	{
149818334Speter	  insn = prev;
149918334Speter	  prev = PREV_INSN (insn);
150018334Speter
150118334Speter	  /* If the insn is a CALL_INSN, we need to ensure that
150218334Speter	     everything dies.  But otherwise don't process unless there
150318334Speter	     are some stack regs present. */
150418334Speter
150518334Speter	  if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
150618334Speter	    record_reg_life (insn, block, &regstack);
150718334Speter
150818334Speter	} while (insn != block_begin[block]);
150918334Speter
151018334Speter      /* Set the state at the start of the block.  Mark that no
151118334Speter	 register mapping information known yet. */
151218334Speter
151318334Speter      COPY_HARD_REG_SET (block_stack_in[block].reg_set, regstack.reg_set);
151418334Speter      block_stack_in[block].top = -2;
151518334Speter
151618334Speter      /* If there is a label, propagate our register life to all jumps
151718334Speter	 to this label. */
151818334Speter
151918334Speter      if (GET_CODE (insn) == CODE_LABEL)
152018334Speter	{
152118334Speter	  register rtx label;
152218334Speter	  int must_restart = 0;
152318334Speter
152418334Speter	  for (label = LABEL_REFS (insn); label != insn;
152518334Speter	       label = LABEL_NEXTREF (label))
152618334Speter	    {
152718334Speter	      int jump_block = BLOCK_NUM (CONTAINING_INSN (label));
152818334Speter
152918334Speter	      if (jump_block < block)
153018334Speter		IOR_HARD_REG_SET (block_out_reg_set[jump_block],
153118334Speter				  block_stack_in[block].reg_set);
153218334Speter	      else
153318334Speter		{
153418334Speter		  /* The block containing the jump has already been
153518334Speter		     processed.  If there are registers that were not known
153618334Speter		     to be live then, but are live now, we must back up
153718334Speter		     and restart life analysis from that point with the new
153818334Speter		     life information. */
153918334Speter
154018334Speter		  GO_IF_HARD_REG_SUBSET (block_stack_in[block].reg_set,
154118334Speter					 block_out_reg_set[jump_block],
154218334Speter					 win);
154318334Speter
154418334Speter		  IOR_HARD_REG_SET (block_out_reg_set[jump_block],
154518334Speter				    block_stack_in[block].reg_set);
154618334Speter
154718334Speter		  block = jump_block;
154818334Speter		  must_restart = 1;
154918334Speter
155018334Speter		win:
155118334Speter		  ;
155218334Speter		}
155318334Speter	    }
155418334Speter	  if (must_restart)
155518334Speter	    continue;
155618334Speter	}
155718334Speter
155818334Speter      if (block_drops_in[block])
155918334Speter	IOR_HARD_REG_SET (block_out_reg_set[block-1],
156018334Speter			  block_stack_in[block].reg_set);
156118334Speter
156218334Speter      block -= 1;
156318334Speter    }
156418334Speter
156518334Speter    /* If any reg is live at the start of the first block of a
156618334Speter       function, then we must guarantee that the reg holds some value by
156718334Speter       generating our own "load" of that register.  Otherwise a 387 would
156818334Speter       fault trying to access an empty register. */
156918334Speter
157018334Speter  /* Load zero into each live register.  The fact that a register
157118334Speter     appears live at the function start necessarily implies an error
157218334Speter     in the user program: it means that (unless the offending code is *never*
157318334Speter     executed) this program is using uninitialised floating point
157418334Speter     variables.  In order to keep broken code like this happy, we initialise
157518334Speter     those variables with zero.
157618334Speter
157718334Speter     Note that we are inserting virtual register references here:
157818334Speter     these insns must be processed by convert_regs later.  Also, these
157918334Speter     insns will not be in block_number, so BLOCK_NUM() will fail for them. */
158018334Speter
158118334Speter  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
158218334Speter    if (TEST_HARD_REG_BIT (block_stack_in[0].reg_set, reg)
158318334Speter        && ! TEST_HARD_REG_BIT (*stackentry, reg))
158418334Speter      {
158518334Speter	rtx init_rtx;
158618334Speter
158718334Speter	init_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG(reg, DFmode),
158818334Speter			    CONST0_RTX (DFmode));
158918334Speter	block_begin[0] = emit_insn_after (init_rtx, first);
159018334Speter	PUT_MODE (block_begin[0], QImode);
159118334Speter
159218334Speter	CLEAR_HARD_REG_BIT (block_stack_in[0].reg_set, reg);
159318334Speter      }
159418334Speter}
159518334Speter
159618334Speter/*****************************************************************************
159718334Speter   This section deals with stack register substitution, and forms the second
159818334Speter   pass over the RTL.
159918334Speter *****************************************************************************/
160018334Speter
160118334Speter/* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
160218334Speter   the desired hard REGNO. */
160318334Speter
160418334Speterstatic void
160518334Speterreplace_reg (reg, regno)
160618334Speter     rtx *reg;
160718334Speter     int regno;
160818334Speter{
160918334Speter  if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG
161018334Speter      || ! STACK_REG_P (*reg))
161118334Speter    abort ();
161218334Speter
161318334Speter  switch (GET_MODE_CLASS (GET_MODE (*reg)))
161418334Speter   {
161518334Speter     default: abort ();
161618334Speter     case MODE_FLOAT:
161718334Speter     case MODE_COMPLEX_FLOAT:;
161818334Speter   }
161918334Speter
162018334Speter  *reg = FP_MODE_REG (regno, GET_MODE (*reg));
162118334Speter}
162218334Speter
162318334Speter/* Remove a note of type NOTE, which must be found, for register
162418334Speter   number REGNO from INSN.  Remove only one such note. */
162518334Speter
162618334Speterstatic void
162718334Speterremove_regno_note (insn, note, regno)
162818334Speter     rtx insn;
162918334Speter     enum reg_note note;
163018334Speter     int regno;
163118334Speter{
163218334Speter  register rtx *note_link, this;
163318334Speter
163418334Speter  note_link = &REG_NOTES(insn);
163518334Speter  for (this = *note_link; this; this = XEXP (this, 1))
163618334Speter    if (REG_NOTE_KIND (this) == note
163718334Speter	&& REG_P (XEXP (this, 0)) && REGNO (XEXP (this, 0)) == regno)
163818334Speter      {
163918334Speter	*note_link = XEXP (this, 1);
164018334Speter	return;
164118334Speter      }
164218334Speter    else
164318334Speter      note_link = &XEXP (this, 1);
164418334Speter
164518334Speter  abort ();
164618334Speter}
164718334Speter
164818334Speter/* Find the hard register number of virtual register REG in REGSTACK.
164918334Speter   The hard register number is relative to the top of the stack.  -1 is
165018334Speter   returned if the register is not found. */
165118334Speter
165218334Speterstatic int
165318334Speterget_hard_regnum (regstack, reg)
165418334Speter     stack regstack;
165518334Speter     rtx reg;
165618334Speter{
165718334Speter  int i;
165818334Speter
165918334Speter  if (! STACK_REG_P (reg))
166018334Speter    abort ();
166118334Speter
166218334Speter  for (i = regstack->top; i >= 0; i--)
166318334Speter    if (regstack->reg[i] == REGNO (reg))
166418334Speter      break;
166518334Speter
166618334Speter  return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
166718334Speter}
166818334Speter
166918334Speter/* Delete INSN from the RTL.  Mark the insn, but don't remove it from
167018334Speter   the chain of insns.  Doing so could confuse block_begin and block_end
167118334Speter   if this were the only insn in the block. */
167218334Speter
167318334Speterstatic void
167418334Speterdelete_insn_for_stacker (insn)
167518334Speter     rtx insn;
167618334Speter{
167718334Speter  PUT_CODE (insn, NOTE);
167818334Speter  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
167918334Speter  NOTE_SOURCE_FILE (insn) = 0;
168018334Speter}
168118334Speter
168218334Speter/* Emit an insn to pop virtual register REG before or after INSN.
168318334Speter   REGSTACK is the stack state after INSN and is updated to reflect this
168418334Speter   pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
168518334Speter   is represented as a SET whose destination is the register to be popped
168618334Speter   and source is the top of stack.  A death note for the top of stack
168718334Speter   cases the movdf pattern to pop. */
168818334Speter
168918334Speterstatic rtx
169018334Speteremit_pop_insn (insn, regstack, reg, when)
169118334Speter     rtx insn;
169218334Speter     stack regstack;
169318334Speter     rtx reg;
169418334Speter     rtx (*when)();
169518334Speter{
169618334Speter  rtx pop_insn, pop_rtx;
169718334Speter  int hard_regno;
169818334Speter
169918334Speter  hard_regno = get_hard_regnum (regstack, reg);
170018334Speter
170118334Speter  if (hard_regno < FIRST_STACK_REG)
170218334Speter    abort ();
170318334Speter
170418334Speter  pop_rtx = gen_rtx (SET, VOIDmode, FP_MODE_REG (hard_regno, DFmode),
170518334Speter		     FP_MODE_REG (FIRST_STACK_REG, DFmode));
170618334Speter
170718334Speter  pop_insn = (*when) (pop_rtx, insn);
170818334Speter  /* ??? This used to be VOIDmode, but that seems wrong. */
170918334Speter  PUT_MODE (pop_insn, QImode);
171018334Speter
171118334Speter  REG_NOTES (pop_insn) = gen_rtx (EXPR_LIST, REG_DEAD,
171218334Speter				  FP_MODE_REG (FIRST_STACK_REG, DFmode),
171318334Speter				  REG_NOTES (pop_insn));
171418334Speter
171518334Speter  regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
171618334Speter    = regstack->reg[regstack->top];
171718334Speter  regstack->top -= 1;
171818334Speter  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));
171918334Speter
172018334Speter  return pop_insn;
172118334Speter}
172218334Speter
172318334Speter/* Emit an insn before or after INSN to swap virtual register REG with the
172418334Speter   top of stack.  WHEN should be `emit_insn_before' or `emit_insn_before'
172518334Speter   REGSTACK is the stack state before the swap, and is updated to reflect
172618334Speter   the swap.  A swap insn is represented as a PARALLEL of two patterns:
172718334Speter   each pattern moves one reg to the other.
172818334Speter
172918334Speter   If REG is already at the top of the stack, no insn is emitted. */
173018334Speter
173118334Speterstatic void
173218334Speteremit_swap_insn (insn, regstack, reg)
173318334Speter     rtx insn;
173418334Speter     stack regstack;
173518334Speter     rtx reg;
173618334Speter{
173718334Speter  int hard_regno;
173818334Speter  rtx gen_swapdf();
173918334Speter  rtx swap_rtx, swap_insn;
174018334Speter  int tmp, other_reg;		/* swap regno temps */
174118334Speter  rtx i1;			/* the stack-reg insn prior to INSN */
174218334Speter  rtx i1set = NULL_RTX;		/* the SET rtx within I1 */
174318334Speter
174418334Speter  hard_regno = get_hard_regnum (regstack, reg);
174518334Speter
174618334Speter  if (hard_regno < FIRST_STACK_REG)
174718334Speter    abort ();
174818334Speter  if (hard_regno == FIRST_STACK_REG)
174918334Speter    return;
175018334Speter
175118334Speter  other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);
175218334Speter
175318334Speter  tmp = regstack->reg[other_reg];
175418334Speter  regstack->reg[other_reg] = regstack->reg[regstack->top];
175518334Speter  regstack->reg[regstack->top] = tmp;
175618334Speter
175718334Speter  /* Find the previous insn involving stack regs, but don't go past
175818334Speter     any labels, calls or jumps.  */
175918334Speter  i1 = prev_nonnote_insn (insn);
176018334Speter  while (i1 && GET_CODE (i1) == INSN && GET_MODE (i1) != QImode)
176118334Speter    i1 = prev_nonnote_insn (i1);
176218334Speter
176318334Speter  if (i1)
176418334Speter    i1set = single_set (i1);
176518334Speter
176618334Speter  if (i1set)
176718334Speter    {
176818334Speter      rtx i2;			/* the stack-reg insn prior to I1 */
176918334Speter      rtx i1src = *get_true_reg (&SET_SRC (i1set));
177018334Speter      rtx i1dest = *get_true_reg (&SET_DEST (i1set));
177118334Speter
177218334Speter      /* If the previous register stack push was from the reg we are to
177318334Speter	 swap with, omit the swap. */
177418334Speter
177518334Speter      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == FIRST_STACK_REG
177618334Speter	  && GET_CODE (i1src) == REG && REGNO (i1src) == hard_regno - 1
177718334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
177818334Speter	return;
177918334Speter
178018334Speter      /* If the previous insn wrote to the reg we are to swap with,
178118334Speter	 omit the swap.  */
178218334Speter
178318334Speter      if (GET_CODE (i1dest) == REG && REGNO (i1dest) == hard_regno
178418334Speter	  && GET_CODE (i1src) == REG && REGNO (i1src) == FIRST_STACK_REG
178518334Speter	  && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
178618334Speter	return;
178718334Speter    }
178818334Speter
178918334Speter  if (GET_RTX_CLASS (GET_CODE (i1)) == 'i' && sets_cc0_p (PATTERN (i1)))
179018334Speter    {
179118334Speter      i1 = next_nonnote_insn (i1);
179218334Speter      if (i1 == insn)
179318334Speter	abort ();
179418334Speter    }
179518334Speter
179618334Speter  swap_rtx = gen_swapdf (FP_MODE_REG (hard_regno, DFmode),
179718334Speter			 FP_MODE_REG (FIRST_STACK_REG, DFmode));
179818334Speter  swap_insn = emit_insn_after (swap_rtx, i1);
179918334Speter  /* ??? This used to be VOIDmode, but that seems wrong. */
180018334Speter  PUT_MODE (swap_insn, QImode);
180118334Speter}
180218334Speter
180318334Speter/* Handle a move to or from a stack register in PAT, which is in INSN.
180418334Speter   REGSTACK is the current stack. */
180518334Speter
180618334Speterstatic void
180718334Spetermove_for_stack_reg (insn, regstack, pat)
180818334Speter     rtx insn;
180918334Speter     stack regstack;
181018334Speter     rtx pat;
181118334Speter{
181218334Speter  rtx *psrc =  get_true_reg (&SET_SRC (pat));
181318334Speter  rtx *pdest = get_true_reg (&SET_DEST (pat));
181418334Speter  rtx src, dest;
181518334Speter  rtx note;
181618334Speter
181718334Speter  src = *psrc; dest = *pdest;
181818334Speter
181918334Speter  if (STACK_REG_P (src) && STACK_REG_P (dest))
182018334Speter    {
182118334Speter      /* Write from one stack reg to another.  If SRC dies here, then
182218334Speter	 just change the register mapping and delete the insn. */
182318334Speter
182418334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
182518334Speter      if (note)
182618334Speter	{
182718334Speter	  int i;
182818334Speter
182918334Speter	  /* If this is a no-op move, there must not be a REG_DEAD note. */
183018334Speter	  if (REGNO (src) == REGNO (dest))
183118334Speter	    abort ();
183218334Speter
183318334Speter	  for (i = regstack->top; i >= 0; i--)
183418334Speter	    if (regstack->reg[i] == REGNO (src))
183518334Speter	      break;
183618334Speter
183718334Speter	  /* The source must be live, and the dest must be dead. */
183818334Speter	  if (i < 0 || get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
183918334Speter	    abort ();
184018334Speter
184118334Speter	  /* It is possible that the dest is unused after this insn.
184218334Speter	     If so, just pop the src. */
184318334Speter
184418334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
184518334Speter	    {
184618334Speter	      emit_pop_insn (insn, regstack, src, emit_insn_after);
184718334Speter
184818334Speter	      delete_insn_for_stacker (insn);
184918334Speter	      return;
185018334Speter	    }
185118334Speter
185218334Speter	  regstack->reg[i] = REGNO (dest);
185318334Speter
185418334Speter	  SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
185518334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
185618334Speter
185718334Speter	  delete_insn_for_stacker (insn);
185818334Speter
185918334Speter	  return;
186018334Speter	}
186118334Speter
186218334Speter      /* The source reg does not die. */
186318334Speter
186418334Speter      /* If this appears to be a no-op move, delete it, or else it
186518334Speter	 will confuse the machine description output patterns. But if
186618334Speter	 it is REG_UNUSED, we must pop the reg now, as per-insn processing
186718334Speter	 for REG_UNUSED will not work for deleted insns. */
186818334Speter
186918334Speter      if (REGNO (src) == REGNO (dest))
187018334Speter	{
187118334Speter	  if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
187218334Speter	    emit_pop_insn (insn, regstack, dest, emit_insn_after);
187318334Speter
187418334Speter	  delete_insn_for_stacker (insn);
187518334Speter	  return;
187618334Speter	}
187718334Speter
187818334Speter      /* The destination ought to be dead */
187918334Speter      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
188018334Speter	abort ();
188118334Speter
188218334Speter      replace_reg (psrc, get_hard_regnum (regstack, src));
188318334Speter
188418334Speter      regstack->reg[++regstack->top] = REGNO (dest);
188518334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
188618334Speter      replace_reg (pdest, FIRST_STACK_REG);
188718334Speter    }
188818334Speter  else if (STACK_REG_P (src))
188918334Speter    {
189018334Speter      /* Save from a stack reg to MEM, or possibly integer reg.  Since
189118334Speter	 only top of stack may be saved, emit an exchange first if
189218334Speter	 needs be. */
189318334Speter
189418334Speter      emit_swap_insn (insn, regstack, src);
189518334Speter
189618334Speter      note = find_regno_note (insn, REG_DEAD, REGNO (src));
189718334Speter      if (note)
189818334Speter	{
189918334Speter	  replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
190018334Speter	  regstack->top--;
190118334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
190218334Speter	}
190318334Speter      else if (GET_MODE (src) == XFmode && regstack->top != REG_STACK_SIZE)
190418334Speter	{
190518334Speter	  /* A 387 cannot write an XFmode value to a MEM without
190618334Speter	     clobbering the source reg.  The output code can handle
190718334Speter	     this by reading back the value from the MEM.
190818334Speter	     But it is more efficient to use a temp register if one is
190918334Speter	     available.  Push the source value here if the register
191018334Speter	     stack is not full, and then write the value to memory via
191118334Speter	     a pop.  */
191218334Speter	  rtx push_rtx, push_insn;
191318334Speter	  rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, XFmode);
191418334Speter
191518334Speter	  push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
191618334Speter	  push_insn = emit_insn_before (push_rtx, insn);
191718334Speter	  PUT_MODE (push_insn, QImode);
191818334Speter	  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_DEAD, top_stack_reg,
191918334Speter				      REG_NOTES (insn));
192018334Speter	}
192118334Speter
192218334Speter      replace_reg (psrc, FIRST_STACK_REG);
192318334Speter    }
192418334Speter  else if (STACK_REG_P (dest))
192518334Speter    {
192618334Speter      /* Load from MEM, or possibly integer REG or constant, into the
192718334Speter	 stack regs.  The actual target is always the top of the
192818334Speter	 stack. The stack mapping is changed to reflect that DEST is
192918334Speter	 now at top of stack.  */
193018334Speter
193118334Speter      /* The destination ought to be dead */
193218334Speter      if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
193318334Speter	abort ();
193418334Speter
193518334Speter      if (regstack->top >= REG_STACK_SIZE)
193618334Speter	abort ();
193718334Speter
193818334Speter      regstack->reg[++regstack->top] = REGNO (dest);
193918334Speter      SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
194018334Speter      replace_reg (pdest, FIRST_STACK_REG);
194118334Speter    }
194218334Speter  else
194318334Speter    abort ();
194418334Speter}
194518334Speter
194618334Spetervoid
194718334Speterswap_rtx_condition (pat)
194818334Speter     rtx pat;
194918334Speter{
195018334Speter  register char *fmt;
195118334Speter  register int i;
195218334Speter
195318334Speter  if (GET_RTX_CLASS (GET_CODE (pat)) == '<')
195418334Speter    {
195518334Speter      PUT_CODE (pat, swap_condition (GET_CODE (pat)));
195618334Speter      return;
195718334Speter    }
195818334Speter
195918334Speter  fmt = GET_RTX_FORMAT (GET_CODE (pat));
196018334Speter  for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
196118334Speter    {
196218334Speter      if (fmt[i] == 'E')
196318334Speter	{
196418334Speter	  register int j;
196518334Speter
196618334Speter	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
196718334Speter	    swap_rtx_condition (XVECEXP (pat, i, j));
196818334Speter	}
196918334Speter      else if (fmt[i] == 'e')
197018334Speter	swap_rtx_condition (XEXP (pat, i));
197118334Speter    }
197218334Speter}
197318334Speter
197418334Speter/* Handle a comparison.  Special care needs to be taken to avoid
197518334Speter   causing comparisons that a 387 cannot do correctly, such as EQ.
197618334Speter
197718334Speter   Also, a pop insn may need to be emitted.  The 387 does have an
197818334Speter   `fcompp' insn that can pop two regs, but it is sometimes too expensive
197918334Speter   to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
198018334Speter   set up. */
198118334Speter
198218334Speterstatic void
198318334Spetercompare_for_stack_reg (insn, regstack, pat)
198418334Speter     rtx insn;
198518334Speter     stack regstack;
198618334Speter     rtx pat;
198718334Speter{
198818334Speter  rtx *src1, *src2;
198918334Speter  rtx src1_note, src2_note;
199018334Speter
199118334Speter  src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
199218334Speter  src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
199318334Speter
199418334Speter  /* ??? If fxch turns out to be cheaper than fstp, give priority to
199518334Speter     registers that die in this insn - move those to stack top first. */
199618334Speter  if (! STACK_REG_P (*src1)
199718334Speter      || (STACK_REG_P (*src2)
199818334Speter	  && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
199918334Speter    {
200018334Speter      rtx temp, next;
200118334Speter
200218334Speter      temp = XEXP (SET_SRC (pat), 0);
200318334Speter      XEXP (SET_SRC (pat), 0) = XEXP (SET_SRC (pat), 1);
200418334Speter      XEXP (SET_SRC (pat), 1) = temp;
200518334Speter
200618334Speter      src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
200718334Speter      src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
200818334Speter
200918334Speter      next = next_cc0_user (insn);
201018334Speter      if (next == NULL_RTX)
201118334Speter	abort ();
201218334Speter
201318334Speter      swap_rtx_condition (PATTERN (next));
201418334Speter      INSN_CODE (next) = -1;
201518334Speter      INSN_CODE (insn) = -1;
201618334Speter    }
201718334Speter
201818334Speter  /* We will fix any death note later. */
201918334Speter
202018334Speter  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
202118334Speter
202218334Speter  if (STACK_REG_P (*src2))
202318334Speter    src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
202418334Speter  else
202518334Speter    src2_note = NULL_RTX;
202618334Speter
202718334Speter  emit_swap_insn (insn, regstack, *src1);
202818334Speter
202918334Speter  replace_reg (src1, FIRST_STACK_REG);
203018334Speter
203118334Speter  if (STACK_REG_P (*src2))
203218334Speter    replace_reg (src2, get_hard_regnum (regstack, *src2));
203318334Speter
203418334Speter  if (src1_note)
203518334Speter    {
203618334Speter      CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src1_note, 0)));
203718334Speter      replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
203818334Speter      regstack->top--;
203918334Speter    }
204018334Speter
204118334Speter  /* If the second operand dies, handle that.  But if the operands are
204218334Speter     the same stack register, don't bother, because only one death is
204318334Speter     needed, and it was just handled. */
204418334Speter
204518334Speter  if (src2_note
204618334Speter      && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
204718334Speter	    && REGNO (*src1) == REGNO (*src2)))
204818334Speter    {
204918334Speter      /* As a special case, two regs may die in this insn if src2 is
205018334Speter	 next to top of stack and the top of stack also dies.  Since
205118334Speter	 we have already popped src1, "next to top of stack" is really
205218334Speter	 at top (FIRST_STACK_REG) now. */
205318334Speter
205418334Speter      if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
205518334Speter	  && src1_note)
205618334Speter	{
205718334Speter	  CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (XEXP (src2_note, 0)));
205818334Speter	  replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
205918334Speter	  regstack->top--;
206018334Speter	}
206118334Speter      else
206218334Speter	{
206318334Speter	  /* The 386 can only represent death of the first operand in
206418334Speter	     the case handled above.  In all other cases, emit a separate
206518334Speter	     pop and remove the death note from here. */
206618334Speter
206718334Speter	  link_cc0_insns (insn);
206818334Speter
206918334Speter	  remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
207018334Speter
207118334Speter	  emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
207218334Speter			 emit_insn_after);
207318334Speter	}
207418334Speter    }
207518334Speter}
207618334Speter
207718334Speter/* Substitute new registers in PAT, which is part of INSN.  REGSTACK
207818334Speter   is the current register layout. */
207918334Speter
208018334Speterstatic void
208118334Spetersubst_stack_regs_pat (insn, regstack, pat)
208218334Speter     rtx insn;
208318334Speter     stack regstack;
208418334Speter     rtx pat;
208518334Speter{
208618334Speter  rtx *dest, *src;
208718334Speter  rtx *src1 = (rtx *) NULL_PTR, *src2;
208818334Speter  rtx src1_note, src2_note;
208918334Speter
209018334Speter  if (GET_CODE (pat) != SET)
209118334Speter    return;
209218334Speter
209318334Speter  dest = get_true_reg (&SET_DEST (pat));
209418334Speter  src  = get_true_reg (&SET_SRC (pat));
209518334Speter
209618334Speter  /* See if this is a `movM' pattern, and handle elsewhere if so. */
209718334Speter
209818334Speter  if (*dest != cc0_rtx
209918334Speter      && (STACK_REG_P (*src)
210018334Speter	  || (STACK_REG_P (*dest)
210118334Speter	      && (GET_CODE (*src) == REG || GET_CODE (*src) == MEM
210218334Speter		  || GET_CODE (*src) == CONST_DOUBLE))))
210318334Speter    move_for_stack_reg (insn, regstack, pat);
210418334Speter  else
210518334Speter    switch (GET_CODE (SET_SRC (pat)))
210618334Speter      {
210718334Speter      case COMPARE:
210818334Speter	compare_for_stack_reg (insn, regstack, pat);
210918334Speter	break;
211018334Speter
211118334Speter      case CALL:
211218334Speter	 {
211318334Speter	   int count;
211418334Speter	   for (count = HARD_REGNO_NREGS (REGNO (*dest), GET_MODE (*dest));
211518334Speter              --count >= 0;)
211618334Speter	    {
211718334Speter	      regstack->reg[++regstack->top] = REGNO (*dest) + count;
211818334Speter	      SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count);
211918334Speter	    }
212018334Speter	 }
212118334Speter	replace_reg (dest, FIRST_STACK_REG);
212218334Speter	break;
212318334Speter
212418334Speter      case REG:
212518334Speter	/* This is a `tstM2' case. */
212618334Speter	if (*dest != cc0_rtx)
212718334Speter	  abort ();
212818334Speter
212918334Speter	src1 = src;
213018334Speter
213118334Speter	/* Fall through. */
213218334Speter
213318334Speter      case FLOAT_TRUNCATE:
213418334Speter      case SQRT:
213518334Speter      case ABS:
213618334Speter      case NEG:
213718334Speter	/* These insns only operate on the top of the stack. DEST might
213818334Speter	   be cc0_rtx if we're processing a tstM pattern. Also, it's
213918334Speter	   possible that the tstM case results in a REG_DEAD note on the
214018334Speter	   source.  */
214118334Speter
214218334Speter	if (src1 == 0)
214318334Speter	  src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
214418334Speter
214518334Speter	emit_swap_insn (insn, regstack, *src1);
214618334Speter
214718334Speter	src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
214818334Speter
214918334Speter	if (STACK_REG_P (*dest))
215018334Speter	  replace_reg (dest, FIRST_STACK_REG);
215118334Speter
215218334Speter	if (src1_note)
215318334Speter	  {
215418334Speter	    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
215518334Speter	    regstack->top--;
215618334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
215718334Speter	  }
215818334Speter
215918334Speter	replace_reg (src1, FIRST_STACK_REG);
216018334Speter
216118334Speter	break;
216218334Speter
216318334Speter      case MINUS:
216418334Speter      case DIV:
216518334Speter	/* On i386, reversed forms of subM3 and divM3 exist for
216618334Speter	   MODE_FLOAT, so the same code that works for addM3 and mulM3
216718334Speter	   can be used. */
216818334Speter      case MULT:
216918334Speter      case PLUS:
217018334Speter	/* These insns can accept the top of stack as a destination
217118334Speter	   from a stack reg or mem, or can use the top of stack as a
217218334Speter	   source and some other stack register (possibly top of stack)
217318334Speter	   as a destination. */
217418334Speter
217518334Speter	src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
217618334Speter	src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
217718334Speter
217818334Speter	/* We will fix any death note later. */
217918334Speter
218018334Speter	if (STACK_REG_P (*src1))
218118334Speter	  src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
218218334Speter	else
218318334Speter	  src1_note = NULL_RTX;
218418334Speter	if (STACK_REG_P (*src2))
218518334Speter	  src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
218618334Speter	else
218718334Speter	  src2_note = NULL_RTX;
218818334Speter
218918334Speter	/* If either operand is not a stack register, then the dest
219018334Speter	   must be top of stack. */
219118334Speter
219218334Speter	if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
219318334Speter	  emit_swap_insn (insn, regstack, *dest);
219418334Speter	else
219518334Speter	  {
219618334Speter	    /* Both operands are REG.  If neither operand is already
219718334Speter	       at the top of stack, choose to make the one that is the dest
219818334Speter	       the new top of stack.  */
219918334Speter
220018334Speter	    int src1_hard_regnum, src2_hard_regnum;
220118334Speter
220218334Speter	    src1_hard_regnum = get_hard_regnum (regstack, *src1);
220318334Speter	    src2_hard_regnum = get_hard_regnum (regstack, *src2);
220418334Speter	    if (src1_hard_regnum == -1 || src2_hard_regnum == -1)
220518334Speter	      abort ();
220618334Speter
220718334Speter	    if (src1_hard_regnum != FIRST_STACK_REG
220818334Speter		&& src2_hard_regnum != FIRST_STACK_REG)
220918334Speter	      emit_swap_insn (insn, regstack, *dest);
221018334Speter	  }
221118334Speter
221218334Speter	if (STACK_REG_P (*src1))
221318334Speter	  replace_reg (src1, get_hard_regnum (regstack, *src1));
221418334Speter	if (STACK_REG_P (*src2))
221518334Speter	  replace_reg (src2, get_hard_regnum (regstack, *src2));
221618334Speter
221718334Speter	if (src1_note)
221818334Speter	  {
221918334Speter	    /* If the register that dies is at the top of stack, then
222018334Speter	       the destination is somewhere else - merely substitute it.
222118334Speter	       But if the reg that dies is not at top of stack, then
222218334Speter	       move the top of stack to the dead reg, as though we had
222318334Speter	       done the insn and then a store-with-pop. */
222418334Speter
222518334Speter	    if (REGNO (XEXP (src1_note, 0)) == regstack->reg[regstack->top])
222618334Speter	      {
222718334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
222818334Speter		replace_reg (dest, get_hard_regnum (regstack, *dest));
222918334Speter	      }
223018334Speter	    else
223118334Speter	      {
223218334Speter		int regno = get_hard_regnum (regstack, XEXP (src1_note, 0));
223318334Speter
223418334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
223518334Speter		replace_reg (dest, regno);
223618334Speter
223718334Speter		regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
223818334Speter		  = regstack->reg[regstack->top];
223918334Speter	      }
224018334Speter
224118334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set,
224218334Speter				REGNO (XEXP (src1_note, 0)));
224318334Speter	    replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
224418334Speter	    regstack->top--;
224518334Speter	  }
224618334Speter	else if (src2_note)
224718334Speter	  {
224818334Speter	    if (REGNO (XEXP (src2_note, 0)) == regstack->reg[regstack->top])
224918334Speter	      {
225018334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
225118334Speter		replace_reg (dest, get_hard_regnum (regstack, *dest));
225218334Speter	      }
225318334Speter	    else
225418334Speter	      {
225518334Speter		int regno = get_hard_regnum (regstack, XEXP (src2_note, 0));
225618334Speter
225718334Speter		SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
225818334Speter		replace_reg (dest, regno);
225918334Speter
226018334Speter		regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
226118334Speter		  = regstack->reg[regstack->top];
226218334Speter	      }
226318334Speter
226418334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set,
226518334Speter				REGNO (XEXP (src2_note, 0)));
226618334Speter	    replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
226718334Speter	    regstack->top--;
226818334Speter	  }
226918334Speter	else
227018334Speter	  {
227118334Speter	    SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
227218334Speter	    replace_reg (dest, get_hard_regnum (regstack, *dest));
227318334Speter	  }
227418334Speter
227518334Speter	break;
227618334Speter
227718334Speter      case UNSPEC:
227818334Speter	switch (XINT (SET_SRC (pat), 1))
227918334Speter	  {
228018334Speter	  case 1: /* sin */
228118334Speter	  case 2: /* cos */
228218334Speter	    /* These insns only operate on the top of the stack.  */
228318334Speter
228418334Speter	    src1 = get_true_reg (&XVECEXP (SET_SRC (pat), 0, 0));
228518334Speter
228618334Speter	    emit_swap_insn (insn, regstack, *src1);
228718334Speter
228818334Speter	    src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
228918334Speter
229018334Speter	    if (STACK_REG_P (*dest))
229118334Speter	      replace_reg (dest, FIRST_STACK_REG);
229218334Speter
229318334Speter	    if (src1_note)
229418334Speter	      {
229518334Speter		replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
229618334Speter		regstack->top--;
229718334Speter		CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
229818334Speter	      }
229918334Speter
230018334Speter	    replace_reg (src1, FIRST_STACK_REG);
230118334Speter
230218334Speter	    break;
230318334Speter
230418334Speter	  default:
230518334Speter	    abort ();
230618334Speter	  }
230718334Speter	break;
230818334Speter
230918334Speter      default:
231018334Speter	abort ();
231118334Speter      }
231218334Speter}
231318334Speter
231418334Speter/* Substitute hard regnums for any stack regs in INSN, which has
231518334Speter   N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
231618334Speter   before the insn, and is updated with changes made here.  CONSTRAINTS is
231718334Speter   an array of the constraint strings used in the asm statement.
231818334Speter
231918334Speter   OPERANDS is an array of the operands, and OPERANDS_LOC is a
232018334Speter   parallel array of where the operands were found.  The output operands
232118334Speter   all precede the input operands.
232218334Speter
232318334Speter   There are several requirements and assumptions about the use of
232418334Speter   stack-like regs in asm statements.  These rules are enforced by
232518334Speter   record_asm_stack_regs; see comments there for details.  Any
232618334Speter   asm_operands left in the RTL at this point may be assume to meet the
232718334Speter   requirements, since record_asm_stack_regs removes any problem asm.  */
232818334Speter
232918334Speterstatic void
233018334Spetersubst_asm_stack_regs (insn, regstack, operands, operands_loc, constraints,
233118334Speter		      n_inputs, n_outputs)
233218334Speter     rtx insn;
233318334Speter     stack regstack;
233418334Speter     rtx *operands, **operands_loc;
233518334Speter     char **constraints;
233618334Speter     int n_inputs, n_outputs;
233718334Speter{
233818334Speter  int n_operands = n_inputs + n_outputs;
233918334Speter  int first_input = n_outputs;
234018334Speter  rtx body = PATTERN (insn);
234118334Speter
234218334Speter  int *operand_matches = (int *) alloca (n_operands * sizeof (int *));
234318334Speter  enum reg_class *operand_class
234418334Speter    = (enum reg_class *) alloca (n_operands * sizeof (enum reg_class *));
234518334Speter
234618334Speter  rtx *note_reg;		/* Array of note contents */
234718334Speter  rtx **note_loc;		/* Address of REG field of each note */
234818334Speter  enum reg_note *note_kind;	/* The type of each note */
234918334Speter
235018334Speter  rtx *clobber_reg;
235118334Speter  rtx **clobber_loc;
235218334Speter
235318334Speter  struct stack_def temp_stack;
235418334Speter  int n_notes;
235518334Speter  int n_clobbers;
235618334Speter  rtx note;
235718334Speter  int i;
235818334Speter
235918334Speter  /* Find out what the constraints required.  If no constraint
236018334Speter     alternative matches, that is a compiler bug: we should have caught
236118334Speter     such an insn during the life analysis pass (and reload should have
236218334Speter     caught it regardless). */
236318334Speter
236418334Speter  i = constrain_asm_operands (n_operands, operands, constraints,
236518334Speter			      operand_matches, operand_class);
236618334Speter  if (i < 0)
236718334Speter    abort ();
236818334Speter
236918334Speter  /* Strip SUBREGs here to make the following code simpler. */
237018334Speter  for (i = 0; i < n_operands; i++)
237118334Speter    if (GET_CODE (operands[i]) == SUBREG
237218334Speter	&& GET_CODE (SUBREG_REG (operands[i])) == REG)
237318334Speter      {
237418334Speter	operands_loc[i] = & SUBREG_REG (operands[i]);
237518334Speter	operands[i] = SUBREG_REG (operands[i]);
237618334Speter      }
237718334Speter
237818334Speter  /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND.  */
237918334Speter
238018334Speter  for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
238118334Speter    i++;
238218334Speter
238318334Speter  note_reg = (rtx *) alloca (i * sizeof (rtx));
238418334Speter  note_loc = (rtx **) alloca (i * sizeof (rtx *));
238518334Speter  note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note));
238618334Speter
238718334Speter  n_notes = 0;
238818334Speter  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
238918334Speter    {
239018334Speter      rtx reg = XEXP (note, 0);
239118334Speter      rtx *loc = & XEXP (note, 0);
239218334Speter
239318334Speter      if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
239418334Speter	{
239518334Speter	  loc = & SUBREG_REG (reg);
239618334Speter	  reg = SUBREG_REG (reg);
239718334Speter	}
239818334Speter
239918334Speter      if (STACK_REG_P (reg)
240018334Speter	  && (REG_NOTE_KIND (note) == REG_DEAD
240118334Speter	      || REG_NOTE_KIND (note) == REG_UNUSED))
240218334Speter	{
240318334Speter	  note_reg[n_notes] = reg;
240418334Speter	  note_loc[n_notes] = loc;
240518334Speter	  note_kind[n_notes] = REG_NOTE_KIND (note);
240618334Speter	  n_notes++;
240718334Speter	}
240818334Speter    }
240918334Speter
241018334Speter  /* Set up CLOBBER_REG and CLOBBER_LOC.  */
241118334Speter
241218334Speter  n_clobbers = 0;
241318334Speter
241418334Speter  if (GET_CODE (body) == PARALLEL)
241518334Speter    {
241618334Speter      clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx *));
241718334Speter      clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx **));
241818334Speter
241918334Speter      for (i = 0; i < XVECLEN (body, 0); i++)
242018334Speter	if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
242118334Speter	  {
242218334Speter	    rtx clobber = XVECEXP (body, 0, i);
242318334Speter	    rtx reg = XEXP (clobber, 0);
242418334Speter	    rtx *loc = & XEXP (clobber, 0);
242518334Speter
242618334Speter	    if (GET_CODE (reg) == SUBREG && GET_CODE (SUBREG_REG (reg)) == REG)
242718334Speter	      {
242818334Speter		loc = & SUBREG_REG (reg);
242918334Speter		reg = SUBREG_REG (reg);
243018334Speter	      }
243118334Speter
243218334Speter	    if (STACK_REG_P (reg))
243318334Speter	      {
243418334Speter		clobber_reg[n_clobbers] = reg;
243518334Speter		clobber_loc[n_clobbers] = loc;
243618334Speter		n_clobbers++;
243718334Speter	      }
243818334Speter	  }
243918334Speter    }
244018334Speter
244118334Speter  bcopy ((char *) regstack, (char *) &temp_stack, sizeof (temp_stack));
244218334Speter
244318334Speter  /* Put the input regs into the desired place in TEMP_STACK.  */
244418334Speter
244518334Speter  for (i = first_input; i < first_input + n_inputs; i++)
244618334Speter    if (STACK_REG_P (operands[i])
244718334Speter	&& reg_class_subset_p (operand_class[i], FLOAT_REGS)
244818334Speter	&& operand_class[i] != FLOAT_REGS)
244918334Speter      {
245018334Speter	/* If an operand needs to be in a particular reg in
245118334Speter	   FLOAT_REGS, the constraint was either 't' or 'u'.  Since
245218334Speter	   these constraints are for single register classes, and reload
245318334Speter	   guaranteed that operand[i] is already in that class, we can
245418334Speter	   just use REGNO (operands[i]) to know which actual reg this
245518334Speter	   operand needs to be in. */
245618334Speter
245718334Speter	int regno = get_hard_regnum (&temp_stack, operands[i]);
245818334Speter
245918334Speter	if (regno < 0)
246018334Speter	  abort ();
246118334Speter
246218334Speter	if (regno != REGNO (operands[i]))
246318334Speter	  {
246418334Speter	    /* operands[i] is not in the right place.  Find it
246518334Speter	       and swap it with whatever is already in I's place.
246618334Speter	       K is where operands[i] is now.  J is where it should
246718334Speter	       be. */
246818334Speter	    int j, k, temp;
246918334Speter
247018334Speter	    k = temp_stack.top - (regno - FIRST_STACK_REG);
247118334Speter	    j = (temp_stack.top
247218334Speter		 - (REGNO (operands[i]) - FIRST_STACK_REG));
247318334Speter
247418334Speter	    temp = temp_stack.reg[k];
247518334Speter	    temp_stack.reg[k] = temp_stack.reg[j];
247618334Speter	    temp_stack.reg[j] = temp;
247718334Speter	  }
247818334Speter      }
247918334Speter
248018334Speter  /* emit insns before INSN to make sure the reg-stack is in the right
248118334Speter     order.  */
248218334Speter
248318334Speter  change_stack (insn, regstack, &temp_stack, emit_insn_before);
248418334Speter
248518334Speter  /* Make the needed input register substitutions.  Do death notes and
248618334Speter     clobbers too, because these are for inputs, not outputs. */
248718334Speter
248818334Speter  for (i = first_input; i < first_input + n_inputs; i++)
248918334Speter    if (STACK_REG_P (operands[i]))
249018334Speter      {
249118334Speter	int regnum = get_hard_regnum (regstack, operands[i]);
249218334Speter
249318334Speter	if (regnum < 0)
249418334Speter	  abort ();
249518334Speter
249618334Speter	replace_reg (operands_loc[i], regnum);
249718334Speter      }
249818334Speter
249918334Speter  for (i = 0; i < n_notes; i++)
250018334Speter    if (note_kind[i] == REG_DEAD)
250118334Speter      {
250218334Speter	int regnum = get_hard_regnum (regstack, note_reg[i]);
250318334Speter
250418334Speter	if (regnum < 0)
250518334Speter	  abort ();
250618334Speter
250718334Speter	replace_reg (note_loc[i], regnum);
250818334Speter      }
250918334Speter
251018334Speter  for (i = 0; i < n_clobbers; i++)
251118334Speter    {
251218334Speter      /* It's OK for a CLOBBER to reference a reg that is not live.
251318334Speter         Don't try to replace it in that case.  */
251418334Speter      int regnum = get_hard_regnum (regstack, clobber_reg[i]);
251518334Speter
251618334Speter      if (regnum >= 0)
251718334Speter	{
251818334Speter	  /* Sigh - clobbers always have QImode.  But replace_reg knows
251918334Speter	     that these regs can't be MODE_INT and will abort.  Just put
252018334Speter	     the right reg there without calling replace_reg.  */
252118334Speter
252218334Speter	  *clobber_loc[i] = FP_MODE_REG (regnum, DFmode);
252318334Speter	}
252418334Speter    }
252518334Speter
252618334Speter  /* Now remove from REGSTACK any inputs that the asm implicitly popped. */
252718334Speter
252818334Speter  for (i = first_input; i < first_input + n_inputs; i++)
252918334Speter    if (STACK_REG_P (operands[i]))
253018334Speter      {
253118334Speter	/* An input reg is implicitly popped if it is tied to an
253218334Speter	   output, or if there is a CLOBBER for it. */
253318334Speter	int j;
253418334Speter
253518334Speter	for (j = 0; j < n_clobbers; j++)
253618334Speter	  if (operands_match_p (clobber_reg[j], operands[i]))
253718334Speter	    break;
253818334Speter
253918334Speter	if (j < n_clobbers || operand_matches[i] >= 0)
254018334Speter	  {
254118334Speter	    /* operands[i] might not be at the top of stack.  But that's OK,
254218334Speter	       because all we need to do is pop the right number of regs
254318334Speter	       off of the top of the reg-stack.  record_asm_stack_regs
254418334Speter	       guaranteed that all implicitly popped regs were grouped
254518334Speter	       at the top of the reg-stack.  */
254618334Speter
254718334Speter	    CLEAR_HARD_REG_BIT (regstack->reg_set,
254818334Speter				regstack->reg[regstack->top]);
254918334Speter	    regstack->top--;
255018334Speter	  }
255118334Speter      }
255218334Speter
255318334Speter  /* Now add to REGSTACK any outputs that the asm implicitly pushed.
255418334Speter     Note that there isn't any need to substitute register numbers.
255518334Speter     ???  Explain why this is true. */
255618334Speter
255718334Speter  for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
255818334Speter    {
255918334Speter      /* See if there is an output for this hard reg.  */
256018334Speter      int j;
256118334Speter
256218334Speter      for (j = 0; j < n_outputs; j++)
256318334Speter	if (STACK_REG_P (operands[j]) && REGNO (operands[j]) == i)
256418334Speter	  {
256518334Speter	    regstack->reg[++regstack->top] = i;
256618334Speter	    SET_HARD_REG_BIT (regstack->reg_set, i);
256718334Speter	    break;
256818334Speter	  }
256918334Speter    }
257018334Speter
257118334Speter  /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
257218334Speter     input that the asm didn't implicitly pop.  If the asm didn't
257318334Speter     implicitly pop an input reg, that reg will still be live.
257418334Speter
257518334Speter     Note that we can't use find_regno_note here: the register numbers
257618334Speter     in the death notes have already been substituted.  */
257718334Speter
257818334Speter  for (i = 0; i < n_outputs; i++)
257918334Speter    if (STACK_REG_P (operands[i]))
258018334Speter      {
258118334Speter	int j;
258218334Speter
258318334Speter	for (j = 0; j < n_notes; j++)
258418334Speter	  if (REGNO (operands[i]) == REGNO (note_reg[j])
258518334Speter	      && note_kind[j] == REG_UNUSED)
258618334Speter	    {
258718334Speter	      insn = emit_pop_insn (insn, regstack, operands[i],
258818334Speter				    emit_insn_after);
258918334Speter	      break;
259018334Speter	    }
259118334Speter      }
259218334Speter
259318334Speter  for (i = first_input; i < first_input + n_inputs; i++)
259418334Speter    if (STACK_REG_P (operands[i]))
259518334Speter      {
259618334Speter	int j;
259718334Speter
259818334Speter	for (j = 0; j < n_notes; j++)
259918334Speter	  if (REGNO (operands[i]) == REGNO (note_reg[j])
260018334Speter	      && note_kind[j] == REG_DEAD
260118334Speter	      && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (operands[i])))
260218334Speter	    {
260318334Speter	      insn = emit_pop_insn (insn, regstack, operands[i],
260418334Speter				    emit_insn_after);
260518334Speter	      break;
260618334Speter	    }
260718334Speter      }
260818334Speter}
260918334Speter
261018334Speter/* Substitute stack hard reg numbers for stack virtual registers in
261118334Speter   INSN.  Non-stack register numbers are not changed.  REGSTACK is the
261218334Speter   current stack content.  Insns may be emitted as needed to arrange the
261318334Speter   stack for the 387 based on the contents of the insn. */
261418334Speter
261518334Speterstatic void
261618334Spetersubst_stack_regs (insn, regstack)
261718334Speter     rtx insn;
261818334Speter     stack regstack;
261918334Speter{
262018334Speter  register rtx *note_link, note;
262118334Speter  register int i;
262218334Speter  int n_operands;
262318334Speter
262418334Speter  if (GET_CODE (insn) == CALL_INSN)
262518334Speter   {
262618334Speter     int top = regstack->top;
262718334Speter
262818334Speter     /* If there are any floating point parameters to be passed in
262918334Speter	registers for this call, make sure they are in the right
263018334Speter	order.  */
263118334Speter
263218334Speter     if (top >= 0)
263318334Speter      {
263418334Speter	straighten_stack (PREV_INSN (insn), regstack);
263518334Speter
263618334Speter	/* Now mark the arguments as dead after the call.  */
263718334Speter
263818334Speter        while (regstack->top >= 0)
263918334Speter         {
264018334Speter           CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top);
264118334Speter	   regstack->top--;
264218334Speter         }
264318334Speter      }
264418334Speter   }
264518334Speter
264618334Speter  /* Do the actual substitution if any stack regs are mentioned.
264718334Speter     Since we only record whether entire insn mentions stack regs, and
264818334Speter     subst_stack_regs_pat only works for patterns that contain stack regs,
264918334Speter     we must check each pattern in a parallel here.  A call_value_pop could
265018334Speter     fail otherwise. */
265118334Speter
265218334Speter  if (GET_MODE (insn) == QImode)
265318334Speter    {
265418334Speter      n_operands = asm_noperands (PATTERN (insn));
265518334Speter      if (n_operands >= 0)
265618334Speter	{
265718334Speter	  /* This insn is an `asm' with operands.  Decode the operands,
265818334Speter	     decide how many are inputs, and do register substitution.
265918334Speter	     Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */
266018334Speter
266118334Speter	  rtx operands[MAX_RECOG_OPERANDS];
266218334Speter	  rtx *operands_loc[MAX_RECOG_OPERANDS];
266318334Speter	  rtx body = PATTERN (insn);
266418334Speter	  int n_inputs, n_outputs;
266518334Speter	  char **constraints
266618334Speter	    = (char **) alloca (n_operands * sizeof (char *));
266718334Speter
266818334Speter	  decode_asm_operands (body, operands, operands_loc,
266918334Speter			       constraints, NULL_PTR);
267018334Speter	  get_asm_operand_lengths (body, n_operands, &n_inputs, &n_outputs);
267118334Speter	  subst_asm_stack_regs (insn, regstack, operands, operands_loc,
267218334Speter				constraints, n_inputs, n_outputs);
267318334Speter	  return;
267418334Speter	}
267518334Speter
267618334Speter      if (GET_CODE (PATTERN (insn)) == PARALLEL)
267718334Speter	for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
267818334Speter	  {
267918334Speter	    if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
268018334Speter	      subst_stack_regs_pat (insn, regstack,
268118334Speter				    XVECEXP (PATTERN (insn), 0, i));
268218334Speter	  }
268318334Speter      else
268418334Speter	subst_stack_regs_pat (insn, regstack, PATTERN (insn));
268518334Speter    }
268618334Speter
268718334Speter  /* subst_stack_regs_pat may have deleted a no-op insn.  If so, any
268818334Speter     REG_UNUSED will already have been dealt with, so just return. */
268918334Speter
269018334Speter  if (GET_CODE (insn) == NOTE)
269118334Speter    return;
269218334Speter
269318334Speter  /* If there is a REG_UNUSED note on a stack register on this insn,
269418334Speter     the indicated reg must be popped.  The REG_UNUSED note is removed,
269518334Speter     since the form of the newly emitted pop insn references the reg,
269618334Speter     making it no longer `unset'. */
269718334Speter
269818334Speter  note_link = &REG_NOTES(insn);
269918334Speter  for (note = *note_link; note; note = XEXP (note, 1))
270018334Speter    if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
270118334Speter      {
270218334Speter	*note_link = XEXP (note, 1);
270318334Speter	insn = emit_pop_insn (insn, regstack, XEXP (note, 0), emit_insn_after);
270418334Speter      }
270518334Speter    else
270618334Speter      note_link = &XEXP (note, 1);
270718334Speter}
270818334Speter
270918334Speter/* Change the organization of the stack so that it fits a new basic
271018334Speter   block.  Some registers might have to be popped, but there can never be
271118334Speter   a register live in the new block that is not now live.
271218334Speter
271318334Speter   Insert any needed insns before or after INSN.  WHEN is emit_insn_before
271418334Speter   or emit_insn_after. OLD is the original stack layout, and NEW is
271518334Speter   the desired form.  OLD is updated to reflect the code emitted, ie, it
271618334Speter   will be the same as NEW upon return.
271718334Speter
271818334Speter   This function will not preserve block_end[].  But that information
271918334Speter   is no longer needed once this has executed. */
272018334Speter
272118334Speterstatic void
272218334Speterchange_stack (insn, old, new, when)
272318334Speter     rtx insn;
272418334Speter     stack old;
272518334Speter     stack new;
272618334Speter     rtx (*when)();
272718334Speter{
272818334Speter  int reg;
272918334Speter
273018334Speter  /* We will be inserting new insns "backwards", by calling emit_insn_before.
273118334Speter     If we are to insert after INSN, find the next insn, and insert before
273218334Speter     it.  */
273318334Speter
273418334Speter  if (when == emit_insn_after)
273518334Speter    insn = NEXT_INSN (insn);
273618334Speter
273718334Speter  /* Pop any registers that are not needed in the new block. */
273818334Speter
273918334Speter  for (reg = old->top; reg >= 0; reg--)
274018334Speter    if (! TEST_HARD_REG_BIT (new->reg_set, old->reg[reg]))
274118334Speter      emit_pop_insn (insn, old, FP_MODE_REG (old->reg[reg], DFmode),
274218334Speter		     emit_insn_before);
274318334Speter
274418334Speter  if (new->top == -2)
274518334Speter    {
274618334Speter      /* If the new block has never been processed, then it can inherit
274718334Speter	 the old stack order. */
274818334Speter
274918334Speter      new->top = old->top;
275018334Speter      bcopy (old->reg, new->reg, sizeof (new->reg));
275118334Speter    }
275218334Speter  else
275318334Speter    {
275418334Speter      /* This block has been entered before, and we must match the
275518334Speter	 previously selected stack order. */
275618334Speter
275718334Speter      /* By now, the only difference should be the order of the stack,
275818334Speter	 not their depth or liveliness. */
275918334Speter
276018334Speter      GO_IF_HARD_REG_EQUAL (old->reg_set, new->reg_set, win);
276118334Speter
276218334Speter      abort ();
276318334Speter
276418334Speter    win:
276518334Speter
276618334Speter      if (old->top != new->top)
276718334Speter	abort ();
276818334Speter
276918334Speter      /* Loop here emitting swaps until the stack is correct.  The
277018334Speter	 worst case number of swaps emitted is N + 2, where N is the
277118334Speter	 depth of the stack.  In some cases, the reg at the top of
277218334Speter	 stack may be correct, but swapped anyway in order to fix
277318334Speter	 other regs.  But since we never swap any other reg away from
277418334Speter	 its correct slot, this algorithm will converge. */
277518334Speter
277618334Speter      do
277718334Speter	{
277818334Speter	  /* Swap the reg at top of stack into the position it is
277918334Speter	     supposed to be in, until the correct top of stack appears. */
278018334Speter
278118334Speter	  while (old->reg[old->top] != new->reg[new->top])
278218334Speter	    {
278318334Speter	      for (reg = new->top; reg >= 0; reg--)
278418334Speter		if (new->reg[reg] == old->reg[old->top])
278518334Speter		  break;
278618334Speter
278718334Speter	      if (reg == -1)
278818334Speter		abort ();
278918334Speter
279018334Speter	      emit_swap_insn (insn, old,
279118334Speter			      FP_MODE_REG (old->reg[reg], DFmode));
279218334Speter	    }
279318334Speter
279418334Speter	  /* See if any regs remain incorrect.  If so, bring an
279518334Speter	     incorrect reg to the top of stack, and let the while loop
279618334Speter	     above fix it. */
279718334Speter
279818334Speter	  for (reg = new->top; reg >= 0; reg--)
279918334Speter	    if (new->reg[reg] != old->reg[reg])
280018334Speter	      {
280118334Speter		emit_swap_insn (insn, old,
280218334Speter				FP_MODE_REG (old->reg[reg], DFmode));
280318334Speter		break;
280418334Speter	      }
280518334Speter	} while (reg >= 0);
280618334Speter
280718334Speter      /* At this point there must be no differences. */
280818334Speter
280918334Speter      for (reg = old->top; reg >= 0; reg--)
281018334Speter	if (old->reg[reg] != new->reg[reg])
281118334Speter	  abort ();
281218334Speter    }
281318334Speter}
281418334Speter
281518334Speter/* Check PAT, which points to RTL in INSN, for a LABEL_REF.  If it is
281618334Speter   found, ensure that a jump from INSN to the code_label to which the
281718334Speter   label_ref points ends up with the same stack as that at the
281818334Speter   code_label.  Do this by inserting insns just before the code_label to
281918334Speter   pop and rotate the stack until it is in the correct order.  REGSTACK
282018334Speter   is the order of the register stack in INSN.
282118334Speter
282218334Speter   Any code that is emitted here must not be later processed as part
282318334Speter   of any block, as it will already contain hard register numbers. */
282418334Speter
282518334Speterstatic void
282618334Spetergoto_block_pat (insn, regstack, pat)
282718334Speter     rtx insn;
282818334Speter     stack regstack;
282918334Speter     rtx pat;
283018334Speter{
283118334Speter  rtx label;
283218334Speter  rtx new_jump, new_label, new_barrier;
283318334Speter  rtx *ref;
283418334Speter  stack label_stack;
283518334Speter  struct stack_def temp_stack;
283618334Speter  int reg;
283718334Speter
283818334Speter  switch (GET_CODE (pat))
283918334Speter   {
284018334Speter     case RETURN:
284118334Speter	straighten_stack (PREV_INSN (insn), regstack);
284218334Speter	return;
284318334Speter     default:
284418334Speter     {
284518334Speter      int i, j;
284618334Speter      char *fmt = GET_RTX_FORMAT (GET_CODE (pat));
284718334Speter
284818334Speter      for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
284918334Speter	{
285018334Speter	  if (fmt[i] == 'e')
285118334Speter	    goto_block_pat (insn, regstack, XEXP (pat, i));
285218334Speter	  if (fmt[i] == 'E')
285318334Speter	    for (j = 0; j < XVECLEN (pat, i); j++)
285418334Speter	      goto_block_pat (insn, regstack, XVECEXP (pat, i, j));
285518334Speter	}
285618334Speter      return;
285718334Speter     }
285818334Speter     case LABEL_REF:;
285918334Speter   }
286018334Speter
286118334Speter  label = XEXP (pat, 0);
286218334Speter  if (GET_CODE (label) != CODE_LABEL)
286318334Speter    abort ();
286418334Speter
286518334Speter  /* First, see if in fact anything needs to be done to the stack at all. */
286618334Speter  if (INSN_UID (label) <= 0)
286718334Speter    return;
286818334Speter
286918334Speter  label_stack = &block_stack_in[BLOCK_NUM (label)];
287018334Speter
287118334Speter  if (label_stack->top == -2)
287218334Speter    {
287318334Speter      /* If the target block hasn't had a stack order selected, then
287418334Speter	 we need merely ensure that no pops are needed. */
287518334Speter
287618334Speter      for (reg = regstack->top; reg >= 0; reg--)
287718334Speter	if (! TEST_HARD_REG_BIT (label_stack->reg_set, regstack->reg[reg]))
287818334Speter	  break;
287918334Speter
288018334Speter      if (reg == -1)
288118334Speter	{
288218334Speter	  /* change_stack will not emit any code in this case. */
288318334Speter
288418334Speter	  change_stack (label, regstack, label_stack, emit_insn_after);
288518334Speter	  return;
288618334Speter	}
288718334Speter    }
288818334Speter  else if (label_stack->top == regstack->top)
288918334Speter    {
289018334Speter      for (reg = label_stack->top; reg >= 0; reg--)
289118334Speter	if (label_stack->reg[reg] != regstack->reg[reg])
289218334Speter	  break;
289318334Speter
289418334Speter      if (reg == -1)
289518334Speter	return;
289618334Speter    }
289718334Speter
289818334Speter  /* At least one insn will need to be inserted before label.  Insert
289918334Speter     a jump around the code we are about to emit.  Emit a label for the new
290018334Speter     code, and point the original insn at this new label. We can't use
290118334Speter     redirect_jump here, because we're using fld[4] of the code labels as
290218334Speter     LABEL_REF chains, no NUSES counters. */
290318334Speter
290418334Speter  new_jump = emit_jump_insn_before (gen_jump (label), label);
290518334Speter  record_label_references (new_jump, PATTERN (new_jump));
290618334Speter  JUMP_LABEL (new_jump) = label;
290718334Speter
290818334Speter  new_barrier = emit_barrier_after (new_jump);
290918334Speter
291018334Speter  new_label = gen_label_rtx ();
291118334Speter  emit_label_after (new_label, new_barrier);
291218334Speter  LABEL_REFS (new_label) = new_label;
291318334Speter
291418334Speter  /* The old label_ref will no longer point to the code_label if now uses,
291518334Speter     so strip the label_ref from the code_label's chain of references. */
291618334Speter
291718334Speter  for (ref = &LABEL_REFS (label); *ref != label; ref = &LABEL_NEXTREF (*ref))
291818334Speter    if (*ref == pat)
291918334Speter      break;
292018334Speter
292118334Speter  if (*ref == label)
292218334Speter    abort ();
292318334Speter
292418334Speter  *ref = LABEL_NEXTREF (*ref);
292518334Speter
292618334Speter  XEXP (pat, 0) = new_label;
292718334Speter  record_label_references (insn, PATTERN (insn));
292818334Speter
292918334Speter  if (JUMP_LABEL (insn) == label)
293018334Speter    JUMP_LABEL (insn) = new_label;
293118334Speter
293218334Speter  /* Now emit the needed code. */
293318334Speter
293418334Speter  temp_stack = *regstack;
293518334Speter
293618334Speter  change_stack (new_label, &temp_stack, label_stack, emit_insn_after);
293718334Speter}
293818334Speter
293918334Speter/* Traverse all basic blocks in a function, converting the register
294018334Speter   references in each insn from the "flat" register file that gcc uses, to
294118334Speter   the stack-like registers the 387 uses. */
294218334Speter
294318334Speterstatic void
294418334Speterconvert_regs ()
294518334Speter{
294618334Speter  register int block, reg;
294718334Speter  register rtx insn, next;
294818334Speter  struct stack_def regstack;
294918334Speter
295018334Speter  for (block = 0; block < blocks; block++)
295118334Speter    {
295218334Speter      if (block_stack_in[block].top == -2)
295318334Speter	{
295418334Speter	  /* This block has not been previously encountered.  Choose a
295518334Speter	     default mapping for any stack regs live on entry */
295618334Speter
295718334Speter	  block_stack_in[block].top = -1;
295818334Speter
295918334Speter	  for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; reg--)
296018334Speter	    if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, reg))
296118334Speter	      block_stack_in[block].reg[++block_stack_in[block].top] = reg;
296218334Speter	}
296318334Speter
296418334Speter      /* Process all insns in this block.  Keep track of `next' here,
296518334Speter	 so that we don't process any insns emitted while making
296618334Speter	 substitutions in INSN. */
296718334Speter
296818334Speter      next = block_begin[block];
296918334Speter      regstack = block_stack_in[block];
297018334Speter      do
297118334Speter	{
297218334Speter	  insn = next;
297318334Speter	  next = NEXT_INSN (insn);
297418334Speter
297518334Speter	  /* Don't bother processing unless there is a stack reg
297618334Speter	     mentioned or if it's a CALL_INSN (register passing of
297718334Speter	     floating point values). */
297818334Speter
297918334Speter	  if (GET_MODE (insn) == QImode || GET_CODE (insn) == CALL_INSN)
298018334Speter	    subst_stack_regs (insn, &regstack);
298118334Speter
298218334Speter	} while (insn != block_end[block]);
298318334Speter
298418334Speter      /* Something failed if the stack life doesn't match. */
298518334Speter
298618334Speter      GO_IF_HARD_REG_EQUAL (regstack.reg_set, block_out_reg_set[block], win);
298718334Speter
298818334Speter      abort ();
298918334Speter
299018334Speter    win:
299118334Speter
299218334Speter      /* Adjust the stack of this block on exit to match the stack of
299318334Speter	 the target block, or copy stack information into stack of
299418334Speter	 jump target if the target block's stack order hasn't been set
299518334Speter	 yet. */
299618334Speter
299718334Speter      if (GET_CODE (insn) == JUMP_INSN)
299818334Speter	goto_block_pat (insn, &regstack, PATTERN (insn));
299918334Speter
300018334Speter      /* Likewise handle the case where we fall into the next block. */
300118334Speter
300218334Speter      if ((block < blocks - 1) && block_drops_in[block+1])
300318334Speter	change_stack (insn, &regstack, &block_stack_in[block+1],
300418334Speter		      emit_insn_after);
300518334Speter    }
300618334Speter
300718334Speter  /* If the last basic block is the end of a loop, and that loop has
300818334Speter     regs live at its start, then the last basic block will have regs live
300918334Speter     at its end that need to be popped before the function returns. */
301018334Speter
301118334Speter   {
301218334Speter     int value_reg_low, value_reg_high;
301318334Speter     value_reg_low = value_reg_high = -1;
301418334Speter      {
301518334Speter        rtx retvalue;
301618334Speter        if (retvalue = stack_result (current_function_decl))
301718334Speter	 {
301818334Speter	   value_reg_low = REGNO (retvalue);
301918334Speter	   value_reg_high = value_reg_low +
302018334Speter	    HARD_REGNO_NREGS (value_reg_low, GET_MODE (retvalue)) - 1;
302118334Speter	 }
302218334Speter
302318334Speter      }
302418334Speter     for (reg = regstack.top; reg >= 0; reg--)
302518334Speter        if (regstack.reg[reg] < value_reg_low ||
302618334Speter            regstack.reg[reg] > value_reg_high)
302718334Speter           insn = emit_pop_insn (insn, &regstack,
302818334Speter			    FP_MODE_REG (regstack.reg[reg], DFmode),
302918334Speter			    emit_insn_after);
303018334Speter   }
303118334Speter  straighten_stack (insn, &regstack);
303218334Speter}
303318334Speter
303418334Speter/* Check expression PAT, which is in INSN, for label references.  if
303518334Speter   one is found, print the block number of destination to FILE. */
303618334Speter
303718334Speterstatic void
303818334Speterprint_blocks (file, insn, pat)
303918334Speter     FILE *file;
304018334Speter     rtx insn, pat;
304118334Speter{
304218334Speter  register RTX_CODE code = GET_CODE (pat);
304318334Speter  register int i;
304418334Speter  register char *fmt;
304518334Speter
304618334Speter  if (code == LABEL_REF)
304718334Speter    {
304818334Speter      register rtx label = XEXP (pat, 0);
304918334Speter
305018334Speter      if (GET_CODE (label) != CODE_LABEL)
305118334Speter	abort ();
305218334Speter
305318334Speter      fprintf (file, " %d", BLOCK_NUM (label));
305418334Speter
305518334Speter      return;
305618334Speter    }
305718334Speter
305818334Speter  fmt = GET_RTX_FORMAT (code);
305918334Speter  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
306018334Speter    {
306118334Speter      if (fmt[i] == 'e')
306218334Speter	print_blocks (file, insn, XEXP (pat, i));
306318334Speter      if (fmt[i] == 'E')
306418334Speter	{
306518334Speter	  register int j;
306618334Speter	  for (j = 0; j < XVECLEN (pat, i); j++)
306718334Speter	    print_blocks (file, insn, XVECEXP (pat, i, j));
306818334Speter	}
306918334Speter    }
307018334Speter}
307118334Speter
307218334Speter/* Write information about stack registers and stack blocks into FILE.
307318334Speter   This is part of making a debugging dump.  */
307418334Speterstatic void
307518334Speterdump_stack_info (file)
307618334Speter     FILE *file;
307718334Speter{
307818334Speter  register int block;
307918334Speter
308018334Speter  fprintf (file, "\n%d stack blocks.\n", blocks);
308118334Speter  for (block = 0; block < blocks; block++)
308218334Speter    {
308318334Speter      register rtx head, jump, end;
308418334Speter      register int regno;
308518334Speter
308618334Speter      fprintf (file, "\nStack block %d: first insn %d, last %d.\n",
308718334Speter	       block, INSN_UID (block_begin[block]),
308818334Speter	       INSN_UID (block_end[block]));
308918334Speter
309018334Speter      head = block_begin[block];
309118334Speter
309218334Speter      fprintf (file, "Reached from blocks: ");
309318334Speter      if (GET_CODE (head) == CODE_LABEL)
309418334Speter	for (jump = LABEL_REFS (head);
309518334Speter	     jump != head;
309618334Speter	     jump = LABEL_NEXTREF (jump))
309718334Speter	  {
309818334Speter	    register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
309918334Speter	    fprintf (file, " %d", from_block);
310018334Speter	  }
310118334Speter      if (block_drops_in[block])
310218334Speter	fprintf (file, " previous");
310318334Speter
310418334Speter      fprintf (file, "\nlive stack registers on block entry: ");
310518334Speter      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
310618334Speter	{
310718334Speter	  if (TEST_HARD_REG_BIT (block_stack_in[block].reg_set, regno))
310818334Speter	    fprintf (file, "%d ", regno);
310918334Speter	}
311018334Speter
311118334Speter      fprintf (file, "\nlive stack registers on block exit: ");
311218334Speter      for (regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
311318334Speter	{
311418334Speter	  if (TEST_HARD_REG_BIT (block_out_reg_set[block], regno))
311518334Speter	    fprintf (file, "%d ", regno);
311618334Speter	}
311718334Speter
311818334Speter      end = block_end[block];
311918334Speter
312018334Speter      fprintf (file, "\nJumps to blocks: ");
312118334Speter      if (GET_CODE (end) == JUMP_INSN)
312218334Speter	print_blocks (file, end, PATTERN (end));
312318334Speter
312418334Speter      if (block + 1 < blocks && block_drops_in[block+1])
312518334Speter	fprintf (file, " next");
312618334Speter      else if (block + 1 == blocks
312718334Speter	       || (GET_CODE (end) == JUMP_INSN
312818334Speter		   && GET_CODE (PATTERN (end)) == RETURN))
312918334Speter	fprintf (file, " return");
313018334Speter
313118334Speter      fprintf (file, "\n");
313218334Speter    }
313318334Speter}
313418334Speter#endif /* STACK_REGS */
3135