OSDN Git Service

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