OSDN Git Service

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