OSDN Git Service

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