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