OSDN Git Service

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