OSDN Git Service

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