Jakub Jelinek <jj@ultra.linux.cz>
[platform/upstream/gcc.git] / gcc / java / expr.c
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2    Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
26
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "real.h"
31 #include "rtl.h"
32 #include "flags.h"
33 #include "expr.h"
34 #include "java-tree.h"
35 #include "javaop.h"
36 #include "java-opcodes.h"
37 #include "jcf.h"
38 #include "java-except.h"
39 #include "parse.h"
40 #include "toplev.h"
41 #include "except.h"
42
43 static void flush_quick_stack PROTO ((void));
44 static void push_value PROTO ((tree));
45 static tree pop_value PROTO ((tree));
46 static void java_stack_swap PROTO ((void));
47 static void java_stack_dup PROTO ((int, int));
48 static tree build_java_athrow PROTO ((tree));
49 static void build_java_jsr PROTO ((tree, tree));
50 static void build_java_ret PROTO ((tree));
51 static void expand_java_multianewarray PROTO ((tree, int));
52 static void expand_java_arraystore PROTO ((tree));
53 static void expand_java_arrayload PROTO ((tree));
54 static void expand_java_array_length PROTO ((void));
55 static tree build_java_monitor PROTO ((tree, tree));
56 static void expand_java_pushc PROTO ((int, tree));
57 static void expand_java_return PROTO ((tree));
58 static void expand_java_NEW PROTO ((tree));
59 static void expand_java_INSTANCEOF PROTO ((tree));
60 static void expand_java_CHECKCAST PROTO ((tree));
61 static void expand_iinc PROTO ((unsigned int, int, int));
62 static void expand_java_binop PROTO ((tree, enum tree_code));
63 static void note_label PROTO ((int, int));
64 static void expand_compare PROTO ((enum tree_code, tree, tree, int));
65 static void expand_test PROTO ((enum tree_code, tree, int));
66 static void expand_cond PROTO ((enum tree_code, tree, int));
67 static void expand_java_goto PROTO ((int));
68 #if 0
69 static void expand_java_call PROTO ((int, int));
70 static void expand_java_ret PROTO ((tree)); 
71 #endif
72 static tree pop_arguments PROTO ((tree)); 
73 static void expand_invoke PROTO ((int, int, int)); 
74 static void expand_java_field_op PROTO ((int, int, int)); 
75 static void java_push_constant_from_pool PROTO ((struct JCF *, int)); 
76  
77 static tree operand_type[59];
78 extern struct obstack permanent_obstack;
79
80 void
81 init_expr_processing()
82 {
83   operand_type[21] = operand_type[54] = int_type_node;
84   operand_type[22] = operand_type[55] = long_type_node;
85   operand_type[23] = operand_type[56] = float_type_node;
86   operand_type[24] = operand_type[57] = double_type_node;
87   operand_type[25] = operand_type[58] = ptr_type_node;
88 }
89
90 /* We store the stack state in two places:
91    Within a basic block, we use the quick_stack, which is a
92    pushdown list (TREE_LISTs) of expression nodes.
93    This is the top part of the stack;  below that we use find_stack_slot.
94    At the end of a basic block, the quick_stack must be flushed
95    to the stack slot array (as handled by find_stack_slot).
96    Using quick_stack generates better code (especially when
97    compiled without optimization), because we do not have to
98    explicitly store and load trees to temporary variables.
99
100    If a variable is on the quick stack, it means the value of variable
101    when the quick stack was last flushed.  Conceptually, flush_quick_stack
102    saves all the the quick_stack elements in parellel.  However, that is
103    complicated, so it actually saves them (i.e. copies each stack value
104    to is home virtual register) from low indexes.  This allows a quick_stack
105    element at index i (counting from the bottom of stack the) to references
106    slot virtuals for register that are >= i, but not those that are deeper.
107    This convention makes most operations easier.  For example iadd works
108    even when the stack contains (reg[0], reg[1]):  It results in the
109    stack containing (reg[0]+reg[1]), which is OK.  However, some stack
110    operations are more complicated.  For example dup given a stack
111    containing (reg[0]) would yield (reg[0], reg[0]), which would violate
112    the convention, since stack value 1 would refer to a register with
113    lower index (reg[0]), which flush_quick_stack does not safely handle.
114    So dup cannot just add an extra element to the quick_stack, but iadd can.
115 */
116
117 tree quick_stack = NULL_TREE;
118
119 /* A free-list of unused permamnet TREE_LIST nodes. */
120 tree tree_list_free_list = NULL_TREE;
121
122 /* The stack pointer of the Java virtual machine.
123    This does include the size of the quick_stack. */
124
125 int stack_pointer;
126
127 unsigned char *linenumber_table;
128 int linenumber_count;
129
130 tree
131 truthvalue_conversion (expr)
132      tree expr;
133 {
134   /* It is simpler and generates better code to have only TRUTH_*_EXPR
135      or comparison expressions as truth values at this level.
136
137      This function should normally be identity for Java.  */
138
139   switch (TREE_CODE (expr))
140     {
141     case EQ_EXPR:
142     case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
143     case TRUTH_ANDIF_EXPR:
144     case TRUTH_ORIF_EXPR:
145     case TRUTH_AND_EXPR:
146     case TRUTH_OR_EXPR:
147     case ERROR_MARK:
148       return expr;
149
150     case INTEGER_CST:
151       return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
152
153     case REAL_CST:
154       return real_zerop (expr) ? boolean_false_node : boolean_true_node;
155
156     /* are these legal? XXX JH */
157     case NEGATE_EXPR:
158     case ABS_EXPR:
159     case FLOAT_EXPR:
160     case FFS_EXPR:
161       /* These don't change whether an object is non-zero or zero.  */
162       return truthvalue_conversion (TREE_OPERAND (expr, 0));
163
164     case COND_EXPR:
165       /* Distribute the conversion into the arms of a COND_EXPR.  */
166       return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
167                           truthvalue_conversion (TREE_OPERAND (expr, 1)),
168                           truthvalue_conversion (TREE_OPERAND (expr, 2))));
169
170     case NOP_EXPR:
171       /* If this is widening the argument, we can ignore it.  */
172       if (TYPE_PRECISION (TREE_TYPE (expr))
173           >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
174         return truthvalue_conversion (TREE_OPERAND (expr, 0));
175       /* fall through to default */
176
177     default:
178       return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
179     }
180 }
181
182 #ifdef JAVA_USE_HANDLES
183 /* Given a pointer to a handle, get a pointer to an object. */
184
185 tree
186 unhand_expr (expr)
187      tree expr;
188 {
189   tree field, handle_type;
190   expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
191   handle_type = TREE_TYPE (expr);
192   field = TYPE_FIELDS (handle_type);
193   expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
194   return expr;
195 }
196 #endif
197
198 /* Save any stack slots that happen to be in the quick_stack into their
199    home virtual register slots.
200
201    The copy order is from low stack index to high, to support the invariant
202    that the expression for a slot may contain decls for stack slots with
203    higher (or the same) index, but not lower. */
204
205 static void
206 flush_quick_stack ()
207 {
208   int stack_index = stack_pointer;
209   register tree prev, cur, next;
210
211   /* First reverse the quick_stack, and count the number of slots it has. */
212   for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
213     {
214       next = TREE_CHAIN (cur);
215       TREE_CHAIN (cur) = prev;
216       prev = cur;
217       stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
218     }
219   quick_stack = prev;
220
221   while (quick_stack != NULL_TREE)
222     {
223       tree decl;
224       tree node = quick_stack, type;
225       quick_stack = TREE_CHAIN (node);
226       TREE_CHAIN (node) = tree_list_free_list;
227       tree_list_free_list = node;
228       node = TREE_VALUE (node);
229       type = TREE_TYPE (node);
230
231       decl = find_stack_slot (stack_index, type);
232       if (decl != node)
233           expand_assignment (decl, node, 0, 0);
234       stack_index += 1 + TYPE_IS_WIDE (type);
235     }
236 }
237
238 void
239 push_type (type)
240      tree type;
241 {
242   int n_words;
243   type = promote_type (type);
244   n_words = 1 + TYPE_IS_WIDE (type);
245   if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
246     fatal ("stack overflow");
247   stack_type_map[stack_pointer++] = type;
248   n_words--;
249   while (--n_words >= 0)
250     stack_type_map[stack_pointer++] = TYPE_SECOND;
251 }
252
253 static void
254 push_value (value)
255      tree value;
256 {
257   tree type = TREE_TYPE (value);
258   if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
259     {
260       type = promote_type (type);
261       value = convert (type, value);
262     }
263   push_type (type);
264   if (tree_list_free_list == NULL_TREE)
265     quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
266   else
267     {
268       tree node = tree_list_free_list;
269       tree_list_free_list = TREE_CHAIN (tree_list_free_list);
270       TREE_VALUE (node) = value;
271       TREE_CHAIN (node) = quick_stack;
272       quick_stack = node;
273     }
274 }
275
276 /* Pop a type from the type stack.
277    TYPE is the expected type.   Return the actual type, which must be
278    convertible to TYPE, otherwise NULL_TREE is returned. */
279
280 tree
281 pop_type_0 (type)
282      tree type;
283 {
284   int n_words;
285   tree t;
286   if (TREE_CODE (type) == RECORD_TYPE)
287     type = promote_type (type);
288   n_words = 1 + TYPE_IS_WIDE (type);
289   if (stack_pointer < n_words)
290     fatal ("stack underflow");
291   while (--n_words > 0)
292     {
293       if (stack_type_map[--stack_pointer] != void_type_node)
294         fatal ("Invalid multi-word value on type stack");
295     }
296   t = stack_type_map[--stack_pointer];
297   if (type == NULL_TREE || t == type)
298     return t;
299   if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
300       && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
301       return t;
302   if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
303     {
304       if (type == ptr_type_node || type == object_ptr_type_node)
305         return t;
306       else if (t == ptr_type_node)  /* Special case for null reference. */
307         return type;
308       else if (can_widen_reference_to (t, type))
309         return t;
310       /* This is a kludge, but matches what Sun's verifier does.
311          It can be tricked, but is safe as long as type errors
312          (i.e. interface method calls) are caught at run-time. */
313       else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
314                && t == object_ptr_type_node)
315         return t;
316     }
317   return NULL_TREE;
318 }
319
320 /* Pop a type from the type stack.
321    TYPE is the expected type.  Return the actual type, which must be
322    convertible to TYPE, otherwise call error. */
323
324 tree
325 pop_type (type)
326      tree type;
327 {
328   tree t = pop_type_0 (type);
329   if (t != NULL_TREE)
330     return t;
331   error ("unexpected type on stack");
332   return type;
333 }
334
335 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
336    Handles array types and interfaces.  */
337
338 int
339 can_widen_reference_to (source_type, target_type)
340      tree source_type, target_type;
341 {
342   if (source_type == ptr_type_node || target_type == object_ptr_type_node)
343     return 1;
344
345   /* Get rid of pointers  */
346   if (TREE_CODE (source_type) == POINTER_TYPE)
347     source_type = TREE_TYPE (source_type);
348   if (TREE_CODE (target_type) == POINTER_TYPE)
349     target_type = TREE_TYPE (target_type);
350
351   if (source_type == target_type)
352     return 1;
353   else
354     {
355       source_type = HANDLE_TO_CLASS_TYPE (source_type);
356       target_type = HANDLE_TO_CLASS_TYPE (target_type);
357       if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
358         {
359           HOST_WIDE_INT source_length, target_length;
360           if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
361             return 0;
362           target_length = java_array_type_length (target_type);
363           if (target_length >= 0)
364             {
365               source_length = java_array_type_length (source_type);
366               if (source_length != target_length)
367                 return 0;
368             }
369           source_type = TYPE_ARRAY_ELEMENT (source_type);
370           target_type = TYPE_ARRAY_ELEMENT (target_type);
371           if (source_type == target_type)
372             return 1;
373           if (TREE_CODE (source_type) != POINTER_TYPE
374               || TREE_CODE (target_type) != POINTER_TYPE)
375             return 0;
376           return can_widen_reference_to (source_type, target_type);
377         }
378       else
379         {
380           int source_depth = class_depth (source_type);
381           int target_depth = class_depth (target_type);
382
383           if (CLASS_INTERFACE (TYPE_NAME (target_type)))
384             {
385               /* target_type is OK if source_type or source_type ancestors
386                  implement target_type. We handle multiple sub-interfaces  */
387
388               tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
389               int n = TREE_VEC_LENGTH (basetype_vec), i;
390               for (i=0 ; i < n; i++)
391                 if (can_widen_reference_to 
392                     (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
393                      target_type))
394                   return 1;
395                 if (n == 0)
396                   return 0;
397             }
398
399           for ( ; source_depth > target_depth;  source_depth--) 
400             {
401               source_type = TYPE_BINFO_BASETYPE (source_type, 0); 
402             }
403           return source_type == target_type;
404         }
405     }
406 }
407
408 static tree
409 pop_value (type)
410      tree type;
411 {
412   type = pop_type (type);
413   if (quick_stack)
414     {
415       tree node = quick_stack;
416       quick_stack = TREE_CHAIN (quick_stack);
417       TREE_CHAIN (node) = tree_list_free_list;
418       tree_list_free_list = node;
419       node = TREE_VALUE (node);
420       return node;
421     }
422   else
423     return find_stack_slot (stack_pointer, promote_type (type));
424 }
425
426
427 /* Pop and discrad the top COUNT stack slots. */
428
429 static void
430 java_stack_pop (count)
431      int count;
432 {
433   while (count > 0)
434     {
435       tree type, val;
436       if (stack_pointer == 0)
437         fatal ("stack underflow");
438       type = stack_type_map[stack_pointer - 1];
439       if (type == TYPE_SECOND)
440         {
441           count--;
442           if (stack_pointer == 1 || count <= 0)
443             fatal ("stack underflow");
444           type = stack_type_map[stack_pointer - 2];
445         }
446       val = pop_value (type);
447       count--;
448     }
449 }
450
451 /* Implement the 'swap' operator (to swap two top stack slots). */
452
453 static void
454 java_stack_swap ()
455 {
456   tree type1, type2;
457   rtx temp;
458   tree decl1, decl2;
459
460   if (stack_pointer < 2
461       || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
462       || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
463       || type1 == TYPE_SECOND || type2 == TYPE_SECOND
464       || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
465     fatal ("bad stack swap");
466
467   flush_quick_stack ();
468   decl1 = find_stack_slot (stack_pointer - 1, type1);
469   decl2 = find_stack_slot (stack_pointer - 2, type2);
470   temp = copy_to_reg (DECL_RTL (decl1));
471   emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
472   emit_move_insn (DECL_RTL (decl2), temp);
473   stack_type_map[stack_pointer - 1] = type2;
474   stack_type_map[stack_pointer - 2] = type1;
475 }
476
477 static void
478 java_stack_dup (size, offset)
479      int size, offset;
480 {
481   int low_index = stack_pointer - size - offset;
482   int dst_index;
483   if (low_index < 0)
484     error ("stack underflow - dup* operation");
485
486   flush_quick_stack ();
487
488   stack_pointer += size;
489   dst_index = stack_pointer;
490
491   for (dst_index = stack_pointer;  --dst_index >= low_index; )
492     {
493       tree type;
494       int src_index = dst_index - size;
495       if (src_index < low_index)
496         src_index = dst_index + size + offset;
497       type = stack_type_map [src_index];
498       if (type == TYPE_SECOND)
499         {
500           if (src_index <= low_index)
501             fatal ("dup operation splits 64-bit number");
502           stack_type_map[dst_index] = type;
503           src_index--;  dst_index--;
504           type = stack_type_map[src_index];
505           if (! TYPE_IS_WIDE (type))
506             fatal ("internal error - dup operation");
507         }
508       else if (TYPE_IS_WIDE (type))
509         fatal ("internal error - dup operation");
510       if (src_index != dst_index)
511         {
512           tree src_decl = find_stack_slot (src_index, type);
513           tree dst_decl = find_stack_slot (dst_index, type);
514           emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
515           stack_type_map[dst_index] = type;
516         }
517     }
518 }
519
520 /* Calls _Jv_Throw.  Discard the contents of the value stack. */
521
522 static tree
523 build_java_athrow (node)
524     tree node;
525 {
526   tree call;
527
528   call = build (CALL_EXPR,
529                 void_type_node,
530                 build_address_of (throw_node),
531                 build_tree_list (NULL_TREE, node),
532                 NULL_TREE);
533   TREE_SIDE_EFFECTS (call) = 1;
534   expand_expr_stmt (call);
535   java_stack_pop (stack_pointer);
536 }
537
538 /* Implementation for jsr/ret */
539
540 static void
541 build_java_jsr (where, ret)
542     tree where;
543     tree ret;
544 {
545   tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
546   push_value (ret_label);
547   flush_quick_stack ();
548   expand_goto (where);
549   expand_label (ret);
550 }
551
552 static void
553 build_java_ret (location)
554   tree location;
555 {
556   expand_computed_goto (location);
557 }
558  
559 /* Implementation of operations on array: new, load, store, length */
560
561 /* Array core info access macros */
562
563 #define JAVA_ARRAY_LENGTH_OFFSET(A)                                        \
564   size_binop (CEIL_DIV_EXPR,                                               \
565               (DECL_FIELD_BITPOS                                           \
566                   (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
567               size_int (BITS_PER_UNIT))
568
569 tree
570 decode_newarray_type (atype)
571   int atype;
572 {
573   switch (atype)
574     {
575     case 4:  return boolean_type_node;
576     case 5:  return char_type_node;
577     case 6:  return float_type_node;
578     case 7:  return double_type_node;
579     case 8:  return byte_type_node;
580     case 9:  return short_type_node;
581     case 10: return int_type_node;
582     case 11: return long_type_node;
583     default: return NULL_TREE;
584     }
585 }
586
587 /* Map primitive type to the code used by OPCODE_newarray. */
588
589 int
590 encode_newarray_type (type)
591      tree type;
592 {
593   if (type == boolean_type_node)
594     return 4;
595   else if (type == char_type_node)
596     return 5;
597   else if (type == float_type_node)
598     return 6;
599   else if (type == double_type_node)
600     return 7;
601   else if (type == byte_type_node)
602     return 8;
603   else if (type == short_type_node)
604     return 9;
605   else if (type == int_type_node)
606     return 10;
607   else if (type == long_type_node)
608     return 11;
609   else
610     fatal ("Can't compute type code - patch_newarray");
611 }
612
613 /* Build a call to _Jv_ThrowBadArrayIndex(), the
614    ArrayIndexOfBoundsException exception handler.  */
615
616 static tree
617 build_java_throw_out_of_bounds_exception (index)
618     tree index;
619 {
620   tree node = build (CALL_EXPR, int_type_node,
621                      build_address_of (soft_badarrayindex_node), 
622                      build_tree_list (NULL_TREE, index), NULL_TREE);
623   TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
624   return (node);
625 }
626
627 /* Return the length of an array. Doesn't perform any checking on the nature
628    or value of the array NODE. May be used to implement some bytecodes.  */
629
630 tree
631 build_java_array_length_access (node)
632     tree node;
633 {
634   tree type = TREE_TYPE (node);
635   HOST_WIDE_INT length;
636   if (!is_array_type_p (type))
637     fatal ("array length on a non-array reference");
638   length = java_array_type_length (type);
639   if (length >= 0)
640     return build_int_2 (length, 0);
641   return fold (build1 (INDIRECT_REF,
642                        int_type_node,
643                        fold (build (PLUS_EXPR, ptr_type_node,
644                                     node, 
645                                     JAVA_ARRAY_LENGTH_OFFSET(node)))));
646 }
647
648 /* Optionally checks an array against the NULL pointer, eventually throwing a
649    NullPointerException. It could replace signal handling, but tied to NULL.
650    ARG1: the pointer to check, ARG2: the expression to use if
651    the pointer is non-null and ARG3 the type that should be returned.   */
652
653 tree
654 build_java_arraynull_check (node, expr, type)
655     tree node ATTRIBUTE_UNUSED;
656     tree expr;
657     tree type ATTRIBUTE_UNUSED;
658 {
659 #if 0
660   static int java_array_access_throws_null_exception = 0;
661   node = ???;
662   if (java_array_access_throws_null_exception)
663       return (build (COND_EXPR, 
664                      type,
665                      build (EQ_EXPR, int_type_node, node, null_pointer_node),
666                      build_java_athrow (node), expr ));
667   else
668 #endif
669       return (expr);
670 }
671
672 static tree
673 java_array_data_offset (array)
674      tree array;
675 {
676   tree array_type = TREE_TYPE (TREE_TYPE (array));
677   tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
678   if (data_fld == NULL_TREE)
679     return size_in_bytes (array_type);
680   else
681     return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
682                         / BITS_PER_UNIT, 0);
683 }
684
685 /* Implement array indexing (either as l-value or r-value).
686    Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
687    Optionally performs bounds checking and/or test to NULL.
688    At this point, ARRAY should have been verified as an array.  */
689
690 tree
691 build_java_arrayaccess (array, type, index)
692     tree array, type, index;
693 {
694   tree arith, node, throw = NULL_TREE;
695
696   arith = fold (build (PLUS_EXPR, int_type_node,
697                        java_array_data_offset (array),
698                        fold (build (MULT_EXPR, int_type_node,
699                                     index, size_in_bytes(type)))));
700
701   if (flag_bounds_check)
702     {
703       /* Generate:
704        * (unsigned jint) INDEX >= (unsigned jint) LEN
705        *    && throw ArrayIndexOutOfBoundsException.
706        * Note this is equivalent to and more efficient than:
707        * INDEX < 0 || INDEX >= LEN && throw ... */
708       tree test;
709       tree len = build_java_array_length_access (array);
710       TREE_TYPE (len) = unsigned_int_type_node;
711       test = fold (build (GE_EXPR, boolean_type_node, 
712                                convert (unsigned_int_type_node, index),
713                                len));
714       if (! integer_zerop (test))
715         {
716           throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
717                          build_java_throw_out_of_bounds_exception (index));
718           /* allows expansion within COMPOUND */
719           TREE_SIDE_EFFECTS( throw ) = 1;
720         }
721     }
722
723   node = build1 (INDIRECT_REF, type, 
724                  fold (build (PLUS_EXPR, ptr_type_node, 
725                               array, 
726                               (throw ? build (COMPOUND_EXPR, int_type_node, 
727                                               throw, arith )
728                                      : arith))));
729
730   return (fold (build_java_arraynull_check (array, node, type)));
731 }
732
733 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
734    ARRAY_NODE. This function is used to retrieve something less vague than
735    a pointer type when indexing the first dimension of something like [[<t>.
736    May return a corrected type, if necessary, otherwise INDEXED_TYPE is
737    return unchanged.
738    As a side effect, it also makes sure that ARRAY_NODE is an array.  */
739
740 static tree
741 build_java_check_indexed_type (array_node, indexed_type)
742     tree array_node;
743     tree indexed_type;
744 {
745   tree elt_type;
746
747   if (!is_array_type_p (TREE_TYPE (array_node)))
748     fatal ("array indexing on a non-array reference");
749
750   elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
751
752   if (indexed_type == ptr_type_node )
753       return promote_type (elt_type);
754
755   /* BYTE/BOOLEAN store and load are used for both type */
756   if (indexed_type == byte_type_node && elt_type == boolean_type_node )
757     return boolean_type_node;
758
759   if (indexed_type != elt_type )
760     fatal ("type array element mismatch");
761   else
762     return indexed_type;
763 }
764
765 /* newarray triggers a call to _Jv_NewArray. This function should be called
766    with an integer code (the type of array to create) and get from the stack
767    the size of the dimmension.  */
768
769 tree
770 build_newarray (atype_value, length)
771      int atype_value;
772      tree length;
773 {
774   tree type = build_java_array_type (decode_newarray_type (atype_value),
775                                      TREE_CODE (length) == INTEGER_CST
776                                      ? TREE_INT_CST_LOW (length)
777                                      : -1);
778   return build (CALL_EXPR, promote_type (type),
779                 build_address_of (soft_newarray_node),
780                 tree_cons (NULL_TREE, 
781                            build_int_2 (atype_value, 0),
782                            build_tree_list (NULL_TREE, length)),
783                 NULL_TREE);
784 }
785
786 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
787    of the dimension. */
788
789 tree
790 build_anewarray (class_type, length)
791     tree class_type;
792     tree length;
793 {
794   tree type = build_java_array_type (class_type,
795                                      TREE_CODE (length) == INTEGER_CST
796                                      ? TREE_INT_CST_LOW (length)
797                                      : -1);
798   return build (CALL_EXPR, promote_type (type),
799                 build_address_of (soft_anewarray_node),
800                 tree_cons (NULL_TREE, length,
801                            tree_cons (NULL_TREE, build_class_ref (class_type),
802                                       build_tree_list (NULL_TREE,
803                                                        null_pointer_node))),
804                 NULL_TREE);
805 }
806
807 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
808
809 tree
810 build_new_array (type, length)
811      tree type;
812      tree length;
813 {
814   if (JPRIMITIVE_TYPE_P (type))
815     return build_newarray (encode_newarray_type (type), length);
816   else
817     return build_anewarray (TREE_TYPE (type), length);
818 }
819
820 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
821    class pointer, a number of dimensions and the matching number of
822    dimensions. The argument list is NULL terminated.  */
823
824 static void
825 expand_java_multianewarray (class_type, ndim)
826     tree class_type;
827     int  ndim;
828 {
829   int i;
830   tree args = build_tree_list( NULL_TREE, null_pointer_node );
831
832   for( i = 0; i < ndim; i++ )
833     args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
834
835   push_value (build (CALL_EXPR,
836                      promote_type (class_type),
837                      build_address_of (soft_multianewarray_node),
838                      tree_cons (NULL_TREE, build_class_ref (class_type),
839                                 tree_cons (NULL_TREE, 
840                                            build_int_2 (ndim, 0), args )),
841                      NULL_TREE));
842 }
843
844 /*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
845     ARRAY is an array type. May expand some bound checking and NULL
846     pointer checking. RHS_TYPE_NODE we are going to store. In the case
847     of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
848     INT. In those cases, we make the convertion.
849
850     if ARRAy is a reference type, the assignment is checked at run-time
851     to make sure that the RHS can be assigned to the array element
852     type. It is not necessary to generate this code if ARRAY is final.  */
853
854 static void
855 expand_java_arraystore (rhs_type_node)
856      tree rhs_type_node;
857 {
858   tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
859                                  && TYPE_PRECISION (rhs_type_node) <= 32) ? 
860                                  int_type_node : rhs_type_node);
861   tree index = pop_value (int_type_node);
862   tree array = pop_value (ptr_type_node);
863
864   rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
865
866   flush_quick_stack ();
867
868   index = save_expr (index);
869   array = save_expr (array);
870
871   if (TREE_CODE (rhs_type_node) == POINTER_TYPE
872       && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
873     {
874       tree check = build (CALL_EXPR, void_type_node,
875                           build_address_of (soft_checkarraystore_node),
876                           tree_cons (NULL_TREE, array,
877                                      build_tree_list (NULL_TREE, rhs_node)),
878                           NULL_TREE);
879       TREE_SIDE_EFFECTS (check) = 1;
880       expand_expr_stmt (check);
881     }
882   
883   expand_assignment (build_java_arrayaccess (array,
884                                              rhs_type_node,
885                                              index),
886                      rhs_node, 0, 0);
887 }
888
889 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
890    sure that LHS is an array type. May expand some bound checking and NULL
891    pointer checking.  
892    LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
893    BOOLEAN/SHORT, we push a promoted type back to the stack.
894 */
895
896 static void
897 expand_java_arrayload (lhs_type_node )
898     tree lhs_type_node;
899 {
900   tree load_node;
901   tree index_node = pop_value (int_type_node);
902   tree array_node = pop_value (ptr_type_node);
903
904   index_node = save_expr (index_node);
905   array_node = save_expr (array_node);
906   lhs_type_node   = build_java_check_indexed_type (array_node, lhs_type_node);
907
908   load_node = build_java_arrayaccess (array_node,
909                                       lhs_type_node,
910                                       index_node);
911
912   if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
913     load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
914   push_value (load_node);
915 }
916
917 /* Expands .length. Makes sure that we deal with and array and may expand
918    a NULL check on the array object.  */
919
920 static void
921 expand_java_array_length ()
922 {
923   tree array  = pop_value (ptr_type_node);
924   tree length = build_java_array_length_access (array);
925
926   push_value (build_java_arraynull_check (array, length, int_type_node));
927 }
928
929 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
930    either soft_monitorenter_node or soft_monitorexit_node.  */
931
932 static tree
933 build_java_monitor (call, object)
934     tree call;
935     tree object;
936 {
937   return (build (CALL_EXPR,
938                  void_type_node,
939                  build_address_of (call),
940                  build_tree_list (NULL_TREE, object),
941                  NULL_TREE));
942 }
943
944 /* Emit code for one of the PUSHC instructions. */
945
946 static void
947 expand_java_pushc (ival, type)
948      int ival;
949      tree type;
950 {
951   tree value;
952   if (type == ptr_type_node && ival == 0)
953     value = null_pointer_node;
954   else if (type == int_type_node || type == long_type_node)
955     {
956       value = build_int_2 (ival, ival < 0 ? -1 : 0);
957       TREE_TYPE (value) = type;
958     }
959   else if (type == float_type_node || type == double_type_node)
960     {
961       REAL_VALUE_TYPE x;
962 #ifdef REAL_ARITHMETIC
963       REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
964 #else
965       x = ival;
966 #endif
967       value = build_real (type, x);
968     }
969   else
970     fatal ("internal error in expand_java_pushc");
971   push_value (value);
972 }
973
974 static void
975 expand_java_return (type)
976      tree type;
977 {
978   if (type == void_type_node)
979     expand_null_return ();
980   else
981     {
982       tree retval = pop_value (type);
983       tree res = DECL_RESULT (current_function_decl);
984       retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
985       TREE_SIDE_EFFECTS (retval) = 1;
986       expand_return (retval);
987     }
988 }
989
990 tree
991 build_address_of (value)
992      tree value;
993 {
994   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
995 }
996
997 static void
998 expand_java_NEW (type)
999      tree type;
1000 {
1001   if (! CLASS_LOADED_P (type))
1002     load_class (type, 1);
1003   layout_class_methods (type);
1004   push_value (build (CALL_EXPR, promote_type (type),
1005                      build_address_of (alloc_object_node),
1006                      tree_cons (NULL_TREE, build_class_ref (type),
1007                                 build_tree_list (NULL_TREE,
1008                                                  size_in_bytes (type))),
1009                      NULL_TREE));
1010 }
1011
1012 static void
1013 expand_java_INSTANCEOF (type)
1014      tree type;
1015 {
1016   tree value = pop_value (object_ptr_type_node);
1017   value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
1018                  build_address_of (soft_instanceof_node),
1019                  tree_cons (NULL_TREE, value,
1020                             build_tree_list (NULL_TREE,
1021                                              build_class_ref (type))),
1022                  NULL_TREE);
1023   push_value (value);
1024 }
1025
1026 static void
1027 expand_java_CHECKCAST (type)
1028      tree type;
1029 {
1030   tree value = pop_value (ptr_type_node);
1031   value = build (CALL_EXPR, promote_type (type),
1032                  build_address_of (soft_checkcast_node),
1033                  tree_cons (NULL_TREE, build_class_ref (type),
1034                             build_tree_list (NULL_TREE, value)),
1035                  NULL_TREE);
1036   push_value (value);
1037 }
1038
1039 static void
1040 expand_iinc (local_var_index, ival, pc)
1041      unsigned int local_var_index;
1042      int ival;
1043      int pc;
1044 {
1045     tree local_var, res;
1046     tree constant_value;
1047
1048     flush_quick_stack ();
1049     local_var = find_local_variable (local_var_index, int_type_node, pc);
1050     constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1051     res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1052     expand_assignment (local_var, res, 0, 0);
1053 }
1054
1055       
1056 tree
1057 build_java_soft_divmod (op, type, op1, op2)
1058     enum tree_code op;
1059     tree type, op1, op2;
1060 {
1061   tree call = NULL;
1062   tree arg1 = convert (type, op1);
1063   tree arg2 = convert (type, op2);
1064
1065   if (type == int_type_node)
1066     {     
1067       switch (op)
1068         {
1069         case TRUNC_DIV_EXPR:
1070           call = soft_idiv_node;
1071           break;
1072         case TRUNC_MOD_EXPR:
1073           call = soft_irem_node;
1074           break;
1075         default:
1076           break;
1077         }
1078     }
1079   else if (type == long_type_node)
1080     {     
1081       switch (op)
1082         {
1083         case TRUNC_DIV_EXPR:
1084           call = soft_ldiv_node;
1085           break;
1086         case TRUNC_MOD_EXPR:
1087           call = soft_lrem_node;
1088           break;
1089         default:
1090           break;
1091         }
1092     }
1093
1094   if (! call)
1095     fatal ("Internal compiler error in build_java_soft_divmod");
1096                   
1097   call = build (CALL_EXPR, type,
1098                 build_address_of (call),
1099                 tree_cons (NULL_TREE, arg1,
1100                            build_tree_list (NULL_TREE, arg2)),
1101                 NULL_TREE);
1102           
1103   return call;
1104 }
1105
1106 tree
1107 build_java_binop (op, type, arg1, arg2)
1108      enum tree_code op;
1109      tree type, arg1, arg2;
1110 {
1111   tree mask;
1112   switch (op)
1113     {
1114     case URSHIFT_EXPR:
1115       {
1116         tree u_type = unsigned_type (type);
1117         arg1 = convert (u_type, arg1);
1118         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1119         return convert (type, arg1);
1120       }
1121     case LSHIFT_EXPR:
1122     case RSHIFT_EXPR:
1123       mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1124       arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1125       break;
1126
1127     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1128     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1129       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1130       {
1131         tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1132                                     boolean_type_node, arg1, arg2));
1133         tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1134         tree second_compare = fold (build (COND_EXPR, int_type_node,
1135                                            ifexp2, integer_zero_node,
1136                                            op == COMPARE_L_EXPR
1137                                            ? integer_negative_one_node
1138                                            : integer_one_node));
1139         return fold (build (COND_EXPR, int_type_node, ifexp1,
1140                             op == COMPARE_L_EXPR ? integer_one_node
1141                             : integer_negative_one_node,
1142                             second_compare));
1143       }
1144     case COMPARE_EXPR:
1145       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1146       {
1147         tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1148         tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1149         tree second_compare = fold ( build (COND_EXPR, int_type_node,
1150                                             ifexp2, integer_one_node,
1151                                             integer_zero_node));
1152         return fold (build (COND_EXPR, int_type_node,
1153                             ifexp1, integer_negative_one_node, second_compare));
1154       }      
1155     case TRUNC_DIV_EXPR:
1156     case TRUNC_MOD_EXPR:
1157       if (TREE_CODE (type) == REAL_TYPE
1158           && op == TRUNC_MOD_EXPR)
1159         {
1160           tree call;
1161           if (type != double_type_node)
1162             {
1163               arg1 = convert (double_type_node, arg1);
1164               arg2 = convert (double_type_node, arg2);
1165             }
1166           call = build (CALL_EXPR, double_type_node,
1167                         build_address_of (soft_fmod_node),
1168                         tree_cons (NULL_TREE, arg1,
1169                                    build_tree_list (NULL_TREE, arg2)),
1170                         NULL_TREE);
1171           if (type != double_type_node)
1172             call = convert (type, call);
1173           return call;
1174         }
1175       
1176       if (TREE_CODE (type) == INTEGER_TYPE
1177           && flag_use_divide_subroutine
1178           && ! flag_syntax_only)
1179         return build_java_soft_divmod (op, type, arg1, arg2);
1180       
1181       break;
1182     default:  ;
1183     }
1184   return fold (build (op, type, arg1, arg2));
1185 }
1186
1187 static void
1188 expand_java_binop (type, op)
1189      tree type;  enum tree_code op;
1190 {
1191   tree larg, rarg;
1192   tree ltype = type;
1193   tree rtype = type;
1194   switch (op)
1195     {
1196     case LSHIFT_EXPR:
1197     case RSHIFT_EXPR:
1198     case URSHIFT_EXPR:
1199       rtype = int_type_node;
1200       rarg = pop_value (rtype);
1201       break;
1202     default:
1203       rarg = pop_value (rtype);
1204     }
1205   larg = pop_value (ltype);
1206   push_value (build_java_binop (op, type, larg, rarg));
1207 }
1208
1209 /* Lookup the field named NAME in *TYPEP or its super classes.
1210    If not found, return NULL_TREE.
1211    (If the *TYPEP is not found, return error_mark_node.)
1212    If found, return the FIELD_DECL, and set *TYPEP to the
1213    class containing the field. */
1214
1215 tree
1216 lookup_field (typep, name)
1217      tree *typep;
1218      tree name;
1219 {
1220   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1221     {
1222       load_class (*typep, 1);
1223       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1224         return error_mark_node;
1225     }
1226   do
1227     {
1228       tree field, basetype_vec;
1229       int n, i;
1230
1231       for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1232         if (DECL_NAME (field) == name)
1233           return field;
1234
1235       /* Process implemented interfaces. */
1236       basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1237       n = TREE_VEC_LENGTH (basetype_vec);
1238       for (i = 0; i < n; i++)
1239         {
1240           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1241           if ((field = lookup_field (&t, name)))
1242             return field;
1243         }
1244       *typep = CLASSTYPE_SUPER (*typep);
1245     } while (*typep);
1246   return NULL_TREE;
1247 }
1248
1249 /* Look up the field named NAME in object SELF_VALUE,
1250    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1251    SELF_VALUE is NULL_TREE if looking for a static field. */
1252
1253 tree
1254 build_field_ref (self_value, self_class, name)
1255      tree self_value, self_class, name;
1256 {
1257   tree base_class = self_class;
1258   tree field_decl = lookup_field (&base_class, name);
1259   if (field_decl == NULL_TREE)
1260     {
1261       error ("field `%s' not found", IDENTIFIER_POINTER (name));
1262       return error_mark_node;
1263     }
1264   if (self_value == NULL_TREE)
1265     {
1266       return build_static_field_ref (field_decl);
1267     }
1268   else
1269     {
1270       tree base_handle_type = promote_type (base_class);
1271       if (base_handle_type != TREE_TYPE (self_value))
1272         self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1273 #ifdef JAVA_USE_HANDLES
1274       self_value = unhand_expr (self_value);
1275 #endif
1276       self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1277                            self_value);
1278       return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1279                           self_value, field_decl));
1280     }
1281 }
1282
1283 tree
1284 lookup_label (pc)
1285      int pc;
1286 {
1287   tree name;
1288   char buf[32];
1289   ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1290   name = get_identifier (buf);
1291   if (IDENTIFIER_LOCAL_VALUE (name))
1292     return IDENTIFIER_LOCAL_VALUE (name);
1293   else
1294     {
1295       /* The type of the address of a label is return_address_type_node. */
1296       tree decl = create_label_decl (name);
1297       LABEL_PC (decl) = pc;
1298       label_rtx (decl);
1299       return pushdecl (decl);
1300     }
1301 }
1302
1303 /* Generate a unique name for the purpose of loops and switches
1304    labels, and try-catch-finally blocks label or temporary variables.  */
1305
1306 tree
1307 generate_name ()
1308 {
1309   static int l_number = 0;
1310   char buff [32];
1311   ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1312   l_number++;
1313   return get_identifier (buff);
1314 }
1315
1316 tree
1317 create_label_decl (name)
1318      tree name;
1319 {
1320   tree decl;
1321   push_obstacks (&permanent_obstack, &permanent_obstack);
1322   decl = build_decl (LABEL_DECL, name, 
1323                      TREE_TYPE (return_address_type_node));
1324   pop_obstacks ();
1325   DECL_CONTEXT (decl) = current_function_decl;
1326   DECL_IGNORED_P (decl) = 1;
1327   return decl;
1328 }
1329
1330 /* This maps a bytecode offset (PC) to various flags. */
1331 char *instruction_bits;
1332
1333 static void
1334 note_label (current_pc, target_pc)
1335      int current_pc ATTRIBUTE_UNUSED, target_pc;
1336 {
1337   lookup_label (target_pc);
1338   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1339 }
1340
1341 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1342    where CONDITION is one of one the compare operators. */
1343
1344 static void
1345 expand_compare (condition, value1, value2, target_pc)
1346      enum tree_code condition;
1347      tree value1, value2;
1348      int target_pc;
1349 {
1350   tree target = lookup_label (target_pc);
1351   tree cond = fold (build (condition, boolean_type_node, value1, value2));
1352   expand_start_cond (truthvalue_conversion (cond), 0);
1353   expand_goto (target);
1354   expand_end_cond ();
1355 }
1356
1357 /* Emit code for a TEST-type opcode. */
1358
1359 static void
1360 expand_test (condition, type, target_pc)
1361      enum tree_code condition;
1362      tree type;
1363      int target_pc;
1364 {
1365   tree value1, value2;
1366   flush_quick_stack ();
1367   value1 = pop_value (type);
1368   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1369   expand_compare (condition, value1, value2, target_pc);
1370 }
1371
1372 /* Emit code for a COND-type opcode. */
1373
1374 static void
1375 expand_cond (condition, type, target_pc)
1376      enum tree_code condition;
1377      tree type;
1378      int target_pc;
1379 {
1380   tree value1, value2;
1381   flush_quick_stack ();
1382   /* note: pop values in opposite order */
1383   value2 = pop_value (type);
1384   value1 = pop_value (type);
1385   /* Maybe should check value1 and value2 for type compatibility ??? */
1386   expand_compare (condition, value1, value2, target_pc);
1387 }
1388
1389 static void
1390 expand_java_goto (target_pc)
1391      int target_pc;
1392 {
1393   tree target_label = lookup_label (target_pc);
1394   flush_quick_stack ();
1395   expand_goto (target_label);
1396 }
1397
1398 #if 0
1399 static void
1400 expand_java_call (target_pc, return_address)
1401      int target_pc, return_address;
1402 {
1403   tree target_label = lookup_label (target_pc);
1404   tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1405   push_value (value);
1406   flush_quick_stack ();
1407   expand_goto (target_label);
1408 }
1409
1410 static void
1411 expand_java_ret (return_address)
1412      tree return_address ATTRIBUTE_UNUSED;
1413 {
1414   warning ("ret instruction not implemented");
1415 #if 0
1416   tree target_label = lookup_label (target_pc);
1417   flush_quick_stack ();
1418   expand_goto (target_label);
1419 #endif
1420 }
1421 #endif
1422
1423 /* Recursive helper function to pop argument types during verifiation. */
1424
1425 void
1426 pop_argument_types (arg_types)
1427      tree arg_types;
1428 {
1429   if (arg_types == end_params_node)
1430     return;
1431   if (TREE_CODE (arg_types) == TREE_LIST)
1432     {
1433       pop_argument_types (TREE_CHAIN (arg_types));
1434       pop_type (TREE_VALUE (arg_types));
1435       return;
1436     }
1437   abort ();
1438 }
1439
1440 static tree
1441 pop_arguments (arg_types)
1442      tree arg_types;
1443 {
1444   if (arg_types == end_params_node)
1445     return NULL_TREE;
1446   if (TREE_CODE (arg_types) == TREE_LIST)
1447     {
1448       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1449       tree type = TREE_VALUE (arg_types);
1450       tree arg = pop_value (type);
1451       if (PROMOTE_PROTOTYPES
1452           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1453           && INTEGRAL_TYPE_P (type))
1454         arg = convert (integer_type_node, arg);
1455       return tree_cons (NULL_TREE, arg, tail);
1456     }
1457   abort ();
1458 }
1459
1460 /* Build an expression to initialize the class CLAS.
1461    if EXPR is non-NULL, returns an expression to first call the initializer
1462    (if it is needed) and then calls EXPR. */
1463
1464 tree
1465 build_class_init (clas, expr)
1466      tree clas, expr;
1467 {
1468   tree init;
1469   if (inherits_from_p (current_class, clas))
1470     return expr;
1471   init = build (CALL_EXPR, void_type_node,
1472                 build_address_of (soft_initclass_node),
1473                 build_tree_list (NULL_TREE, build_class_ref (clas)),
1474                 NULL_TREE);
1475   TREE_SIDE_EFFECTS (init) = 1;
1476   if (expr != NULL_TREE)
1477     {
1478       expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1479       TREE_SIDE_EFFECTS (expr) = 1;
1480       return expr;
1481     }
1482   return init;
1483 }
1484
1485 static tree methods_ident = NULL_TREE;
1486 static tree ncode_ident = NULL_TREE;
1487 tree dtable_ident = NULL_TREE;
1488
1489 tree
1490 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1491      tree method, method_type ATTRIBUTE_UNUSED, self_type,
1492           method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1493 {
1494   tree func;
1495   if (is_compiled_class (self_type))
1496     {
1497       make_decl_rtl (method, NULL, 1);
1498       func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1499     }
1500   else
1501     {
1502       /* We don't know whether the method has been (statically) compiled.
1503          Compile this code to get a reference to the method's code:
1504          
1505          SELF_TYPE->methods[METHOD_INDEX].ncode
1506          
1507          This is guaranteed to work (assuming SELF_TYPE has
1508          been initialized), since if the method is not compiled yet,
1509          its ncode points to a trampoline that forces compilation. */
1510       
1511       int method_index = 0;
1512       tree meth;
1513       tree ref = build_class_ref (self_type);
1514       ref = build1 (INDIRECT_REF, class_type_node, ref);
1515       if (ncode_ident == NULL_TREE)
1516         ncode_ident = get_identifier ("ncode");
1517       if (methods_ident == NULL_TREE)
1518         methods_ident = get_identifier ("methods");
1519       ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1520                    lookup_field (&class_type_node, methods_ident));
1521       for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1522            ; meth = TREE_CHAIN (meth))
1523         {
1524           if (method == meth)
1525             break;
1526           if (meth == NULL_TREE)
1527             fatal ("method '%s' not found in class",
1528                    IDENTIFIER_POINTER (DECL_NAME (method)));
1529           method_index++;
1530         }
1531       method_index *= int_size_in_bytes (method_type_node);
1532       ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1533                          ref, build_int_2 (method_index, 0)));
1534       ref = build1 (INDIRECT_REF, method_type_node, ref);
1535       func = build (COMPONENT_REF, nativecode_ptr_type_node,
1536                     ref,
1537                     lookup_field (&method_type_node, ncode_ident));
1538     }
1539   return func;
1540 }
1541
1542 tree
1543 invoke_build_dtable (is_invoke_interface, arg_list)
1544      int is_invoke_interface;
1545      tree arg_list;
1546 {
1547   tree dtable, objectref;
1548
1549   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1550
1551   /* If we're dealing with interfaces and if the objectref
1552      argument is an array then get the dispatch table of the class
1553      Object rather than the one from the objectref.  */
1554   objectref = (is_invoke_interface 
1555                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1556                object_type_node : TREE_VALUE (arg_list));
1557   
1558   if (dtable_ident == NULL_TREE)
1559     dtable_ident = get_identifier ("vtable");
1560   dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1561   dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1562                   lookup_field (&object_type_node, dtable_ident));
1563
1564   return dtable;
1565 }
1566
1567 tree 
1568 build_invokevirtual (dtable, method)
1569      tree dtable, method;
1570 {
1571   tree func;
1572   tree nativecode_ptr_ptr_type_node
1573     = build_pointer_type (nativecode_ptr_type_node);
1574   int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1575   /* Add one to skip "class" field of dtable, and one to skip unused
1576      vtable entry (for C++ compatibility). */
1577   method_index += 2;
1578   method_index
1579     *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1580   func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1581                       dtable, build_int_2 (method_index, 0)));
1582   func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1583
1584   return func;
1585 }
1586
1587 tree
1588 build_invokeinterface (dtable, method_name, method_signature)
1589      tree dtable, method_name, method_signature;
1590 {
1591   static tree class_ident = NULL_TREE;
1592   tree lookup_arg;
1593
1594   /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
1595      ensure that the selected method exists, is public and not
1596      abstract nor static.  */
1597             
1598   if (class_ident == NULL_TREE)
1599     class_ident = get_identifier ("class");
1600   
1601   dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1602   dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1603                   lookup_field (&dtable_type, class_ident));
1604   lookup_arg = build_tree_list (NULL_TREE, 
1605                                 (build_utf8_ref 
1606                                  (unmangle_classname
1607                                   (IDENTIFIER_POINTER(method_signature),
1608                                    IDENTIFIER_LENGTH(method_signature)))));
1609   lookup_arg = tree_cons (NULL_TREE, dtable,
1610                           tree_cons (NULL_TREE, build_utf8_ref (method_name),
1611                                      lookup_arg));
1612   return build (CALL_EXPR, ptr_type_node, 
1613                 build_address_of (soft_lookupinterfacemethod_node),
1614                 lookup_arg, NULL_TREE);
1615 }
1616   
1617 /* Expand one of the invoke_* opcodes.
1618    OCPODE is the specific opcode.
1619    METHOD_REF_INDEX is an index into the constant pool.
1620    NARGS is the number of arguments, or -1 if not specified. */
1621
1622 static void
1623 expand_invoke (opcode, method_ref_index, nargs)
1624      int opcode;
1625      int method_ref_index;
1626      int nargs ATTRIBUTE_UNUSED;
1627 {
1628   tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1629   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1630   tree self_type = get_class_constant
1631     (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1632   char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1633   tree call, func, method, arg_list, method_type;
1634
1635   if (! CLASS_LOADED_P (self_type))
1636     {
1637       load_class (self_type, 1);
1638       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1639         fatal ("failed to find class '%s'", self_name);
1640     }
1641   layout_class_methods (self_type);
1642
1643   if (method_name == init_identifier_node)
1644     method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1645                                       method_signature);
1646   else
1647     method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1648                                  method_name, method_signature);
1649   if (method == NULL_TREE)
1650     {
1651       error ("Class '%s' has no method named '%s' matching signature '%s'",
1652              self_name,
1653              IDENTIFIER_POINTER (method_name),
1654              IDENTIFIER_POINTER (method_signature));
1655     }
1656   /* Invoke static can't invoke static/abstract method */
1657   else if (opcode == OPCODE_invokestatic)
1658     {
1659       if (!METHOD_STATIC (method))
1660         {
1661           error ("invokestatic on non static method");
1662           method = NULL_TREE;
1663         }
1664       else if (METHOD_ABSTRACT (method))
1665         {
1666           error ("invokestatic on abstract method");
1667           method = NULL_TREE;
1668         }
1669     }
1670   else
1671     {
1672       if (METHOD_STATIC (method))
1673         {
1674           error ("invoke[non-static] on static method");
1675           method = NULL_TREE;
1676         }
1677     }
1678
1679   if (method == NULL_TREE)
1680     {
1681       method_type = get_type_from_signature (method_signature);
1682       pop_arguments (TYPE_ARG_TYPES (method_type));
1683       if (opcode != OPCODE_invokestatic) 
1684         pop_type (self_type);
1685       method_type = promote_type (TREE_TYPE (method_type));
1686       push_value (convert (method_type, integer_zero_node));
1687       return;
1688     }
1689
1690   method_type = TREE_TYPE (method);
1691   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1692   flush_quick_stack ();
1693
1694   func = NULL_TREE;
1695   if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1696       || (opcode == OPCODE_invokevirtual
1697           && (METHOD_PRIVATE (method)
1698               || METHOD_FINAL (method) 
1699               || CLASS_FINAL (TYPE_NAME (self_type)))))
1700     func = build_known_method_ref (method, method_type, self_type,
1701                                    method_signature, arg_list);
1702   else
1703     {
1704       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
1705                                          arg_list);
1706       if (opcode == OPCODE_invokevirtual)
1707         func = build_invokevirtual (dtable, method);
1708       else
1709         func = build_invokeinterface (dtable, method_name, method_signature);
1710     }
1711   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1712   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1713   TREE_SIDE_EFFECTS (call) = 1;
1714
1715   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1716     expand_expr_stmt (call);
1717   else
1718     {
1719       push_value (call);
1720       flush_quick_stack ();
1721     }
1722 }
1723
1724
1725 /* Expand an operation to extract from or store into a field.
1726    IS_STATIC is 1 iff the field is static.
1727    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
1728    FIELD_REF_INDEX is an index into the constant pool.  */
1729
1730 static void
1731 expand_java_field_op (is_static, is_putting, field_ref_index)
1732      int is_static;
1733      int is_putting;
1734      int field_ref_index;
1735 {
1736   tree self_type = 
1737       get_class_constant (current_jcf, 
1738                           COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 
1739                                                      field_ref_index));
1740   char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1741   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
1742   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
1743                                                   field_ref_index);
1744   tree field_type = get_type_from_signature (field_signature);
1745   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1746   tree field_ref;
1747   int is_error = 0;
1748   tree field_decl = lookup_field (&self_type, field_name);
1749   if (field_decl == error_mark_node)
1750     {
1751       is_error = 1;
1752     }
1753   else if (field_decl == NULL_TREE)
1754     {
1755       error ("Missing field '%s' in '%s'",
1756              IDENTIFIER_POINTER (field_name), self_name);
1757       is_error = 1;
1758     }
1759   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1760     {
1761       error ("Mismatching signature for field '%s' in '%s'",
1762              IDENTIFIER_POINTER (field_name), self_name);
1763       is_error = 1;
1764     }
1765   field_ref = is_static ? NULL_TREE : pop_value (self_type);
1766   if (is_error)
1767     {
1768       if (! is_putting)
1769         push_value (convert (field_type, integer_zero_node));
1770       flush_quick_stack ();
1771       return;
1772     }
1773
1774   /* Inline references to java.lang.PRIMTYPE.TYPE.
1775      In addition to being a useful (minor) optimization,
1776      this is also needed to avoid circularities in the implementation
1777      of these fields in libjava. */
1778   if (field_name == TYPE_identifier_node && ! is_putting
1779       && ! flag_emit_class_files && field_type == class_ptr_type
1780       && strncmp (self_name, "java.lang.", 10) == 0)
1781     {
1782       tree typ = build_primtype_type_ref (self_name);
1783       if (typ)
1784         {
1785           push_value (typ);
1786           return;
1787         }
1788     }
1789
1790   field_ref = build_field_ref (field_ref, self_type, field_name);
1791   if (is_static)
1792     field_ref = build_class_init (self_type, field_ref);
1793   if (is_putting)
1794     {
1795       flush_quick_stack ();
1796       if (FIELD_FINAL (field_decl))
1797         {
1798           if (DECL_CONTEXT (field_decl) != current_class)
1799             error_with_decl (field_decl,
1800                      "assignment to final field `%s' not in field's class");
1801           else if (FIELD_STATIC (field_decl))
1802             {
1803               if (!IS_CLINIT (current_function_decl))
1804                 error_with_decl (field_decl, 
1805              "assignment to final static field `%s' not in class initializer");
1806             }
1807           else
1808             {
1809               if (! DECL_CONSTRUCTOR_P (current_function_decl))
1810                 error_with_decl (field_decl, "assignment to final field `%s' "
1811                                  "not in constructor");
1812             }
1813         }
1814       expand_assignment (field_ref, new_value, 0, 0);
1815     }
1816   else
1817     push_value (field_ref);
1818 }
1819
1820 tree
1821 build_primtype_type_ref (self_name)
1822     char *self_name;
1823 {
1824   char *class_name = self_name+10;
1825   tree typ;
1826   if (strncmp(class_name, "Byte", 4) == 0)
1827     typ = byte_type_node;
1828   else if (strncmp(class_name, "Short", 5) == 0)
1829     typ = short_type_node;
1830   else if (strncmp(class_name, "Integer", 7) == 0)
1831     typ = int_type_node;
1832   else if (strncmp(class_name, "Long", 4) == 0)
1833     typ = long_type_node;
1834   else if (strncmp(class_name, "Float", 5) == 0)
1835     typ = float_type_node;
1836   else if (strncmp(class_name, "Double", 6) == 0)
1837     typ = double_type_node;
1838   else if (strncmp(class_name, "Boolean", 7) == 0)
1839     typ = boolean_type_node;
1840   else if (strncmp(class_name, "Char", 4) == 0)
1841     typ = char_type_node;
1842   else if (strncmp(class_name, "Void", 4) == 0)
1843     typ = void_type_node;
1844   else
1845     typ = NULL_TREE;
1846   if (typ != NULL_TREE)
1847     return build_class_ref (typ);
1848   else
1849     return NULL_TREE;
1850 }
1851
1852 void
1853 load_type_state (label)
1854      tree label;
1855 {
1856   int i;
1857   tree vec = LABEL_TYPE_STATE (label);
1858   int cur_length = TREE_VEC_LENGTH (vec);
1859   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1860   for (i = 0; i < cur_length; i++)
1861     type_map [i] = TREE_VEC_ELT (vec, i);
1862 }
1863
1864 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1865    dependant things, but they rely on gcc routines. This function is
1866    placed here because it uses things defined locally in parse.y. */
1867
1868 static tree
1869 case_identity (t, v)
1870      tree t __attribute__ ((__unused__));
1871      tree v;
1872 {
1873   return v;
1874 }
1875
1876 struct rtx_def *
1877 java_lang_expand_expr (exp, target, tmode, modifier)
1878      register tree exp;
1879      rtx target ATTRIBUTE_UNUSED;
1880      enum machine_mode tmode ATTRIBUTE_UNUSED;
1881      enum expand_modifier modifier ATTRIBUTE_UNUSED;
1882 {
1883   tree current;
1884
1885   switch (TREE_CODE (exp))
1886     {
1887     case NEW_ARRAY_INIT:
1888       {
1889         rtx tmp;
1890         tree array_type = TREE_TYPE (TREE_TYPE (exp));
1891         tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1892         tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1893         HOST_WIDE_INT ilength = java_array_type_length (array_type);
1894         tree length = build_int_2 (ilength, 0);
1895         tree init = TREE_OPERAND (exp, 0);
1896         tree array_decl;
1897 #if 0
1898         /* Enable this once we can set the vtable field statically.  FIXME */
1899         if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1900             && JPRIMITIVE_TYPE_P (element_type))
1901           {
1902             tree temp, value, init_decl;
1903             START_RECORD_CONSTRUCTOR (temp, object_type_node);
1904             PUSH_FIELD_VALUE (temp, "vtable",
1905                               null_pointer_node /* FIXME */
1906                               );
1907             PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1908             FINISH_RECORD_CONSTRUCTOR (temp);
1909             START_RECORD_CONSTRUCTOR (value, array_type);
1910             PUSH_SUPER_VALUE (value, temp);
1911             PUSH_FIELD_VALUE (value, "length", length);
1912             PUSH_FIELD_VALUE (value, "data", init);
1913             FINISH_RECORD_CONSTRUCTOR (value);
1914
1915             init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1916             pushdecl_top_level (init_decl);
1917             TREE_STATIC (init_decl) = 1;
1918             DECL_INITIAL (init_decl) = value;
1919             DECL_IGNORED_P (init_decl) = 1;
1920             TREE_READONLY (init_decl) = 1;
1921             make_decl_rtl (init_decl, NULL, 1);
1922             init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1923             return expand_expr (init, target, tmode, modifier);
1924           }
1925 #endif
1926         array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1927         expand_decl (array_decl);
1928         tmp = expand_assignment (array_decl,
1929                                  build_new_array (element_type, length),
1930                                  1, 0);
1931         if (TREE_CONSTANT (init)
1932             && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1933           {
1934             tree init_decl = build_decl (VAR_DECL, generate_name (),
1935                                          TREE_TYPE (init));
1936             pushdecl_top_level (init_decl);
1937             TREE_STATIC (init_decl) = 1;
1938             DECL_INITIAL (init_decl) = init;
1939             DECL_IGNORED_P (init_decl) = 1;
1940             TREE_READONLY (init_decl) = 1;
1941             make_decl_rtl (init_decl, NULL, 1);
1942             init = init_decl;
1943           }
1944         expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1945                                   build1 (INDIRECT_REF, array_type, array_decl),
1946                                   data_fld),
1947                            init, 0, 0);
1948         return tmp;
1949       }
1950     case BLOCK:
1951       if (BLOCK_EXPR_BODY (exp))
1952         {
1953           tree local;
1954           tree body = BLOCK_EXPR_BODY (exp);
1955           pushlevel (2);        /* 2 and above */
1956           expand_start_bindings (0);
1957           local = BLOCK_EXPR_DECLS (exp);
1958           while (local)
1959             {
1960               tree next = TREE_CHAIN (local);
1961               layout_decl (local, 0);
1962               expand_decl (pushdecl (local));
1963               local = next;
1964             }
1965           /* Avoid deep recursion for long block.  */
1966           while (TREE_CODE (body) == COMPOUND_EXPR)
1967             {
1968               expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1969               emit_queue ();
1970               body = TREE_OPERAND (body, 1);
1971             }
1972           expand_expr (body, const0_rtx, VOIDmode, 0);
1973           emit_queue ();
1974           poplevel (1, 1, 0);
1975           expand_end_bindings (getdecls (), 1, 0);
1976           return const0_rtx;
1977         }
1978       break;
1979
1980     case CASE_EXPR:
1981       {
1982         tree duplicate;
1983         if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1984                       build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), 
1985                       &duplicate) == 2)
1986           {
1987             EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1988             parse_error_context
1989               (wfl_operator, "Duplicate case label: `%s'",
1990                print_int_node (TREE_OPERAND (exp, 0)));
1991           }
1992         return const0_rtx;
1993       }
1994
1995     case DEFAULT_EXPR:
1996       pushcase (NULL_TREE, 0, 
1997                 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1998       return const0_rtx;
1999
2000     case SWITCH_EXPR:
2001       expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2002       expand_expr_stmt (TREE_OPERAND (exp, 1));
2003       expand_end_case (TREE_OPERAND (exp, 0));
2004       return const0_rtx;
2005
2006     case TRY_EXPR:
2007       /* We expand a try[-catch] block */
2008
2009       /* Expand the try block */
2010       expand_eh_region_start ();
2011       expand_expr_stmt (TREE_OPERAND (exp, 0));
2012       expand_start_all_catch ();
2013
2014       /* Expand all catch clauses (EH handlers) */
2015       for (current = TREE_OPERAND (exp, 1); current; 
2016            current = TREE_CHAIN (current))
2017         {
2018           tree type;
2019           tree catch = TREE_OPERAND (current, 0);
2020           tree decl = BLOCK_EXPR_DECLS (catch);
2021           type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2022           start_catch_handler (prepare_eh_table_type (type));
2023           expand_expr_stmt (TREE_OPERAND (current, 0));
2024
2025           expand_resume_after_catch ();
2026           end_catch_handler ();
2027         }
2028       expand_end_all_catch ();
2029       break;
2030
2031     default:
2032       fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2033              tree_code_name [TREE_CODE (exp)]);
2034     }
2035 }
2036
2037 void
2038 expand_byte_code (jcf, method)
2039      JCF *jcf;
2040      tree method;
2041 {
2042   int PC;
2043   int i;
2044   int saw_index;
2045   unsigned char *linenumber_pointer;
2046   int dead_code_index = -1;
2047
2048 #undef RET /* Defined by config/i386/i386.h */
2049 #undef AND /* Causes problems with opcodes for iand and land. */
2050 #undef PTR
2051 #define BCODE byte_ops
2052 #define BYTE_type_node byte_type_node
2053 #define SHORT_type_node short_type_node
2054 #define INT_type_node int_type_node
2055 #define LONG_type_node long_type_node
2056 #define CHAR_type_node char_type_node
2057 #define PTR_type_node ptr_type_node
2058 #define FLOAT_type_node float_type_node
2059 #define DOUBLE_type_node double_type_node
2060 #define VOID_type_node void_type_node
2061   jint INT_temp;
2062   unsigned char* byte_ops;
2063   long length = DECL_CODE_LENGTH (method);
2064
2065   stack_pointer = 0;
2066   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2067   byte_ops = jcf->read_ptr;
2068
2069 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2070 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2071 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2072 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2073
2074 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2075
2076   instruction_bits = oballoc (length + 1);
2077   bzero (instruction_bits, length + 1);
2078
2079   /* We make an initial pass of the line number table, to note
2080      which instructions have associated line number entries. */
2081   linenumber_pointer = linenumber_table;
2082   for (i = 0; i < linenumber_count; i++)
2083     {
2084       int pc = GET_u2 (linenumber_pointer);
2085       linenumber_pointer += 4;
2086       if (pc >= length)
2087         warning ("invalid PC in line number table");
2088       else
2089         {
2090           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2091             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2092           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2093         }
2094     }  
2095
2096   /* Do a preliminary pass.
2097    * This figures out which PC can be the targets of jumps. */
2098   for (PC = 0; PC < length;)
2099     {
2100       int oldpc = PC; /* PC at instruction start. */
2101       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
2102       switch (byte_ops[PC++])
2103         {
2104 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2105         case OPCODE: \
2106           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2107           break;
2108
2109 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2110
2111 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2112 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2113 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2114 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2115 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2116 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2117 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2118 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2119
2120 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2121   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2122 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2123   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2124 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2125 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2126 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2127 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2128
2129 /* two forms of wide instructions */
2130 #define PRE_SPECIAL_WIDE(IGNORE) \
2131   { \
2132     int modified_opcode = IMMEDIATE_u1; \
2133     if (modified_opcode == OPCODE_iinc) \
2134       { \
2135         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2136         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
2137       } \
2138     else \
2139       { \
2140         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2141       } \
2142   }
2143
2144 /* nothing */ /* XXX JH */
2145
2146 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2147
2148 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2149
2150 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2151 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2152           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2153 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2154 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2155 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2156 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2157 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2158 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2159 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2160
2161 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2162 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2163 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2164   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2165   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2166 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2167   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2168   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2169
2170 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
2171
2172 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2173   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2174
2175 #define PRE_LOOKUP_SWITCH                                               \
2176   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
2177     NOTE_LABEL (default_offset+oldpc);                                  \
2178     if (npairs >= 0)                                                    \
2179       while (--npairs >= 0) {                                           \
2180        jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
2181        jint offset = IMMEDIATE_s4;                                      \
2182        NOTE_LABEL (offset+oldpc); }                                     \
2183   }
2184
2185 #define PRE_TABLE_SWITCH                                \
2186   { jint default_offset = IMMEDIATE_s4;                 \
2187     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
2188     NOTE_LABEL (default_offset+oldpc);                  \
2189     if (low <= high)                                    \
2190      while (low++ <= high) {                            \
2191        jint offset = IMMEDIATE_s4;                      \
2192        NOTE_LABEL (offset+oldpc); }                     \
2193   }
2194
2195 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2196 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2197 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2198   (void)(IMMEDIATE_u2); \
2199   PC += 2 * IS_INTERFACE /* for invokeinterface */;
2200
2201 #include "javaop.def"
2202 #undef JAVAOP
2203         }
2204     } /* for */
2205
2206   if (! verify_jvm_instructions (jcf, byte_ops, length))
2207     return;
2208
2209   /* Translate bytecodes to rtl instructions. */
2210   linenumber_pointer = linenumber_table;
2211   for (PC = 0; PC < length;)
2212     {
2213       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2214         {
2215           tree label = lookup_label (PC);
2216           flush_quick_stack ();
2217           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2218             expand_label (label);
2219           if (LABEL_VERIFIED (label) || PC == 0)
2220             load_type_state (label);
2221         }
2222
2223       if (! (instruction_bits [PC] & BCODE_VERIFIED))
2224         {
2225           if (dead_code_index == -1)
2226             {
2227               /* This is the start of a region of unreachable bytecodes.
2228                  They still need to be processed in order for EH ranges
2229                  to get handled correctly.  However, we can simply
2230                  replace these bytecodes with nops.  */
2231               dead_code_index = PC;
2232             }
2233           
2234           /* Turn this bytecode into a nop.  */
2235           byte_ops[PC] = 0x0;
2236         }
2237        else
2238         {
2239           if (dead_code_index != -1)
2240             {
2241               /* We've just reached the end of a region of dead code.  */
2242               warning ("Unreachable bytecode from %d to before %d.",
2243                        dead_code_index, PC);
2244               dead_code_index = -1;
2245             }
2246         }
2247
2248       /* Handle possible line number entry for this PC.
2249
2250          This code handles out-of-order and multiple linenumbers per PC,
2251          but is optimized for the case of line numbers increasing
2252          monotonically with PC. */
2253       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2254         {
2255           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2256               || GET_u2 (linenumber_pointer) != PC)
2257             linenumber_pointer = linenumber_table;
2258           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2259             {
2260               int pc = GET_u2 (linenumber_pointer);
2261               linenumber_pointer += 4;
2262               if (pc == PC)
2263                 {
2264                   lineno = GET_u2 (linenumber_pointer - 2);
2265                   emit_line_note (input_filename, lineno);
2266                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2267                     break;
2268                 }
2269             }
2270         }
2271       maybe_start_try (PC);
2272       maybe_pushlevels (PC);
2273
2274       PC = process_jvm_instruction (PC, byte_ops, length);
2275
2276       maybe_poplevels (PC);
2277       maybe_end_try (PC);
2278     } /* for */
2279   
2280   if (dead_code_index != -1)
2281     {
2282       /* We've just reached the end of a region of dead code.  */
2283       warning ("Unreachable bytecode from %d to the end of the method.", 
2284               dead_code_index);
2285     }
2286 }
2287
2288 static void
2289 java_push_constant_from_pool (jcf, index)
2290      JCF *jcf;
2291      int index;
2292 {
2293   tree c;
2294   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2295     {
2296       tree name;
2297       push_obstacks (&permanent_obstack, &permanent_obstack);
2298       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2299       index = alloc_name_constant (CONSTANT_String, name);
2300       c = build_ref_from_constant_pool (index);
2301       TREE_TYPE (c) = promote_type (string_type_node);
2302       pop_obstacks ();
2303     }
2304   else
2305     c = get_constant (jcf, index);
2306   push_value (c);
2307
2308
2309 int
2310 process_jvm_instruction (PC, byte_ops, length)
2311      int PC;
2312      unsigned char* byte_ops;
2313      long length ATTRIBUTE_UNUSED;
2314
2315   const char *opname; /* Temporary ??? */
2316   int oldpc = PC; /* PC at instruction start. */
2317
2318   /* If the instruction is at the beginning of a exception handler,
2319      replace the top of the stack with the thrown object reference */
2320   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2321     {
2322       tree type = pop_type (ptr_type_node);
2323       push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2324     }
2325
2326   switch (byte_ops[PC++])
2327     {
2328 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2329     case OPCODE: \
2330       opname = #OPNAME; \
2331       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2332       break;
2333
2334 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
2335   {                                                                     \
2336     int saw_index = 0;                                                  \
2337     int index     = OPERAND_VALUE;                                      \
2338     build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2339   }
2340
2341 #define JSR(OPERAND_TYPE, OPERAND_VALUE)                \
2342   {                                                     \
2343     tree where = lookup_label (oldpc+OPERAND_VALUE);    \
2344     tree ret   = lookup_label (PC);                     \
2345     build_java_jsr (where, ret);                        \
2346     load_type_state (ret);                              \
2347   }
2348
2349 /* Push a constant onto the stack. */
2350 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2351   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
2352     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2353     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2354
2355 /* internal macro added for use by the WIDE case */
2356 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2357   push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2358
2359 /* Push local variable onto the opcode stack. */
2360 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2361   { \
2362     /* have to do this since OPERAND_VALUE may have side-effects */ \
2363     int opvalue = OPERAND_VALUE; \
2364     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2365   }
2366
2367 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2368   expand_java_return (OPERAND_TYPE##_type_node)
2369
2370 #define REM_EXPR TRUNC_MOD_EXPR
2371 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2372   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2373
2374 #define FIELD(IS_STATIC, IS_PUT) \
2375   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2376
2377 #define TEST(OPERAND_TYPE, CONDITION) \
2378   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2379
2380 #define COND(OPERAND_TYPE, CONDITION) \
2381   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2382
2383 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2384   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2385
2386 #define BRANCH_GOTO(OPERAND_VALUE) \
2387   expand_java_goto (oldpc + OPERAND_VALUE)
2388
2389 #define BRANCH_CALL(OPERAND_VALUE) \
2390   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2391
2392 #if 0
2393 #define BRANCH_RETURN(OPERAND_VALUE) \
2394   { \
2395     tree type = OPERAND_TYPE##_type_node; \
2396     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2397     expand_java_ret (value); \
2398   }
2399 #endif
2400
2401 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2402           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2403           fprintf (stderr, "(not implemented)\n")
2404 #define NOT_IMPL1(OPERAND_VALUE) \
2405           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2406           fprintf (stderr, "(not implemented)\n")
2407
2408 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2409
2410 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2411
2412 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2413
2414 #define STACK_SWAP(COUNT) java_stack_swap()
2415
2416 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2417 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2418 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2419
2420 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2421   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2422
2423 #define LOOKUP_SWITCH \
2424   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
2425     tree selector = pop_value (INT_type_node); \
2426     tree duplicate, label; \
2427     tree type = TREE_TYPE (selector); \
2428     flush_quick_stack (); \
2429     expand_start_case (0, selector, type, "switch statement");\
2430     push_momentary (); \
2431     while (--npairs >= 0) \
2432       { \
2433         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2434         tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2435         TREE_TYPE (value) = type; \
2436         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2437         pushcase (value, convert, label, &duplicate); \
2438         expand_java_goto (oldpc + offset); \
2439       } \
2440     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2441     pushcase (NULL_TREE, 0, label, &duplicate); \
2442     expand_java_goto (oldpc + default_offset); \
2443     pop_momentary (); \
2444     expand_end_case (selector); \
2445   }
2446
2447 #define TABLE_SWITCH \
2448   { jint default_offset = IMMEDIATE_s4; \
2449     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2450     tree selector = pop_value (INT_type_node); \
2451     tree duplicate, label; \
2452     tree type = TREE_TYPE (selector); \
2453     flush_quick_stack (); \
2454     expand_start_case (0, selector, type, "switch statement");\
2455     push_momentary (); \
2456     for (; low <= high; low++) \
2457       { \
2458         jint offset = IMMEDIATE_s4; \
2459         tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2460         TREE_TYPE (value) = type; \
2461         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2462         pushcase (value, convert, label, &duplicate); \
2463         expand_java_goto (oldpc + offset); \
2464       } \
2465     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2466     pushcase (NULL_TREE, 0, label, &duplicate); \
2467     expand_java_goto (oldpc + default_offset); \
2468     pop_momentary (); \
2469     expand_end_case (selector); \
2470   }
2471
2472 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2473   { int opcode = byte_ops[PC-1]; \
2474     int method_ref_index = IMMEDIATE_u2; \
2475     int nargs; \
2476     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
2477     else nargs = -1; \
2478     expand_invoke (opcode, method_ref_index, nargs); \
2479   }
2480
2481 /* Handle new, checkcast, instanceof */
2482 #define OBJECT(TYPE, OP) \
2483   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2484
2485 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2486
2487 #define ARRAY_LOAD(OPERAND_TYPE)                        \
2488   {                                                     \
2489     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
2490   }
2491
2492 #define ARRAY_STORE(OPERAND_TYPE)                       \
2493   {                                                     \
2494     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2495   }
2496
2497 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2498 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2499 #define ARRAY_NEW_PTR()                                                 \
2500     push_value (build_anewarray (get_class_constant (current_jcf,       \
2501                                                      IMMEDIATE_u2),     \
2502                                  pop_value (int_type_node)));
2503 #define ARRAY_NEW_NUM()                         \
2504   {                                             \
2505     int atype = IMMEDIATE_u1;                   \
2506     push_value (build_newarray (atype, pop_value (int_type_node)));\
2507   }
2508 #define ARRAY_NEW_MULTI()                                       \
2509   {                                                             \
2510     tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
2511     int  ndims = IMMEDIATE_u1;                                  \
2512     expand_java_multianewarray( class, ndims );                 \
2513   }
2514
2515 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2516   push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2517                             pop_value (OPERAND_TYPE##_type_node))));
2518
2519 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
2520   {                                                                      \
2521     push_value (build1 (NOP_EXPR, int_type_node,                         \
2522                         (convert (TO_TYPE##_type_node,                   \
2523                                   pop_value (FROM_TYPE##_type_node))))); \
2524   }
2525
2526 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
2527   {                                                             \
2528     push_value (convert (TO_TYPE##_type_node,                   \
2529                          pop_value (FROM_TYPE##_type_node)));   \
2530   }
2531
2532 /* internal macro added for use by the WIDE case 
2533    Added TREE_TYPE (decl) assignment, apbianco  */
2534 #define STORE_INTERNAL(OPTYPE, OPVALUE)                 \
2535   {                                                     \
2536     tree decl, value;                                   \
2537     int var = OPVALUE;                                  \
2538     tree type = OPTYPE;                                 \
2539     value = pop_value (type);                           \
2540     type = TREE_TYPE (value);                           \
2541     decl = find_local_variable (var, type, oldpc);      \
2542     set_local_type (var, type );                        \
2543     expand_assignment (decl, value, 0, 0);              \
2544   }
2545
2546 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2547   { \
2548     /* have to do this since OPERAND_VALUE may have side-effects */ \
2549     int opvalue = OPERAND_VALUE; \
2550     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2551   }
2552
2553 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2554   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2555
2556 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2557 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
2558
2559 #define MONITOR_OPERATION(call)                 \
2560   {                                             \
2561     tree o = pop_value (ptr_type_node);         \
2562     tree c;                                     \
2563     flush_quick_stack ();                       \
2564     c = build_java_monitor (call, o);           \
2565     TREE_SIDE_EFFECTS (c) = 1;                  \
2566     expand_expr_stmt (c);                       \
2567   }
2568
2569 #define SPECIAL_IINC(IGNORED) \
2570   { \
2571     unsigned int local_var_index = IMMEDIATE_u1; \
2572     int ival = IMMEDIATE_s1; \
2573     expand_iinc(local_var_index, ival, oldpc); \
2574   }
2575
2576 #define SPECIAL_WIDE(IGNORED) \
2577   { \
2578     int modified_opcode = IMMEDIATE_u1; \
2579     unsigned int local_var_index = IMMEDIATE_u2; \
2580     switch (modified_opcode) \
2581       { \
2582       case OPCODE_iinc: \
2583         { \
2584           int ival = IMMEDIATE_s2; \
2585           expand_iinc (local_var_index, ival, oldpc); \
2586           break; \
2587         } \
2588       case OPCODE_iload: \
2589       case OPCODE_lload: \
2590       case OPCODE_fload: \
2591       case OPCODE_dload: \
2592       case OPCODE_aload: \
2593         { \
2594           /* duplicate code from LOAD macro */ \
2595           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2596           break; \
2597         } \
2598       case OPCODE_istore: \
2599       case OPCODE_lstore: \
2600       case OPCODE_fstore: \
2601       case OPCODE_dstore: \
2602       case OPCODE_astore: \
2603         { \
2604           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2605           break; \
2606         } \
2607       default: \
2608         error ("unrecogized wide sub-instruction"); \
2609       } \
2610   }
2611
2612 #define SPECIAL_THROW(IGNORED) \
2613   build_java_athrow (pop_value (throwable_type_node))
2614
2615 #define SPECIAL_BREAK NOT_IMPL1
2616 #define IMPL          NOT_IMPL
2617
2618 #include "javaop.def"
2619 #undef JAVAOP
2620    default:
2621     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2622   }
2623   return PC;
2624 }
2625
2626 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2627    order, as specified by Java Language Specification.
2628
2629    The problem is that while expand_expr will evaluate its sub-operands in
2630    left-to-right order, for variables it will just return an rtx (i.e.
2631    an lvalue) for the variable (rather than an rvalue).  So it is possible
2632    that a later sub-operand will change the register, and when the
2633    actual operation is done, it will use the new value, when it should
2634    have used the original value.
2635
2636    We fix this by using save_expr.  This forces the sub-operand to be
2637    copied into a fresh virtual register,
2638
2639    For method invocation, we modify the arguments so that a
2640    left-to-right order evaluation is performed. Saved expressions
2641    will, in CALL_EXPR order, be reused when the call will be expanded.
2642 */
2643
2644 tree
2645 force_evaluation_order (node)
2646      tree  node;
2647 {
2648   if (flag_syntax_only)
2649     return node;
2650   if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
2651     {
2652       if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2653         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2654     }
2655   else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2656     {
2657       tree arg, cmp;
2658
2659       if (!TREE_OPERAND (node, 1))
2660         return node;
2661
2662       /* This reverses the evaluation order. This is a desired effect. */
2663       for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1); 
2664            arg; arg = TREE_CHAIN (arg))
2665         {
2666           tree saved = save_expr (TREE_VALUE (arg));
2667           cmp = (cmp == NULL_TREE ? saved :
2668                  build (COMPOUND_EXPR, void_type_node, cmp, saved));
2669           TREE_VALUE (arg) = saved;
2670         }
2671       
2672       if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
2673         TREE_SIDE_EFFECTS (cmp) = 1;
2674
2675       if (cmp)
2676         {
2677           cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
2678           CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
2679           TREE_SIDE_EFFECTS (cmp) = 1;
2680           node = cmp;
2681         }
2682     }
2683   return node;
2684 }