OSDN Git Service

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