/* Process expressions for the GNU compiler for the Java(TM) language.
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   Free Software Foundation, Inc.

This file is part of GCC.

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

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

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.  

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "real.h"
#include "rtl.h"
#include "flags.h"
#include "expr.h"
#include "java-tree.h"
#include "javaop.h"
#include "java-opcodes.h"
#include "jcf.h"
#include "java-except.h"
#include "parse.h"
#include "toplev.h"
#include "except.h"
#include "ggc.h"
#include "tree-gimple.h"
#include "target.h"

static void flush_quick_stack (void);
static void push_value (tree);
static tree pop_value (tree);
static void java_stack_swap (void);
static void java_stack_dup (int, int);
static void build_java_athrow (tree);
static void build_java_jsr (int, int);
static void build_java_ret (tree);
static void expand_java_multianewarray (tree, int);
static void expand_java_arraystore (tree);
static void expand_java_arrayload (tree);
static void expand_java_array_length (void);
static tree build_java_monitor (tree, tree);
static void expand_java_pushc (int, tree);
static void expand_java_return (tree);
static void expand_load_internal (int, tree, int);
static void expand_java_NEW (tree);
static void expand_java_INSTANCEOF (tree);
static void expand_java_CHECKCAST (tree);
static void expand_iinc (unsigned int, int, int);
static void expand_java_binop (tree, enum tree_code);
static void note_label (int, int);
static void expand_compare (enum tree_code, tree, tree, int);
static void expand_test (enum tree_code, tree, int);
static void expand_cond (enum tree_code, tree, int);
static void expand_java_goto (int);
static tree expand_java_switch (tree, int);
static void expand_java_add_case (tree, int, int);
#if 0
static void expand_java_call (int, int);
static void expand_java_ret (tree); 
#endif
static tree pop_arguments (tree); 
static void expand_invoke (int, int, int); 
static void expand_java_field_op (int, int, int); 
static void java_push_constant_from_pool (struct JCF *, int); 
static void java_stack_pop (int); 
static tree build_java_throw_out_of_bounds_exception (tree); 
static tree build_java_check_indexed_type (tree, tree); 
static unsigned char peek_opcode_at_pc (struct JCF *, int, int);
static void promote_arguments (void);

static GTY(()) tree operand_type[59];

static GTY(()) tree methods_ident;
static GTY(()) tree ncode_ident;
tree dtable_ident = NULL_TREE;

/* Set to nonzero value in order to emit class initialization code
   before static field references.  */
int always_initialize_class_p = 0;

/* We store the stack state in two places:
   Within a basic block, we use the quick_stack, which is a
   pushdown list (TREE_LISTs) of expression nodes.
   This is the top part of the stack;  below that we use find_stack_slot.
   At the end of a basic block, the quick_stack must be flushed
   to the stack slot array (as handled by find_stack_slot).
   Using quick_stack generates better code (especially when
   compiled without optimization), because we do not have to
   explicitly store and load trees to temporary variables.

   If a variable is on the quick stack, it means the value of variable
   when the quick stack was last flushed.  Conceptually, flush_quick_stack
   saves all the quick_stack elements in parallel.  However, that is
   complicated, so it actually saves them (i.e. copies each stack value
   to is home virtual register) from low indexes.  This allows a quick_stack
   element at index i (counting from the bottom of stack the) to references
   slot virtuals for register that are >= i, but not those that are deeper.
   This convention makes most operations easier.  For example iadd works
   even when the stack contains (reg[0], reg[1]):  It results in the
   stack containing (reg[0]+reg[1]), which is OK.  However, some stack
   operations are more complicated.  For example dup given a stack
   containing (reg[0]) would yield (reg[0], reg[0]), which would violate
   the convention, since stack value 1 would refer to a register with
   lower index (reg[0]), which flush_quick_stack does not safely handle.
   So dup cannot just add an extra element to the quick_stack, but iadd can.
*/

static GTY(()) tree quick_stack;

/* A free-list of unused permanent TREE_LIST nodes.  */
static GTY((deletable)) tree tree_list_free_list;

/* The physical memory page size used in this computer.  See
   build_field_ref().  */
static GTY(()) tree page_size;

/* The stack pointer of the Java virtual machine.
   This does include the size of the quick_stack. */

int stack_pointer;

const unsigned char *linenumber_table;
int linenumber_count;

/* Largest pc so far in this method that has been passed to lookup_label. */
int highest_label_pc_this_method = -1;

/* Base value for this method to add to pc to get generated label. */
int start_label_pc_this_method = 0;

void
init_expr_processing (void)
{
  operand_type[21] = operand_type[54] = int_type_node;
  operand_type[22] = operand_type[55] = long_type_node;
  operand_type[23] = operand_type[56] = float_type_node;
  operand_type[24] = operand_type[57] = double_type_node;
  operand_type[25] = operand_type[58] = ptr_type_node;
}

tree
java_truthvalue_conversion (tree expr)
{
  /* It is simpler and generates better code to have only TRUTH_*_EXPR
     or comparison expressions as truth values at this level.

     This function should normally be identity for Java.  */

  switch (TREE_CODE (expr))
    {
    case EQ_EXPR:   case NE_EXPR:   case UNEQ_EXPR: case LTGT_EXPR:
    case LE_EXPR:   case GE_EXPR:   case LT_EXPR:   case GT_EXPR:
    case UNLE_EXPR: case UNGE_EXPR: case UNLT_EXPR: case UNGT_EXPR:
    case ORDERED_EXPR: case UNORDERED_EXPR:
    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
    case TRUTH_NOT_EXPR:
    case ERROR_MARK:
      return expr;

    case INTEGER_CST:
      return integer_zerop (expr) ? boolean_false_node : boolean_true_node;

    case REAL_CST:
      return real_zerop (expr) ? boolean_false_node : boolean_true_node;

    /* are these legal? XXX JH */
    case NEGATE_EXPR:
    case ABS_EXPR:
    case FLOAT_EXPR:
      /* These don't change whether an object is nonzero or zero.  */
      return java_truthvalue_conversion (TREE_OPERAND (expr, 0));

    case COND_EXPR:
      /* Distribute the conversion into the arms of a COND_EXPR.  */
      return fold_build3 (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
			  java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
			  java_truthvalue_conversion (TREE_OPERAND (expr, 2)));

    case NOP_EXPR:
      /* If this is widening the argument, we can ignore it.  */
      if (TYPE_PRECISION (TREE_TYPE (expr))
          >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
        return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
      /* fall through to default */

    default:
      return fold_build2 (NE_EXPR, boolean_type_node,
			  expr, boolean_false_node);
    }
}

/* Save any stack slots that happen to be in the quick_stack into their
   home virtual register slots.

   The copy order is from low stack index to high, to support the invariant
   that the expression for a slot may contain decls for stack slots with
   higher (or the same) index, but not lower. */

static void
flush_quick_stack (void)
{
  int stack_index = stack_pointer;
  tree prev, cur, next;

  /* First reverse the quick_stack, and count the number of slots it has. */
  for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
    {
      next = TREE_CHAIN (cur);
      TREE_CHAIN (cur) = prev;
      prev = cur;
      stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
    }
  quick_stack = prev;

  while (quick_stack != NULL_TREE)
    {
      tree decl;
      tree node = quick_stack, type;
      quick_stack = TREE_CHAIN (node);
      TREE_CHAIN (node) = tree_list_free_list;
      tree_list_free_list = node;
      node = TREE_VALUE (node);
      type = TREE_TYPE (node);

      decl = find_stack_slot (stack_index, type);
      if (decl != node)
	java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (node), decl, node));
      stack_index += 1 + TYPE_IS_WIDE (type);
    }
}

/* Push TYPE on the type stack.
   Return true on success, 0 on overflow. */

int
push_type_0 (tree type)
{
  int n_words;
  type = promote_type (type);
  n_words = 1 + TYPE_IS_WIDE (type);
  if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
    return 0;
  /* Allocate decl for this variable now, so we get a temporary that
     survives the whole method. */
  find_stack_slot (stack_pointer, type);
  stack_type_map[stack_pointer++] = type;
  n_words--;
  while (--n_words >= 0)
    stack_type_map[stack_pointer++] = TYPE_SECOND;
  return 1;
}

void
push_type (tree type)
{
  int r = push_type_0 (type);
  gcc_assert (r);
}

static void
push_value (tree value)
{
  tree type = TREE_TYPE (value);
  if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
    {
      type = promote_type (type);
      value = convert (type, value);
    }
  push_type (type);
  if (tree_list_free_list == NULL_TREE)
    quick_stack = tree_cons (NULL_TREE, value, quick_stack);
  else
    {
      tree node = tree_list_free_list;
      tree_list_free_list = TREE_CHAIN (tree_list_free_list);
      TREE_VALUE (node) = value;
      TREE_CHAIN (node) = quick_stack;
      quick_stack = node;
    }
  /* If the value has a side effect, then we need to evaluate it
     whether or not the result is used.  If the value ends up on the
     quick stack and is then popped, this won't happen -- so we flush
     the quick stack.  It is safest to simply always flush, though,
     since TREE_SIDE_EFFECTS doesn't capture COMPONENT_REF, and for
     the latter we may need to strip conversions.  */
  flush_quick_stack ();
}

/* Pop a type from the type stack.
   TYPE is the expected type.   Return the actual type, which must be
   convertible to TYPE.
   On an error, *MESSAGEP is set to a freshly malloc'd error message. */

tree
pop_type_0 (tree type, char **messagep)
{
  int n_words;
  tree t;
  *messagep = NULL;
  if (TREE_CODE (type) == RECORD_TYPE)
    type = promote_type (type);
  n_words = 1 + TYPE_IS_WIDE (type);
  if (stack_pointer < n_words)
    {
      *messagep = xstrdup ("stack underflow");
      return type;
    }
  while (--n_words > 0)
    {
      if (stack_type_map[--stack_pointer] != void_type_node)
	{
	  *messagep = xstrdup ("Invalid multi-word value on type stack");
	  return type;
	}
    }
  t = stack_type_map[--stack_pointer];
  if (type == NULL_TREE || t == type)
    return t;
  if (TREE_CODE (t) == TREE_LIST)
    {      
      do
	{
	  tree tt = TREE_PURPOSE (t);
	  if (! can_widen_reference_to (tt, type))
	    {
	      t = tt;
	      goto fail;
	    }
	  t = TREE_CHAIN (t);
	}
      while (t);
      return t;
    }
  if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
      && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
    return t;
  if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
    {
      /* If the expected type we've been passed is object or ptr
	 (i.e. void*), the caller needs to know the real type.  */
      if (type == ptr_type_node || type == object_ptr_type_node)
        return t;

      /* Since the verifier has already run, we know that any
	 types we see will be compatible.  In BC mode, this fact
	 may be checked at runtime, but if that is so then we can
	 assume its truth here as well.  So, we always succeed
	 here, with the expected type.  */
      return type;
    }

  if (! flag_verify_invocations && flag_indirect_dispatch
      && t == object_ptr_type_node)
    {
      if (type != ptr_type_node)
	warning (0, "need to insert runtime check for %s", 
		 xstrdup (lang_printable_name (type, 0)));
      return type;
    }

  /* lang_printable_name uses a static buffer, so we must save the result
     from calling it the first time.  */
 fail:
  {
    char *temp = xstrdup (lang_printable_name (type, 0));
    /* If the stack contains a multi-word type, keep popping the stack until 
       the real type is found.  */
    while (t == void_type_node)
      t = stack_type_map[--stack_pointer];
    *messagep = concat ("expected type '", temp,
			"' but stack contains '", lang_printable_name (t, 0),
			"'", NULL);
    free (temp);
  }
  return type;
}

/* Pop a type from the type stack.
   TYPE is the expected type.  Return the actual type, which must be
   convertible to TYPE, otherwise call error. */

tree
pop_type (tree type)
{
  char *message = NULL;
  type = pop_type_0 (type, &message);
  if (message != NULL)
    {
      error ("%s", message);
      free (message);
    }
  return type;
}


/* Return true if two type assertions are equal.  */

static int
type_assertion_eq (const void * k1_p, const void * k2_p)
{
  type_assertion k1 = *(type_assertion *)k1_p;
  type_assertion k2 = *(type_assertion *)k2_p;
  return (k1.assertion_code == k2.assertion_code
          && k1.op1 == k2.op1
	  && k1.op2 == k2.op2);
}

/* Hash a type assertion.  */

static hashval_t
type_assertion_hash (const void *p)
{
  const type_assertion *k_p = p;
  hashval_t hash = iterative_hash (&k_p->assertion_code, sizeof
				   k_p->assertion_code, 0);
  hash = iterative_hash (&k_p->op1, sizeof k_p->op1, hash);
  return iterative_hash (&k_p->op2, sizeof k_p->op2, hash);
}

/* Add an entry to the type assertion table for the given class.  
   CLASS is the class for which this assertion will be evaluated by the 
   runtime during loading/initialization.
   ASSERTION_CODE is the 'opcode' or type of this assertion: see java-tree.h.
   OP1 and OP2 are the operands. The tree type of these arguments may be
   specific to each assertion_code. */

void
add_type_assertion (tree class, int assertion_code, tree op1, tree op2)
{
  htab_t assertions_htab;
  type_assertion as;
  void **as_pp;

  assertions_htab = TYPE_ASSERTIONS (class);
  if (assertions_htab == NULL)
    {
      assertions_htab = htab_create_ggc (7, type_assertion_hash, 
					 type_assertion_eq, NULL);
      TYPE_ASSERTIONS (current_class) = assertions_htab;
    }

  as.assertion_code = assertion_code;
  as.op1 = op1;
  as.op2 = op2;

  as_pp = htab_find_slot (assertions_htab, &as, INSERT);

  /* Don't add the same assertion twice.  */
  if (*as_pp)
    return;

  *as_pp = ggc_alloc (sizeof (type_assertion));
  **(type_assertion **)as_pp = as;
}


/* Return 1 if SOURCE_TYPE can be safely widened to TARGET_TYPE.
   Handles array types and interfaces.  */

int
can_widen_reference_to (tree source_type, tree target_type)
{
  if (source_type == ptr_type_node || target_type == object_ptr_type_node)
    return 1;

  /* Get rid of pointers  */
  if (TREE_CODE (source_type) == POINTER_TYPE)
    source_type = TREE_TYPE (source_type);
  if (TREE_CODE (target_type) == POINTER_TYPE)
    target_type = TREE_TYPE (target_type);

  if (source_type == target_type)
    return 1;

  /* FIXME: This is very pessimistic, in that it checks everything,
     even if we already know that the types are compatible.  If we're
     to support full Java class loader semantics, we need this.
     However, we could do something more optimal.  */
  if (! flag_verify_invocations)
    {
      add_type_assertion (current_class, JV_ASSERT_TYPES_COMPATIBLE, 
			  source_type, target_type);

      if (!quiet_flag)
       warning (0, "assert: %s is assign compatible with %s", 
		xstrdup (lang_printable_name (target_type, 0)),
		xstrdup (lang_printable_name (source_type, 0)));
      /* Punt everything to runtime.  */
      return 1;
    }

  if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
    {
      return 1;
    }
  else
    {
      if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
	{
	  HOST_WIDE_INT source_length, target_length;
	  if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
	    {
	      /* An array implements Cloneable and Serializable.  */
	      tree name = DECL_NAME (TYPE_NAME (target_type));
	      return (name == java_lang_cloneable_identifier_node
		      || name == java_io_serializable_identifier_node);
	    }
	  target_length = java_array_type_length (target_type);
	  if (target_length >= 0)
	    {
	      source_length = java_array_type_length (source_type);
	      if (source_length != target_length)
		return 0;
	    }
	  source_type = TYPE_ARRAY_ELEMENT (source_type);
	  target_type = TYPE_ARRAY_ELEMENT (target_type);
	  if (source_type == target_type)
	    return 1;
	  if (TREE_CODE (source_type) != POINTER_TYPE
	      || TREE_CODE (target_type) != POINTER_TYPE)
	    return 0;
	  return can_widen_reference_to (source_type, target_type);
	}
      else
	{
	  int source_depth = class_depth (source_type);
	  int target_depth = class_depth (target_type);

	  if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
	    {
	      if (! quiet_flag)
		warning (0, "assert: %s is assign compatible with %s", 
			 xstrdup (lang_printable_name (target_type, 0)),
			 xstrdup (lang_printable_name (source_type, 0)));
	      return 1;
	    }

 	  /* class_depth can return a negative depth if an error occurred */
	  if (source_depth < 0 || target_depth < 0)
	    return 0;

	  if (CLASS_INTERFACE (TYPE_NAME (target_type)))
	    {
	      /* target_type is OK if source_type or source_type ancestors
		 implement target_type. We handle multiple sub-interfaces  */
	      tree binfo, base_binfo;
	      int i;

	      for (binfo = TYPE_BINFO (source_type), i = 0;
		   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	        if (can_widen_reference_to
		    (BINFO_TYPE (base_binfo), target_type))
		  return 1;
	      
	      if (!i)
		return 0;
	    }

	  for ( ; source_depth > target_depth;  source_depth--) 
	    {
	      source_type
		= BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (source_type), 0));
	    }
	  return source_type == target_type;
	}
    }
}

static tree
pop_value (tree type)
{
  type = pop_type (type);
  if (quick_stack)
    {
      tree node = quick_stack;
      quick_stack = TREE_CHAIN (quick_stack);
      TREE_CHAIN (node) = tree_list_free_list;
      tree_list_free_list = node;
      node = TREE_VALUE (node);
      return node;
    }
  else
    return find_stack_slot (stack_pointer, promote_type (type));
}


/* Pop and discard the top COUNT stack slots. */

static void
java_stack_pop (int count)
{
  while (count > 0)
    {
      tree type, val;

      gcc_assert (stack_pointer != 0);

      type = stack_type_map[stack_pointer - 1];
      if (type == TYPE_SECOND)
	{
	  count--;
	  gcc_assert (stack_pointer != 1 && count > 0);

	  type = stack_type_map[stack_pointer - 2];
	}
      val = pop_value (type);
      count--;
    }
}

/* Implement the 'swap' operator (to swap two top stack slots). */

static void
java_stack_swap (void)
{
  tree type1, type2;
  tree temp;
  tree decl1, decl2;

  if (stack_pointer < 2
      || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
      || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
      || type1 == TYPE_SECOND || type2 == TYPE_SECOND
      || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
    /* Bad stack swap.  */
    abort ();
  /* Bad stack swap.  */

  flush_quick_stack ();
  decl1 = find_stack_slot (stack_pointer - 1, type1);
  decl2 = find_stack_slot (stack_pointer - 2, type2);
  temp = build_decl (VAR_DECL, NULL_TREE, type1);
  java_add_local_var (temp);
  java_add_stmt (build2 (MODIFY_EXPR, type1, temp, decl1));
  java_add_stmt (build2 (MODIFY_EXPR, type2, 
			 find_stack_slot (stack_pointer - 1, type2),
			 decl2));
  java_add_stmt (build2 (MODIFY_EXPR, type1, 
			 find_stack_slot (stack_pointer - 2, type1),
			 temp));
  stack_type_map[stack_pointer - 1] = type2;
  stack_type_map[stack_pointer - 2] = type1;
}

static void
java_stack_dup (int size, int offset)
{
  int low_index = stack_pointer - size - offset;
  int dst_index;
  if (low_index < 0)
    error ("stack underflow - dup* operation");

  flush_quick_stack ();

  stack_pointer += size;
  dst_index = stack_pointer;

  for (dst_index = stack_pointer;  --dst_index >= low_index; )
    {
      tree type;
      int src_index = dst_index - size;
      if (src_index < low_index)
	src_index = dst_index + size + offset;
      type = stack_type_map [src_index];
      if (type == TYPE_SECOND)
	{
	  /* Dup operation splits 64-bit number.  */
	  gcc_assert (src_index > low_index);

	  stack_type_map[dst_index] = type;
	  src_index--;  dst_index--;
	  type = stack_type_map[src_index];
	  gcc_assert (TYPE_IS_WIDE (type));
	}
      else
	gcc_assert (! TYPE_IS_WIDE (type));

      if (src_index != dst_index)
	{
	  tree src_decl = find_stack_slot (src_index, type);
	  tree dst_decl = find_stack_slot (dst_index, type);

	  java_add_stmt 
	    (build2 (MODIFY_EXPR, TREE_TYPE (dst_decl), dst_decl, src_decl));
	  stack_type_map[dst_index] = type;
	}
    }
}

/* Calls _Jv_Throw or _Jv_Sjlj_Throw.  Discard the contents of the
   value stack. */

static void
build_java_athrow (tree node)
{
  tree call;

  call = build3 (CALL_EXPR,
		 void_type_node,
		 build_address_of (throw_node),
		 build_tree_list (NULL_TREE, node),
		 NULL_TREE);
  TREE_SIDE_EFFECTS (call) = 1;
  java_add_stmt (call);
  java_stack_pop (stack_pointer);
}

/* Implementation for jsr/ret */

static void
build_java_jsr (int target_pc, int return_pc)
{
  tree where =  lookup_label (target_pc);
  tree ret = lookup_label (return_pc);
  tree ret_label = fold_build1 (ADDR_EXPR, return_address_type_node, ret);
  push_value (ret_label);
  flush_quick_stack ();
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, where));

  /* Do not need to emit the label here.  We noted the existence of the
     label as a jump target in note_instructions; we'll emit the label
     for real at the beginning of the expand_byte_code loop.  */
}

static void
build_java_ret (tree location)
{
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, location));
}
 
/* Implementation of operations on array: new, load, store, length */

tree
decode_newarray_type (int atype)
{
  switch (atype)
    {
    case 4:  return boolean_type_node;
    case 5:  return char_type_node;
    case 6:  return float_type_node;
    case 7:  return double_type_node;
    case 8:  return byte_type_node;
    case 9:  return short_type_node;
    case 10: return int_type_node;
    case 11: return long_type_node;
    default: return NULL_TREE;
    }
}

/* Map primitive type to the code used by OPCODE_newarray. */

int
encode_newarray_type (tree type)
{
  if (type == boolean_type_node)
    return 4;
  else if (type == char_type_node)
    return 5;
  else if (type == float_type_node)
    return 6;
  else if (type == double_type_node)
    return 7;
  else if (type == byte_type_node)
    return 8;
  else if (type == short_type_node)
    return 9;
  else if (type == int_type_node)
    return 10;
  else if (type == long_type_node)
    return 11;
  else
    gcc_unreachable ();
}

/* Build a call to _Jv_ThrowBadArrayIndex(), the
   ArrayIndexOfBoundsException exception handler.  */

static tree
build_java_throw_out_of_bounds_exception (tree index)
{
  tree node = build3 (CALL_EXPR, int_type_node,
		      build_address_of (soft_badarrayindex_node), 
		      build_tree_list (NULL_TREE, index), NULL_TREE);
  TREE_SIDE_EFFECTS (node) = 1;	/* Allows expansion within ANDIF */
  return (node);
}

/* Return the length of an array. Doesn't perform any checking on the nature
   or value of the array NODE. May be used to implement some bytecodes.  */

tree
build_java_array_length_access (tree node)
{
  tree type = TREE_TYPE (node);
  tree array_type = TREE_TYPE (type);
  HOST_WIDE_INT length;

  if (!is_array_type_p (type))
    {
      /* With the new verifier, we will see an ordinary pointer type
	 here.  In this case, we just use an arbitrary array type.  */
      array_type = build_java_array_type (object_ptr_type_node, -1);
      type = promote_type (array_type);
    }

  length = java_array_type_length (type);
  if (length >= 0)
    return build_int_cst (NULL_TREE, length);

  node = build3 (COMPONENT_REF, int_type_node,
		 build_java_indirect_ref (array_type, node,
					  flag_check_references),
		 lookup_field (&array_type, get_identifier ("length")),
		 NULL_TREE);
  IS_ARRAY_LENGTH_ACCESS (node) = 1;
  return node;
}

/* Optionally checks a reference against the NULL pointer.  ARG1: the
   expr, ARG2: we should check the reference.  Don't generate extra
   checks if we're not generating code.  */

tree 
java_check_reference (tree expr, int check)
{
  if (!flag_syntax_only && check)
    {
      expr = save_expr (expr);
      expr = build3 (COND_EXPR, TREE_TYPE (expr),
		     build2 (EQ_EXPR, boolean_type_node,
			     expr, null_pointer_node),
		     build3 (CALL_EXPR, void_type_node, 
			     build_address_of (soft_nullpointer_node),
			     NULL_TREE, NULL_TREE),
		     expr);
    }

  return expr;
}

/* Reference an object: just like an INDIRECT_REF, but with checking.  */

tree
build_java_indirect_ref (tree type, tree expr, int check)
{
  tree t;
  t = java_check_reference (expr, check);
  t = convert (build_pointer_type (type), t);
  return build1 (INDIRECT_REF, type, t);
}

/* Implement array indexing (either as l-value or r-value).
   Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
   Optionally performs bounds checking and/or test to NULL.
   At this point, ARRAY should have been verified as an array.  */

tree
build_java_arrayaccess (tree array, tree type, tree index)
{
  tree node, throw = NULL_TREE;
  tree data_field;
  tree ref;
  tree array_type = TREE_TYPE (TREE_TYPE (array));

  if (!is_array_type_p (TREE_TYPE (array)))
    {
      /* With the new verifier, we will see an ordinary pointer type
	 here.  In this case, we just use the correct array type.  */
      array_type = build_java_array_type (type, -1);
    }

  if (flag_bounds_check)
    {
      /* Generate:
       * (unsigned jint) INDEX >= (unsigned jint) LEN
       *    && throw ArrayIndexOutOfBoundsException.
       * Note this is equivalent to and more efficient than:
       * INDEX < 0 || INDEX >= LEN && throw ... */
      tree test;
      tree len = convert (unsigned_int_type_node,
			  build_java_array_length_access (array));
      test = fold_build2 (GE_EXPR, boolean_type_node, 
			  convert (unsigned_int_type_node, index),
			  len);
      if (! integer_zerop (test))
	{
	  throw = build2 (TRUTH_ANDIF_EXPR, int_type_node, test,
			  build_java_throw_out_of_bounds_exception (index));
	  /* allows expansion within COMPOUND */
	  TREE_SIDE_EFFECTS( throw ) = 1;
	}
    }

  /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
     to have the bounds check evaluated first. */
  if (throw != NULL_TREE)
    index = build2 (COMPOUND_EXPR, int_type_node, throw, index);
 
  data_field = lookup_field (&array_type, get_identifier ("data"));

  ref = build3 (COMPONENT_REF, TREE_TYPE (data_field),    
		build_java_indirect_ref (array_type, array, 
					 flag_check_references),
		data_field, NULL_TREE);
  
  node = build4 (ARRAY_REF, type, ref, index, NULL_TREE, NULL_TREE);
  return node;
}

/* Generate code to throw an ArrayStoreException if OBJECT is not assignable
   (at runtime) to an element of ARRAY.  A NOP_EXPR is returned if it can
   determine that no check is required. */

tree
build_java_arraystore_check (tree array, tree object)
{
  tree check, element_type, source;
  tree array_type_p = TREE_TYPE (array);
  tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));

  if (! flag_verify_invocations)
    {
      /* With the new verifier, we don't track precise types.  FIXME:
	 performance regression here.  */
      element_type = TYPE_NAME (object_type_node);
    }
  else
    {
      gcc_assert (is_array_type_p (array_type_p));

      /* Get the TYPE_DECL for ARRAY's element type. */
      element_type
	= TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
    }

  gcc_assert (TREE_CODE (element_type) == TYPE_DECL
	      && TREE_CODE (object_type) == TYPE_DECL);

  if (!flag_store_check)
    return build1 (NOP_EXPR, array_type_p, array);

  /* No check is needed if the element type is final.  Also check that
     element_type matches object_type, since in the bytecode
     compilation case element_type may be the actual element type of
     the array rather than its declared type.  However, if we're doing
     indirect dispatch, we can't do the `final' optimization.  */
  if (element_type == object_type
      && ! flag_indirect_dispatch
      && CLASS_FINAL (element_type))
    return build1 (NOP_EXPR, array_type_p, array);
  
  /* OBJECT might be wrapped by a SAVE_EXPR. */
  if (TREE_CODE (object) == SAVE_EXPR)
    source = TREE_OPERAND (object, 0);
  else
    source = object;
  
  /* Avoid the check if OBJECT was just loaded from the same array. */
  if (TREE_CODE (source) == ARRAY_REF)
    {
      tree target;
      source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
      source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
      source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
      if (TREE_CODE (source) == SAVE_EXPR)
	source = TREE_OPERAND (source, 0);
      
      target = array;
      if (TREE_CODE (target) == SAVE_EXPR)
	target = TREE_OPERAND (target, 0);
      
      if (source == target)
        return build1 (NOP_EXPR, array_type_p, array);
    }

  /* Build an invocation of _Jv_CheckArrayStore */
  check = build3 (CALL_EXPR, void_type_node,
		  build_address_of (soft_checkarraystore_node),
		  tree_cons (NULL_TREE, array,
			     build_tree_list (NULL_TREE, object)),
		  NULL_TREE);
  TREE_SIDE_EFFECTS (check) = 1;

  return check;
}

/* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
   ARRAY_NODE. This function is used to retrieve something less vague than
   a pointer type when indexing the first dimension of something like [[<t>.
   May return a corrected type, if necessary, otherwise INDEXED_TYPE is
   return unchanged.  */

static tree
build_java_check_indexed_type (tree array_node ATTRIBUTE_UNUSED,
			       tree indexed_type)
{
  /* We used to check to see if ARRAY_NODE really had array type.
     However, with the new verifier, this is not necessary, as we know
     that the object will be an array of the appropriate type.  */

  return indexed_type;
}

/* newarray triggers a call to _Jv_NewPrimArray. This function should be 
   called with an integer code (the type of array to create), and the length
   of the array to create.  */

tree
build_newarray (int atype_value, tree length)
{
  tree type_arg;

  tree prim_type = decode_newarray_type (atype_value);
  tree type
    = build_java_array_type (prim_type,
			     host_integerp (length, 0) == INTEGER_CST
			     ? tree_low_cst (length, 0) : -1);

  /* If compiling to native, pass a reference to the primitive type class 
     and save the runtime some work. However, the bytecode generator
     expects to find the type_code int here. */
  if (flag_emit_class_files)
    type_arg = build_int_cst (NULL_TREE, atype_value);
  else
    type_arg = build_class_ref (prim_type);

  return build3 (CALL_EXPR, promote_type (type),
		 build_address_of (soft_newarray_node),
		 tree_cons (NULL_TREE, 
			    type_arg,
			    build_tree_list (NULL_TREE, length)),
		 NULL_TREE);
}

/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
   of the dimension. */

tree
build_anewarray (tree class_type, tree length)
{
  tree type
    = build_java_array_type (class_type,
			     host_integerp (length, 0)
			     ? tree_low_cst (length, 0) : -1);

  return build3 (CALL_EXPR, promote_type (type),
		 build_address_of (soft_anewarray_node),
		 tree_cons (NULL_TREE, length,
			    tree_cons (NULL_TREE, build_class_ref (class_type),
				       build_tree_list (NULL_TREE,
							null_pointer_node))),
		 NULL_TREE);
}

/* Return a node the evaluates 'new TYPE[LENGTH]'. */

tree
build_new_array (tree type, tree length)
{
  if (JPRIMITIVE_TYPE_P (type))
    return build_newarray (encode_newarray_type (type), length);
  else
    return build_anewarray (TREE_TYPE (type), length);
}

/* Generates a call to _Jv_NewMultiArray. multianewarray expects a
   class pointer, a number of dimensions and the matching number of
   dimensions. The argument list is NULL terminated.  */

static void
expand_java_multianewarray (tree class_type, int ndim)
{
  int i;
  tree args = build_tree_list( NULL_TREE, null_pointer_node );

  for( i = 0; i < ndim; i++ )
    args = tree_cons (NULL_TREE, pop_value (int_type_node), args);

  push_value (build3 (CALL_EXPR,
		      promote_type (class_type),
		      build_address_of (soft_multianewarray_node),
		      tree_cons (NULL_TREE, build_class_ref (class_type),
				 tree_cons (NULL_TREE, 
					    build_int_cst (NULL_TREE, ndim),
					    args)),
		      NULL_TREE));
}

/*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
    ARRAY is an array type. May expand some bound checking and NULL
    pointer checking. RHS_TYPE_NODE we are going to store. In the case
    of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
    INT. In those cases, we make the conversion.

    if ARRAy is a reference type, the assignment is checked at run-time
    to make sure that the RHS can be assigned to the array element
    type. It is not necessary to generate this code if ARRAY is final.  */

static void
expand_java_arraystore (tree rhs_type_node)
{
  tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
				 && TYPE_PRECISION (rhs_type_node) <= 32) ? 
				 int_type_node : rhs_type_node);
  tree index = pop_value (int_type_node);
  tree array_type, array;

  /* If we're processing an `aaload' we might as well just pick
     `Object'.  */
  if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
    {
      array_type = build_java_array_type (object_ptr_type_node, -1);
      rhs_type_node = object_ptr_type_node;
    }
  else
    array_type = build_java_array_type (rhs_type_node, -1);

  array = pop_value (array_type);
  array = build1 (NOP_EXPR, promote_type (array_type), array);

  rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);

  flush_quick_stack ();

  index = save_expr (index);
  array = save_expr (array);

  if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
    {
      tree check = build_java_arraystore_check (array, rhs_node);
      java_add_stmt (check);
    }
  
  array = build_java_arrayaccess (array, rhs_type_node, index);
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (array), array, rhs_node));  
}

/* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
   sure that LHS is an array type. May expand some bound checking and NULL
   pointer checking.  
   LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
   BOOLEAN/SHORT, we push a promoted type back to the stack.
*/

static void
expand_java_arrayload (tree lhs_type_node)
{
  tree load_node;
  tree index_node = pop_value (int_type_node);
  tree array_type;
  tree array_node;

  /* If we're processing an `aaload' we might as well just pick
     `Object'.  */
  if (TREE_CODE (lhs_type_node) == POINTER_TYPE)
    {
      array_type = build_java_array_type (object_ptr_type_node, -1);
      lhs_type_node = object_ptr_type_node;
    }
  else
    array_type = build_java_array_type (lhs_type_node, -1);
  array_node = pop_value (array_type);
  array_node = build1 (NOP_EXPR, promote_type (array_type), array_node);

  index_node = save_expr (index_node);
  array_node = save_expr (array_node);

  lhs_type_node = build_java_check_indexed_type (array_node,
						 lhs_type_node);
  load_node = build_java_arrayaccess (array_node,
				      lhs_type_node,
				      index_node);
  if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
    load_node = fold_build1 (NOP_EXPR, int_type_node, load_node);
  push_value (load_node);
}

/* Expands .length. Makes sure that we deal with and array and may expand
   a NULL check on the array object.  */

static void
expand_java_array_length (void)
{
  tree array  = pop_value (ptr_type_node);
  tree length = build_java_array_length_access (array);

  push_value (length);
}

/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
   either soft_monitorenter_node or soft_monitorexit_node.  */

static tree
build_java_monitor (tree call, tree object)
{
  return build3 (CALL_EXPR,
		 void_type_node,
		 build_address_of (call),
		 build_tree_list (NULL_TREE, object),
		 NULL_TREE);
}

/* Emit code for one of the PUSHC instructions. */

static void
expand_java_pushc (int ival, tree type)
{
  tree value;
  if (type == ptr_type_node && ival == 0)
    value = null_pointer_node;
  else if (type == int_type_node || type == long_type_node)
    value = build_int_cst (type, ival);
  else if (type == float_type_node || type == double_type_node)
    {
      REAL_VALUE_TYPE x;
      REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
      value = build_real (type, x);
    }
  else
    gcc_unreachable ();

  push_value (value);
}

static void
expand_java_return (tree type)
{
  if (type == void_type_node)
    java_add_stmt (build1 (RETURN_EXPR, void_type_node, NULL));   
  else
    {
      tree retval = pop_value (type);
      tree res = DECL_RESULT (current_function_decl);
      retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, retval);

      /* Handle the situation where the native integer type is smaller
	 than the JVM integer. It can happen for many cross compilers.
	 The whole if expression just goes away if INT_TYPE_SIZE < 32
	 is false. */
      if (INT_TYPE_SIZE < 32
	  && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
	      < GET_MODE_SIZE (TYPE_MODE (type))))
	retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
      
      TREE_SIDE_EFFECTS (retval) = 1;
      java_add_stmt (build1 (RETURN_EXPR, TREE_TYPE (retval), retval));
    }
}

static void
expand_load_internal (int index, tree type, int pc)
{
  tree copy;
  tree var = find_local_variable (index, type, pc);

  /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
     on the stack.  If there is an assignment to this VAR_DECL between
     the stack push and the use, then the wrong code could be
     generated.  To avoid this we create a new local and copy our
     value into it.  Then we push this new local on the stack.
     Hopefully this all gets optimized out.  */
  copy = build_decl (VAR_DECL, NULL_TREE, type);
  if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
      && TREE_TYPE (copy) != TREE_TYPE (var))
    var = convert (type, var);
  java_add_local_var (copy);
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (var), copy, var));
  
  push_value (copy);
}

tree
build_address_of (tree value)
{
  return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
}

bool
class_has_finalize_method (tree type)
{
  tree super = CLASSTYPE_SUPER (type);

  if (super == NULL_TREE)
    return false;	/* Every class with a real finalizer inherits	*/
   			/* from java.lang.Object.			*/
  else
    return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
}

tree
java_create_object (tree type)
{
  tree alloc_node = (class_has_finalize_method (type) 
		     ? alloc_object_node
		     : alloc_no_finalizer_node);
  
  return build3 (CALL_EXPR, promote_type (type),
		 build_address_of (alloc_node),
		 build_tree_list (NULL_TREE, build_class_ref (type)),
		 NULL_TREE);
}

static void
expand_java_NEW (tree type)
{
  tree alloc_node;

  alloc_node = (class_has_finalize_method (type) ? alloc_object_node
		  				 : alloc_no_finalizer_node);
  if (! CLASS_LOADED_P (type))
    load_class (type, 1);
  safe_layout_class (type);
  push_value (build3 (CALL_EXPR, promote_type (type),
		      build_address_of (alloc_node),
		      build_tree_list (NULL_TREE, build_class_ref (type)),
		      NULL_TREE));
}

/* This returns an expression which will extract the class of an
   object.  */

tree
build_get_class (tree value)
{
  tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
  tree vtable_field = lookup_field (&object_type_node,
				    get_identifier ("vtable"));
  tree tmp = build3 (COMPONENT_REF, dtable_ptr_type,
		     build_java_indirect_ref (object_type_node, value,
					      flag_check_references),
		     vtable_field, NULL_TREE);
  return build3 (COMPONENT_REF, class_ptr_type,
		 build1 (INDIRECT_REF, dtable_type, tmp),
		 class_field, NULL_TREE);
}

/* This builds the tree representation of the `instanceof' operator.
   It tries various tricks to optimize this in cases where types are
   known.  */

tree
build_instanceof (tree value, tree type)
{
  tree expr;
  tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
  tree valtype = TREE_TYPE (TREE_TYPE (value));
  tree valclass = TYPE_NAME (valtype);
  tree klass;

  /* When compiling from bytecode, we need to ensure that TYPE has
     been loaded.  */
  if (CLASS_P (type) && ! CLASS_LOADED_P (type))
    {
      load_class (type, 1);
      safe_layout_class (type);
      if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
	return error_mark_node;
    }
  klass = TYPE_NAME (type);

  if (type == object_type_node || inherits_from_p (valtype, type))
    {
      /* Anything except `null' is an instance of Object.  Likewise,
	 if the object is known to be an instance of the class, then
	 we only need to check for `null'.  */
      expr = build2 (NE_EXPR, itype, value, null_pointer_node);
    }
  else if (flag_verify_invocations
	   && ! TYPE_ARRAY_P (type)
	   && ! TYPE_ARRAY_P (valtype)
	   && DECL_P (klass) && DECL_P (valclass)
	   && ! CLASS_INTERFACE (valclass)
	   && ! CLASS_INTERFACE (klass)
	   && ! inherits_from_p (type, valtype)
	   && (CLASS_FINAL (klass)
	       || ! inherits_from_p (valtype, type)))
    {
      /* The classes are from different branches of the derivation
	 tree, so we immediately know the answer.  */
      expr = boolean_false_node;
    }
  else if (DECL_P (klass) && CLASS_FINAL (klass))
    {
      tree save = save_expr (value);
      expr = build3 (COND_EXPR, itype,
		     build2 (NE_EXPR, boolean_type_node,
			     save, null_pointer_node),
		     build2 (EQ_EXPR, itype,
			     build_get_class (save),
			     build_class_ref (type)),
		     boolean_false_node);
    }
  else
    {
      expr = build3 (CALL_EXPR, itype,
		     build_address_of (soft_instanceof_node),
		     tree_cons (NULL_TREE, value,
				build_tree_list (NULL_TREE,
						 build_class_ref (type))),
		     NULL_TREE);
    }
  TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
  return expr;
}

static void
expand_java_INSTANCEOF (tree type)
{
  tree value = pop_value (object_ptr_type_node);
  value = build_instanceof (value, type);
  push_value (value);
}

static void
expand_java_CHECKCAST (tree type)
{
  tree value = pop_value (ptr_type_node);
  value = build3 (CALL_EXPR, promote_type (type),
		  build_address_of (soft_checkcast_node),
		  tree_cons (NULL_TREE, build_class_ref (type),
			     build_tree_list (NULL_TREE, value)),
		  NULL_TREE);
  push_value (value);
}

static void
expand_iinc (unsigned int local_var_index, int ival, int pc)
{
  tree local_var, res;
  tree constant_value;

  flush_quick_stack ();
  local_var = find_local_variable (local_var_index, int_type_node, pc);
  constant_value = build_int_cst (NULL_TREE, ival);
  res = fold_build2 (PLUS_EXPR, int_type_node, local_var, constant_value);
  java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (local_var), local_var, res));
}


tree
build_java_soft_divmod (enum tree_code op, tree type, tree op1, tree op2)
{
  tree call = NULL;
  tree arg1 = convert (type, op1);
  tree arg2 = convert (type, op2);

  if (type == int_type_node)
    {	  
      switch (op)
	{
	case TRUNC_DIV_EXPR:
	  call = soft_idiv_node;
	  break;
	case TRUNC_MOD_EXPR:
	  call = soft_irem_node;
	  break;
	default:
	  break;
	}
    }
  else if (type == long_type_node)
    {	  
      switch (op)
	{
	case TRUNC_DIV_EXPR:
	  call = soft_ldiv_node;
	  break;
	case TRUNC_MOD_EXPR:
	  call = soft_lrem_node;
	  break;
	default:
	  break;
	}
    }

  gcc_assert (call);
  call = build3 (CALL_EXPR, type,
		 build_address_of (call),
		 tree_cons (NULL_TREE, arg1,
			    build_tree_list (NULL_TREE, arg2)),
		 NULL_TREE);
	  
  return call;
}

tree
build_java_binop (enum tree_code op, tree type, tree arg1, tree arg2)
{
  tree mask;
  switch (op)
    {
    case URSHIFT_EXPR:
      {
	tree u_type = java_unsigned_type (type);
	arg1 = convert (u_type, arg1);
	arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
	return convert (type, arg1);
      }
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
      mask = build_int_cst (NULL_TREE,
			    TYPE_PRECISION (TREE_TYPE (arg1)) - 1);
      arg2 = fold_build2 (BIT_AND_EXPR, int_type_node, arg2, mask);
      break;

    case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
    case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
      arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
      {
	tree ifexp1 = fold_build2 (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
				   boolean_type_node, arg1, arg2);
	tree ifexp2 = fold_build2 (EQ_EXPR, boolean_type_node, arg1, arg2);
	tree second_compare = fold_build3 (COND_EXPR, int_type_node,
					   ifexp2, integer_zero_node,
					   op == COMPARE_L_EXPR
					   ? integer_minus_one_node
					   : integer_one_node);
	return fold_build3 (COND_EXPR, int_type_node, ifexp1,
			    op == COMPARE_L_EXPR ? integer_one_node
			    : integer_minus_one_node,
			    second_compare);
      }
    case COMPARE_EXPR:
      arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
      {
	tree ifexp1 = fold_build2 (LT_EXPR, boolean_type_node, arg1, arg2);
	tree ifexp2 = fold_build2 (GT_EXPR, boolean_type_node, arg1, arg2);
	tree second_compare = fold_build3 (COND_EXPR, int_type_node,
					   ifexp2, integer_one_node,
					   integer_zero_node);
	return fold_build3 (COND_EXPR, int_type_node,
			    ifexp1, integer_minus_one_node, second_compare);
      }      
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
      if (TREE_CODE (type) == REAL_TYPE
	  && op == TRUNC_MOD_EXPR)
	{
	  tree call;
	  if (type != double_type_node)
	    {
	      arg1 = convert (double_type_node, arg1);
	      arg2 = convert (double_type_node, arg2);
	    }
	  call = build3 (CALL_EXPR, double_type_node,
			 build_address_of (soft_fmod_node),
			 tree_cons (NULL_TREE, arg1,
				    build_tree_list (NULL_TREE, arg2)),
			 NULL_TREE);
	  if (type != double_type_node)
	    call = convert (type, call);
	  return call;
	}
      
      if (TREE_CODE (type) == INTEGER_TYPE
	  && flag_use_divide_subroutine
	  && ! flag_syntax_only)
	return build_java_soft_divmod (op, type, arg1, arg2);
      
      break;
    default:  ;
    }
  return fold_build2 (op, type, arg1, arg2);
}

static void
expand_java_binop (tree type, enum tree_code op)
{
  tree larg, rarg;
  tree ltype = type;
  tree rtype = type;
  switch (op)
    {
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case URSHIFT_EXPR:
      rtype = int_type_node;
      rarg = pop_value (rtype);
      break;
    default:
      rarg = pop_value (rtype);
    }
  larg = pop_value (ltype);
  push_value (build_java_binop (op, type, larg, rarg));
}

/* Lookup the field named NAME in *TYPEP or its super classes.
   If not found, return NULL_TREE.
   (If the *TYPEP is not found, or if the field reference is
   ambiguous, return error_mark_node.)
   If found, return the FIELD_DECL, and set *TYPEP to the
   class containing the field. */

tree
lookup_field (tree *typep, tree name)
{
  if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
    {
      load_class (*typep, 1);
      safe_layout_class (*typep);
      if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
	return error_mark_node;
    }
  do
    {
      tree field, binfo, base_binfo;
      tree save_field;
      int i;

      for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
	if (DECL_NAME (field) == name)
	  return field;

      /* Process implemented interfaces. */
      save_field = NULL_TREE;
      for (binfo = TYPE_BINFO (*typep), i = 0;
	   BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
	{
	  tree t = BINFO_TYPE (base_binfo);
	  if ((field = lookup_field (&t, name)))
	    {
	      if (save_field == field)
		continue;
	      if (save_field == NULL_TREE)
		save_field = field;
	      else
		{
		  tree i1 = DECL_CONTEXT (save_field);
		  tree i2 = DECL_CONTEXT (field);
		  error ("reference %qs is ambiguous: appears in interface %qs and interface %qs",
			 IDENTIFIER_POINTER (name),
			 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
			 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
		  return error_mark_node;
		}
	    }
	}

      if (save_field != NULL_TREE)
	return save_field;

      *typep = CLASSTYPE_SUPER (*typep);
    } while (*typep);
  return NULL_TREE;
}

/* Look up the field named NAME in object SELF_VALUE,
   which has class SELF_CLASS (a non-handle RECORD_TYPE).
   SELF_VALUE is NULL_TREE if looking for a static field. */

tree
build_field_ref (tree self_value, tree self_class, tree name)
{
  tree base_class = self_class;
  tree field_decl = lookup_field (&base_class, name);
  if (field_decl == NULL_TREE)
    {
      error ("field %qs not found", IDENTIFIER_POINTER (name));
      return error_mark_node;
    }
  if (self_value == NULL_TREE)
    {
      return build_static_field_ref (field_decl);
    }
  else
    {
      tree base_type = promote_type (base_class);

      /* CHECK is true if self_value is not the this pointer.  */
      int check = (! (DECL_P (self_value)
		      && DECL_NAME (self_value) == this_identifier_node));

      /* Determine whether a field offset from NULL will lie within
	 Page 0: this is necessary on those GNU/Linux/BSD systems that
	 trap SEGV to generate NullPointerExceptions.  

	 We assume that Page 0 will be mapped with NOPERM, and that
	 memory may be allocated from any other page, so only field
	 offsets < pagesize are guaranteed to trap.  We also assume
	 the smallest page size we'll encounter is 4k bytes.  */
      if (! flag_syntax_only && check && ! flag_check_references 
	  && ! flag_indirect_dispatch)
	{
	  tree field_offset = byte_position (field_decl);
	  if (! page_size)
	    page_size = size_int (4096); 	      
	  check = ! INT_CST_LT_UNSIGNED (field_offset, page_size);
	}

      if (base_type != TREE_TYPE (self_value))
	self_value = fold_build1 (NOP_EXPR, base_type, self_value);
      if (! flag_syntax_only && flag_indirect_dispatch)
	{
	  tree otable_index
	    = build_int_cst (NULL_TREE, get_symbol_table_index 
			     (field_decl, NULL_TREE, 
			      &TYPE_OTABLE_METHODS (output_class)));
	  tree field_offset
	    = build4 (ARRAY_REF, integer_type_node,
		      TYPE_OTABLE_DECL (output_class), otable_index,
		      NULL_TREE, NULL_TREE);
	  tree address;

	  if (DECL_CONTEXT (field_decl) != output_class)
	    field_offset
	      = build3 (COND_EXPR, TREE_TYPE (field_offset),
			build2 (EQ_EXPR, boolean_type_node,
				field_offset, integer_zero_node),
			build3 (CALL_EXPR, void_type_node, 
				build_address_of (soft_nosuchfield_node),
				build_tree_list (NULL_TREE, otable_index), 
				NULL_TREE),
			field_offset);
	  
	  field_offset = fold (convert (sizetype, field_offset));
	  self_value = java_check_reference (self_value, check);
	  address 
	    = fold_build2 (PLUS_EXPR, 
			   build_pointer_type (TREE_TYPE (field_decl)),
			   self_value, field_offset);
	  return fold_build1 (INDIRECT_REF, TREE_TYPE (field_decl), address);
	}

      self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
					    self_value, check);
      return fold_build3 (COMPONENT_REF, TREE_TYPE (field_decl),
			  self_value, field_decl, NULL_TREE);
    }
}

tree
lookup_label (int pc)
{
  tree name;
  char buf[32];
  if (pc > highest_label_pc_this_method)
    highest_label_pc_this_method = pc;
  ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", start_label_pc_this_method + pc);
  name = get_identifier (buf);
  if (IDENTIFIER_LOCAL_VALUE (name))
    return IDENTIFIER_LOCAL_VALUE (name);
  else
    {
      /* The type of the address of a label is return_address_type_node. */
      tree decl = create_label_decl (name);
      LABEL_PC (decl) = pc;
      return pushdecl (decl);
    }
}

/* Generate a unique name for the purpose of loops and switches
   labels, and try-catch-finally blocks label or temporary variables.  */

tree
generate_name (void)
{
  static int l_number = 0;
  char buff [32];
  ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
  l_number++;
  return get_identifier (buff);
}

tree
create_label_decl (tree name)
{
  tree decl;
  decl = build_decl (LABEL_DECL, name, 
		     TREE_TYPE (return_address_type_node));
  DECL_CONTEXT (decl) = current_function_decl;
  DECL_IGNORED_P (decl) = 1;
  return decl;
}

/* This maps a bytecode offset (PC) to various flags. */
char *instruction_bits;

static void
note_label (int current_pc ATTRIBUTE_UNUSED, int target_pc)
{
  lookup_label (target_pc);
  instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
}

/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
   where CONDITION is one of one the compare operators. */

static void
expand_compare (enum tree_code condition, tree value1, tree value2,
		int target_pc)
{
  tree target = lookup_label (target_pc);
  tree cond = fold_build2 (condition, boolean_type_node, value1, value2);
  java_add_stmt 
    (build3 (COND_EXPR, void_type_node, java_truthvalue_conversion (cond),
	     build1 (GOTO_EXPR, void_type_node, target), 
	     build_java_empty_stmt ()));
}

/* Emit code for a TEST-type opcode. */

static void
expand_test (enum tree_code condition, tree type, int target_pc)
{
  tree value1, value2;
  flush_quick_stack ();
  value1 = pop_value (type);
  value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
  expand_compare (condition, value1, value2, target_pc);
}

/* Emit code for a COND-type opcode. */

static void
expand_cond (enum tree_code condition, tree type, int target_pc)
{
  tree value1, value2;
  flush_quick_stack ();
  /* note: pop values in opposite order */
  value2 = pop_value (type);
  value1 = pop_value (type);
  /* Maybe should check value1 and value2 for type compatibility ??? */
  expand_compare (condition, value1, value2, target_pc);
}

static void
expand_java_goto (int target_pc)
{
  tree target_label = lookup_label (target_pc);
  flush_quick_stack ();
  java_add_stmt (build1 (GOTO_EXPR, void_type_node, target_label));
}

static tree
expand_java_switch (tree selector, int default_pc)
{
  tree switch_expr, x;

  flush_quick_stack ();
  switch_expr = build3 (SWITCH_EXPR, TREE_TYPE (selector), selector,
			NULL_TREE, NULL_TREE);
  java_add_stmt (switch_expr);

  x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
	      create_artificial_label ());
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));

  x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));

  return switch_expr;
}

static void
expand_java_add_case (tree switch_expr, int match, int target_pc)
{
  tree value, x;

  value = build_int_cst (TREE_TYPE (switch_expr), match);
  
  x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
	      create_artificial_label ());
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));

  x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
  append_to_statement_list (x, &SWITCH_BODY (switch_expr));
}

static tree
pop_arguments (tree arg_types)
{
  if (arg_types == end_params_node)
    return NULL_TREE;
  if (TREE_CODE (arg_types) == TREE_LIST)
    {
      tree tail = pop_arguments (TREE_CHAIN (arg_types));
      tree type = TREE_VALUE (arg_types);
      tree arg = pop_value (type);

      /* We simply cast each argument to its proper type.  This is
	 needed since we lose type information coming out of the
	 verifier.  We also have to do this when we pop an integer
	 type that must be promoted for the function call.  */
      if (TREE_CODE (type) == POINTER_TYPE)
	arg = build1 (NOP_EXPR, type, arg);
      else if (targetm.calls.promote_prototypes (type)
	       && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
	       && INTEGRAL_TYPE_P (type))
	arg = convert (integer_type_node, arg);
      return tree_cons (NULL_TREE, arg, tail);
    }
  gcc_unreachable ();
}

/* Attach to PTR (a block) the declaration found in ENTRY. */

int
attach_init_test_initialization_flags (void **entry, void *ptr)
{
  tree block = (tree)ptr;
  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;

  if (block != error_mark_node)
    {
      if (TREE_CODE (block) == BIND_EXPR)
        {
	  tree body = BIND_EXPR_BODY (block);
	  TREE_CHAIN (ite->value) = BIND_EXPR_VARS (block);
	  BIND_EXPR_VARS (block) = ite->value;
	  body = build2 (COMPOUND_EXPR, void_type_node,
			 build1 (DECL_EXPR, void_type_node, ite->value), body);
	  BIND_EXPR_BODY (block) = body;
	}
      else
	{
	  tree body = BLOCK_SUBBLOCKS (block);
	  TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
	  BLOCK_EXPR_DECLS (block) = ite->value;
	  body = build2 (COMPOUND_EXPR, void_type_node,
			 build1 (DECL_EXPR, void_type_node, ite->value), body);
	  BLOCK_SUBBLOCKS (block) = body;
        }
      
    }
  return true;
}

/* Build an expression to initialize the class CLAS.
   if EXPR is non-NULL, returns an expression to first call the initializer
   (if it is needed) and then calls EXPR. */

tree
build_class_init (tree clas, tree expr)
{
  tree init;

  /* An optimization: if CLAS is a superclass of the class we're
     compiling, we don't need to initialize it.  However, if CLAS is
     an interface, it won't necessarily be initialized, even if we
     implement it.  */
  if ((! CLASS_INTERFACE (TYPE_NAME (clas))
       && inherits_from_p (current_class, clas))
      || current_class == clas)
    return expr;

  if (always_initialize_class_p)
    {
      init = build3 (CALL_EXPR, void_type_node,
		     build_address_of (soft_initclass_node),
		     build_tree_list (NULL_TREE, build_class_ref (clas)),
		     NULL_TREE);
      TREE_SIDE_EFFECTS (init) = 1;
    }
  else
    {
      tree *init_test_decl;
      tree decl;
      init_test_decl = java_treetreehash_new
	(DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);

      if (*init_test_decl == NULL)
	{
	  /* Build a declaration and mark it as a flag used to track
	     static class initializations. */
	  decl = build_decl (VAR_DECL, NULL_TREE,
			     boolean_type_node);
	  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
	  LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
	  DECL_CONTEXT (decl) = current_function_decl;
	  DECL_FUNCTION_INIT_TEST_CLASS (decl) = clas;
	  /* Tell the check-init code to ignore this decl when not
             optimizing class initialization. */
	  if (!STATIC_CLASS_INIT_OPT_P ())
	    DECL_BIT_INDEX (decl) = -1;
	  DECL_INITIAL (decl) = boolean_false_node;
	  /* Don't emit any symbolic debugging info for this decl.  */
	  DECL_IGNORED_P (decl) = 1;	  
	  *init_test_decl = decl;
	}

      init = build3 (CALL_EXPR, void_type_node,
		     build_address_of (soft_initclass_node),
		     build_tree_list (NULL_TREE, build_class_ref (clas)),
		     NULL_TREE);
      TREE_SIDE_EFFECTS (init) = 1;
      init = build3 (COND_EXPR, void_type_node,
		     build2 (EQ_EXPR, boolean_type_node, 
			     *init_test_decl, boolean_false_node),
		     init, integer_zero_node);
      TREE_SIDE_EFFECTS (init) = 1;
      init = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, 
		     build2 (MODIFY_EXPR, boolean_type_node,
			     *init_test_decl, boolean_true_node));
      TREE_SIDE_EFFECTS (init) = 1;
    }

  if (expr != NULL_TREE)
    {
      expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
      TREE_SIDE_EFFECTS (expr) = 1;
      return expr;
    }
  return init;
}



/* Rewrite expensive calls that require stack unwinding at runtime to
   cheaper alternatives.  The logic here performs these
   transformations:

   java.lang.Class.forName("foo") -> java.lang.Class.forName("foo", class$)
   java.lang.Class.getClassLoader() -> java.lang.Class.getClassLoader(class$)

*/

typedef struct
{
  const char *classname;
  const char *method;
  const char *signature;
  const char *new_signature;
  int flags;
  tree (*rewrite_arglist) (tree arglist);
} rewrite_rule;

/* Add this.class to the end of an arglist.  */

static tree 
rewrite_arglist_getclass (tree arglist)
{
  return chainon (arglist, 
		  tree_cons (NULL_TREE, build_class_ref (output_class), NULL_TREE));
}

static rewrite_rule rules[] =
  {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;", 
    "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 
    ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
   {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
    "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
    ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
   {NULL, NULL, NULL, NULL, 0, NULL}};

/* Scan the rules list for replacements for *METHOD_P and replace the
   args accordingly.  If the rewrite results in an access to a private
   method, update SPECIAL.*/

void
maybe_rewrite_invocation (tree *method_p, tree *arg_list_p, 
			  tree *method_signature_p, tree *special)
{
  tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
  rewrite_rule *p;
  *special = NULL_TREE;

  for (p = rules; p->classname; p++)
    {
      if (get_identifier (p->classname) == context)
	{
	  tree method = DECL_NAME (*method_p);
	  if (get_identifier (p->method) == method
	      && get_identifier (p->signature) == *method_signature_p)
	    {
	      tree maybe_method
		= lookup_java_method (DECL_CONTEXT (*method_p),
				      method,
				      get_identifier (p->new_signature));
	      if (! maybe_method && ! flag_verify_invocations)
		{
		  maybe_method
		    = add_method (DECL_CONTEXT (*method_p), p->flags, 
				  method, get_identifier (p->new_signature));
		  DECL_EXTERNAL (maybe_method) = 1;
		}
	      *method_p = maybe_method;
	      gcc_assert (*method_p);
	      *arg_list_p = p->rewrite_arglist (*arg_list_p);
	      *method_signature_p = get_identifier (p->new_signature);
	      *special = integer_one_node;

	      break;
	    }
	}
    }
}



tree
build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
			tree self_type, tree method_signature ATTRIBUTE_UNUSED,
			tree arg_list ATTRIBUTE_UNUSED, tree special)
{
  tree func;
  if (is_compiled_class (self_type))
    {
      /* With indirect dispatch we have to use indirect calls for all
	 publicly visible methods or gcc will use PLT indirections
	 to reach them.  We also have to use indirect dispatch for all
	 external methods.  */
      if (! flag_indirect_dispatch 
	  || (! DECL_EXTERNAL (method) && ! TREE_PUBLIC (method)))
	{
	  func = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (method)),
			 method);
	}
      else
	{
	  tree table_index
	    = build_int_cst (NULL_TREE, 
			     (get_symbol_table_index 
			      (method, special,
			       &TYPE_ATABLE_METHODS (output_class))));
	  func 
	    = build4 (ARRAY_REF,  
		      TREE_TYPE (TREE_TYPE (TYPE_ATABLE_DECL (output_class))),
		      TYPE_ATABLE_DECL (output_class), table_index,
		      NULL_TREE, NULL_TREE);
	}
      func = convert (method_ptr_type_node, func);
    }
  else
    {
      /* We don't know whether the method has been (statically) compiled.
	 Compile this code to get a reference to the method's code:

	 SELF_TYPE->methods[METHOD_INDEX].ncode

      */

      int method_index = 0;
      tree meth, ref;

      /* The method might actually be declared in some superclass, so
	 we have to use its class context, not the caller's notion of
	 where the method is.  */
      self_type = DECL_CONTEXT (method);
      ref = build_class_ref (self_type);
      ref = build1 (INDIRECT_REF, class_type_node, ref);
      if (ncode_ident == NULL_TREE)
	ncode_ident = get_identifier ("ncode");
      if (methods_ident == NULL_TREE)
	methods_ident = get_identifier ("methods");
      ref = build3 (COMPONENT_REF, method_ptr_type_node, ref,
		    lookup_field (&class_type_node, methods_ident),
		    NULL_TREE);
      for (meth = TYPE_METHODS (self_type);
	   ; meth = TREE_CHAIN (meth))
	{
	  if (method == meth)
	    break;
	  if (meth == NULL_TREE)
	    fatal_error ("method '%s' not found in class",
			 IDENTIFIER_POINTER (DECL_NAME (method)));
	  method_index++;
	}
      method_index *= int_size_in_bytes (method_type_node);
      ref = fold_build2 (PLUS_EXPR, method_ptr_type_node,
			 ref, build_int_cst (NULL_TREE, method_index));
      ref = build1 (INDIRECT_REF, method_type_node, ref);
      func = build3 (COMPONENT_REF, nativecode_ptr_type_node,
		     ref, lookup_field (&method_type_node, ncode_ident),
		     NULL_TREE);
    }
  return func;
}

tree
invoke_build_dtable (int is_invoke_interface, tree arg_list)
{
  tree dtable, objectref;

  TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));

  /* If we're dealing with interfaces and if the objectref
     argument is an array then get the dispatch table of the class
     Object rather than the one from the objectref.  */
  objectref = (is_invoke_interface 
	       && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list)))
	       ? build_class_ref (object_type_node) : TREE_VALUE (arg_list));

  if (dtable_ident == NULL_TREE)
    dtable_ident = get_identifier ("vtable");
  dtable = build_java_indirect_ref (object_type_node, objectref, 
				    flag_check_references);
  dtable = build3 (COMPONENT_REF, dtable_ptr_type, dtable,
		   lookup_field (&object_type_node, dtable_ident), NULL_TREE);

  return dtable;
}

/* Determine the index in SYMBOL_TABLE for a reference to the decl
   T. If this decl has not been seen before, it will be added to the
   [oa]table_methods. If it has, the existing table slot will be
   reused.  */

int
get_symbol_table_index (tree t, tree special, tree *symbol_table)
{
  int i = 1;
  tree method_list;

  if (*symbol_table == NULL_TREE)
    {
      *symbol_table = build_tree_list (special, t);
      return 1;
    }
  
  method_list = *symbol_table;
  
  while (1)
    {
      tree value = TREE_VALUE (method_list);
      tree purpose = TREE_PURPOSE (method_list);
      if (value == t && purpose == special)
	return i;
      i++;
      if (TREE_CHAIN (method_list) == NULL_TREE)
        break;
      else
        method_list = TREE_CHAIN (method_list);
    }

  TREE_CHAIN (method_list) = build_tree_list (special, t);
  return i;
}

tree 
build_invokevirtual (tree dtable, tree method, tree special)
{
  tree func;
  tree nativecode_ptr_ptr_type_node
    = build_pointer_type (nativecode_ptr_type_node);
  tree method_index;
  tree otable_index;

  if (flag_indirect_dispatch)
    {
      gcc_assert (! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))));

      otable_index 
	= build_int_cst (NULL_TREE, get_symbol_table_index 
			 (method, special,
			  &TYPE_OTABLE_METHODS (output_class)));
      method_index = build4 (ARRAY_REF, integer_type_node, 
			     TYPE_OTABLE_DECL (output_class), 
			     otable_index, NULL_TREE, NULL_TREE);
    }
  else
    {
      /* We fetch the DECL_VINDEX field directly here, rather than
	 using get_method_index().  DECL_VINDEX is the true offset
	 from the vtable base to a method, regrdless of any extra
	 words inserted at the start of the vtable.  */
      method_index = DECL_VINDEX (method);
      method_index = size_binop (MULT_EXPR, method_index,
				 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	method_index = size_binop (MULT_EXPR, method_index,
				   size_int (TARGET_VTABLE_USES_DESCRIPTORS));
    }

  func = fold_build2 (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
		      convert (nativecode_ptr_ptr_type_node, method_index));

  if (TARGET_VTABLE_USES_DESCRIPTORS)
    func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
  else
    func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);

  return func;
}

static GTY(()) tree class_ident;
tree
build_invokeinterface (tree dtable, tree method)
{
  tree lookup_arg;
  tree interface;
  tree idx;

  /* We expand invokeinterface here.  */
	    
  if (class_ident == NULL_TREE)
    class_ident = get_identifier ("class");

  dtable = build_java_indirect_ref (dtable_type, dtable,
				    flag_check_references);
  dtable = build3 (COMPONENT_REF, class_ptr_type, dtable,
		   lookup_field (&dtable_type, class_ident), NULL_TREE);

  interface = DECL_CONTEXT (method);
  gcc_assert (CLASS_INTERFACE (TYPE_NAME (interface)));
  layout_class_methods (interface);
  
  if (flag_indirect_dispatch)
    {
      int itable_index 
	= 2 * (get_symbol_table_index 
	       (method, NULL_TREE, &TYPE_ITABLE_METHODS (output_class)));
      interface 
	= build4 (ARRAY_REF, 
		 TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
		 TYPE_ITABLE_DECL (output_class), 
		  build_int_cst (NULL_TREE, itable_index-1),
		  NULL_TREE, NULL_TREE);
      idx 
	= build4 (ARRAY_REF, 
		 TREE_TYPE (TREE_TYPE (TYPE_ITABLE_DECL (output_class))),
		 TYPE_ITABLE_DECL (output_class), 
		  build_int_cst (NULL_TREE, itable_index),
		  NULL_TREE, NULL_TREE);
      interface = convert (class_ptr_type, interface);
      idx = convert (integer_type_node, idx);
    }
  else
    {
      idx = build_int_cst (NULL_TREE, 
			   get_interface_method_index (method, interface));
      interface = build_class_ref (interface);
    }
				     			  
  lookup_arg = tree_cons (NULL_TREE, dtable,
			  tree_cons (NULL_TREE, interface,
				     build_tree_list (NULL_TREE, idx)));

  return build3 (CALL_EXPR, ptr_type_node, 
		 build_address_of (soft_lookupinterfacemethod_node),
		 lookup_arg, NULL_TREE);
}
  
/* Expand one of the invoke_* opcodes.
   OPCODE is the specific opcode.
   METHOD_REF_INDEX is an index into the constant pool.
   NARGS is the number of arguments, or -1 if not specified. */

static void
expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
{
  tree method_signature
    = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
  tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool,
					 method_ref_index);
  tree self_type
    = get_class_constant (current_jcf,
                          COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool,
                          method_ref_index));
  const char *const self_name
    = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
  tree call, func, method, arg_list, method_type;
  tree check = NULL_TREE;

  tree special = NULL_TREE;

  if (! CLASS_LOADED_P (self_type))
    {
      load_class (self_type, 1);
      safe_layout_class (self_type);
      if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
	fatal_error ("failed to find class '%s'", self_name);
    }
  layout_class_methods (self_type);

  if (ID_INIT_P (method_name))
    method = lookup_java_constructor (self_type, method_signature);
  else
    method = lookup_java_method (self_type, method_name, method_signature);

  /* We've found a method in a class other than the one in which it
     was wanted.  This can happen if, for instance, we're trying to
     compile invokespecial super.equals().  
     FIXME: This is a kludge.  Rather than nullifying the result, we
     should change lookup_java_method() so that it doesn't search the
     superclass chain when we're BC-compiling.  */
  if (! flag_verify_invocations
      && method
      && ! TYPE_ARRAY_P (self_type)
      && self_type != DECL_CONTEXT (method))
    method = NULL_TREE;

  /* We've found a method in an interface, but this isn't an interface
     call.  */
  if (opcode != OPCODE_invokeinterface
      && method
      && (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method)))))
    method = NULL_TREE;

  /* We've found a non-interface method but we are making an
     interface call.  This can happen if the interface overrides a
     method in Object.  */
  if (! flag_verify_invocations
      && opcode == OPCODE_invokeinterface
      && method
      && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))))
    method = NULL_TREE;

  if (method == NULL_TREE)
    {
      if (flag_verify_invocations || ! flag_indirect_dispatch)
	{
	  error ("class '%s' has no method named '%s' matching signature '%s'",
		 self_name,
		 IDENTIFIER_POINTER (method_name),
		 IDENTIFIER_POINTER (method_signature));
	}
      else
	{
	  int flags = ACC_PUBLIC;
	  if (opcode == OPCODE_invokestatic)
	    flags |= ACC_STATIC;
	  if (opcode == OPCODE_invokeinterface)
	    {
	      flags |= ACC_INTERFACE | ACC_ABSTRACT;
	      CLASS_INTERFACE (TYPE_NAME (self_type)) = 1;
	    }
	  method = add_method (self_type, flags, method_name,
			       method_signature);
	  DECL_ARTIFICIAL (method) = 1;
	  METHOD_DUMMY (method) = 1;
	  layout_class_method (self_type, NULL,
			       method, NULL);
	}
    }

  /* Invoke static can't invoke static/abstract method */
  if (method != NULL_TREE)
    {
      if (opcode == OPCODE_invokestatic)
	{
	  if (!METHOD_STATIC (method))
	    {
	      error ("invokestatic on non static method");
	      method = NULL_TREE;
	    }
	  else if (METHOD_ABSTRACT (method))
	    {
	      error ("invokestatic on abstract method");
	      method = NULL_TREE;
	    }
	}
      else
	{
	  if (METHOD_STATIC (method))
	    {
	      error ("invoke[non-static] on static method");
	      method = NULL_TREE;
	    }
	}
    }

  if (method == NULL_TREE)
    {
      /* If we got here, we emitted an error message above.  So we
	 just pop the arguments, push a properly-typed zero, and
	 continue.  */
      method_type = get_type_from_signature (method_signature);
      pop_arguments (TYPE_ARG_TYPES (method_type));
      if (opcode != OPCODE_invokestatic) 
	pop_type (self_type);
      method_type = promote_type (TREE_TYPE (method_type));
      push_value (convert (method_type, integer_zero_node));
      return;
    }

  method_type = TREE_TYPE (method);
  arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
  flush_quick_stack ();

  maybe_rewrite_invocation (&method, &arg_list, &method_signature,
			    &special);

  func = NULL_TREE;
  if (opcode == OPCODE_invokestatic)
    func = build_known_method_ref (method, method_type, self_type,
				   method_signature, arg_list, special);
  else if (opcode == OPCODE_invokespecial
	   || (opcode == OPCODE_invokevirtual
	       && (METHOD_PRIVATE (method)
		   || METHOD_FINAL (method) 
		   || CLASS_FINAL (TYPE_NAME (self_type)))))
    {
      /* If the object for the method call is null, we throw an
	 exception.  We don't do this if the object is the current
	 method's `this'.  In other cases we just rely on an
	 optimization pass to eliminate redundant checks.  FIXME:
	 Unfortunately there doesn't seem to be a way to determine
	 what the current method is right now.
	 We do omit the check if we're calling <init>.  */
      /* We use a SAVE_EXPR here to make sure we only evaluate
	 the new `self' expression once.  */
      tree save_arg = save_expr (TREE_VALUE (arg_list));
      TREE_VALUE (arg_list) = save_arg;
      check = java_check_reference (save_arg, ! DECL_INIT_P (method));
      func = build_known_method_ref (method, method_type, self_type,
				     method_signature, arg_list, special);
    }
  else
    {
      tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
					 arg_list);
      if (opcode == OPCODE_invokevirtual)
	func = build_invokevirtual (dtable, method, special);
      else
	func = build_invokeinterface (dtable, method);
    }
      
  if (TREE_CODE (func) == ADDR_EXPR)
    TREE_TYPE (func) = build_pointer_type (method_type);
  else
    func = build1 (NOP_EXPR, build_pointer_type (method_type), func);

  call = build3 (CALL_EXPR, TREE_TYPE (method_type),
		 func, arg_list, NULL_TREE);
  TREE_SIDE_EFFECTS (call) = 1;
  call = check_for_builtin (method, call);

  if (check != NULL_TREE)
    {
      call = build2 (COMPOUND_EXPR, TREE_TYPE (call), check, call);
      TREE_SIDE_EFFECTS (call) = 1;
    }

  if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
    java_add_stmt (call);
  else
    {
      push_value (call);
      flush_quick_stack ();
    }
}

/* Create a stub which will be put into the vtable but which will call
   a JNI function.  */

tree
build_jni_stub (tree method)
{
  tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
  tree jni_func_type, tem;
  tree env_var, res_var = NULL_TREE, block;
  tree method_args, res_type;
  tree meth_var;
  tree bind;

  int args_size = 0;

  tree klass = DECL_CONTEXT (method);
  int from_class = ! CLASS_FROM_SOURCE_P (klass);
  klass = build_class_ref (klass);

  gcc_assert (METHOD_NATIVE (method) && flag_jni);

  DECL_ARTIFICIAL (method) = 1;
  DECL_EXTERNAL (method) = 0;

  env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
  DECL_CONTEXT (env_var) = method;

  if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
    {
      res_var = build_decl (VAR_DECL, get_identifier ("res"),
			    TREE_TYPE (TREE_TYPE (method)));
      DECL_CONTEXT (res_var) = method;
      TREE_CHAIN (env_var) = res_var;
    }

  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
  TREE_STATIC (meth_var) = 1;
  TREE_PUBLIC (meth_var) = 0;
  DECL_EXTERNAL (meth_var) = 0;
  DECL_CONTEXT (meth_var) = method;
  DECL_ARTIFICIAL (meth_var) = 1;
  DECL_INITIAL (meth_var) = null_pointer_node;
  TREE_USED (meth_var) = 1;
  chainon (env_var, meth_var);
  build_result_decl (method);

  /* One strange way that the front ends are different is that they
     store arguments differently.  */
  if (from_class)
    method_args = DECL_ARGUMENTS (method);
  else
    method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
  block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
  TREE_SIDE_EFFECTS (block) = 1;
  /* When compiling from source we don't set the type of the block,
     because that will prevent patch_return from ever being run.  */
  if (from_class)
    TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));

  /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
  body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
		 build3 (CALL_EXPR, ptr_type_node,
			 build_address_of (soft_getjnienvnewframe_node),
			 build_tree_list (NULL_TREE, klass),
			 NULL_TREE));
  CAN_COMPLETE_NORMALLY (body) = 1;

  /* All the arguments to this method become arguments to the
     underlying JNI function.  If we had to wrap object arguments in a
     special way, we would do that here.  */
  args = NULL_TREE;
  for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
    {
      int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tem)));
#ifdef PARM_BOUNDARY
      arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
                  * PARM_BOUNDARY);
#endif
      args_size += (arg_bits / BITS_PER_UNIT);

      args = tree_cons (NULL_TREE, tem, args);
    }
  args = nreverse (args);
  arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));

  /* For a static method the second argument is the class.  For a
     non-static method the second argument is `this'; that is already
     available in the argument list.  */
  if (METHOD_STATIC (method))
    {
      args_size += int_size_in_bytes (TREE_TYPE (klass));
      args = tree_cons (NULL_TREE, klass, args);
      arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
    }

  /* The JNIEnv structure is the first argument to the JNI function.  */
  args_size += int_size_in_bytes (TREE_TYPE (env_var));
  args = tree_cons (NULL_TREE, env_var, args);
  arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);

  /* We call _Jv_LookupJNIMethod to find the actual underlying
     function pointer.  _Jv_LookupJNIMethod will throw the appropriate
     exception if this function is not found at runtime.  */
  tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size));
  method_sig = build_java_signature (TREE_TYPE (method));
  lookup_arg = tree_cons (NULL_TREE,
                          build_utf8_ref (unmangle_classname
                                          (IDENTIFIER_POINTER (method_sig),
                                           IDENTIFIER_LENGTH (method_sig))), 
                          tem);
  tem = DECL_NAME (method);
  lookup_arg
    = tree_cons (NULL_TREE, klass,
		 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
  
  tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);

#ifdef MODIFY_JNI_METHOD_CALL
  tem = MODIFY_JNI_METHOD_CALL (tem);
#endif

  jni_func_type = build_pointer_type (tem);

  jnifunc = build3 (COND_EXPR, ptr_type_node,
		    meth_var, meth_var,
		    build2 (MODIFY_EXPR, ptr_type_node, meth_var,
			    build3 (CALL_EXPR, ptr_type_node,
				    build_address_of
				      (soft_lookupjnimethod_node),
				    lookup_arg, NULL_TREE)));

  /* Now we make the actual JNI call via the resulting function
     pointer.    */
  call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
		 build1 (NOP_EXPR, jni_func_type, jnifunc),
		 args, NULL_TREE);

  /* If the JNI call returned a result, capture it here.  If we had to
     unwrap JNI object results, we would do that here.  */
  if (res_var != NULL_TREE)
    {
      /* If the call returns an object, it may return a JNI weak
	 reference, in which case we must unwrap it.  */
      if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
	call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
		       build_address_of (soft_unwrapjni_node),
		       build_tree_list (NULL_TREE, call),
		       NULL_TREE);
      call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
		     res_var, call);
    }

  TREE_SIDE_EFFECTS (call) = 1;
  CAN_COMPLETE_NORMALLY (call) = 1;

  body = build2 (COMPOUND_EXPR, void_type_node, body, call);
  TREE_SIDE_EFFECTS (body) = 1;

  /* Now free the environment we allocated.  */
  call = build3 (CALL_EXPR, ptr_type_node,
		 build_address_of (soft_jnipopsystemframe_node),
		 build_tree_list (NULL_TREE, env_var),
		 NULL_TREE);
  TREE_SIDE_EFFECTS (call) = 1;
  CAN_COMPLETE_NORMALLY (call) = 1;
  body = build2 (COMPOUND_EXPR, void_type_node, body, call);
  TREE_SIDE_EFFECTS (body) = 1;

  /* Finally, do the return.  */
  res_type = void_type_node;
  if (res_var != NULL_TREE)
    {
      tree drt;
      gcc_assert (DECL_RESULT (method));
      /* Make sure we copy the result variable to the actual
	 result.  We use the type of the DECL_RESULT because it
	 might be different from the return type of the function:
	 it might be promoted.  */
      drt = TREE_TYPE (DECL_RESULT (method));
      if (drt != TREE_TYPE (res_var))
	res_var = build1 (CONVERT_EXPR, drt, res_var);
      res_var = build2 (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
      TREE_SIDE_EFFECTS (res_var) = 1;
    }

  body = build2 (COMPOUND_EXPR, void_type_node, body,
		 build1 (RETURN_EXPR, res_type, res_var));
  TREE_SIDE_EFFECTS (body) = 1;
  
  bind = build3 (BIND_EXPR, void_type_node, BLOCK_VARS (block), 
		 body, block);
  return bind;
}


/* Given lvalue EXP, return a volatile expression that references the
   same object.  */

tree
java_modify_addr_for_volatile (tree exp)
{
  tree exp_type = TREE_TYPE (exp);
  tree v_type 
    = build_qualified_type (exp_type,
			    TYPE_QUALS (exp_type) | TYPE_QUAL_VOLATILE);
  tree addr = build_fold_addr_expr (exp);
  v_type = build_pointer_type (v_type);
  addr = fold_convert (v_type, addr);
  exp = build_fold_indirect_ref (addr);
  return exp;
}


/* Expand an operation to extract from or store into a field.
   IS_STATIC is 1 iff the field is static.
   IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
   FIELD_REF_INDEX is an index into the constant pool.  */

static void
expand_java_field_op (int is_static, int is_putting, int field_ref_index)
{
  tree self_type
    = get_class_constant (current_jcf,
                          COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
                          field_ref_index));
  const char *self_name
    = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
  tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
  tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
						  field_ref_index);
  tree field_type = get_type_from_signature (field_signature);
  tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
  tree field_ref;
  int is_error = 0;
  tree original_self_type = self_type;
  tree field_decl;
  tree modify_expr;
  
  if (! CLASS_LOADED_P (self_type))
    load_class (self_type, 1);  
  field_decl = lookup_field (&self_type, field_name);
  if (field_decl == error_mark_node)
    {
      is_error = 1;
    }
  else if (field_decl == NULL_TREE)
    {
      if (! flag_verify_invocations)
	{
	  int flags = ACC_PUBLIC;
	  if (is_static)
	    flags |= ACC_STATIC;
	  self_type = original_self_type;
	  field_decl = add_field (original_self_type, field_name,
				  field_type, flags); 
	  DECL_ARTIFICIAL (field_decl) = 1;
	  DECL_IGNORED_P (field_decl) = 1;
#if 0
	  /* FIXME: We should be pessimistic about volatility.  We
	     don't know one way or another, but this is safe.
	     However, doing this has bad effects on code quality.  We
	     need to look at better ways to do this.  */
	  TREE_THIS_VOLATILE (field_decl) = 1;
#endif
	}
      else
	{      
	  error ("missing field '%s' in '%s'",
		 IDENTIFIER_POINTER (field_name), self_name);
	  is_error = 1;
      }
    }
  else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
    {
      error ("mismatching signature for field '%s' in '%s'",
	     IDENTIFIER_POINTER (field_name), self_name);
      is_error = 1;
    }
  field_ref = is_static ? NULL_TREE : pop_value (self_type);
  if (is_error)
    {
      if (! is_putting)
	push_value (convert (field_type, integer_zero_node));
      flush_quick_stack ();
      return;
    }

  field_ref = build_field_ref (field_ref, self_type, field_name);
  if (is_static
      && ! flag_indirect_dispatch)
    {
      tree context = DECL_CONTEXT (field_ref);
      if (context != self_type && CLASS_INTERFACE (TYPE_NAME (context)))
	field_ref = build_class_init (context, field_ref);
      field_ref = build_class_init (self_type, field_ref);
    }
  if (is_putting)
    {
      flush_quick_stack ();
      if (FIELD_FINAL (field_decl))
	{
	  if (DECL_CONTEXT (field_decl) != current_class)
            error ("assignment to final field %q+D not in field's class",
                   field_decl);
	  /* We used to check for assignments to final fields not
	     occurring in the class initializer or in a constructor
	     here.  However, this constraint doesn't seem to be
	     enforced by the JVM.  */
	}      

      if (TREE_THIS_VOLATILE (field_decl))
	field_ref = java_modify_addr_for_volatile (field_ref);

      modify_expr = build2 (MODIFY_EXPR, TREE_TYPE (field_ref),
			    field_ref, new_value);

      if (TREE_THIS_VOLATILE (field_decl))
	java_add_stmt 
	  (build3 
	   (CALL_EXPR, void_type_node,
	    build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]),
	    NULL_TREE, NULL_TREE));
      	  
      java_add_stmt (modify_expr);
    }
  else
    {
      tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
      java_add_local_var (temp);

      if (TREE_THIS_VOLATILE (field_decl))
	field_ref = java_modify_addr_for_volatile (field_ref);

      modify_expr 
	= build2 (MODIFY_EXPR, TREE_TYPE (field_ref), temp, field_ref);
      java_add_stmt (modify_expr);

      if (TREE_THIS_VOLATILE (field_decl))
	java_add_stmt 
	  (build3 
	   (CALL_EXPR, void_type_node,
	    build_address_of (built_in_decls[BUILT_IN_SYNCHRONIZE]),
	    NULL_TREE, NULL_TREE));

      push_value (temp);
    }      
  TREE_THIS_VOLATILE (field_ref) = TREE_THIS_VOLATILE (field_decl);
}

void
load_type_state (tree label)
{
  int i;
  tree vec = LABEL_TYPE_STATE (label);
  int cur_length = TREE_VEC_LENGTH (vec);
  stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
  for (i = 0; i < cur_length; i++)
    type_map [i] = TREE_VEC_ELT (vec, i);
}

/* Go over METHOD's bytecode and note instruction starts in
   instruction_bits[].  */

void
note_instructions (JCF *jcf, tree method)
{
  int PC; 
  unsigned char* byte_ops;
  long length = DECL_CODE_LENGTH (method);

  int saw_index;
  jint INT_temp;

#undef RET /* Defined by config/i386/i386.h */
#undef PTR
#define BCODE byte_ops
#define BYTE_type_node byte_type_node
#define SHORT_type_node short_type_node
#define INT_type_node int_type_node
#define LONG_type_node long_type_node
#define CHAR_type_node char_type_node
#define PTR_type_node ptr_type_node
#define FLOAT_type_node float_type_node
#define DOUBLE_type_node double_type_node
#define VOID_type_node void_type_node
#define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
#define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
#define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
#define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)

#define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */

  JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
  byte_ops = jcf->read_ptr;
  instruction_bits = xrealloc (instruction_bits, length + 1);
  memset (instruction_bits, 0, length + 1);

  /* This pass figures out which PC can be the targets of jumps. */
  for (PC = 0; PC < length;)
    {
      int oldpc = PC; /* PC at instruction start. */
      instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
      switch (byte_ops[PC++])
	{
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
        case OPCODE: \
	  PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
	  break;

#define NOTE_LABEL(PC) note_label(oldpc, PC)

#define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
#define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
#define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
#define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
#define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
#define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
#define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
#define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */

#define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
  PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
#define PRE_SPECIAL_IINC(OPERAND_TYPE) \
  ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
#define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
#define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
#define PRE_SPECIAL_THROW(IGNORE) /* nothing */
#define PRE_SPECIAL_BREAK(IGNORE) /* nothing */

/* two forms of wide instructions */
#define PRE_SPECIAL_WIDE(IGNORE) \
  { \
    int modified_opcode = IMMEDIATE_u1; \
    if (modified_opcode == OPCODE_iinc)	\
      { \
	(void) IMMEDIATE_u2;	/* indexbyte1 and indexbyte2 */ \
	(void) IMMEDIATE_s2;	/* constbyte1 and constbyte2 */ \
      } \
    else \
      { \
	(void) IMMEDIATE_u2;	/* indexbyte1 and indexbyte2 */ \
      } \
  }

#define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */

#define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */

#define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
#define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
	  PRE_ARRAY_##SUBOP(OPERAND_TYPE)
#define PRE_ARRAY_LOAD(TYPE) /* nothing */
#define PRE_ARRAY_STORE(TYPE) /* nothing */
#define PRE_ARRAY_LENGTH(TYPE) /* nothing */
#define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
#define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
#define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
#define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)

#define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
#define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
#define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
  saw_index = 0;  INT_temp = (OPERAND_VALUE); \
  if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
#define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
  saw_index = 0;  INT_temp = (OPERAND_VALUE); \
  NOTE_LABEL (PC); \
  if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);

#define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)

#define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
  PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH

#define PRE_LOOKUP_SWITCH						\
  { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;	\
    NOTE_LABEL (default_offset+oldpc);					\
    if (npairs >= 0)							\
      while (--npairs >= 0) {						\
       jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;			\
       jint offset = IMMEDIATE_s4;					\
       NOTE_LABEL (offset+oldpc); }					\
  }

#define PRE_TABLE_SWITCH				\
  { jint default_offset = IMMEDIATE_s4;			\
    jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;	\
    NOTE_LABEL (default_offset+oldpc);			\
    if (low <= high)					\
     while (low++ <= high) {				\
       jint offset = IMMEDIATE_s4;			\
       NOTE_LABEL (offset+oldpc); }			\
  }

#define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
#define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
#define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
  (void)(IMMEDIATE_u2); \
  PC += 2 * IS_INTERFACE /* for invokeinterface */;

#include "javaop.def"
#undef JAVAOP
	}
    } /* for */
}

void
expand_byte_code (JCF *jcf, tree method)
{
  int PC;
  int i;
  const unsigned char *linenumber_pointer;
  int dead_code_index = -1;
  unsigned char* byte_ops;
  long length = DECL_CODE_LENGTH (method);

  stack_pointer = 0;
  JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
  byte_ops = jcf->read_ptr;

  /* We make an initial pass of the line number table, to note
     which instructions have associated line number entries. */
  linenumber_pointer = linenumber_table;
  for (i = 0; i < linenumber_count; i++)
    {
      int pc = GET_u2 (linenumber_pointer);
      linenumber_pointer += 4;
      if (pc >= length)
	warning (0, "invalid PC in line number table");
      else
	{
	  if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
	    instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
	  instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
	}
    }  

  if (! verify_jvm_instructions_new (jcf, byte_ops, length))
    return;

  promote_arguments ();

  /* Translate bytecodes.  */
  linenumber_pointer = linenumber_table;
  for (PC = 0; PC < length;)
    {
      if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
	{
	  tree label = lookup_label (PC);
          flush_quick_stack ();
	  if ((instruction_bits [PC] & BCODE_TARGET) != 0)
	    java_add_stmt (build1 (LABEL_EXPR, void_type_node, label));
	  if (LABEL_VERIFIED (label) || PC == 0)
	    load_type_state (label);
	}

      if (! (instruction_bits [PC] & BCODE_VERIFIED))
	{
	  if (dead_code_index == -1)
	    {
	      /* This is the start of a region of unreachable bytecodes.
                 They still need to be processed in order for EH ranges
                 to get handled correctly.  However, we can simply
                 replace these bytecodes with nops.  */
	      dead_code_index = PC;
            }
          
          /* Turn this bytecode into a nop.  */
          byte_ops[PC] = 0x0;
        }
       else
        {
	  if (dead_code_index != -1)
	    {
              /* We've just reached the end of a region of dead code.  */
	      if (extra_warnings)
		warning (0, "unreachable bytecode from %d to before %d",
			 dead_code_index, PC);
              dead_code_index = -1;
            }
	}

      /* Handle possible line number entry for this PC.

	 This code handles out-of-order and multiple linenumbers per PC,
	 but is optimized for the case of line numbers increasing
	 monotonically with PC. */
      if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
	{
	  if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
	      || GET_u2 (linenumber_pointer) != PC)
	    linenumber_pointer = linenumber_table;
	  while (linenumber_pointer < linenumber_table + linenumber_count * 4)
	    {
	      int pc = GET_u2 (linenumber_pointer);
	      linenumber_pointer += 4;
	      if (pc == PC)
		{
		  int line = GET_u2 (linenumber_pointer - 2);
#ifdef USE_MAPPED_LOCATION
		  input_location = linemap_line_start (&line_table, line, 1);
#else
		  input_location.line = line;
#endif
		  if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
		    break;
		}
	    }
	}
      maybe_pushlevels (PC);
      PC = process_jvm_instruction (PC, byte_ops, length);
      maybe_poplevels (PC);
    } /* for */
  
  if (dead_code_index != -1)
    {
      /* We've just reached the end of a region of dead code.  */
      if (extra_warnings)
	warning (0, "unreachable bytecode from %d to the end of the method", 
		 dead_code_index);
    }
}

static void
java_push_constant_from_pool (JCF *jcf, int index)
{
  tree c;
  if (JPOOL_TAG (jcf, index) == CONSTANT_String)
    {
      tree name;
      name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
      index = alloc_name_constant (CONSTANT_String, name);
      c = build_ref_from_constant_pool (index);
      c = convert (promote_type (string_type_node), c);
    }
  else if (JPOOL_TAG (jcf, index) == CONSTANT_Class
	   || JPOOL_TAG (jcf, index) == CONSTANT_ResolvedClass)
    {
      tree record = get_class_constant (jcf, index);
      c = build_class_ref (record);
    }
  else
    c = get_constant (jcf, index);
  push_value (c);
} 

int
process_jvm_instruction (int PC, const unsigned char* byte_ops,
			 long length ATTRIBUTE_UNUSED)
{ 
  const char *opname; /* Temporary ??? */
  int oldpc = PC; /* PC at instruction start. */

  /* If the instruction is at the beginning of an exception handler,
     replace the top of the stack with the thrown object reference.  */
  if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
    {
      /* Note that the verifier will not emit a type map at all for
	 dead exception handlers.  In this case we just ignore the
	 situation.  */
      if ((instruction_bits[PC] & BCODE_VERIFIED) != 0)
	{
	  tree type = pop_type (promote_type (throwable_type_node));
	  push_value (build_exception_object_ref (type));
	}
    }

  switch (byte_ops[PC++])
    {
#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
    case OPCODE: \
      opname = #OPNAME; \
      OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
      break;

#define RET(OPERAND_TYPE, OPERAND_VALUE) 				\
  {									\
    int saw_index = 0;							\
    int index     = OPERAND_VALUE;					\
    build_java_ret							\
      (find_local_variable (index, return_address_type_node, oldpc));	\
  }

#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
  {						    \
    /* OPERAND_VALUE may have side-effects on PC */ \
    int opvalue = OPERAND_VALUE;		    \
    build_java_jsr (oldpc + opvalue, PC);	    \
  }

/* Push a constant onto the stack. */
#define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
  { int saw_index = 0;  int ival = (OPERAND_VALUE); \
    if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
    else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }

/* internal macro added for use by the WIDE case */
#define LOAD_INTERNAL(OPTYPE, OPVALUE) \
  expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);

/* Push local variable onto the opcode stack. */
#define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
  { \
    /* have to do this since OPERAND_VALUE may have side-effects */ \
    int opvalue = OPERAND_VALUE; \
    LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
  }

#define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
  expand_java_return (OPERAND_TYPE##_type_node)

#define REM_EXPR TRUNC_MOD_EXPR
#define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
  expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)

#define FIELD(IS_STATIC, IS_PUT) \
  expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)

#define TEST(OPERAND_TYPE, CONDITION) \
  expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)

#define COND(OPERAND_TYPE, CONDITION) \
  expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)

#define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
  BRANCH_##OPERAND_TYPE (OPERAND_VALUE)

#define BRANCH_GOTO(OPERAND_VALUE) \
  expand_java_goto (oldpc + OPERAND_VALUE)

#define BRANCH_CALL(OPERAND_VALUE) \
  expand_java_call (oldpc + OPERAND_VALUE, oldpc)

#if 0
#define BRANCH_RETURN(OPERAND_VALUE) \
  { \
    tree type = OPERAND_TYPE##_type_node; \
    tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
    expand_java_ret (value); \
  }
#endif

#define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
	  fprintf (stderr, "%3d: %s ", oldpc, opname); \
	  fprintf (stderr, "(not implemented)\n")
#define NOT_IMPL1(OPERAND_VALUE) \
	  fprintf (stderr, "%3d: %s ", oldpc, opname); \
	  fprintf (stderr, "(not implemented)\n")

#define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)

#define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)

#define STACK_POP(COUNT) java_stack_pop (COUNT)

#define STACK_SWAP(COUNT) java_stack_swap()

#define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
#define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
#define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)

#define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
  PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH

#define LOOKUP_SWITCH \
  { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
    tree selector = pop_value (INT_type_node); \
    tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
    while (--npairs >= 0) \
      { \
	jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
	expand_java_add_case (switch_expr, match, oldpc + offset); \
      } \
  }

#define TABLE_SWITCH \
  { jint default_offset = IMMEDIATE_s4; \
    jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
    tree selector = pop_value (INT_type_node); \
    tree switch_expr = expand_java_switch (selector, oldpc + default_offset); \
    for (; low <= high; low++) \
      { \
        jint offset = IMMEDIATE_s4; \
	expand_java_add_case (switch_expr, low, oldpc + offset); \
      } \
  }

#define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
  { int opcode = byte_ops[PC-1]; \
    int method_ref_index = IMMEDIATE_u2; \
    int nargs; \
    if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
    else nargs = -1; \
    expand_invoke (opcode, method_ref_index, nargs); \
  }

/* Handle new, checkcast, instanceof */
#define OBJECT(TYPE, OP) \
  expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))

#define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)

#define ARRAY_LOAD(OPERAND_TYPE) 			\
  {							\
    expand_java_arrayload( OPERAND_TYPE##_type_node );	\
  }

#define ARRAY_STORE(OPERAND_TYPE)			\
  {							\
    expand_java_arraystore( OPERAND_TYPE##_type_node );	\
  }

#define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
#define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
#define ARRAY_NEW_PTR()							\
    push_value (build_anewarray (get_class_constant (current_jcf,	\
						     IMMEDIATE_u2),	\
				 pop_value (int_type_node)));
#define ARRAY_NEW_NUM()				\
  {						\
    int atype = IMMEDIATE_u1;			\
    push_value (build_newarray (atype, pop_value (int_type_node)));\
  }
#define ARRAY_NEW_MULTI()					\
  {								\
    tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );	\
    int  ndims = IMMEDIATE_u1;					\
    expand_java_multianewarray( class, ndims );			\
  }

#define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
  push_value (fold_build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
			   pop_value (OPERAND_TYPE##_type_node)));

#define CONVERT2(FROM_TYPE, TO_TYPE)					 \
  {									 \
    push_value (build1 (NOP_EXPR, int_type_node,			 \
			(convert (TO_TYPE##_type_node,			 \
				  pop_value (FROM_TYPE##_type_node))))); \
  }

#define CONVERT(FROM_TYPE, TO_TYPE)				\
  {								\
    push_value (convert (TO_TYPE##_type_node,	                \
			 pop_value (FROM_TYPE##_type_node)));	\
  }

/* internal macro added for use by the WIDE case 
   Added TREE_TYPE (decl) assignment, apbianco  */
#define STORE_INTERNAL(OPTYPE, OPVALUE)				\
  {								\
    tree decl, value;						\
    int index = OPVALUE;					\
    tree type = OPTYPE;						\
    value = pop_value (type);					\
    type = TREE_TYPE (value);					\
    decl = find_local_variable (index, type, oldpc);		\
    set_local_type (index, type);				\
    java_add_stmt (build2 (MODIFY_EXPR, type, decl, value));	\
  }

#define STORE(OPERAND_TYPE, OPERAND_VALUE) \
  { \
    /* have to do this since OPERAND_VALUE may have side-effects */ \
    int opvalue = OPERAND_VALUE; \
    STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
  }

#define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
  SPECIAL_##INSTRUCTION(OPERAND_TYPE)

#define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
#define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)

#define MONITOR_OPERATION(call)			\
  {						\
    tree o = pop_value (ptr_type_node);		\
    tree c;					\
    flush_quick_stack ();			\
    c = build_java_monitor (call, o);		\
    TREE_SIDE_EFFECTS (c) = 1;			\
    java_add_stmt (c);				\
  }

#define SPECIAL_IINC(IGNORED) \
  { \
    unsigned int local_var_index = IMMEDIATE_u1; \
    int ival = IMMEDIATE_s1; \
    expand_iinc(local_var_index, ival, oldpc); \
  }

#define SPECIAL_WIDE(IGNORED) \
  { \
    int modified_opcode = IMMEDIATE_u1; \
    unsigned int local_var_index = IMMEDIATE_u2; \
    switch (modified_opcode) \
      { \
      case OPCODE_iinc: \
	{ \
	  int ival = IMMEDIATE_s2; \
	  expand_iinc (local_var_index, ival, oldpc); \
	  break; \
	} \
      case OPCODE_iload: \
      case OPCODE_lload: \
      case OPCODE_fload: \
      case OPCODE_dload: \
      case OPCODE_aload: \
	{ \
	  /* duplicate code from LOAD macro */ \
	  LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
	  break; \
	} \
      case OPCODE_istore: \
      case OPCODE_lstore: \
      case OPCODE_fstore: \
      case OPCODE_dstore: \
      case OPCODE_astore: \
	{ \
	  STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
	  break; \
	} \
      default: \
        error ("unrecogized wide sub-instruction"); \
      } \
  }

#define SPECIAL_THROW(IGNORED) \
  build_java_athrow (pop_value (throwable_type_node))

#define SPECIAL_BREAK NOT_IMPL1
#define IMPL          NOT_IMPL

#include "javaop.def"
#undef JAVAOP
   default:
    fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
  }
  return PC;
}

/* Return the opcode at PC in the code section pointed to by
   CODE_OFFSET.  */

static unsigned char
peek_opcode_at_pc (JCF *jcf, int code_offset, int pc)
{
  unsigned char opcode;
  long absolute_offset = (long)JCF_TELL (jcf);

  JCF_SEEK (jcf, code_offset);
  opcode = jcf->read_ptr [pc];
  JCF_SEEK (jcf, absolute_offset);
  return opcode;
}

/* Some bytecode compilers are emitting accurate LocalVariableTable
   attributes. Here's an example:
   
     PC   <t>store_<n>
     PC+1 ...
     
     Attribute "LocalVariableTable"
     slot #<n>: ... (PC: PC+1 length: L)
   
   This is accurate because the local in slot <n> really exists after
   the opcode at PC is executed, hence from PC+1 to PC+1+L.

   This procedure recognizes this situation and extends the live range
   of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
   length of the store instruction.)

   This function is used by `give_name_to_locals' so that a local's
   DECL features a DECL_LOCAL_START_PC such that the first related
   store operation will use DECL as a destination, not an unrelated
   temporary created for the occasion.

   This function uses a global (instruction_bits) `note_instructions' should
   have allocated and filled properly.  */

int
maybe_adjust_start_pc (struct JCF *jcf, int code_offset,
		       int start_pc, int slot)
{
  int first, index, opcode;
  int pc, insn_pc;
  int wide_found = 0;

  if (!start_pc)
    return start_pc;

  first = index = -1;

  /* Find last previous instruction and remember it */
  for (pc = start_pc-1; pc; pc--) 
    if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
      break;
  insn_pc = pc;

  /* Retrieve the instruction, handle `wide'. */  
  opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
  if (opcode == OPCODE_wide)
    {
      wide_found = 1;
      opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
    }

  switch (opcode)
    {
    case OPCODE_astore_0:
    case OPCODE_astore_1:
    case OPCODE_astore_2:
    case OPCODE_astore_3:
      first = OPCODE_astore_0;
      break;

    case OPCODE_istore_0:
    case OPCODE_istore_1:
    case OPCODE_istore_2:
    case OPCODE_istore_3:
      first = OPCODE_istore_0;
      break;
      
    case OPCODE_lstore_0:
    case OPCODE_lstore_1:
    case OPCODE_lstore_2:
    case OPCODE_lstore_3:
      first = OPCODE_lstore_0;
      break;

    case OPCODE_fstore_0:
    case OPCODE_fstore_1:
    case OPCODE_fstore_2:
    case OPCODE_fstore_3:
      first = OPCODE_fstore_0;
      break;

    case OPCODE_dstore_0:
    case OPCODE_dstore_1:
    case OPCODE_dstore_2:
    case OPCODE_dstore_3:
      first = OPCODE_dstore_0;
      break;

    case OPCODE_astore:
    case OPCODE_istore:
    case OPCODE_lstore:
    case OPCODE_fstore:
    case OPCODE_dstore:
      index = peek_opcode_at_pc (jcf, code_offset, pc);
      if (wide_found)
	{
	  int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
	  index = (other << 8) + index;
	}
      break;
    }

  /* Now we decide: first >0 means we have a <t>store_<n>, index >0
     means we have a <t>store. */
  if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
    start_pc = insn_pc;

  return start_pc;
}

/* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
   order, as specified by Java Language Specification.

   The problem is that while expand_expr will evaluate its sub-operands in
   left-to-right order, for variables it will just return an rtx (i.e.
   an lvalue) for the variable (rather than an rvalue).  So it is possible
   that a later sub-operand will change the register, and when the
   actual operation is done, it will use the new value, when it should
   have used the original value.

   We fix this by using save_expr.  This forces the sub-operand to be
   copied into a fresh virtual register,

   For method invocation, we modify the arguments so that a
   left-to-right order evaluation is performed. Saved expressions
   will, in CALL_EXPR order, be reused when the call will be expanded.

   We also promote outgoing args if needed.  */

tree
force_evaluation_order (tree node)
{
  if (flag_syntax_only)
    return node;
  if (TREE_CODE (node) == CALL_EXPR
      || TREE_CODE (node) == NEW_CLASS_EXPR
      || (TREE_CODE (node) == COMPOUND_EXPR
	  && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
	  && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) 
    {
      tree arg, cmp;

      arg = node;
      
      /* Position arg properly, account for wrapped around ctors. */
      if (TREE_CODE (node) == COMPOUND_EXPR)
        arg = TREE_OPERAND (node, 0);
      
      arg = TREE_OPERAND (arg, 1);
      
      /* An empty argument list is ok, just ignore it.  */
      if (!arg)
	return node;

      /* Not having a list of arguments here is an error. */ 
      gcc_assert (TREE_CODE (arg) == TREE_LIST);

      /* This reverses the evaluation order. This is a desired effect. */
      for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
	{
	  /* Promote types smaller than integer.  This is required by
	     some ABIs.  */
	  tree type = TREE_TYPE (TREE_VALUE (arg));
	  tree saved;
	  if (targetm.calls.promote_prototypes (type)
	      && INTEGRAL_TYPE_P (type)
	      && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
				      TYPE_SIZE (integer_type_node)))
	    TREE_VALUE (arg) = fold_convert (integer_type_node, TREE_VALUE (arg));

	  saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
	  cmp = (cmp == NULL_TREE ? saved :
		 build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
	  TREE_VALUE (arg) = saved;
	}
      
      if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
	TREE_SIDE_EFFECTS (cmp) = 1;

      if (cmp)
	{
	  cmp = build2 (COMPOUND_EXPR, TREE_TYPE (node), cmp, node);
	  if (TREE_TYPE (cmp) != void_type_node)
	    cmp = save_expr (cmp);
	  CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
	  TREE_SIDE_EFFECTS (cmp) = 1;
	  node = cmp;
	}
    }
  return node;
}

/* EXPR_WITH_FILE_LOCATION are used to keep track of the exact
   location where an expression or an identifier were encountered. It
   is necessary for languages where the frontend parser will handle
   recursively more than one file (Java is one of them).  */

tree
build_expr_wfl (tree node,
#ifdef USE_MAPPED_LOCATION
		source_location location
#else
		const char *file, int line, int col
#endif
)
{
  tree wfl;

#ifdef USE_MAPPED_LOCATION
  wfl = make_node (EXPR_WITH_FILE_LOCATION);
  SET_EXPR_LOCATION (wfl, location);
#else
  static const char *last_file = 0;
  static tree last_filenode = NULL_TREE;

  wfl = make_node (EXPR_WITH_FILE_LOCATION);

  EXPR_WFL_SET_LINECOL (wfl, line, col);
  if (file != last_file)
    {
      last_file = file;
      last_filenode = file ? get_identifier (file) : NULL_TREE;
    }
  EXPR_WFL_FILENAME_NODE (wfl) = last_filenode;
#endif
  EXPR_WFL_NODE (wfl) = node;
  if (node)
    {
      if (!TYPE_P (node))
	TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
      TREE_TYPE (wfl) = TREE_TYPE (node);
    }

  return wfl;
}

#ifdef USE_MAPPED_LOCATION
tree
expr_add_location (tree node, source_location location, bool statement)
{
  tree wfl;
#if 0
  /* FIXME. This optimization causes failures in code that expects an
     EXPR_WITH_FILE_LOCATION.  E.g. in resolve_qualified_expression_name. */
  if (node && ! (statement && flag_emit_class_files))
    {
      source_location node_loc = EXPR_LOCATION (node);
      if (node_loc == location || location == UNKNOWN_LOCATION)
	return node;
      if (node_loc == UNKNOWN_LOCATION
	  && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (node))))
	{
	  SET_EXPR_LOCATION (node, location);
	  return node;
	}
    }
#endif
  wfl = make_node (EXPR_WITH_FILE_LOCATION);
  SET_EXPR_LOCATION (wfl, location);
  EXPR_WFL_NODE (wfl) = node;
  if (statement && debug_info_level != DINFO_LEVEL_NONE)
    EXPR_WFL_EMIT_LINE_NOTE (wfl) = 1;
  if (node)
    {
      if (!TYPE_P (node))
	TREE_SIDE_EFFECTS (wfl) = TREE_SIDE_EFFECTS (node);
      TREE_TYPE (wfl) = TREE_TYPE (node);
    }

  return wfl;
}
#endif

/* Build a node to represent empty statements and blocks. */

tree
build_java_empty_stmt (void)
{
  tree t = build_empty_stmt ();
  CAN_COMPLETE_NORMALLY (t) = 1;
  return t;
}

/* Promote all args of integral type before generating any code.  */

static void
promote_arguments (void)
{
  int i;
  tree arg;
  for (arg = DECL_ARGUMENTS (current_function_decl), i = 0;
       arg != NULL_TREE;  arg = TREE_CHAIN (arg), i++)
    {
      tree arg_type = TREE_TYPE (arg);
      if (INTEGRAL_TYPE_P (arg_type)
	  && TYPE_PRECISION (arg_type) < 32)
	{
	  tree copy = find_local_variable (i, integer_type_node, -1);
	  java_add_stmt (build2 (MODIFY_EXPR, integer_type_node,
				 copy,
				 fold_convert (integer_type_node, arg)));
	}
      if (TYPE_IS_WIDE (arg_type))
	i++;
    }
}

#include "gt-java-expr.h"
