OSDN Git Service

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