OSDN Git Service

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