OSDN Git Service

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