GCC Middle and Back End API Reference
reg-stack.c File Reference

Data Structures

struct  stack_def
struct  block_info_def

Typedefs

typedef struct stack_defstack_ptr
typedef struct block_info_defblock_info

Enumerations

enum  emit_where { EMIT_AFTER, EMIT_BEFORE }

Functions

static int stack_regs_mentioned_p (const_rtx pat)
static void pop_stack (stack_ptr, int)
static rtxget_true_reg (rtx *)
static int check_asm_stack_operands (rtx)
static void get_asm_operands_in_out (rtx, int *, int *)
static rtx stack_result (tree)
static void replace_reg (rtx *, int)
static void remove_regno_note (rtx, enum reg_note, unsigned int)
static int get_hard_regnum (stack_ptr, rtx)
static rtx emit_pop_insn (rtx, stack_ptr, rtx, enum emit_where)
static void swap_to_top (rtx, stack_ptr, rtx, rtx)
static bool move_for_stack_reg (rtx, stack_ptr, rtx)
static bool move_nan_for_stack_reg (rtx, stack_ptr, rtx)
static int swap_rtx_condition_1 (rtx)
static int swap_rtx_condition (rtx)
static void compare_for_stack_reg (rtx, stack_ptr, rtx)
static bool subst_stack_regs_pat (rtx, stack_ptr, rtx)
static void subst_asm_stack_regs (rtx, stack_ptr)
static bool subst_stack_regs (rtx, stack_ptr)
static void change_stack (rtx, stack_ptr, stack_ptr, enum emit_where)
static void print_stack (FILE *, stack_ptr)
static rtx next_flags_user (rtx)
static int stack_regs_mentioned_p ()
int stack_regs_mentioned ()
static rtx next_flags_user ()
static void straighten_stack ()
static void pop_stack ()
static rtxget_true_reg ()
static int check_asm_stack_operands ()
static void get_asm_operands_in_out ()
static rtx stack_result ()
static void replace_reg ()
static void remove_regno_note ()
static int get_hard_regnum ()
static rtx emit_pop_insn ()
static void emit_swap_insn ()
static void swap_to_top ()
static bool move_for_stack_reg ()
static bool move_nan_for_stack_reg ()
static int swap_rtx_condition_1 ()
static int swap_rtx_condition ()
static void compare_for_stack_reg ()
static int subst_stack_regs_in_debug_insn ()
static void subst_all_stack_regs_in_debug_insn ()
static bool subst_stack_regs_pat ()
static void subst_asm_stack_regs ()
static bool subst_stack_regs ()
static void change_stack ()
static void print_stack ()
static int convert_regs_entry ()
static void convert_regs_exit ()
static void propagate_stack ()
static bool compensate_edge ()
static bool compensate_edges ()
static edge better_edge ()
static bool convert_regs_1 ()
static bool convert_regs_2 ()
static void convert_regs ()
static bool reg_to_stack ()
static bool gate_handle_stack_regs ()
rtl_opt_passmake_pass_stack_regs ()
static unsigned int rest_of_handle_stack_regs ()
rtl_opt_passmake_pass_stack_regs_run ()

Variables

static vec< char > stack_regs_mentioned_data
int regstack_completed = 0
static basic_block current_block
static bool starting_stack_p
static rtx FP_mode_reg [LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE]
static rtx not_a_num
static rtx ix86_flags_rtx
static bool any_malformed_asm

Typedef Documentation

typedef struct block_info_def * block_info
This is used to carry information about basic blocks.  It is
   attached to the AUX field of the standard CFG block.   
typedef struct stack_def * stack_ptr
This is the basic stack record.  TOP is an index into REG[] such
   that REG[TOP] is the top of stack.  If TOP is -1 the stack is empty.

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

   REG_SET indicates which registers are live.   

Enumeration Type Documentation

enum emit_where
Passed to change_stack to indicate where to emit insns.   
Enumerator:
EMIT_AFTER 
EMIT_BEFORE 

Function Documentation

static edge better_edge ( )
static
Select the better of two edges E1 and E2 to use to determine the
   stack layout for their shared destination basic block.  This is
   typically the more frequently executed.  The edge E1 may be NULL
   (in which case E2 is returned), but E2 is always non-NULL.   

References edge_def::count, basic_block_def::index, and edge_def::src.

Referenced by convert_regs_1().

static void change_stack ( rtx  ,
stack_ptr  ,
stack_ptr  ,
enum  emit_where 
)
static
static void change_stack ( )
static
Change the organization of the stack so that it fits a new basic
   block.  Some registers might have to be popped, but there can never be
   a register live in the new block that is not now live.

   Insert any needed insns before or after INSN, as indicated by
   WHERE.  OLD is the original stack layout, and NEW is the desired
   form.  OLD is updated to reflect the code emitted, i.e., it will be
   the same as NEW upon return.

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

References EMIT_AFTER, EMIT_BEFORE, emit_insn_before(), emit_pop_insn(), emit_swap_insn(), hard_reg_set_equal_p(), live, memcpy(), not_a_num, stack_def::reg, stack_def::reg_set, slots, starting_stack_p, and stack_def::top.

static int check_asm_stack_operands ( rtx  )
static

Referenced by subst_asm_stack_regs().

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

References any_malformed_asm, constrain_operands(), error_for_asm(), extract_insn(), get_asm_operands_in_out(), memset(), recog_data_d::n_operands, recog_data_d::operand, operands_match_p(), preprocess_constraints(), recog_data, recog_op_alt, stack_def::reg, and which_alternative.

static void compare_for_stack_reg ( rtx  ,
stack_ptr  ,
rtx   
)
static

Referenced by subst_stack_regs_pat().

static void compare_for_stack_reg ( )
static
Handle a comparison.  Special care needs to be taken to avoid
   causing comparisons that a 387 cannot do correctly, such as EQ.

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

References EMIT_AFTER, emit_pop_insn(), emit_swap_insn(), find_regno_note(), get_hard_regnum(), get_true_reg(), pop_stack(), remove_regno_note(), replace_reg(), and swap_rtx_condition().

static bool compensate_edge ( )
static
Adjust the stack of edge E's source block on exit to match the stack
   of it's target block upon input.  The stack layouts of both blocks
   should have been defined by now.   

References change_stack(), edge_def::dest, dump_file, EMIT_AFTER, EMIT_BEFORE, emit_note(), end_sequence(), edge_def::flags, get_insns(), basic_block_def::index, insert_insn_on_edge(), print_stack(), stack_def::reg, edge_def::src, start_sequence(), basic_block_def::succs, and stack_def::top.

Referenced by compensate_edges().

static bool compensate_edges ( )
static
Traverse all non-entry edges in the CFG, and emit the necessary
   edge compensation code to change the stack from stack_out of the
   source block to the stack_in of the destination block.   

References compensate_edge(), inserted, starting_stack_p, and basic_block_def::succs.

Referenced by convert_regs().

static void convert_regs ( )
static
Traverse all basic blocks in a function, converting the register
   references in each insn from the "flat" register file that gcc uses,
   to the stack-like registers the 387 uses.   

References cfg_altered, cleanup_cfg(), clear_aux_for_blocks(), commit_edge_insertions(), compensate_edges(), convert_regs_2(), convert_regs_entry(), convert_regs_exit(), edge_def::dest, dump_file, fixup_abnormal_edges(), and inserted.

Referenced by reg_to_stack().

static bool convert_regs_2 ( )
static
Convert registers in all blocks reachable from BLOCK.  Return true if the
   CFG has been modified in the process.   

References cfg_altered, convert_regs_1(), edge_def::dest, edge_def::flags, free(), stack, and basic_block_def::succs.

Referenced by convert_regs().

static int convert_regs_entry ( )
static
This function was doing life analysis.  We now let the regular live
   code do it's job, so we only need to check some extra invariants
   that reg-stack expects.  Primary among these being that all registers
   are initialized before use.

   The function returns true when code was emitted to CFG edges and
   commit_edge_insertions needs to be called.   

References edge_def::dest, insert_insn_on_edge(), inserted, not_a_num, stack_def::reg, and stack_def::top.

Referenced by convert_regs().

static void convert_regs_exit ( )
static
Construct the desired stack for function exit.  This will either
   be `empty', or the function return value at top-of-stack.   

References current_function_decl, stack_def::reg, stack_def::reg_set, stack_result(), and stack_def::top.

Referenced by convert_regs().

static rtx emit_pop_insn ( )
static
Emit an insn to pop virtual register REG before or after INSN.
   REGSTACK is the stack state after INSN and is updated to reflect this
   pop.  WHEN is either emit_insn_before or emit_insn_after.  A pop insn
   is represented as a SET whose destination is the register to be popped
   and source is the top of stack.  A death note for the top of stack
   cases the movdf pattern to pop.   

References add_reg_note(), EMIT_AFTER, emit_insn_after(), emit_insn_before(), emit_pop_insn(), get_hard_regnum(), stack_def::reg, stack_def::reg_set, and stack_def::top.

static void emit_swap_insn ( )
static
Emit an insn before or after INSN to swap virtual register REG with
   the top of stack.  REGSTACK is the stack state before the swap, and
   is updated to reflect the swap.  A swap insn is represented as a
   PARALLEL of two patterns: each pattern moves one reg to the other.

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

References any_malformed_asm, emit_insn_after(), emit_insn_before(), find_regno_note(), get_hard_regnum(), get_true_reg(), i1, limit, stack_def::reg, stack_regs_mentioned(), starting_stack_p, and stack_def::top.

Referenced by change_stack(), compare_for_stack_reg(), move_for_stack_reg(), and subst_stack_regs_pat().

static bool gate_handle_stack_regs ( )
static
static void get_asm_operands_in_out ( rtx  ,
int *  ,
int *   
)
static
static void get_asm_operands_in_out ( )
static
Calculate the number of inputs and outputs in BODY, an
   asm_operands.  N_OPERANDS is the total number of operands, and
   N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
   placed.   

References extract_asm_operands(), recog_data_d::n_operands, and recog_data.

static int get_hard_regnum ( )
static
Find the hard register number of virtual register REG in REGSTACK.
   The hard register number is relative to the top of the stack.  -1 is
   returned if the register is not found.   

References stack_def::reg, and stack_def::top.

static rtx* get_true_reg ( rtx )
static
static rtx* get_true_reg ( )
static
Return a pointer to the REG expression within PAT.  If PAT is not a
   REG, possible enclosed by a conversion rtx, return the inner part of
   PAT that stopped the search.   

References subreg_regno_offset().

rtl_opt_pass* make_pass_stack_regs ( )
rtl_opt_pass* make_pass_stack_regs_run ( )
static bool move_for_stack_reg ( rtx  ,
stack_ptr  ,
rtx   
)
static
static bool move_for_stack_reg ( )
static
Handle a move to or from a stack register in PAT, which is in INSN.
   REGSTACK is the current stack.  Return whether a control flow insn
   was deleted in the process.   

References add_reg_note(), control_flow_insn_p(), delete_insn(), EMIT_AFTER, emit_insn_before(), emit_pop_insn(), emit_swap_insn(), find_regno_note(), get_hard_regnum(), get_true_reg(), move_nan_for_stack_reg(), stack_def::reg, stack_def::reg_set, replace_reg(), SET, and stack_def::top.

static bool move_nan_for_stack_reg ( rtx  ,
stack_ptr  ,
rtx   
)
static
static bool move_nan_for_stack_reg ( )
static
A helper function which replaces INSN with a pattern that loads up
   a NaN into DEST, then invokes move_for_stack_reg.   

References move_for_stack_reg(), and not_a_num.

static rtx next_flags_user ( rtx  )
static

Referenced by swap_rtx_condition().

static rtx next_flags_user ( )
static
static void pop_stack ( stack_ptr  ,
int   
)
static

Referenced by compare_for_stack_reg().

static void pop_stack ( )
static
Pop a register from the stack.   

References stack_def::reg, stack_def::reg_set, and stack_def::top.

static void print_stack ( FILE *  ,
stack_ptr   
)
static

Referenced by compensate_edge(), and convert_regs_1().

static void print_stack ( )
static
Print stack configuration.   

References stack_def::reg, and stack_def::top.

static void propagate_stack ( )
static
Copy the stack info from the end of edge E's source block to the
   start of E's destination block.   

References edge_def::dest, stack_def::reg, stack_def::reg_set, edge_def::src, and stack_def::top.

Referenced by convert_regs_1().

static bool reg_to_stack ( )
static
Convert register usage from "flat" register file usage to a "stack
   register file.  FILE is the dump file, if used.

   Construct a CFG and run life analysis.  Then convert each insn one
   by one.  Run a last cleanup_cfg pass, if optimizing, to eliminate
   code duplication created when the converter inserts pop insns on
   the edges.   

References alloc_aux_for_blocks(), convert_regs(), df_analyze(), df_note_add_problem(), df_regs_ever_live_p(), edge_def::flags, force_const_mem(), free_aux_for_blocks(), gen_rtx_REG(), get_max_uid(), ix86_flags_rtx, mark_dfs_back_edges(), max_uid, memset(), not_a_num, basic_block_def::preds, real_nan(), stack_def::reg, and edge_def::src.

Referenced by rest_of_handle_stack_regs().

static void remove_regno_note ( rtx  ,
enum  reg_note,
unsigned  int 
)
static
static void remove_regno_note ( )
static
Remove a note of type NOTE, which must be found, for register
   number REGNO from INSN.  Remove only one such note.   
static void replace_reg ( )
static
Replace REG, which is a pointer to a stack reg RTX, with an RTX for
   the desired hard REGNO.   
static unsigned int rest_of_handle_stack_regs ( )
static
Convert register usage from flat register file usage to a stack
   register file.   

References reg_to_stack(), and regstack_completed.

int stack_regs_mentioned ( )
Return nonzero if INSN mentions stacked registers, else return zero.   

References stack_regs_mentioned_p().

Referenced by convert_regs_1(), emit_swap_insn(), old_insns_match_p(), and subst_stack_regs().

static int stack_regs_mentioned_p ( const_rtx  pat)
static
Forward declarations  

Referenced by stack_regs_mentioned(), stack_regs_mentioned_p(), and subst_stack_regs().

static int stack_regs_mentioned_p ( )
static
Return nonzero if any stack register is mentioned somewhere within PAT.   

References stack_regs_mentioned_p().

static rtx stack_result ( tree  )
static

Referenced by convert_regs_exit().

static rtx stack_result ( )
static
If current function returns its result in an fp stack register,
   return the REG.  Otherwise, return 0.   

References aggregate_value_p(), and targetm.

static void straighten_stack ( )
static
Reorganize the stack into ascending numbers, before this insn.   

References change_stack(), EMIT_BEFORE, stack_def::reg, stack_def::reg_set, and stack_def::top.

Referenced by subst_stack_regs().

static void subst_all_stack_regs_in_debug_insn ( )
static
Substitute hardware stack regs in debug insn INSN, using stack
   layout REGSTACK.  If we can't find a hardware stack reg for any of
   the REGs in it, reset the debug insn.   

References for_each_rtx(), and subst_stack_regs_in_debug_insn().

Referenced by convert_regs_1().

static void subst_asm_stack_regs ( rtx  ,
stack_ptr   
)
static

Referenced by subst_stack_regs().

static void subst_asm_stack_regs ( )
static
Substitute hard regnums for any stack regs in INSN, which has
   N_INPUTS inputs and N_OUTPUTS outputs.  REGSTACK is the stack info
   before the insn, and is updated with changes made here.

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

References change_stack(), check_asm_stack_operands(), constrain_operands(), EMIT_AFTER, EMIT_BEFORE, emit_pop_insn(), extract_insn(), get_asm_operands_in_out(), get_hard_regnum(), recog_data_d::n_operands, recog_data_d::operand, recog_data_d::operand_loc, operands_match_p(), preprocess_constraints(), recog_data, recog_op_alt, stack_def::reg, reg_class_subset_p(), stack_def::reg_set, replace_reg(), stack_def::top, and which_alternative.

static bool subst_stack_regs ( rtx  ,
stack_ptr   
)
static

Referenced by convert_regs_1().

static bool subst_stack_regs ( )
static
Substitute stack hard reg numbers for stack virtual registers in
   INSN.  Non-stack register numbers are not changed.  REGSTACK is the
   current stack content.  Insns may be emitted as needed to arrange the
   stack for the 387 based on the contents of the insn.  Return whether
   a control flow insn was deleted in the process.   

References asm_noperands(), EMIT_AFTER, emit_pop_insn(), find_reg_note(), n_operands, stack_def::reg_set, stack_regs_mentioned(), stack_regs_mentioned_p(), straighten_stack(), subst_asm_stack_regs(), subst_stack_regs_pat(), and stack_def::top.

static int subst_stack_regs_in_debug_insn ( )
static
Substitute new registers in LOC, which is part of a debug insn.
   REGSTACK is the current register layout.   

References get_hard_regnum(), and replace_reg().

Referenced by subst_all_stack_regs_in_debug_insn().

static bool subst_stack_regs_pat ( rtx  ,
stack_ptr  ,
rtx   
)
static

Referenced by subst_stack_regs().

static bool subst_stack_regs_pat ( )
static
static int swap_rtx_condition ( rtx  )
static
static int swap_rtx_condition_1 ( rtx  )
static
static int swap_rtx_condition_1 ( )
static
Swap the condition on a branch, if there is one.  Return true if we
   found a condition to swap.  False if the condition was not used as
   such.   

References swap_condition(), and swap_rtx_condition_1().

static void swap_to_top ( rtx  ,
stack_ptr  ,
rtx  ,
rtx   
)
static

Referenced by subst_stack_regs_pat().

static void swap_to_top ( )
static
Emit an insns before INSN to swap virtual register SRC1 with
   the top of stack and virtual register SRC2 with second stack
   slot. REGSTACK is the stack state before the swaps, and
   is updated to reflect the swaps.  A swap insn is represented as a
   PARALLEL of two patterns: each pattern moves one reg to the other.

   If SRC1 and/or SRC2 are already at the right place, no swap insn
   is emitted.   

References change_stack(), EMIT_BEFORE, get_hard_regnum(), stack_def::reg, and stack_def::top.


Variable Documentation

bool any_malformed_asm
static
Set if we find any malformed asms in a block.   

Referenced by check_asm_stack_operands(), convert_regs_1(), and emit_swap_insn().

basic_block current_block
static
The block we're currently working on.   

Referenced by find_control_dependence(), and prepend_lexical_block().

rtx FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE]
static
This is the register file for all register after conversion.   
rtx ix86_flags_rtx
static
rtx not_a_num
static
Used to initialize uninitialized registers.   

Referenced by change_stack(), convert_regs_1(), convert_regs_entry(), move_nan_for_stack_reg(), and reg_to_stack().

int regstack_completed = 0
Nonzero after end of regstack pass.
   Set to 1 or 0 by reg-stack.c.   

Referenced by df_ignore_stack_reg(), rest_of_clean_state(), and rest_of_handle_stack_regs().

vec<char> stack_regs_mentioned_data
static
Register to Stack convert for GNU compiler.
   Copyright (C) 1992-2013 Free Software Foundation, Inc.

   This file is part of GCC.

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

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

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.   
This pass converts stack-like registers from the "flat register
   file" model that gcc uses, to a stack convention that the 387 uses.

   * The form of the input:

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

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

   * The form of the output:

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

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

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

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

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

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

   * Methodology:

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

   * asm_operands:

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

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

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

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

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

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

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

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

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

      The asm above would be written as

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

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

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

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

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

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

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

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

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

        asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
We use this array to cache info about insns, because otherwise we
   spend too much time in stack_regs_mentioned_p.

   Indexed by insn UIDs.  A value of zero is uninitialized, one indicates
   the insn uses stack registers, two indicates the insn does not use
   stack registers.   
bool starting_stack_p
static
In the current_block, whether we're processing the first register
   stack or call instruction, i.e. the regstack is currently the
   same as BLOCK_INFO(current_block)->stack_in.   

Referenced by change_stack(), compensate_edges(), convert_regs_1(), and emit_swap_insn().