OSDN Git Service

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