OSDN Git Service

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