OSDN Git Service

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