OSDN Git Service

Fix for PR java/5812.
[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;
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   /* Avoid the check if OBJECT was just loaded from the same array. */
841   if (TREE_CODE (object) == ARRAY_REF)
842     {
843       tree target;
844       tree source = TREE_OPERAND (object, 0); /* COMPONENT_REF. */
845       source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
846       source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
847       if (TREE_CODE (source) == SAVE_EXPR)
848         source = TREE_OPERAND (source, 0);
849       
850       target = array;
851       if (TREE_CODE (target) == SAVE_EXPR)
852         target = TREE_OPERAND (target, 0);
853       
854       if (source == target)
855         return build1 (NOP_EXPR, array_type_p, array);
856     }
857
858   /* Build an invocation of _Jv_CheckArrayStore */
859   check = build (CALL_EXPR, void_type_node,
860                  build_address_of (soft_checkarraystore_node),
861                  tree_cons (NULL_TREE, array,
862                             build_tree_list (NULL_TREE, object)),
863                  NULL_TREE);
864   TREE_SIDE_EFFECTS (check) = 1;
865
866   return check;
867 }
868
869 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
870    ARRAY_NODE. This function is used to retrieve something less vague than
871    a pointer type when indexing the first dimension of something like [[<t>.
872    May return a corrected type, if necessary, otherwise INDEXED_TYPE is
873    return unchanged.
874    As a side effect, it also makes sure that ARRAY_NODE is an array.  */
875
876 static tree
877 build_java_check_indexed_type (array_node, indexed_type)
878     tree array_node;
879     tree indexed_type;
880 {
881   tree elt_type;
882
883   if (!is_array_type_p (TREE_TYPE (array_node)))
884     abort ();
885
886   elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
887
888   if (indexed_type == ptr_type_node )
889       return promote_type (elt_type);
890
891   /* BYTE/BOOLEAN store and load are used for both type */
892   if (indexed_type == byte_type_node && elt_type == boolean_type_node )
893     return boolean_type_node;
894
895   if (indexed_type != elt_type )
896     abort ();
897   else
898     return indexed_type;
899 }
900
901 /* newarray triggers a call to _Jv_NewPrimArray. This function should be 
902    called with an integer code (the type of array to create), and the length
903    of the array to create.  */
904
905 tree
906 build_newarray (atype_value, length)
907      int atype_value;
908      tree length;
909 {
910   tree type_arg;
911
912   tree prim_type = decode_newarray_type (atype_value);
913   tree type
914     = build_java_array_type (prim_type,
915                              host_integerp (length, 0) == INTEGER_CST
916                              ? tree_low_cst (length, 0) : -1);
917
918   /* If compiling to native, pass a reference to the primitive type class 
919      and save the runtime some work. However, the bytecode generator
920      expects to find the type_code int here. */
921   if (flag_emit_class_files)
922     type_arg = build_int_2 (atype_value, 0);
923   else
924     type_arg = build_class_ref (prim_type);
925
926   return build (CALL_EXPR, promote_type (type),
927                 build_address_of (soft_newarray_node),
928                 tree_cons (NULL_TREE, 
929                            type_arg,
930                            build_tree_list (NULL_TREE, length)),
931                 NULL_TREE);
932 }
933
934 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
935    of the dimension. */
936
937 tree
938 build_anewarray (class_type, length)
939     tree class_type;
940     tree length;
941 {
942   tree type
943     = build_java_array_type (class_type,
944                              host_integerp (length, 0)
945                              ? tree_low_cst (length, 0) : -1);
946
947   return build (CALL_EXPR, promote_type (type),
948                 build_address_of (soft_anewarray_node),
949                 tree_cons (NULL_TREE, length,
950                            tree_cons (NULL_TREE, build_class_ref (class_type),
951                                       build_tree_list (NULL_TREE,
952                                                        null_pointer_node))),
953                 NULL_TREE);
954 }
955
956 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
957
958 tree
959 build_new_array (type, length)
960      tree type;
961      tree length;
962 {
963   if (JPRIMITIVE_TYPE_P (type))
964     return build_newarray (encode_newarray_type (type), length);
965   else
966     return build_anewarray (TREE_TYPE (type), length);
967 }
968
969 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
970    class pointer, a number of dimensions and the matching number of
971    dimensions. The argument list is NULL terminated.  */
972
973 static void
974 expand_java_multianewarray (class_type, ndim)
975     tree class_type;
976     int  ndim;
977 {
978   int i;
979   tree args = build_tree_list( NULL_TREE, null_pointer_node );
980
981   for( i = 0; i < ndim; i++ )
982     args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
983
984   push_value (build (CALL_EXPR,
985                      promote_type (class_type),
986                      build_address_of (soft_multianewarray_node),
987                      tree_cons (NULL_TREE, build_class_ref (class_type),
988                                 tree_cons (NULL_TREE, 
989                                            build_int_2 (ndim, 0), args )),
990                      NULL_TREE));
991 }
992
993 /*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
994     ARRAY is an array type. May expand some bound checking and NULL
995     pointer checking. RHS_TYPE_NODE we are going to store. In the case
996     of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
997     INT. In those cases, we make the convertion.
998
999     if ARRAy is a reference type, the assignment is checked at run-time
1000     to make sure that the RHS can be assigned to the array element
1001     type. It is not necessary to generate this code if ARRAY is final.  */
1002
1003 static void
1004 expand_java_arraystore (rhs_type_node)
1005      tree rhs_type_node;
1006 {
1007   tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
1008                                  && TYPE_PRECISION (rhs_type_node) <= 32) ? 
1009                                  int_type_node : rhs_type_node);
1010   tree index = pop_value (int_type_node);
1011   tree array = pop_value (ptr_type_node);
1012
1013   rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
1014
1015   flush_quick_stack ();
1016
1017   index = save_expr (index);
1018   array = save_expr (array);
1019
1020   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1021     {
1022       tree check = build_java_arraystore_check (array, rhs_node);
1023       expand_expr_stmt (check);
1024     }
1025   
1026   expand_assignment (build_java_arrayaccess (array,
1027                                              rhs_type_node,
1028                                              index),
1029                      rhs_node, 0, 0);
1030 }
1031
1032 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
1033    sure that LHS is an array type. May expand some bound checking and NULL
1034    pointer checking.  
1035    LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1036    BOOLEAN/SHORT, we push a promoted type back to the stack.
1037 */
1038
1039 static void
1040 expand_java_arrayload (lhs_type_node )
1041     tree lhs_type_node;
1042 {
1043   tree load_node;
1044   tree index_node = pop_value (int_type_node);
1045   tree array_node = pop_value (ptr_type_node);
1046
1047   index_node = save_expr (index_node);
1048   array_node = save_expr (array_node);
1049   lhs_type_node   = build_java_check_indexed_type (array_node, lhs_type_node);
1050
1051   load_node = build_java_arrayaccess (array_node,
1052                                       lhs_type_node,
1053                                       index_node);
1054
1055   if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1056     load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1057   push_value (load_node);
1058 }
1059
1060 /* Expands .length. Makes sure that we deal with and array and may expand
1061    a NULL check on the array object.  */
1062
1063 static void
1064 expand_java_array_length ()
1065 {
1066   tree array  = pop_value (ptr_type_node);
1067   tree length = build_java_array_length_access (array);
1068
1069   push_value (length);
1070 }
1071
1072 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1073    either soft_monitorenter_node or soft_monitorexit_node.  */
1074
1075 static tree
1076 build_java_monitor (call, object)
1077     tree call;
1078     tree object;
1079 {
1080   return (build (CALL_EXPR,
1081                  void_type_node,
1082                  build_address_of (call),
1083                  build_tree_list (NULL_TREE, object),
1084                  NULL_TREE));
1085 }
1086
1087 /* Emit code for one of the PUSHC instructions. */
1088
1089 static void
1090 expand_java_pushc (ival, type)
1091      int ival;
1092      tree type;
1093 {
1094   tree value;
1095   if (type == ptr_type_node && ival == 0)
1096     value = null_pointer_node;
1097   else if (type == int_type_node || type == long_type_node)
1098     {
1099       value = build_int_2 (ival, ival < 0 ? -1 : 0);
1100       TREE_TYPE (value) = type;
1101     }
1102   else if (type == float_type_node || type == double_type_node)
1103     {
1104       REAL_VALUE_TYPE x;
1105       REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1106       value = build_real (type, x);
1107     }
1108   else
1109     abort ();
1110
1111   push_value (value);
1112 }
1113
1114 static void
1115 expand_java_return (type)
1116      tree type;
1117 {
1118   if (type == void_type_node)
1119     expand_null_return ();
1120   else
1121     {
1122       tree retval = pop_value (type);
1123       tree res = DECL_RESULT (current_function_decl);
1124       retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1125
1126       /* Handle the situation where the native integer type is smaller
1127          than the JVM integer. It can happen for many cross compilers.
1128          The whole if expression just goes away if INT_TYPE_SIZE < 32
1129          is false. */
1130       if (INT_TYPE_SIZE < 32
1131           && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1132               < GET_MODE_SIZE (TYPE_MODE (type))))
1133         retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1134       
1135       TREE_SIDE_EFFECTS (retval) = 1;
1136       expand_return (retval);
1137     }
1138 }
1139
1140 static void
1141 expand_load_internal (index, type, pc)
1142      int index;
1143      tree type;
1144      int pc;
1145 {
1146   tree copy;
1147   tree var = find_local_variable (index, type, pc);
1148
1149   /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1150      on the stack.  If there is an assignment to this VAR_DECL between
1151      the stack push and the use, then the wrong code could be
1152      generated.  To avoid this we create a new local and copy our
1153      value into it.  Then we push this new local on the stack.
1154      Hopefully this all gets optimized out.  */
1155   copy = build_decl (VAR_DECL, NULL_TREE, type);
1156   DECL_CONTEXT (copy) = current_function_decl;
1157   layout_decl (copy, 0);
1158   DECL_REGISTER (copy) = 1;
1159   expand_decl (copy);
1160   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1161   DECL_INITIAL (copy) = var;
1162   expand_decl_init (copy);
1163   push_value (copy);
1164 }
1165
1166 tree
1167 build_address_of (value)
1168      tree value;
1169 {
1170   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1171 }
1172
1173 bool class_has_finalize_method (type)
1174      tree type;
1175 {
1176   tree super = CLASSTYPE_SUPER (type);
1177
1178   if (super == NULL_TREE)
1179     return false;       /* Every class with a real finalizer inherits   */
1180                         /* from java.lang.Object.                       */
1181   else
1182     return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1183 }
1184
1185 static void
1186 expand_java_NEW (type)
1187      tree type;
1188 {
1189   tree alloc_node;
1190
1191   alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1192                                                  : alloc_no_finalizer_node);
1193   if (! CLASS_LOADED_P (type))
1194     load_class (type, 1);
1195   safe_layout_class (type);
1196   push_value (build (CALL_EXPR, promote_type (type),
1197                      build_address_of (alloc_node),
1198                      tree_cons (NULL_TREE, build_class_ref (type),
1199                                 build_tree_list (NULL_TREE,
1200                                                  size_in_bytes (type))),
1201                      NULL_TREE));
1202 }
1203
1204 /* This returns an expression which will extract the class of an
1205    object.  */
1206
1207 tree
1208 build_get_class (value)
1209      tree value;
1210 {
1211   tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1212   tree vtable_field = lookup_field (&object_type_node,
1213                                     get_identifier ("vtable"));
1214   return build (COMPONENT_REF, class_ptr_type,
1215                 build1 (INDIRECT_REF, dtable_type,
1216                         build (COMPONENT_REF, dtable_ptr_type,
1217                                build_java_indirect_ref (object_type_node, value,
1218                                                         flag_check_references),
1219                                vtable_field)),
1220                 class_field);
1221 }
1222
1223 /* This builds the tree representation of the `instanceof' operator.
1224    It tries various tricks to optimize this in cases where types are
1225    known.  */
1226
1227 tree
1228 build_instanceof (value, type)
1229      tree value, type;
1230 {
1231   tree expr;
1232   tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1233   tree valtype = TREE_TYPE (TREE_TYPE (value));
1234   tree valclass = TYPE_NAME (valtype);
1235   tree klass;
1236
1237   /* When compiling from bytecode, we need to ensure that TYPE has
1238      been loaded.  */
1239   if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1240     {
1241       load_class (type, 1);
1242       safe_layout_class (type);
1243       if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1244         return error_mark_node;
1245     }
1246   klass = TYPE_NAME (type);
1247
1248   if (type == object_type_node || inherits_from_p (valtype, type))
1249     {
1250       /* Anything except `null' is an instance of Object.  Likewise,
1251          if the object is known to be an instance of the class, then
1252          we only need to check for `null'.  */
1253       expr = build (COND_EXPR, itype,
1254                     value,
1255                     boolean_true_node, boolean_false_node);
1256     }
1257   else if (! TYPE_ARRAY_P (type)
1258            && ! TYPE_ARRAY_P (valtype)
1259            && DECL_P (klass) && DECL_P (valclass)
1260            && ! CLASS_INTERFACE (valclass)
1261            && ! CLASS_INTERFACE (klass)
1262            && ! inherits_from_p (type, valtype)
1263            && (CLASS_FINAL (klass)
1264                || ! inherits_from_p (valtype, type)))
1265     {
1266       /* The classes are from different branches of the derivation
1267          tree, so we immediately know the answer.  */
1268       expr = boolean_false_node;
1269     }
1270   else if (DECL_P (klass) && CLASS_FINAL (klass))
1271     {
1272       tree save = save_expr (value);
1273       expr = build (COND_EXPR, itype,
1274                     save,
1275                     build (EQ_EXPR, itype,
1276                            build_get_class (save),
1277                            build_class_ref (type)),
1278                     boolean_false_node);
1279     }
1280   else
1281     {
1282       expr = build (CALL_EXPR, itype,
1283                     build_address_of (soft_instanceof_node),
1284                     tree_cons (NULL_TREE, value,
1285                                build_tree_list (NULL_TREE,
1286                                                 build_class_ref (type))),
1287                     NULL_TREE);
1288     }
1289   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1290   return expr;
1291 }
1292
1293 static void
1294 expand_java_INSTANCEOF (type)
1295      tree type;
1296 {
1297   tree value = pop_value (object_ptr_type_node);
1298   value = build_instanceof (value, type);
1299   push_value (value);
1300 }
1301
1302 static void
1303 expand_java_CHECKCAST (type)
1304      tree type;
1305 {
1306   tree value = pop_value (ptr_type_node);
1307   value = build (CALL_EXPR, promote_type (type),
1308                  build_address_of (soft_checkcast_node),
1309                  tree_cons (NULL_TREE, build_class_ref (type),
1310                             build_tree_list (NULL_TREE, value)),
1311                  NULL_TREE);
1312   push_value (value);
1313 }
1314
1315 static void
1316 expand_iinc (local_var_index, ival, pc)
1317      unsigned int local_var_index;
1318      int ival;
1319      int pc;
1320 {
1321     tree local_var, res;
1322     tree constant_value;
1323
1324     flush_quick_stack ();
1325     local_var = find_local_variable (local_var_index, int_type_node, pc);
1326     constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1327     res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1328     expand_assignment (local_var, res, 0, 0);
1329 }
1330
1331       
1332 tree
1333 build_java_soft_divmod (op, type, op1, op2)
1334     enum tree_code op;
1335     tree type, op1, op2;
1336 {
1337   tree call = NULL;
1338   tree arg1 = convert (type, op1);
1339   tree arg2 = convert (type, op2);
1340
1341   if (type == int_type_node)
1342     {     
1343       switch (op)
1344         {
1345         case TRUNC_DIV_EXPR:
1346           call = soft_idiv_node;
1347           break;
1348         case TRUNC_MOD_EXPR:
1349           call = soft_irem_node;
1350           break;
1351         default:
1352           break;
1353         }
1354     }
1355   else if (type == long_type_node)
1356     {     
1357       switch (op)
1358         {
1359         case TRUNC_DIV_EXPR:
1360           call = soft_ldiv_node;
1361           break;
1362         case TRUNC_MOD_EXPR:
1363           call = soft_lrem_node;
1364           break;
1365         default:
1366           break;
1367         }
1368     }
1369
1370   if (! call)
1371     abort ();
1372                   
1373   call = build (CALL_EXPR, type,
1374                 build_address_of (call),
1375                 tree_cons (NULL_TREE, arg1,
1376                            build_tree_list (NULL_TREE, arg2)),
1377                 NULL_TREE);
1378           
1379   return call;
1380 }
1381
1382 tree
1383 build_java_binop (op, type, arg1, arg2)
1384      enum tree_code op;
1385      tree type, arg1, arg2;
1386 {
1387   tree mask;
1388   switch (op)
1389     {
1390     case URSHIFT_EXPR:
1391       {
1392         tree u_type = unsigned_type (type);
1393         arg1 = convert (u_type, arg1);
1394         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1395         return convert (type, arg1);
1396       }
1397     case LSHIFT_EXPR:
1398     case RSHIFT_EXPR:
1399       mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1400       arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1401       break;
1402
1403     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1404     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1405       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1406       {
1407         tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1408                                     boolean_type_node, arg1, arg2));
1409         tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1410         tree second_compare = fold (build (COND_EXPR, int_type_node,
1411                                            ifexp2, integer_zero_node,
1412                                            op == COMPARE_L_EXPR
1413                                            ? integer_minus_one_node
1414                                            : integer_one_node));
1415         return fold (build (COND_EXPR, int_type_node, ifexp1,
1416                             op == COMPARE_L_EXPR ? integer_one_node
1417                             : integer_minus_one_node,
1418                             second_compare));
1419       }
1420     case COMPARE_EXPR:
1421       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1422       {
1423         tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1424         tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1425         tree second_compare = fold ( build (COND_EXPR, int_type_node,
1426                                             ifexp2, integer_one_node,
1427                                             integer_zero_node));
1428         return fold (build (COND_EXPR, int_type_node,
1429                             ifexp1, integer_minus_one_node, second_compare));
1430       }      
1431     case TRUNC_DIV_EXPR:
1432     case TRUNC_MOD_EXPR:
1433       if (TREE_CODE (type) == REAL_TYPE
1434           && op == TRUNC_MOD_EXPR)
1435         {
1436           tree call;
1437           if (type != double_type_node)
1438             {
1439               arg1 = convert (double_type_node, arg1);
1440               arg2 = convert (double_type_node, arg2);
1441             }
1442           call = build (CALL_EXPR, double_type_node,
1443                         build_address_of (soft_fmod_node),
1444                         tree_cons (NULL_TREE, arg1,
1445                                    build_tree_list (NULL_TREE, arg2)),
1446                         NULL_TREE);
1447           if (type != double_type_node)
1448             call = convert (type, call);
1449           return call;
1450         }
1451       
1452       if (TREE_CODE (type) == INTEGER_TYPE
1453           && flag_use_divide_subroutine
1454           && ! flag_syntax_only)
1455         return build_java_soft_divmod (op, type, arg1, arg2);
1456       
1457       break;
1458     default:  ;
1459     }
1460   return fold (build (op, type, arg1, arg2));
1461 }
1462
1463 static void
1464 expand_java_binop (type, op)
1465      tree type;  enum tree_code op;
1466 {
1467   tree larg, rarg;
1468   tree ltype = type;
1469   tree rtype = type;
1470   switch (op)
1471     {
1472     case LSHIFT_EXPR:
1473     case RSHIFT_EXPR:
1474     case URSHIFT_EXPR:
1475       rtype = int_type_node;
1476       rarg = pop_value (rtype);
1477       break;
1478     default:
1479       rarg = pop_value (rtype);
1480     }
1481   larg = pop_value (ltype);
1482   push_value (build_java_binop (op, type, larg, rarg));
1483 }
1484
1485 /* Lookup the field named NAME in *TYPEP or its super classes.
1486    If not found, return NULL_TREE.
1487    (If the *TYPEP is not found, or if the field reference is
1488    ambiguous, return error_mark_node.)
1489    If found, return the FIELD_DECL, and set *TYPEP to the
1490    class containing the field. */
1491
1492 tree
1493 lookup_field (typep, name)
1494      tree *typep;
1495      tree name;
1496 {
1497   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1498     {
1499       load_class (*typep, 1);
1500       safe_layout_class (*typep);
1501       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1502         return error_mark_node;
1503     }
1504   do
1505     {
1506       tree field, basetype_vec;
1507       tree save_field;
1508       int n, i;
1509
1510       for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1511         if (DECL_NAME (field) == name)
1512           return field;
1513
1514       /* If *typep is an innerclass, lookup the field in its enclosing
1515          contexts */
1516       if (INNER_CLASS_TYPE_P (*typep))
1517         {
1518           tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1519
1520           if ((field = lookup_field (&outer_type, name)))
1521             return field;
1522         }
1523
1524       /* Process implemented interfaces. */
1525       basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1526       n = TREE_VEC_LENGTH (basetype_vec);
1527       save_field = NULL_TREE;
1528       for (i = 0; i < n; i++)
1529         {
1530           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1531           if ((field = lookup_field (&t, name)))
1532             {
1533               if (save_field == field)
1534                 continue;
1535               if (save_field == NULL_TREE)
1536                 save_field = field;
1537               else
1538                 {
1539                   tree i1 = DECL_CONTEXT (save_field);
1540                   tree i2 = DECL_CONTEXT (field);
1541                   error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1542                          IDENTIFIER_POINTER (name),
1543                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1544                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1545                   return error_mark_node;
1546                 }
1547             }
1548         }
1549
1550       if (save_field != NULL_TREE)
1551         return save_field;
1552
1553       *typep = CLASSTYPE_SUPER (*typep);
1554     } while (*typep);
1555   return NULL_TREE;
1556 }
1557
1558 /* Look up the field named NAME in object SELF_VALUE,
1559    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1560    SELF_VALUE is NULL_TREE if looking for a static field. */
1561
1562 tree
1563 build_field_ref (self_value, self_class, name)
1564      tree self_value, self_class, name;
1565 {
1566   tree base_class = self_class;
1567   tree field_decl = lookup_field (&base_class, name);
1568   if (field_decl == NULL_TREE)
1569     {
1570       error ("field `%s' not found", IDENTIFIER_POINTER (name));
1571       return error_mark_node;
1572     }
1573   if (self_value == NULL_TREE)
1574     {
1575       return build_static_field_ref (field_decl);
1576     }
1577   else
1578     {
1579       tree base_handle_type = promote_type (base_class);
1580       if (base_handle_type != TREE_TYPE (self_value))
1581         self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1582 #ifdef JAVA_USE_HANDLES
1583       self_value = unhand_expr (self_value);
1584 #endif
1585       self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1586                                             self_value, flag_check_references);
1587       return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1588                           self_value, field_decl));
1589     }
1590 }
1591
1592 tree
1593 lookup_label (pc)
1594      int pc;
1595 {
1596   tree name;
1597   char buf[32];
1598   ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1599   name = get_identifier (buf);
1600   if (IDENTIFIER_LOCAL_VALUE (name))
1601     return IDENTIFIER_LOCAL_VALUE (name);
1602   else
1603     {
1604       /* The type of the address of a label is return_address_type_node. */
1605       tree decl = create_label_decl (name);
1606       LABEL_PC (decl) = pc;
1607       label_rtx (decl);
1608       return pushdecl (decl);
1609     }
1610 }
1611
1612 /* Generate a unique name for the purpose of loops and switches
1613    labels, and try-catch-finally blocks label or temporary variables.  */
1614
1615 tree
1616 generate_name ()
1617 {
1618   static int l_number = 0;
1619   char buff [32];
1620   ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1621   l_number++;
1622   return get_identifier (buff);
1623 }
1624
1625 tree
1626 create_label_decl (name)
1627      tree name;
1628 {
1629   tree decl;
1630   decl = build_decl (LABEL_DECL, name, 
1631                      TREE_TYPE (return_address_type_node));
1632   DECL_CONTEXT (decl) = current_function_decl;
1633   DECL_IGNORED_P (decl) = 1;
1634   return decl;
1635 }
1636
1637 /* This maps a bytecode offset (PC) to various flags. */
1638 char *instruction_bits;
1639
1640 static void
1641 note_label (current_pc, target_pc)
1642      int current_pc ATTRIBUTE_UNUSED, target_pc;
1643 {
1644   lookup_label (target_pc);
1645   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1646 }
1647
1648 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1649    where CONDITION is one of one the compare operators. */
1650
1651 static void
1652 expand_compare (condition, value1, value2, target_pc)
1653      enum tree_code condition;
1654      tree value1, value2;
1655      int target_pc;
1656 {
1657   tree target = lookup_label (target_pc);
1658   tree cond = fold (build (condition, boolean_type_node, value1, value2));
1659   expand_start_cond (truthvalue_conversion (cond), 0);
1660   expand_goto (target);
1661   expand_end_cond ();
1662 }
1663
1664 /* Emit code for a TEST-type opcode. */
1665
1666 static void
1667 expand_test (condition, type, target_pc)
1668      enum tree_code condition;
1669      tree type;
1670      int target_pc;
1671 {
1672   tree value1, value2;
1673   flush_quick_stack ();
1674   value1 = pop_value (type);
1675   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1676   expand_compare (condition, value1, value2, target_pc);
1677 }
1678
1679 /* Emit code for a COND-type opcode. */
1680
1681 static void
1682 expand_cond (condition, type, target_pc)
1683      enum tree_code condition;
1684      tree type;
1685      int target_pc;
1686 {
1687   tree value1, value2;
1688   flush_quick_stack ();
1689   /* note: pop values in opposite order */
1690   value2 = pop_value (type);
1691   value1 = pop_value (type);
1692   /* Maybe should check value1 and value2 for type compatibility ??? */
1693   expand_compare (condition, value1, value2, target_pc);
1694 }
1695
1696 static void
1697 expand_java_goto (target_pc)
1698      int target_pc;
1699 {
1700   tree target_label = lookup_label (target_pc);
1701   flush_quick_stack ();
1702   expand_goto (target_label);
1703 }
1704
1705 #if 0
1706 static void
1707 expand_java_call (target_pc, return_address)
1708      int target_pc, return_address;
1709 {
1710   tree target_label = lookup_label (target_pc);
1711   tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1712   push_value (value);
1713   flush_quick_stack ();
1714   expand_goto (target_label);
1715 }
1716
1717 static void
1718 expand_java_ret (return_address)
1719      tree return_address ATTRIBUTE_UNUSED;
1720 {
1721   warning ("ret instruction not implemented");
1722 #if 0
1723   tree target_label = lookup_label (target_pc);
1724   flush_quick_stack ();
1725   expand_goto (target_label);
1726 #endif
1727 }
1728 #endif
1729
1730 static tree
1731 pop_arguments (arg_types)
1732      tree arg_types;
1733 {
1734   if (arg_types == end_params_node)
1735     return NULL_TREE;
1736   if (TREE_CODE (arg_types) == TREE_LIST)
1737     {
1738       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1739       tree type = TREE_VALUE (arg_types);
1740       tree arg = pop_value (type);
1741       if (PROMOTE_PROTOTYPES
1742           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1743           && INTEGRAL_TYPE_P (type))
1744         arg = convert (integer_type_node, arg);
1745       return tree_cons (NULL_TREE, arg, tail);
1746     }
1747   abort ();
1748 }
1749
1750 /* Build an expression to initialize the class CLAS.
1751    if EXPR is non-NULL, returns an expression to first call the initializer
1752    (if it is needed) and then calls EXPR. */
1753
1754 tree
1755 build_class_init (clas, expr)
1756      tree clas, expr;
1757 {
1758   tree init;
1759   struct init_test_hash_entry *ite;
1760   if (inherits_from_p (current_class, clas))
1761     return expr;
1762
1763   if (always_initialize_class_p)
1764     {
1765       init = build (CALL_EXPR, void_type_node,
1766                     build_address_of (soft_initclass_node),
1767                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1768                     NULL_TREE);
1769       TREE_SIDE_EFFECTS (init) = 1;
1770     }
1771   else
1772     {
1773       ite = (struct init_test_hash_entry *)
1774         hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1775                      (const hash_table_key) clas,
1776                      TRUE, NULL);
1777       
1778       if (ite->init_test_decl == 0)
1779         {
1780           /* Build a declaration and mark it as a flag used to track
1781              static class initializations. */
1782           ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1783                                             boolean_type_node);
1784           MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl);
1785           LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1;
1786           DECL_CONTEXT (ite->init_test_decl) = current_function_decl;
1787           DECL_FUNCTION_INIT_TEST_CLASS (ite->init_test_decl) = clas;
1788           /* Tell the check-init code to ignore this decl when not
1789              optimizing class initialization. */
1790           if (!STATIC_CLASS_INIT_OPT_P ())
1791             DECL_BIT_INDEX(ite->init_test_decl) = -1;
1792         }
1793
1794       init = build (CALL_EXPR, void_type_node,
1795                     build_address_of (soft_initclass_node),
1796                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1797                     NULL_TREE);
1798       TREE_SIDE_EFFECTS (init) = 1;
1799       init = build (COND_EXPR, void_type_node,
1800                     build (EQ_EXPR, boolean_type_node, 
1801                            ite->init_test_decl, boolean_false_node),
1802                     init, integer_zero_node);
1803       TREE_SIDE_EFFECTS (init) = 1;
1804       init = build (COMPOUND_EXPR, TREE_TYPE (expr), init, 
1805                     build (MODIFY_EXPR, boolean_type_node,
1806                            ite->init_test_decl, boolean_true_node));
1807       TREE_SIDE_EFFECTS (init) = 1;
1808     }
1809
1810   if (expr != NULL_TREE)
1811     {
1812       expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1813       TREE_SIDE_EFFECTS (expr) = 1;
1814       return expr;
1815     }
1816   return init;
1817 }
1818
1819 tree
1820 build_known_method_ref (method, method_type, self_type,
1821                         method_signature, arg_list)
1822      tree method, method_type ATTRIBUTE_UNUSED, self_type,
1823           method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1824 {
1825   tree func;
1826   if (is_compiled_class (self_type))
1827     {
1828       make_decl_rtl (method, NULL);
1829       func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1830     }
1831   else
1832     {
1833       /* We don't know whether the method has been (statically) compiled.
1834          Compile this code to get a reference to the method's code:
1835
1836          SELF_TYPE->methods[METHOD_INDEX].ncode
1837
1838          This is guaranteed to work (assuming SELF_TYPE has
1839          been initialized), since if the method is not compiled yet,
1840          its ncode points to a trampoline that forces compilation. */
1841
1842       int method_index = 0;
1843       tree meth;
1844       tree ref = build_class_ref (self_type);
1845       ref = build1 (INDIRECT_REF, class_type_node, ref);
1846       if (ncode_ident == NULL_TREE)
1847         ncode_ident = get_identifier ("ncode");
1848       if (methods_ident == NULL_TREE)
1849         methods_ident = get_identifier ("methods");
1850       ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1851                    lookup_field (&class_type_node, methods_ident));
1852       for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1853            ; meth = TREE_CHAIN (meth))
1854         {
1855           if (method == meth)
1856             break;
1857           if (meth == NULL_TREE)
1858             fatal_error ("method '%s' not found in class",
1859                          IDENTIFIER_POINTER (DECL_NAME (method)));
1860           method_index++;
1861         }
1862       method_index *= int_size_in_bytes (method_type_node);
1863       ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1864                          ref, build_int_2 (method_index, 0)));
1865       ref = build1 (INDIRECT_REF, method_type_node, ref);
1866       func = build (COMPONENT_REF, nativecode_ptr_type_node,
1867                     ref,
1868                     lookup_field (&method_type_node, ncode_ident));
1869     }
1870   return func;
1871 }
1872
1873 tree
1874 invoke_build_dtable (is_invoke_interface, arg_list)
1875      int is_invoke_interface;
1876      tree arg_list;
1877 {
1878   tree dtable, objectref;
1879
1880   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1881
1882   /* If we're dealing with interfaces and if the objectref
1883      argument is an array then get the dispatch table of the class
1884      Object rather than the one from the objectref.  */
1885   objectref = (is_invoke_interface 
1886                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1887                object_type_node : TREE_VALUE (arg_list));
1888   
1889   if (dtable_ident == NULL_TREE)
1890     dtable_ident = get_identifier ("vtable");
1891   dtable = build_java_indirect_ref (object_type_node, objectref, 
1892                                     flag_check_references);
1893   dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1894                   lookup_field (&object_type_node, dtable_ident));
1895
1896   return dtable;
1897 }
1898
1899 /* Determine the index in the virtual offset table (otable) for a call to
1900    METHOD. If this method has not been seen before, it will be added to the 
1901    otable_methods. If it has, the existing otable slot will be reused. */
1902
1903 int
1904 get_offset_table_index (method)
1905      tree method;
1906 {
1907   int i = 1;
1908   tree method_list;
1909   
1910   if (otable_methods == NULL_TREE)
1911     {
1912       otable_methods = build_tree_list (method, method);
1913       return 1;
1914     }
1915   
1916   method_list = otable_methods;
1917   
1918   while (1)
1919     {
1920       if (TREE_VALUE (method_list) == method)
1921         return i;
1922       i++;
1923       if (TREE_CHAIN (method_list) == NULL_TREE)
1924         break;
1925       else
1926         method_list = TREE_CHAIN (method_list);
1927     }
1928
1929   TREE_CHAIN (method_list) = build_tree_list (method, method);
1930   return i;
1931 }
1932
1933 tree 
1934 build_invokevirtual (dtable, method)
1935      tree dtable, method;
1936 {
1937   tree func;
1938   tree nativecode_ptr_ptr_type_node
1939     = build_pointer_type (nativecode_ptr_type_node);
1940   tree method_index;
1941   tree otable_index;
1942
1943   if (flag_indirect_dispatch)
1944     {
1945       otable_index = build_int_2 (get_offset_table_index (method), 0);
1946       method_index = build (ARRAY_REF, integer_type_node, otable_decl, 
1947                             otable_index);
1948     }
1949   else
1950     {
1951       method_index = convert (sizetype, DECL_VINDEX (method));
1952
1953       if (TARGET_VTABLE_USES_DESCRIPTORS)
1954         /* Add one to skip bogus descriptor for class and GC descriptor. */
1955         method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1956       else
1957         /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor.  */
1958         method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1959
1960       method_index = size_binop (MULT_EXPR, method_index,
1961                                  TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1962
1963       if (TARGET_VTABLE_USES_DESCRIPTORS)
1964         method_index = size_binop (MULT_EXPR, method_index,
1965                                    size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1966     }
1967
1968   func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1969                       convert (nativecode_ptr_ptr_type_node, method_index)));
1970
1971   if (TARGET_VTABLE_USES_DESCRIPTORS)
1972     func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1973   else
1974     func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1975
1976   return func;
1977 }
1978
1979 tree
1980 build_invokeinterface (dtable, method)
1981      tree dtable, method;
1982 {
1983   static tree class_ident = NULL_TREE;
1984   tree lookup_arg;
1985   tree interface;
1986   tree idx;
1987   tree meth;
1988   tree otable_index;
1989   int i;
1990
1991   /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
1992      ensure that the selected method exists, is public and not
1993      abstract nor static.  */
1994             
1995   if (class_ident == NULL_TREE)
1996     {
1997       class_ident = get_identifier ("class");
1998       ggc_add_tree_root (&class_ident, 1);
1999     }
2000
2001   dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
2002   dtable = build (COMPONENT_REF, class_ptr_type, dtable,
2003                   lookup_field (&dtable_type, class_ident));
2004
2005   interface = DECL_CONTEXT (method);
2006   layout_class_methods (interface);
2007   
2008   if (flag_indirect_dispatch)
2009     {
2010       otable_index = build_int_2 (get_offset_table_index (method), 0);
2011       idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
2012     }
2013   else
2014     {
2015       i = 1;
2016       for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
2017         {
2018           if (meth == method)
2019             {
2020               idx = build_int_2 (i, 0);
2021               break;
2022             }
2023           if (meth == NULL_TREE)
2024             abort ();
2025         }
2026     }
2027
2028   lookup_arg = tree_cons (NULL_TREE, dtable,
2029                           tree_cons (NULL_TREE, build_class_ref (interface),
2030                                      build_tree_list (NULL_TREE, idx)));
2031                                                           
2032   return build (CALL_EXPR, ptr_type_node, 
2033                 build_address_of (soft_lookupinterfacemethod_node),
2034                 lookup_arg, NULL_TREE);
2035 }
2036   
2037 /* Expand one of the invoke_* opcodes.
2038    OCPODE is the specific opcode.
2039    METHOD_REF_INDEX is an index into the constant pool.
2040    NARGS is the number of arguments, or -1 if not specified. */
2041
2042 static void
2043 expand_invoke (opcode, method_ref_index, nargs)
2044      int opcode;
2045      int method_ref_index;
2046      int nargs ATTRIBUTE_UNUSED;
2047 {
2048   tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
2049   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
2050   tree self_type = get_class_constant
2051     (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
2052   const char *const self_name
2053     = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2054   tree call, func, method, arg_list, method_type;
2055   tree check = NULL_TREE;
2056
2057   if (! CLASS_LOADED_P (self_type))
2058     {
2059       load_class (self_type, 1);
2060       safe_layout_class (self_type);
2061       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2062         fatal_error ("failed to find class '%s'", self_name);
2063     }
2064   layout_class_methods (self_type);
2065
2066   if (ID_INIT_P (method_name))
2067     method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
2068                                       method_signature);
2069   else
2070     method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
2071                                  method_name, method_signature);
2072   if (method == NULL_TREE)
2073     {
2074       error ("class '%s' has no method named '%s' matching signature '%s'",
2075              self_name,
2076              IDENTIFIER_POINTER (method_name),
2077              IDENTIFIER_POINTER (method_signature));
2078     }
2079   /* Invoke static can't invoke static/abstract method */
2080   else if (opcode == OPCODE_invokestatic)
2081     {
2082       if (!METHOD_STATIC (method))
2083         {
2084           error ("invokestatic on non static method");
2085           method = NULL_TREE;
2086         }
2087       else if (METHOD_ABSTRACT (method))
2088         {
2089           error ("invokestatic on abstract method");
2090           method = NULL_TREE;
2091         }
2092     }
2093   else
2094     {
2095       if (METHOD_STATIC (method))
2096         {
2097           error ("invoke[non-static] on static method");
2098           method = NULL_TREE;
2099         }
2100     }
2101
2102   if (method == NULL_TREE)
2103     {
2104       method_type = get_type_from_signature (method_signature);
2105       pop_arguments (TYPE_ARG_TYPES (method_type));
2106       if (opcode != OPCODE_invokestatic) 
2107         pop_type (self_type);
2108       method_type = promote_type (TREE_TYPE (method_type));
2109       push_value (convert (method_type, integer_zero_node));
2110       return;
2111     }
2112
2113   method_type = TREE_TYPE (method);
2114   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2115   flush_quick_stack ();
2116
2117   func = NULL_TREE;
2118   if (opcode == OPCODE_invokestatic)
2119     func = build_known_method_ref (method, method_type, self_type,
2120                                    method_signature, arg_list);
2121   else if (opcode == OPCODE_invokespecial
2122            || (opcode == OPCODE_invokevirtual
2123                && (METHOD_PRIVATE (method)
2124                    || METHOD_FINAL (method) 
2125                    || CLASS_FINAL (TYPE_NAME (self_type)))))
2126     {
2127       /* If the object for the method call is null, we throw an
2128          exception.  We don't do this if the object is the current
2129          method's `this'.  In other cases we just rely on an
2130          optimization pass to eliminate redundant checks.  FIXME:
2131          Unfortunately there doesn't seem to be a way to determine
2132          what the current method is right now.  */
2133       /* We use a SAVE_EXPR here to make sure we only evaluate
2134          the new `self' expression once.  */
2135       tree save_arg = save_expr (TREE_VALUE (arg_list));
2136       TREE_VALUE (arg_list) = save_arg;
2137       check = java_check_reference (save_arg, 1);
2138       func = build_known_method_ref (method, method_type, self_type,
2139                                      method_signature, arg_list);
2140     }
2141   else
2142     {
2143       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
2144                                          arg_list);
2145       if (opcode == OPCODE_invokevirtual)
2146         func = build_invokevirtual (dtable, method);
2147       else
2148         func = build_invokeinterface (dtable, method);
2149     }
2150   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2151
2152   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2153   TREE_SIDE_EFFECTS (call) = 1;
2154   call = check_for_builtin (method, call);
2155
2156   if (check != NULL_TREE)
2157     {
2158       call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2159       TREE_SIDE_EFFECTS (call) = 1;
2160     }
2161
2162   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2163     expand_expr_stmt (call);
2164   else
2165     {
2166       push_value (call);
2167       flush_quick_stack ();
2168     }
2169 }
2170
2171 /* Create a stub which will be put into the vtable but which will call
2172    a JNI function.  */
2173
2174 tree
2175 build_jni_stub (method)
2176      tree method;
2177 {
2178   tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2179   tree jni_func_type, tem;
2180   tree env_var, res_var = NULL_TREE, block;
2181   tree method_args, res_type;
2182   tree meth_var;
2183
2184   tree klass = DECL_CONTEXT (method);
2185   int from_class = ! CLASS_FROM_SOURCE_P (klass);
2186   klass = build_class_ref (klass);
2187
2188   if (! METHOD_NATIVE (method) || ! flag_jni)
2189     abort ();
2190
2191   DECL_ARTIFICIAL (method) = 1;
2192   DECL_EXTERNAL (method) = 0;
2193
2194   env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2195   DECL_CONTEXT (env_var) = method;
2196
2197   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2198     {
2199       res_var = build_decl (VAR_DECL, get_identifier ("res"),
2200                             TREE_TYPE (TREE_TYPE (method)));
2201       DECL_CONTEXT (res_var) = method;
2202       TREE_CHAIN (env_var) = res_var;
2203     }
2204
2205   meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2206   TREE_STATIC (meth_var) = 1;
2207   TREE_PUBLIC (meth_var) = 0;
2208   DECL_EXTERNAL (meth_var) = 0;
2209   DECL_CONTEXT (meth_var) = method;
2210   DECL_ARTIFICIAL (meth_var) = 1;
2211   DECL_INITIAL (meth_var) = null_pointer_node;
2212   TREE_USED (meth_var) = 1;
2213   chainon (env_var, meth_var);
2214   layout_decl (meth_var, 0);
2215   make_decl_rtl (meth_var, NULL);
2216   rest_of_decl_compilation (meth_var, NULL, 0, 0);
2217
2218   /* One strange way that the front ends are different is that they
2219      store arguments differently.  */
2220   if (from_class)
2221     method_args = DECL_ARGUMENTS (method);
2222   else
2223     method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2224   block = build_block (env_var, NULL_TREE, NULL_TREE,
2225                        method_args, NULL_TREE);
2226   TREE_SIDE_EFFECTS (block) = 1;
2227   /* When compiling from source we don't set the type of the block,
2228      because that will prevent patch_return from ever being run.  */
2229   if (from_class)
2230     TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2231
2232   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
2233   body = build (MODIFY_EXPR, ptr_type_node, env_var,
2234                 build (CALL_EXPR, ptr_type_node,
2235                        build_address_of (soft_getjnienvnewframe_node),
2236                        build_tree_list (NULL_TREE, klass),
2237                        NULL_TREE));
2238   CAN_COMPLETE_NORMALLY (body) = 1;
2239
2240   /* All the arguments to this method become arguments to the
2241      underlying JNI function.  If we had to wrap object arguments in a
2242      special way, we would do that here.  */
2243   args = NULL_TREE;
2244   for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2245     args = tree_cons (NULL_TREE, tem, args);
2246   args = nreverse (args);
2247   arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2248
2249   /* For a static method the second argument is the class.  For a
2250      non-static method the second argument is `this'; that is already
2251      available in the argument list.  */
2252   if (METHOD_STATIC (method))
2253     {
2254       args = tree_cons (NULL_TREE, klass, args);
2255       arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2256     }
2257
2258   /* The JNIEnv structure is the first argument to the JNI function.  */
2259   args = tree_cons (NULL_TREE, env_var, args);
2260   arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2261
2262   /* We call _Jv_LookupJNIMethod to find the actual underlying
2263      function pointer.  _Jv_LookupJNIMethod will throw the appropriate
2264      exception if this function is not found at runtime.  */
2265   method_sig = build_java_signature (TREE_TYPE (method));
2266   lookup_arg =
2267     build_tree_list (NULL_TREE,
2268                      build_utf8_ref (unmangle_classname
2269                                      (IDENTIFIER_POINTER (method_sig),
2270                                       IDENTIFIER_LENGTH (method_sig))));
2271   tem = DECL_NAME (method);
2272   lookup_arg
2273     = tree_cons (NULL_TREE, klass,
2274                  tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2275
2276   jni_func_type
2277     = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2278                                                arg_types));
2279
2280   jnifunc = build (COND_EXPR, ptr_type_node,
2281                    meth_var, meth_var,
2282                    build (MODIFY_EXPR, ptr_type_node,
2283                           meth_var,
2284                           build (CALL_EXPR, ptr_type_node,
2285                                  build_address_of (soft_lookupjnimethod_node),
2286                                  lookup_arg, NULL_TREE)));
2287
2288   /* Now we make the actual JNI call via the resulting function
2289      pointer.    */
2290   call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2291                 build1 (NOP_EXPR, jni_func_type, jnifunc),
2292                 args, NULL_TREE);
2293
2294   /* If the JNI call returned a result, capture it here.  If we had to
2295      unwrap JNI object results, we would do that here.  */
2296   if (res_var != NULL_TREE)
2297     call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2298                   res_var, call);
2299
2300   TREE_SIDE_EFFECTS (call) = 1;
2301   CAN_COMPLETE_NORMALLY (call) = 1;
2302
2303   body = build (COMPOUND_EXPR, void_type_node, body, call);
2304   TREE_SIDE_EFFECTS (body) = 1;
2305
2306   /* Now free the environment we allocated.  */
2307   call = build (CALL_EXPR, ptr_type_node,
2308                 build_address_of (soft_jnipopsystemframe_node),
2309                 build_tree_list (NULL_TREE, env_var),
2310                 NULL_TREE);
2311   TREE_SIDE_EFFECTS (call) = 1;
2312   CAN_COMPLETE_NORMALLY (call) = 1;
2313   body = build (COMPOUND_EXPR, void_type_node, body, call);
2314   TREE_SIDE_EFFECTS (body) = 1;
2315
2316   /* Finally, do the return.  When compiling from source we rely on
2317      patch_return to patch the return value -- because DECL_RESULT is
2318      not set at the time this function is called.  */
2319   if (from_class)
2320     {
2321       res_type = void_type_node;
2322       if (res_var != NULL_TREE)
2323         {
2324           tree drt;
2325           if (! DECL_RESULT (method))
2326             abort ();
2327           /* Make sure we copy the result variable to the actual
2328              result.  We use the type of the DECL_RESULT because it
2329              might be different from the return type of the function:
2330              it might be promoted.  */
2331           drt = TREE_TYPE (DECL_RESULT (method));
2332           if (drt != TREE_TYPE (res_var))
2333             res_var = build1 (CONVERT_EXPR, drt, res_var);
2334           res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2335           TREE_SIDE_EFFECTS (res_var) = 1;
2336         }
2337     }
2338   else
2339     {
2340       /* This is necessary to get patch_return to run.  */
2341       res_type = NULL_TREE;
2342     }
2343   body = build (COMPOUND_EXPR, void_type_node, body,
2344                 build1 (RETURN_EXPR, res_type, res_var));
2345   TREE_SIDE_EFFECTS (body) = 1;
2346
2347   BLOCK_EXPR_BODY (block) = body;
2348   return block;
2349 }
2350
2351 /* Expand an operation to extract from or store into a field.
2352    IS_STATIC is 1 iff the field is static.
2353    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
2354    FIELD_REF_INDEX is an index into the constant pool.  */
2355
2356 static void
2357 expand_java_field_op (is_static, is_putting, field_ref_index)
2358      int is_static;
2359      int is_putting;
2360      int field_ref_index;
2361 {
2362   tree self_type = 
2363       get_class_constant (current_jcf, 
2364                           COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 
2365                                                      field_ref_index));
2366   const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2367   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2368   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
2369                                                   field_ref_index);
2370   tree field_type = get_type_from_signature (field_signature);
2371   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2372   tree field_ref;
2373   int is_error = 0;
2374   tree field_decl = lookup_field (&self_type, field_name);
2375   if (field_decl == error_mark_node)
2376     {
2377       is_error = 1;
2378     }
2379   else if (field_decl == NULL_TREE)
2380     {
2381       error ("missing field '%s' in '%s'",
2382              IDENTIFIER_POINTER (field_name), self_name);
2383       is_error = 1;
2384     }
2385   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2386     {
2387       error ("mismatching signature for field '%s' in '%s'",
2388              IDENTIFIER_POINTER (field_name), self_name);
2389       is_error = 1;
2390     }
2391   field_ref = is_static ? NULL_TREE : pop_value (self_type);
2392   if (is_error)
2393     {
2394       if (! is_putting)
2395         push_value (convert (field_type, integer_zero_node));
2396       flush_quick_stack ();
2397       return;
2398     }
2399
2400   field_ref = build_field_ref (field_ref, self_type, field_name);
2401   if (is_static)
2402     field_ref = build_class_init (self_type, field_ref);
2403   if (is_putting)
2404     {
2405       flush_quick_stack ();
2406       if (FIELD_FINAL (field_decl))
2407         {
2408           if (DECL_CONTEXT (field_decl) != current_class)
2409             error_with_decl (field_decl,
2410                      "assignment to final field `%s' not in field's class");
2411           else if (FIELD_STATIC (field_decl))
2412             {
2413               if (!DECL_CLINIT_P (current_function_decl))
2414                 warning_with_decl (field_decl, 
2415              "assignment to final static field `%s' not in class initializer");
2416             }
2417           else
2418             {
2419               tree cfndecl_name = DECL_NAME (current_function_decl);
2420               if (! DECL_CONSTRUCTOR_P (current_function_decl)
2421                   && !ID_FINIT_P (cfndecl_name))
2422                 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2423             }
2424         }
2425       expand_assignment (field_ref, new_value, 0, 0);
2426     }
2427   else
2428     push_value (field_ref);
2429 }
2430
2431 void
2432 load_type_state (label)
2433      tree label;
2434 {
2435   int i;
2436   tree vec = LABEL_TYPE_STATE (label);
2437   int cur_length = TREE_VEC_LENGTH (vec);
2438   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2439   for (i = 0; i < cur_length; i++)
2440     type_map [i] = TREE_VEC_ELT (vec, i);
2441 }
2442
2443 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2444    dependent things, but they rely on gcc routines. This function is
2445    placed here because it uses things defined locally in parse.y. */
2446
2447 static tree
2448 case_identity (t, v)
2449      tree t __attribute__ ((__unused__));
2450      tree v;
2451 {
2452   return v;
2453 }
2454
2455 /* Return the name of the vtable for an array of a given primitive
2456    type.  */
2457 static tree
2458 get_primitive_array_vtable (tree elt)
2459 {
2460   tree r;
2461   if (elt == boolean_type_node)
2462     r = boolean_array_vtable;
2463   else if (elt == byte_type_node)
2464     r = byte_array_vtable;
2465   else if (elt == char_type_node)
2466     r = char_array_vtable;
2467   else if (elt == short_type_node)
2468     r = short_array_vtable;
2469   else if (elt == int_type_node)
2470     r = int_array_vtable;
2471   else if (elt == long_type_node)
2472     r = long_array_vtable;
2473   else if (elt == float_type_node)
2474     r = float_array_vtable;
2475   else if (elt == double_type_node)
2476     r = double_array_vtable;
2477   else
2478     abort ();
2479   return build_address_of (r);
2480 }
2481
2482 struct rtx_def *
2483 java_lang_expand_expr (exp, target, tmode, modifier)
2484      register tree exp;
2485      rtx target;
2486      enum machine_mode tmode;
2487      enum expand_modifier modifier;
2488 {
2489   tree current;
2490
2491   switch (TREE_CODE (exp))
2492     {
2493     case NEW_ARRAY_INIT:
2494       {
2495         rtx tmp;
2496         tree array_type = TREE_TYPE (TREE_TYPE (exp));
2497         tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2498         tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2499         HOST_WIDE_INT ilength = java_array_type_length (array_type);
2500         tree length = build_int_2 (ilength, 0);
2501         tree init = TREE_OPERAND (exp, 0);
2502         tree array_decl;
2503
2504         /* See if we can generate the array statically.  */
2505         if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2506             && JPRIMITIVE_TYPE_P (element_type))
2507           {
2508             tree temp, value, init_decl;
2509             struct rtx_def *r;
2510             START_RECORD_CONSTRUCTOR (temp, object_type_node);
2511             PUSH_FIELD_VALUE (temp, "vtable",
2512                               get_primitive_array_vtable (element_type));
2513             if (! flag_hash_synchronization)
2514               PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2515             FINISH_RECORD_CONSTRUCTOR (temp);
2516             START_RECORD_CONSTRUCTOR (value, array_type);
2517             PUSH_SUPER_VALUE (value, temp);
2518             PUSH_FIELD_VALUE (value, "length", length);
2519             PUSH_FIELD_VALUE (value, "data", init);
2520             FINISH_RECORD_CONSTRUCTOR (value);
2521
2522             init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2523             pushdecl_top_level (init_decl);
2524             TREE_STATIC (init_decl) = 1;
2525             DECL_INITIAL (init_decl) = value;
2526             DECL_IGNORED_P (init_decl) = 1;
2527             TREE_READONLY (init_decl) = 1;
2528             rest_of_decl_compilation (init_decl, NULL, 1, 0);
2529             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2530             init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2531             r = expand_expr (init, target, tmode, modifier);
2532             return r;
2533           }
2534
2535         array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2536         expand_decl (array_decl);
2537         tmp = expand_assignment (array_decl,
2538                                  build_new_array (element_type, length),
2539                                  1, 0);
2540         if (TREE_CONSTANT (init)
2541             && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2542           {
2543             tree init_decl;
2544             init_decl = build_decl (VAR_DECL, generate_name (),
2545                                     TREE_TYPE (init));
2546             pushdecl_top_level (init_decl);
2547             TREE_STATIC (init_decl) = 1;
2548             DECL_INITIAL (init_decl) = init;
2549             DECL_IGNORED_P (init_decl) = 1;
2550             TREE_READONLY (init_decl) = 1;
2551             rest_of_decl_compilation (init_decl, NULL, 1, 0);
2552             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2553             init = init_decl;
2554           }
2555         expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2556                                   build_java_indirect_ref (array_type, 
2557                                           array_decl, flag_check_references), 
2558                                   data_fld), init, 0, 0);
2559         return tmp;
2560       }
2561     case BLOCK:
2562       if (BLOCK_EXPR_BODY (exp))
2563         {
2564           tree local;
2565           tree body = BLOCK_EXPR_BODY (exp);
2566           /* Set to 1 or more when we found a static class
2567              initialization flag. */
2568           int found_class_initialization_flag = 0;
2569
2570           pushlevel (2);        /* 2 and above */
2571           expand_start_bindings (0);
2572           local = BLOCK_EXPR_DECLS (exp);
2573           while (local)
2574             {
2575               tree next = TREE_CHAIN (local);
2576               found_class_initialization_flag +=
2577                 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2578               layout_decl (local, 0);
2579               expand_decl (pushdecl (local));
2580               local = next;
2581             }
2582
2583           /* Emit initialization code for test flags if we saw one. */
2584           if (! always_initialize_class_p 
2585               && current_function_decl
2586               && found_class_initialization_flag)
2587             hash_traverse 
2588               (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2589                emit_init_test_initialization, NULL);
2590
2591           /* Avoid deep recursion for long block.  */
2592           while (TREE_CODE (body) == COMPOUND_EXPR)
2593             {
2594               expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2595               emit_queue ();
2596               body = TREE_OPERAND (body, 1);
2597             }
2598           expand_expr (body, const0_rtx, VOIDmode, 0);
2599           emit_queue ();
2600           expand_end_bindings (getdecls (), 1, 0);
2601           poplevel (1, 1, 0);
2602           return const0_rtx;
2603         }
2604       return const0_rtx;
2605
2606     case CASE_EXPR:
2607       {
2608         tree duplicate;
2609         if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2610                       build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), 
2611                       &duplicate) == 2)
2612           {
2613             EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2614             parse_error_context
2615               (wfl_operator, "Duplicate case label: `%s'",
2616                print_int_node (TREE_OPERAND (exp, 0)));
2617           }
2618         return const0_rtx;
2619       }
2620
2621     case DEFAULT_EXPR:
2622       pushcase (NULL_TREE, 0, 
2623                 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2624       return const0_rtx;
2625
2626     case SWITCH_EXPR:
2627       expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2628       expand_expr_stmt (TREE_OPERAND (exp, 1));
2629       expand_end_case (TREE_OPERAND (exp, 0));
2630       return const0_rtx;
2631
2632     case TRY_EXPR:
2633       /* We expand a try[-catch] block */
2634
2635       /* Expand the try block */
2636       expand_eh_region_start ();
2637       expand_expr_stmt (TREE_OPERAND (exp, 0));
2638       expand_start_all_catch ();
2639
2640       /* Expand all catch clauses (EH handlers) */
2641       for (current = TREE_OPERAND (exp, 1); current; 
2642            current = TREE_CHAIN (current))
2643         {
2644           tree catch = TREE_OPERAND (current, 0);
2645           tree decl = BLOCK_EXPR_DECLS (catch);
2646           tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2647
2648           expand_start_catch (type);
2649           expand_expr_stmt (TREE_OPERAND (current, 0));
2650           expand_end_catch ();
2651         }
2652       expand_end_all_catch ();
2653       return const0_rtx;
2654
2655     case JAVA_EXC_OBJ_EXPR:
2656       return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2657                           target, tmode, modifier);
2658
2659     default:
2660       internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2661     }
2662 }
2663
2664 /* Go over METHOD's bytecode and note instruction starts in
2665    instruction_bits[].  */
2666
2667 void
2668 note_instructions (jcf, method)
2669      JCF *jcf;
2670      tree method;
2671 {
2672   int PC; 
2673   unsigned char* byte_ops;
2674   long length = DECL_CODE_LENGTH (method);
2675
2676   int saw_index;
2677   jint INT_temp;
2678
2679 #undef RET /* Defined by config/i386/i386.h */
2680 #undef AND /* Causes problems with opcodes for iand and land. */
2681 #undef PTR
2682 #define BCODE byte_ops
2683 #define BYTE_type_node byte_type_node
2684 #define SHORT_type_node short_type_node
2685 #define INT_type_node int_type_node
2686 #define LONG_type_node long_type_node
2687 #define CHAR_type_node char_type_node
2688 #define PTR_type_node ptr_type_node
2689 #define FLOAT_type_node float_type_node
2690 #define DOUBLE_type_node double_type_node
2691 #define VOID_type_node void_type_node
2692 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2693 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2694 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2695 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2696
2697 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2698
2699   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2700   byte_ops = jcf->read_ptr;
2701   instruction_bits = xrealloc (instruction_bits, length + 1);
2702   memset (instruction_bits, 0, length + 1);
2703
2704   /* This pass figures out which PC can be the targets of jumps. */
2705   for (PC = 0; PC < length;)
2706     {
2707       int oldpc = PC; /* PC at instruction start. */
2708       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
2709       switch (byte_ops[PC++])
2710         {
2711 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2712         case OPCODE: \
2713           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2714           break;
2715
2716 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2717
2718 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2719 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2720 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2721 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2722 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2723 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2724 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2725 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2726
2727 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2728   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2729 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2730   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2731 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2732 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2733 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2734 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2735
2736 /* two forms of wide instructions */
2737 #define PRE_SPECIAL_WIDE(IGNORE) \
2738   { \
2739     int modified_opcode = IMMEDIATE_u1; \
2740     if (modified_opcode == OPCODE_iinc) \
2741       { \
2742         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2743         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
2744       } \
2745     else \
2746       { \
2747         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2748       } \
2749   }
2750
2751 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2752
2753 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2754
2755 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2756 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2757           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2758 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2759 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2760 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2761 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2762 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2763 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2764 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2765
2766 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2767 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2768 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2769   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2770   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2771 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2772   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2773   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2774
2775 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
2776
2777 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2778   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2779
2780 #define PRE_LOOKUP_SWITCH                                               \
2781   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
2782     NOTE_LABEL (default_offset+oldpc);                                  \
2783     if (npairs >= 0)                                                    \
2784       while (--npairs >= 0) {                                           \
2785        jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
2786        jint offset = IMMEDIATE_s4;                                      \
2787        NOTE_LABEL (offset+oldpc); }                                     \
2788   }
2789
2790 #define PRE_TABLE_SWITCH                                \
2791   { jint default_offset = IMMEDIATE_s4;                 \
2792     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
2793     NOTE_LABEL (default_offset+oldpc);                  \
2794     if (low <= high)                                    \
2795      while (low++ <= high) {                            \
2796        jint offset = IMMEDIATE_s4;                      \
2797        NOTE_LABEL (offset+oldpc); }                     \
2798   }
2799
2800 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2801 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2802 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2803   (void)(IMMEDIATE_u2); \
2804   PC += 2 * IS_INTERFACE /* for invokeinterface */;
2805
2806 #include "javaop.def"
2807 #undef JAVAOP
2808         }
2809     } /* for */
2810 }
2811
2812 void
2813 expand_byte_code (jcf, method)
2814      JCF *jcf;
2815      tree method;
2816 {
2817   int PC;
2818   int i;
2819   const unsigned char *linenumber_pointer;
2820   int dead_code_index = -1;
2821   unsigned char* byte_ops;
2822   long length = DECL_CODE_LENGTH (method);
2823
2824   stack_pointer = 0;
2825   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2826   byte_ops = jcf->read_ptr;
2827
2828   /* We make an initial pass of the line number table, to note
2829      which instructions have associated line number entries. */
2830   linenumber_pointer = linenumber_table;
2831   for (i = 0; i < linenumber_count; i++)
2832     {
2833       int pc = GET_u2 (linenumber_pointer);
2834       linenumber_pointer += 4;
2835       if (pc >= length)
2836         warning ("invalid PC in line number table");
2837       else
2838         {
2839           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2840             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2841           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2842         }
2843     }  
2844
2845   if (! verify_jvm_instructions (jcf, byte_ops, length))
2846     return;
2847
2848   /* Translate bytecodes to rtl instructions. */
2849   linenumber_pointer = linenumber_table;
2850   for (PC = 0; PC < length;)
2851     {
2852       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2853         {
2854           tree label = lookup_label (PC);
2855           flush_quick_stack ();
2856           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2857             expand_label (label);
2858           if (LABEL_VERIFIED (label) || PC == 0)
2859             load_type_state (label);
2860         }
2861
2862       if (! (instruction_bits [PC] & BCODE_VERIFIED))
2863         {
2864           if (dead_code_index == -1)
2865             {
2866               /* This is the start of a region of unreachable bytecodes.
2867                  They still need to be processed in order for EH ranges
2868                  to get handled correctly.  However, we can simply
2869                  replace these bytecodes with nops.  */
2870               dead_code_index = PC;
2871             }
2872           
2873           /* Turn this bytecode into a nop.  */
2874           byte_ops[PC] = 0x0;
2875         }
2876        else
2877         {
2878           if (dead_code_index != -1)
2879             {
2880               /* We've just reached the end of a region of dead code.  */
2881               warning ("unreachable bytecode from %d to before %d",
2882                        dead_code_index, PC);
2883               dead_code_index = -1;
2884             }
2885         }
2886
2887       /* Handle possible line number entry for this PC.
2888
2889          This code handles out-of-order and multiple linenumbers per PC,
2890          but is optimized for the case of line numbers increasing
2891          monotonically with PC. */
2892       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2893         {
2894           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2895               || GET_u2 (linenumber_pointer) != PC)
2896             linenumber_pointer = linenumber_table;
2897           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2898             {
2899               int pc = GET_u2 (linenumber_pointer);
2900               linenumber_pointer += 4;
2901               if (pc == PC)
2902                 {
2903                   lineno = GET_u2 (linenumber_pointer - 2);
2904                   emit_line_note (input_filename, lineno);
2905                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2906                     break;
2907                 }
2908             }
2909         }
2910       maybe_pushlevels (PC);
2911       PC = process_jvm_instruction (PC, byte_ops, length);
2912       maybe_poplevels (PC);
2913     } /* for */
2914   
2915   if (dead_code_index != -1)
2916     {
2917       /* We've just reached the end of a region of dead code.  */
2918       warning ("unreachable bytecode from %d to the end of the method", 
2919               dead_code_index);
2920     }
2921 }
2922
2923 static void
2924 java_push_constant_from_pool (jcf, index)
2925      JCF *jcf;
2926      int index;
2927 {
2928   tree c;
2929   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2930     {
2931       tree name;
2932       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2933       index = alloc_name_constant (CONSTANT_String, name);
2934       c = build_ref_from_constant_pool (index);
2935       TREE_TYPE (c) = promote_type (string_type_node);
2936     }
2937   else
2938     c = get_constant (jcf, index);
2939   push_value (c);
2940
2941
2942 int
2943 process_jvm_instruction (PC, byte_ops, length)
2944      int PC;
2945      const unsigned char* byte_ops;
2946      long length ATTRIBUTE_UNUSED;
2947
2948   const char *opname; /* Temporary ??? */
2949   int oldpc = PC; /* PC at instruction start. */
2950
2951   /* If the instruction is at the beginning of a exception handler,
2952      replace the top of the stack with the thrown object reference */
2953   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2954     {
2955       tree type = pop_type (ptr_type_node);
2956       push_value (build (JAVA_EXC_OBJ_EXPR, type));
2957     }
2958
2959   switch (byte_ops[PC++])
2960     {
2961 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2962     case OPCODE: \
2963       opname = #OPNAME; \
2964       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2965       break;
2966
2967 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
2968   {                                                                     \
2969     int saw_index = 0;                                                  \
2970     int index     = OPERAND_VALUE;                                      \
2971     build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2972   }
2973
2974 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2975   build_java_jsr (oldpc+OPERAND_VALUE, PC);
2976
2977 /* Push a constant onto the stack. */
2978 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2979   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
2980     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2981     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2982
2983 /* internal macro added for use by the WIDE case */
2984 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2985   expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
2986
2987 /* Push local variable onto the opcode stack. */
2988 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2989   { \
2990     /* have to do this since OPERAND_VALUE may have side-effects */ \
2991     int opvalue = OPERAND_VALUE; \
2992     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2993   }
2994
2995 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2996   expand_java_return (OPERAND_TYPE##_type_node)
2997
2998 #define REM_EXPR TRUNC_MOD_EXPR
2999 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3000   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3001
3002 #define FIELD(IS_STATIC, IS_PUT) \
3003   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3004
3005 #define TEST(OPERAND_TYPE, CONDITION) \
3006   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3007
3008 #define COND(OPERAND_TYPE, CONDITION) \
3009   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3010
3011 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3012   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3013
3014 #define BRANCH_GOTO(OPERAND_VALUE) \
3015   expand_java_goto (oldpc + OPERAND_VALUE)
3016
3017 #define BRANCH_CALL(OPERAND_VALUE) \
3018   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3019
3020 #if 0
3021 #define BRANCH_RETURN(OPERAND_VALUE) \
3022   { \
3023     tree type = OPERAND_TYPE##_type_node; \
3024     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3025     expand_java_ret (value); \
3026   }
3027 #endif
3028
3029 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3030           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3031           fprintf (stderr, "(not implemented)\n")
3032 #define NOT_IMPL1(OPERAND_VALUE) \
3033           fprintf (stderr, "%3d: %s ", oldpc, opname); \
3034           fprintf (stderr, "(not implemented)\n")
3035
3036 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3037
3038 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3039
3040 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3041
3042 #define STACK_SWAP(COUNT) java_stack_swap()
3043
3044 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3045 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3046 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3047
3048 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3049   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3050
3051 #define LOOKUP_SWITCH \
3052   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
3053     tree selector = pop_value (INT_type_node); \
3054     tree duplicate, label; \
3055     tree type = TREE_TYPE (selector); \
3056     flush_quick_stack (); \
3057     expand_start_case (0, selector, type, "switch statement");\
3058     while (--npairs >= 0) \
3059       { \
3060         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3061         tree value = build_int_2 (match, match < 0 ? -1 : 0); \
3062         TREE_TYPE (value) = type; \
3063         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3064         pushcase (value, convert, label, &duplicate); \
3065         expand_java_goto (oldpc + offset); \
3066       } \
3067     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3068     pushcase (NULL_TREE, 0, label, &duplicate); \
3069     expand_java_goto (oldpc + default_offset); \
3070     expand_end_case (selector); \
3071   }
3072
3073 #define TABLE_SWITCH \
3074   { jint default_offset = IMMEDIATE_s4; \
3075     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3076     tree selector = pop_value (INT_type_node); \
3077     tree duplicate, label; \
3078     tree type = TREE_TYPE (selector); \
3079     flush_quick_stack (); \
3080     expand_start_case (0, selector, type, "switch statement");\
3081     for (; low <= high; low++) \
3082       { \
3083         jint offset = IMMEDIATE_s4; \
3084         tree value = build_int_2 (low, low < 0 ? -1 : 0); \
3085         TREE_TYPE (value) = type; \
3086         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3087         pushcase (value, convert, label, &duplicate); \
3088         expand_java_goto (oldpc + offset); \
3089       } \
3090     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3091     pushcase (NULL_TREE, 0, label, &duplicate); \
3092     expand_java_goto (oldpc + default_offset); \
3093     expand_end_case (selector); \
3094   }
3095
3096 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3097   { int opcode = byte_ops[PC-1]; \
3098     int method_ref_index = IMMEDIATE_u2; \
3099     int nargs; \
3100     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
3101     else nargs = -1; \
3102     expand_invoke (opcode, method_ref_index, nargs); \
3103   }
3104
3105 /* Handle new, checkcast, instanceof */
3106 #define OBJECT(TYPE, OP) \
3107   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3108
3109 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3110
3111 #define ARRAY_LOAD(OPERAND_TYPE)                        \
3112   {                                                     \
3113     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
3114   }
3115
3116 #define ARRAY_STORE(OPERAND_TYPE)                       \
3117   {                                                     \
3118     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3119   }
3120
3121 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3122 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3123 #define ARRAY_NEW_PTR()                                                 \
3124     push_value (build_anewarray (get_class_constant (current_jcf,       \
3125                                                      IMMEDIATE_u2),     \
3126                                  pop_value (int_type_node)));
3127 #define ARRAY_NEW_NUM()                         \
3128   {                                             \
3129     int atype = IMMEDIATE_u1;                   \
3130     push_value (build_newarray (atype, pop_value (int_type_node)));\
3131   }
3132 #define ARRAY_NEW_MULTI()                                       \
3133   {                                                             \
3134     tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
3135     int  ndims = IMMEDIATE_u1;                                  \
3136     expand_java_multianewarray( class, ndims );                 \
3137   }
3138
3139 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3140   push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3141                             pop_value (OPERAND_TYPE##_type_node))));
3142
3143 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
3144   {                                                                      \
3145     push_value (build1 (NOP_EXPR, int_type_node,                         \
3146                         (convert (TO_TYPE##_type_node,                   \
3147                                   pop_value (FROM_TYPE##_type_node))))); \
3148   }
3149
3150 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
3151   {                                                             \
3152     push_value (convert (TO_TYPE##_type_node,                   \
3153                          pop_value (FROM_TYPE##_type_node)));   \
3154   }
3155
3156 /* internal macro added for use by the WIDE case 
3157    Added TREE_TYPE (decl) assignment, apbianco  */
3158 #define STORE_INTERNAL(OPTYPE, OPVALUE)                 \
3159   {                                                     \
3160     tree decl, value;                                   \
3161     int var = OPVALUE;                                  \
3162     tree type = OPTYPE;                                 \
3163     value = pop_value (type);                           \
3164     type = TREE_TYPE (value);                           \
3165     decl = find_local_variable (var, type, oldpc);      \
3166     set_local_type (var, type );                        \
3167     expand_assignment (decl, value, 0, 0);              \
3168   }
3169
3170 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3171   { \
3172     /* have to do this since OPERAND_VALUE may have side-effects */ \
3173     int opvalue = OPERAND_VALUE; \
3174     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3175   }
3176
3177 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3178   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3179
3180 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3181 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
3182
3183 #define MONITOR_OPERATION(call)                 \
3184   {                                             \
3185     tree o = pop_value (ptr_type_node);         \
3186     tree c;                                     \
3187     flush_quick_stack ();                       \
3188     c = build_java_monitor (call, o);           \
3189     TREE_SIDE_EFFECTS (c) = 1;                  \
3190     expand_expr_stmt (c);                       \
3191   }
3192
3193 #define SPECIAL_IINC(IGNORED) \
3194   { \
3195     unsigned int local_var_index = IMMEDIATE_u1; \
3196     int ival = IMMEDIATE_s1; \
3197     expand_iinc(local_var_index, ival, oldpc); \
3198   }
3199
3200 #define SPECIAL_WIDE(IGNORED) \
3201   { \
3202     int modified_opcode = IMMEDIATE_u1; \
3203     unsigned int local_var_index = IMMEDIATE_u2; \
3204     switch (modified_opcode) \
3205       { \
3206       case OPCODE_iinc: \
3207         { \
3208           int ival = IMMEDIATE_s2; \
3209           expand_iinc (local_var_index, ival, oldpc); \
3210           break; \
3211         } \
3212       case OPCODE_iload: \
3213       case OPCODE_lload: \
3214       case OPCODE_fload: \
3215       case OPCODE_dload: \
3216       case OPCODE_aload: \
3217         { \
3218           /* duplicate code from LOAD macro */ \
3219           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3220           break; \
3221         } \
3222       case OPCODE_istore: \
3223       case OPCODE_lstore: \
3224       case OPCODE_fstore: \
3225       case OPCODE_dstore: \
3226       case OPCODE_astore: \
3227         { \
3228           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3229           break; \
3230         } \
3231       default: \
3232         error ("unrecogized wide sub-instruction"); \
3233       } \
3234   }
3235
3236 #define SPECIAL_THROW(IGNORED) \
3237   build_java_athrow (pop_value (throwable_type_node))
3238
3239 #define SPECIAL_BREAK NOT_IMPL1
3240 #define IMPL          NOT_IMPL
3241
3242 #include "javaop.def"
3243 #undef JAVAOP
3244    default:
3245     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3246   }
3247   return PC;
3248 }
3249
3250 /* Return the opcode at PC in the code section pointed to by
3251    CODE_OFFSET.  */
3252
3253 static unsigned char
3254 peek_opcode_at_pc (jcf, code_offset, pc)
3255     JCF *jcf;
3256     int code_offset, pc;
3257 {
3258   unsigned char opcode;
3259   long absolute_offset = (long)JCF_TELL (jcf);
3260
3261   JCF_SEEK (jcf, code_offset);
3262   opcode = jcf->read_ptr [pc];
3263   JCF_SEEK (jcf, absolute_offset);
3264   return opcode;
3265 }
3266
3267 /* Some bytecode compilers are emitting accurate LocalVariableTable
3268    attributes. Here's an example:
3269    
3270      PC   <t>store_<n>
3271      PC+1 ...
3272      
3273      Attribute "LocalVariableTable"
3274      slot #<n>: ... (PC: PC+1 length: L)
3275    
3276    This is accurate because the local in slot <n> really exists after
3277    the opcode at PC is executed, hence from PC+1 to PC+1+L.
3278
3279    This procedure recognizes this situation and extends the live range
3280    of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3281    length of the store instruction.)
3282
3283    This function is used by `give_name_to_locals' so that a local's
3284    DECL features a DECL_LOCAL_START_PC such that the first related
3285    store operation will use DECL as a destination, not a unrelated
3286    temporary created for the occasion.
3287
3288    This function uses a global (instruction_bits) `note_instructions' should
3289    have allocated and filled properly.  */
3290
3291 int
3292 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3293      struct JCF *jcf;
3294      int code_offset, start_pc, slot;
3295 {
3296   int first, index, opcode;
3297   int pc, insn_pc;
3298   int wide_found = 0;
3299
3300   if (!start_pc)
3301     return start_pc;
3302
3303   first = index = -1;
3304
3305   /* Find last previous instruction and remember it */
3306   for (pc = start_pc-1; pc; pc--) 
3307     if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3308       break;
3309   insn_pc = pc;
3310
3311   /* Retrieve the instruction, handle `wide'. */  
3312   opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3313   if (opcode == OPCODE_wide)
3314     {
3315       wide_found = 1;
3316       opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3317     }
3318
3319   switch (opcode)
3320     {
3321     case OPCODE_astore_0:
3322     case OPCODE_astore_1:
3323     case OPCODE_astore_2:
3324     case OPCODE_astore_3:
3325       first = OPCODE_astore_0;
3326       break;
3327
3328     case OPCODE_istore_0:
3329     case OPCODE_istore_1:
3330     case OPCODE_istore_2:
3331     case OPCODE_istore_3:
3332       first = OPCODE_istore_0;
3333       break;
3334       
3335     case OPCODE_lstore_0:
3336     case OPCODE_lstore_1:
3337     case OPCODE_lstore_2:
3338     case OPCODE_lstore_3:
3339       first = OPCODE_lstore_0;
3340       break;
3341
3342     case OPCODE_fstore_0:
3343     case OPCODE_fstore_1:
3344     case OPCODE_fstore_2:
3345     case OPCODE_fstore_3:
3346       first = OPCODE_fstore_0;
3347       break;
3348
3349     case OPCODE_dstore_0:
3350     case OPCODE_dstore_1:
3351     case OPCODE_dstore_2:
3352     case OPCODE_dstore_3:
3353       first = OPCODE_dstore_0;
3354       break;
3355
3356     case OPCODE_astore:
3357     case OPCODE_istore:
3358     case OPCODE_lstore:
3359     case OPCODE_fstore:
3360     case OPCODE_dstore:
3361       index = peek_opcode_at_pc (jcf, code_offset, pc);
3362       if (wide_found)
3363         {
3364           int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3365           index = (other << 8) + index;
3366         }
3367       break;
3368     }
3369
3370   /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3371      means we have a <t>store. */
3372   if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3373     start_pc = insn_pc;
3374
3375   return start_pc;
3376 }
3377
3378 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3379    order, as specified by Java Language Specification.
3380
3381    The problem is that while expand_expr will evaluate its sub-operands in
3382    left-to-right order, for variables it will just return an rtx (i.e.
3383    an lvalue) for the variable (rather than an rvalue).  So it is possible
3384    that a later sub-operand will change the register, and when the
3385    actual operation is done, it will use the new value, when it should
3386    have used the original value.
3387
3388    We fix this by using save_expr.  This forces the sub-operand to be
3389    copied into a fresh virtual register,
3390
3391    For method invocation, we modify the arguments so that a
3392    left-to-right order evaluation is performed. Saved expressions
3393    will, in CALL_EXPR order, be reused when the call will be expanded.
3394 */
3395
3396 tree
3397 force_evaluation_order (node)
3398      tree  node;
3399 {
3400   if (flag_syntax_only)
3401     return node;
3402   if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3403     {
3404       if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3405         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3406     }
3407   else if (TREE_CODE (node) == CALL_EXPR
3408            || TREE_CODE (node) == NEW_CLASS_EXPR
3409            || (TREE_CODE (node) == COMPOUND_EXPR
3410                && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3411                && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR)) 
3412     {
3413       tree arg, cmp;
3414
3415       if (!TREE_OPERAND (node, 1))
3416         return node;
3417
3418       arg = node;
3419       
3420       /* Position arg properly, account for wrapped around ctors. */
3421       if (TREE_CODE (node) == COMPOUND_EXPR)
3422         arg = TREE_OPERAND (node, 0);
3423       
3424       arg = TREE_OPERAND (arg, 1);
3425       
3426       /* Not having a list of argument here is an error. */ 
3427       if (TREE_CODE (arg) != TREE_LIST)
3428         abort ();
3429
3430       /* This reverses the evaluation order. This is a desired effect. */
3431       for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3432         {
3433           tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3434           cmp = (cmp == NULL_TREE ? saved :
3435                  build (COMPOUND_EXPR, void_type_node, cmp, saved));
3436           TREE_VALUE (arg) = saved;
3437         }
3438       
3439       if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3440         TREE_SIDE_EFFECTS (cmp) = 1;
3441
3442       if (cmp)
3443         {
3444           cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3445           CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3446           TREE_SIDE_EFFECTS (cmp) = 1;
3447           node = cmp;
3448         }
3449     }
3450   return node;
3451 }
3452
3453 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3454    method in order to emit initialization code for each test flag.  */
3455
3456 static bool
3457 emit_init_test_initialization (entry, key)
3458   struct hash_entry *entry;
3459   hash_table_key key ATTRIBUTE_UNUSED;
3460 {
3461   struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
3462   tree klass = build_class_ref ((tree) entry->key);
3463   tree rhs;
3464
3465   /* If the DECL_INITIAL of the test flag is set to true, it
3466      means that the class is already initialized the time it
3467      is in use. */
3468   if (DECL_INITIAL (ite->init_test_decl) == boolean_true_node)
3469     rhs = boolean_true_node;
3470   /* Otherwise, we initialize the class init check variable by looking
3471      at the `state' field of the class to see if it is already
3472      initialized.  This makes things a bit faster if the class is
3473      already initialized, which should be the common case.  */
3474   else
3475     rhs = build (GE_EXPR, boolean_type_node,
3476                  build (COMPONENT_REF, byte_type_node,
3477                         build1 (INDIRECT_REF, class_type_node, klass),
3478                         lookup_field (&class_type_node,
3479                                       get_identifier ("state"))),
3480                  build_int_2 (JV_STATE_DONE, 0));
3481
3482   expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node, 
3483                            ite->init_test_decl, rhs));
3484   return true;
3485 }