OSDN Git Service

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