OSDN Git Service

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