OSDN Git Service

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