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