OSDN Git Service

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