Allow uses of interface types to verify.
[platform/upstream/gcc.git] / gcc / java / expr.c
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
26
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "real.h"
31 #include "rtl.h"
32 #include "expr.h"
33 #include "java-tree.h"
34 #include "javaop.h"
35 #include "java-opcodes.h"
36 #include "jcf.h"
37 #include "java-except.h"
38 #include "parse.h"
39 #include "toplev.h"
40
41 static tree operand_type[59];
42 extern struct obstack permanent_obstack;
43
44 void
45 init_expr_processing()
46 {
47   operand_type[21] = operand_type[54] = int_type_node;
48   operand_type[22] = operand_type[55] = long_type_node;
49   operand_type[23] = operand_type[56] = float_type_node;
50   operand_type[24] = operand_type[57] = double_type_node;
51   operand_type[25] = operand_type[58] = ptr_type_node;
52 }
53
54 /* We store the stack state in two places:
55    Within a basic block, we use the quick_stack, which is a
56    pushdown list (TREE_LISTs) of expression nodes.
57    This is the top part of the stack;  below that we use find_stack_slot.
58    At the end of a basic block, the quick_stack must be flushed
59    to the stack slot array (as handled by find_stack_slot).
60    Using quick_stack generates better code (especially when
61    compiled without optimization), because we do not have to
62    explicitly store and load trees to temporary variables.
63
64    If a variable is on the quick stack, it means the value of variable
65    when the quick stack was last flushed.  Conceptually, flush_quick_stack
66    saves all the the quick_stack elements in parellel.  However, that is
67    complicated, so it actually saves them (i.e. copies each stack value
68    to is home virtual register) from low indexes.  This allows a quick_stack
69    element at index i (counting from the bottom of stack the) to references
70    slot virtuals for register that are >= i, but not those that are deeper.
71    This convention makes most operations easier.  For example iadd works
72    even when the stack contains (reg[0], reg[1]):  It results in the
73    stack containing (reg[0]+reg[1]), which is OK.  However, some stack
74    operations are more complicated.  For example dup given a stack
75    containing (reg[0]) would yield (reg[0], reg[0]), which would violate
76    the convention, since stack value 1 would refer to a register with
77    lower index (reg[0]), which flush_quick_stack does not safely handle.
78    So dup cannot just add an extra element to the quick_stack, but iadd can.
79 */
80
81 tree quick_stack = NULL_TREE;
82
83 /* A free-list of unused permamnet TREE_LIST nodes. */
84 tree tree_list_free_list = NULL_TREE;
85
86 /* The stack pointer of the Java virtual machine.
87    This does include the size of the quick_stack. */
88
89 int stack_pointer;
90
91 unsigned char *linenumber_table;
92 int linenumber_count;
93
94 tree
95 truthvalue_conversion (expr)
96      tree expr;
97 {
98   /* It is simpler and generates better code to have only TRUTH_*_EXPR
99      or comparison expressions as truth values at this level.
100
101      This function should normally be identity for Java.  */
102
103   switch (TREE_CODE (expr))
104     {
105     case EQ_EXPR:
106     case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
107     case TRUTH_ANDIF_EXPR:
108     case TRUTH_ORIF_EXPR:
109     case TRUTH_AND_EXPR:
110     case TRUTH_OR_EXPR:
111     case ERROR_MARK:
112       return expr;
113
114     case INTEGER_CST:
115       return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
116
117     case REAL_CST:
118       return real_zerop (expr) ? boolean_false_node : boolean_true_node;
119
120     /* are these legal? XXX JH */
121     case NEGATE_EXPR:
122     case ABS_EXPR:
123     case FLOAT_EXPR:
124     case FFS_EXPR:
125       /* These don't change whether an object is non-zero or zero.  */
126       return truthvalue_conversion (TREE_OPERAND (expr, 0));
127
128     case COND_EXPR:
129       /* Distribute the conversion into the arms of a COND_EXPR.  */
130       return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
131                           truthvalue_conversion (TREE_OPERAND (expr, 1)),
132                           truthvalue_conversion (TREE_OPERAND (expr, 2))));
133
134     case NOP_EXPR:
135       /* If this is widening the argument, we can ignore it.  */
136       if (TYPE_PRECISION (TREE_TYPE (expr))
137           >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
138         return truthvalue_conversion (TREE_OPERAND (expr, 0));
139       /* fall through to default */
140
141     default:
142       return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
143     }
144 }
145
146 #ifdef JAVA_USE_HANDLES
147 /* Given a pointer to a handle, get a pointer to an object. */
148
149 tree
150 unhand_expr (expr)
151      tree expr;
152 {
153   tree field, handle_type;
154   expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
155   handle_type = TREE_TYPE (expr);
156   field = TYPE_FIELDS (handle_type);
157   expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
158   return expr;
159 }
160 #endif
161
162 /* Save any stack slots that happen to be in the quick_stack into their
163    home virtual register slots.
164
165    The copy order is from low stack index to high, to support the invariant
166    that the expression for a slot may contain decls for stack slots with
167    higher (or the same) index, but not lower. */
168
169 void
170 flush_quick_stack ()
171 {
172   int stack_index = stack_pointer;
173   register tree prev, cur, next;
174
175   /* First reverse the quick_stack, and count the number of slots it has. */
176   for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
177     {
178       next = TREE_CHAIN (cur);
179       TREE_CHAIN (cur) = prev;
180       prev = cur;
181       stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
182     }
183   quick_stack = prev;
184
185   while (quick_stack != NULL_TREE)
186     {
187       tree decl;
188       tree node = quick_stack, type;
189       quick_stack = TREE_CHAIN (node);
190       TREE_CHAIN (node) = tree_list_free_list;
191       tree_list_free_list = node;
192       node = TREE_VALUE (node);
193       type = TREE_TYPE (node);
194
195       decl = find_stack_slot (stack_index, type);
196       if (decl != node)
197           expand_assignment (decl, node, 0, 0);
198       stack_index += 1 + TYPE_IS_WIDE (type);
199     }
200 }
201
202 void
203 push_type (type)
204      tree type;
205 {
206   int n_words;
207   type = promote_type (type);
208   n_words = 1 + TYPE_IS_WIDE (type);
209   if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
210     fatal ("stack overflow");
211   stack_type_map[stack_pointer++] = type;
212   n_words--;
213   while (--n_words >= 0)
214     stack_type_map[stack_pointer++] = TYPE_SECOND;
215 }
216
217 void
218 push_value (value)
219      tree value;
220 {
221   tree type = TREE_TYPE (value);
222   if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
223     {
224       type = promote_type (type);
225       value = convert (type, value);
226     }
227   push_type (type);
228   if (tree_list_free_list == NULL_TREE)
229     quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
230   else
231     {
232       tree node = tree_list_free_list;
233       tree_list_free_list = TREE_CHAIN (tree_list_free_list);
234       TREE_VALUE (node) = value;
235       TREE_CHAIN (node) = quick_stack;
236       quick_stack = node;
237     }
238 }
239
240 tree
241 pop_type (type)
242      tree type;
243 {
244   int n_words;
245   int i;
246   tree t;
247   if (TREE_CODE (type) == RECORD_TYPE)
248     type = promote_type (type);
249   n_words = 1 + TYPE_IS_WIDE (type);
250   if (stack_pointer < n_words)
251     fatal ("stack underflow");
252   while (--n_words > 0)
253     {
254       if (stack_type_map[--stack_pointer] != void_type_node)
255         fatal ("Invalid multi-word value on type stack");
256     }
257   t = stack_type_map[--stack_pointer];
258   if (type == NULL_TREE || t == type)
259     return t;
260   if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
261       && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
262       return t;
263   if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
264     {
265       if (type == ptr_type_node || type == object_ptr_type_node)
266         return t;
267       else if (t == ptr_type_node)  /* Special case for null reference. */
268         return type;
269       else if (can_widen_reference_to (t, type))
270         return t;
271       /* This is a kludge, but matches what Sun's verifier does.
272          It can be tricked, but is safe as long as type errors
273          (i.e. interface method calls) are caught at run-time. */
274       else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
275                && t == object_ptr_type_node)
276         return t;
277     }
278   error ("unexpected type on stack");
279   return t;
280 }
281
282 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
283    Handles array types and interfaces.  */
284
285 int
286 can_widen_reference_to (source_type, target_type)
287      tree source_type, target_type;
288 {
289   if (source_type == ptr_type_node || target_type == object_ptr_type_node)
290     return 1;
291
292   /* Get rid of pointers  */
293   if (TREE_CODE (source_type) == POINTER_TYPE)
294     source_type = TREE_TYPE (source_type);
295   if (TREE_CODE (target_type) == POINTER_TYPE)
296     target_type = TREE_TYPE (target_type);
297
298   if (source_type == target_type)
299     return 1;
300   else
301     {
302       source_type = HANDLE_TO_CLASS_TYPE (source_type);
303       target_type = HANDLE_TO_CLASS_TYPE (target_type);
304       if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
305         {
306           HOST_WIDE_INT source_length, target_length;
307           if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
308             return 0;
309           target_length = java_array_type_length (target_type);
310           if (target_length >= 0)
311             {
312               source_length = java_array_type_length (source_type);
313               if (source_length != target_length)
314                 return 0;
315             }
316           source_type = TYPE_ARRAY_ELEMENT (source_type);
317           target_type = TYPE_ARRAY_ELEMENT (target_type);
318           if (source_type == target_type)
319             return 1;
320           if (TREE_CODE (source_type) != POINTER_TYPE
321               || TREE_CODE (target_type) != POINTER_TYPE)
322             return 0;
323           return can_widen_reference_to (source_type, target_type);
324         }
325       else
326         {
327           int source_depth = class_depth (source_type);
328           int target_depth = class_depth (target_type);
329
330           if (CLASS_INTERFACE (TYPE_NAME (target_type)))
331             {
332               /* target_type is OK if source_type or source_type ancestors
333                  implement target_type. We handle multiple sub-interfaces  */
334
335               tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
336               int n = TREE_VEC_LENGTH (basetype_vec), i;
337               for (i=0 ; i < n; i++)
338                 if (can_widen_reference_to 
339                     (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
340                      target_type))
341                   return 1;
342                 if (n == 0)
343                   return 0;
344             }
345
346           for ( ; source_depth > target_depth;  source_depth--) 
347             {
348               source_type = TYPE_BINFO_BASETYPE (source_type, 0); 
349             }
350           return source_type == target_type;
351         }
352     }
353 }
354
355 tree
356 pop_value (type)
357      tree type;
358 {
359   int n_words = 1 + TYPE_IS_WIDE (type);
360   int i;
361   type = pop_type (type);
362   if (quick_stack)
363     {
364       tree node = quick_stack;
365       quick_stack = TREE_CHAIN (quick_stack);
366       TREE_CHAIN (node) = tree_list_free_list;
367       tree_list_free_list = node;
368       node = TREE_VALUE (node);
369       return node;
370     }
371   else
372     return find_stack_slot (stack_pointer, promote_type (type));
373 }
374
375
376 /* Pop and discrad the top COUNT stack slots. */
377
378 void
379 java_stack_pop (count)
380      int count;
381 {
382   while (count > 0)
383     {
384       tree type, val;
385       if (stack_pointer == 0)
386         fatal ("stack underflow");
387       type = stack_type_map[stack_pointer - 1];
388       if (type == TYPE_SECOND)
389         {
390           count--;
391           if (stack_pointer == 1 || count <= 0)
392             fatal ("stack underflow");
393           type = stack_type_map[stack_pointer - 2];
394         }
395       val = pop_value (type);
396       count--;
397     }
398 }
399
400 /* Implement the 'swap' operator (to swap two top stack slots). */
401
402 void
403 java_stack_swap ()
404 {
405   tree type1, type2;
406   rtx temp;
407   tree decl1, decl2;
408
409   if (stack_pointer < 2
410       || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
411       || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
412       || type1 == TYPE_SECOND || type2 == TYPE_SECOND
413       || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
414     fatal ("bad stack swap");
415
416   flush_quick_stack ();
417   decl1 = find_stack_slot (stack_pointer - 1, type1);
418   decl2 = find_stack_slot (stack_pointer - 2, type2);
419   temp = copy_to_reg (DECL_RTL (decl1));
420   emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
421   emit_move_insn (DECL_RTL (decl2), temp);
422   stack_type_map[stack_pointer - 1] = type2;
423   stack_type_map[stack_pointer - 2] = type1;
424 }
425
426 void
427 java_stack_dup (size, offset)
428      int size, offset;
429 {
430   int low_index = stack_pointer - size - offset;
431   int dst_index;
432   if (low_index < 0)
433     error ("stack underflow - dup* operation");
434
435   flush_quick_stack ();
436
437   stack_pointer += size;
438   dst_index = stack_pointer;
439
440   for (dst_index = stack_pointer;  --dst_index >= low_index; )
441     {
442       tree type;
443       int src_index = dst_index - size;
444       if (src_index < low_index)
445         src_index = dst_index + size + offset;
446       type = stack_type_map [src_index];
447       if (type == TYPE_SECOND)
448         {
449           if (src_index <= low_index)
450             fatal ("dup operation splits 64-bit number");
451           stack_type_map[dst_index] = type;
452           src_index--;  dst_index--;
453           type = stack_type_map[src_index];
454           if (! TYPE_IS_WIDE (type))
455             fatal ("internal error - dup operation");
456         }
457       else if (TYPE_IS_WIDE (type))
458         fatal ("internal error - dup operation");
459       if (src_index != dst_index)
460         {
461           tree src_decl = find_stack_slot (src_index, type);
462           tree dst_decl = find_stack_slot (dst_index, type);
463           emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
464           stack_type_map[dst_index] = type;
465         }
466     }
467 }
468
469 /* Calls _Jv_Throw.  Discard the contents of the value stack. */
470
471 tree
472 build_java_athrow (node)
473     tree node;
474 {
475   tree call;
476
477   call = build (CALL_EXPR,
478                 void_type_node,
479                 build_address_of (throw_node),
480                 build_tree_list (NULL_TREE, node),
481                 NULL_TREE);
482   TREE_SIDE_EFFECTS (call) = 1;
483   expand_expr_stmt (call);
484   java_stack_pop (stack_pointer);
485 }
486
487 /* Implementation for jsr/ret */
488
489 void
490 build_java_jsr (where, ret)
491     tree where;
492     tree ret;
493 {
494   tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
495   push_value (ret_label);
496   flush_quick_stack ();
497   expand_goto (where);
498   expand_label (ret);
499 }
500
501 void
502 build_java_ret (location)
503   tree location;
504 {
505   expand_computed_goto (location);
506 }
507  
508 /* Implementation of operations on array: new, load, store, length */
509
510 /* Array core info access macros */
511
512 #define JAVA_ARRAY_LENGTH_OFFSET(A)                                        \
513   size_binop (CEIL_DIV_EXPR,                                               \
514               (DECL_FIELD_BITPOS                                           \
515                   (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
516               size_int (BITS_PER_UNIT))
517
518 tree
519 decode_newarray_type  (int atype)
520 {
521   switch (atype)
522     {
523     case 4:  return boolean_type_node;
524     case 5:  return char_type_node;
525     case 6:  return float_type_node;
526     case 7:  return double_type_node;
527     case 8:  return byte_type_node;
528     case 9:  return short_type_node;
529     case 10: return int_type_node;
530     case 11: return long_type_node;
531     default: return NULL_TREE;
532     }
533 }
534
535 /* Build a call to _Jv_ThrowBadArrayIndex(), the
536    ArrayIndexOfBoundsException exception handler.  */
537
538 static tree
539 build_java_throw_out_of_bounds_exception (index)
540     tree index;
541 {
542   tree node = build (CALL_EXPR, int_type_node,
543                      build_address_of (soft_badarrayindex_node), 
544                      build_tree_list (NULL_TREE, index), NULL_TREE);
545   TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
546   return (node);
547 }
548
549 /* Return the length of an array. Doesn't perform any checking on the nature
550    or value of the array NODE. May be used to implement some bytecodes.  */
551
552 tree
553 build_java_array_length_access (node)
554     tree node;
555 {
556   tree type = TREE_TYPE (node);
557   HOST_WIDE_INT length;
558   if (!is_array_type_p (type))
559     fatal ("array length on a non-array reference");
560   length = java_array_type_length (type);
561   if (length >= 0)
562     return build_int_2 (length, 0);
563   return fold (build1 (INDIRECT_REF,
564                        int_type_node,
565                        fold (build (PLUS_EXPR, ptr_type_node,
566                                     node, 
567                                     JAVA_ARRAY_LENGTH_OFFSET(node)))));
568 }
569
570 /* Optionally checks an array against the NULL pointer, eventually throwing a
571    NullPointerException. It could replace signal handling, but tied to NULL.
572    ARG1: the pointer to check, ARG2: the expression to use if
573    the pointer is non-null and ARG3 the type that should be returned.   */
574
575 tree
576 build_java_arraynull_check (node, expr, type)
577     tree node;                  
578     tree expr;                  
579     tree type;                  
580 {
581 #if 0
582   static int java_array_access_throws_null_exception = 0;
583   node = ???;
584   if (java_array_access_throws_null_exception)
585       return (build (COND_EXPR, 
586                      type,
587                      build (EQ_EXPR, int_type_node, node, null_pointer_node),
588                      build_java_athrow (node), expr ));
589   else
590 #endif
591       return (expr);
592 }
593
594 static tree
595 java_array_data_offset (array)
596      tree array;
597 {
598   tree array_type = TREE_TYPE (TREE_TYPE (array));
599   tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
600   if (data_fld == NULL_TREE)
601     return size_in_bytes (array_type);
602   else
603     return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
604                         / BITS_PER_UNIT, 0);
605 }
606
607 /* Implement array indexing (either as l-value or r-value).
608    Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
609    Optionally performs bounds checking and/or test to NULL.
610    At this point, ARRAY should have been verified as an array.  */
611
612 tree
613 build_java_arrayaccess (array, type, index)
614     tree array, type, index;
615 {
616   tree arith, node, throw = NULL_TREE;
617
618   arith = fold (build (PLUS_EXPR, int_type_node,
619                        java_array_data_offset (array),
620                        fold (build (MULT_EXPR, int_type_node,
621                                     index, size_in_bytes(type)))));
622
623   if (flag_bounds_check)
624     {
625       /* Generate:
626        * (unsigned jint) INDEX >= (unsigned jint) LEN
627        *    && throw ArrayIndexOutOfBoundsException.
628        * Note this is equivalent to and more efficient than:
629        * INDEX < 0 || INDEX >= LEN && throw ... */
630       tree test;
631       tree len = build_java_array_length_access (array);
632       TREE_TYPE (len) = unsigned_int_type_node;
633       test = fold (build (GE_EXPR, boolean_type_node, 
634                                convert (unsigned_int_type_node, index),
635                                len));
636       if (! integer_zerop (test))
637         {
638           throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
639                          build_java_throw_out_of_bounds_exception (index));
640           /* allows expansion within COMPOUND */
641           TREE_SIDE_EFFECTS( throw ) = 1;
642         }
643     }
644
645   node = build1 (INDIRECT_REF, type, 
646                  fold (build (PLUS_EXPR, ptr_type_node, 
647                               array, 
648                               (throw ? build (COMPOUND_EXPR, int_type_node, 
649                                               throw, arith )
650                                      : arith))));
651
652   return (fold (build_java_arraynull_check (array, node, type)));
653 }
654
655 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
656    ARRAY_NODE. This function is used to retrieve something less vague than
657    a pointer type when indexing the first dimension of something like [[<t>.
658    May return a corrected type, if necessary, otherwise INDEXED_TYPE is
659    return unchanged.
660    As a side effect, it also makes sure that ARRAY_NODE is an array.  */
661
662 static tree
663 build_java_check_indexed_type (array_node, indexed_type)
664     tree array_node;
665     tree indexed_type;
666 {
667   tree elt_type;
668
669   if (!is_array_type_p (TREE_TYPE (array_node)))
670     fatal ("array indexing on a non-array reference");
671
672   elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
673
674   if (indexed_type == ptr_type_node )
675       return promote_type (elt_type);
676
677   /* BYTE/BOOLEAN store and load are used for both type */
678   if (indexed_type == byte_type_node && elt_type == boolean_type_node )
679     return boolean_type_node;
680
681   if (indexed_type != elt_type )
682     fatal ("type array element mismatch");
683   else
684     return indexed_type;
685 }
686
687 /* newarray triggers a call to _Jv_NewArray. This function should be called
688    with an integer code (the type of array to create) and get from the stack
689    the size of the dimmension.  */
690
691 tree
692 build_newarray (atype_value, length)
693      int atype_value;
694      tree length;
695 {
696   tree type = build_java_array_type (decode_newarray_type (atype_value),
697                                      TREE_CODE (length) == INTEGER_CST
698                                      ? TREE_INT_CST_LOW (length)
699                                      : -1);
700   return build (CALL_EXPR, promote_type (type),
701                 build_address_of (soft_newarray_node),
702                 tree_cons (NULL_TREE, 
703                            build_int_2 (atype_value, 0),
704                            build_tree_list (NULL_TREE, length)),
705                 NULL_TREE);
706 }
707
708 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
709    of the dimension. */
710 /* Merge with build_newarray.  FIXME. */
711 tree
712 build_anewarray (class_type, length)
713     tree class_type;
714     tree length;
715 {
716   tree type = build_java_array_type (class_type,
717                                      TREE_CODE (length) == INTEGER_CST
718                                      ? TREE_INT_CST_LOW (length)
719                                      : -1);
720   return build (CALL_EXPR, promote_type (type),
721                 build_address_of (soft_anewarray_node),
722                 tree_cons (NULL_TREE, length,
723                            tree_cons (NULL_TREE, build_class_ref (class_type),
724                                       build_tree_list (NULL_TREE,
725                                                        null_pointer_node))),
726                 NULL_TREE);
727 }
728
729 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
730    class pointer, a number of dimensions and the matching number of
731    dimensions. The argument list is NULL terminated.  */
732
733 void
734 expand_java_multianewarray (class_type, ndim)
735     tree class_type;
736     int  ndim;
737 {
738   int i;
739   tree args = build_tree_list( NULL_TREE, null_pointer_node );
740
741   for( i = 0; i < ndim; i++ )
742     args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
743
744   push_value (build (CALL_EXPR,
745                      promote_type (class_type),
746                      build_address_of (soft_multianewarray_node),
747                      tree_cons (NULL_TREE, build_class_ref (class_type),
748                                 tree_cons (NULL_TREE, 
749                                            build_int_2 (ndim, 0), args )),
750                      NULL_TREE));
751 }
752
753 /*  ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
754     ARRAY is an array type. May expand some bound checking and NULL
755     pointer checking. RHS_TYPE_NODE we are going to store. In the case
756     of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
757     INT. In those cases, we make the convertion.
758
759     if ARRAy is a reference type, the assignment is checked at run-time
760     to make sure that the RHS can be assigned to the array element
761     type. It is not necessary to generate this code if ARRAY is final.  */
762
763 void
764 expand_java_arraystore (rhs_type_node)
765      tree rhs_type_node;
766 {
767   tree rhs_node    = pop_value ((INTEGRAL_TYPE_P (rhs_type_node) 
768                                  && TYPE_PRECISION (rhs_type_node) <= 32) ? 
769                                  int_type_node : rhs_type_node);
770   tree index = pop_value (int_type_node);
771   tree array = pop_value (ptr_type_node);
772
773   rhs_type_node    = build_java_check_indexed_type (array, rhs_type_node);
774
775   flush_quick_stack ();
776
777   index = save_expr (index);
778   array = save_expr (array);
779
780   if (TREE_CODE (rhs_type_node) == POINTER_TYPE
781       && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
782     {
783       tree check = build (CALL_EXPR, void_type_node,
784                           build_address_of (soft_checkarraystore_node),
785                           tree_cons (NULL_TREE, array,
786                                      build_tree_list (NULL_TREE, rhs_node)),
787                           NULL_TREE);
788       TREE_SIDE_EFFECTS (check) = 1;
789       expand_expr_stmt (check);
790     }
791   
792   expand_assignment (build_java_arrayaccess (array,
793                                              rhs_type_node,
794                                              index),
795                      rhs_node, 0, 0);
796 }
797
798 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes 
799    sure that LHS is an array type. May expand some bound checking and NULL
800    pointer checking.  
801    LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
802    BOOLEAN/SHORT, we push a promoted type back to the stack.
803 */
804
805 void
806 expand_java_arrayload (lhs_type_node )
807     tree lhs_type_node;
808 {
809   tree load_node;
810   int convert;
811   tree index_node = pop_value (int_type_node);
812   tree array_node = pop_value (ptr_type_node);
813
814   index_node = save_expr (index_node);
815   array_node = save_expr (array_node);
816   lhs_type_node   = build_java_check_indexed_type (array_node, lhs_type_node);
817
818   load_node = build_java_arrayaccess (array_node,
819                                       lhs_type_node,
820                                       index_node);
821
822   if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
823     load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
824   push_value (load_node);
825 }
826
827 /* Expands .length. Makes sure that we deal with and array and may expand
828    a NULL check on the array object.  */
829
830 void
831 expand_java_array_length ()
832 {
833   tree array  = pop_value (ptr_type_node);
834   tree length = build_java_array_length_access (array);
835
836   push_value (build_java_arraynull_check (array, length, int_type_node));
837 }
838
839 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
840    either soft_monitorenter_node or soft_monitorexit_node.  */
841
842 tree
843 build_java_monitor (call, object)
844     tree call;
845     tree object;
846 {
847   return (build (CALL_EXPR,
848                  void_type_node,
849                  build_address_of (call),
850                  build_tree_list (NULL_TREE, object),
851                  NULL_TREE));
852 }
853
854 /* Emit code for one of the PUSHC instructions. */
855
856 void
857 expand_java_pushc (ival, type)
858      int ival;
859      tree type;
860 {
861   tree value;
862   if (type == ptr_type_node && ival == 0)
863     value = null_pointer_node;
864   else if (type == int_type_node || type == long_type_node)
865     {
866       value = build_int_2 (ival, ival < 0 ? -1 : 0);
867       TREE_TYPE (value) = type;
868     }
869   else if (type == float_type_node || type == double_type_node)
870     {
871       REAL_VALUE_TYPE x;
872 #ifdef REAL_ARITHMETIC
873       REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
874 #else
875       x = ival;
876 #endif
877       value = build_real (type, x);
878     }
879   else
880     fatal ("internal error in expand_java_pushc");
881   push_value (value);
882 }
883
884 void
885 expand_java_return (type)
886      tree type;
887 {
888   if (type == void_type_node)
889     expand_null_return ();
890   else
891     {
892       tree retval = pop_value (type);
893       tree res = DECL_RESULT (current_function_decl);
894       retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
895       TREE_SIDE_EFFECTS (retval) = 1;
896       expand_return (retval);
897     }
898 }
899
900 tree
901 build_address_of (value)
902      tree value;
903 {
904   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
905 }
906
907 void
908 expand_java_NEW (type)
909      tree type;
910 {
911   if (! CLASS_LOADED_P (type))
912     load_class (type, 1);
913   push_value (build (CALL_EXPR, promote_type (type),
914                      build_address_of (alloc_object_node),
915                      tree_cons (NULL_TREE, build_class_ref (type),
916                                 build_tree_list (NULL_TREE,
917                                                  size_in_bytes (type))),
918                      NULL_TREE));
919 }
920
921 void
922 expand_java_INSTANCEOF (type)
923      tree type;
924 {
925   tree value = pop_value (object_ptr_type_node);
926   value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
927                  build_address_of (soft_instanceof_node),
928                  tree_cons (NULL_TREE, value,
929                             build_tree_list (NULL_TREE,
930                                              build_class_ref (type))),
931                  NULL_TREE);
932   push_value (value);
933 }
934
935 void
936 expand_java_CHECKCAST (type)
937      tree type;
938 {
939   tree value = pop_value (ptr_type_node);
940   value = build (CALL_EXPR, promote_type (type),
941                  build_address_of (soft_checkcast_node),
942                  tree_cons (NULL_TREE, build_class_ref (type),
943                             build_tree_list (NULL_TREE, value)),
944                  NULL_TREE);
945   push_value (value);
946 }
947
948 void
949 expand_iinc (unsigned int local_var_index, int ival, int pc)
950 {
951     tree local_var, res;
952     tree constant_value;
953
954     flush_quick_stack ();
955     local_var = find_local_variable (local_var_index, int_type_node, pc);
956     constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
957     res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
958     expand_assignment (local_var, res, 0, 0);
959 }
960
961 tree
962 build_java_binop (op, type, arg1, arg2)
963      enum tree_code op;
964      tree type, arg1, arg2;
965 {
966   tree mask;
967   switch (op)
968     {
969     case URSHIFT_EXPR:
970       {
971         tree u_type = unsigned_type (type);
972         arg1 = convert (u_type, arg1);
973         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
974         return convert (type, arg1);
975       }
976     case LSHIFT_EXPR:
977     case RSHIFT_EXPR:
978       mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
979       arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
980       break;
981
982     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
983     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
984       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
985       {
986         tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
987                                     boolean_type_node, arg1, arg2));
988         tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
989         tree second_compare = fold (build (COND_EXPR, int_type_node,
990                                            ifexp2, integer_zero_node,
991                                            op == COMPARE_L_EXPR
992                                            ? integer_negative_one_node
993                                            : integer_one_node));
994         return fold (build (COND_EXPR, int_type_node, ifexp1,
995                             op == COMPARE_L_EXPR ? integer_one_node
996                             : integer_negative_one_node,
997                             second_compare));
998       }
999     case COMPARE_EXPR:
1000       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1001       {
1002         tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1003         tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1004         tree second_compare = fold ( build (COND_EXPR, int_type_node,
1005                                             ifexp2, integer_one_node,
1006                                             integer_zero_node));
1007         return fold (build (COND_EXPR, int_type_node,
1008                             ifexp1, integer_negative_one_node, second_compare));
1009       }
1010
1011     case TRUNC_MOD_EXPR:
1012       if (TREE_CODE (type) == REAL_TYPE)
1013         {
1014           tree call;
1015           if (type != double_type_node)
1016             {
1017               arg1 = convert (double_type_node, arg1);
1018               arg2 = convert (double_type_node, arg2);
1019             }
1020           call = build (CALL_EXPR, double_type_node,
1021                         build_address_of (soft_fmod_node),
1022                         tree_cons (NULL_TREE, arg1,
1023                                    build_tree_list (NULL_TREE, arg2)),
1024                         NULL_TREE);
1025           if (type != double_type_node)
1026             call = convert (type, call);
1027           return call;
1028         }
1029       break;
1030
1031 #if 0   /* not required */
1032     case PLUS_EXPR:
1033     case MULT_EXPR:
1034     case MINUS_EXPR:
1035     case TRUNC_DIV_EXPR:
1036     case RDIV_EXPR:
1037 /*    case REM_EXPR: */
1038     case BIT_AND_EXPR:
1039     case BIT_IOR_EXPR:
1040     case BIT_XOR_EXPR:
1041       break;
1042     default:
1043       error ("unknown opcode");
1044       return error_mark_node;
1045 #endif
1046
1047     }
1048   return fold (build (op, type, arg1, arg2));
1049 }
1050
1051 void
1052 expand_java_binop (type, op)
1053      tree type;  enum tree_code op;
1054 {
1055   tree larg, rarg;
1056   tree ltype = type;
1057   tree rtype = type;
1058   switch (op)
1059     {
1060     case LSHIFT_EXPR:
1061     case RSHIFT_EXPR:
1062     case URSHIFT_EXPR:
1063       rtype = int_type_node;
1064       rarg = pop_value (rtype);
1065       break;
1066     default:
1067       rarg = pop_value (rtype);
1068     }
1069   larg = pop_value (ltype);
1070   push_value (build_java_binop (op, type, larg, rarg));
1071 }
1072
1073 /* Lookup the field named NAME in *TYPEP or its super classes.
1074    If not found, return NULL_TREE.
1075    (If the *TYPEP is not found, return error_mark_node.)
1076    If found, return the FIELD_DECL, and set *TYPEP to the
1077    class containing the field. */
1078
1079 tree
1080 lookup_field (typep, name)
1081      tree *typep;
1082      tree name;
1083 {
1084   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1085     {
1086       load_class (*typep, 1);
1087       if (TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1088         return error_mark_node;
1089     }
1090   do
1091     {
1092       tree field;
1093       for (field = TYPE_FIELDS (*typep);  field;  field = TREE_CHAIN (field))
1094         {
1095           if (DECL_NAME (field) == name)
1096             return field;
1097         }
1098       *typep = CLASSTYPE_SUPER (*typep);
1099     } while (*typep);
1100   return NULL_TREE;
1101 }
1102
1103 /* Look up the field named NAME in object SELF_VALUE,
1104    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1105    SELF_VALUE is NULL_TREE if looking for a static field. */
1106
1107 tree
1108 build_field_ref (self_value, self_class, name)
1109      tree self_value, self_class, name;
1110 {
1111   tree base_class = self_class;
1112   tree field_decl = lookup_field (&base_class, name);
1113   if (field_decl == NULL_TREE)
1114     {
1115       error ("field `%s' not found", IDENTIFIER_POINTER (name));
1116       return error_mark_node;
1117     }
1118   if (self_value == NULL_TREE)
1119     {
1120       return build_static_field_ref (field_decl);
1121     }
1122   else
1123     {
1124       tree base_handle_type = promote_type (base_class);
1125       if (base_handle_type != TREE_TYPE (self_value))
1126         self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1127 #ifdef JAVA_USE_HANDLES
1128       self_value = unhand_expr (self_value);
1129 #endif
1130       self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1131                            self_value);
1132       return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1133                           self_value, field_decl));
1134     }
1135 }
1136
1137 tree
1138 lookup_label (pc)
1139      int pc;
1140 {
1141   tree name;
1142   char buf[20];
1143   sprintf (buf, "LJpc=%d", pc);
1144   name = get_identifier (buf);
1145   if (IDENTIFIER_LOCAL_VALUE (name))
1146     return IDENTIFIER_LOCAL_VALUE (name);
1147   else
1148     {
1149       /* The type of the address of a label is return_address_type_node. */
1150       tree decl = create_label_decl (name);
1151       LABEL_PC (decl) = pc;
1152       label_rtx (decl);
1153       return pushdecl (decl);
1154     }
1155 }
1156
1157 /* Generate a unique name for the purpose of loops and switches
1158    labels, and try-catch-finally blocks label or temporary variables.  */
1159
1160 tree
1161 generate_name ()
1162 {
1163   static int l_number = 0;
1164   char buff [20];
1165   sprintf (buff, "$L%d", l_number++);
1166   return get_identifier (buff);
1167 }
1168
1169 tree
1170 create_label_decl (name)
1171      tree name;
1172 {
1173   tree decl;
1174   push_obstacks (&permanent_obstack, &permanent_obstack);
1175   decl = build_decl (LABEL_DECL, name, 
1176                      TREE_TYPE (return_address_type_node));
1177   pop_obstacks ();
1178   DECL_CONTEXT (decl) = current_function_decl;
1179   DECL_IGNORED_P (decl) = 1;
1180   return decl;
1181 }
1182
1183 /* This maps a bytecode offset (PC) to various flags. */
1184 char *instruction_bits;
1185
1186 void
1187 note_label (current_pc, target_pc)
1188      int current_pc, target_pc;
1189 {
1190   lookup_label (target_pc);
1191   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1192 }
1193
1194 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1195    where CONDITION is one of one the compare operators. */
1196
1197 void
1198 expand_compare (condition, value1, value2, target_pc)
1199      enum tree_code condition;
1200      tree value1, value2;
1201      int target_pc;
1202 {
1203   tree target = lookup_label (target_pc);
1204   tree cond = fold (build (condition, boolean_type_node, value1, value2));
1205   expand_start_cond (truthvalue_conversion (cond), 0);
1206   expand_goto (target);
1207   expand_end_cond ();
1208 }
1209
1210 /* Emit code for a TEST-type opcode. */
1211
1212 void
1213 expand_test (condition, type, target_pc)
1214      enum tree_code condition;
1215      tree type;
1216      int target_pc;
1217 {
1218   tree value1, value2;
1219   flush_quick_stack ();
1220   value1 = pop_value (type);
1221   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1222   expand_compare (condition, value1, value2, target_pc);
1223 }
1224
1225 /* Emit code for a COND-type opcode. */
1226
1227 void
1228 expand_cond (condition, type, target_pc)
1229      enum tree_code condition;
1230      tree type;
1231      int target_pc;
1232 {
1233   tree value1, value2;
1234   flush_quick_stack ();
1235   /* note: pop values in opposite order */
1236   value2 = pop_value (type);
1237   value1 = pop_value (type);
1238   /* Maybe should check value1 and value2 for type compatibility ??? */
1239   expand_compare (condition, value1, value2, target_pc);
1240 }
1241
1242 void
1243 expand_java_goto (target_pc)
1244      int target_pc;
1245 {
1246   tree target_label = lookup_label (target_pc);
1247   flush_quick_stack ();
1248   expand_goto (target_label);
1249 }
1250
1251 void
1252 expand_java_call (target_pc, return_address)
1253      int target_pc, return_address;
1254 {
1255   tree target_label = lookup_label (target_pc);
1256   tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1257   push_value (value);
1258   flush_quick_stack ();
1259   expand_goto (target_label);
1260 }
1261
1262 void
1263 expand_java_ret (return_address)
1264      tree return_address;
1265 {
1266   warning ("ret instruction not implemented");
1267 #if 0
1268   tree target_label = lookup_label (target_pc);
1269   flush_quick_stack ();
1270   expand_goto (target_label);
1271 #endif
1272 }
1273
1274 /* Recursive helper function to pop argument types during verifiation. */
1275
1276 void
1277 pop_argument_types (arg_types)
1278      tree arg_types;
1279 {
1280   if (arg_types == NULL_TREE)
1281     return;
1282   if (TREE_CODE (arg_types) == TREE_LIST)
1283     {
1284       pop_argument_types (TREE_CHAIN (arg_types));
1285       pop_type (TREE_VALUE (arg_types));
1286       return;
1287     }
1288   abort ();
1289 }
1290
1291 tree
1292 pop_arguments (arg_types)
1293      tree arg_types;
1294 {
1295   if (arg_types == NULL_TREE)
1296     return NULL_TREE;
1297   if (TREE_CODE (arg_types) == TREE_LIST)
1298     {
1299       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1300       tree type = TREE_VALUE (arg_types);
1301       tree arg = pop_value (type);
1302 #ifdef PROMOTE_PROTOTYPES
1303       if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1304           && INTEGRAL_TYPE_P (type))
1305         arg = convert (integer_type_node, arg);
1306 #endif
1307       return tree_cons (NULL_TREE, arg, tail);
1308     }
1309   abort ();
1310 }
1311
1312 /* Build an expression to initialize the class CLAS.
1313    if EXPR is non-NULL, returns an expression to first call the initializer
1314    (if it is needed) and then calls EXPR. */
1315
1316 tree
1317 build_class_init (clas, expr)
1318      tree clas, expr;
1319 {
1320   tree init;
1321   if (inherits_from_p (current_class, clas))
1322     return expr;
1323   init = build (CALL_EXPR, void_type_node,
1324                 build_address_of (soft_initclass_node),
1325                 build_tree_list (NULL_TREE, build_class_ref (clas)),
1326                 NULL_TREE);
1327   TREE_SIDE_EFFECTS (init) = 1;
1328   if (expr != NULL_TREE)
1329     {
1330       expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1331       TREE_SIDE_EFFECTS (expr) = 1;
1332       return expr;
1333     }
1334   return init;
1335 }
1336
1337 static tree methods_ident = NULL_TREE;
1338 static tree ncode_ident = NULL_TREE;
1339 tree dtable_ident = NULL_TREE;
1340
1341 tree
1342 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1343      tree method, method_type, self_type, method_signature, arg_list;
1344 {
1345   tree func;
1346   if (is_compiled_class (self_type))
1347     {
1348       make_decl_rtl (method, NULL, 1);
1349       func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1350     }
1351   else
1352     {
1353       /* We don't know whether the method has been (statically) compiled.
1354          Compile this code to get a reference to the method's code:
1355          
1356          SELF_TYPE->methods[METHOD_INDEX].ncode
1357          
1358          This is guaranteed to work (assuming SELF_TYPE has
1359          been initialized), since if the method is not compiled yet,
1360          its ncode points to a trampoline that forces compilation. */
1361       
1362       int method_index = 0;
1363       tree meth;
1364       tree ref = build_class_ref (self_type);
1365       ref = build1 (INDIRECT_REF, class_type_node, ref);
1366       if (ncode_ident == NULL_TREE)
1367         ncode_ident = get_identifier ("ncode");
1368       if (methods_ident == NULL_TREE)
1369         methods_ident = get_identifier ("methods");
1370       ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1371                    lookup_field (&class_type_node, methods_ident));
1372       for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1373            ; meth = TREE_CHAIN (meth))
1374         {
1375           if (method == meth)
1376             break;
1377           if (meth == NULL_TREE)
1378             fatal ("method '%s' not found in class",
1379                    IDENTIFIER_POINTER (DECL_NAME (method)));
1380           method_index++;
1381         }
1382       method_index *= int_size_in_bytes (method_type_node);
1383       ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1384                          ref, build_int_2 (method_index, 0)));
1385       ref = build1 (INDIRECT_REF, method_type_node, ref);
1386       func = build (COMPONENT_REF, nativecode_ptr_type_node,
1387                     ref,
1388                     lookup_field (&method_type_node, ncode_ident));
1389     }
1390   return func;
1391 }
1392
1393 tree
1394 invoke_build_dtable (is_invoke_interface, arg_list)
1395      int is_invoke_interface;
1396      tree arg_list;
1397 {
1398   tree dtable, objectref;
1399
1400   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1401
1402   /* If we're dealing with interfaces and if the objectref
1403      argument is an array then get the dispatch table of the class
1404      Object rather than the one from the objectref.  */
1405   objectref = (is_invoke_interface 
1406                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1407                object_type_node : TREE_VALUE (arg_list));
1408   
1409   if (dtable_ident == NULL_TREE)
1410     dtable_ident = get_identifier ("dtable");
1411   dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1412   dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1413                   lookup_field (&object_type_node, dtable_ident));
1414
1415   return dtable;
1416 }
1417
1418 tree 
1419 build_invokevirtual (dtable, method)
1420      tree dtable, method;
1421 {
1422   tree func;
1423   tree nativecode_ptr_ptr_type_node
1424     = build_pointer_type (nativecode_ptr_type_node);
1425   int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1426   /* Add one to skip "class" field of dtable, and one to skip unused
1427      vtable entry (for C++ compatibility). */
1428   method_index += 2;
1429   method_index
1430     *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1431   func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1432                       dtable, build_int_2 (method_index, 0)));
1433   func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1434
1435   return func;
1436 }
1437
1438 tree
1439 build_invokeinterface (dtable, method_name, method_signature)
1440      tree dtable, method_name, method_signature;
1441 {
1442   static tree class_ident = NULL_TREE;
1443   tree lookup_arg;
1444
1445   /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
1446      ensure that the selected method exists, is public and not
1447      abstract nor static.  */
1448             
1449   if (class_ident == NULL_TREE)
1450     class_ident = get_identifier ("class");
1451   
1452   dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1453   dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1454                   lookup_field (&dtable_type, class_ident));
1455   lookup_arg = build_tree_list (NULL_TREE, build_utf8_ref (method_signature));
1456   lookup_arg = tree_cons (NULL_TREE, dtable,
1457                           tree_cons (NULL_TREE, build_utf8_ref (method_name),
1458                                      lookup_arg));
1459   return build (CALL_EXPR, ptr_type_node, 
1460                 build_address_of (soft_lookupinterfacemethod_node),
1461                 lookup_arg, NULL_TREE);
1462 }
1463   
1464 /* Expand one of the invoke_* opcodes.
1465    OCPODE is the specific opcode.
1466    METHOD_REF_INDEX is an index into the constant pool.
1467    NARGS is the number of arguments, or -1 if not specified. */
1468
1469 void
1470 expand_invoke (opcode, method_ref_index, nargs)
1471      int opcode;
1472      int method_ref_index;
1473      int nargs;
1474 {
1475   tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1476   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1477   tree self_type = get_class_constant
1478     (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1479   char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1480   tree call, func, method, arg_list, method_type;
1481
1482   if (! CLASS_LOADED_P (self_type))
1483     {
1484       load_class (self_type, 1);
1485       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1486         fatal ("failed to find class '%s'", self_name);
1487     }
1488
1489   if (method_name == init_identifier_node)
1490     method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1491                                       method_signature);
1492   else
1493     method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1494                                  method_name, method_signature);
1495   if (method == NULL_TREE)
1496     {
1497       error ("Class '%s' has no method named '%s' matching signature '%s'",
1498              self_name,
1499              IDENTIFIER_POINTER (method_name),
1500              IDENTIFIER_POINTER (method_signature));
1501     }
1502   /* Invoke static can't invoke static/abstract method */
1503   else if (opcode == OPCODE_invokestatic)
1504     {
1505       if (!METHOD_STATIC (method))
1506         {
1507           error ("invokestatic on non static method");
1508           method = NULL_TREE;
1509         }
1510       else if (METHOD_ABSTRACT (method))
1511         {
1512           error ("invokestatic on abstract method");
1513           method = NULL_TREE;
1514         }
1515     }
1516   else
1517     {
1518       if (METHOD_STATIC (method))
1519         {
1520           error ("invoke[non-static] on static method");
1521           method = NULL_TREE;
1522         }
1523     }
1524
1525   if (method == NULL_TREE)
1526     {
1527       method_type = get_type_from_signature (method_signature);
1528       pop_arguments (TYPE_ARG_TYPES (method_type));
1529       if (opcode != OPCODE_invokestatic) 
1530         pop_type (self_type);
1531       method_type = promote_type (TREE_TYPE (method_type));
1532       push_value (convert (method_type, integer_zero_node));
1533       return;
1534     }
1535
1536   method_type = TREE_TYPE (method);
1537   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1538   flush_quick_stack ();
1539
1540   func = NULL_TREE;
1541   if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1542       || (opcode == OPCODE_invokevirtual
1543           && (METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
1544     func = build_known_method_ref (method, method_type, self_type,
1545                                    method_signature, arg_list);
1546   else
1547     {
1548       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
1549                                          arg_list);
1550       if (opcode == OPCODE_invokevirtual)
1551         func = build_invokevirtual (dtable, method);
1552       else
1553         func = build_invokeinterface (dtable, method_name, method_signature);
1554     }
1555   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1556   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1557   TREE_SIDE_EFFECTS (call) = 1;
1558
1559   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1560     expand_expr_stmt (call);
1561   else
1562     {
1563       push_value (call);
1564       flush_quick_stack ();
1565     }
1566 }
1567
1568
1569 /* Expand an operation to extract from or store into a field.
1570    IS_STATIC is 1 iff the field is static.
1571    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
1572    FIELD_REF_INDEX is an index into the constant pool.  */
1573
1574 void
1575 expand_java_field_op (is_static, is_putting, field_ref_index)
1576      int is_static;
1577      int is_putting;
1578      int field_ref_index;
1579 {
1580   tree self_type = get_class_constant
1581     (current_jcf, COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, field_ref_index));
1582   char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1583   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
1584   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, field_ref_index);
1585   tree field_type = get_type_from_signature (field_signature);
1586   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1587   tree field_ref;
1588   int is_error = 0;
1589   tree field_decl = lookup_field (&self_type, field_name);
1590   if (field_decl == error_mark_node)
1591     {
1592       is_error = 1;
1593     }
1594   else if (field_decl == NULL_TREE)
1595     {
1596       error ("Missing field '%s' in '%s'",
1597              IDENTIFIER_POINTER (field_name), self_name);
1598       is_error = 1;
1599     }
1600   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1601     {
1602       error ("Mismatching signature for field '%s' in '%s'",
1603              IDENTIFIER_POINTER (field_name), self_name);
1604       is_error = 1;
1605     }
1606   field_ref = is_static ? NULL_TREE : pop_value (self_type);
1607   if (is_error)
1608     {
1609       if (! is_putting)
1610         push_value (convert (field_type, integer_zero_node));
1611       flush_quick_stack ();
1612       return;
1613     }
1614
1615   /* Inline references to java.lang.PRIMTYPE.TYPE.
1616      In addition to being a useful (minor) optimization,
1617      this is also needed to avoid circularities in the implementation
1618      of these fields in libjava. */
1619   if (field_name == TYPE_identifier_node && ! is_putting
1620       && field_type == class_ptr_type
1621       && strncmp (self_name, "java.lang.", 10) == 0)
1622     {
1623       tree typ = build_primtype_type_ref (self_name);
1624       if (typ)
1625         {
1626           push_value (typ);
1627           return;
1628         }
1629     }
1630
1631   field_ref = build_field_ref (field_ref, self_type, field_name);
1632   if (is_static)
1633     field_ref = build_class_init (self_type, field_ref);
1634   if (is_putting)
1635     {
1636       flush_quick_stack ();
1637       if (FIELD_FINAL (field_decl))
1638         {
1639           if (DECL_CONTEXT (field_decl) != current_class)
1640             error_with_decl (field_decl,
1641                      "assignment to final field `%s' not in field's class");
1642           else if (FIELD_STATIC (field_decl))
1643             {
1644               if (DECL_NAME (current_function_decl) != clinit_identifier_node)
1645                 error_with_decl (field_decl, 
1646              "assignment to final static field `%s' not in class initializer");
1647             }
1648           else
1649             {
1650               if (! DECL_CONSTRUCTOR_P (current_function_decl))
1651                 error_with_decl (field_decl, 
1652                            "assignment to final field `%s' not in constructor");
1653             }
1654         }
1655       expand_assignment (field_ref, new_value, 0, 0);
1656     }
1657   else
1658     push_value (field_ref);
1659 }
1660
1661 tree
1662 build_primtype_type_ref (self_name)
1663     char *self_name;
1664 {
1665   char *class_name = self_name+10;
1666   tree typ;
1667   if (strncmp(class_name, "Byte", 4) == 0)
1668     typ = byte_type_node;
1669   else if (strncmp(class_name, "Short", 5) == 0)
1670     typ = short_type_node;
1671   else if (strncmp(class_name, "Integer", 7) == 0)
1672     typ = int_type_node;
1673   else if (strncmp(class_name, "Long", 4) == 0)
1674     typ = long_type_node;
1675   else if (strncmp(class_name, "Float", 5) == 0)
1676     typ = float_type_node;
1677   else if (strncmp(class_name, "Boolean", 7) == 0)
1678     typ = boolean_type_node;
1679   else if (strncmp(class_name, "Char", 4) == 0)
1680     typ = char_type_node;
1681   else if (strncmp(class_name, "Void", 4) == 0)
1682     typ = void_type_node;
1683   else
1684     typ = NULL_TREE;
1685   if (typ != NULL_TREE)
1686     return build_class_ref (typ);
1687   else
1688     return NULL_TREE;
1689 }
1690
1691 void
1692 load_type_state (label)
1693      tree label;
1694 {
1695   int i;
1696   tree vec = LABEL_TYPE_STATE (label);
1697   int cur_length = TREE_VEC_LENGTH (vec);
1698   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1699   for (i = 0; i < cur_length; i++)
1700     type_map [i] = TREE_VEC_ELT (vec, i);
1701 }
1702
1703 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1704    dependant things, but they rely on gcc routines. This function is
1705    placed here because it uses things defined locally in parse.y. */
1706
1707 static tree
1708 case_identity (t, v)
1709      tree t __attribute__ ((__unused__));
1710      tree v;
1711 {
1712   return v;
1713 }
1714
1715 struct rtx_def *
1716 java_lang_expand_expr (exp, target, tmode, modifier)
1717      register tree exp;
1718      rtx target;
1719      enum machine_mode tmode;
1720      enum expand_modifier modifier;
1721 {
1722   register rtx op0;
1723   tree type = TREE_TYPE (exp);
1724   register enum machine_mode mode = TYPE_MODE (type);
1725   int unsignedp = TREE_UNSIGNED (type);
1726   tree node, current;
1727   int has_finally_p;
1728
1729   switch (TREE_CODE (exp))
1730     {
1731     case BLOCK:
1732       if (BLOCK_EXPR_BODY (exp))
1733         {
1734           tree local;
1735           tree body = BLOCK_EXPR_BODY (exp);
1736           struct rtx_def *to_return;
1737           pushlevel (2);        /* 2 and above */
1738           expand_start_bindings (0);
1739           local = BLOCK_EXPR_DECLS (exp);
1740           while (local)
1741             {
1742               tree next = TREE_CHAIN (local);
1743               layout_decl (local, 0);
1744               expand_decl (pushdecl (local));
1745               local = next;
1746             }
1747           /* Avoid deep recursion for long block.  */
1748           while (TREE_CODE (body) == COMPOUND_EXPR)
1749             {
1750               expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1751               body = TREE_OPERAND (body, 1);
1752             }
1753           to_return = expand_expr (body, target, tmode, modifier);
1754           poplevel (1, 1, 0);
1755           expand_end_bindings (getdecls (), 1, 0);
1756           return to_return;
1757         }
1758       break;
1759
1760     case CASE_EXPR:
1761       {
1762         tree duplicate;
1763         if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1764                       build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), &duplicate) == 2)
1765           {
1766             EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1767             parse_error_context
1768               (wfl_operator, "Duplicate case label: `%s'",
1769                print_int_node (TREE_OPERAND (exp, 0)));
1770           }
1771         return const0_rtx;
1772       }
1773
1774     case DEFAULT_EXPR:
1775       pushcase (NULL_TREE, 0, build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1776       return const0_rtx;
1777
1778     case SWITCH_EXPR:
1779       expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
1780       expand_expr_stmt (TREE_OPERAND (exp, 1));
1781       expand_end_case (TREE_OPERAND (exp, 0));
1782       return const0_rtx;
1783
1784     case TRY_EXPR:
1785       /* We expand a try[-catch][-finally] block */
1786
1787       /* Expand the try block */
1788       expand_eh_region_start ();
1789       expand_expr_stmt (TREE_OPERAND (exp, 0));
1790       expand_start_all_catch ();
1791       has_finally_p = (TREE_OPERAND (exp, 2) ? 1 : 0);
1792
1793       /* Expand all catch clauses (EH handlers) */
1794       for (current = TREE_OPERAND (exp, 1); current; 
1795            current = TREE_CHAIN (current))
1796         {
1797           extern rtx return_label;
1798           tree type;
1799           /* If we have a finally, the last exception handler is the
1800              one that is supposed to catch everything. */
1801           if (has_finally_p && !TREE_CHAIN (current))
1802             type = NULL_TREE;
1803           else
1804             {
1805               tree catch = java_get_catch_block (current, has_finally_p);
1806               tree decl = BLOCK_EXPR_DECLS (catch);
1807               type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
1808             }
1809           start_catch_handler (prepare_eh_table_type (type));
1810           expand_expr_stmt (TREE_OPERAND (current, 0));
1811
1812           /* Need to expand a goto to the end of the function here,
1813              but not for the catch everything handler. */
1814           if (type)
1815             {
1816               if (return_label)
1817                 emit_jump (return_label);
1818               else
1819                 fatal ("No return_label for this function - "
1820                        "java_lang_expand_expr");
1821             }
1822           end_catch_handler ();
1823         }
1824
1825       /* Expand the finally block, if any */
1826       if (has_finally_p)
1827         {
1828           tree finally = TREE_OPERAND (exp, 2);
1829           if (FINALLY_EXPR_LABEL (finally))
1830             emit_label (label_rtx (FINALLY_EXPR_LABEL (finally)));
1831           expand_expr_stmt (FINALLY_EXPR_BLOCK (finally));
1832         }
1833       expand_end_all_catch ();
1834       break;
1835
1836     default:
1837       fatal ("Can't expand '%s' tree - java_lang_expand_expr",
1838              tree_code_name [TREE_CODE (exp)]);
1839     }
1840 }
1841
1842 void
1843 expand_byte_code (jcf, method)
1844      JCF *jcf;
1845      tree method;
1846 {
1847   int PC;
1848   int i;
1849   int saw_index;
1850   unsigned char *linenumber_pointer;
1851   struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
1852   struct eh_range *eh_ranges;
1853
1854 #undef RET /* Defined by config/i386/i386.h */
1855 #undef AND /* Causes problems with opcodes for iand and land. */
1856 #undef PTR
1857 #define BCODE byte_ops
1858 #define BYTE_type_node byte_type_node
1859 #define SHORT_type_node short_type_node
1860 #define INT_type_node int_type_node
1861 #define LONG_type_node long_type_node
1862 #define CHAR_type_node char_type_node
1863 #define PTR_type_node ptr_type_node
1864 #define FLOAT_type_node float_type_node
1865 #define DOUBLE_type_node double_type_node
1866 #define VOID_type_node void_type_node
1867   jint INT_temp;
1868   unsigned char* byte_ops;
1869   long length = DECL_CODE_LENGTH (method);
1870
1871   stack_pointer = 0;
1872   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
1873   byte_ops = jcf->read_ptr;
1874
1875 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1876 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1877 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1878 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1879
1880 #define CHECK_PC_IN_RANGE(PC) 1 /* Already handled by verifier. */
1881
1882   instruction_bits = oballoc (length + 1);
1883   bzero (instruction_bits, length + 1);
1884
1885   /* We make an initial pass of the line number table, to note
1886      which instructions have associated line number entries. */
1887   linenumber_pointer = linenumber_table;
1888   for (i = 0; i < linenumber_count; i++)
1889     {
1890       int pc = GET_u2 (linenumber_pointer);
1891       linenumber_pointer += 4;
1892       if (pc >= length)
1893         warning ("invalid PC in line number table");
1894       else
1895         {
1896           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
1897             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
1898           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
1899         }
1900     }  
1901
1902   /* Do a preliminary pass.
1903    * This figures out which PC can be the targets of jumps. */
1904   for (PC = 0; PC < length;)
1905     {
1906       int oldpc = PC; /* PC at instruction start. */
1907       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
1908       switch (byte_ops[PC++])
1909         {
1910 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
1911         case OPCODE: \
1912           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
1913           break;
1914
1915 #define NOTE_LABEL(PC) note_label(oldpc, PC)
1916
1917 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1918 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1919 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1920 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1921 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1922 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1923 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1924 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1925
1926 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
1927   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
1928 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
1929   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
1930 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
1931 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
1932 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
1933 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
1934
1935 /* two forms of wide instructions */
1936 #define PRE_SPECIAL_WIDE(IGNORE) \
1937   { \
1938     int modified_opcode = IMMEDIATE_u1; \
1939     if (modified_opcode == OPCODE_iinc) \
1940       { \
1941         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
1942         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
1943       } \
1944     else \
1945       { \
1946         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
1947       } \
1948   }
1949
1950 /* nothing */ /* XXX JH */
1951
1952 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
1953
1954 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1955
1956 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1957 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
1958           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
1959 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
1960 #define PRE_ARRAY_STORE(TYPE) /* nothing */
1961 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
1962 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
1963 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
1964 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
1965 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
1966
1967 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
1968 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
1969 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
1970   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
1971   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
1972 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
1973   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
1974   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
1975
1976 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
1977
1978 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
1979   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
1980
1981 #define PRE_LOOKUP_SWITCH                                               \
1982   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
1983     NOTE_LABEL (default_offset+oldpc);                                  \
1984     if (npairs >= 0)                                                    \
1985       while (--npairs >= 0) {                                           \
1986        jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4;           \
1987        NOTE_LABEL (offset+oldpc); }                                     \
1988   }
1989
1990 #define PRE_TABLE_SWITCH                                \
1991   { jint default_offset = IMMEDIATE_s4;                 \
1992     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
1993     NOTE_LABEL (default_offset+oldpc);                  \
1994     if (low <= high)                                    \
1995      while (low++ <= high) {                            \
1996        jint offset = IMMEDIATE_s4;                      \
1997        NOTE_LABEL (offset+oldpc); }                     \
1998   }
1999
2000 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2001 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2002 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2003   (void)(IMMEDIATE_u2); \
2004   PC += 2 * IS_INTERFACE /* for invokeinterface */;
2005
2006 #include "javaop.def"
2007 #undef JAVAOP
2008         }
2009     } /* for */
2010
2011   if (! verify_jvm_instructions (jcf, byte_ops, length))
2012     return;
2013
2014   /* Translate bytecodes to rtl instructions. */
2015   linenumber_pointer = linenumber_table;
2016   for (PC = 0; PC < length;)
2017     {
2018       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2019         {
2020           tree label = lookup_label (PC);
2021           flush_quick_stack ();
2022           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2023             expand_label (label);
2024           if (LABEL_VERIFIED (label) || PC == 0)
2025             load_type_state (label);
2026         }
2027
2028       if (! (instruction_bits [PC] & BCODE_VERIFIED))
2029         {
2030           /* never executed - skip */
2031           warning ("Some bytecode operations (starting at pc %d) can never be executed", PC);
2032           while (PC < length
2033                  && ! (instruction_bits [PC] & BCODE_VERIFIED))
2034             PC++;
2035           continue;
2036         }
2037
2038
2039       /* Handle possible line number entry for this PC.
2040
2041          This code handles out-of-order and multiple linenumbers per PC,
2042          but is optimized for the case of line numbers increasing
2043          monotonically with PC. */
2044       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2045         {
2046           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2047               || GET_u2 (linenumber_pointer) != PC)
2048             linenumber_pointer = linenumber_table;
2049           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2050             {
2051               int pc = GET_u2 (linenumber_pointer);
2052               linenumber_pointer += 4;
2053               if (pc == PC)
2054                 {
2055                   lineno = GET_u2 (linenumber_pointer - 2);
2056                   emit_line_note (input_filename, lineno);
2057                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2058                     break;
2059                 }
2060             }
2061         }
2062       maybe_start_try (PC);
2063       maybe_pushlevels (PC);
2064
2065       PC = process_jvm_instruction (PC, byte_ops, length);
2066
2067       maybe_poplevels (PC);
2068       maybe_end_try (PC);
2069     } /* for */
2070 }
2071
2072 void
2073 java_push_constant_from_pool (jcf, index)
2074      JCF *jcf;
2075      int index;
2076 {
2077   tree c;
2078   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2079     {
2080       tree name;
2081       push_obstacks (&permanent_obstack, &permanent_obstack);
2082       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2083       index = alloc_name_constant (CONSTANT_String, name);
2084       c = build_ref_from_constant_pool (index);
2085       TREE_TYPE (c) = promote_type (string_type_node);
2086       pop_obstacks ();
2087     }
2088   else
2089     c = get_constant (jcf, index);
2090   push_value (c);
2091
2092
2093 int
2094 process_jvm_instruction (PC, byte_ops, length)
2095      int PC;
2096      unsigned char* byte_ops;
2097      long length;
2098
2099   char *opname; /* Temporary ??? */
2100   int oldpc = PC; /* PC at instruction start. */
2101
2102   /* If the instruction is at the beginning of a exception handler,
2103      replace the top of the stack with the thrown object reference */
2104   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2105     {
2106       pop_value (ptr_type_node);
2107       push_value (soft_exceptioninfo_call_node);
2108     }
2109
2110   switch (byte_ops[PC++])
2111     {
2112 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2113     case OPCODE: \
2114       opname = #OPNAME; \
2115       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2116       break;
2117
2118 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
2119   {                                                                     \
2120     int saw_index = 0;                                                  \
2121     int index     = OPERAND_VALUE;                                      \
2122     build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2123   }
2124
2125 #define JSR(OPERAND_TYPE, OPERAND_VALUE)                \
2126   {                                                     \
2127     tree where = lookup_label (oldpc+OPERAND_VALUE);    \
2128     tree ret   = lookup_label (PC);                     \
2129     build_java_jsr (where, ret);                        \
2130   }
2131
2132 /* Push a constant onto the stack. */
2133 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2134   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
2135     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2136     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2137
2138 /* internal macro added for use by the WIDE case */
2139 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2140   push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2141
2142 /* Push local variable onto the opcode stack. */
2143 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2144   { \
2145     /* have to do this since OPERAND_VALUE may have side-effects */ \
2146     int opvalue = OPERAND_VALUE; \
2147     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2148   }
2149
2150 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2151   expand_java_return (OPERAND_TYPE##_type_node)
2152
2153 #define REM_EXPR TRUNC_MOD_EXPR
2154 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2155   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2156
2157 #define FIELD(IS_STATIC, IS_PUT) \
2158   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2159
2160 #define TEST(OPERAND_TYPE, CONDITION) \
2161   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2162
2163 #define COND(OPERAND_TYPE, CONDITION) \
2164   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2165
2166 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2167   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2168
2169 #define BRANCH_GOTO(OPERAND_VALUE) \
2170   expand_java_goto (oldpc + OPERAND_VALUE)
2171
2172 #define BRANCH_CALL(OPERAND_VALUE) \
2173   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2174
2175 #if 0
2176 #define BRANCH_RETURN(OPERAND_VALUE) \
2177   { \
2178     tree type = OPERAND_TYPE##_type_node; \
2179     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2180     expand_java_ret (value); \
2181   }
2182 #endif
2183
2184 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2185           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2186           fprintf (stderr, "(not implemented)\n")
2187 #define NOT_IMPL1(OPERAND_VALUE) \
2188           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2189           fprintf (stderr, "(not implemented)\n")
2190
2191 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2192
2193 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2194
2195 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2196
2197 #define STACK_SWAP(COUNT) java_stack_swap()
2198
2199 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2200 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2201 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2202
2203 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2204   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2205
2206 #define LOOKUP_SWITCH \
2207   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
2208     tree selector = pop_value (INT_type_node); \
2209     tree duplicate, label; \
2210     tree type = TREE_TYPE (selector); \
2211     flush_quick_stack (); \
2212     expand_start_case (0, selector, type, "switch statement");\
2213     push_momentary (); \
2214     while (--npairs >= 0) \
2215       { \
2216         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2217         tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2218         TREE_TYPE (value) = type; \
2219         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2220         pushcase (value, convert, label, &duplicate); \
2221         expand_java_goto (oldpc + offset); \
2222       } \
2223     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2224     pushcase (NULL_TREE, 0, label, &duplicate); \
2225     expand_java_goto (oldpc + default_offset); \
2226     pop_momentary (); \
2227     expand_end_case (selector); \
2228   }
2229
2230 #define TABLE_SWITCH \
2231   { jint default_offset = IMMEDIATE_s4; \
2232     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2233     tree selector = pop_value (INT_type_node); \
2234     tree duplicate, label; \
2235     tree type = TREE_TYPE (selector); \
2236     flush_quick_stack (); \
2237     expand_start_case (0, selector, type, "switch statement");\
2238     push_momentary (); \
2239     for (; low <= high; low++) \
2240       { \
2241         jint offset = IMMEDIATE_s4; \
2242         tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2243         TREE_TYPE (value) = type; \
2244         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2245         pushcase (value, convert, label, &duplicate); \
2246         expand_java_goto (oldpc + offset); \
2247       } \
2248     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2249     pushcase (NULL_TREE, 0, label, &duplicate); \
2250     expand_java_goto (oldpc + default_offset); \
2251     pop_momentary (); \
2252     expand_end_case (selector); \
2253   }
2254
2255 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2256   { int opcode = byte_ops[PC-1]; \
2257     int method_ref_index = IMMEDIATE_u2; \
2258     int nargs; \
2259     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
2260     else nargs = -1; \
2261     expand_invoke (opcode, method_ref_index, nargs); \
2262   }
2263
2264 /* Handle new, checkcast, instanceof */
2265 #define OBJECT(TYPE, OP) \
2266   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2267
2268 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2269
2270 #define ARRAY_LOAD(OPERAND_TYPE)                        \
2271   {                                                     \
2272     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
2273   }
2274
2275 #define ARRAY_STORE(OPERAND_TYPE)                       \
2276   {                                                     \
2277     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2278   }
2279
2280 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2281 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2282 #define ARRAY_NEW_PTR()                                                 \
2283     push_value (build_anewarray (get_class_constant (current_jcf,       \
2284                                                      IMMEDIATE_u2),     \
2285                                  pop_value (int_type_node)));
2286 #define ARRAY_NEW_NUM()                         \
2287   {                                             \
2288     int atype = IMMEDIATE_u1;                   \
2289     push_value (build_newarray (atype, pop_value (int_type_node)));\
2290   }
2291 #define ARRAY_NEW_MULTI()                                       \
2292   {                                                             \
2293     tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
2294     int  ndims = IMMEDIATE_u1;                                  \
2295     expand_java_multianewarray( class, ndims );                 \
2296   }
2297
2298 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2299   push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2300                             pop_value (OPERAND_TYPE##_type_node))));
2301
2302 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
2303   {                                                                      \
2304     push_value (build1 (NOP_EXPR, int_type_node,                         \
2305                         (convert (TO_TYPE##_type_node,                   \
2306                                   pop_value (FROM_TYPE##_type_node))))); \
2307   }
2308
2309 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
2310   {                                                             \
2311     push_value (convert (TO_TYPE##_type_node,                   \
2312                          pop_value (FROM_TYPE##_type_node)));   \
2313   }
2314
2315 /* internal macro added for use by the WIDE case 
2316    Added TREE_TYPE (decl) assignment, apbianco  */
2317 #define STORE_INTERNAL(OPTYPE, OPVALUE)                 \
2318   {                                                     \
2319     tree decl, value;                                   \
2320     int var = OPVALUE;                                  \
2321     tree type = OPTYPE;                                 \
2322     value = pop_value (type);                           \
2323     type = TREE_TYPE (value);                           \
2324     decl = find_local_variable (var, type, oldpc);      \
2325     set_local_type (var, type );                        \
2326     expand_assignment (decl, value, 0, 0);              \
2327   }
2328
2329 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2330   { \
2331     /* have to do this since OPERAND_VALUE may have side-effects */ \
2332     int opvalue = OPERAND_VALUE; \
2333     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2334   }
2335
2336 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2337   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2338
2339 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2340 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
2341
2342 #define MONITOR_OPERATION(call)                 \
2343   {                                             \
2344     tree o = pop_value (ptr_type_node);         \
2345     tree c;                                     \
2346     flush_quick_stack ();                       \
2347     c = build_java_monitor (call, o);           \
2348     TREE_SIDE_EFFECTS (c) = 1;                  \
2349     expand_expr_stmt (c);                       \
2350   }
2351
2352 #define SPECIAL_IINC(IGNORED) \
2353   { \
2354     unsigned int local_var_index = IMMEDIATE_u1; \
2355     int ival = IMMEDIATE_s1; \
2356     expand_iinc(local_var_index, ival, oldpc); \
2357   }
2358
2359 #define SPECIAL_WIDE(IGNORED) \
2360   { \
2361     int modified_opcode = IMMEDIATE_u1; \
2362     unsigned int local_var_index = IMMEDIATE_u2; \
2363     switch (modified_opcode) \
2364       { \
2365       case OPCODE_iinc: \
2366         { \
2367           int ival = IMMEDIATE_s2; \
2368           expand_iinc (local_var_index, ival, oldpc); \
2369           break; \
2370         } \
2371       case OPCODE_iload: \
2372       case OPCODE_lload: \
2373       case OPCODE_fload: \
2374       case OPCODE_dload: \
2375       case OPCODE_aload: \
2376         { \
2377           /* duplicate code from LOAD macro */ \
2378           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2379           break; \
2380         } \
2381       case OPCODE_istore: \
2382       case OPCODE_lstore: \
2383       case OPCODE_fstore: \
2384       case OPCODE_dstore: \
2385       case OPCODE_astore: \
2386         { \
2387           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2388           break; \
2389         } \
2390       default: \
2391         error ("unrecogized wide sub-instruction"); \
2392       } \
2393   }
2394
2395 #define SPECIAL_THROW(IGNORED) \
2396   build_java_athrow (pop_value (throwable_type_node))
2397
2398 #define SPECIAL_BREAK NOT_IMPL1
2399 #define IMPL          NOT_IMPL
2400
2401 #include "javaop.def"
2402 #undef JAVAOP
2403    default:
2404     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2405   }
2406   return PC;
2407 }