OSDN Git Service

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