OSDN Git Service

abc5f69103fffb4fb45b83ec93b1837f1663ae33
[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 "defaults.h"
43 #include "ggc.h"
44
45 static void flush_quick_stack PARAMS ((void));
46 static void push_value PARAMS ((tree));
47 static tree pop_value PARAMS ((tree));
48 static void java_stack_swap PARAMS ((void));
49 static void java_stack_dup PARAMS ((int, int));
50 static void build_java_athrow PARAMS ((tree));
51 static void build_java_jsr PARAMS ((tree, tree));
52 static void build_java_ret PARAMS ((tree));
53 static void expand_java_multianewarray PARAMS ((tree, int));
54 static void expand_java_arraystore PARAMS ((tree));
55 static void expand_java_arrayload PARAMS ((tree));
56 static void expand_java_array_length PARAMS ((void));
57 static tree build_java_monitor PARAMS ((tree, tree));
58 static void expand_java_pushc PARAMS ((int, tree));
59 static void expand_java_return PARAMS ((tree));
60 static void expand_java_NEW PARAMS ((tree));
61 static void expand_java_INSTANCEOF PARAMS ((tree));
62 static void expand_java_CHECKCAST PARAMS ((tree));
63 static void expand_iinc PARAMS ((unsigned int, int, int));
64 static void expand_java_binop PARAMS ((tree, enum tree_code));
65 static void note_label PARAMS ((int, int));
66 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
67 static void expand_test PARAMS ((enum tree_code, tree, int));
68 static void expand_cond PARAMS ((enum tree_code, tree, int));
69 static void expand_java_goto PARAMS ((int));
70 #if 0
71 static void expand_java_call PARAMS ((int, int));
72 static void expand_java_ret PARAMS ((tree)); 
73 #endif
74 static tree pop_arguments PARAMS ((tree)); 
75 static void expand_invoke PARAMS ((int, int, int)); 
76 static void expand_java_field_op PARAMS ((int, int, int)); 
77 static void java_push_constant_from_pool PARAMS ((struct JCF *, int)); 
78 static void java_stack_pop PARAMS ((int)); 
79 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree)); 
80 static tree build_java_check_indexed_type PARAMS ((tree, tree)); 
81 static tree java_array_data_offset PARAMS ((tree)); 
82 static tree case_identity PARAMS ((tree, tree)); 
83 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
84
85 static tree operand_type[59];
86 extern struct obstack permanent_obstack;
87
88 static tree methods_ident = NULL_TREE;
89 static tree ncode_ident = NULL_TREE;
90 tree dtable_ident = NULL_TREE;
91
92 /* Set to non-zero value in order to emit class initilization code
93    before static field references.  */
94 int always_initialize_class_p;
95
96 /* We store the stack state in two places:
97    Within a basic block, we use the quick_stack, which is a
98    pushdown list (TREE_LISTs) of expression nodes.
99    This is the top part of the stack;  below that we use find_stack_slot.
100    At the end of a basic block, the quick_stack must be flushed
101    to the stack slot array (as handled by find_stack_slot).
102    Using quick_stack generates better code (especially when
103    compiled without optimization), because we do not have to
104    explicitly store and load trees to temporary variables.
105
106    If a variable is on the quick stack, it means the value of variable
107    when the quick stack was last flushed.  Conceptually, flush_quick_stack
108    saves all the the quick_stack elements in parellel.  However, that is
109    complicated, so it actually saves them (i.e. copies each stack value
110    to is home virtual register) from low indexes.  This allows a quick_stack
111    element at index i (counting from the bottom of stack the) to references
112    slot virtuals for register that are >= i, but not those that are deeper.
113    This convention makes most operations easier.  For example iadd works
114    even when the stack contains (reg[0], reg[1]):  It results in the
115    stack containing (reg[0]+reg[1]), which is OK.  However, some stack
116    operations are more complicated.  For example dup given a stack
117    containing (reg[0]) would yield (reg[0], reg[0]), which would violate
118    the convention, since stack value 1 would refer to a register with
119    lower index (reg[0]), which flush_quick_stack does not safely handle.
120    So dup cannot just add an extra element to the quick_stack, but iadd can.
121 */
122
123 static tree quick_stack = NULL_TREE;
124
125 /* A free-list of unused permamnet TREE_LIST nodes. */
126 static tree tree_list_free_list = NULL_TREE;
127
128 /* The stack pointer of the Java virtual machine.
129    This does include the size of the quick_stack. */
130
131 int stack_pointer;
132
133 const unsigned char *linenumber_table;
134 int linenumber_count;
135
136 void
137 init_expr_processing()
138 {
139   operand_type[21] = operand_type[54] = int_type_node;
140   operand_type[22] = operand_type[55] = long_type_node;
141   operand_type[23] = operand_type[56] = float_type_node;
142   operand_type[24] = operand_type[57] = double_type_node;
143   operand_type[25] = operand_type[58] = ptr_type_node;
144   ggc_add_tree_root (operand_type, 59);
145   ggc_add_tree_root (&methods_ident, 1);
146   ggc_add_tree_root (&ncode_ident, 1);
147   ggc_add_tree_root (&quick_stack, 1);
148   ggc_add_tree_root (&tree_list_free_list, 1);
149 }
150
151 tree
152 truthvalue_conversion (expr)
153      tree expr;
154 {
155   /* It is simpler and generates better code to have only TRUTH_*_EXPR
156      or comparison expressions as truth values at this level.
157
158      This function should normally be identity for Java.  */
159
160   switch (TREE_CODE (expr))
161     {
162     case EQ_EXPR:
163     case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
164     case TRUTH_ANDIF_EXPR:
165     case TRUTH_ORIF_EXPR:
166     case TRUTH_AND_EXPR:
167     case TRUTH_OR_EXPR:
168     case ERROR_MARK:
169       return expr;
170
171     case INTEGER_CST:
172       return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
173
174     case REAL_CST:
175       return real_zerop (expr) ? boolean_false_node : boolean_true_node;
176
177     /* are these legal? XXX JH */
178     case NEGATE_EXPR:
179     case ABS_EXPR:
180     case FLOAT_EXPR:
181     case FFS_EXPR:
182       /* These don't change whether an object is non-zero or zero.  */
183       return truthvalue_conversion (TREE_OPERAND (expr, 0));
184
185     case COND_EXPR:
186       /* Distribute the conversion into the arms of a COND_EXPR.  */
187       return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
188                           truthvalue_conversion (TREE_OPERAND (expr, 1)),
189                           truthvalue_conversion (TREE_OPERAND (expr, 2))));
190
191     case NOP_EXPR:
192       /* If this is widening the argument, we can ignore it.  */
193       if (TYPE_PRECISION (TREE_TYPE (expr))
194           >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
195         return truthvalue_conversion (TREE_OPERAND (expr, 0));
196       /* fall through to default */
197
198     default:
199       return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
200     }
201 }
202
203 #ifdef JAVA_USE_HANDLES
204 /* Given a pointer to a handle, get a pointer to an object. */
205
206 tree
207 unhand_expr (expr)
208      tree expr;
209 {
210   tree field, handle_type;
211   expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
212   handle_type = TREE_TYPE (expr);
213   field = TYPE_FIELDS (handle_type);
214   expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
215   return expr;
216 }
217 #endif
218
219 /* Save any stack slots that happen to be in the quick_stack into their
220    home virtual register slots.
221
222    The copy order is from low stack index to high, to support the invariant
223    that the expression for a slot may contain decls for stack slots with
224    higher (or the same) index, but not lower. */
225
226 static void
227 flush_quick_stack ()
228 {
229   int stack_index = stack_pointer;
230   register tree prev, cur, next;
231
232   /* First reverse the quick_stack, and count the number of slots it has. */
233   for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
234     {
235       next = TREE_CHAIN (cur);
236       TREE_CHAIN (cur) = prev;
237       prev = cur;
238       stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
239     }
240   quick_stack = prev;
241
242   while (quick_stack != NULL_TREE)
243     {
244       tree decl;
245       tree node = quick_stack, type;
246       quick_stack = TREE_CHAIN (node);
247       TREE_CHAIN (node) = tree_list_free_list;
248       tree_list_free_list = node;
249       node = TREE_VALUE (node);
250       type = TREE_TYPE (node);
251
252       decl = find_stack_slot (stack_index, type);
253       if (decl != node)
254           expand_assignment (decl, node, 0, 0);
255       stack_index += 1 + TYPE_IS_WIDE (type);
256     }
257 }
258
259 /* Push TYPE on the type stack.
260    Return true on success, 0 on overflow. */
261
262 int
263 push_type_0 (type)
264      tree type;
265 {
266   int n_words;
267   type = promote_type (type);
268   n_words = 1 + TYPE_IS_WIDE (type);
269   if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
270     return 0;
271   stack_type_map[stack_pointer++] = type;
272   n_words--;
273   while (--n_words >= 0)
274     stack_type_map[stack_pointer++] = TYPE_SECOND;
275   return 1;
276 }
277
278 void
279 push_type (type)
280      tree type;
281 {
282   if (! push_type_0 (type))
283     fatal ("stack overflow");
284 }
285
286 static void
287 push_value (value)
288      tree value;
289 {
290   tree type = TREE_TYPE (value);
291   if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
292     {
293       type = promote_type (type);
294       value = convert (type, value);
295     }
296   push_type (type);
297   if (tree_list_free_list == NULL_TREE)
298     quick_stack = tree_cons (NULL_TREE, value, quick_stack);
299   else
300     {
301       tree node = tree_list_free_list;
302       tree_list_free_list = TREE_CHAIN (tree_list_free_list);
303       TREE_VALUE (node) = value;
304       TREE_CHAIN (node) = quick_stack;
305       quick_stack = node;
306     }
307 }
308
309 /* Pop a type from the type stack.
310    TYPE is the expected type.   Return the actual type, which must be
311    convertible to TYPE.
312    On an error, *MESSAGEP is set to a freshly malloc'd error message. */
313
314 tree
315 pop_type_0 (type, messagep)
316      tree type;
317      char **messagep;
318 {
319   int n_words;
320   tree t;
321   *messagep = NULL;
322   if (TREE_CODE (type) == RECORD_TYPE)
323     type = promote_type (type);
324   n_words = 1 + TYPE_IS_WIDE (type);
325   if (stack_pointer < n_words)
326     {
327       *messagep = xstrdup ("stack underflow");
328       return type;
329     }
330   while (--n_words > 0)
331     {
332       if (stack_type_map[--stack_pointer] != void_type_node)
333         {
334           *messagep = xstrdup ("Invalid multi-word value on type stack");
335           return type;
336         }
337     }
338   t = stack_type_map[--stack_pointer];
339   if (type == NULL_TREE || t == type)
340     return t;
341   if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
342       && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
343       return t;
344   if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
345     {
346       if (type == ptr_type_node || type == object_ptr_type_node)
347         return t;
348       else if (t == ptr_type_node)  /* Special case for null reference. */
349         return type;
350       else if (can_widen_reference_to (t, type))
351         return t;
352       /* This is a kludge, but matches what Sun's verifier does.
353          It can be tricked, but is safe as long as type errors
354          (i.e. interface method calls) are caught at run-time. */
355       /* FIXME: this is worse than a kludge, probably.  */
356       return object_ptr_type_node;
357     }
358   {
359     const char *str1 = "expected type '";
360     const char *str3 = "' but stack contains '";
361     const char *str5 = "'";
362     int len1 = strlen (str1);
363     int len2 = strlen (lang_printable_name (type, 0));
364     int len3 = strlen (str3);
365     int len4 = strlen (lang_printable_name (t, 0));
366     int len5 = strlen (str5);
367     char *msg = xmalloc (len1 + len2 + len3 + len4 + len5 + 1);
368     *messagep = msg;
369     strcpy (msg, str1);  msg += len1;
370     strcpy (msg, lang_printable_name (type, 0));  msg += len2;
371     strcpy (msg, str3);  msg += len3;
372     strcpy (msg, lang_printable_name (t, 0));  msg += len4;
373     strcpy (msg, str5);
374     return type;
375   }
376 }
377
378 /* Pop a type from the type stack.
379    TYPE is the expected type.  Return the actual type, which must be
380    convertible to TYPE, otherwise call error. */
381
382 tree
383 pop_type (type)
384      tree type;
385 {
386   char *message = NULL;
387   type = pop_type_0 (type, &message);
388   if (message != NULL)
389     {
390       error (message);
391       free (message);
392     }
393   return type;
394 }
395
396 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
397    Handles array types and interfaces.  */
398
399 int
400 can_widen_reference_to (source_type, target_type)
401      tree source_type, target_type;
402 {
403   if (source_type == ptr_type_node || target_type == object_ptr_type_node)
404     return 1;
405
406   /* Get rid of pointers  */
407   if (TREE_CODE (source_type) == POINTER_TYPE)
408     source_type = TREE_TYPE (source_type);
409   if (TREE_CODE (target_type) == POINTER_TYPE)
410     target_type = TREE_TYPE (target_type);
411
412   if (source_type == target_type)
413     return 1;
414   else
415     {
416       source_type = HANDLE_TO_CLASS_TYPE (source_type);
417       target_type = HANDLE_TO_CLASS_TYPE (target_type);
418       if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
419         {
420           HOST_WIDE_INT source_length, target_length;
421           if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
422             return 0;
423           target_length = java_array_type_length (target_type);
424           if (target_length >= 0)
425             {
426               source_length = java_array_type_length (source_type);
427               if (source_length != target_length)
428                 return 0;
429             }
430           source_type = TYPE_ARRAY_ELEMENT (source_type);
431           target_type = TYPE_ARRAY_ELEMENT (target_type);
432           if (source_type == target_type)
433             return 1;
434           if (TREE_CODE (source_type) != POINTER_TYPE
435               || TREE_CODE (target_type) != POINTER_TYPE)
436             return 0;
437           return can_widen_reference_to (source_type, target_type);
438         }
439       else
440         {
441           int source_depth = class_depth (source_type);
442           int target_depth = class_depth (target_type);
443
444           /* class_depth can return a negative depth if an error occurred */
445           if (source_depth < 0 || target_depth < 0)
446             return 0;
447
448           if (CLASS_INTERFACE (TYPE_NAME (target_type)))
449             {
450               /* target_type is OK if source_type or source_type ancestors
451                  implement target_type. We handle multiple sub-interfaces  */
452
453               tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
454               int n = TREE_VEC_LENGTH (basetype_vec), i;
455               for (i=0 ; i < n; i++)
456                 if (can_widen_reference_to 
457                     (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
458                      target_type))
459                   return 1;
460               if (n == 0)
461                 return 0;
462             }
463
464           for ( ; source_depth > target_depth;  source_depth--) 
465             {
466               source_type = TYPE_BINFO_BASETYPE (source_type, 0); 
467             }
468           return source_type == target_type;
469         }
470     }
471 }
472
473 static tree
474 pop_value (type)
475      tree type;
476 {
477   type = pop_type (type);
478   if (quick_stack)
479     {
480       tree node = quick_stack;
481       quick_stack = TREE_CHAIN (quick_stack);
482       TREE_CHAIN (node) = tree_list_free_list;
483       tree_list_free_list = node;
484       node = TREE_VALUE (node);
485       return node;
486     }
487   else
488     return find_stack_slot (stack_pointer, promote_type (type));
489 }
490
491
492 /* Pop and discrad the top COUNT stack slots. */
493
494 static void
495 java_stack_pop (count)
496      int count;
497 {
498   while (count > 0)
499     {
500       tree type, val;
501       if (stack_pointer == 0)
502         fatal ("stack underflow");
503       type = stack_type_map[stack_pointer - 1];
504       if (type == TYPE_SECOND)
505         {
506           count--;
507           if (stack_pointer == 1 || count <= 0)
508             fatal ("stack underflow");
509           type = stack_type_map[stack_pointer - 2];
510         }
511       val = pop_value (type);
512       count--;
513     }
514 }
515
516 /* Implement the 'swap' operator (to swap two top stack slots). */
517
518 static void
519 java_stack_swap ()
520 {
521   tree type1, type2;
522   rtx temp;
523   tree decl1, decl2;
524
525   if (stack_pointer < 2
526       || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
527       || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
528       || type1 == TYPE_SECOND || type2 == TYPE_SECOND
529       || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
530     fatal ("bad stack swap");
531
532   flush_quick_stack ();
533   decl1 = find_stack_slot (stack_pointer - 1, type1);
534   decl2 = find_stack_slot (stack_pointer - 2, type2);
535   temp = copy_to_reg (DECL_RTL (decl1));
536   emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
537   emit_move_insn (DECL_RTL (decl2), temp);
538   stack_type_map[stack_pointer - 1] = type2;
539   stack_type_map[stack_pointer - 2] = type1;
540 }
541
542 static void
543 java_stack_dup (size, offset)
544      int size, offset;
545 {
546   int low_index = stack_pointer - size - offset;
547   int dst_index;
548   if (low_index < 0)
549     error ("stack underflow - dup* operation");
550
551   flush_quick_stack ();
552
553   stack_pointer += size;
554   dst_index = stack_pointer;
555
556   for (dst_index = stack_pointer;  --dst_index >= low_index; )
557     {
558       tree type;
559       int src_index = dst_index - size;
560       if (src_index < low_index)
561         src_index = dst_index + size + offset;
562       type = stack_type_map [src_index];
563       if (type == TYPE_SECOND)
564         {
565           if (src_index <= low_index)
566             fatal ("dup operation splits 64-bit number");
567           stack_type_map[dst_index] = type;
568           src_index--;  dst_index--;
569           type = stack_type_map[src_index];
570           if (! TYPE_IS_WIDE (type))
571             fatal ("internal error - dup operation");
572         }
573       else if (TYPE_IS_WIDE (type))
574         fatal ("internal error - dup operation");
575       if (src_index != dst_index)
576         {
577           tree src_decl = find_stack_slot (src_index, type);
578           tree dst_decl = find_stack_slot (dst_index, type);
579           emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
580           stack_type_map[dst_index] = type;
581         }
582     }
583 }
584
585 /* Calls _Jv_Throw or _Jv_Sjlj_Throw.  Discard the contents of the
586    value stack. */
587
588 static void
589 build_java_athrow (node)
590     tree node;
591 {
592   tree call;
593
594   call = build (CALL_EXPR,
595                 void_type_node,
596                 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
597                 build_tree_list (NULL_TREE, node),
598                 NULL_TREE);
599   TREE_SIDE_EFFECTS (call) = 1;
600   expand_expr_stmt (call);
601   java_stack_pop (stack_pointer);
602 }
603
604 /* Implementation for jsr/ret */
605
606 static void
607 build_java_jsr (where, ret)
608     tree where;
609     tree ret;
610 {
611   tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
612   push_value (ret_label);
613   flush_quick_stack ();
614   emit_jump (label_rtx (where));
615   expand_label (ret);
616 }
617
618 static void
619 build_java_ret (location)
620   tree location;
621 {
622   expand_computed_goto (location);
623 }
624  
625 /* Implementation of operations on array: new, load, store, length */
626
627 /* Array core info access macros */
628
629 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
630   byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
631
632 tree
633 decode_newarray_type (atype)
634   int atype;
635 {
636   switch (atype)
637     {
638     case 4:  return boolean_type_node;
639     case 5:  return char_type_node;
640     case 6:  return float_type_node;
641     case 7:  return double_type_node;
642     case 8:  return byte_type_node;
643     case 9:  return short_type_node;
644     case 10: return int_type_node;
645     case 11: return long_type_node;
646     default: return NULL_TREE;
647     }
648 }
649
650 /* Map primitive type to the code used by OPCODE_newarray. */
651
652 int
653 encode_newarray_type (type)
654      tree type;
655 {
656   if (type == boolean_type_node)
657     return 4;
658   else if (type == char_type_node)
659     return 5;
660   else if (type == float_type_node)
661     return 6;
662   else if (type == double_type_node)
663     return 7;
664   else if (type == byte_type_node)
665     return 8;
666   else if (type == short_type_node)
667     return 9;
668   else if (type == int_type_node)
669     return 10;
670   else if (type == long_type_node)
671     return 11;
672   else
673     fatal ("Can't compute type code - patch_newarray");
674 }
675
676 /* Build a call to _Jv_ThrowBadArrayIndex(), the
677    ArrayIndexOfBoundsException exception handler.  */
678
679 static tree
680 build_java_throw_out_of_bounds_exception (index)
681     tree index;
682 {
683   tree node = build (CALL_EXPR, int_type_node,
684                      build_address_of (soft_badarrayindex_node), 
685                      build_tree_list (NULL_TREE, index), NULL_TREE);
686   TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
687   return (node);
688 }
689
690 /* Return the length of an array. Doesn't perform any checking on the nature
691    or value of the array NODE. May be used to implement some bytecodes.  */
692
693 tree
694 build_java_array_length_access (node)
695     tree node;
696 {
697   tree type = TREE_TYPE (node);
698   HOST_WIDE_INT length;
699   if (!is_array_type_p (type))
700     fatal ("array length on a non-array reference");
701   length = java_array_type_length (type);
702   if (length >= 0)
703     return build_int_2 (length, 0);
704   return fold (build1 (INDIRECT_REF,
705                        int_type_node,
706                        fold (build (PLUS_EXPR, ptr_type_node,
707                                     node, 
708                                     JAVA_ARRAY_LENGTH_OFFSET(node)))));
709 }
710
711 /* Optionally checks an array against the NULL pointer, eventually throwing a
712    NullPointerException. It could replace signal handling, but tied to NULL.
713    ARG1: the pointer to check, ARG2: the expression to use if
714    the pointer is non-null and ARG3 the type that should be returned.   */
715
716 tree
717 build_java_arraynull_check (node, expr, type)
718     tree node ATTRIBUTE_UNUSED;
719     tree expr;
720     tree type ATTRIBUTE_UNUSED;
721 {
722 #if 0
723   static int java_array_access_throws_null_exception = 0;
724   node = ???;
725   if (java_array_access_throws_null_exception)
726       return (build (COND_EXPR, 
727                      type,
728                      build (EQ_EXPR, int_type_node, node, null_pointer_node),
729                      build_java_athrow (node), expr ));
730   else
731 #endif
732       return (expr);
733 }
734
735 static tree
736 java_array_data_offset (array)
737      tree array;
738 {
739   tree array_type = TREE_TYPE (TREE_TYPE (array));
740   tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
741
742   if (data_fld == NULL_TREE)
743     return size_in_bytes (array_type);
744   else
745     return byte_position (data_fld);
746 }
747
748 /* Implement array indexing (either as l-value or r-value).
749    Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
750    Optionally performs bounds checking and/or test to NULL.
751    At this point, ARRAY should have been verified as an array.  */
752
753 tree
754 build_java_arrayaccess (array, type, index)
755     tree array, type, index;
756 {
757   tree arith, node, throw = NULL_TREE;
758
759   arith = fold (build (PLUS_EXPR, int_type_node,
760                        java_array_data_offset (array),
761                        fold (build (MULT_EXPR, int_type_node,
762                                     index, size_in_bytes(type)))));
763
764   if (flag_bounds_check)
765     {
766       /* Generate:
767        * (unsigned jint) INDEX >= (unsigned jint) LEN
768        *    && throw ArrayIndexOutOfBoundsException.
769        * Note this is equivalent to and more efficient than:
770        * INDEX < 0 || INDEX >= LEN && throw ... */
771       tree test;
772       tree len = build_java_array_length_access (array);
773       TREE_TYPE (len) = unsigned_int_type_node;
774       test = fold (build (GE_EXPR, boolean_type_node, 
775                                convert (unsigned_int_type_node, index),
776                                len));
777       if (! integer_zerop (test))
778         {
779           throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
780                          build_java_throw_out_of_bounds_exception (index));
781           /* allows expansion within COMPOUND */
782           TREE_SIDE_EFFECTS( throw ) = 1;
783         }
784     }
785
786   node = build1 (INDIRECT_REF, type, 
787                  fold (build (PLUS_EXPR, ptr_type_node, 
788                               array, 
789                               (throw ? build (COMPOUND_EXPR, int_type_node, 
790                                               throw, arith )
791                                      : arith))));
792
793   return (fold (build_java_arraynull_check (array, node, type)));
794 }
795
796 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
797    ARRAY_NODE. This function is used to retrieve something less vague than
798    a pointer type when indexing the first dimension of something like [[<t>.
799    May return a corrected type, if necessary, otherwise INDEXED_TYPE is
800    return unchanged.
801    As a side effect, it also makes sure that ARRAY_NODE is an array.  */
802
803 static tree
804 build_java_check_indexed_type (array_node, indexed_type)
805     tree array_node;
806     tree indexed_type;
807 {
808   tree elt_type;
809
810   if (!is_array_type_p (TREE_TYPE (array_node)))
811     fatal ("array indexing on a non-array reference");
812
813   elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
814
815   if (indexed_type == ptr_type_node )
816       return promote_type (elt_type);
817
818   /* BYTE/BOOLEAN store and load are used for both type */
819   if (indexed_type == byte_type_node && elt_type == boolean_type_node )
820     return boolean_type_node;
821
822   if (indexed_type != elt_type )
823     fatal ("type array element mismatch");
824   else
825     return indexed_type;
826 }
827
828 /* newarray triggers a call to _Jv_NewPrimArray. This function should be 
829    called with an integer code (the type of array to create), and the length
830    of the array to create.  */
831
832 tree
833 build_newarray (atype_value, length)
834      int atype_value;
835      tree length;
836 {
837   tree type_arg;
838
839   tree prim_type = decode_newarray_type (atype_value);
840   tree type
841     = build_java_array_type (prim_type,
842                              host_integerp (length, 0) == INTEGER_CST
843                              ? tree_low_cst (length, 0) : -1);
844
845   /* If compiling to native, pass a reference to the primitive type class 
846      and save the runtime some work. However, the bytecode generator
847      expects to find the type_code int here. */
848   if (flag_emit_class_files)
849     type_arg = build_int_2 (atype_value, 0);
850   else
851     type_arg = build_class_ref (prim_type);
852
853   return build (CALL_EXPR, promote_type (type),
854                 build_address_of (soft_newarray_node),
855                 tree_cons (NULL_TREE, 
856                            type_arg,
857                            build_tree_list (NULL_TREE, length)),
858                 NULL_TREE);
859 }
860
861 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
862    of the dimension. */
863
864 tree
865 build_anewarray (class_type, length)
866     tree class_type;
867     tree length;
868 {
869   tree type
870     = build_java_array_type (class_type,
871                              host_integerp (length, 0)
872                              ? tree_low_cst (length, 0) : -1);
873
874   return build (CALL_EXPR, promote_type (type),
875                 build_address_of (soft_anewarray_node),
876                 tree_cons (NULL_TREE, length,
877                            tree_cons (NULL_TREE, build_class_ref (class_type),
878                                       build_tree_list (NULL_TREE,
879                                                        null_pointer_node))),
880                 NULL_TREE);
881 }
882
883 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
884
885 tree
886 build_new_array (type, length)
887      tree type;
888      tree length;
889 {
890   if (JPRIMITIVE_TYPE_P (type))
891     return build_newarray (encode_newarray_type (type), length);
892   else
893     return build_anewarray (TREE_TYPE (type), length);
894 }
895
896 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
897    class pointer, a number of dimensions and the matching number of
898    dimensions. The argument list is NULL terminated.  */
899
900 static void
901 expand_java_multianewarray (class_type, ndim)
902     tree class_type;
903     int  ndim;
904 {
905   int i;
906   tree args = build_tree_list( NULL_TREE, null_pointer_node );
907
908   for( i = 0; i < ndim; i++ )
909     args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
910
911   push_value (build (CALL_EXPR,
912                      promote_type (class_type),
913                      build_address_of (soft_multianewarray_node),
914                      tree_cons (NULL_TREE, build_class_ref (class_type),
915                                 tree_cons (NULL_TREE, 
916                                            build_int_2 (ndim, 0), args )),
917                      NULL_TREE));
918 }
919
920 /*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
921     ARRAY is an array type. May expand some bound checking and NULL
922     pointer checking. RHS_TYPE_NODE we are going to store. In the case
923     of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
924     INT. In those cases, we make the convertion.
925
926     if ARRAy is a reference type, the assignment is checked at run-time
927     to make sure that the RHS can be assigned to the array element
928     type. It is not necessary to generate this code if ARRAY is final.  */
929
930 static void
931 expand_java_arraystore (rhs_type_node)
932      tree rhs_type_node;
933 {
934   tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
935                                  && TYPE_PRECISION (rhs_type_node) <= 32) ? 
936                                  int_type_node : rhs_type_node);
937   tree index = pop_value (int_type_node);
938   tree array = pop_value (ptr_type_node);
939
940   rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
941
942   flush_quick_stack ();
943
944   index = save_expr (index);
945   array = save_expr (array);
946
947   if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
948     {
949       tree check = build (CALL_EXPR, void_type_node,
950                           build_address_of (soft_checkarraystore_node),
951                           tree_cons (NULL_TREE, array,
952                                      build_tree_list (NULL_TREE, rhs_node)),
953                           NULL_TREE);
954       TREE_SIDE_EFFECTS (check) = 1;
955       expand_expr_stmt (check);
956     }
957   
958   expand_assignment (build_java_arrayaccess (array,
959                                              rhs_type_node,
960                                              index),
961                      rhs_node, 0, 0);
962 }
963
964 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
965    sure that LHS is an array type. May expand some bound checking and NULL
966    pointer checking.  
967    LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
968    BOOLEAN/SHORT, we push a promoted type back to the stack.
969 */
970
971 static void
972 expand_java_arrayload (lhs_type_node )
973     tree lhs_type_node;
974 {
975   tree load_node;
976   tree index_node = pop_value (int_type_node);
977   tree array_node = pop_value (ptr_type_node);
978
979   index_node = save_expr (index_node);
980   array_node = save_expr (array_node);
981   lhs_type_node   = build_java_check_indexed_type (array_node, lhs_type_node);
982
983   load_node = build_java_arrayaccess (array_node,
984                                       lhs_type_node,
985                                       index_node);
986
987   if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
988     load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
989   push_value (load_node);
990 }
991
992 /* Expands .length. Makes sure that we deal with and array and may expand
993    a NULL check on the array object.  */
994
995 static void
996 expand_java_array_length ()
997 {
998   tree array  = pop_value (ptr_type_node);
999   tree length = build_java_array_length_access (array);
1000
1001   push_value (build_java_arraynull_check (array, length, int_type_node));
1002 }
1003
1004 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1005    either soft_monitorenter_node or soft_monitorexit_node.  */
1006
1007 static tree
1008 build_java_monitor (call, object)
1009     tree call;
1010     tree object;
1011 {
1012   return (build (CALL_EXPR,
1013                  void_type_node,
1014                  build_address_of (call),
1015                  build_tree_list (NULL_TREE, object),
1016                  NULL_TREE));
1017 }
1018
1019 /* Emit code for one of the PUSHC instructions. */
1020
1021 static void
1022 expand_java_pushc (ival, type)
1023      int ival;
1024      tree type;
1025 {
1026   tree value;
1027   if (type == ptr_type_node && ival == 0)
1028     value = null_pointer_node;
1029   else if (type == int_type_node || type == long_type_node)
1030     {
1031       value = build_int_2 (ival, ival < 0 ? -1 : 0);
1032       TREE_TYPE (value) = type;
1033     }
1034   else if (type == float_type_node || type == double_type_node)
1035     {
1036       REAL_VALUE_TYPE x;
1037 #ifdef REAL_ARITHMETIC
1038       REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1039 #else
1040       x = ival;
1041 #endif
1042       value = build_real (type, x);
1043     }
1044   else
1045     fatal ("internal error in expand_java_pushc");
1046   push_value (value);
1047 }
1048
1049 static void
1050 expand_java_return (type)
1051      tree type;
1052 {
1053   if (type == void_type_node)
1054     expand_null_return ();
1055   else
1056     {
1057       tree retval = pop_value (type);
1058       tree res = DECL_RESULT (current_function_decl);
1059       retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1060
1061       /* Handle the situation where the native integer type is smaller
1062          than the JVM integer. It can happen for many cross compilers.
1063          The whole if expression just goes away if INT_TYPE_SIZE < 32
1064          is false. */
1065       if (INT_TYPE_SIZE < 32
1066           && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1067               < GET_MODE_SIZE (TYPE_MODE (type))))
1068         retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1069       
1070       TREE_SIDE_EFFECTS (retval) = 1;
1071       expand_return (retval);
1072     }
1073 }
1074
1075 tree
1076 build_address_of (value)
1077      tree value;
1078 {
1079   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1080 }
1081
1082 static void
1083 expand_java_NEW (type)
1084      tree type;
1085 {
1086   if (! CLASS_LOADED_P (type))
1087     load_class (type, 1);
1088   safe_layout_class (type);
1089   push_value (build (CALL_EXPR, promote_type (type),
1090                      build_address_of (alloc_object_node),
1091                      tree_cons (NULL_TREE, build_class_ref (type),
1092                                 build_tree_list (NULL_TREE,
1093                                                  size_in_bytes (type))),
1094                      NULL_TREE));
1095 }
1096
1097 /* This returns an expression which will extract the class of an
1098    object.  */
1099
1100 tree
1101 build_get_class (value)
1102      tree value;
1103 {
1104   tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1105   tree vtable_field = lookup_field (&object_type_node,
1106                                     get_identifier ("vtable"));
1107   return build (COMPONENT_REF, class_ptr_type,
1108                 build1 (INDIRECT_REF, dtable_type,
1109                         build (COMPONENT_REF, dtable_ptr_type,
1110                                build1 (INDIRECT_REF, object_type_node, value),
1111                                vtable_field)),
1112                 class_field);
1113 }
1114
1115 /* This builds the tree representation of the `instanceof' operator.
1116    It tries various tricks to optimize this in cases where types are
1117    known.  */
1118
1119 tree
1120 build_instanceof (value, type)
1121      tree value, type;
1122 {
1123   tree expr;
1124   tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1125   tree valtype = TREE_TYPE (TREE_TYPE (value));
1126   tree valclass = TYPE_NAME (valtype);
1127   tree klass;
1128
1129   /* When compiling from bytecode, we need to ensure that TYPE has
1130      been loaded.  */
1131   if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1132     {
1133       load_class (type, 1);
1134       safe_layout_class (type);
1135       if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1136         return error_mark_node;
1137     }
1138   klass = TYPE_NAME (type);
1139
1140   if (type == object_type_node || inherits_from_p (valtype, type))
1141     {
1142       /* Anything except `null' is an instance of Object.  Likewise,
1143          if the object is known to be an instance of the class, then
1144          we only need to check for `null'.  */
1145       expr = build (COND_EXPR, itype,
1146                     value,
1147                     boolean_true_node, boolean_false_node);
1148     }
1149   else if (DECL_P (klass) && DECL_P (valclass)
1150            && ! CLASS_INTERFACE (valclass)
1151            && ! CLASS_INTERFACE (klass)
1152            && ! inherits_from_p (type, valtype)
1153            && (CLASS_FINAL (klass)
1154                || ! inherits_from_p (valtype, type)))
1155     {
1156       /* The classes are from different branches of the derivation
1157          tree, so we immediately know the answer.  */
1158       expr = boolean_false_node;
1159     }
1160   else if (DECL_P (klass) && CLASS_FINAL (klass))
1161     {
1162       tree save = save_expr (value);
1163       expr = build (COND_EXPR, itype,
1164                     save,
1165                     build (EQ_EXPR, itype,
1166                            build_get_class (save),
1167                            build_class_ref (type)),
1168                     boolean_false_node);
1169     }
1170   else
1171     {
1172       expr = build (CALL_EXPR, itype,
1173                     build_address_of (soft_instanceof_node),
1174                     tree_cons (NULL_TREE, value,
1175                                build_tree_list (NULL_TREE,
1176                                                 build_class_ref (type))),
1177                     NULL_TREE);
1178     }
1179   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1180   return expr;
1181 }
1182
1183 static void
1184 expand_java_INSTANCEOF (type)
1185      tree type;
1186 {
1187   tree value = pop_value (object_ptr_type_node);
1188   value = build_instanceof (value, type);
1189   push_value (value);
1190 }
1191
1192 static void
1193 expand_java_CHECKCAST (type)
1194      tree type;
1195 {
1196   tree value = pop_value (ptr_type_node);
1197   value = build (CALL_EXPR, promote_type (type),
1198                  build_address_of (soft_checkcast_node),
1199                  tree_cons (NULL_TREE, build_class_ref (type),
1200                             build_tree_list (NULL_TREE, value)),
1201                  NULL_TREE);
1202   push_value (value);
1203 }
1204
1205 static void
1206 expand_iinc (local_var_index, ival, pc)
1207      unsigned int local_var_index;
1208      int ival;
1209      int pc;
1210 {
1211     tree local_var, res;
1212     tree constant_value;
1213
1214     flush_quick_stack ();
1215     local_var = find_local_variable (local_var_index, int_type_node, pc);
1216     constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1217     res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1218     expand_assignment (local_var, res, 0, 0);
1219 }
1220
1221       
1222 tree
1223 build_java_soft_divmod (op, type, op1, op2)
1224     enum tree_code op;
1225     tree type, op1, op2;
1226 {
1227   tree call = NULL;
1228   tree arg1 = convert (type, op1);
1229   tree arg2 = convert (type, op2);
1230
1231   if (type == int_type_node)
1232     {     
1233       switch (op)
1234         {
1235         case TRUNC_DIV_EXPR:
1236           call = soft_idiv_node;
1237           break;
1238         case TRUNC_MOD_EXPR:
1239           call = soft_irem_node;
1240           break;
1241         default:
1242           break;
1243         }
1244     }
1245   else if (type == long_type_node)
1246     {     
1247       switch (op)
1248         {
1249         case TRUNC_DIV_EXPR:
1250           call = soft_ldiv_node;
1251           break;
1252         case TRUNC_MOD_EXPR:
1253           call = soft_lrem_node;
1254           break;
1255         default:
1256           break;
1257         }
1258     }
1259
1260   if (! call)
1261     fatal ("Internal compiler error in build_java_soft_divmod");
1262                   
1263   call = build (CALL_EXPR, type,
1264                 build_address_of (call),
1265                 tree_cons (NULL_TREE, arg1,
1266                            build_tree_list (NULL_TREE, arg2)),
1267                 NULL_TREE);
1268           
1269   return call;
1270 }
1271
1272 tree
1273 build_java_binop (op, type, arg1, arg2)
1274      enum tree_code op;
1275      tree type, arg1, arg2;
1276 {
1277   tree mask;
1278   switch (op)
1279     {
1280     case URSHIFT_EXPR:
1281       {
1282         tree u_type = unsigned_type (type);
1283         arg1 = convert (u_type, arg1);
1284         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1285         return convert (type, arg1);
1286       }
1287     case LSHIFT_EXPR:
1288     case RSHIFT_EXPR:
1289       mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1290       arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1291       break;
1292
1293     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1294     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1295       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1296       {
1297         tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1298                                     boolean_type_node, arg1, arg2));
1299         tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1300         tree second_compare = fold (build (COND_EXPR, int_type_node,
1301                                            ifexp2, integer_zero_node,
1302                                            op == COMPARE_L_EXPR
1303                                            ? integer_negative_one_node
1304                                            : integer_one_node));
1305         return fold (build (COND_EXPR, int_type_node, ifexp1,
1306                             op == COMPARE_L_EXPR ? integer_one_node
1307                             : integer_negative_one_node,
1308                             second_compare));
1309       }
1310     case COMPARE_EXPR:
1311       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1312       {
1313         tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1314         tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1315         tree second_compare = fold ( build (COND_EXPR, int_type_node,
1316                                             ifexp2, integer_one_node,
1317                                             integer_zero_node));
1318         return fold (build (COND_EXPR, int_type_node,
1319                             ifexp1, integer_negative_one_node, second_compare));
1320       }      
1321     case TRUNC_DIV_EXPR:
1322     case TRUNC_MOD_EXPR:
1323       if (TREE_CODE (type) == REAL_TYPE
1324           && op == TRUNC_MOD_EXPR)
1325         {
1326           tree call;
1327           if (type != double_type_node)
1328             {
1329               arg1 = convert (double_type_node, arg1);
1330               arg2 = convert (double_type_node, arg2);
1331             }
1332           call = build (CALL_EXPR, double_type_node,
1333                         build_address_of (soft_fmod_node),
1334                         tree_cons (NULL_TREE, arg1,
1335                                    build_tree_list (NULL_TREE, arg2)),
1336                         NULL_TREE);
1337           if (type != double_type_node)
1338             call = convert (type, call);
1339           return call;
1340         }
1341       
1342       if (TREE_CODE (type) == INTEGER_TYPE
1343           && flag_use_divide_subroutine
1344           && ! flag_syntax_only)
1345         return build_java_soft_divmod (op, type, arg1, arg2);
1346       
1347       break;
1348     default:  ;
1349     }
1350   return fold (build (op, type, arg1, arg2));
1351 }
1352
1353 static void
1354 expand_java_binop (type, op)
1355      tree type;  enum tree_code op;
1356 {
1357   tree larg, rarg;
1358   tree ltype = type;
1359   tree rtype = type;
1360   switch (op)
1361     {
1362     case LSHIFT_EXPR:
1363     case RSHIFT_EXPR:
1364     case URSHIFT_EXPR:
1365       rtype = int_type_node;
1366       rarg = pop_value (rtype);
1367       break;
1368     default:
1369       rarg = pop_value (rtype);
1370     }
1371   larg = pop_value (ltype);
1372   push_value (build_java_binop (op, type, larg, rarg));
1373 }
1374
1375 /* Lookup the field named NAME in *TYPEP or its super classes.
1376    If not found, return NULL_TREE.
1377    (If the *TYPEP is not found, or if the field reference is
1378    ambiguous, return error_mark_node.)
1379    If found, return the FIELD_DECL, and set *TYPEP to the
1380    class containing the field. */
1381
1382 tree
1383 lookup_field (typep, name)
1384      tree *typep;
1385      tree name;
1386 {
1387   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1388     {
1389       load_class (*typep, 1);
1390       safe_layout_class (*typep);
1391       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1392         return error_mark_node;
1393     }
1394   do
1395     {
1396       tree field, basetype_vec;
1397       tree save_field;
1398       int n, i;
1399
1400       for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1401         if (DECL_NAME (field) == name)
1402           return field;
1403
1404       /* If *typep is an innerclass, lookup the field in its enclosing
1405          contexts */
1406       if (INNER_CLASS_TYPE_P (*typep))
1407         {
1408           tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1409
1410           if ((field = lookup_field (&outer_type, name)))
1411             return field;
1412         }
1413
1414       /* Process implemented interfaces. */
1415       basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1416       n = TREE_VEC_LENGTH (basetype_vec);
1417       save_field = NULL_TREE;
1418       for (i = 0; i < n; i++)
1419         {
1420           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1421           if ((field = lookup_field (&t, name)))
1422             {
1423               if (save_field == field)
1424                 continue;
1425               if (save_field == NULL_TREE)
1426                 save_field = field;
1427               else
1428                 {
1429                   tree i1 = DECL_CONTEXT (save_field);
1430                   tree i2 = DECL_CONTEXT (field);
1431                   error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1432                          IDENTIFIER_POINTER (name),
1433                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1434                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1435                   return error_mark_node;
1436                 }
1437             }
1438         }
1439
1440       if (save_field != NULL_TREE)
1441         return save_field;
1442
1443       *typep = CLASSTYPE_SUPER (*typep);
1444     } while (*typep);
1445   return NULL_TREE;
1446 }
1447
1448 /* Look up the field named NAME in object SELF_VALUE,
1449    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1450    SELF_VALUE is NULL_TREE if looking for a static field. */
1451
1452 tree
1453 build_field_ref (self_value, self_class, name)
1454      tree self_value, self_class, name;
1455 {
1456   tree base_class = self_class;
1457   tree field_decl = lookup_field (&base_class, name);
1458   if (field_decl == NULL_TREE)
1459     {
1460       error ("field `%s' not found", IDENTIFIER_POINTER (name));
1461       return error_mark_node;
1462     }
1463   if (self_value == NULL_TREE)
1464     {
1465       return build_static_field_ref (field_decl);
1466     }
1467   else
1468     {
1469       tree base_handle_type = promote_type (base_class);
1470       if (base_handle_type != TREE_TYPE (self_value))
1471         self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1472 #ifdef JAVA_USE_HANDLES
1473       self_value = unhand_expr (self_value);
1474 #endif
1475       self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1476                            self_value);
1477       return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1478                           self_value, field_decl));
1479     }
1480 }
1481
1482 tree
1483 lookup_label (pc)
1484      int pc;
1485 {
1486   tree name;
1487   char buf[32];
1488   ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1489   name = get_identifier (buf);
1490   if (IDENTIFIER_LOCAL_VALUE (name))
1491     return IDENTIFIER_LOCAL_VALUE (name);
1492   else
1493     {
1494       /* The type of the address of a label is return_address_type_node. */
1495       tree decl = create_label_decl (name);
1496       LABEL_PC (decl) = pc;
1497       label_rtx (decl);
1498       return pushdecl (decl);
1499     }
1500 }
1501
1502 /* Generate a unique name for the purpose of loops and switches
1503    labels, and try-catch-finally blocks label or temporary variables.  */
1504
1505 tree
1506 generate_name ()
1507 {
1508   static int l_number = 0;
1509   char buff [32];
1510   ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1511   l_number++;
1512   return get_identifier (buff);
1513 }
1514
1515 tree
1516 create_label_decl (name)
1517      tree name;
1518 {
1519   tree decl;
1520   decl = build_decl (LABEL_DECL, name, 
1521                      TREE_TYPE (return_address_type_node));
1522   DECL_CONTEXT (decl) = current_function_decl;
1523   DECL_IGNORED_P (decl) = 1;
1524   return decl;
1525 }
1526
1527 /* This maps a bytecode offset (PC) to various flags. */
1528 char *instruction_bits;
1529
1530 static void
1531 note_label (current_pc, target_pc)
1532      int current_pc ATTRIBUTE_UNUSED, target_pc;
1533 {
1534   lookup_label (target_pc);
1535   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1536 }
1537
1538 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1539    where CONDITION is one of one the compare operators. */
1540
1541 static void
1542 expand_compare (condition, value1, value2, target_pc)
1543      enum tree_code condition;
1544      tree value1, value2;
1545      int target_pc;
1546 {
1547   tree target = lookup_label (target_pc);
1548   tree cond = fold (build (condition, boolean_type_node, value1, value2));
1549   expand_start_cond (truthvalue_conversion (cond), 0);
1550   expand_goto (target);
1551   expand_end_cond ();
1552 }
1553
1554 /* Emit code for a TEST-type opcode. */
1555
1556 static void
1557 expand_test (condition, type, target_pc)
1558      enum tree_code condition;
1559      tree type;
1560      int target_pc;
1561 {
1562   tree value1, value2;
1563   flush_quick_stack ();
1564   value1 = pop_value (type);
1565   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1566   expand_compare (condition, value1, value2, target_pc);
1567 }
1568
1569 /* Emit code for a COND-type opcode. */
1570
1571 static void
1572 expand_cond (condition, type, target_pc)
1573      enum tree_code condition;
1574      tree type;
1575      int target_pc;
1576 {
1577   tree value1, value2;
1578   flush_quick_stack ();
1579   /* note: pop values in opposite order */
1580   value2 = pop_value (type);
1581   value1 = pop_value (type);
1582   /* Maybe should check value1 and value2 for type compatibility ??? */
1583   expand_compare (condition, value1, value2, target_pc);
1584 }
1585
1586 static void
1587 expand_java_goto (target_pc)
1588      int target_pc;
1589 {
1590   tree target_label = lookup_label (target_pc);
1591   flush_quick_stack ();
1592   expand_goto (target_label);
1593 }
1594
1595 #if 0
1596 static void
1597 expand_java_call (target_pc, return_address)
1598      int target_pc, return_address;
1599 {
1600   tree target_label = lookup_label (target_pc);
1601   tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1602   push_value (value);
1603   flush_quick_stack ();
1604   expand_goto (target_label);
1605 }
1606
1607 static void
1608 expand_java_ret (return_address)
1609      tree return_address ATTRIBUTE_UNUSED;
1610 {
1611   warning ("ret instruction not implemented");
1612 #if 0
1613   tree target_label = lookup_label (target_pc);
1614   flush_quick_stack ();
1615   expand_goto (target_label);
1616 #endif
1617 }
1618 #endif
1619
1620 static tree
1621 pop_arguments (arg_types)
1622      tree arg_types;
1623 {
1624   if (arg_types == end_params_node)
1625     return NULL_TREE;
1626   if (TREE_CODE (arg_types) == TREE_LIST)
1627     {
1628       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1629       tree type = TREE_VALUE (arg_types);
1630       tree arg = pop_value (type);
1631       if (PROMOTE_PROTOTYPES
1632           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1633           && INTEGRAL_TYPE_P (type))
1634         arg = convert (integer_type_node, arg);
1635       return tree_cons (NULL_TREE, arg, tail);
1636     }
1637   abort ();
1638 }
1639
1640 /* Build an expression to initialize the class CLAS.
1641    if EXPR is non-NULL, returns an expression to first call the initializer
1642    (if it is needed) and then calls EXPR. */
1643
1644 tree
1645 build_class_init (clas, expr)
1646      tree clas, expr;
1647 {
1648   tree init, call;
1649   struct init_test_hash_entry *ite;
1650   if (inherits_from_p (current_class, clas))
1651     return expr;
1652
1653   if (always_initialize_class_p)
1654     {
1655       init = build (CALL_EXPR, void_type_node,
1656                     build_address_of (soft_initclass_node),
1657                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1658                     NULL_TREE);
1659       TREE_SIDE_EFFECTS (init) = 1;
1660     }
1661   else
1662     {
1663       ite = (struct init_test_hash_entry *)
1664         hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1665                      (const hash_table_key) clas,
1666                      TRUE, NULL);
1667       
1668       if (ite->init_test_decl == 0)
1669         ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE, 
1670                                           boolean_type_node);
1671       /* Tell the check-init code to ignore this decl.  */
1672       DECL_BIT_INDEX(ite->init_test_decl) = -1;
1673
1674       init = build (CALL_EXPR, void_type_node,
1675                     build_address_of (soft_initclass_node),
1676                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1677                     NULL_TREE);
1678       TREE_SIDE_EFFECTS (init) = 1;
1679       call = build (COMPOUND_EXPR, TREE_TYPE (expr), init, 
1680                     build (MODIFY_EXPR, boolean_type_node,
1681                            ite->init_test_decl, boolean_true_node));
1682       TREE_SIDE_EFFECTS (call) = 1;
1683       init = build (COND_EXPR, void_type_node,
1684                     build (EQ_EXPR, boolean_type_node, 
1685                            ite->init_test_decl, boolean_false_node),
1686                     call, integer_zero_node);
1687       TREE_SIDE_EFFECTS (init) = 1;
1688     }
1689
1690   if (expr != NULL_TREE)
1691     {
1692       expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1693       TREE_SIDE_EFFECTS (expr) = 1;
1694       return expr;
1695     }
1696   return init;
1697 }
1698
1699 tree
1700 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1701      tree method, method_type ATTRIBUTE_UNUSED, self_type,
1702           method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1703 {
1704   tree func;
1705   if (is_compiled_class (self_type))
1706     {
1707       make_decl_rtl (method, NULL);
1708       func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1709     }
1710   else
1711     {
1712       /* We don't know whether the method has been (statically) compiled.
1713          Compile this code to get a reference to the method's code:
1714          
1715          SELF_TYPE->methods[METHOD_INDEX].ncode
1716          
1717          This is guaranteed to work (assuming SELF_TYPE has
1718          been initialized), since if the method is not compiled yet,
1719          its ncode points to a trampoline that forces compilation. */
1720       
1721       int method_index = 0;
1722       tree meth;
1723       tree ref = build_class_ref (self_type);
1724       ref = build1 (INDIRECT_REF, class_type_node, ref);
1725       if (ncode_ident == NULL_TREE)
1726         ncode_ident = get_identifier ("ncode");
1727       if (methods_ident == NULL_TREE)
1728         methods_ident = get_identifier ("methods");
1729       ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1730                    lookup_field (&class_type_node, methods_ident));
1731       for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1732            ; meth = TREE_CHAIN (meth))
1733         {
1734           if (method == meth)
1735             break;
1736           if (meth == NULL_TREE)
1737             fatal ("method '%s' not found in class",
1738                    IDENTIFIER_POINTER (DECL_NAME (method)));
1739           method_index++;
1740         }
1741       method_index *= int_size_in_bytes (method_type_node);
1742       ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1743                          ref, build_int_2 (method_index, 0)));
1744       ref = build1 (INDIRECT_REF, method_type_node, ref);
1745       func = build (COMPONENT_REF, nativecode_ptr_type_node,
1746                     ref,
1747                     lookup_field (&method_type_node, ncode_ident));
1748     }
1749   return func;
1750 }
1751
1752 tree
1753 invoke_build_dtable (is_invoke_interface, arg_list)
1754      int is_invoke_interface;
1755      tree arg_list;
1756 {
1757   tree dtable, objectref;
1758
1759   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1760
1761   /* If we're dealing with interfaces and if the objectref
1762      argument is an array then get the dispatch table of the class
1763      Object rather than the one from the objectref.  */
1764   objectref = (is_invoke_interface 
1765                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1766                object_type_node : TREE_VALUE (arg_list));
1767   
1768   if (dtable_ident == NULL_TREE)
1769     dtable_ident = get_identifier ("vtable");
1770   dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1771   dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1772                   lookup_field (&object_type_node, dtable_ident));
1773
1774   return dtable;
1775 }
1776
1777 tree 
1778 build_invokevirtual (dtable, method)
1779      tree dtable, method;
1780 {
1781   tree func;
1782   tree nativecode_ptr_ptr_type_node
1783     = build_pointer_type (nativecode_ptr_type_node);
1784   tree method_index = convert (sizetype, DECL_VINDEX (method));
1785
1786   /* Add one to skip "class" field of dtable, and one to skip unused
1787      vtable entry (for C++ compatibility). */
1788   method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1789   method_index = size_binop (MULT_EXPR, method_index,
1790                              TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1791   func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1792                       convert (nativecode_ptr_ptr_type_node, method_index)));
1793   func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1794
1795   return func;
1796 }
1797
1798 tree
1799 build_invokeinterface (dtable, method)
1800      tree dtable, method;
1801 {
1802   static tree class_ident = NULL_TREE;
1803   tree lookup_arg;
1804   tree interface;
1805   tree idx;
1806   tree meth;
1807   int i;
1808
1809   /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
1810      ensure that the selected method exists, is public and not
1811      abstract nor static.  */
1812             
1813   if (class_ident == NULL_TREE)
1814     {
1815       class_ident = get_identifier ("class");
1816       ggc_add_tree_root (&class_ident, 1);
1817     }
1818
1819   dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1820   dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1821                   lookup_field (&dtable_type, class_ident));
1822
1823   interface = DECL_CONTEXT (method);
1824   layout_class_methods (interface);
1825   
1826   i = 1;
1827   for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1828     {
1829       if (meth == method)
1830         {
1831           idx = build_int_2 (i, 0);
1832           break;
1833         }
1834       if (meth == NULL_TREE)
1835         fatal ("internal error in build_invokeinterface");
1836     }
1837
1838   lookup_arg = tree_cons (NULL_TREE, dtable,
1839                           tree_cons (NULL_TREE, build_class_ref (interface),
1840                                      build_tree_list (NULL_TREE, idx)));
1841                                                           
1842   return build (CALL_EXPR, ptr_type_node, 
1843                 build_address_of (soft_lookupinterfacemethod_node),
1844                 lookup_arg, NULL_TREE);
1845 }
1846   
1847 /* Expand one of the invoke_* opcodes.
1848    OCPODE is the specific opcode.
1849    METHOD_REF_INDEX is an index into the constant pool.
1850    NARGS is the number of arguments, or -1 if not specified. */
1851
1852 static void
1853 expand_invoke (opcode, method_ref_index, nargs)
1854      int opcode;
1855      int method_ref_index;
1856      int nargs ATTRIBUTE_UNUSED;
1857 {
1858   tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1859   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1860   tree self_type = get_class_constant
1861     (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1862   const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1863   tree call, func, method, arg_list, method_type;
1864   tree cond = NULL_TREE;
1865
1866   if (! CLASS_LOADED_P (self_type))
1867     {
1868       load_class (self_type, 1);
1869       safe_layout_class (self_type);
1870       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1871         fatal ("failed to find class '%s'", self_name);
1872     }
1873   layout_class_methods (self_type);
1874
1875   if (ID_INIT_P (method_name))
1876     method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1877                                       method_signature);
1878   else
1879     method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1880                                  method_name, method_signature);
1881   if (method == NULL_TREE)
1882     {
1883       error ("Class '%s' has no method named '%s' matching signature '%s'",
1884              self_name,
1885              IDENTIFIER_POINTER (method_name),
1886              IDENTIFIER_POINTER (method_signature));
1887     }
1888   /* Invoke static can't invoke static/abstract method */
1889   else if (opcode == OPCODE_invokestatic)
1890     {
1891       if (!METHOD_STATIC (method))
1892         {
1893           error ("invokestatic on non static method");
1894           method = NULL_TREE;
1895         }
1896       else if (METHOD_ABSTRACT (method))
1897         {
1898           error ("invokestatic on abstract method");
1899           method = NULL_TREE;
1900         }
1901     }
1902   else
1903     {
1904       if (METHOD_STATIC (method))
1905         {
1906           error ("invoke[non-static] on static method");
1907           method = NULL_TREE;
1908         }
1909     }
1910
1911   if (method == NULL_TREE)
1912     {
1913       method_type = get_type_from_signature (method_signature);
1914       pop_arguments (TYPE_ARG_TYPES (method_type));
1915       if (opcode != OPCODE_invokestatic) 
1916         pop_type (self_type);
1917       method_type = promote_type (TREE_TYPE (method_type));
1918       push_value (convert (method_type, integer_zero_node));
1919       return;
1920     }
1921
1922   method_type = TREE_TYPE (method);
1923   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1924   flush_quick_stack ();
1925
1926   func = NULL_TREE;
1927   if (opcode == OPCODE_invokestatic)
1928     func = build_known_method_ref (method, method_type, self_type,
1929                                    method_signature, arg_list);
1930   else if (opcode == OPCODE_invokespecial
1931            || (opcode == OPCODE_invokevirtual
1932                && (METHOD_PRIVATE (method)
1933                    || METHOD_FINAL (method) 
1934                    || CLASS_FINAL (TYPE_NAME (self_type)))))
1935     {
1936       /* If the object for the method call is null, we throw an
1937          exception.  We don't do this if the object is the current
1938          method's `this'.  In other cases we just rely on an
1939          optimization pass to eliminate redundant checks.  FIXME:
1940          Unfortunately there doesn't seem to be a way to determine
1941          what the current method is right now.  */
1942       /* We use a SAVE_EXPR here to make sure we only evaluate
1943          the new `self' expression once.  */
1944       tree save_arg = save_expr (TREE_VALUE (arg_list));
1945       TREE_VALUE (arg_list) = save_arg;
1946       cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1947       func = build_known_method_ref (method, method_type, self_type,
1948                                      method_signature, arg_list);
1949     }
1950   else
1951     {
1952       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
1953                                          arg_list);
1954       if (opcode == OPCODE_invokevirtual)
1955         func = build_invokevirtual (dtable, method);
1956       else
1957         func = build_invokeinterface (dtable, method);
1958     }
1959   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1960   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1961   TREE_SIDE_EFFECTS (call) = 1;
1962
1963   if (cond != NULL_TREE)
1964     {
1965       /* We have to make the `then' branch a compound expression to
1966          make the types turn out right.  This seems bizarre.  */
1967       call = build (COND_EXPR, TREE_TYPE (call), cond,
1968                     build (COMPOUND_EXPR, TREE_TYPE (call),
1969                            build (CALL_EXPR, void_type_node,
1970                                   build_address_of (soft_nullpointer_node),
1971                                   NULL_TREE, NULL_TREE),
1972                            (FLOAT_TYPE_P (TREE_TYPE (call))
1973                             ? build_real (TREE_TYPE (call), dconst0)
1974                             : build1 (CONVERT_EXPR, TREE_TYPE (call),
1975                                       integer_zero_node))),
1976                     call);
1977       TREE_SIDE_EFFECTS (call) = 1;
1978     }
1979
1980   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1981     expand_expr_stmt (call);
1982   else
1983     {
1984       push_value (call);
1985       flush_quick_stack ();
1986     }
1987 }
1988
1989 /* Create a stub which will be put into the vtable but which will call
1990    a JNI function.  */
1991
1992 tree
1993 build_jni_stub (method)
1994      tree method;
1995 {
1996   tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1997   tree jni_func_type, tem;
1998   tree env_var, res_var = NULL_TREE, block;
1999   tree method_args, res_type;
2000   tree meth_var;
2001
2002   tree klass = DECL_CONTEXT (method);
2003   int from_class = ! CLASS_FROM_SOURCE_P (klass);
2004   klass = build_class_ref (klass);
2005
2006   if (! METHOD_NATIVE (method) || ! flag_jni)
2007     abort ();
2008
2009   DECL_ARTIFICIAL (method) = 1;
2010   DECL_EXTERNAL (method) = 0;
2011
2012   env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2013   DECL_CONTEXT (env_var) = method;
2014
2015   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2016     {
2017       res_var = build_decl (VAR_DECL, get_identifier ("res"),
2018                             TREE_TYPE (TREE_TYPE (method)));
2019       DECL_CONTEXT (res_var) = method;
2020       TREE_CHAIN (env_var) = res_var;
2021     }
2022
2023   meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2024   TREE_STATIC (meth_var) = 1;
2025   TREE_PUBLIC (meth_var) = 0;
2026   DECL_EXTERNAL (meth_var) = 0;
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             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2391             make_decl_rtl (init_decl, NULL);
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             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2414             make_decl_rtl (init_decl, NULL);
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 }