OSDN Git Service

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