/* Expands front end tree to back end RTL for GNU C-Compiler
   Copyright (C) 1987, 88, 89, 92-6, 1997 Free Software Foundation, Inc.

This file is part of GNU CC.

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

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

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */


/* This file handles the generation of rtl code from tree structure
   above the level of expressions, using subroutines in exp*.c and emit-rtl.c.
   It also creates the rtl expressions for parameters and auto variables
   and has full responsibility for allocating stack slots.

   The functions whose names start with `expand_' are called by the
   parser to generate RTL instructions for various kinds of constructs.

   Some control and binding constructs require calling several such
   functions at different times.  For example, a simple if-then
   is expanded by calling `expand_start_cond' (with the condition-expression
   as argument) before parsing the then-clause and calling `expand_end_cond'
   after parsing the then-clause.  */

#include "config.h"

#include <stdio.h>
#include <ctype.h>

#include "rtl.h"
#include "tree.h"
#include "flags.h"
#include "except.h"
#include "function.h"
#include "insn-flags.h"
#include "insn-config.h"
#include "insn-codes.h"
#include "expr.h"
#include "hard-reg-set.h"
#include "obstack.h"
#include "loop.h"
#include "recog.h"
#include "machmode.h"

#include "bytecode.h"
#include "bc-typecd.h"
#include "bc-opcode.h"
#include "bc-optab.h"
#include "bc-emit.h"

#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
struct obstack stmt_obstack;

/* Filename and line number of last line-number note,
   whether we actually emitted it or not.  */
char *emit_filename;
int emit_lineno;

/* Nonzero if within a ({...}) grouping, in which case we must
   always compute a value for each expr-stmt in case it is the last one.  */

int expr_stmts_for_value;

/* Each time we expand an expression-statement,
   record the expr's type and its RTL value here.  */

static tree last_expr_type;
static rtx last_expr_value;

/* Each time we expand the end of a binding contour (in `expand_end_bindings')
   and we emit a new NOTE_INSN_BLOCK_END note, we save a pointer to it here.
   This is used by the `remember_end_note' function to record the endpoint
   of each generated block in its associated BLOCK node.  */

static rtx last_block_end_note;

/* Number of binding contours started so far in this function.  */

int block_start_count;

/* Nonzero if function being compiled needs to
   return the address of where it has put a structure value.  */

extern int current_function_returns_pcc_struct;

/* Label that will go on parm cleanup code, if any.
   Jumping to this label runs cleanup code for parameters, if
   such code must be run.  Following this code is the logical return label.  */

extern rtx cleanup_label;

/* Label that will go on function epilogue.
   Jumping to this label serves as a "return" instruction
   on machines which require execution of the epilogue on all returns.  */

extern rtx return_label;

/* Offset to end of allocated area of stack frame.
   If stack grows down, this is the address of the last stack slot allocated.
   If stack grows up, this is the address for the next slot.  */
extern int frame_offset;

/* Label to jump back to for tail recursion, or 0 if we have
   not yet needed one for this function.  */
extern rtx tail_recursion_label;

/* Place after which to insert the tail_recursion_label if we need one.  */
extern rtx tail_recursion_reentry;

/* Location at which to save the argument pointer if it will need to be
   referenced.  There are two cases where this is done: if nonlocal gotos
   exist, or if vars whose is an offset from the argument pointer will be
   needed by inner routines.  */

extern rtx arg_pointer_save_area;

/* Chain of all RTL_EXPRs that have insns in them.  */
extern tree rtl_expr_chain;

/* Stack allocation level in which temporaries for TARGET_EXPRs live.  */
extern int target_temp_slot_level;

extern int temp_slot_level;

/* Functions and data structures for expanding case statements.  */

/* Case label structure, used to hold info on labels within case
   statements.  We handle "range" labels; for a single-value label
   as in C, the high and low limits are the same.

   An AVL tree of case nodes is initially created, and later transformed
   to a list linked via the RIGHT fields in the nodes.  Nodes with
   higher case values are later in the list.

   Switch statements can be output in one of two forms.  A branch table
   is used if there are more than a few labels and the labels are dense
   within the range between the smallest and largest case value.  If a
   branch table is used, no further manipulations are done with the case
   node chain.

   The alternative to the use of a branch table is to generate a series
   of compare and jump insns.  When that is done, we use the LEFT, RIGHT,
   and PARENT fields to hold a binary tree.  Initially the tree is
   totally unbalanced, with everything on the right.  We balance the tree
   with nodes on the left having lower case values than the parent
   and nodes on the right having higher values.  We then output the tree
   in order.  */

struct case_node
{
  struct case_node	*left;	/* Left son in binary tree */
  struct case_node	*right;	/* Right son in binary tree; also node chain */
  struct case_node	*parent; /* Parent of node in binary tree */
  tree			low;	/* Lowest index value for this label */
  tree			high;	/* Highest index value for this label */
  tree			code_label; /* Label to jump to when node matches */
  int			balance;
};

typedef struct case_node case_node;
typedef struct case_node *case_node_ptr;

/* These are used by estimate_case_costs and balance_case_nodes.  */

/* This must be a signed type, and non-ANSI compilers lack signed char.  */
static short *cost_table;
static int use_cost_table;

/* Stack of control and binding constructs we are currently inside.

   These constructs begin when you call `expand_start_WHATEVER'
   and end when you call `expand_end_WHATEVER'.  This stack records
   info about how the construct began that tells the end-function
   what to do.  It also may provide information about the construct
   to alter the behavior of other constructs within the body.
   For example, they may affect the behavior of C `break' and `continue'.

   Each construct gets one `struct nesting' object.
   All of these objects are chained through the `all' field.
   `nesting_stack' points to the first object (innermost construct).
   The position of an entry on `nesting_stack' is in its `depth' field.

   Each type of construct has its own individual stack.
   For example, loops have `loop_stack'.  Each object points to the
   next object of the same type through the `next' field.

   Some constructs are visible to `break' exit-statements and others
   are not.  Which constructs are visible depends on the language.
   Therefore, the data structure allows each construct to be visible
   or not, according to the args given when the construct is started.
   The construct is visible if the `exit_label' field is non-null.
   In that case, the value should be a CODE_LABEL rtx.  */

struct nesting
{
  struct nesting *all;
  struct nesting *next;
  int depth;
  rtx exit_label;
  union
    {
      /* For conds (if-then and if-then-else statements).  */
      struct
	{
	  /* Label for the end of the if construct.
	     There is none if EXITFLAG was not set
	     and no `else' has been seen yet.  */
	  rtx endif_label;
	  /* Label for the end of this alternative.
	     This may be the end of the if or the next else/elseif.  */
	  rtx next_label;
	} cond;
      /* For loops.  */
      struct
	{
	  /* Label at the top of the loop; place to loop back to.  */
	  rtx start_label;
	  /* Label at the end of the whole construct.  */
	  rtx end_label;
	  /* Label before a jump that branches to the end of the whole
	     construct.  This is where destructors go if any.  */
	  rtx alt_end_label;
	  /* Label for `continue' statement to jump to;
	     this is in front of the stepper of the loop.  */
	  rtx continue_label;
	} loop;
      /* For variable binding contours.  */
      struct
	{
	  /* Sequence number of this binding contour within the function,
	     in order of entry.  */
	  int block_start_count;
	  /* Nonzero => value to restore stack to on exit.  Complemented by
	     bc_stack_level (see below) when generating bytecodes.  */
	  rtx stack_level;
	  /* The NOTE that starts this contour.
	     Used by expand_goto to check whether the destination
	     is within each contour or not.  */
	  rtx first_insn;
	  /* Innermost containing binding contour that has a stack level.  */
	  struct nesting *innermost_stack_block;
	  /* List of cleanups to be run on exit from this contour.
	     This is a list of expressions to be evaluated.
	     The TREE_PURPOSE of each link is the ..._DECL node
	     which the cleanup pertains to.  */
	  tree cleanups;
	  /* List of cleanup-lists of blocks containing this block,
	     as they were at the locus where this block appears.
	     There is an element for each containing block,
	     ordered innermost containing block first.
	     The tail of this list can be 0,
	     if all remaining elements would be empty lists.
	     The element's TREE_VALUE is the cleanup-list of that block,
	     which may be null.  */
	  tree outer_cleanups;
	  /* Chain of labels defined inside this binding contour.
	     For contours that have stack levels or cleanups.  */
	  struct label_chain *label_chain;
	  /* Number of function calls seen, as of start of this block.  */
	  int function_call_count;
	  /* Bytecode specific: stack level to restore stack to on exit.  */
	  int bc_stack_level;
	  /* Nonzero if this is associated with a EH region.  */
	  int exception_region;
	  /* The saved target_temp_slot_level from our outer block.
	     We may reset target_temp_slot_level to be the level of
	     this block, if that is done, target_temp_slot_level
	     reverts to the saved target_temp_slot_level at the very
	     end of the block.  */
	  int target_temp_slot_level;
	  /* True if we are currently emitting insns in an area of
	     output code that is controlled by a conditional
	     expression.  This is used by the cleanup handling code to
	     generate conditional cleanup actions.  */
	  int conditional_code;
	  /* A place to move the start of the exception region for any
	     of the conditional cleanups, must be at the end or after
	     the start of the last unconditional cleanup, and before any
	     conditional branch points.  */
	  rtx last_unconditional_cleanup;
	  /* When in a conditional context, this is the specific
	     cleanup list associated with last_unconditional_cleanup,
	     where we place the conditionalized cleanups.  */
	  tree *cleanup_ptr;
	} block;
      /* For switch (C) or case (Pascal) statements,
	 and also for dummies (see `expand_start_case_dummy').  */
      struct
	{
	  /* The insn after which the case dispatch should finally
	     be emitted.  Zero for a dummy.  */
	  rtx start;
	  /* For bytecodes, the case table is in-lined right in the code.
	     A label is needed for skipping over this block. It is only
	     used when generating bytecodes.  */
	  rtx skip_label;
	  /* A list of case labels; it is first built as an AVL tree.
	     During expand_end_case, this is converted to a list, and may be
	     rearranged into a nearly balanced binary tree.  */
	  struct case_node *case_list;
	  /* Label to jump to if no case matches.  */
	  tree default_label;
	  /* The expression to be dispatched on.  */
	  tree index_expr;
	  /* Type that INDEX_EXPR should be converted to.  */
	  tree nominal_type;
	  /* Number of range exprs in case statement.  */
	  int num_ranges;
	  /* Name of this kind of statement, for warnings.  */
	  char *printname;
	  /* Nonzero if a case label has been seen in this case stmt.  */
	  char seenlabel;
	} case_stmt;
    } data;
};

/* Chain of all pending binding contours.  */
struct nesting *block_stack;

/* If any new stacks are added here, add them to POPSTACKS too.  */

/* Chain of all pending binding contours that restore stack levels
   or have cleanups.  */
struct nesting *stack_block_stack;

/* Chain of all pending conditional statements.  */
struct nesting *cond_stack;

/* Chain of all pending loops.  */
struct nesting *loop_stack;

/* Chain of all pending case or switch statements.  */
struct nesting *case_stack;

/* Separate chain including all of the above,
   chained through the `all' field.  */
struct nesting *nesting_stack;

/* Number of entries on nesting_stack now.  */
int nesting_depth;

/* Allocate and return a new `struct nesting'.  */

#define ALLOC_NESTING() \
 (struct nesting *) obstack_alloc (&stmt_obstack, sizeof (struct nesting))

/* Pop the nesting stack element by element until we pop off
   the element which is at the top of STACK.
   Update all the other stacks, popping off elements from them
   as we pop them from nesting_stack.  */

#define POPSTACK(STACK)					\
do { struct nesting *target = STACK;			\
     struct nesting *this;				\
     do { this = nesting_stack;				\
	  if (loop_stack == this)			\
	    loop_stack = loop_stack->next;		\
	  if (cond_stack == this)			\
	    cond_stack = cond_stack->next;		\
	  if (block_stack == this)			\
	    block_stack = block_stack->next;		\
	  if (stack_block_stack == this)		\
	    stack_block_stack = stack_block_stack->next; \
	  if (case_stack == this)			\
	    case_stack = case_stack->next;		\
	  nesting_depth = nesting_stack->depth - 1;	\
	  nesting_stack = this->all;			\
	  obstack_free (&stmt_obstack, this); }		\
     while (this != target); } while (0)

/* In some cases it is impossible to generate code for a forward goto
   until the label definition is seen.  This happens when it may be necessary
   for the goto to reset the stack pointer: we don't yet know how to do that.
   So expand_goto puts an entry on this fixup list.
   Each time a binding contour that resets the stack is exited,
   we check each fixup.
   If the target label has now been defined, we can insert the proper code.  */

struct goto_fixup
{
  /* Points to following fixup.  */
  struct goto_fixup *next;
  /* Points to the insn before the jump insn.
     If more code must be inserted, it goes after this insn.  */
  rtx before_jump;
  /* The LABEL_DECL that this jump is jumping to, or 0
     for break, continue or return.  */
  tree target;
  /* The BLOCK for the place where this goto was found.  */
  tree context;
  /* The CODE_LABEL rtx that this is jumping to.  */
  rtx target_rtl;
  /* Number of binding contours started in current function
     before the label reference.  */
  int block_start_count;
  /* The outermost stack level that should be restored for this jump.
     Each time a binding contour that resets the stack is exited,
     if the target label is *not* yet defined, this slot is updated.  */
  rtx stack_level;
  /* List of lists of cleanup expressions to be run by this goto.
     There is one element for each block that this goto is within.
     The tail of this list can be 0,
     if all remaining elements would be empty.
     The TREE_VALUE contains the cleanup list of that block as of the
     time this goto was seen.
     The TREE_ADDRESSABLE flag is 1 for a block that has been exited.  */
  tree cleanup_list_list;

  /* Bytecode specific members follow */

  /* The label that this jump is jumping to, or 0 for break, continue
     or return.  */
  struct bc_label *bc_target;

  /* The label we use for the fixup patch */
  struct bc_label *label;

  /* True (non-0) if fixup has been handled */
  int bc_handled:1;

  /* Like stack_level above, except refers to the interpreter stack */
  int bc_stack_level;
};

static struct goto_fixup *goto_fixup_chain;

/* Within any binding contour that must restore a stack level,
   all labels are recorded with a chain of these structures.  */

struct label_chain
{
  /* Points to following fixup.  */
  struct label_chain *next;
  tree label;
};


/* Non-zero if we are using EH to handle cleanus.  */
static int using_eh_for_cleanups_p = 0;


static void expand_goto_internal	PROTO((tree, rtx, rtx));
static void bc_expand_goto_internal	PROTO((enum bytecode_opcode,
					       struct bc_label *, tree));
static int expand_fixup			PROTO((tree, rtx, rtx));
static void bc_expand_fixup		PROTO((enum bytecode_opcode,
					       struct bc_label *, int));
static void fixup_gotos			PROTO((struct nesting *, rtx, tree,
					       rtx, int));
static void bc_fixup_gotos		PROTO((struct nesting *, int, tree,
					       rtx, int));
static void bc_expand_start_cond	PROTO((tree, int));
static void bc_expand_end_cond		PROTO((void));
static void bc_expand_start_else	PROTO((void));
static void bc_expand_end_loop		PROTO((void));
static void bc_expand_end_bindings	PROTO((tree, int, int));
static void bc_expand_decl		PROTO((tree, tree));
static void bc_expand_variable_local_init PROTO((tree));
static void bc_expand_decl_init		PROTO((tree));
static void expand_null_return_1	PROTO((rtx, int));
static void expand_value_return		PROTO((rtx));
static int tail_recursion_args		PROTO((tree, tree));
static void expand_cleanups		PROTO((tree, tree, int, int));
static void bc_expand_start_case	PROTO((struct nesting *, tree,
					       tree, char *));
static int bc_pushcase			PROTO((tree, tree));
static void bc_check_for_full_enumeration_handling PROTO((tree));
static void bc_expand_end_case		PROTO((tree));
static void do_jump_if_equal		PROTO((rtx, rtx, rtx, int));
static int estimate_case_costs		PROTO((case_node_ptr));
static void group_case_nodes		PROTO((case_node_ptr));
static void balance_case_nodes		PROTO((case_node_ptr *,
					       case_node_ptr));
static int node_has_low_bound		PROTO((case_node_ptr, tree));
static int node_has_high_bound		PROTO((case_node_ptr, tree));
static int node_is_bounded		PROTO((case_node_ptr, tree));
static void emit_jump_if_reachable	PROTO((rtx));
static void emit_case_nodes		PROTO((rtx, case_node_ptr, rtx, tree));
static int add_case_node		PROTO((tree, tree, tree, tree *));
static struct case_node *case_tree2list	PROTO((case_node *, case_node *));

extern rtx bc_allocate_local ();
extern rtx bc_allocate_variable_array ();

void
using_eh_for_cleanups ()
{
  using_eh_for_cleanups_p = 1;
}

void
init_stmt ()
{
  gcc_obstack_init (&stmt_obstack);
  init_eh ();
}

void
init_stmt_for_function ()
{
  /* We are not currently within any block, conditional, loop or case.  */
  block_stack = 0;
  stack_block_stack = 0;
  loop_stack = 0;
  case_stack = 0;
  cond_stack = 0;
  nesting_stack = 0;
  nesting_depth = 0;

  block_start_count = 0;

  /* No gotos have been expanded yet.  */
  goto_fixup_chain = 0;

  /* We are not processing a ({...}) grouping.  */
  expr_stmts_for_value = 0;
  last_expr_type = 0;

  init_eh_for_function ();
}

void
save_stmt_status (p)
     struct function *p;
{
  p->block_stack = block_stack;
  p->stack_block_stack = stack_block_stack;
  p->cond_stack = cond_stack;
  p->loop_stack = loop_stack;
  p->case_stack = case_stack;
  p->nesting_stack = nesting_stack;
  p->nesting_depth = nesting_depth;
  p->block_start_count = block_start_count;
  p->last_expr_type = last_expr_type;
  p->last_expr_value = last_expr_value;
  p->expr_stmts_for_value = expr_stmts_for_value;
  p->emit_filename = emit_filename;
  p->emit_lineno = emit_lineno;
  p->goto_fixup_chain = goto_fixup_chain;
  save_eh_status (p);
}

void
restore_stmt_status (p)
     struct function *p;
{
  block_stack = p->block_stack;
  stack_block_stack = p->stack_block_stack;
  cond_stack = p->cond_stack;
  loop_stack = p->loop_stack;
  case_stack = p->case_stack;
  nesting_stack = p->nesting_stack;
  nesting_depth = p->nesting_depth;
  block_start_count = p->block_start_count;
  last_expr_type = p->last_expr_type;
  last_expr_value = p->last_expr_value;
  expr_stmts_for_value = p->expr_stmts_for_value;
  emit_filename = p->emit_filename;
  emit_lineno = p->emit_lineno;
  goto_fixup_chain = p->goto_fixup_chain;
  restore_eh_status (p);
}

/* Emit a no-op instruction.  */

void
emit_nop ()
{
  rtx last_insn;

  if (!output_bytecode)
    {
      last_insn = get_last_insn ();
      if (!optimize
	  && (GET_CODE (last_insn) == CODE_LABEL
	      || (GET_CODE (last_insn) == NOTE
		  && prev_real_insn (last_insn) == 0)))
	emit_insn (gen_nop ());
    }
}

/* Return the rtx-label that corresponds to a LABEL_DECL,
   creating it if necessary.  */

rtx
label_rtx (label)
     tree label;
{
  if (TREE_CODE (label) != LABEL_DECL)
    abort ();

  if (DECL_RTL (label))
    return DECL_RTL (label);

  return DECL_RTL (label) = gen_label_rtx ();
}

/* Add an unconditional jump to LABEL as the next sequential instruction.  */

void
emit_jump (label)
     rtx label;
{
  do_pending_stack_adjust ();
  emit_jump_insn (gen_jump (label));
  emit_barrier ();
}

/* Emit code to jump to the address
   specified by the pointer expression EXP.  */

void
expand_computed_goto (exp)
     tree exp;
{
  if (output_bytecode)
    {
      bc_expand_expr (exp);
      bc_emit_instruction (jumpP);
    }
  else
    {
      rtx x = expand_expr (exp, NULL_RTX, VOIDmode, 0);

#ifdef POINTERS_EXTEND_UNSIGNED
      x = convert_memory_address (Pmode, x);
#endif

      emit_queue ();
      /* Be sure the function is executable.  */
      if (flag_check_memory_usage)
	emit_library_call (chkr_check_exec_libfunc, 1,
			   VOIDmode, 1, x, ptr_mode);

      do_pending_stack_adjust ();
      emit_indirect_jump (x);
    }
}

/* Handle goto statements and the labels that they can go to.  */

/* Specify the location in the RTL code of a label LABEL,
   which is a LABEL_DECL tree node.

   This is used for the kind of label that the user can jump to with a
   goto statement, and for alternatives of a switch or case statement.
   RTL labels generated for loops and conditionals don't go through here;
   they are generated directly at the RTL level, by other functions below.

   Note that this has nothing to do with defining label *names*.
   Languages vary in how they do that and what that even means.  */

void
expand_label (label)
     tree label;
{
  struct label_chain *p;

  if (output_bytecode)
    {
      if (! DECL_RTL (label))
	DECL_RTL (label) = bc_gen_rtx ((char *) 0, 0, bc_get_bytecode_label ());
      if (! bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (DECL_RTL (label))))
	error ("multiply defined label");
      return;
    }

  do_pending_stack_adjust ();
  emit_label (label_rtx (label));
  if (DECL_NAME (label))
    LABEL_NAME (DECL_RTL (label)) = IDENTIFIER_POINTER (DECL_NAME (label));

  if (stack_block_stack != 0)
    {
      p = (struct label_chain *) oballoc (sizeof (struct label_chain));
      p->next = stack_block_stack->data.block.label_chain;
      stack_block_stack->data.block.label_chain = p;
      p->label = label;
    }
}

/* Declare that LABEL (a LABEL_DECL) may be used for nonlocal gotos
   from nested functions.  */

void
declare_nonlocal_label (label)
     tree label;
{
  nonlocal_labels = tree_cons (NULL_TREE, label, nonlocal_labels);
  LABEL_PRESERVE_P (label_rtx (label)) = 1;
  if (nonlocal_goto_handler_slot == 0)
    {
      nonlocal_goto_handler_slot
	= assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
      emit_stack_save (SAVE_NONLOCAL,
		       &nonlocal_goto_stack_level,
		       PREV_INSN (tail_recursion_reentry));
    }
}

/* Generate RTL code for a `goto' statement with target label LABEL.
   LABEL should be a LABEL_DECL tree node that was or will later be
   defined with `expand_label'.  */

void
expand_goto (label)
     tree label;
{
  tree context;

  if (output_bytecode)
    {
      expand_goto_internal (label, label_rtx (label), NULL_RTX);
      return;
    }

  /* Check for a nonlocal goto to a containing function.  */
  context = decl_function_context (label);
  if (context != 0 && context != current_function_decl)
    {
      struct function *p = find_function_data (context);
      rtx label_ref = gen_rtx (LABEL_REF, Pmode, label_rtx (label));
      rtx temp;

      p->has_nonlocal_label = 1;
      current_function_has_nonlocal_goto = 1;
      LABEL_REF_NONLOCAL_P (label_ref) = 1;

      /* Copy the rtl for the slots so that they won't be shared in
	 case the virtual stack vars register gets instantiated differently
	 in the parent than in the child.  */

#if HAVE_nonlocal_goto
      if (HAVE_nonlocal_goto)
	emit_insn (gen_nonlocal_goto (lookup_static_chain (label),
				      copy_rtx (p->nonlocal_goto_handler_slot),
				      copy_rtx (p->nonlocal_goto_stack_level),
				      label_ref));
      else
#endif
	{
	  rtx addr;

	  /* Restore frame pointer for containing function.
	     This sets the actual hard register used for the frame pointer
	     to the location of the function's incoming static chain info.
	     The non-local goto handler will then adjust it to contain the
	     proper value and reload the argument pointer, if needed.  */
	  emit_move_insn (hard_frame_pointer_rtx, lookup_static_chain (label));

	  /* We have now loaded the frame pointer hardware register with
	     the address of that corresponds to the start of the virtual
	     stack vars.  So replace virtual_stack_vars_rtx in all
	     addresses we use with stack_pointer_rtx.  */

	  /* Get addr of containing function's current nonlocal goto handler,
	     which will do any cleanups and then jump to the label.  */
	  addr = copy_rtx (p->nonlocal_goto_handler_slot);
	  temp = copy_to_reg (replace_rtx (addr, virtual_stack_vars_rtx,
					   hard_frame_pointer_rtx));
	  
	  /* Restore the stack pointer.  Note this uses fp just restored.  */
	  addr = p->nonlocal_goto_stack_level;
	  if (addr)
	    addr = replace_rtx (copy_rtx (addr),
				virtual_stack_vars_rtx,
				hard_frame_pointer_rtx);

	  emit_stack_restore (SAVE_NONLOCAL, addr, NULL_RTX);

	  /* Put in the static chain register the nonlocal label address.  */
	  emit_move_insn (static_chain_rtx, label_ref);
	  /* USE of hard_frame_pointer_rtx added for consistency; not clear if
	     really needed.  */
	  emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
	  emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
	  emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
	  emit_indirect_jump (temp);
	}
     }
  else
    expand_goto_internal (label, label_rtx (label), NULL_RTX);
}

/* Generate RTL code for a `goto' statement with target label BODY.
   LABEL should be a LABEL_REF.
   LAST_INSN, if non-0, is the rtx we should consider as the last
   insn emitted (for the purposes of cleaning up a return).  */

static void
expand_goto_internal (body, label, last_insn)
     tree body;
     rtx label;
     rtx last_insn;
{
  struct nesting *block;
  rtx stack_level = 0;

  /* NOTICE!  If a bytecode instruction other than `jump' is needed,
     then the caller has to call bc_expand_goto_internal()
     directly. This is rather an exceptional case, and there aren't
     that many places where this is necessary.  */
  if (output_bytecode)
    {
      expand_goto_internal (body, label, last_insn);
      return;
    }

  if (GET_CODE (label) != CODE_LABEL)
    abort ();

  /* If label has already been defined, we can tell now
     whether and how we must alter the stack level.  */

  if (PREV_INSN (label) != 0)
    {
      /* Find the innermost pending block that contains the label.
	 (Check containment by comparing insn-uids.)
	 Then restore the outermost stack level within that block,
	 and do cleanups of all blocks contained in it.  */
      for (block = block_stack; block; block = block->next)
	{
	  if (INSN_UID (block->data.block.first_insn) < INSN_UID (label))
	    break;
	  if (block->data.block.stack_level != 0)
	    stack_level = block->data.block.stack_level;
	  /* Execute the cleanups for blocks we are exiting.  */
	  if (block->data.block.cleanups != 0)
	    {
	      expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
	      do_pending_stack_adjust ();
	    }
	}

      if (stack_level)
	{
	  /* Ensure stack adjust isn't done by emit_jump, as this
	     would clobber the stack pointer.  This one should be
	     deleted as dead by flow.  */
	  clear_pending_stack_adjust ();
	  do_pending_stack_adjust ();
	  emit_stack_restore (SAVE_BLOCK, stack_level, NULL_RTX);
	}

      if (body != 0 && DECL_TOO_LATE (body))
	error ("jump to `%s' invalidly jumps into binding contour",
	       IDENTIFIER_POINTER (DECL_NAME (body)));
    }
  /* Label not yet defined: may need to put this goto
     on the fixup list.  */
  else if (! expand_fixup (body, label, last_insn))
    {
      /* No fixup needed.  Record that the label is the target
	 of at least one goto that has no fixup.  */
      if (body != 0)
	TREE_ADDRESSABLE (body) = 1;
    }

  emit_jump (label);
}

/* Generate a jump with OPCODE to the given bytecode LABEL which is
   found within BODY.  */

static void
bc_expand_goto_internal (opcode, label, body)
     enum bytecode_opcode opcode;
     struct bc_label *label;
     tree body;
{
  struct nesting *block;
  int stack_level = -1;

  /* If the label is defined, adjust the stack as necessary.
     If it's not defined, we have to push the reference on the
     fixup list.  */

  if (label->defined)
    {

      /* Find the innermost pending block that contains the label.
	 (Check containment by comparing bytecode uids.)  Then restore the
	 outermost stack level within that block.  */

      for (block = block_stack; block; block = block->next)
	{
	  if (BYTECODE_BC_LABEL (block->data.block.first_insn)->uid < label->uid)
	    break;
	  if (block->data.block.bc_stack_level)
	    stack_level = block->data.block.bc_stack_level;

	  /* Execute the cleanups for blocks we are exiting.  */
	  if (block->data.block.cleanups != 0)
	    {
	      expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
	      do_pending_stack_adjust ();
	    }
	}

      /* Restore the stack level. If we need to adjust the stack, we
	 must do so after the jump, since the jump may depend on
	 what's on the stack.  Thus, any stack-modifying conditional
	 jumps (these are the only ones that rely on what's on the
	 stack) go into the fixup list.  */

      if (stack_level >= 0
	  && stack_depth != stack_level
	  && opcode != jump)

	bc_expand_fixup (opcode, label, stack_level);
      else
	{
	  if (stack_level >= 0)
	    bc_adjust_stack (stack_depth - stack_level);

	  if (body && DECL_BIT_FIELD (body))
	    error ("jump to `%s' invalidly jumps into binding contour",
		   IDENTIFIER_POINTER (DECL_NAME (body)));
	  
	  /* Emit immediate jump */
	  bc_emit_bytecode (opcode);
	  bc_emit_bytecode_labelref (label);
	  
#ifdef DEBUG_PRINT_CODE
	  fputc ('\n', stderr);
#endif
	}
    }
  else
    /* Put goto in the fixup list */
    bc_expand_fixup (opcode, label, stack_level);
}

/* Generate if necessary a fixup for a goto
   whose target label in tree structure (if any) is TREE_LABEL
   and whose target in rtl is RTL_LABEL.

   If LAST_INSN is nonzero, we pretend that the jump appears
   after insn LAST_INSN instead of at the current point in the insn stream.

   The fixup will be used later to insert insns just before the goto.
   Those insns will restore the stack level as appropriate for the
   target label, and will (in the case of C++) also invoke any object
   destructors which have to be invoked when we exit the scopes which
   are exited by the goto.

   Value is nonzero if a fixup is made.  */

static int
expand_fixup (tree_label, rtl_label, last_insn)
     tree tree_label;
     rtx rtl_label;
     rtx last_insn;
{
  struct nesting *block, *end_block;

  /* See if we can recognize which block the label will be output in.
     This is possible in some very common cases.
     If we succeed, set END_BLOCK to that block.
     Otherwise, set it to 0.  */

  if (cond_stack
      && (rtl_label == cond_stack->data.cond.endif_label
	  || rtl_label == cond_stack->data.cond.next_label))
    end_block = cond_stack;
  /* If we are in a loop, recognize certain labels which
     are likely targets.  This reduces the number of fixups
     we need to create.  */
  else if (loop_stack
      && (rtl_label == loop_stack->data.loop.start_label
	  || rtl_label == loop_stack->data.loop.end_label
	  || rtl_label == loop_stack->data.loop.continue_label))
    end_block = loop_stack;
  else
    end_block = 0;

  /* Now set END_BLOCK to the binding level to which we will return.  */

  if (end_block)
    {
      struct nesting *next_block = end_block->all;
      block = block_stack;

      /* First see if the END_BLOCK is inside the innermost binding level.
	 If so, then no cleanups or stack levels are relevant.  */
      while (next_block && next_block != block)
	next_block = next_block->all;

      if (next_block)
	return 0;

      /* Otherwise, set END_BLOCK to the innermost binding level
	 which is outside the relevant control-structure nesting.  */
      next_block = block_stack->next;
      for (block = block_stack; block != end_block; block = block->all)
	if (block == next_block)
	  next_block = next_block->next;
      end_block = next_block;
    }

  /* Does any containing block have a stack level or cleanups?
     If not, no fixup is needed, and that is the normal case
     (the only case, for standard C).  */
  for (block = block_stack; block != end_block; block = block->next)
    if (block->data.block.stack_level != 0
	|| block->data.block.cleanups != 0)
      break;

  if (block != end_block)
    {
      /* Ok, a fixup is needed.  Add a fixup to the list of such.  */
      struct goto_fixup *fixup
	= (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
      /* In case an old stack level is restored, make sure that comes
	 after any pending stack adjust.  */
      /* ?? If the fixup isn't to come at the present position,
	 doing the stack adjust here isn't useful.  Doing it with our
	 settings at that location isn't useful either.  Let's hope
	 someone does it!  */
      if (last_insn == 0)
	do_pending_stack_adjust ();
      fixup->target = tree_label;
      fixup->target_rtl = rtl_label;

      /* Create a BLOCK node and a corresponding matched set of
	 NOTE_INSN_BEGIN_BLOCK and NOTE_INSN_END_BLOCK notes at
	 this point.  The notes will encapsulate any and all fixup
	 code which we might later insert at this point in the insn
	 stream.  Also, the BLOCK node will be the parent (i.e. the
	 `SUPERBLOCK') of any other BLOCK nodes which we might create
	 later on when we are expanding the fixup code.  */

      {
        register rtx original_before_jump
          = last_insn ? last_insn : get_last_insn ();

        start_sequence ();
        pushlevel (0);
        fixup->before_jump = emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);
        last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
        fixup->context = poplevel (1, 0, 0);  /* Create the BLOCK node now! */
        end_sequence ();
        emit_insns_after (fixup->before_jump, original_before_jump);
      }

      fixup->block_start_count = block_start_count;
      fixup->stack_level = 0;
      fixup->cleanup_list_list
	= ((block->data.block.outer_cleanups
	    || block->data.block.cleanups)
	   ? tree_cons (NULL_TREE, block->data.block.cleanups,
			block->data.block.outer_cleanups)
	   : 0);
      fixup->next = goto_fixup_chain;
      goto_fixup_chain = fixup;
    }

  return block != 0;
}


/* Generate bytecode jump with OPCODE to a fixup routine that links to LABEL.
   Make the fixup restore the stack level to STACK_LEVEL.  */

static void
bc_expand_fixup (opcode, label, stack_level)
     enum bytecode_opcode opcode;
     struct bc_label *label;
     int stack_level;
{
  struct goto_fixup *fixup
    = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));

  fixup->label  = bc_get_bytecode_label ();
  fixup->bc_target = label;
  fixup->bc_stack_level = stack_level;
  fixup->bc_handled = FALSE;

  fixup->next = goto_fixup_chain;
  goto_fixup_chain = fixup;

  /* Insert a jump to the fixup code */
  bc_emit_bytecode (opcode);
  bc_emit_bytecode_labelref (fixup->label);

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif
}

/* Expand any needed fixups in the outputmost binding level of the
   function.  FIRST_INSN is the first insn in the function.  */

void
expand_fixups (first_insn)
     rtx first_insn;
{
  fixup_gotos (NULL_PTR, NULL_RTX, NULL_TREE, first_insn, 0);
}

/* When exiting a binding contour, process all pending gotos requiring fixups.
   THISBLOCK is the structure that describes the block being exited.
   STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
   CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
   FIRST_INSN is the insn that began this contour.

   Gotos that jump out of this contour must restore the
   stack level and do the cleanups before actually jumping.

   DONT_JUMP_IN nonzero means report error there is a jump into this
   contour from before the beginning of the contour.
   This is also done if STACK_LEVEL is nonzero.  */

static void
fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
     struct nesting *thisblock;
     rtx stack_level;
     tree cleanup_list;
     rtx first_insn;
     int dont_jump_in;
{
  register struct goto_fixup *f, *prev;

  if (output_bytecode)
    {
      /* ??? The second arg is the bc stack level, which is not the same
	 as STACK_LEVEL.  I have no idea what should go here, so I'll
	 just pass 0.  */
      bc_fixup_gotos (thisblock, 0, cleanup_list, first_insn, dont_jump_in);
      return;
    }

  /* F is the fixup we are considering; PREV is the previous one.  */
  /* We run this loop in two passes so that cleanups of exited blocks
     are run first, and blocks that are exited are marked so
     afterwards.  */

  for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
    {
      /* Test for a fixup that is inactive because it is already handled.  */
      if (f->before_jump == 0)
	{
	  /* Delete inactive fixup from the chain, if that is easy to do.  */
	  if (prev != 0)
	    prev->next = f->next;
	}
      /* Has this fixup's target label been defined?
	 If so, we can finalize it.  */
      else if (PREV_INSN (f->target_rtl) != 0)
	{
	  register rtx cleanup_insns;

	  /* Get the first non-label after the label
	     this goto jumps to.  If that's before this scope begins,
	     we don't have a jump into the scope.  */
	  rtx after_label = f->target_rtl;
	  while (after_label != 0 && GET_CODE (after_label) == CODE_LABEL)
	    after_label = NEXT_INSN (after_label);

	  /* If this fixup jumped into this contour from before the beginning
	     of this contour, report an error.  */
	  /* ??? Bug: this does not detect jumping in through intermediate
	     blocks that have stack levels or cleanups.
	     It detects only a problem with the innermost block
	     around the label.  */
	  if (f->target != 0
	      && (dont_jump_in || stack_level || cleanup_list)
	      /* If AFTER_LABEL is 0, it means the jump goes to the end
		 of the rtl, which means it jumps into this scope.  */
	      && (after_label == 0
		  || INSN_UID (first_insn) < INSN_UID (after_label))
	      && INSN_UID (first_insn) > INSN_UID (f->before_jump)
	      && ! DECL_ERROR_ISSUED (f->target))
	    {
	      error_with_decl (f->target,
			       "label `%s' used before containing binding contour");
	      /* Prevent multiple errors for one label.  */
	      DECL_ERROR_ISSUED (f->target) = 1;
	    }

	  /* We will expand the cleanups into a sequence of their own and
	     then later on we will attach this new sequence to the insn
	     stream just ahead of the actual jump insn.  */

	  start_sequence ();

	  /* Temporarily restore the lexical context where we will
	     logically be inserting the fixup code.  We do this for the
	     sake of getting the debugging information right.  */

	  pushlevel (0);
	  set_block (f->context);

	  /* Expand the cleanups for blocks this jump exits.  */
	  if (f->cleanup_list_list)
	    {
	      tree lists;
	      for (lists = f->cleanup_list_list; lists; lists = TREE_CHAIN (lists))
		/* Marked elements correspond to blocks that have been closed.
		   Do their cleanups.  */
		if (TREE_ADDRESSABLE (lists)
		    && TREE_VALUE (lists) != 0)
		  {
		    expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
		    /* Pop any pushes done in the cleanups,
		       in case function is about to return.  */
		    do_pending_stack_adjust ();
		  }
	    }

	  /* Restore stack level for the biggest contour that this
	     jump jumps out of.  */
	  if (f->stack_level)
	    emit_stack_restore (SAVE_BLOCK, f->stack_level, f->before_jump);

	  /* Finish up the sequence containing the insns which implement the
	     necessary cleanups, and then attach that whole sequence to the
	     insn stream just ahead of the actual jump insn.  Attaching it
	     at that point insures that any cleanups which are in fact
	     implicit C++ object destructions (which must be executed upon
	     leaving the block) appear (to the debugger) to be taking place
	     in an area of the generated code where the object(s) being
	     destructed are still "in scope".  */

	  cleanup_insns = get_insns ();
	  poplevel (1, 0, 0);

	  end_sequence ();
	  emit_insns_after (cleanup_insns, f->before_jump);


	  f->before_jump = 0;
	}
    }

  /* For any still-undefined labels, do the cleanups for this block now.
     We must do this now since items in the cleanup list may go out
     of scope when the block ends.  */
  for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
    if (f->before_jump != 0
	&& PREV_INSN (f->target_rtl) == 0
	/* Label has still not appeared.  If we are exiting a block with
	   a stack level to restore, that started before the fixup,
	   mark this stack level as needing restoration
	   when the fixup is later finalized.   */
	&& thisblock != 0
	/* Note: if THISBLOCK == 0 and we have a label that hasn't appeared, it
	   means the label is undefined.  That's erroneous, but possible.  */
	&& (thisblock->data.block.block_start_count
	    <= f->block_start_count))
      {
	tree lists = f->cleanup_list_list;
	rtx cleanup_insns;

	for (; lists; lists = TREE_CHAIN (lists))
	  /* If the following elt. corresponds to our containing block
	     then the elt. must be for this block.  */
	  if (TREE_CHAIN (lists) == thisblock->data.block.outer_cleanups)
	    {
	      start_sequence ();
	      pushlevel (0);
	      set_block (f->context);
	      expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
	      do_pending_stack_adjust ();
	      cleanup_insns = get_insns ();
	      poplevel (1, 0, 0);
	      end_sequence ();
	      if (cleanup_insns != 0)
		f->before_jump
		  = emit_insns_after (cleanup_insns, f->before_jump);

	      f->cleanup_list_list = TREE_CHAIN (lists);
	    }

	if (stack_level)
	  f->stack_level = stack_level;
      }
}


/* When exiting a binding contour, process all pending gotos requiring fixups.
   Note: STACK_DEPTH is not altered.

   The arguments are currently not used in the bytecode compiler, but we may
   need them one day for languages other than C.

   THISBLOCK is the structure that describes the block being exited.
   STACK_LEVEL is the rtx for the stack level to restore exiting this contour.
   CLEANUP_LIST is a list of expressions to evaluate on exiting this contour.
   FIRST_INSN is the insn that began this contour.

   Gotos that jump out of this contour must restore the
   stack level and do the cleanups before actually jumping.

   DONT_JUMP_IN nonzero means report error there is a jump into this
   contour from before the beginning of the contour.
   This is also done if STACK_LEVEL is nonzero.  */

static void
bc_fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
     struct nesting *thisblock;
     int stack_level;
     tree cleanup_list;
     rtx first_insn;
     int dont_jump_in;
{
  register struct goto_fixup *f, *prev;
  int saved_stack_depth;

  /* F is the fixup we are considering; PREV is the previous one.  */

  for (prev = 0, f = goto_fixup_chain; f; prev = f, f = f->next)
    {
      /* Test for a fixup that is inactive because it is already handled.  */
      if (f->before_jump == 0)
	{
	  /* Delete inactive fixup from the chain, if that is easy to do.  */
	  if (prev)
	    prev->next = f->next;
	}

      /* Emit code to restore the stack and continue */
      bc_emit_bytecode_labeldef (f->label);

      /* Save stack_depth across call, since bc_adjust_stack will alter
         the perceived stack depth via the instructions generated.  */

      if (f->bc_stack_level >= 0)
	{
	  saved_stack_depth = stack_depth;
	  bc_adjust_stack (stack_depth - f->bc_stack_level);
	  stack_depth = saved_stack_depth;
	}

      bc_emit_bytecode (jump);
      bc_emit_bytecode_labelref (f->bc_target);

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif
    }

  goto_fixup_chain = NULL;
}

/* Generate RTL for an asm statement (explicit assembler code).
   BODY is a STRING_CST node containing the assembler code text,
   or an ADDR_EXPR containing a STRING_CST.  */

void
expand_asm (body)
     tree body;
{
  if (output_bytecode)
    {
      error ("`asm' is invalid when generating bytecode");
      return;
    }

  if (flag_check_memory_usage)
    {
      error ("`asm' cannot be used with `-fcheck-memory-usage'");
      return;
    }

  if (TREE_CODE (body) == ADDR_EXPR)
    body = TREE_OPERAND (body, 0);

  emit_insn (gen_rtx (ASM_INPUT, VOIDmode,
		      TREE_STRING_POINTER (body)));
  last_expr_type = 0;
}

/* Generate RTL for an asm statement with arguments.
   STRING is the instruction template.
   OUTPUTS is a list of output arguments (lvalues); INPUTS a list of inputs.
   Each output or input has an expression in the TREE_VALUE and
   a constraint-string in the TREE_PURPOSE.
   CLOBBERS is a list of STRING_CST nodes each naming a hard register
   that is clobbered by this insn.

   Not all kinds of lvalue that may appear in OUTPUTS can be stored directly.
   Some elements of OUTPUTS may be replaced with trees representing temporary
   values.  The caller should copy those temporary values to the originally
   specified lvalues.

   VOL nonzero means the insn is volatile; don't optimize it.  */

void
expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
     tree string, outputs, inputs, clobbers;
     int vol;
     char *filename;
     int line;
{
  rtvec argvec, constraints;
  rtx body;
  int ninputs = list_length (inputs);
  int noutputs = list_length (outputs);
  int ninout = 0;
  int nclobbers;
  tree tail;
  register int i;
  /* Vector of RTX's of evaluated output operands.  */
  rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
  int *inout_opnum = (int *) alloca (noutputs * sizeof (int));
  enum machine_mode *inout_mode
    = (enum machine_mode *) alloca (noutputs * sizeof (enum machine_mode));
  /* The insn we have emitted.  */
  rtx insn;

  /* An ASM with no outputs needs to be treated as volatile.  */
  if (noutputs == 0)
    vol = 1;

  if (output_bytecode)
    {
      error ("`asm' is invalid when generating bytecode");
      return;
    }

  if (flag_check_memory_usage)
    {
      error ("`asm' cannot be used with `-fcheck-memory-usage'");
      return;
    }

  /* Count the number of meaningful clobbered registers, ignoring what
     we would ignore later.  */
  nclobbers = 0;
  for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
    {
      char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
      i = decode_reg_name (regname);
      if (i >= 0 || i == -4)
	++nclobbers;
      else if (i == -2)
	error ("unknown register name `%s' in `asm'", regname);
    }

  last_expr_type = 0;

  for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
    {
      tree val = TREE_VALUE (tail);
      tree type = TREE_TYPE (val);
      tree val1;
      int j;
      int found_equal = 0;
      int found_plus = 0;
      int allows_reg = 0;

      /* If there's an erroneous arg, emit no insn.  */
      if (TREE_TYPE (val) == error_mark_node)
	return;

      /* Make sure constraint has `=' and does not have `+'.  Also, see
	 if it allows any register.  Be liberal on the latter test, since
	 the worst that happens if we get it wrong is we issue an error
	 message.  */

      for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
	switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
	  {
	  case '+':
	    /* Make sure we can specify the matching operand.  */
	    if (i > 9)
	      {
		error ("output operand constraint %d contains `+'", i);
		return;
	      }

	    /* Replace '+' with '='.  */
	    TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] = '=';
	    found_plus = 1;
	    break;

	  case '=':
	    found_equal = 1;
	    break;

	  case '?':  case '!':  case '*':  case '%':  case '&':
	  case 'V':  case 'm':  case 'o':  case '<':  case '>':
	  case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
	  case 's':  case 'i':  case 'n':
	  case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
	  case 'N':  case 'O':  case 'P':  case ',':
#ifdef EXTRA_CONSTRAINT
	  case 'Q':  case 'R':  case 'S':  case 'T':  case 'U':
#endif
	    break;

	  case '0':  case '1':  case '2':  case '3':  case '4':
	  case '5':  case '6':  case '7':  case '8':  case '9':
	    error ("matching constraint not valid in output operand");
	    break;

	  case 'p':  case 'g':  case 'r':
	  default:
	    allows_reg = 1;
	    break;
	  }

      if (! found_equal && ! found_plus)
	{
	  error ("output operand constraint lacks `='");
	  return;
	}

      /* If an output operand is not a decl or indirect ref and our constraint
	 allows a register, make a temporary to act as an intermediate.
	 Make the asm insn write into that, then our caller will copy it to
	 the real output operand.  Likewise for promoted variables.  */

      if (TREE_CODE (val) == INDIRECT_REF
	  || (TREE_CODE_CLASS (TREE_CODE (val)) == 'd'
	      && ! (GET_CODE (DECL_RTL (val)) == REG
		    && GET_MODE (DECL_RTL (val)) != TYPE_MODE (type)))
	  || ! allows_reg
	  || found_plus)
	{
	  if (! allows_reg)
	    mark_addressable (TREE_VALUE (tail));

	  output_rtx[i]
	    = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode,
			   EXPAND_MEMORY_USE_WO);

	  if (! allows_reg && GET_CODE (output_rtx[i]) != MEM)
	    error ("output number %d not directly addressable", i);
	}
      else
	{
	  output_rtx[i] = assign_temp (type, 0, 0, 0);
	  TREE_VALUE (tail) = make_tree (type, output_rtx[i]);
	}

      if (found_plus)
	{
	  inout_mode[ninout] = TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)));
	  inout_opnum[ninout++] = i;
	}
    }

  ninputs += ninout;
  if (ninputs + noutputs > MAX_RECOG_OPERANDS)
    {
      error ("more than %d operands in `asm'", MAX_RECOG_OPERANDS);
      return;
    }

  /* Make vectors for the expression-rtx and constraint strings.  */

  argvec = rtvec_alloc (ninputs);
  constraints = rtvec_alloc (ninputs);

  body = gen_rtx (ASM_OPERANDS, VOIDmode,
		  TREE_STRING_POINTER (string), "", 0, argvec, constraints,
		  filename, line);
  MEM_VOLATILE_P (body) = vol;

  /* Eval the inputs and put them into ARGVEC.
     Put their constraints into ASM_INPUTs and store in CONSTRAINTS.  */

  i = 0;
  for (tail = inputs; tail; tail = TREE_CHAIN (tail))
    {
      int j;
      int allows_reg = 0;

      /* If there's an erroneous arg, emit no insn,
	 because the ASM_INPUT would get VOIDmode
	 and that could cause a crash in reload.  */
      if (TREE_TYPE (TREE_VALUE (tail)) == error_mark_node)
	return;
      if (TREE_PURPOSE (tail) == NULL_TREE)
	{
	  error ("hard register `%s' listed as input operand to `asm'",
		 TREE_STRING_POINTER (TREE_VALUE (tail)) );
	  return;
	}

      /* Make sure constraint has neither `=' nor `+'.  */

      for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
	switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
	  {
	  case '+':   case '=':
	    error ("input operand constraint contains `%c'",
		   TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
	    return;

	  case '?':  case '!':  case '*':  case '%':  case '&':
	  case 'V':  case 'm':  case 'o':  case '<':  case '>':
	  case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
	  case 's':  case 'i':  case 'n':
	  case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
	  case 'N':  case 'O':  case 'P':  case ',':
#ifdef EXTRA_CONSTRAINT
	  case 'Q':  case 'R':  case 'S':  case 'T':  case 'U':
#endif
	    break;

	    /* Whether or not a numeric constraint allows a register is
	       decided by the matching constraint, and so there is no need
	       to do anything special with them.  We must handle them in
	       the default case, so that we don't unnecessarily force
	       operands to memory.  */
	  case '0':  case '1':  case '2':  case '3':  case '4':
	  case '5':  case '6':  case '7':  case '8':  case '9':
	    if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]
		>= '0' + noutputs)
	      error ("matching constraint references invalid operand number");

	    /* ... fall through ... */

	  case 'p':  case 'g':  case 'r':
	  default:
	    allows_reg = 1;
	    break;
	  }

      if (! allows_reg)
	mark_addressable (TREE_VALUE (tail));

      XVECEXP (body, 3, i)      /* argvec */
	= expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
      if (CONSTANT_P (XVECEXP (body, 3, i))
	  && ! general_operand (XVECEXP (body, 3, i),
				TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
	{
	  if (allows_reg)
	    XVECEXP (body, 3, i)
	      = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
			   XVECEXP (body, 3, i));
	  else
	    XVECEXP (body, 3, i)
	      = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
				 XVECEXP (body, 3, i));
	}

      if (! allows_reg
	  && (GET_CODE (XVECEXP (body, 3, i)) == REG
	      || GET_CODE (XVECEXP (body, 3, i)) == SUBREG
	      || GET_CODE (XVECEXP (body, 3, i)) == CONCAT))
	{
	  tree type = TREE_TYPE (TREE_VALUE (tail));
	  rtx memloc = assign_temp (type, 1, 1, 1);

	  emit_move_insn (memloc, XVECEXP (body, 3, i));
	  XVECEXP (body, 3, i) = memloc;
	}
	  
      XVECEXP (body, 4, i)      /* constraints */
	= gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
		   TREE_STRING_POINTER (TREE_PURPOSE (tail)));
      i++;
    }

  /* Protect all the operands from the queue,
     now that they have all been evaluated.  */

  for (i = 0; i < ninputs - ninout; i++)
    XVECEXP (body, 3, i) = protect_from_queue (XVECEXP (body, 3, i), 0);

  for (i = 0; i < noutputs; i++)
    output_rtx[i] = protect_from_queue (output_rtx[i], 1);

  /* For in-out operands, copy output rtx to input rtx. */
  for (i = 0; i < ninout; i++)
    {
      static char match[9+1][2]
	= {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
      int j = inout_opnum[i];

      XVECEXP (body, 3, ninputs - ninout + i)      /* argvec */
	= output_rtx[j];
      XVECEXP (body, 4, ninputs - ninout + i)      /* constraints */
	= gen_rtx (ASM_INPUT, inout_mode[j], match[j]);
    }

  /* Now, for each output, construct an rtx
     (set OUTPUT (asm_operands INSN OUTPUTNUMBER OUTPUTCONSTRAINT
			       ARGVEC CONSTRAINTS))
     If there is more than one, put them inside a PARALLEL.  */

  if (noutputs == 1 && nclobbers == 0)
    {
      XSTR (body, 1) = TREE_STRING_POINTER (TREE_PURPOSE (outputs));
      insn = emit_insn (gen_rtx (SET, VOIDmode, output_rtx[0], body));
    }
  else if (noutputs == 0 && nclobbers == 0)
    {
      /* No output operands: put in a raw ASM_OPERANDS rtx.  */
      insn = emit_insn (body);
    }
  else
    {
      rtx obody = body;
      int num = noutputs;
      if (num == 0) num = 1;
      body = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (num + nclobbers));

      /* For each output operand, store a SET.  */

      for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
	{
	  XVECEXP (body, 0, i)
	    = gen_rtx (SET, VOIDmode,
		       output_rtx[i],
		       gen_rtx (ASM_OPERANDS, VOIDmode,
				TREE_STRING_POINTER (string),
				TREE_STRING_POINTER (TREE_PURPOSE (tail)),
				i, argvec, constraints,
				filename, line));
	  MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
	}

      /* If there are no outputs (but there are some clobbers)
	 store the bare ASM_OPERANDS into the PARALLEL.  */

      if (i == 0)
	XVECEXP (body, 0, i++) = obody;

      /* Store (clobber REG) for each clobbered register specified.  */

      for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
	{
	  char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
	  int j = decode_reg_name (regname);

	  if (j < 0)
	    {
	      if (j == -3)	/* `cc', which is not a register */
		continue;

	      if (j == -4)	/* `memory', don't cache memory across asm */
		{
		  XVECEXP (body, 0, i++)
		    = gen_rtx (CLOBBER, VOIDmode,
			       gen_rtx (MEM, BLKmode,
					gen_rtx (SCRATCH, VOIDmode, 0)));
		  continue;
		}

	      /* Ignore unknown register, error already signalled.  */
	      continue;
	    }

	  /* Use QImode since that's guaranteed to clobber just one reg.  */
	  XVECEXP (body, 0, i++)
	    = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, QImode, j));
	}

      insn = emit_insn (body);
    }

  free_temp_slots ();
}

/* Generate RTL to evaluate the expression EXP
   and remember it in case this is the VALUE in a ({... VALUE; }) constr.  */

void
expand_expr_stmt (exp)
     tree exp;
{
  if (output_bytecode)
    {
      int org_stack_depth = stack_depth;

      bc_expand_expr (exp);

      /* Restore stack depth */
      if (stack_depth < org_stack_depth)
	abort ();
      
      bc_emit_instruction (drop);

      last_expr_type = TREE_TYPE (exp);
      return;
    }

  /* If -W, warn about statements with no side effects,
     except for an explicit cast to void (e.g. for assert()), and
     except inside a ({...}) where they may be useful.  */
  if (expr_stmts_for_value == 0 && exp != error_mark_node)
    {
      if (! TREE_SIDE_EFFECTS (exp) && (extra_warnings || warn_unused)
	  && !(TREE_CODE (exp) == CONVERT_EXPR
	       && TREE_TYPE (exp) == void_type_node))
	warning_with_file_and_line (emit_filename, emit_lineno,
				    "statement with no effect");
      else if (warn_unused)
	warn_if_unused_value (exp);
    }

  /* If EXP is of function type and we are expanding statements for
     value, convert it to pointer-to-function.  */
  if (expr_stmts_for_value && TREE_CODE (TREE_TYPE (exp)) == FUNCTION_TYPE)
    exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);

  last_expr_type = TREE_TYPE (exp);
  if (! flag_syntax_only)
    last_expr_value = expand_expr (exp,
				   (expr_stmts_for_value
				    ? NULL_RTX : const0_rtx),
				   VOIDmode, 0);

  /* If all we do is reference a volatile value in memory,
     copy it to a register to be sure it is actually touched.  */
  if (last_expr_value != 0 && GET_CODE (last_expr_value) == MEM
      && TREE_THIS_VOLATILE (exp))
    {
      if (TYPE_MODE (TREE_TYPE (exp)) == VOIDmode)
	;
      else if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
	copy_to_reg (last_expr_value);
      else
	{
	  rtx lab = gen_label_rtx ();
	  
	  /* Compare the value with itself to reference it.  */
	  emit_cmp_insn (last_expr_value, last_expr_value, EQ,
			 expand_expr (TYPE_SIZE (last_expr_type),
				      NULL_RTX, VOIDmode, 0),
			 BLKmode, 0,
			 TYPE_ALIGN (last_expr_type) / BITS_PER_UNIT);
	  emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (lab));
	  emit_label (lab);
	}
    }

  /* If this expression is part of a ({...}) and is in memory, we may have
     to preserve temporaries.  */
  preserve_temp_slots (last_expr_value);

  /* Free any temporaries used to evaluate this expression.  Any temporary
     used as a result of this expression will already have been preserved
     above.  */
  free_temp_slots ();

  emit_queue ();
}

/* Warn if EXP contains any computations whose results are not used.
   Return 1 if a warning is printed; 0 otherwise.  */

int
warn_if_unused_value (exp)
     tree exp;
{
  if (TREE_USED (exp))
    return 0;

  switch (TREE_CODE (exp))
    {
    case PREINCREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTDECREMENT_EXPR:
    case MODIFY_EXPR:
    case INIT_EXPR:
    case TARGET_EXPR:
    case CALL_EXPR:
    case METHOD_CALL_EXPR:
    case RTL_EXPR:
    case TRY_CATCH_EXPR:
    case WITH_CLEANUP_EXPR:
    case EXIT_EXPR:
      /* We don't warn about COND_EXPR because it may be a useful
	 construct if either arm contains a side effect.  */
    case COND_EXPR:
      return 0;

    case BIND_EXPR:
      /* For a binding, warn if no side effect within it.  */
      return warn_if_unused_value (TREE_OPERAND (exp, 1));

    case SAVE_EXPR:
      return warn_if_unused_value (TREE_OPERAND (exp, 1));

    case TRUTH_ORIF_EXPR:
    case TRUTH_ANDIF_EXPR:
      /* In && or ||, warn if 2nd operand has no side effect.  */
      return warn_if_unused_value (TREE_OPERAND (exp, 1));

    case COMPOUND_EXPR:
      if (TREE_NO_UNUSED_WARNING (exp))
	return 0;
      if (warn_if_unused_value (TREE_OPERAND (exp, 0)))
	return 1;
      /* Let people do `(foo (), 0)' without a warning.  */
      if (TREE_CONSTANT (TREE_OPERAND (exp, 1)))
	return 0;
      return warn_if_unused_value (TREE_OPERAND (exp, 1));

    case NOP_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      /* Don't warn about values cast to void.  */
      if (TREE_TYPE (exp) == void_type_node)
	return 0;
      /* Don't warn about conversions not explicit in the user's program.  */
      if (TREE_NO_UNUSED_WARNING (exp))
	return 0;
      /* Assignment to a cast usually results in a cast of a modify.
	 Don't complain about that.  There can be an arbitrary number of
	 casts before the modify, so we must loop until we find the first
	 non-cast expression and then test to see if that is a modify.  */
      {
	tree tem = TREE_OPERAND (exp, 0);

	while (TREE_CODE (tem) == CONVERT_EXPR || TREE_CODE (tem) == NOP_EXPR)
	  tem = TREE_OPERAND (tem, 0);

	if (TREE_CODE (tem) == MODIFY_EXPR || TREE_CODE (tem) == INIT_EXPR
	    || TREE_CODE (tem) == CALL_EXPR)
	  return 0;
      }
      goto warn;

    case INDIRECT_REF:
      /* Don't warn about automatic dereferencing of references, since
	 the user cannot control it.  */
      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
	return warn_if_unused_value (TREE_OPERAND (exp, 0));
      /* ... fall through ...  */
      
    default:
      /* Referencing a volatile value is a side effect, so don't warn.  */
      if ((TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
	   || TREE_CODE_CLASS (TREE_CODE (exp)) == 'r')
	  && TREE_THIS_VOLATILE (exp))
	return 0;
    warn:
      warning_with_file_and_line (emit_filename, emit_lineno,
				  "value computed is not used");
      return 1;
    }
}

/* Clear out the memory of the last expression evaluated.  */

void
clear_last_expr ()
{
  last_expr_type = 0;
}

/* Begin a statement which will return a value.
   Return the RTL_EXPR for this statement expr.
   The caller must save that value and pass it to expand_end_stmt_expr.  */

tree
expand_start_stmt_expr ()
{
  int momentary;
  tree t;

  /* When generating bytecode just note down the stack depth */
  if (output_bytecode)
    return (build_int_2 (stack_depth, 0));

  /* Make the RTL_EXPR node temporary, not momentary,
     so that rtl_expr_chain doesn't become garbage.  */
  momentary = suspend_momentary ();
  t = make_node (RTL_EXPR);
  resume_momentary (momentary);
  do_pending_stack_adjust ();
  start_sequence_for_rtl_expr (t);
  NO_DEFER_POP;
  expr_stmts_for_value++;
  return t;
}

/* Restore the previous state at the end of a statement that returns a value.
   Returns a tree node representing the statement's value and the
   insns to compute the value.

   The nodes of that expression have been freed by now, so we cannot use them.
   But we don't want to do that anyway; the expression has already been
   evaluated and now we just want to use the value.  So generate a RTL_EXPR
   with the proper type and RTL value.

   If the last substatement was not an expression,
   return something with type `void'.  */

tree
expand_end_stmt_expr (t)
     tree t;
{
  if (output_bytecode)
    {
      int i;
      tree t;
      
      
      /* At this point, all expressions have been evaluated in order.
	 However, all expression values have been popped when evaluated,
	 which means we have to recover the last expression value.  This is
	 the last value removed by means of a `drop' instruction.  Instead
	 of adding code to inhibit dropping the last expression value, it
	 is here recovered by undoing the `drop'.  Since `drop' is
	 equivalent to `adjustackSI [1]', it can be undone with `adjstackSI
	 [-1]'.  */
      
      bc_adjust_stack (-1);
      
      if (!last_expr_type)
	last_expr_type = void_type_node;
      
      t = make_node (RTL_EXPR);
      TREE_TYPE (t) = last_expr_type;
      RTL_EXPR_RTL (t) = NULL;
      RTL_EXPR_SEQUENCE (t) = NULL;
      
      /* Don't consider deleting this expr or containing exprs at tree level.  */
      TREE_THIS_VOLATILE (t) = 1;
      
      last_expr_type = 0;
      return t;
    }

  OK_DEFER_POP;

  if (last_expr_type == 0)
    {
      last_expr_type = void_type_node;
      last_expr_value = const0_rtx;
    }
  else if (last_expr_value == 0)
    /* There are some cases where this can happen, such as when the
       statement is void type.  */
    last_expr_value = const0_rtx;
  else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
    /* Remove any possible QUEUED.  */
    last_expr_value = protect_from_queue (last_expr_value, 0);

  emit_queue ();

  TREE_TYPE (t) = last_expr_type;
  RTL_EXPR_RTL (t) = last_expr_value;
  RTL_EXPR_SEQUENCE (t) = get_insns ();

  rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);

  end_sequence ();

  /* Don't consider deleting this expr or containing exprs at tree level.  */
  TREE_SIDE_EFFECTS (t) = 1;
  /* Propagate volatility of the actual RTL expr.  */
  TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);

  last_expr_type = 0;
  expr_stmts_for_value--;

  return t;
}

/* Generate RTL for the start of an if-then.  COND is the expression
   whose truth should be tested.

   If EXITFLAG is nonzero, this conditional is visible to
   `exit_something'.  */

void
expand_start_cond (cond, exitflag)
     tree cond;
     int exitflag;
{
  struct nesting *thiscond = ALLOC_NESTING ();

  /* Make an entry on cond_stack for the cond we are entering.  */

  thiscond->next = cond_stack;
  thiscond->all = nesting_stack;
  thiscond->depth = ++nesting_depth;
  thiscond->data.cond.next_label = gen_label_rtx ();
  /* Before we encounter an `else', we don't need a separate exit label
     unless there are supposed to be exit statements
     to exit this conditional.  */
  thiscond->exit_label = exitflag ? gen_label_rtx () : 0;
  thiscond->data.cond.endif_label = thiscond->exit_label;
  cond_stack = thiscond;
  nesting_stack = thiscond;

  if (output_bytecode)
    bc_expand_start_cond (cond, exitflag);
  else
    do_jump (cond, thiscond->data.cond.next_label, NULL_RTX);
}

/* Generate RTL between then-clause and the elseif-clause
   of an if-then-elseif-....  */

void
expand_start_elseif (cond)
     tree cond;
{
  if (cond_stack->data.cond.endif_label == 0)
    cond_stack->data.cond.endif_label = gen_label_rtx ();
  emit_jump (cond_stack->data.cond.endif_label);
  emit_label (cond_stack->data.cond.next_label);
  cond_stack->data.cond.next_label = gen_label_rtx ();
  do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);
}

/* Generate RTL between the then-clause and the else-clause
   of an if-then-else.  */

void
expand_start_else ()
{
  if (cond_stack->data.cond.endif_label == 0)
    cond_stack->data.cond.endif_label = gen_label_rtx ();

  if (output_bytecode)
    {
      bc_expand_start_else ();
      return;
    }

  emit_jump (cond_stack->data.cond.endif_label);
  emit_label (cond_stack->data.cond.next_label);
  cond_stack->data.cond.next_label = 0;  /* No more _else or _elseif calls.  */
}

/* After calling expand_start_else, turn this "else" into an "else if"
   by providing another condition.  */

void
expand_elseif (cond)
     tree cond;
{
  cond_stack->data.cond.next_label = gen_label_rtx ();
  do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);
}

/* Generate RTL for the end of an if-then.
   Pop the record for it off of cond_stack.  */

void
expand_end_cond ()
{
  struct nesting *thiscond = cond_stack;

  if (output_bytecode)
    bc_expand_end_cond ();
  else
    {
      do_pending_stack_adjust ();
      if (thiscond->data.cond.next_label)
	emit_label (thiscond->data.cond.next_label);
      if (thiscond->data.cond.endif_label)
	emit_label (thiscond->data.cond.endif_label);
    }

  POPSTACK (cond_stack);
  last_expr_type = 0;
}


/* Generate code for the start of an if-then.  COND is the expression
   whose truth is to be tested; if EXITFLAG is nonzero this conditional
   is to be visible to exit_something.  It is assumed that the caller
   has pushed the previous context on the cond stack.  */

static void
bc_expand_start_cond (cond, exitflag)
     tree cond;
     int exitflag;
{
  struct nesting *thiscond = cond_stack;

  thiscond->data.case_stmt.nominal_type = cond;
  if (! exitflag)
    thiscond->exit_label = gen_label_rtx ();
  bc_expand_expr (cond);
  bc_emit_bytecode (xjumpifnot);
  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label));

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif
}

/* Generate the label for the end of an if with
   no else- clause.  */

static void
bc_expand_end_cond ()
{
  struct nesting *thiscond = cond_stack;

  bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->exit_label));
}

/* Generate code for the start of the else- clause of
   an if-then-else.  */

static void
bc_expand_start_else ()
{
  struct nesting *thiscond = cond_stack;

  thiscond->data.cond.endif_label = thiscond->exit_label;
  thiscond->exit_label = gen_label_rtx ();
  bc_emit_bytecode (jump);
  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscond->exit_label));

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif

  bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscond->data.cond.endif_label));
}

/* Generate RTL for the start of a loop.  EXIT_FLAG is nonzero if this
   loop should be exited by `exit_something'.  This is a loop for which
   `expand_continue' will jump to the top of the loop.

   Make an entry on loop_stack to record the labels associated with
   this loop.  */

struct nesting *
expand_start_loop (exit_flag)
     int exit_flag;
{
  register struct nesting *thisloop = ALLOC_NESTING ();

  /* Make an entry on loop_stack for the loop we are entering.  */

  thisloop->next = loop_stack;
  thisloop->all = nesting_stack;
  thisloop->depth = ++nesting_depth;
  thisloop->data.loop.start_label = gen_label_rtx ();
  thisloop->data.loop.end_label = gen_label_rtx ();
  thisloop->data.loop.alt_end_label = 0;
  thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
  thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
  loop_stack = thisloop;
  nesting_stack = thisloop;

  if (output_bytecode)
    {
      bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->data.loop.start_label));
      return thisloop;
    }

  do_pending_stack_adjust ();
  emit_queue ();
  emit_note (NULL_PTR, NOTE_INSN_LOOP_BEG);
  emit_label (thisloop->data.loop.start_label);

  return thisloop;
}

/* Like expand_start_loop but for a loop where the continuation point
   (for expand_continue_loop) will be specified explicitly.  */

struct nesting *
expand_start_loop_continue_elsewhere (exit_flag)
     int exit_flag;
{
  struct nesting *thisloop = expand_start_loop (exit_flag);
  loop_stack->data.loop.continue_label = gen_label_rtx ();
  return thisloop;
}

/* Specify the continuation point for a loop started with
   expand_start_loop_continue_elsewhere.
   Use this at the point in the code to which a continue statement
   should jump.  */

void
expand_loop_continue_here ()
{
  if (output_bytecode)
    {
      bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (loop_stack->data.loop.continue_label));
      return;
    }
  do_pending_stack_adjust ();
  emit_note (NULL_PTR, NOTE_INSN_LOOP_CONT);
  emit_label (loop_stack->data.loop.continue_label);
}

/* End a loop.  */

static void
bc_expand_end_loop ()
{
  struct nesting *thisloop = loop_stack;

  bc_emit_bytecode (jump);
  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thisloop->data.loop.start_label));

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif

  bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisloop->exit_label));
  POPSTACK (loop_stack);
  last_expr_type = 0;
}


/* Finish a loop.  Generate a jump back to the top and the loop-exit label.
   Pop the block off of loop_stack.  */

void
expand_end_loop ()
{
  register rtx insn;
  register rtx start_label;
  rtx last_test_insn = 0;
  int num_insns = 0;
    
  if (output_bytecode)
    {
      bc_expand_end_loop ();
      return;
    }

  insn = get_last_insn ();
  start_label = loop_stack->data.loop.start_label;

  /* Mark the continue-point at the top of the loop if none elsewhere.  */
  if (start_label == loop_stack->data.loop.continue_label)
    emit_note_before (NOTE_INSN_LOOP_CONT, start_label);

  do_pending_stack_adjust ();

  /* If optimizing, perhaps reorder the loop.  If the loop
     starts with a conditional exit, roll that to the end
     where it will optimize together with the jump back.

     We look for the last conditional branch to the exit that we encounter
     before hitting 30 insns or a CALL_INSN.  If we see an unconditional
     branch to the exit first, use it.

     We must also stop at NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes
     because moving them is not valid.  */

  if (optimize
      &&
      ! (GET_CODE (insn) == JUMP_INSN
	 && GET_CODE (PATTERN (insn)) == SET
	 && SET_DEST (PATTERN (insn)) == pc_rtx
	 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE))
    {
      /* Scan insns from the top of the loop looking for a qualified
	 conditional exit.  */
      for (insn = NEXT_INSN (loop_stack->data.loop.start_label); insn;
	   insn = NEXT_INSN (insn))
	{
	  if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)
	    break;

	  if (GET_CODE (insn) == NOTE
	      && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG
		  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END))
	    break;

	  if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN)
	    num_insns++;

	  if (last_test_insn && num_insns > 30)
	    break;

	  if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET
	      && SET_DEST (PATTERN (insn)) == pc_rtx
	      && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE
	      && ((GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == LABEL_REF
		   && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
			== loop_stack->data.loop.end_label)
		       || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 1), 0)
			   == loop_stack->data.loop.alt_end_label)))
		  || (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 2)) == LABEL_REF
		      && ((XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
			   == loop_stack->data.loop.end_label)
			  || (XEXP (XEXP (SET_SRC (PATTERN (insn)), 2), 0)
			      == loop_stack->data.loop.alt_end_label)))))
	    last_test_insn = insn;

	  if (last_test_insn == 0 && GET_CODE (insn) == JUMP_INSN
	      && GET_CODE (PATTERN (insn)) == SET
	      && SET_DEST (PATTERN (insn)) == pc_rtx
	      && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF
	      && ((XEXP (SET_SRC (PATTERN (insn)), 0)
		   == loop_stack->data.loop.end_label)
		  || (XEXP (SET_SRC (PATTERN (insn)), 0)
		      == loop_stack->data.loop.alt_end_label)))
	    /* Include BARRIER.  */
	    last_test_insn = NEXT_INSN (insn);
	}

      if (last_test_insn != 0 && last_test_insn != get_last_insn ())
	{
	  /* We found one.  Move everything from there up
	     to the end of the loop, and add a jump into the loop
	     to jump to there.  */
	  register rtx newstart_label = gen_label_rtx ();
	  register rtx start_move = start_label;

	  /* If the start label is preceded by a NOTE_INSN_LOOP_CONT note,
	     then we want to move this note also.  */
	  if (GET_CODE (PREV_INSN (start_move)) == NOTE
	      && (NOTE_LINE_NUMBER (PREV_INSN (start_move))
		  == NOTE_INSN_LOOP_CONT))
	    start_move = PREV_INSN (start_move);

	  emit_label_after (newstart_label, PREV_INSN (start_move));
	  reorder_insns (start_move, last_test_insn, get_last_insn ());
	  emit_jump_insn_after (gen_jump (start_label),
				PREV_INSN (newstart_label));
	  emit_barrier_after (PREV_INSN (newstart_label));
	  start_label = newstart_label;
	}
    }

  emit_jump (start_label);
  emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
  emit_label (loop_stack->data.loop.end_label);

  POPSTACK (loop_stack);

  last_expr_type = 0;
}

/* Generate a jump to the current loop's continue-point.
   This is usually the top of the loop, but may be specified
   explicitly elsewhere.  If not currently inside a loop,
   return 0 and do nothing; caller will print an error message.  */

int
expand_continue_loop (whichloop)
     struct nesting *whichloop;
{
  last_expr_type = 0;
  if (whichloop == 0)
    whichloop = loop_stack;
  if (whichloop == 0)
    return 0;
  expand_goto_internal (NULL_TREE, whichloop->data.loop.continue_label,
			NULL_RTX);
  return 1;
}

/* Generate a jump to exit the current loop.  If not currently inside a loop,
   return 0 and do nothing; caller will print an error message.  */

int
expand_exit_loop (whichloop)
     struct nesting *whichloop;
{
  last_expr_type = 0;
  if (whichloop == 0)
    whichloop = loop_stack;
  if (whichloop == 0)
    return 0;
  expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label, NULL_RTX);
  return 1;
}

/* Generate a conditional jump to exit the current loop if COND
   evaluates to zero.  If not currently inside a loop,
   return 0 and do nothing; caller will print an error message.  */

int
expand_exit_loop_if_false (whichloop, cond)
     struct nesting *whichloop;
     tree cond;
{
  last_expr_type = 0;
  if (whichloop == 0)
    whichloop = loop_stack;
  if (whichloop == 0)
    return 0;
  if (output_bytecode)
    {
      bc_expand_expr (cond);
      bc_expand_goto_internal (xjumpifnot,
			       BYTECODE_BC_LABEL (whichloop->exit_label),
			       NULL_TREE);
    }
  else
    {
      /* In order to handle fixups, we actually create a conditional jump
	 around a unconditional branch to exit the loop.  If fixups are
	 necessary, they go before the unconditional branch.  */

      rtx label = gen_label_rtx ();
      rtx last_insn;

      do_jump (cond, NULL_RTX, label);
      last_insn = get_last_insn ();
      if (GET_CODE (last_insn) == CODE_LABEL)
	whichloop->data.loop.alt_end_label = last_insn;
      expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label,
			    NULL_RTX);
      emit_label (label);
    }

  return 1;
}

/* Return non-zero if we should preserve sub-expressions as separate
   pseudos.  We never do so if we aren't optimizing.  We always do so
   if -fexpensive-optimizations.

   Otherwise, we only do so if we are in the "early" part of a loop.  I.e.,
   the loop may still be a small one.  */

int
preserve_subexpressions_p ()
{
  rtx insn;

  if (flag_expensive_optimizations)
    return 1;

  if (optimize == 0 || loop_stack == 0)
    return 0;

  insn = get_last_insn_anywhere ();

  return (insn
	  && (INSN_UID (insn) - INSN_UID (loop_stack->data.loop.start_label)
	      < n_non_fixed_regs * 3));

}

/* Generate a jump to exit the current loop, conditional, binding contour
   or case statement.  Not all such constructs are visible to this function,
   only those started with EXIT_FLAG nonzero.  Individual languages use
   the EXIT_FLAG parameter to control which kinds of constructs you can
   exit this way.

   If not currently inside anything that can be exited,
   return 0 and do nothing; caller will print an error message.  */

int
expand_exit_something ()
{
  struct nesting *n;
  last_expr_type = 0;
  for (n = nesting_stack; n; n = n->all)
    if (n->exit_label != 0)
      {
	expand_goto_internal (NULL_TREE, n->exit_label, NULL_RTX);
	return 1;
      }

  return 0;
}

/* Generate RTL to return from the current function, with no value.
   (That is, we do not do anything about returning any value.)  */

void
expand_null_return ()
{
  struct nesting *block = block_stack;
  rtx last_insn = 0;

  if (output_bytecode)
    {
      bc_emit_instruction (ret);
      return;
    }

  /* Does any pending block have cleanups?  */

  while (block && block->data.block.cleanups == 0)
    block = block->next;

  /* If yes, use a goto to return, since that runs cleanups.  */

  expand_null_return_1 (last_insn, block != 0);
}

/* Generate RTL to return from the current function, with value VAL.  */

static void
expand_value_return (val)
     rtx val;
{
  struct nesting *block = block_stack;
  rtx last_insn = get_last_insn ();
  rtx return_reg = DECL_RTL (DECL_RESULT (current_function_decl));

  /* Copy the value to the return location
     unless it's already there.  */

  if (return_reg != val)
    {
#ifdef PROMOTE_FUNCTION_RETURN
      tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
      int unsignedp = TREE_UNSIGNED (type);
      enum machine_mode mode
	= promote_mode (type, DECL_MODE (DECL_RESULT (current_function_decl)),
			&unsignedp, 1);

      if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
	convert_move (return_reg, val, unsignedp);
      else
#endif
	emit_move_insn (return_reg, val);
    }
  if (GET_CODE (return_reg) == REG
      && REGNO (return_reg) < FIRST_PSEUDO_REGISTER)
    emit_insn (gen_rtx (USE, VOIDmode, return_reg));
  /* Handle calls that return values in multiple non-contiguous locations.
     The Irix 6 ABI has examples of this.  */
  else if (GET_CODE (return_reg) == PARALLEL)
    {
      int i;

      for (i = 0; i < XVECLEN (return_reg, 0); i++)
	{
	  rtx x = XEXP (XVECEXP (return_reg, 0, i), 0);

	  if (GET_CODE (x) == REG
	      && REGNO (x) < FIRST_PSEUDO_REGISTER)
	    emit_insn (gen_rtx (USE, VOIDmode, x));
	}
    }

  /* Does any pending block have cleanups?  */

  while (block && block->data.block.cleanups == 0)
    block = block->next;

  /* If yes, use a goto to return, since that runs cleanups.
     Use LAST_INSN to put cleanups *before* the move insn emitted above.  */

  expand_null_return_1 (last_insn, block != 0);
}

/* Output a return with no value.  If LAST_INSN is nonzero,
   pretend that the return takes place after LAST_INSN.
   If USE_GOTO is nonzero then don't use a return instruction;
   go to the return label instead.  This causes any cleanups
   of pending blocks to be executed normally.  */

static void
expand_null_return_1 (last_insn, use_goto)
     rtx last_insn;
     int use_goto;
{
  rtx end_label = cleanup_label ? cleanup_label : return_label;

  clear_pending_stack_adjust ();
  do_pending_stack_adjust ();
  last_expr_type = 0;

  /* PCC-struct return always uses an epilogue.  */
  if (current_function_returns_pcc_struct || use_goto)
    {
      if (end_label == 0)
	end_label = return_label = gen_label_rtx ();
      expand_goto_internal (NULL_TREE, end_label, last_insn);
      return;
    }

  /* Otherwise output a simple return-insn if one is available,
     unless it won't do the job.  */
#ifdef HAVE_return
  if (HAVE_return && use_goto == 0 && cleanup_label == 0)
    {
      emit_jump_insn (gen_return ());
      emit_barrier ();
      return;
    }
#endif

  /* Otherwise jump to the epilogue.  */
  expand_goto_internal (NULL_TREE, end_label, last_insn);
}

/* Generate RTL to evaluate the expression RETVAL and return it
   from the current function.  */

void
expand_return (retval)
     tree retval;
{
  /* If there are any cleanups to be performed, then they will
     be inserted following LAST_INSN.  It is desirable
     that the last_insn, for such purposes, should be the
     last insn before computing the return value.  Otherwise, cleanups
     which call functions can clobber the return value.  */
  /* ??? rms: I think that is erroneous, because in C++ it would
     run destructors on variables that might be used in the subsequent
     computation of the return value.  */
  rtx last_insn = 0;
  register rtx val = 0;
  register rtx op0;
  tree retval_rhs;
  int cleanups;
  struct nesting *block;

  /* Bytecode returns are quite simple, just leave the result on the
     arithmetic stack.  */
  if (output_bytecode)
    {
      bc_expand_expr (retval);
      bc_emit_instruction (ret);
      return;
    }
  
  /* If function wants no value, give it none.  */
  if (TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl))) == VOID_TYPE)
    {
      expand_expr (retval, NULL_RTX, VOIDmode, 0);
      emit_queue ();
      expand_null_return ();
      return;
    }

  /* Are any cleanups needed?  E.g. C++ destructors to be run?  */
  /* This is not sufficient.  We also need to watch for cleanups of the
     expression we are about to expand.  Unfortunately, we cannot know
     if it has cleanups until we expand it, and we want to change how we
     expand it depending upon if we need cleanups.  We can't win.  */
#if 0
  cleanups = any_pending_cleanups (1);
#else
  cleanups = 1;
#endif

  if (TREE_CODE (retval) == RESULT_DECL)
    retval_rhs = retval;
  else if ((TREE_CODE (retval) == MODIFY_EXPR || TREE_CODE (retval) == INIT_EXPR)
	   && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
    retval_rhs = TREE_OPERAND (retval, 1);
  else if (TREE_TYPE (retval) == void_type_node)
    /* Recognize tail-recursive call to void function.  */
    retval_rhs = retval;
  else
    retval_rhs = NULL_TREE;

  /* Only use `last_insn' if there are cleanups which must be run.  */
  if (cleanups || cleanup_label != 0)
    last_insn = get_last_insn ();

  /* Distribute return down conditional expr if either of the sides
     may involve tail recursion (see test below).  This enhances the number
     of tail recursions we see.  Don't do this always since it can produce
     sub-optimal code in some cases and we distribute assignments into
     conditional expressions when it would help.  */

  if (optimize && retval_rhs != 0
      && frame_offset == 0
      && TREE_CODE (retval_rhs) == COND_EXPR
      && (TREE_CODE (TREE_OPERAND (retval_rhs, 1)) == CALL_EXPR
	  || TREE_CODE (TREE_OPERAND (retval_rhs, 2)) == CALL_EXPR))
    {
      rtx label = gen_label_rtx ();
      tree expr;

      do_jump (TREE_OPERAND (retval_rhs, 0), label, NULL_RTX);
      expr = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (current_function_decl)),
		    DECL_RESULT (current_function_decl),
		    TREE_OPERAND (retval_rhs, 1));
      TREE_SIDE_EFFECTS (expr) = 1;
      expand_return (expr);
      emit_label (label);

      expr = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (current_function_decl)),
		    DECL_RESULT (current_function_decl),
		    TREE_OPERAND (retval_rhs, 2));
      TREE_SIDE_EFFECTS (expr) = 1;
      expand_return (expr);
      return;
    }

  /* For tail-recursive call to current function,
     just jump back to the beginning.
     It's unsafe if any auto variable in this function
     has its address taken; for simplicity,
     require stack frame to be empty.  */
  if (optimize && retval_rhs != 0
      && frame_offset == 0
      && TREE_CODE (retval_rhs) == CALL_EXPR
      && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
      && TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0) == current_function_decl
      /* Finish checking validity, and if valid emit code
	 to set the argument variables for the new call.  */
      && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
			      DECL_ARGUMENTS (current_function_decl)))
    {
      if (tail_recursion_label == 0)
	{
	  tail_recursion_label = gen_label_rtx ();
	  emit_label_after (tail_recursion_label,
			    tail_recursion_reentry);
	}
      emit_queue ();
      expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
      emit_barrier ();
      return;
    }
#ifdef HAVE_return
  /* This optimization is safe if there are local cleanups
     because expand_null_return takes care of them.
     ??? I think it should also be safe when there is a cleanup label,
     because expand_null_return takes care of them, too.
     Any reason why not?  */
  if (HAVE_return && cleanup_label == 0
      && ! current_function_returns_pcc_struct
      && BRANCH_COST <= 1)
    {
      /* If this is  return x == y;  then generate
	 if (x == y) return 1; else return 0;
	 if we can do it with explicit return insns and branches are cheap,
	 but not if we have the corresponding scc insn.  */
      int has_scc = 0;
      if (retval_rhs)
	switch (TREE_CODE (retval_rhs))
	  {
	  case EQ_EXPR:
#ifdef HAVE_seq
	    has_scc = HAVE_seq;
#endif
	  case NE_EXPR:
#ifdef HAVE_sne
	    has_scc = HAVE_sne;
#endif
	  case GT_EXPR:
#ifdef HAVE_sgt
	    has_scc = HAVE_sgt;
#endif
	  case GE_EXPR:
#ifdef HAVE_sge
	    has_scc = HAVE_sge;
#endif
	  case LT_EXPR:
#ifdef HAVE_slt
	    has_scc = HAVE_slt;
#endif
	  case LE_EXPR:
#ifdef HAVE_sle
	    has_scc = HAVE_sle;
#endif
	  case TRUTH_ANDIF_EXPR:
	  case TRUTH_ORIF_EXPR:
	  case TRUTH_AND_EXPR:
	  case TRUTH_OR_EXPR:
	  case TRUTH_NOT_EXPR:
	  case TRUTH_XOR_EXPR:
	    if (! has_scc)
	      {
		op0 = gen_label_rtx ();
		jumpifnot (retval_rhs, op0);
		expand_value_return (const1_rtx);
		emit_label (op0);
		expand_value_return (const0_rtx);
		return;
	      }
	  }
    }
#endif /* HAVE_return */

  /* If the result is an aggregate that is being returned in one (or more)
     registers, load the registers here.  The compiler currently can't handle
     copying a BLKmode value into registers.  We could put this code in a
     more general area (for use by everyone instead of just function
     call/return), but until this feature is generally usable it is kept here
     (and in expand_call).  The value must go into a pseudo in case there
     are cleanups that will clobber the real return register.  */

  if (retval_rhs != 0
      && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
      && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
    {
      int i, bitpos, xbitpos;
      int big_endian_correction = 0;
      int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
      int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
      int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
      rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
      rtx result_reg, src, dst;
      rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
      enum machine_mode tmpmode, result_reg_mode;

      /* Structures whose size is not a multiple of a word are aligned
	 to the least significant byte (to the right).  On a BYTES_BIG_ENDIAN
	 machine, this means we must skip the empty high order bytes when
	 calculating the bit offset.  */
      if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
	big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
						  * BITS_PER_UNIT));

      /* Copy the structure BITSIZE bits at a time.  */ 
      for (bitpos = 0, xbitpos = big_endian_correction;
	   bitpos < bytes * BITS_PER_UNIT;
	   bitpos += bitsize, xbitpos += bitsize)
	{
	  /* We need a new destination pseudo each time xbitpos is
	     on a word boundary and when xbitpos == big_endian_correction
	     (the first time through).  */
	  if (xbitpos % BITS_PER_WORD == 0
	      || xbitpos == big_endian_correction)
	    {
	      /* Generate an appropriate register.  */
	      dst = gen_reg_rtx (word_mode);
	      result_pseudos[xbitpos / BITS_PER_WORD] = dst;

	      /* Clobber the destination before we move anything into it.  */
	      emit_insn (gen_rtx (CLOBBER, VOIDmode, dst));
	    }

	  /* We need a new source operand each time bitpos is on a word
	     boundary.  */
	  if (bitpos % BITS_PER_WORD == 0)
	    src = operand_subword_force (result_val,
					 bitpos / BITS_PER_WORD,
					 BLKmode);

	  /* Use bitpos for the source extraction (left justified) and
	     xbitpos for the destination store (right justified).  */
	  store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
			   extract_bit_field (src, bitsize,
					      bitpos % BITS_PER_WORD, 1,
					      NULL_RTX, word_mode,
					      word_mode,
					      bitsize / BITS_PER_UNIT,
					      BITS_PER_WORD),
			   bitsize / BITS_PER_UNIT, BITS_PER_WORD);
	}

      /* Find the smallest integer mode large enough to hold the
	 entire structure and use that mode instead of BLKmode
	 on the USE insn for the return register.   */
      bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
      for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
	   tmpmode != MAX_MACHINE_MODE;
	   tmpmode = GET_MODE_WIDER_MODE (tmpmode))
	{
	  /* Have we found a large enough mode?  */
	  if (GET_MODE_SIZE (tmpmode) >= bytes)
	    break;
	}

      /* No suitable mode found.  */
      if (tmpmode == MAX_MACHINE_MODE)
	abort ();

      PUT_MODE (DECL_RTL (DECL_RESULT (current_function_decl)), tmpmode);

      if (GET_MODE_SIZE (tmpmode) < GET_MODE_SIZE (word_mode))
	result_reg_mode = word_mode;
      else
	result_reg_mode = tmpmode;
      result_reg = gen_reg_rtx (result_reg_mode);

      emit_queue ();
      for (i = 0; i < n_regs; i++)
	emit_move_insn (operand_subword (result_reg, i, 0, result_reg_mode),
			result_pseudos[i]);

      if (tmpmode != result_reg_mode)
	result_reg = gen_lowpart (tmpmode, result_reg);

      expand_value_return (result_reg);
    }
  else if (cleanups
      && retval_rhs != 0
      && TREE_TYPE (retval_rhs) != void_type_node
      && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
    {
      /* Calculate the return value into a pseudo reg.  */
      val = gen_reg_rtx (DECL_MODE (DECL_RESULT (current_function_decl)));
      val = expand_expr (retval_rhs, val, GET_MODE (val), 0);
      val = force_not_mem (val);
      emit_queue ();
      /* Return the calculated value, doing cleanups first.  */
      expand_value_return (val);
    }
  else
    {
      /* No cleanups or no hard reg used;
	 calculate value into hard return reg.  */
      expand_expr (retval, const0_rtx, VOIDmode, 0);
      emit_queue ();
      expand_value_return (DECL_RTL (DECL_RESULT (current_function_decl)));
    }
}

/* Return 1 if the end of the generated RTX is not a barrier.
   This means code already compiled can drop through.  */

int
drop_through_at_end_p ()
{
  rtx insn = get_last_insn ();
  while (insn && GET_CODE (insn) == NOTE)
    insn = PREV_INSN (insn);
  return insn && GET_CODE (insn) != BARRIER;
}

/* Emit code to alter this function's formal parms for a tail-recursive call.
   ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
   FORMALS is the chain of decls of formals.
   Return 1 if this can be done;
   otherwise return 0 and do not emit any code.  */

static int
tail_recursion_args (actuals, formals)
     tree actuals, formals;
{
  register tree a = actuals, f = formals;
  register int i;
  register rtx *argvec;

  /* Check that number and types of actuals are compatible
     with the formals.  This is not always true in valid C code.
     Also check that no formal needs to be addressable
     and that all formals are scalars.  */

  /* Also count the args.  */

  for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
    {
      if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (a)))
	  != TYPE_MAIN_VARIANT (TREE_TYPE (f)))
	return 0;
      if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
	return 0;
    }
  if (a != 0 || f != 0)
    return 0;

  /* Compute all the actuals.  */

  argvec = (rtx *) alloca (i * sizeof (rtx));

  for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
    argvec[i] = expand_expr (TREE_VALUE (a), NULL_RTX, VOIDmode, 0);

  /* Find which actual values refer to current values of previous formals.
     Copy each of them now, before any formal is changed.  */

  for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
    {
      int copy = 0;
      register int j;
      for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
	if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
	  { copy = 1; break; }
      if (copy)
	argvec[i] = copy_to_reg (argvec[i]);
    }

  /* Store the values of the actuals into the formals.  */

  for (f = formals, a = actuals, i = 0; f;
       f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
    {
      if (GET_MODE (DECL_RTL (f)) == GET_MODE (argvec[i]))
	emit_move_insn (DECL_RTL (f), argvec[i]);
      else
	convert_move (DECL_RTL (f), argvec[i],
		      TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (a))));
    }

  free_temp_slots ();
  return 1;
}

/* Generate the RTL code for entering a binding contour.
   The variables are declared one by one, by calls to `expand_decl'.

   EXIT_FLAG is nonzero if this construct should be visible to
   `exit_something'.  */

void
expand_start_bindings (exit_flag)
     int exit_flag;
{
  struct nesting *thisblock = ALLOC_NESTING ();
  rtx note = output_bytecode ? 0 : emit_note (NULL_PTR, NOTE_INSN_BLOCK_BEG);

  /* Make an entry on block_stack for the block we are entering.  */

  thisblock->next = block_stack;
  thisblock->all = nesting_stack;
  thisblock->depth = ++nesting_depth;
  thisblock->data.block.stack_level = 0;
  thisblock->data.block.cleanups = 0;
  thisblock->data.block.function_call_count = 0;
  thisblock->data.block.exception_region = 0;
  thisblock->data.block.target_temp_slot_level = target_temp_slot_level;

  thisblock->data.block.conditional_code = 0;
  thisblock->data.block.last_unconditional_cleanup = note;
  thisblock->data.block.cleanup_ptr = &thisblock->data.block.cleanups;

  if (block_stack
      && !(block_stack->data.block.cleanups == NULL_TREE
	   && block_stack->data.block.outer_cleanups == NULL_TREE))
    thisblock->data.block.outer_cleanups
      = tree_cons (NULL_TREE, block_stack->data.block.cleanups,
		   block_stack->data.block.outer_cleanups);
  else
    thisblock->data.block.outer_cleanups = 0;
  thisblock->data.block.label_chain = 0;
  thisblock->data.block.innermost_stack_block = stack_block_stack;
  thisblock->data.block.first_insn = note;
  thisblock->data.block.block_start_count = ++block_start_count;
  thisblock->exit_label = exit_flag ? gen_label_rtx () : 0;
  block_stack = thisblock;
  nesting_stack = thisblock;

  if (!output_bytecode)
    {
      /* Make a new level for allocating stack slots.  */
      push_temp_slots ();
    }
}

/* Specify the scope of temporaries created by TARGET_EXPRs.  Similar
   to CLEANUP_POINT_EXPR, but handles cases when a series of calls to
   expand_expr are made.  After we end the region, we know that all
   space for all temporaries that were created by TARGET_EXPRs will be
   destroyed and their space freed for reuse.  */

void
expand_start_target_temps ()
{
  /* This is so that even if the result is preserved, the space
     allocated will be freed, as we know that it is no longer in use.  */
  push_temp_slots ();

  /* Start a new binding layer that will keep track of all cleanup
     actions to be performed.  */
  expand_start_bindings (0);

  target_temp_slot_level = temp_slot_level;
}

void
expand_end_target_temps ()
{
  expand_end_bindings (NULL_TREE, 0, 0);
  
  /* This is so that even if the result is preserved, the space
     allocated will be freed, as we know that it is no longer in use.  */
  pop_temp_slots ();
}

/* Mark top block of block_stack as an implicit binding for an
   exception region.  This is used to prevent infinite recursion when
   ending a binding with expand_end_bindings.  It is only ever called
   by expand_eh_region_start, as that it the only way to create a
   block stack for a exception region.  */

void
mark_block_as_eh_region ()
{
  block_stack->data.block.exception_region = 1;
  if (block_stack->next
      && block_stack->next->data.block.conditional_code)
    {
      block_stack->data.block.conditional_code
	= block_stack->next->data.block.conditional_code;
      block_stack->data.block.last_unconditional_cleanup
	= block_stack->next->data.block.last_unconditional_cleanup;
      block_stack->data.block.cleanup_ptr
	= block_stack->next->data.block.cleanup_ptr;
    }
}

/* True if we are currently emitting insns in an area of output code
   that is controlled by a conditional expression.  This is used by
   the cleanup handling code to generate conditional cleanup actions.  */

int
conditional_context ()
{
  return block_stack && block_stack->data.block.conditional_code;
}

/* Mark top block of block_stack as not for an implicit binding for an
   exception region.  This is only ever done by expand_eh_region_end
   to let expand_end_bindings know that it is being called explicitly
   to end the binding layer for just the binding layer associated with
   the exception region, otherwise expand_end_bindings would try and
   end all implicit binding layers for exceptions regions, and then
   one normal binding layer.  */

void
mark_block_as_not_eh_region ()
{
  block_stack->data.block.exception_region = 0;
}

/* True if the top block of block_stack was marked as for an exception
   region by mark_block_as_eh_region.  */

int
is_eh_region ()
{
  return block_stack && block_stack->data.block.exception_region;
}

/* Given a pointer to a BLOCK node, save a pointer to the most recently
   generated NOTE_INSN_BLOCK_END in the BLOCK_END_NOTE field of the given
   BLOCK node.  */

void
remember_end_note (block)
     register tree block;
{
  BLOCK_END_NOTE (block) = last_block_end_note;
  last_block_end_note = NULL_RTX;
}

/* Generate RTL code to terminate a binding contour.
   VARS is the chain of VAR_DECL nodes
   for the variables bound in this contour.
   MARK_ENDS is nonzero if we should put a note at the beginning
   and end of this binding contour.

   DONT_JUMP_IN is nonzero if it is not valid to jump into this contour.
   (That is true automatically if the contour has a saved stack level.)  */

void
expand_end_bindings (vars, mark_ends, dont_jump_in)
     tree vars;
     int mark_ends;
     int dont_jump_in;
{
  register struct nesting *thisblock;
  register tree decl;

  while (block_stack->data.block.exception_region)
    {
      /* Because we don't need or want a new temporary level and
	 because we didn't create one in expand_eh_region_start,
	 create a fake one now to avoid removing one in
	 expand_end_bindings.  */
      push_temp_slots ();

      block_stack->data.block.exception_region = 0;

      expand_end_bindings (NULL_TREE, 0, 0);
    }

  if (output_bytecode)
    {
      bc_expand_end_bindings (vars, mark_ends, dont_jump_in);
      return;
    }

  /* Since expand_eh_region_start does an expand_start_bindings, we
     have to first end all the bindings that were created by
     expand_eh_region_start.  */
     
  thisblock = block_stack;

  if (warn_unused)
    for (decl = vars; decl; decl = TREE_CHAIN (decl))
      if (! TREE_USED (decl) && TREE_CODE (decl) == VAR_DECL
	  && ! DECL_IN_SYSTEM_HEADER (decl))
	warning_with_decl (decl, "unused variable `%s'");

  if (thisblock->exit_label)
    {
      do_pending_stack_adjust ();
      emit_label (thisblock->exit_label);
    }

  /* If necessary, make a handler for nonlocal gotos taking
     place in the function calls in this block.  */
  if (function_call_count != thisblock->data.block.function_call_count
      && nonlocal_labels
      /* Make handler for outermost block
	 if there were any nonlocal gotos to this function.  */
      && (thisblock->next == 0 ? current_function_has_nonlocal_label
	  /* Make handler for inner block if it has something
	     special to do when you jump out of it.  */
	  : (thisblock->data.block.cleanups != 0
	     || thisblock->data.block.stack_level != 0)))
    {
      tree link;
      rtx afterward = gen_label_rtx ();
      rtx handler_label = gen_label_rtx ();
      rtx save_receiver = gen_reg_rtx (Pmode);
      rtx insns;

      /* Don't let jump_optimize delete the handler.  */
      LABEL_PRESERVE_P (handler_label) = 1;

      /* Record the handler address in the stack slot for that purpose,
	 during this block, saving and restoring the outer value.  */
      if (thisblock->next != 0)
	{
	  emit_move_insn (nonlocal_goto_handler_slot, save_receiver);

	  start_sequence ();
	  emit_move_insn (save_receiver, nonlocal_goto_handler_slot);
	  insns = get_insns ();
	  end_sequence ();
	  emit_insns_before (insns, thisblock->data.block.first_insn);
	}

      start_sequence ();
      emit_move_insn (nonlocal_goto_handler_slot,
		      gen_rtx (LABEL_REF, Pmode, handler_label));
      insns = get_insns ();
      end_sequence ();
      emit_insns_before (insns, thisblock->data.block.first_insn);

      /* Jump around the handler; it runs only when specially invoked.  */
      emit_jump (afterward);
      emit_label (handler_label);

#ifdef HAVE_nonlocal_goto
      if (! HAVE_nonlocal_goto)
#endif
	/* First adjust our frame pointer to its actual value.  It was
	   previously set to the start of the virtual area corresponding to
	   the stacked variables when we branched here and now needs to be
	   adjusted to the actual hardware fp value.

	   Assignments are to virtual registers are converted by
	   instantiate_virtual_regs into the corresponding assignment
	   to the underlying register (fp in this case) that makes
	   the original assignment true.
	   So the following insn will actually be
	   decrementing fp by STARTING_FRAME_OFFSET.  */
	emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);

#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      if (fixed_regs[ARG_POINTER_REGNUM])
	{
#ifdef ELIMINABLE_REGS
	  /* If the argument pointer can be eliminated in favor of the
	     frame pointer, we don't need to restore it.  We assume here
	     that if such an elimination is present, it can always be used.
	     This is the case on all known machines; if we don't make this
	     assumption, we do unnecessary saving on many machines.  */
	  static struct elims {int from, to;} elim_regs[] = ELIMINABLE_REGS;
	  int i;

	  for (i = 0; i < sizeof elim_regs / sizeof elim_regs[0]; i++)
	    if (elim_regs[i].from == ARG_POINTER_REGNUM
		&& elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
	      break;

	  if (i == sizeof elim_regs / sizeof elim_regs [0])
#endif
	    {
	      /* Now restore our arg pointer from the address at which it
		 was saved in our stack frame.
		 If there hasn't be space allocated for it yet, make
		 some now.  */
	      if (arg_pointer_save_area == 0)
		arg_pointer_save_area
		  = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
	      emit_move_insn (virtual_incoming_args_rtx,
			      /* We need a pseudo here, or else
				 instantiate_virtual_regs_1 complains.  */
			      copy_to_reg (arg_pointer_save_area));
	    }
	}
#endif

#ifdef HAVE_nonlocal_goto_receiver
      if (HAVE_nonlocal_goto_receiver)
	emit_insn (gen_nonlocal_goto_receiver ());
#endif

      /* The handler expects the desired label address in the static chain
	 register.  It tests the address and does an appropriate jump
	 to whatever label is desired.  */
      for (link = nonlocal_labels; link; link = TREE_CHAIN (link))
	/* Skip any labels we shouldn't be able to jump to from here.  */
	if (! DECL_TOO_LATE (TREE_VALUE (link)))
	  {
	    rtx not_this = gen_label_rtx ();
	    rtx this = gen_label_rtx ();
	    do_jump_if_equal (static_chain_rtx,
			      gen_rtx (LABEL_REF, Pmode, DECL_RTL (TREE_VALUE (link))),
			      this, 0);
	    emit_jump (not_this);
	    emit_label (this);
	    expand_goto (TREE_VALUE (link));
	    emit_label (not_this);
	  }
      /* If label is not recognized, abort.  */
      emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "abort"), 0,
			 VOIDmode, 0);
      emit_barrier ();
      emit_label (afterward);
    }

  /* Don't allow jumping into a block that has cleanups or a stack level.  */
  if (dont_jump_in
      || thisblock->data.block.stack_level != 0
      || thisblock->data.block.cleanups != 0)
    {
      struct label_chain *chain;

      /* Any labels in this block are no longer valid to go to.
	 Mark them to cause an error message.  */
      for (chain = thisblock->data.block.label_chain; chain; chain = chain->next)
	{
	  DECL_TOO_LATE (chain->label) = 1;
	  /* If any goto without a fixup came to this label,
	     that must be an error, because gotos without fixups
	     come from outside all saved stack-levels and all cleanups.  */
	  if (TREE_ADDRESSABLE (chain->label))
	    error_with_decl (chain->label,
			     "label `%s' used before containing binding contour");
	}
    }

  /* Restore stack level in effect before the block
     (only if variable-size objects allocated).  */
  /* Perform any cleanups associated with the block.  */

  if (thisblock->data.block.stack_level != 0
      || thisblock->data.block.cleanups != 0)
    {
      /* Only clean up here if this point can actually be reached.  */
      int reachable = GET_CODE (get_last_insn ()) != BARRIER;

      /* Don't let cleanups affect ({...}) constructs.  */
      int old_expr_stmts_for_value = expr_stmts_for_value;
      rtx old_last_expr_value = last_expr_value;
      tree old_last_expr_type = last_expr_type;
      expr_stmts_for_value = 0;

      /* Do the cleanups.  */
      expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0, reachable);
      if (reachable)
	do_pending_stack_adjust ();

      expr_stmts_for_value = old_expr_stmts_for_value;
      last_expr_value = old_last_expr_value;
      last_expr_type = old_last_expr_type;

      /* Restore the stack level.  */

      if (reachable && thisblock->data.block.stack_level != 0)
	{
	  emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
			      thisblock->data.block.stack_level, NULL_RTX);
	  if (nonlocal_goto_handler_slot != 0)
	    emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
			     NULL_RTX);
	}

      /* Any gotos out of this block must also do these things.
	 Also report any gotos with fixups that came to labels in this
	 level.  */
      fixup_gotos (thisblock,
		   thisblock->data.block.stack_level,
		   thisblock->data.block.cleanups,
		   thisblock->data.block.first_insn,
		   dont_jump_in);
    }

  /* Mark the beginning and end of the scope if requested.
     We do this now, after running cleanups on the variables
     just going out of scope, so they are in scope for their cleanups.  */

  if (mark_ends)
    last_block_end_note = emit_note (NULL_PTR, NOTE_INSN_BLOCK_END);
  else
    /* Get rid of the beginning-mark if we don't make an end-mark.  */
    NOTE_LINE_NUMBER (thisblock->data.block.first_insn) = NOTE_INSN_DELETED;

  /* If doing stupid register allocation, make sure lives of all
     register variables declared here extend thru end of scope.  */

  if (obey_regdecls)
    for (decl = vars; decl; decl = TREE_CHAIN (decl))
      {
	rtx rtl = DECL_RTL (decl);
	if (TREE_CODE (decl) == VAR_DECL && rtl != 0)
	  use_variable (rtl);
      }

  /* Restore the temporary level of TARGET_EXPRs.  */
  target_temp_slot_level = thisblock->data.block.target_temp_slot_level;

  /* Restore block_stack level for containing block.  */

  stack_block_stack = thisblock->data.block.innermost_stack_block;
  POPSTACK (block_stack);

  /* Pop the stack slot nesting and free any slots at this level.  */
  pop_temp_slots ();
}


/* End a binding contour.
   VARS is the chain of VAR_DECL nodes for the variables bound
   in this contour.  MARK_ENDS is nonzer if we should put a note
   at the beginning and end of this binding contour.
   DONT_JUMP_IN is nonzero if it is not valid to jump into this
   contour.  */

static void
bc_expand_end_bindings (vars, mark_ends, dont_jump_in)
     tree vars;
     int mark_ends;
     int dont_jump_in;
{
  struct nesting *thisbind = nesting_stack;
  tree decl;

  if (warn_unused)
    for (decl = vars; decl; decl = TREE_CHAIN (decl))
      if (! TREE_USED (TREE_VALUE (decl)) && TREE_CODE (TREE_VALUE (decl)) == VAR_DECL)
	warning_with_decl (decl, "unused variable `%s'");

  if (thisbind->exit_label)
    bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thisbind->exit_label));

  /* Pop block/bindings off stack */
  POPSTACK (block_stack);
}

/* Generate RTL for the automatic variable declaration DECL.
   (Other kinds of declarations are simply ignored if seen here.)  */

void
expand_decl (decl)
     register tree decl;
{
  struct nesting *thisblock = block_stack;
  tree type;

  if (output_bytecode)
    {
      bc_expand_decl (decl, 0);
      return;
    }

  type = TREE_TYPE (decl);

  /* Only automatic variables need any expansion done.
     Static and external variables, and external functions,
     will be handled by `assemble_variable' (called from finish_decl).
     TYPE_DECL and CONST_DECL require nothing.
     PARM_DECLs are handled in `assign_parms'.  */

  if (TREE_CODE (decl) != VAR_DECL)
    return;
  if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
    return;

  /* Create the RTL representation for the variable.  */

  if (type == error_mark_node)
    DECL_RTL (decl) = gen_rtx (MEM, BLKmode, const0_rtx);
  else if (DECL_SIZE (decl) == 0)
    /* Variable with incomplete type.  */
    {
      if (DECL_INITIAL (decl) == 0)
	/* Error message was already done; now avoid a crash.  */
	DECL_RTL (decl) = assign_stack_temp (DECL_MODE (decl), 0, 1);
      else
	/* An initializer is going to decide the size of this array.
	   Until we know the size, represent its address with a reg.  */
	DECL_RTL (decl) = gen_rtx (MEM, BLKmode, gen_reg_rtx (Pmode));
      MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (type);
    }
  else if (DECL_MODE (decl) != BLKmode
	   /* If -ffloat-store, don't put explicit float vars
	      into regs.  */
	   && !(flag_float_store
		&& TREE_CODE (type) == REAL_TYPE)
	   && ! TREE_THIS_VOLATILE (decl)
	   && ! TREE_ADDRESSABLE (decl)
	   && (DECL_REGISTER (decl) || ! obey_regdecls))
    {
      /* Automatic variable that can go in a register.  */
      int unsignedp = TREE_UNSIGNED (type);
      enum machine_mode reg_mode
	= promote_mode (type, DECL_MODE (decl), &unsignedp, 0);

      DECL_RTL (decl) = gen_reg_rtx (reg_mode);
      mark_user_reg (DECL_RTL (decl));

      if (TREE_CODE (type) == POINTER_TYPE)
	mark_reg_pointer (DECL_RTL (decl),
			  (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl)))
			   / BITS_PER_UNIT));
    }

  else if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST
	   && ! (flag_stack_check && ! STACK_CHECK_BUILTIN
		 && (TREE_INT_CST_HIGH (DECL_SIZE (decl)) != 0
		     || (TREE_INT_CST_LOW (DECL_SIZE (decl))
			 > STACK_CHECK_MAX_VAR_SIZE * BITS_PER_UNIT))))
    {
      /* Variable of fixed size that goes on the stack.  */
      rtx oldaddr = 0;
      rtx addr;

      /* If we previously made RTL for this decl, it must be an array
	 whose size was determined by the initializer.
	 The old address was a register; set that register now
	 to the proper address.  */
      if (DECL_RTL (decl) != 0)
	{
	  if (GET_CODE (DECL_RTL (decl)) != MEM
	      || GET_CODE (XEXP (DECL_RTL (decl), 0)) != REG)
	    abort ();
	  oldaddr = XEXP (DECL_RTL (decl), 0);
	}

      DECL_RTL (decl)
	= assign_stack_temp (DECL_MODE (decl),
			     ((TREE_INT_CST_LOW (DECL_SIZE (decl))
			       + BITS_PER_UNIT - 1)
			      / BITS_PER_UNIT),
			     1);
      MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));

      /* Set alignment we actually gave this decl.  */
      DECL_ALIGN (decl) = (DECL_MODE (decl) == BLKmode ? BIGGEST_ALIGNMENT
			   : GET_MODE_BITSIZE (DECL_MODE (decl)));

      if (oldaddr)
	{
	  addr = force_operand (XEXP (DECL_RTL (decl), 0), oldaddr);
	  if (addr != oldaddr)
	    emit_move_insn (oldaddr, addr);
	}

      /* If this is a memory ref that contains aggregate components,
	 mark it as such for cse and loop optimize.  */
      MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));
#if 0
      /* If this is in memory because of -ffloat-store,
	 set the volatile bit, to prevent optimizations from
	 undoing the effects.  */
      if (flag_float_store && TREE_CODE (type) == REAL_TYPE)
	MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
#endif
    }
  else
    /* Dynamic-size object: must push space on the stack.  */
    {
      rtx address, size;

      /* Record the stack pointer on entry to block, if have
	 not already done so.  */
      if (thisblock->data.block.stack_level == 0)
	{
	  do_pending_stack_adjust ();
	  emit_stack_save (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
			   &thisblock->data.block.stack_level,
			   thisblock->data.block.first_insn);
	  stack_block_stack = thisblock;
	}

      /* Compute the variable's size, in bytes.  */
      size = expand_expr (size_binop (CEIL_DIV_EXPR,
				      DECL_SIZE (decl),
				      size_int (BITS_PER_UNIT)),
			  NULL_RTX, VOIDmode, 0);
      free_temp_slots ();

      /* Allocate space on the stack for the variable.  Note that
	 DECL_ALIGN says how the variable is to be aligned and we 
	 cannot use it to conclude anything about the alignment of
	 the size.  */
      address = allocate_dynamic_stack_space (size, NULL_RTX,
					      TYPE_ALIGN (TREE_TYPE (decl)));

      /* Reference the variable indirect through that rtx.  */
      DECL_RTL (decl) = gen_rtx (MEM, DECL_MODE (decl), address);

      /* If this is a memory ref that contains aggregate components,
	 mark it as such for cse and loop optimize.  */
      MEM_IN_STRUCT_P (DECL_RTL (decl)) = AGGREGATE_TYPE_P (TREE_TYPE (decl));

      /* Indicate the alignment we actually gave this variable.  */
#ifdef STACK_BOUNDARY
      DECL_ALIGN (decl) = STACK_BOUNDARY;
#else
      DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
#endif
    }

  if (TREE_THIS_VOLATILE (decl))
    MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
#if 0 /* A variable is not necessarily unchanging
	 just because it is const.  RTX_UNCHANGING_P
	 means no change in the function,
	 not merely no change in the variable's scope.
	 It is correct to set RTX_UNCHANGING_P if the variable's scope
	 is the whole function.  There's no convenient way to test that.  */
  if (TREE_READONLY (decl))
    RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
#endif

  /* If doing stupid register allocation, make sure life of any
     register variable starts here, at the start of its scope.  */

  if (obey_regdecls)
    use_variable (DECL_RTL (decl));
}


/* Generate code for the automatic variable declaration DECL.  For
   most variables this just means we give it a stack offset.  The
   compiler sometimes emits cleanups without variables and we will
   have to deal with those too.  */

static void
bc_expand_decl (decl, cleanup)
     tree decl;
     tree cleanup;
{
  tree type;

  if (!decl)
    {
      /* A cleanup with no variable.  */
      if (!cleanup)
	abort ();

      return;
    }

  /* Only auto variables need any work.  */
  if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl) || DECL_EXTERNAL (decl))
    return;

  type = TREE_TYPE (decl);

  if (type == error_mark_node)
    DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0);

  else if (DECL_SIZE (decl) == 0)

    /* Variable with incomplete type.  The stack offset herein will be
       fixed later in expand_decl_init.  */
    DECL_RTL (decl) = bc_gen_rtx ((char *) 0, 0, (struct bc_label *) 0);

  else if (TREE_CONSTANT (DECL_SIZE (decl)))
    {
      DECL_RTL (decl) = bc_allocate_local (TREE_INT_CST_LOW (DECL_SIZE (decl)) / BITS_PER_UNIT,
					   DECL_ALIGN (decl));
    }
  else
    DECL_RTL (decl) = bc_allocate_variable_array (DECL_SIZE (decl));
}

/* Emit code to perform the initialization of a declaration DECL.  */

void
expand_decl_init (decl)
     tree decl;
{
  int was_used = TREE_USED (decl);

  if (output_bytecode)
    {
      bc_expand_decl_init (decl);
      return;
    }

  /* If this is a CONST_DECL, we don't have to generate any code, but
     if DECL_INITIAL is a constant, call expand_expr to force TREE_CST_RTL
     to be set while in the obstack containing the constant.  If we don't
     do this, we can lose if we have functions nested three deep and the middle
     function makes a CONST_DECL whose DECL_INITIAL is a STRING_CST while
     the innermost function is the first to expand that STRING_CST.  */
  if (TREE_CODE (decl) == CONST_DECL)
    {
      if (DECL_INITIAL (decl) && TREE_CONSTANT (DECL_INITIAL (decl)))
	expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
		     EXPAND_INITIALIZER);
      return;
    }

  if (TREE_STATIC (decl))
    return;

  /* Compute and store the initial value now.  */

  if (DECL_INITIAL (decl) == error_mark_node)
    {
      enum tree_code code = TREE_CODE (TREE_TYPE (decl));
      if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
	  || code == POINTER_TYPE)
	expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
			   0, 0);
      emit_queue ();
    }
  else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
    {
      emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
      expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
      emit_queue ();
    }

  /* Don't let the initialization count as "using" the variable.  */
  TREE_USED (decl) = was_used;

  /* Free any temporaries we made while initializing the decl.  */
  preserve_temp_slots (NULL_RTX);
  free_temp_slots ();
}

/* Expand initialization for variable-sized types. Allocate array
   using newlocalSI and set local variable, which is a pointer to the
   storage.  */

static void
bc_expand_variable_local_init (decl)
     tree decl;
{
  /* Evaluate size expression and coerce to SI */
  bc_expand_expr (DECL_SIZE (decl));

  /* Type sizes are always (?) of TREE_CODE INTEGER_CST, so
     no coercion is necessary (?) */

/*  emit_typecode_conversion (preferred_typecode (TYPE_MODE (DECL_SIZE (decl)),
						TREE_UNSIGNED (DECL_SIZE (decl))), SIcode); */

  /* Emit code to allocate array */
  bc_emit_instruction (newlocalSI);

  /* Store array pointer in local variable. This is the only instance
     where we actually want the address of the pointer to the
     variable-size block, rather than the pointer itself.  We avoid
     using expand_address() since that would cause the pointer to be
     pushed rather than its address. Hence the hard-coded reference;
     notice also that the variable is always local (no global
     variable-size type variables).  */

  bc_load_localaddr (DECL_RTL (decl));
  bc_emit_instruction (storeP);
}


/* Emit code to initialize a declaration.  */

static void
bc_expand_decl_init (decl)
     tree decl;
{
  int org_stack_depth;

  /* Statical initializers are handled elsewhere */

  if (TREE_STATIC (decl))
    return;

  /* Memory original stack depth */
  org_stack_depth = stack_depth;

  /* If the type is variable-size, we first create its space (we ASSUME
     it CAN'T be static).  We do this regardless of whether there's an
     initializer assignment or not.  */

  if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
    bc_expand_variable_local_init (decl);

  /* Expand initializer assignment */
  if (DECL_INITIAL (decl) == error_mark_node)
    {
      enum tree_code code = TREE_CODE (TREE_TYPE (decl));

      if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
	  || code == POINTER_TYPE)

	expand_assignment (TREE_TYPE (decl), decl, 0, 0);
    }
  else if (DECL_INITIAL (decl))
    expand_assignment (TREE_TYPE (decl), decl, 0, 0);

  /* Restore stack depth */
  if (org_stack_depth > stack_depth)
    abort ();

  bc_adjust_stack (stack_depth - org_stack_depth);
}
 

/* CLEANUP is an expression to be executed at exit from this binding contour;
   for example, in C++, it might call the destructor for this variable.

   We wrap CLEANUP in an UNSAVE_EXPR node, so that we can expand the
   CLEANUP multiple times, and have the correct semantics.  This
   happens in exception handling, for gotos, returns, breaks that
   leave the current scope.

   If CLEANUP is nonzero and DECL is zero, we record a cleanup
   that is not associated with any particular variable.   */

int
expand_decl_cleanup (decl, cleanup)
     tree decl, cleanup;
{
  struct nesting *thisblock = block_stack;

  /* Error if we are not in any block.  */
  if (thisblock == 0)
    return 0;

  /* Record the cleanup if there is one.  */

  if (cleanup != 0)
    {
      tree t;
      rtx seq;
      tree *cleanups = &thisblock->data.block.cleanups;
      int cond_context = conditional_context ();

      if (cond_context)
	{
	  rtx flag = gen_reg_rtx (word_mode);
	  rtx set_flag_0;
	  tree cond;

	  start_sequence ();
	  emit_move_insn (flag, const0_rtx);
	  set_flag_0 = get_insns ();
	  end_sequence ();

	  thisblock->data.block.last_unconditional_cleanup
	    = emit_insns_after (set_flag_0,
				thisblock->data.block.last_unconditional_cleanup);

	  emit_move_insn (flag, const1_rtx);

	  /* All cleanups must be on the function_obstack.  */
	  push_obstacks_nochange ();
	  resume_temporary_allocation ();

	  cond = build_decl (VAR_DECL, NULL_TREE, type_for_mode (word_mode, 1));
	  DECL_RTL (cond) = flag;

	  /* Conditionalize the cleanup.  */
	  cleanup = build (COND_EXPR, void_type_node,
			   truthvalue_conversion (cond),
			   cleanup, integer_zero_node);
	  cleanup = fold (cleanup);

	  pop_obstacks ();

	  cleanups = thisblock->data.block.cleanup_ptr;
	}

      /* All cleanups must be on the function_obstack.  */
      push_obstacks_nochange ();
      resume_temporary_allocation ();
      cleanup = unsave_expr (cleanup);
      pop_obstacks ();

      t = *cleanups = temp_tree_cons (decl, cleanup, *cleanups);

      if (! cond_context)
	/* If this block has a cleanup, it belongs in stack_block_stack.  */
	stack_block_stack = thisblock;

      if (cond_context)
	{
	  start_sequence ();
	}

      /* If this was optimized so that there is no exception region for the
	 cleanup, then mark the TREE_LIST node, so that we can later tell
	 if we need to call expand_eh_region_end.  */
      if (! using_eh_for_cleanups_p
	  || expand_eh_region_start_tree (decl, cleanup))
	TREE_ADDRESSABLE (t) = 1;
      /* If that started a new EH region, we're in a new block.  */
      thisblock = block_stack;

      if (cond_context)
	{
	  seq = get_insns ();
	  end_sequence ();
	  if (seq)
	    thisblock->data.block.last_unconditional_cleanup
	      = emit_insns_after (seq,
				  thisblock->data.block.last_unconditional_cleanup);
	}
      else
	{
	  thisblock->data.block.last_unconditional_cleanup
	    = get_last_insn ();
	  thisblock->data.block.cleanup_ptr = &thisblock->data.block.cleanups;
	}
    }
  return 1;
}

/* Like expand_decl_cleanup, but suppress generating an exception handler
   to perform the cleanup.  */

int
expand_decl_cleanup_no_eh (decl, cleanup)
     tree decl, cleanup;
{
  int save_eh = using_eh_for_cleanups_p;
  using_eh_for_cleanups_p = 0;
  expand_decl_cleanup (decl, cleanup);
  using_eh_for_cleanups_p = save_eh;
}

/* Arrange for the top element of the dynamic cleanup chain to be
   popped if we exit the current binding contour.  DECL is the
   associated declaration, if any, otherwise NULL_TREE.  If the
   current contour is left via an exception, then __sjthrow will pop
   the top element off the dynamic cleanup chain.  The code that
   avoids doing the action we push into the cleanup chain in the
   exceptional case is contained in expand_cleanups.

   This routine is only used by expand_eh_region_start, and that is
   the only way in which an exception region should be started.  This
   routine is only used when using the setjmp/longjmp codegen method
   for exception handling.  */

int
expand_dcc_cleanup (decl)
     tree decl;
{
  struct nesting *thisblock = block_stack;
  tree cleanup;

  /* Error if we are not in any block.  */
  if (thisblock == 0)
    return 0;

  /* Record the cleanup for the dynamic handler chain.  */

  /* All cleanups must be on the function_obstack.  */
  push_obstacks_nochange ();
  resume_temporary_allocation ();
  cleanup = make_node (POPDCC_EXPR);
  pop_obstacks ();

  /* Add the cleanup in a manner similar to expand_decl_cleanup.  */
  thisblock->data.block.cleanups
    = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);

  /* If this block has a cleanup, it belongs in stack_block_stack.  */
  stack_block_stack = thisblock;
  return 1;
}

/* Arrange for the top element of the dynamic handler chain to be
   popped if we exit the current binding contour.  DECL is the
   assciated declaration, if any, otherwise NULL_TREE.  If the current
   contour is left via an exception, then __sjthrow will pop the top
   element off the dynamic handler chain.  The code that avoids doing
   the action we push into the handler chain in the exceptional case
   is contained in expand_cleanups.

   This routine is only used by expand_eh_region_start, and that is
   the only way in which an exception region should be started.  This
   routine is only used when using the setjmp/longjmp codegen method
   for exception handling.  */

int
expand_dhc_cleanup (decl)
     tree decl;
{
  struct nesting *thisblock = block_stack;
  tree cleanup;

  /* Error if we are not in any block.  */
  if (thisblock == 0)
    return 0;

  /* Record the cleanup for the dynamic handler chain.  */

  /* All cleanups must be on the function_obstack.  */
  push_obstacks_nochange ();
  resume_temporary_allocation ();
  cleanup = make_node (POPDHC_EXPR);
  pop_obstacks ();

  /* Add the cleanup in a manner similar to expand_decl_cleanup.  */
  thisblock->data.block.cleanups
    = temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);

  /* If this block has a cleanup, it belongs in stack_block_stack.  */
  stack_block_stack = thisblock;
  return 1;
}

/* DECL is an anonymous union.  CLEANUP is a cleanup for DECL.
   DECL_ELTS is the list of elements that belong to DECL's type.
   In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup.  */

void
expand_anon_union_decl (decl, cleanup, decl_elts)
     tree decl, cleanup, decl_elts;
{
  struct nesting *thisblock = block_stack;
  rtx x;

  expand_decl (decl);
  expand_decl_cleanup (decl, cleanup);
  x = DECL_RTL (decl);

  while (decl_elts)
    {
      tree decl_elt = TREE_VALUE (decl_elts);
      tree cleanup_elt = TREE_PURPOSE (decl_elts);
      enum machine_mode mode = TYPE_MODE (TREE_TYPE (decl_elt));

      /* Propagate the union's alignment to the elements.  */
      DECL_ALIGN (decl_elt) = DECL_ALIGN (decl);

      /* If the element has BLKmode and the union doesn't, the union is
         aligned such that the element doesn't need to have BLKmode, so
         change the element's mode to the appropriate one for its size.  */
      if (mode == BLKmode && DECL_MODE (decl) != BLKmode)
	DECL_MODE (decl_elt) = mode
	  = mode_for_size (TREE_INT_CST_LOW (DECL_SIZE (decl_elt)),
			   MODE_INT, 1);

      /* (SUBREG (MEM ...)) at RTL generation time is invalid, so we
         instead create a new MEM rtx with the proper mode.  */
      if (GET_CODE (x) == MEM)
	{
	  if (mode == GET_MODE (x))
	    DECL_RTL (decl_elt) = x;
	  else
	    {
	      DECL_RTL (decl_elt) = gen_rtx (MEM, mode, copy_rtx (XEXP (x, 0)));
	      MEM_IN_STRUCT_P (DECL_RTL (decl_elt)) = MEM_IN_STRUCT_P (x);
	      RTX_UNCHANGING_P (DECL_RTL (decl_elt)) = RTX_UNCHANGING_P (x);
	    }
	}
      else if (GET_CODE (x) == REG)
	{
	  if (mode == GET_MODE (x))
	    DECL_RTL (decl_elt) = x;
	  else
	    DECL_RTL (decl_elt) = gen_rtx (SUBREG, mode, x, 0);
	}
      else
	abort ();

      /* Record the cleanup if there is one.  */

      if (cleanup != 0)
	thisblock->data.block.cleanups
	  = temp_tree_cons (decl_elt, cleanup_elt,
			    thisblock->data.block.cleanups);

      decl_elts = TREE_CHAIN (decl_elts);
    }
}

/* Expand a list of cleanups LIST.
   Elements may be expressions or may be nested lists.

   If DONT_DO is nonnull, then any list-element
   whose TREE_PURPOSE matches DONT_DO is omitted.
   This is sometimes used to avoid a cleanup associated with
   a value that is being returned out of the scope.

   If IN_FIXUP is non-zero, we are generating this cleanup for a fixup
   goto and handle protection regions specially in that case.

   If REACHABLE, we emit code, otherwise just inform the exception handling
   code about this finalization.  */

static void
expand_cleanups (list, dont_do, in_fixup, reachable)
     tree list;
     tree dont_do;
     int in_fixup;
     int reachable;
{
  tree tail;
  for (tail = list; tail; tail = TREE_CHAIN (tail))
    if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
      {
	if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
	  expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable);
	else
	  {
	    if (! in_fixup)
	      {
		tree cleanup = TREE_VALUE (tail);

		/* See expand_d{h,c}c_cleanup for why we avoid this.  */
		if (TREE_CODE (cleanup) != POPDHC_EXPR
		    && TREE_CODE (cleanup) != POPDCC_EXPR
		    /* See expand_eh_region_start_tree for this case.  */
		    && ! TREE_ADDRESSABLE (tail))
		  {
		    cleanup = protect_with_terminate (cleanup);
		    expand_eh_region_end (cleanup);
		  }
	      }

	    if (reachable)
	      {
		/* Cleanups may be run multiple times.  For example,
		   when exiting a binding contour, we expand the
		   cleanups associated with that contour.  When a goto
		   within that binding contour has a target outside that
		   contour, it will expand all cleanups from its scope to
		   the target.  Though the cleanups are expanded multiple
		   times, the control paths are non-overlapping so the
		   cleanups will not be executed twice.  */

		/* We may need to protect fixups with rethrow regions.  */
		int protect = (in_fixup && ! TREE_ADDRESSABLE (tail));
		if (protect)
		  expand_fixup_region_start ();
		expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
		if (protect)
		  expand_fixup_region_end (TREE_VALUE (tail));
		free_temp_slots ();
	      }
	  }
      }
}

/* Mark when the context we are emitting RTL for as a conditional
   context, so that any cleanup actions we register with
   expand_decl_init will be properly conditionalized when those
   cleanup actions are later performed.  Must be called before any
   expression (tree) is expanded that is within a contidional context.  */

void
start_cleanup_deferal ()
{
  /* block_stack can be NULL if we are inside the parameter list.  It is
     OK to do nothing, because cleanups aren't possible here.  */
  if (block_stack)
    ++block_stack->data.block.conditional_code;
}

/* Mark the end of a conditional region of code.  Because cleanup
   deferals may be nested, we may still be in a conditional region
   after we end the currently deferred cleanups, only after we end all
   deferred cleanups, are we back in unconditional code.  */

void
end_cleanup_deferal ()
{
  /* block_stack can be NULL if we are inside the parameter list.  It is
     OK to do nothing, because cleanups aren't possible here.  */
  if (block_stack)
    --block_stack->data.block.conditional_code;
}

/* Move all cleanups from the current block_stack
   to the containing block_stack, where they are assumed to
   have been created.  If anything can cause a temporary to
   be created, but not expanded for more than one level of
   block_stacks, then this code will have to change.  */

void
move_cleanups_up ()
{
  struct nesting *block = block_stack;
  struct nesting *outer = block->next;

  outer->data.block.cleanups
    = chainon (block->data.block.cleanups,
	       outer->data.block.cleanups);
  block->data.block.cleanups = 0;
}

tree
last_cleanup_this_contour ()
{
  if (block_stack == 0)
    return 0;

  return block_stack->data.block.cleanups;
}

/* Return 1 if there are any pending cleanups at this point.
   If THIS_CONTOUR is nonzero, check the current contour as well.
   Otherwise, look only at the contours that enclose this one.  */

int
any_pending_cleanups (this_contour)
     int this_contour;
{
  struct nesting *block;

  if (block_stack == 0)
    return 0;

  if (this_contour && block_stack->data.block.cleanups != NULL)
    return 1;
  if (block_stack->data.block.cleanups == 0
      && block_stack->data.block.outer_cleanups == 0)
    return 0;

  for (block = block_stack->next; block; block = block->next)
    if (block->data.block.cleanups != 0)
      return 1;

  return 0;
}

/* Enter a case (Pascal) or switch (C) statement.
   Push a block onto case_stack and nesting_stack
   to accumulate the case-labels that are seen
   and to record the labels generated for the statement.

   EXIT_FLAG is nonzero if `exit_something' should exit this case stmt.
   Otherwise, this construct is transparent for `exit_something'.

   EXPR is the index-expression to be dispatched on.
   TYPE is its nominal type.  We could simply convert EXPR to this type,
   but instead we take short cuts.  */

void
expand_start_case (exit_flag, expr, type, printname)
     int exit_flag;
     tree expr;
     tree type;
     char *printname;
{
  register struct nesting *thiscase = ALLOC_NESTING ();

  /* Make an entry on case_stack for the case we are entering.  */

  thiscase->next = case_stack;
  thiscase->all = nesting_stack;
  thiscase->depth = ++nesting_depth;
  thiscase->exit_label = exit_flag ? gen_label_rtx () : 0;
  thiscase->data.case_stmt.case_list = 0;
  thiscase->data.case_stmt.index_expr = expr;
  thiscase->data.case_stmt.nominal_type = type;
  thiscase->data.case_stmt.default_label = 0;
  thiscase->data.case_stmt.num_ranges = 0;
  thiscase->data.case_stmt.printname = printname;
  thiscase->data.case_stmt.seenlabel = 0;
  case_stack = thiscase;
  nesting_stack = thiscase;

  if (output_bytecode)
    {
      bc_expand_start_case (thiscase, expr, type, printname);
      return;
    }

  do_pending_stack_adjust ();

  /* Make sure case_stmt.start points to something that won't
     need any transformation before expand_end_case.  */
  if (GET_CODE (get_last_insn ()) != NOTE)
    emit_note (NULL_PTR, NOTE_INSN_DELETED);

  thiscase->data.case_stmt.start = get_last_insn ();

  start_cleanup_deferal ();
}


/* Enter a case statement. It is assumed that the caller has pushed
   the current context onto the case stack.  */

static void
bc_expand_start_case (thiscase, expr, type, printname)
     struct nesting *thiscase;
     tree expr;
     tree type;
     char *printname;
{
  bc_expand_expr (expr);
  bc_expand_conversion (TREE_TYPE (expr), type);

  /* For cases, the skip is a place we jump to that's emitted after
     the size of the jump table is known.  */

  thiscase->data.case_stmt.skip_label = gen_label_rtx ();
  bc_emit_bytecode (jump);
  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label));

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif
}


/* Start a "dummy case statement" within which case labels are invalid
   and are not connected to any larger real case statement.
   This can be used if you don't want to let a case statement jump
   into the middle of certain kinds of constructs.  */

void
expand_start_case_dummy ()
{
  register struct nesting *thiscase = ALLOC_NESTING ();

  /* Make an entry on case_stack for the dummy.  */

  thiscase->next = case_stack;
  thiscase->all = nesting_stack;
  thiscase->depth = ++nesting_depth;
  thiscase->exit_label = 0;
  thiscase->data.case_stmt.case_list = 0;
  thiscase->data.case_stmt.start = 0;
  thiscase->data.case_stmt.nominal_type = 0;
  thiscase->data.case_stmt.default_label = 0;
  thiscase->data.case_stmt.num_ranges = 0;
  case_stack = thiscase;
  nesting_stack = thiscase;
  start_cleanup_deferal ();
}

/* End a dummy case statement.  */

void
expand_end_case_dummy ()
{
  end_cleanup_deferal ();
  POPSTACK (case_stack);
}

/* Return the data type of the index-expression
   of the innermost case statement, or null if none.  */

tree
case_index_expr_type ()
{
  if (case_stack)
    return TREE_TYPE (case_stack->data.case_stmt.index_expr);
  return 0;
}

/* Accumulate one case or default label inside a case or switch statement.
   VALUE is the value of the case (a null pointer, for a default label).
   The function CONVERTER, when applied to arguments T and V,
   converts the value V to the type T.

   If not currently inside a case or switch statement, return 1 and do
   nothing.  The caller will print a language-specific error message.
   If VALUE is a duplicate or overlaps, return 2 and do nothing
   except store the (first) duplicate node in *DUPLICATE.
   If VALUE is out of range, return 3 and do nothing.
   If we are jumping into the scope of a cleanup or var-sized array, return 5.
   Return 0 on success.

   Extended to handle range statements.  */

int
pushcase (value, converter, label, duplicate)
     register tree value;
     tree (*converter) PROTO((tree, tree));
     register tree label;
     tree *duplicate;
{
  register struct case_node **l;
  register struct case_node *n;
  tree index_type;
  tree nominal_type;

  if (output_bytecode)
    return bc_pushcase (value, label);

  /* Fail if not inside a real case statement.  */
  if (! (case_stack && case_stack->data.case_stmt.start))
    return 1;

  if (stack_block_stack
      && stack_block_stack->depth > case_stack->depth)
    return 5;

  index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
  nominal_type = case_stack->data.case_stmt.nominal_type;

  /* If the index is erroneous, avoid more problems: pretend to succeed.  */
  if (index_type == error_mark_node)
    return 0;

  /* Convert VALUE to the type in which the comparisons are nominally done.  */
  if (value != 0)
    value = (*converter) (nominal_type, value);

  /* If this is the first label, warn if any insns have been emitted.  */
  if (case_stack->data.case_stmt.seenlabel == 0)
    {
      rtx insn;
      for (insn = case_stack->data.case_stmt.start;
	   insn;
	   insn = NEXT_INSN (insn))
	{
	  if (GET_CODE (insn) == CODE_LABEL)
	    break;
	  if (GET_CODE (insn) != NOTE
	      && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
	    {
	      warning ("unreachable code at beginning of %s",
		       case_stack->data.case_stmt.printname);
	      break;
	    }
	}
    }
  case_stack->data.case_stmt.seenlabel = 1;

  /* Fail if this value is out of range for the actual type of the index
     (which may be narrower than NOMINAL_TYPE).  */
  if (value != 0 && ! int_fits_type_p (value, index_type))
    return 3;

  /* Fail if this is a duplicate or overlaps another entry.  */
  if (value == 0)
    {
      if (case_stack->data.case_stmt.default_label != 0)
	{
	  *duplicate = case_stack->data.case_stmt.default_label;
	  return 2;
	}
      case_stack->data.case_stmt.default_label = label;
    }
  else
    return add_case_node (value, value, label, duplicate);

  expand_label (label);
  return 0;
}

/* Like pushcase but this case applies to all values between VALUE1 and
   VALUE2 (inclusive).  If VALUE1 is NULL, the range starts at the lowest
   value of the index type and ends at VALUE2.  If VALUE2 is NULL, the range
   starts at VALUE1 and ends at the highest value of the index type.
   If both are NULL, this case applies to all values.

   The return value is the same as that of pushcase but there is one
   additional error code: 4 means the specified range was empty.  */

int
pushcase_range (value1, value2, converter, label, duplicate)
     register tree value1, value2;
     tree (*converter) PROTO((tree, tree));
     register tree label;
     tree *duplicate;
{
  register struct case_node **l;
  register struct case_node *n;
  tree index_type;
  tree nominal_type;

  /* Fail if not inside a real case statement.  */
  if (! (case_stack && case_stack->data.case_stmt.start))
    return 1;

  if (stack_block_stack
      && stack_block_stack->depth > case_stack->depth)
    return 5;

  index_type = TREE_TYPE (case_stack->data.case_stmt.index_expr);
  nominal_type = case_stack->data.case_stmt.nominal_type;

  /* If the index is erroneous, avoid more problems: pretend to succeed.  */
  if (index_type == error_mark_node)
    return 0;

  /* If this is the first label, warn if any insns have been emitted.  */
  if (case_stack->data.case_stmt.seenlabel == 0)
    {
      rtx insn;
      for (insn = case_stack->data.case_stmt.start;
	   insn;
	   insn = NEXT_INSN (insn))
	{
	  if (GET_CODE (insn) == CODE_LABEL)
	    break;
	  if (GET_CODE (insn) != NOTE
	      && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn)) != USE))
	    {
	      warning ("unreachable code at beginning of %s",
		       case_stack->data.case_stmt.printname);
	      break;
	    }
	}
    }
  case_stack->data.case_stmt.seenlabel = 1;

  /* Convert VALUEs to type in which the comparisons are nominally done
     and replace any unspecified value with the corresponding bound.  */
  if (value1 == 0)
    value1 = TYPE_MIN_VALUE (index_type);
  if (value2 == 0)
    value2 = TYPE_MAX_VALUE (index_type);

  /* Fail if the range is empty.  Do this before any conversion since
     we want to allow out-of-range empty ranges.  */
  if (tree_int_cst_lt (value2, value1))
    return 4;

  value1 = (*converter) (nominal_type, value1);
  value2 = (*converter) (nominal_type, value2);

  /* Fail if these values are out of range.  */
  if (TREE_CONSTANT_OVERFLOW (value1)
      || ! int_fits_type_p (value1, index_type))
    return 3;

  if (TREE_CONSTANT_OVERFLOW (value2)
      || ! int_fits_type_p (value2, index_type))
    return 3;

  return add_case_node (value1, value2, label, duplicate);
}

/* Do the actual insertion of a case label for pushcase and pushcase_range
   into case_stack->data.case_stmt.case_list.  Use an AVL tree to avoid
   slowdown for large switch statements.  */

static int
add_case_node (low, high, label, duplicate)
     tree low, high;
     tree label;
     tree *duplicate;
{
  struct case_node *p, **q, *r;

  q = &case_stack->data.case_stmt.case_list;
  p = *q;

  while (r = *q)
    {
      p = r;

      /* Keep going past elements distinctly greater than HIGH.  */
      if (tree_int_cst_lt (high, p->low))
	q = &p->left;

      /* or distinctly less than LOW.  */
      else if (tree_int_cst_lt (p->high, low))
	q = &p->right;

      else
	{
	  /* We have an overlap; this is an error.  */
	  *duplicate = p->code_label;
	  return 2;
	}
    }

  /* Add this label to the chain, and succeed.
     Copy LOW, HIGH so they are on temporary rather than momentary
     obstack and will thus survive till the end of the case statement.  */

  r = (struct case_node *) oballoc (sizeof (struct case_node));
  r->low = copy_node (low);

  /* If the bounds are equal, turn this into the one-value case.  */

  if (tree_int_cst_equal (low, high))
    r->high = r->low;
  else
    {
      r->high = copy_node (high);
      case_stack->data.case_stmt.num_ranges++;
    }

  r->code_label = label;
  expand_label (label);

  *q = r;
  r->parent = p;
  r->left = 0;
  r->right = 0;
  r->balance = 0;

  while (p)
    {
      struct case_node *s;

      if (r == p->left)
	{
	  int b;

	  if (! (b = p->balance))
	    /* Growth propagation from left side.  */
	    p->balance = -1;
	  else if (b < 0)
	    {
	      if (r->balance < 0)
		{
		  /* R-Rotation */
		  if (p->left = s = r->right)
		    s->parent = p;

		  r->right = p;
		  p->balance = 0;
		  r->balance = 0;
		  s = p->parent;
		  p->parent = r;

		  if (r->parent = s)
		    {
		      if (s->left == p)
			s->left = r;
		      else
			s->right = r;
		    }
		  else
		    case_stack->data.case_stmt.case_list = r;
		}
	      else
		/* r->balance == +1 */
		{
		  /* LR-Rotation */

		  int b2;
		  struct case_node *t = r->right;

		  if (p->left = s = t->right)
		    s->parent = p;

		  t->right = p;
		  if (r->right = s = t->left)
		    s->parent = r;

		  t->left = r;
		  b = t->balance;
		  b2 = b < 0;
		  p->balance = b2;
		  b2 = -b2 - b;
		  r->balance = b2;
		  t->balance = 0;
		  s = p->parent;
		  p->parent = t;
		  r->parent = t;

		  if (t->parent = s)
		    {
		      if (s->left == p)
			s->left = t;
		      else
			s->right = t;
		    }
		  else
		    case_stack->data.case_stmt.case_list = t;
		}
	      break;
	    }

	  else
	    {
	      /* p->balance == +1; growth of left side balances the node.  */
	      p->balance = 0;
	      break;
	    }
	}
      else
	/* r == p->right */
	{
	  int b;

	  if (! (b = p->balance))
	    /* Growth propagation from right side.  */
	    p->balance++;
	  else if (b > 0)
	    {
	      if (r->balance > 0)
		{
		  /* L-Rotation */

		  if (p->right = s = r->left)
		    s->parent = p;

		  r->left = p;
		  p->balance = 0;
		  r->balance = 0;
		  s = p->parent;
		  p->parent = r;
		  if (r->parent = s)
		    {
		      if (s->left == p)
			s->left = r;
		      else
			s->right = r;
		    }

		  else
		    case_stack->data.case_stmt.case_list = r;
		}

	      else
		/* r->balance == -1 */
		{
		  /* RL-Rotation */
		  int b2;
		  struct case_node *t = r->left;

		  if (p->right = s = t->left)
		    s->parent = p;

		  t->left = p;

		  if (r->left = s = t->right)
		    s->parent = r;

		  t->right = r;
		  b = t->balance;
		  b2 = b < 0;
		  r->balance = b2;
		  b2 = -b2 - b;
		  p->balance = b2;
		  t->balance = 0;
		  s = p->parent;
		  p->parent = t;
		  r->parent = t;

		  if (t->parent = s)
		    {
		      if (s->left == p)
			s->left = t;
		      else
			s->right = t;
		    }

		  else
		    case_stack->data.case_stmt.case_list = t;
		}
	      break;
	    }
	  else
	    {
	      /* p->balance == -1; growth of right side balances the node.  */
	      p->balance = 0;
	      break;
	    }
	}

      r = p;
      p = p->parent;
    }

  return 0;
}

/* Accumulate one case or default label; VALUE is the value of the
   case, or nil for a default label.  If not currently inside a case,
   return 1 and do nothing.  If VALUE is a duplicate or overlaps, return
   2 and do nothing.  If VALUE is out of range, return 3 and do nothing.
   Return 0 on success.  This function is a leftover from the earlier
   bytecode compiler, which was based on gcc 1.37.  It should be
   merged into pushcase.  */

static int
bc_pushcase (value, label)
     tree value;
     tree label;
{
  struct nesting *thiscase = case_stack;
  struct case_node *case_label, *new_label;

  if (! thiscase)
    return 1;

  /* Fail if duplicate, overlap, or out of type range.  */
  if (value)
    {
      value = convert (thiscase->data.case_stmt.nominal_type, value);
      if (! int_fits_type_p (value, thiscase->data.case_stmt.nominal_type))
	return 3;

      for (case_label = thiscase->data.case_stmt.case_list;
	   case_label->left; case_label = case_label->left)
	if (! tree_int_cst_lt (case_label->left->high, value))
	  break;

      if (case_label != thiscase->data.case_stmt.case_list
	  && ! tree_int_cst_lt (case_label->high, value)
	  || (case_label->left && ! tree_int_cst_lt (value, case_label->left->low)))
	return 2;

      new_label = (struct case_node *) oballoc (sizeof (struct case_node));
      new_label->low = new_label->high = copy_node (value);
      new_label->code_label = label;
      new_label->left = case_label->left;

      case_label->left = new_label;
      thiscase->data.case_stmt.num_ranges++;
    }
  else
    {
      if (thiscase->data.case_stmt.default_label)
	return 2;
      thiscase->data.case_stmt.default_label = label;
    }

  expand_label (label);
  return 0;
}

/* Returns the number of possible values of TYPE.
   Returns -1 if the number is unknown or variable.
   Returns -2 if the number does not fit in a HOST_WIDE_INT.
   Sets *SPARENESS to 2 if TYPE is an ENUMERAL_TYPE whose values
   do not increase monotonically (there may be duplicates);
   to 1 if the values increase monotonically, but not always by 1;
   otherwise sets it to 0.  */

HOST_WIDE_INT
all_cases_count (type, spareness)
     tree type;
     int *spareness;
{
  HOST_WIDE_INT count, count_high = 0;
  *spareness = 0;

  switch (TREE_CODE (type))
    {
      tree t;
    case BOOLEAN_TYPE:
      count = 2;
      break;
    case CHAR_TYPE:
      count = 1 << BITS_PER_UNIT;
      break;
    default:
    case INTEGER_TYPE:
      if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
	  || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST)
	return -1;
      else
	{
	  /* count
	     = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
	     - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + 1
	     but with overflow checking.  */
	  tree mint = TYPE_MIN_VALUE (type);
	  tree maxt = TYPE_MAX_VALUE (type);
	  HOST_WIDE_INT lo, hi;
	  neg_double(TREE_INT_CST_LOW (mint), TREE_INT_CST_HIGH (mint),
		     &lo, &hi);
	  add_double(TREE_INT_CST_LOW (maxt), TREE_INT_CST_HIGH (maxt),
		     lo, hi, &lo, &hi);
	  add_double (lo, hi, 1, 0, &lo, &hi);
	  if (hi != 0 || lo < 0)
	    return -2;
	  count = lo;
	}
      break;
    case ENUMERAL_TYPE:
      count = 0;
      for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t))
	{
	  if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
	      || TREE_CODE (TREE_VALUE (t)) != INTEGER_CST
	      || TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + count
	      != TREE_INT_CST_LOW (TREE_VALUE (t)))
	    *spareness = 1;
	  count++;
	}
      if (*spareness == 1)
	{
	  tree prev = TREE_VALUE (TYPE_VALUES (type));
	  for (t = TYPE_VALUES (type); t = TREE_CHAIN (t), t != NULL_TREE; )
	    {
	      if (! tree_int_cst_lt (prev, TREE_VALUE (t)))
		{
		  *spareness = 2;
		  break;
		}
	      prev = TREE_VALUE (t);
	    }
	  
	}
    }
  return count;
}


#define BITARRAY_TEST(ARRAY, INDEX) \
  ((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
			  & (1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR)))
#define BITARRAY_SET(ARRAY, INDEX) \
  ((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
			  |= 1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR))

/* Set the elements of the bitstring CASES_SEEN (which has length COUNT),
   with the case values we have seen, assuming the case expression
   has the given TYPE.
   SPARSENESS is as determined by all_cases_count.

   The time needed is proportional to COUNT, unless
   SPARSENESS is 2, in which case quadratic time is needed.  */

void
mark_seen_cases (type, cases_seen, count, sparseness)
     tree type;
     unsigned char *cases_seen;
     long count;
     int sparseness;
{
  long i;

  tree next_node_to_try = NULL_TREE;
  long next_node_offset = 0;

  register struct case_node *n, *root = case_stack->data.case_stmt.case_list;
  tree val = make_node (INTEGER_CST);
  TREE_TYPE (val) = type;
  if (! root)
    ; /* Do nothing */
  else if (sparseness == 2)
    {
      tree t;
      HOST_WIDE_INT xlo;

      /* This less efficient loop is only needed to handle
	 duplicate case values (multiple enum constants
	 with the same value).  */
      TREE_TYPE (val) = TREE_TYPE (root->low);
      for (t = TYPE_VALUES (type), xlo = 0;  t != NULL_TREE;
	   t = TREE_CHAIN (t), xlo++)
	{
	  TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (TREE_VALUE (t));
	  TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (TREE_VALUE (t));
	  n = root;
	  do
	    {
	      /* Keep going past elements distinctly greater than VAL.  */
	      if (tree_int_cst_lt (val, n->low))
		n = n->left;
	
	      /* or distinctly less than VAL.  */
	      else if (tree_int_cst_lt (n->high, val))
		n = n->right;
	
	      else
		{
		  /* We have found a matching range.  */
		  BITARRAY_SET (cases_seen, xlo);
		  break;
		}
	    }
	  while (n);
	}
    }
  else
    {
      if (root->left)
	case_stack->data.case_stmt.case_list = root = case_tree2list (root, 0);
      for (n = root; n; n = n->right)
	{
	  TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low);
	  TREE_INT_CST_HIGH (val) = TREE_INT_CST_HIGH (n->low);
	  while ( ! tree_int_cst_lt (n->high, val))
	    {
	      /* Calculate (into xlo) the "offset" of the integer (val).
		 The element with lowest value has offset 0, the next smallest
		 element has offset 1, etc.  */

	      HOST_WIDE_INT xlo, xhi;
	      tree t;
	      if (sparseness && TYPE_VALUES (type) != NULL_TREE)
		{
		  /* The TYPE_VALUES will be in increasing order, so
		     starting searching where we last ended.  */
		  t = next_node_to_try;
		  xlo = next_node_offset;
		  xhi = 0;
		  for (;;)
		    {
		      if (t == NULL_TREE)
			{
			  t = TYPE_VALUES (type);
			  xlo = 0;
			}
		      if (tree_int_cst_equal (val, TREE_VALUE (t)))
			{
			  next_node_to_try = TREE_CHAIN (t);
			  next_node_offset = xlo + 1;
			  break;
			}
		      xlo++;
		      t = TREE_CHAIN (t);
		      if (t == next_node_to_try)
			{
			  xlo = -1;
			  break;
			}
		    }
		}
	      else
		{
		  t = TYPE_MIN_VALUE (type);
		  if (t)
		    neg_double (TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t),
				&xlo, &xhi);
		  else
		    xlo = xhi = 0;
		  add_double (xlo, xhi,
			      TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
			      &xlo, &xhi);
		}
	      
	      if (xhi == 0 && xlo >= 0 && xlo < count)
		BITARRAY_SET (cases_seen, xlo);
	      add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
			  1, 0,
			  &TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val));
	    }
	}
    }
}

/* Called when the index of a switch statement is an enumerated type
   and there is no default label.

   Checks that all enumeration literals are covered by the case
   expressions of a switch.  Also, warn if there are any extra
   switch cases that are *not* elements of the enumerated type.

   If all enumeration literals were covered by the case expressions,
   turn one of the expressions into the default expression since it should
   not be possible to fall through such a switch.  */

void
check_for_full_enumeration_handling (type)
     tree type;
{
  register struct case_node *n;
  register struct case_node **l;
  register tree chain;
  int all_values = 1;

  /* True iff the selector type is a numbered set mode.  */
  int sparseness = 0;

  /* The number of possible selector values.  */
  HOST_WIDE_INT size;

  /* For each possible selector value. a one iff it has been matched
     by a case value alternative.  */
  unsigned char *cases_seen;

  /* The allocated size of cases_seen, in chars.  */
  long bytes_needed;
  tree t;

  if (output_bytecode)
    {
      bc_check_for_full_enumeration_handling (type);
      return;
    }

  if (! warn_switch)
    return;

  size = all_cases_count (type, &sparseness);
  bytes_needed = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR;

  if (size > 0 && size < 600000
      /* We deliberately use malloc here - not xmalloc.  */
      && (cases_seen = (unsigned char *) malloc (bytes_needed)) != NULL)
    {
      long i;
      tree v = TYPE_VALUES (type);
      bzero (cases_seen, bytes_needed);

      /* The time complexity of this code is normally O(N), where
	 N being the number of members in the enumerated type.
	 However, if type is a ENUMERAL_TYPE whose values do not
	 increase monotonically, O(N*log(N)) time may be needed.  */

      mark_seen_cases (type, cases_seen, size, sparseness);

      for (i = 0;  v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
	{
	  if (BITARRAY_TEST(cases_seen, i) == 0)
	    warning ("enumeration value `%s' not handled in switch",
		     IDENTIFIER_POINTER (TREE_PURPOSE (v)));
	}

      free (cases_seen);
    }

  /* Now we go the other way around; we warn if there are case
     expressions that don't correspond to enumerators.  This can
     occur since C and C++ don't enforce type-checking of
     assignments to enumeration variables.  */

  if (case_stack->data.case_stmt.case_list
      && case_stack->data.case_stmt.case_list->left)
    case_stack->data.case_stmt.case_list
      = case_tree2list (case_stack->data.case_stmt.case_list, 0);
  if (warn_switch)
    for (n = case_stack->data.case_stmt.case_list; n; n = n->right)
      {
	for (chain = TYPE_VALUES (type);
	     chain && !tree_int_cst_equal (n->low, TREE_VALUE (chain));
	     chain = TREE_CHAIN (chain))
	  ;

	if (!chain)
	  {
	    if (TYPE_NAME (type) == 0)
	      warning ("case value `%d' not in enumerated type",
		       TREE_INT_CST_LOW (n->low));
	    else
	      warning ("case value `%d' not in enumerated type `%s'",
		       TREE_INT_CST_LOW (n->low),
		       IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
					    == IDENTIFIER_NODE)
					   ? TYPE_NAME (type)
					   : DECL_NAME (TYPE_NAME (type))));
	  }
	if (!tree_int_cst_equal (n->low, n->high))
	  {
	    for (chain = TYPE_VALUES (type);
		 chain && !tree_int_cst_equal (n->high, TREE_VALUE (chain));
		 chain = TREE_CHAIN (chain))
	      ;

	    if (!chain)
	      {
		if (TYPE_NAME (type) == 0)
		  warning ("case value `%d' not in enumerated type",
			   TREE_INT_CST_LOW (n->high));
		else
		  warning ("case value `%d' not in enumerated type `%s'",
			   TREE_INT_CST_LOW (n->high),
			   IDENTIFIER_POINTER ((TREE_CODE (TYPE_NAME (type))
						== IDENTIFIER_NODE)
					       ? TYPE_NAME (type)
					       : DECL_NAME (TYPE_NAME (type))));
	      }
	  }
      }

#if 0
  /* ??? This optimization is disabled because it causes valid programs to
     fail.  ANSI C does not guarantee that an expression with enum type
     will have a value that is the same as one of the enumeration literals.  */

  /* If all values were found as case labels, make one of them the default
     label.  Thus, this switch will never fall through.  We arbitrarily pick
     the last one to make the default since this is likely the most
     efficient choice.  */

  if (all_values)
    {
      for (l = &case_stack->data.case_stmt.case_list;
	   (*l)->right != 0;
	   l = &(*l)->right)
	;

      case_stack->data.case_stmt.default_label = (*l)->code_label;
      *l = 0;
    }
#endif /* 0 */
}


/* Check that all enumeration literals are covered by the case
   expressions of a switch.  Also warn if there are any cases
   that are not elements of the enumerated type.  */

static void
bc_check_for_full_enumeration_handling (type)
     tree type;
{
  struct nesting *thiscase = case_stack;
  struct case_node *c;
  tree e;

  /* Check for enums not handled.  */
  for (e = TYPE_VALUES (type); e; e = TREE_CHAIN (e))
    {
      for (c = thiscase->data.case_stmt.case_list->left;
	   c && tree_int_cst_lt (c->high, TREE_VALUE (e));
	   c = c->left)
	;
      if (! (c && tree_int_cst_equal (c->low, TREE_VALUE (e))))
	warning ("enumerated value `%s' not handled in switch",
		 IDENTIFIER_POINTER (TREE_PURPOSE (e)));
    }

  /* Check for cases not in the enumeration.  */
  for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
    {
      for (e = TYPE_VALUES (type);
	   e && !tree_int_cst_equal (c->low, TREE_VALUE (e));
	   e = TREE_CHAIN (e))
	;
      if (! e)
	warning ("case value `%d' not in enumerated type `%s'",
		 TREE_INT_CST_LOW (c->low),
		 IDENTIFIER_POINTER (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
				     ? TYPE_NAME (type)
				     : DECL_NAME (TYPE_NAME (type))));
    }
}

/* Terminate a case (Pascal) or switch (C) statement
   in which ORIG_INDEX is the expression to be tested.
   Generate the code to test it and jump to the right place.  */

void
expand_end_case (orig_index)
     tree orig_index;
{
  tree minval, maxval, range, orig_minval;
  rtx default_label = 0;
  register struct case_node *n;
  int count;
  rtx index;
  rtx table_label;
  int ncases;
  rtx *labelvec;
  register int i;
  rtx before_case;
  register struct nesting *thiscase = case_stack;
  tree index_expr, index_type;
  int unsignedp;

  if (output_bytecode)
    {
      bc_expand_end_case (orig_index);
      return;
    }

  table_label = gen_label_rtx ();
  index_expr = thiscase->data.case_stmt.index_expr;
  index_type = TREE_TYPE (index_expr);
  unsignedp = TREE_UNSIGNED (index_type);

  do_pending_stack_adjust ();

  /* An ERROR_MARK occurs for various reasons including invalid data type.  */
  if (index_type != error_mark_node)
    {
      /* If switch expression was an enumerated type, check that all
	 enumeration literals are covered by the cases.
	 No sense trying this if there's a default case, however.  */

      if (!thiscase->data.case_stmt.default_label
	  && TREE_CODE (TREE_TYPE (orig_index)) == ENUMERAL_TYPE
	  && TREE_CODE (index_expr) != INTEGER_CST)
	check_for_full_enumeration_handling (TREE_TYPE (orig_index));

      /* If this is the first label, warn if any insns have been emitted.  */
      if (thiscase->data.case_stmt.seenlabel == 0)
	{
	  rtx insn;
	  for (insn = get_last_insn ();
	       insn != case_stack->data.case_stmt.start;
	       insn = PREV_INSN (insn))
	    if (GET_CODE (insn) != NOTE
	        && (GET_CODE (insn) != INSN || GET_CODE (PATTERN (insn))!= USE))
	      {
		warning ("unreachable code at beginning of %s",
			 case_stack->data.case_stmt.printname);
		break;
	      }
	}

      /* If we don't have a default-label, create one here,
	 after the body of the switch.  */
      if (thiscase->data.case_stmt.default_label == 0)
	{
	  thiscase->data.case_stmt.default_label
	    = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
	  expand_label (thiscase->data.case_stmt.default_label);
	}
      default_label = label_rtx (thiscase->data.case_stmt.default_label);

      before_case = get_last_insn ();

      if (thiscase->data.case_stmt.case_list
	  && thiscase->data.case_stmt.case_list->left)
	thiscase->data.case_stmt.case_list
	  = case_tree2list(thiscase->data.case_stmt.case_list, 0);

      /* Simplify the case-list before we count it.  */
      group_case_nodes (thiscase->data.case_stmt.case_list);

      /* Get upper and lower bounds of case values.
	 Also convert all the case values to the index expr's data type.  */

      count = 0;
      for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
	{
	  /* Check low and high label values are integers.  */
	  if (TREE_CODE (n->low) != INTEGER_CST)
	    abort ();
	  if (TREE_CODE (n->high) != INTEGER_CST)
	    abort ();

	  n->low = convert (index_type, n->low);
	  n->high = convert (index_type, n->high);

	  /* Count the elements and track the largest and smallest
	     of them (treating them as signed even if they are not).  */
	  if (count++ == 0)
	    {
	      minval = n->low;
	      maxval = n->high;
	    }
	  else
	    {
	      if (INT_CST_LT (n->low, minval))
		minval = n->low;
	      if (INT_CST_LT (maxval, n->high))
		maxval = n->high;
	    }
	  /* A range counts double, since it requires two compares.  */
	  if (! tree_int_cst_equal (n->low, n->high))
	    count++;
	}

      orig_minval = minval;

      /* Compute span of values.  */
      if (count != 0)
	range = fold (build (MINUS_EXPR, index_type, maxval, minval));

      end_cleanup_deferal ();

      if (count == 0)
	{
	  expand_expr (index_expr, const0_rtx, VOIDmode, 0);
	  emit_queue ();
	  emit_jump (default_label);
	}

      /* If range of values is much bigger than number of values,
	 make a sequence of conditional branches instead of a dispatch.
	 If the switch-index is a constant, do it this way
	 because we can optimize it.  */

#ifndef CASE_VALUES_THRESHOLD
#ifdef HAVE_casesi
#define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
#else
      /* If machine does not have a case insn that compares the
	 bounds, this means extra overhead for dispatch tables
	 which raises the threshold for using them.  */
#define CASE_VALUES_THRESHOLD 5
#endif /* HAVE_casesi */
#endif /* CASE_VALUES_THRESHOLD */

      else if (TREE_INT_CST_HIGH (range) != 0
	       || count < CASE_VALUES_THRESHOLD
	       || ((unsigned HOST_WIDE_INT) (TREE_INT_CST_LOW (range))
		   > 10 * count)
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
	       || flag_pic
#endif
	       || TREE_CODE (index_expr) == INTEGER_CST
	       /* These will reduce to a constant.  */
	       || (TREE_CODE (index_expr) == CALL_EXPR
		   && TREE_CODE (TREE_OPERAND (index_expr, 0)) == ADDR_EXPR
		   && TREE_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == FUNCTION_DECL
		   && DECL_FUNCTION_CODE (TREE_OPERAND (TREE_OPERAND (index_expr, 0), 0)) == BUILT_IN_CLASSIFY_TYPE)
	       || (TREE_CODE (index_expr) == COMPOUND_EXPR
		   && TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST))
	{
	  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);

	  /* If the index is a short or char that we do not have
	     an insn to handle comparisons directly, convert it to
	     a full integer now, rather than letting each comparison
	     generate the conversion.  */

	  if (GET_MODE_CLASS (GET_MODE (index)) == MODE_INT
	      && (cmp_optab->handlers[(int) GET_MODE(index)].insn_code
		  == CODE_FOR_nothing))
	    {
	      enum machine_mode wider_mode;
	      for (wider_mode = GET_MODE (index); wider_mode != VOIDmode;
		   wider_mode = GET_MODE_WIDER_MODE (wider_mode))
		if (cmp_optab->handlers[(int) wider_mode].insn_code
		    != CODE_FOR_nothing)
		  {
		    index = convert_to_mode (wider_mode, index, unsignedp);
		    break;
		  }
	    }

	  emit_queue ();
	  do_pending_stack_adjust ();

	  index = protect_from_queue (index, 0);
	  if (GET_CODE (index) == MEM)
	    index = copy_to_reg (index);
	  if (GET_CODE (index) == CONST_INT
	      || TREE_CODE (index_expr) == INTEGER_CST)
	    {
	      /* Make a tree node with the proper constant value
		 if we don't already have one.  */
	      if (TREE_CODE (index_expr) != INTEGER_CST)
		{
		  index_expr
		    = build_int_2 (INTVAL (index),
				   unsignedp || INTVAL (index) >= 0 ? 0 : -1);
		  index_expr = convert (index_type, index_expr);
		}

	      /* For constant index expressions we need only
		 issue a unconditional branch to the appropriate
		 target code.  The job of removing any unreachable
		 code is left to the optimisation phase if the
		 "-O" option is specified.  */
	      for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
		if (! tree_int_cst_lt (index_expr, n->low)
		    && ! tree_int_cst_lt (n->high, index_expr))
		  break;

	      if (n)
		emit_jump (label_rtx (n->code_label));
	      else
		emit_jump (default_label);
	    }
	  else
	    {
	      /* If the index expression is not constant we generate
		 a binary decision tree to select the appropriate
		 target code.  This is done as follows:

		 The list of cases is rearranged into a binary tree,
		 nearly optimal assuming equal probability for each case.

		 The tree is transformed into RTL, eliminating
		 redundant test conditions at the same time.

		 If program flow could reach the end of the
		 decision tree an unconditional jump to the
		 default code is emitted.  */

	      use_cost_table
		= (TREE_CODE (TREE_TYPE (orig_index)) != ENUMERAL_TYPE
		   && estimate_case_costs (thiscase->data.case_stmt.case_list));
	      balance_case_nodes (&thiscase->data.case_stmt.case_list, 
				  NULL_PTR);
	      emit_case_nodes (index, thiscase->data.case_stmt.case_list,
			       default_label, index_type);
	      emit_jump_if_reachable (default_label);
	    }
	}
      else
	{
	  int win = 0;
#ifdef HAVE_casesi
	  if (HAVE_casesi)
	    {
	      enum machine_mode index_mode = SImode;
	      int index_bits = GET_MODE_BITSIZE (index_mode);
	      rtx op1, op2;
	      enum machine_mode op_mode;

	      /* Convert the index to SImode.  */
	      if (GET_MODE_BITSIZE (TYPE_MODE (index_type))
		  > GET_MODE_BITSIZE (index_mode))
		{
		  enum machine_mode omode = TYPE_MODE (index_type);
		  rtx rangertx = expand_expr (range, NULL_RTX, VOIDmode, 0);

		  /* We must handle the endpoints in the original mode.  */
		  index_expr = build (MINUS_EXPR, index_type,
				      index_expr, minval);
		  minval = integer_zero_node;
		  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
		  emit_cmp_insn (rangertx, index, LTU, NULL_RTX, omode, 1, 0);
		  emit_jump_insn (gen_bltu (default_label));
		  /* Now we can safely truncate.  */
		  index = convert_to_mode (index_mode, index, 0);
		}
	      else
		{
		  if (TYPE_MODE (index_type) != index_mode)
		    {
		      index_expr = convert (type_for_size (index_bits, 0),
					    index_expr);
		      index_type = TREE_TYPE (index_expr);
		    }

		  index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
		}
	      emit_queue ();
	      index = protect_from_queue (index, 0);
	      do_pending_stack_adjust ();

	      op_mode = insn_operand_mode[(int)CODE_FOR_casesi][0];
	      if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][0])
		  (index, op_mode))
		index = copy_to_mode_reg (op_mode, index);

	      op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0);

	      op_mode = insn_operand_mode[(int)CODE_FOR_casesi][1];
	      if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][1])
		  (op1, op_mode))
		op1 = copy_to_mode_reg (op_mode, op1);

	      op2 = expand_expr (range, NULL_RTX, VOIDmode, 0);

	      op_mode = insn_operand_mode[(int)CODE_FOR_casesi][2];
	      if (! (*insn_operand_predicate[(int)CODE_FOR_casesi][2])
		  (op2, op_mode))
		op2 = copy_to_mode_reg (op_mode, op2);

	      emit_jump_insn (gen_casesi (index, op1, op2,
					  table_label, default_label));
	      win = 1;
	    }
#endif
#ifdef HAVE_tablejump
	  if (! win && HAVE_tablejump)
	    {
	      index_expr = convert (thiscase->data.case_stmt.nominal_type,
				    fold (build (MINUS_EXPR, index_type,
						 index_expr, minval)));
	      index_type = TREE_TYPE (index_expr);
	      index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
	      emit_queue ();
	      index = protect_from_queue (index, 0);
	      do_pending_stack_adjust ();

	      do_tablejump (index, TYPE_MODE (index_type),
			    expand_expr (range, NULL_RTX, VOIDmode, 0),
			    table_label, default_label);
	      win = 1;
	    }
#endif
	  if (! win)
	    abort ();

	  /* Get table of labels to jump to, in order of case index.  */

	  ncases = TREE_INT_CST_LOW (range) + 1;
	  labelvec = (rtx *) alloca (ncases * sizeof (rtx));
	  bzero ((char *) labelvec, ncases * sizeof (rtx));

	  for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
	    {
	      register HOST_WIDE_INT i
		= TREE_INT_CST_LOW (n->low) - TREE_INT_CST_LOW (orig_minval);

	      while (1)
		{
		  labelvec[i]
		    = gen_rtx (LABEL_REF, Pmode, label_rtx (n->code_label));
		  if (i + TREE_INT_CST_LOW (orig_minval)
		      == TREE_INT_CST_LOW (n->high))
		    break;
		  i++;
		}
	    }

	  /* Fill in the gaps with the default.  */
	  for (i = 0; i < ncases; i++)
	    if (labelvec[i] == 0)
	      labelvec[i] = gen_rtx (LABEL_REF, Pmode, default_label);

	  /* Output the table */
	  emit_label (table_label);

	  /* This would be a lot nicer if CASE_VECTOR_PC_RELATIVE
	     were an expression, instead of an #ifdef/#ifndef.  */
	  if (
#ifdef CASE_VECTOR_PC_RELATIVE
	      1 ||
#endif
	      flag_pic)
	    emit_jump_insn (gen_rtx (ADDR_DIFF_VEC, CASE_VECTOR_MODE,
				     gen_rtx (LABEL_REF, Pmode, table_label),
				     gen_rtvec_v (ncases, labelvec)));
	  else
	    emit_jump_insn (gen_rtx (ADDR_VEC, CASE_VECTOR_MODE,
				     gen_rtvec_v (ncases, labelvec)));

	  /* If the case insn drops through the table,
	     after the table we must jump to the default-label.
	     Otherwise record no drop-through after the table.  */
#ifdef CASE_DROPS_THROUGH
	  emit_jump (default_label);
#else
	  emit_barrier ();
#endif
	}

      before_case = squeeze_notes (NEXT_INSN (before_case), get_last_insn ());
      reorder_insns (before_case, get_last_insn (),
		     thiscase->data.case_stmt.start);
    }
  else
    end_cleanup_deferal ();

  if (thiscase->exit_label)
    emit_label (thiscase->exit_label);

  POPSTACK (case_stack);

  free_temp_slots ();
}

/* Convert the tree NODE into a list linked by the right field, with the left
   field zeroed.  RIGHT is used for recursion; it is a list to be placed
   rightmost in the resulting list.  */

static struct case_node *
case_tree2list (node, right)
     struct case_node *node, *right;
{
  struct case_node *left;

  if (node->right)
    right = case_tree2list (node->right, right);

  node->right = right;
  if (left = node->left)
    {
      node->left = 0;
      return case_tree2list (left, node);
    }

  return node;
}

/* Terminate a case statement.  EXPR is the original index
   expression.  */

static void
bc_expand_end_case (expr)
     tree expr;
{
  struct nesting *thiscase = case_stack;
  enum bytecode_opcode opcode;
  struct bc_label *jump_label;
  struct case_node *c;

  bc_emit_bytecode (jump);
  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label));

#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif

  /* Now that the size of the jump table is known, emit the actual
     indexed jump instruction.  */
  bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->data.case_stmt.skip_label));

  opcode = TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode
    ? TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseSU : caseSI
      : TREE_UNSIGNED (thiscase->data.case_stmt.nominal_type) ? caseDU : caseDI;

  bc_emit_bytecode (opcode);

  /* Now emit the case instructions literal arguments, in order.
     In addition to the value on the stack, it uses:
     1.  The address of the jump table.
     2.  The size of the jump table.
     3.  The default label.  */

  jump_label = bc_get_bytecode_label ();
  bc_emit_bytecode_labelref (jump_label);
  bc_emit_bytecode_const ((char *) &thiscase->data.case_stmt.num_ranges,
			  sizeof thiscase->data.case_stmt.num_ranges);

  if (thiscase->data.case_stmt.default_label)
    bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (thiscase->data.case_stmt.default_label)));
  else
    bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (thiscase->exit_label));

  /* Output the jump table.  */

  bc_align_bytecode (3 /* PTR_ALIGN */);
  bc_emit_bytecode_labeldef (jump_label);

  if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == SImode)
    for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
      {
	opcode = TREE_INT_CST_LOW (c->low);
	bc_emit_bytecode_const ((char *) &opcode, sizeof opcode);

	opcode = TREE_INT_CST_LOW (c->high);
	bc_emit_bytecode_const ((char *) &opcode, sizeof opcode);

	bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label)));
      }
  else
    if (TYPE_MODE (thiscase->data.case_stmt.nominal_type) == DImode)
      for (c = thiscase->data.case_stmt.case_list->left; c; c = c->left)
	{
	  bc_emit_bytecode_DI_const (c->low);
	  bc_emit_bytecode_DI_const (c->high);

	  bc_emit_bytecode_labelref (BYTECODE_BC_LABEL (DECL_RTL (c->code_label)));
	}
    else
      /* Bad mode */
      abort ();

    
  bc_emit_bytecode_labeldef (BYTECODE_BC_LABEL (thiscase->exit_label));

  /* Possibly issue enumeration warnings.  */

  if (!thiscase->data.case_stmt.default_label
      && TREE_CODE (TREE_TYPE (expr)) == ENUMERAL_TYPE
      && TREE_CODE (expr) != INTEGER_CST
      && warn_switch)
    check_for_full_enumeration_handling (TREE_TYPE (expr));


#ifdef DEBUG_PRINT_CODE
  fputc ('\n', stderr);
#endif

  POPSTACK (case_stack);
}


/* Return unique bytecode ID.  */

int 
bc_new_uid ()
{
  static int bc_uid = 0;

  return (++bc_uid);
}

/* Generate code to jump to LABEL if OP1 and OP2 are equal.  */

static void
do_jump_if_equal (op1, op2, label, unsignedp)
     rtx op1, op2, label;
     int unsignedp;
{
  if (GET_CODE (op1) == CONST_INT
      && GET_CODE (op2) == CONST_INT)
    {
      if (INTVAL (op1) == INTVAL (op2))
	emit_jump (label);
    }
  else
    {
      enum machine_mode mode = GET_MODE (op1);
      if (mode == VOIDmode)
	mode = GET_MODE (op2);
      emit_cmp_insn (op1, op2, EQ, NULL_RTX, mode, unsignedp, 0);
      emit_jump_insn (gen_beq (label));
    }
}

/* Not all case values are encountered equally.  This function
   uses a heuristic to weight case labels, in cases where that
   looks like a reasonable thing to do.

   Right now, all we try to guess is text, and we establish the
   following weights:

	chars above space:	16
	digits:			16
	default:		12
	space, punct:		8
	tab:			4
	newline:		2
	other "\" chars:	1
	remaining chars:	0

   If we find any cases in the switch that are not either -1 or in the range
   of valid ASCII characters, or are control characters other than those
   commonly used with "\", don't treat this switch scanning text.

   Return 1 if these nodes are suitable for cost estimation, otherwise
   return 0.  */

static int
estimate_case_costs (node)
     case_node_ptr node;
{
  tree min_ascii = build_int_2 (-1, -1);
  tree max_ascii = convert (TREE_TYPE (node->high), build_int_2 (127, 0));
  case_node_ptr n;
  int i;

  /* If we haven't already made the cost table, make it now.  Note that the
     lower bound of the table is -1, not zero.  */

  if (cost_table == NULL)
    {
      cost_table = ((short *) xmalloc (129 * sizeof (short))) + 1;
      bzero ((char *) (cost_table - 1), 129 * sizeof (short));

      for (i = 0; i < 128; i++)
	{
	  if (isalnum (i))
	    cost_table[i] = 16;
	  else if (ispunct (i))
	    cost_table[i] = 8;
	  else if (iscntrl (i))
	    cost_table[i] = -1;
	}

      cost_table[' '] = 8;
      cost_table['\t'] = 4;
      cost_table['\0'] = 4;
      cost_table['\n'] = 2;
      cost_table['\f'] = 1;
      cost_table['\v'] = 1;
      cost_table['\b'] = 1;
    }

  /* See if all the case expressions look like text.  It is text if the
     constant is >= -1 and the highest constant is <= 127.  Do all comparisons
     as signed arithmetic since we don't want to ever access cost_table with a
     value less than -1.  Also check that none of the constants in a range
     are strange control characters.  */

  for (n = node; n; n = n->right)
    {
      if ((INT_CST_LT (n->low, min_ascii)) || INT_CST_LT (max_ascii, n->high))
	return 0;

      for (i = TREE_INT_CST_LOW (n->low); i <= TREE_INT_CST_LOW (n->high); i++)
	if (cost_table[i] < 0)
	  return 0;
    }

  /* All interesting values are within the range of interesting
     ASCII characters.  */
  return 1;
}

/* Scan an ordered list of case nodes
   combining those with consecutive values or ranges.

   Eg. three separate entries 1: 2: 3: become one entry 1..3:  */

static void
group_case_nodes (head)
     case_node_ptr head;
{
  case_node_ptr node = head;

  while (node)
    {
      rtx lb = next_real_insn (label_rtx (node->code_label));
      rtx lb2;
      case_node_ptr np = node;

      /* Try to group the successors of NODE with NODE.  */
      while (((np = np->right) != 0)
	     /* Do they jump to the same place?  */
	     && ((lb2 = next_real_insn (label_rtx (np->code_label))) == lb
		 || (lb != 0 && lb2 != 0
		     && simplejump_p (lb)
		     && simplejump_p (lb2)
		     && rtx_equal_p (SET_SRC (PATTERN (lb)),
				     SET_SRC (PATTERN (lb2)))))
	     /* Are their ranges consecutive?  */
	     && tree_int_cst_equal (np->low,
				    fold (build (PLUS_EXPR,
						 TREE_TYPE (node->high),
						 node->high,
						 integer_one_node)))
	     /* An overflow is not consecutive.  */
	     && tree_int_cst_lt (node->high,
				 fold (build (PLUS_EXPR,
					      TREE_TYPE (node->high),
					      node->high,
					      integer_one_node))))
	{
	  node->high = np->high;
	}
      /* NP is the first node after NODE which can't be grouped with it.
	 Delete the nodes in between, and move on to that node.  */
      node->right = np;
      node = np;
    }
}

/* Take an ordered list of case nodes
   and transform them into a near optimal binary tree,
   on the assumption that any target code selection value is as
   likely as any other.

   The transformation is performed by splitting the ordered
   list into two equal sections plus a pivot.  The parts are
   then attached to the pivot as left and right branches.  Each
   branch is is then transformed recursively.  */

static void
balance_case_nodes (head, parent)
     case_node_ptr *head;
     case_node_ptr parent;
{
  register case_node_ptr np;

  np = *head;
  if (np)
    {
      int cost = 0;
      int i = 0;
      int ranges = 0;
      register case_node_ptr *npp;
      case_node_ptr left;

      /* Count the number of entries on branch.  Also count the ranges.  */

      while (np)
	{
	  if (!tree_int_cst_equal (np->low, np->high))
	    {
	      ranges++;
	      if (use_cost_table)
		cost += cost_table[TREE_INT_CST_LOW (np->high)];
	    }

	  if (use_cost_table)
	    cost += cost_table[TREE_INT_CST_LOW (np->low)];

	  i++;
	  np = np->right;
	}

      if (i > 2)
	{
	  /* Split this list if it is long enough for that to help.  */
	  npp = head;
	  left = *npp;
	  if (use_cost_table)
	    {
	      /* Find the place in the list that bisects the list's total cost,
		 Here I gets half the total cost.  */
	      int n_moved = 0;
	      i = (cost + 1) / 2;
	      while (1)
		{
		  /* Skip nodes while their cost does not reach that amount.  */
		  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
		    i -= cost_table[TREE_INT_CST_LOW ((*npp)->high)];
		  i -= cost_table[TREE_INT_CST_LOW ((*npp)->low)];
		  if (i <= 0)
		    break;
		  npp = &(*npp)->right;
		  n_moved += 1;
		}
	      if (n_moved == 0)
		{
		  /* Leave this branch lopsided, but optimize left-hand
		     side and fill in `parent' fields for right-hand side.  */
		  np = *head;
		  np->parent = parent;
		  balance_case_nodes (&np->left, np);
		  for (; np->right; np = np->right)
		    np->right->parent = np;
		  return;
		}
	    }
	  /* If there are just three nodes, split at the middle one.  */
	  else if (i == 3)
	    npp = &(*npp)->right;
	  else
	    {
	      /* Find the place in the list that bisects the list's total cost,
		 where ranges count as 2.
		 Here I gets half the total cost.  */
	      i = (i + ranges + 1) / 2;
	      while (1)
		{
		  /* Skip nodes while their cost does not reach that amount.  */
		  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
		    i--;
		  i--;
		  if (i <= 0)
		    break;
		  npp = &(*npp)->right;
		}
	    }
	  *head = np = *npp;
	  *npp = 0;
	  np->parent = parent;
	  np->left = left;

	  /* Optimize each of the two split parts.  */
	  balance_case_nodes (&np->left, np);
	  balance_case_nodes (&np->right, np);
	}
      else
	{
	  /* Else leave this branch as one level,
	     but fill in `parent' fields.  */
	  np = *head;
	  np->parent = parent;
	  for (; np->right; np = np->right)
	    np->right->parent = np;
	}
    }
}

/* Search the parent sections of the case node tree
   to see if a test for the lower bound of NODE would be redundant.
   INDEX_TYPE is the type of the index expression.

   The instructions to generate the case decision tree are
   output in the same order as nodes are processed so it is
   known that if a parent node checks the range of the current
   node minus one that the current node is bounded at its lower
   span.  Thus the test would be redundant.  */

static int
node_has_low_bound (node, index_type)
     case_node_ptr node;
     tree index_type;
{
  tree low_minus_one;
  case_node_ptr pnode;

  /* If the lower bound of this node is the lowest value in the index type,
     we need not test it.  */

  if (tree_int_cst_equal (node->low, TYPE_MIN_VALUE (index_type)))
    return 1;

  /* If this node has a left branch, the value at the left must be less
     than that at this node, so it cannot be bounded at the bottom and
     we need not bother testing any further.  */

  if (node->left)
    return 0;

  low_minus_one = fold (build (MINUS_EXPR, TREE_TYPE (node->low),
			       node->low, integer_one_node));

  /* If the subtraction above overflowed, we can't verify anything.
     Otherwise, look for a parent that tests our value - 1.  */

  if (! tree_int_cst_lt (low_minus_one, node->low))
    return 0;

  for (pnode = node->parent; pnode; pnode = pnode->parent)
    if (tree_int_cst_equal (low_minus_one, pnode->high))
      return 1;

  return 0;
}

/* Search the parent sections of the case node tree
   to see if a test for the upper bound of NODE would be redundant.
   INDEX_TYPE is the type of the index expression.

   The instructions to generate the case decision tree are
   output in the same order as nodes are processed so it is
   known that if a parent node checks the range of the current
   node plus one that the current node is bounded at its upper
   span.  Thus the test would be redundant.  */

static int
node_has_high_bound (node, index_type)
     case_node_ptr node;
     tree index_type;
{
  tree high_plus_one;
  case_node_ptr pnode;

  /* If the upper bound of this node is the highest value in the type
     of the index expression, we need not test against it.  */

  if (tree_int_cst_equal (node->high, TYPE_MAX_VALUE (index_type)))
    return 1;

  /* If this node has a right branch, the value at the right must be greater
     than that at this node, so it cannot be bounded at the top and
     we need not bother testing any further.  */

  if (node->right)
    return 0;

  high_plus_one = fold (build (PLUS_EXPR, TREE_TYPE (node->high),
			       node->high, integer_one_node));

  /* If the addition above overflowed, we can't verify anything.
     Otherwise, look for a parent that tests our value + 1.  */

  if (! tree_int_cst_lt (node->high, high_plus_one))
    return 0;

  for (pnode = node->parent; pnode; pnode = pnode->parent)
    if (tree_int_cst_equal (high_plus_one, pnode->low))
      return 1;

  return 0;
}

/* Search the parent sections of the
   case node tree to see if both tests for the upper and lower
   bounds of NODE would be redundant.  */

static int
node_is_bounded (node, index_type)
     case_node_ptr node;
     tree index_type;
{
  return (node_has_low_bound (node, index_type)
	  && node_has_high_bound (node, index_type));
}

/*  Emit an unconditional jump to LABEL unless it would be dead code.  */

static void
emit_jump_if_reachable (label)
     rtx label;
{
  if (GET_CODE (get_last_insn ()) != BARRIER)
    emit_jump (label);
}

/* Emit step-by-step code to select a case for the value of INDEX.
   The thus generated decision tree follows the form of the
   case-node binary tree NODE, whose nodes represent test conditions.
   INDEX_TYPE is the type of the index of the switch.

   Care is taken to prune redundant tests from the decision tree
   by detecting any boundary conditions already checked by
   emitted rtx.  (See node_has_high_bound, node_has_low_bound
   and node_is_bounded, above.)

   Where the test conditions can be shown to be redundant we emit
   an unconditional jump to the target code.  As a further
   optimization, the subordinates of a tree node are examined to
   check for bounded nodes.  In this case conditional and/or
   unconditional jumps as a result of the boundary check for the
   current node are arranged to target the subordinates associated
   code for out of bound conditions on the current node node.

   We can assume that when control reaches the code generated here,
   the index value has already been compared with the parents
   of this node, and determined to be on the same side of each parent
   as this node is.  Thus, if this node tests for the value 51,
   and a parent tested for 52, we don't need to consider
   the possibility of a value greater than 51.  If another parent
   tests for the value 50, then this node need not test anything.  */

static void
emit_case_nodes (index, node, default_label, index_type)
     rtx index;
     case_node_ptr node;
     rtx default_label;
     tree index_type;
{
  /* If INDEX has an unsigned type, we must make unsigned branches.  */
  int unsignedp = TREE_UNSIGNED (index_type);
  typedef rtx rtx_function ();
  rtx_function *gen_bgt_pat = unsignedp ? gen_bgtu : gen_bgt;
  rtx_function *gen_bge_pat = unsignedp ? gen_bgeu : gen_bge;
  rtx_function *gen_blt_pat = unsignedp ? gen_bltu : gen_blt;
  rtx_function *gen_ble_pat = unsignedp ? gen_bleu : gen_ble;
  enum machine_mode mode = GET_MODE (index);

  /* See if our parents have already tested everything for us.
     If they have, emit an unconditional jump for this node.  */
  if (node_is_bounded (node, index_type))
    emit_jump (label_rtx (node->code_label));

  else if (tree_int_cst_equal (node->low, node->high))
    {
      /* Node is single valued.  First see if the index expression matches
	 this node and then check our children, if any.  */

      do_jump_if_equal (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
			label_rtx (node->code_label), unsignedp);

      if (node->right != 0 && node->left != 0)
	{
	  /* This node has children on both sides.
	     Dispatch to one side or the other
	     by comparing the index value with this node's value.
	     If one subtree is bounded, check that one first,
	     so we can avoid real branches in the tree.  */

	  if (node_is_bounded (node->right, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						 VOIDmode, 0),
			     GT, NULL_RTX, mode, unsignedp, 0);

	      emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
	      emit_case_nodes (index, node->left, default_label, index_type);
	    }

	  else if (node_is_bounded (node->left, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						 VOIDmode, 0),
			     LT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_blt_pat) (label_rtx (node->left->code_label)));
	      emit_case_nodes (index, node->right, default_label, index_type);
	    }

	  else
	    {
	      /* Neither node is bounded.  First distinguish the two sides;
		 then emit the code for one side at a time.  */

	      tree test_label
		= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);

	      /* See if the value is on the right.  */
	      emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						 VOIDmode, 0),
			     GT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));

	      /* Value must be on the left.
		 Handle the left-hand subtree.  */
	      emit_case_nodes (index, node->left, default_label, index_type);
	      /* If left-hand subtree does nothing,
		 go to default.  */
	      emit_jump_if_reachable (default_label);

	      /* Code branches here for the right-hand subtree.  */
	      expand_label (test_label);
	      emit_case_nodes (index, node->right, default_label, index_type);
	    }
	}

      else if (node->right != 0 && node->left == 0)
	{
	  /* Here we have a right child but no left so we issue conditional
	     branch to default and process the right child.

	     Omit the conditional branch to default if we it avoid only one
	     right child; it costs too much space to save so little time.  */

	  if (node->right->right || node->right->left
	      || !tree_int_cst_equal (node->right->low, node->right->high))
	    {
	      if (!node_has_low_bound (node, index_type))
		{
		  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						     VOIDmode, 0),
				 LT, NULL_RTX, mode, unsignedp, 0);
		  emit_jump_insn ((*gen_blt_pat) (default_label));
		}

	      emit_case_nodes (index, node->right, default_label, index_type);
	    }
	  else
	    /* We cannot process node->right normally
	       since we haven't ruled out the numbers less than
	       this node's value.  So handle node->right explicitly.  */
	    do_jump_if_equal (index,
			      expand_expr (node->right->low, NULL_RTX,
					   VOIDmode, 0),
			      label_rtx (node->right->code_label), unsignedp);
	}

      else if (node->right == 0 && node->left != 0)
	{
	  /* Just one subtree, on the left.  */

#if 0 /* The following code and comment were formerly part
	 of the condition here, but they didn't work
	 and I don't understand what the idea was.  -- rms.  */
	  /* If our "most probable entry" is less probable
	     than the default label, emit a jump to
	     the default label using condition codes
	     already lying around.  With no right branch,
	     a branch-greater-than will get us to the default
	     label correctly.  */
	  if (use_cost_table
	       && cost_table[TREE_INT_CST_LOW (node->high)] < 12)
	    ;
#endif /* 0 */
 	  if (node->left->left || node->left->right
	      || !tree_int_cst_equal (node->left->low, node->left->high))
	    {
	      if (!node_has_high_bound (node, index_type))
		{
		  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						     VOIDmode, 0),
				 GT, NULL_RTX, mode, unsignedp, 0);
		  emit_jump_insn ((*gen_bgt_pat) (default_label));
		}

	      emit_case_nodes (index, node->left, default_label, index_type);
	    }
	  else
	    /* We cannot process node->left normally
	       since we haven't ruled out the numbers less than
	       this node's value.  So handle node->left explicitly.  */
	    do_jump_if_equal (index,
			      expand_expr (node->left->low, NULL_RTX,
					   VOIDmode, 0),
			      label_rtx (node->left->code_label), unsignedp);
	}
    }
  else
    {
      /* Node is a range.  These cases are very similar to those for a single
	 value, except that we do not start by testing whether this node
	 is the one to branch to.  */

      if (node->right != 0 && node->left != 0)
	{
	  /* Node has subtrees on both sides.
	     If the right-hand subtree is bounded,
	     test for it first, since we can go straight there.
	     Otherwise, we need to make a branch in the control structure,
	     then handle the two subtrees.  */
	  tree test_label = 0;

	  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
					     VOIDmode, 0),
			 GT, NULL_RTX, mode, unsignedp, 0);

	  if (node_is_bounded (node->right, index_type))
	    /* Right hand node is fully bounded so we can eliminate any
	       testing and branch directly to the target code.  */
	    emit_jump_insn ((*gen_bgt_pat) (label_rtx (node->right->code_label)));
	  else
	    {
	      /* Right hand node requires testing.
		 Branch to a label where we will handle it later.  */

	      test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
	      emit_jump_insn ((*gen_bgt_pat) (label_rtx (test_label)));
	    }

	  /* Value belongs to this node or to the left-hand subtree.  */

	  emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
			 GE, NULL_RTX, mode, unsignedp, 0);
	  emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));

	  /* Handle the left-hand subtree.  */
	  emit_case_nodes (index, node->left, default_label, index_type);

	  /* If right node had to be handled later, do that now.  */

	  if (test_label)
	    {
	      /* If the left-hand subtree fell through,
		 don't let it fall into the right-hand subtree.  */
	      emit_jump_if_reachable (default_label);

	      expand_label (test_label);
	      emit_case_nodes (index, node->right, default_label, index_type);
	    }
	}

      else if (node->right != 0 && node->left == 0)
	{
	  /* Deal with values to the left of this node,
	     if they are possible.  */
	  if (!node_has_low_bound (node, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
						 VOIDmode, 0),
			     LT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_blt_pat) (default_label));
	    }

	  /* Value belongs to this node or to the right-hand subtree.  */

	  emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
					     VOIDmode, 0),
			 LE, NULL_RTX, mode, unsignedp, 0);
	  emit_jump_insn ((*gen_ble_pat) (label_rtx (node->code_label)));

	  emit_case_nodes (index, node->right, default_label, index_type);
	}

      else if (node->right == 0 && node->left != 0)
	{
	  /* Deal with values to the right of this node,
	     if they are possible.  */
	  if (!node_has_high_bound (node, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						 VOIDmode, 0),
			     GT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_bgt_pat) (default_label));
	    }

	  /* Value belongs to this node or to the left-hand subtree.  */

	  emit_cmp_insn (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0),
			 GE, NULL_RTX, mode, unsignedp, 0);
	  emit_jump_insn ((*gen_bge_pat) (label_rtx (node->code_label)));

	  emit_case_nodes (index, node->left, default_label, index_type);
	}

      else
	{
	  /* Node has no children so we check low and high bounds to remove
	     redundant tests.  Only one of the bounds can exist,
	     since otherwise this node is bounded--a case tested already.  */

	  if (!node_has_high_bound (node, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->high, NULL_RTX,
						 VOIDmode, 0),
			     GT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_bgt_pat) (default_label));
	    }

	  if (!node_has_low_bound (node, index_type))
	    {
	      emit_cmp_insn (index, expand_expr (node->low, NULL_RTX,
						 VOIDmode, 0),
			     LT, NULL_RTX, mode, unsignedp, 0);
	      emit_jump_insn ((*gen_blt_pat) (default_label));
	    }

	  emit_jump (label_rtx (node->code_label));
	}
    }
}

/* These routines are used by the loop unrolling code.  They copy BLOCK trees
   so that the debugging info will be correct for the unrolled loop.  */

/* Indexed by block number, contains a pointer to the N'th block node.  */

static tree *block_vector;

void
find_loop_tree_blocks ()
{
  tree block = DECL_INITIAL (current_function_decl);

  block_vector = identify_blocks (block, get_insns ());
}

void
unroll_block_trees ()
{
  tree block = DECL_INITIAL (current_function_decl);

  reorder_blocks (block_vector, block, get_insns ());
}
