OSDN Git Service

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