OSDN Git Service

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