OSDN Git Service

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