OSDN Git Service

* defaults.h: Provide default definitions for: CHAR_TYPE_SIZE,
[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 static void
988 expand_java_return (type)
989      tree type;
990 {
991   if (type == void_type_node)
992     expand_null_return ();
993   else
994     {
995       tree retval = pop_value (type);
996       tree res = DECL_RESULT (current_function_decl);
997       retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
998
999       /* Handle the situation where the native integer type is smaller
1000          than the JVM integer. It can happen for many cross compilers.
1001          The whole if expression just goes away if INT_TYPE_SIZE < 32
1002          is false. */
1003       if (INT_TYPE_SIZE < 32
1004           && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1005               < GET_MODE_SIZE (TYPE_MODE (type))))
1006         retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1007       
1008       TREE_SIDE_EFFECTS (retval) = 1;
1009       expand_return (retval);
1010     }
1011 }
1012
1013 tree
1014 build_address_of (value)
1015      tree value;
1016 {
1017   return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1018 }
1019
1020 static void
1021 expand_java_NEW (type)
1022      tree type;
1023 {
1024   if (! CLASS_LOADED_P (type))
1025     load_class (type, 1);
1026   safe_layout_class (type);
1027   push_value (build (CALL_EXPR, promote_type (type),
1028                      build_address_of (alloc_object_node),
1029                      tree_cons (NULL_TREE, build_class_ref (type),
1030                                 build_tree_list (NULL_TREE,
1031                                                  size_in_bytes (type))),
1032                      NULL_TREE));
1033 }
1034
1035 /* This returns an expression which will extract the class of an
1036    object.  */
1037
1038 tree
1039 build_get_class (value)
1040      tree value;
1041 {
1042   tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1043   tree vtable_field = lookup_field (&object_type_node,
1044                                     get_identifier ("vtable"));
1045   return build (COMPONENT_REF, class_ptr_type,
1046                 build1 (INDIRECT_REF, dtable_type,
1047                         build (COMPONENT_REF, dtable_ptr_type,
1048                                build1 (INDIRECT_REF, object_type_node, value),
1049                                vtable_field)),
1050                 class_field);
1051 }
1052
1053 /* This builds the tree representation of the `instanceof' operator.
1054    It tries various tricks to optimize this in cases where types are
1055    known.  */
1056
1057 tree
1058 build_instanceof (value, type)
1059      tree value, type;
1060 {
1061   tree expr;
1062   tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1063   tree valtype = TREE_TYPE (TREE_TYPE (value));
1064   tree valclass = TYPE_NAME (valtype);
1065   tree klass;
1066
1067   /* When compiling from bytecode, we need to ensure that TYPE has
1068      been loaded.  */
1069   if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1070     {
1071       load_class (type, 1);
1072       safe_layout_class (type);
1073       if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1074         return error_mark_node;
1075     }
1076   klass = TYPE_NAME (type);
1077
1078   if (type == object_type_node || inherits_from_p (valtype, type))
1079     {
1080       /* Anything except `null' is an instance of Object.  Likewise,
1081          if the object is known to be an instance of the class, then
1082          we only need to check for `null'.  */
1083       expr = build (COND_EXPR, itype,
1084                     value,
1085                     boolean_true_node, boolean_false_node);
1086     }
1087   else if (DECL_P (klass) && DECL_P (valclass)
1088            && ! CLASS_INTERFACE (valclass)
1089            && ! CLASS_INTERFACE (klass)
1090            && ! inherits_from_p (type, valtype)
1091            && (CLASS_FINAL (klass)
1092                || ! inherits_from_p (valtype, type)))
1093     {
1094       /* The classes are from different branches of the derivation
1095          tree, so we immediately know the answer.  */
1096       expr = boolean_false_node;
1097     }
1098   else if (DECL_P (klass) && CLASS_FINAL (klass))
1099     {
1100       tree save = save_expr (value);
1101       expr = build (COND_EXPR, itype,
1102                     save,
1103                     build (EQ_EXPR, itype,
1104                            build_get_class (save),
1105                            build_class_ref (type)),
1106                     boolean_false_node);
1107     }
1108   else
1109     {
1110       expr = build (CALL_EXPR, itype,
1111                     build_address_of (soft_instanceof_node),
1112                     tree_cons (NULL_TREE, value,
1113                                build_tree_list (NULL_TREE,
1114                                                 build_class_ref (type))),
1115                     NULL_TREE);
1116     }
1117   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1118   return expr;
1119 }
1120
1121 static void
1122 expand_java_INSTANCEOF (type)
1123      tree type;
1124 {
1125   tree value = pop_value (object_ptr_type_node);
1126   value = build_instanceof (value, type);
1127   push_value (value);
1128 }
1129
1130 static void
1131 expand_java_CHECKCAST (type)
1132      tree type;
1133 {
1134   tree value = pop_value (ptr_type_node);
1135   value = build (CALL_EXPR, promote_type (type),
1136                  build_address_of (soft_checkcast_node),
1137                  tree_cons (NULL_TREE, build_class_ref (type),
1138                             build_tree_list (NULL_TREE, value)),
1139                  NULL_TREE);
1140   push_value (value);
1141 }
1142
1143 static void
1144 expand_iinc (local_var_index, ival, pc)
1145      unsigned int local_var_index;
1146      int ival;
1147      int pc;
1148 {
1149     tree local_var, res;
1150     tree constant_value;
1151
1152     flush_quick_stack ();
1153     local_var = find_local_variable (local_var_index, int_type_node, pc);
1154     constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1155     res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1156     expand_assignment (local_var, res, 0, 0);
1157 }
1158
1159       
1160 tree
1161 build_java_soft_divmod (op, type, op1, op2)
1162     enum tree_code op;
1163     tree type, op1, op2;
1164 {
1165   tree call = NULL;
1166   tree arg1 = convert (type, op1);
1167   tree arg2 = convert (type, op2);
1168
1169   if (type == int_type_node)
1170     {     
1171       switch (op)
1172         {
1173         case TRUNC_DIV_EXPR:
1174           call = soft_idiv_node;
1175           break;
1176         case TRUNC_MOD_EXPR:
1177           call = soft_irem_node;
1178           break;
1179         default:
1180           break;
1181         }
1182     }
1183   else if (type == long_type_node)
1184     {     
1185       switch (op)
1186         {
1187         case TRUNC_DIV_EXPR:
1188           call = soft_ldiv_node;
1189           break;
1190         case TRUNC_MOD_EXPR:
1191           call = soft_lrem_node;
1192           break;
1193         default:
1194           break;
1195         }
1196     }
1197
1198   if (! call)
1199     fatal ("Internal compiler error in build_java_soft_divmod");
1200                   
1201   call = build (CALL_EXPR, type,
1202                 build_address_of (call),
1203                 tree_cons (NULL_TREE, arg1,
1204                            build_tree_list (NULL_TREE, arg2)),
1205                 NULL_TREE);
1206           
1207   return call;
1208 }
1209
1210 tree
1211 build_java_binop (op, type, arg1, arg2)
1212      enum tree_code op;
1213      tree type, arg1, arg2;
1214 {
1215   tree mask;
1216   switch (op)
1217     {
1218     case URSHIFT_EXPR:
1219       {
1220         tree u_type = unsigned_type (type);
1221         arg1 = convert (u_type, arg1);
1222         arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1223         return convert (type, arg1);
1224       }
1225     case LSHIFT_EXPR:
1226     case RSHIFT_EXPR:
1227       mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1228       arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1229       break;
1230
1231     case COMPARE_L_EXPR:  /* arg1 > arg2 ?  1 : arg1 == arg2 ? 0 : -1 */
1232     case COMPARE_G_EXPR:  /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 :  1 */
1233       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1234       {
1235         tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1236                                     boolean_type_node, arg1, arg2));
1237         tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1238         tree second_compare = fold (build (COND_EXPR, int_type_node,
1239                                            ifexp2, integer_zero_node,
1240                                            op == COMPARE_L_EXPR
1241                                            ? integer_negative_one_node
1242                                            : integer_one_node));
1243         return fold (build (COND_EXPR, int_type_node, ifexp1,
1244                             op == COMPARE_L_EXPR ? integer_one_node
1245                             : integer_negative_one_node,
1246                             second_compare));
1247       }
1248     case COMPARE_EXPR:
1249       arg1 = save_expr (arg1);  arg2 = save_expr (arg2);
1250       {
1251         tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1252         tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1253         tree second_compare = fold ( build (COND_EXPR, int_type_node,
1254                                             ifexp2, integer_one_node,
1255                                             integer_zero_node));
1256         return fold (build (COND_EXPR, int_type_node,
1257                             ifexp1, integer_negative_one_node, second_compare));
1258       }      
1259     case TRUNC_DIV_EXPR:
1260     case TRUNC_MOD_EXPR:
1261       if (TREE_CODE (type) == REAL_TYPE
1262           && op == TRUNC_MOD_EXPR)
1263         {
1264           tree call;
1265           if (type != double_type_node)
1266             {
1267               arg1 = convert (double_type_node, arg1);
1268               arg2 = convert (double_type_node, arg2);
1269             }
1270           call = build (CALL_EXPR, double_type_node,
1271                         build_address_of (soft_fmod_node),
1272                         tree_cons (NULL_TREE, arg1,
1273                                    build_tree_list (NULL_TREE, arg2)),
1274                         NULL_TREE);
1275           if (type != double_type_node)
1276             call = convert (type, call);
1277           return call;
1278         }
1279       
1280       if (TREE_CODE (type) == INTEGER_TYPE
1281           && flag_use_divide_subroutine
1282           && ! flag_syntax_only)
1283         return build_java_soft_divmod (op, type, arg1, arg2);
1284       
1285       break;
1286     default:  ;
1287     }
1288   return fold (build (op, type, arg1, arg2));
1289 }
1290
1291 static void
1292 expand_java_binop (type, op)
1293      tree type;  enum tree_code op;
1294 {
1295   tree larg, rarg;
1296   tree ltype = type;
1297   tree rtype = type;
1298   switch (op)
1299     {
1300     case LSHIFT_EXPR:
1301     case RSHIFT_EXPR:
1302     case URSHIFT_EXPR:
1303       rtype = int_type_node;
1304       rarg = pop_value (rtype);
1305       break;
1306     default:
1307       rarg = pop_value (rtype);
1308     }
1309   larg = pop_value (ltype);
1310   push_value (build_java_binop (op, type, larg, rarg));
1311 }
1312
1313 /* Lookup the field named NAME in *TYPEP or its super classes.
1314    If not found, return NULL_TREE.
1315    (If the *TYPEP is not found, or if the field reference is
1316    ambiguous, return error_mark_node.)
1317    If found, return the FIELD_DECL, and set *TYPEP to the
1318    class containing the field. */
1319
1320 tree
1321 lookup_field (typep, name)
1322      tree *typep;
1323      tree name;
1324 {
1325   if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1326     {
1327       load_class (*typep, 1);
1328       safe_layout_class (*typep);
1329       if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1330         return error_mark_node;
1331     }
1332   do
1333     {
1334       tree field, basetype_vec;
1335       tree save_field;
1336       int n, i;
1337
1338       for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1339         if (DECL_NAME (field) == name)
1340           return field;
1341
1342       /* If *typep is an innerclass, lookup the field in its enclosing
1343          contexts */
1344       if (INNER_CLASS_TYPE_P (*typep))
1345         {
1346           tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1347
1348           if ((field = lookup_field (&outer_type, name)))
1349             return field;
1350         }
1351
1352       /* Process implemented interfaces. */
1353       basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1354       n = TREE_VEC_LENGTH (basetype_vec);
1355       save_field = NULL_TREE;
1356       for (i = 0; i < n; i++)
1357         {
1358           tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1359           if ((field = lookup_field (&t, name)))
1360             {
1361               if (save_field == field)
1362                 continue;
1363               if (save_field == NULL_TREE)
1364                 save_field = field;
1365               else
1366                 {
1367                   tree i1 = DECL_CONTEXT (save_field);
1368                   tree i2 = DECL_CONTEXT (field);
1369                   error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1370                          IDENTIFIER_POINTER (name),
1371                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1372                          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1373                   return error_mark_node;
1374                 }
1375             }
1376         }
1377
1378       if (save_field != NULL_TREE)
1379         return save_field;
1380
1381       *typep = CLASSTYPE_SUPER (*typep);
1382     } while (*typep);
1383   return NULL_TREE;
1384 }
1385
1386 /* Look up the field named NAME in object SELF_VALUE,
1387    which has class SELF_CLASS (a non-handle RECORD_TYPE).
1388    SELF_VALUE is NULL_TREE if looking for a static field. */
1389
1390 tree
1391 build_field_ref (self_value, self_class, name)
1392      tree self_value, self_class, name;
1393 {
1394   tree base_class = self_class;
1395   tree field_decl = lookup_field (&base_class, name);
1396   if (field_decl == NULL_TREE)
1397     {
1398       error ("field `%s' not found", IDENTIFIER_POINTER (name));
1399       return error_mark_node;
1400     }
1401   if (self_value == NULL_TREE)
1402     {
1403       return build_static_field_ref (field_decl);
1404     }
1405   else
1406     {
1407       tree base_handle_type = promote_type (base_class);
1408       if (base_handle_type != TREE_TYPE (self_value))
1409         self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1410 #ifdef JAVA_USE_HANDLES
1411       self_value = unhand_expr (self_value);
1412 #endif
1413       self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1414                            self_value);
1415       return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1416                           self_value, field_decl));
1417     }
1418 }
1419
1420 tree
1421 lookup_label (pc)
1422      int pc;
1423 {
1424   tree name;
1425   char buf[32];
1426   ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1427   name = get_identifier (buf);
1428   if (IDENTIFIER_LOCAL_VALUE (name))
1429     return IDENTIFIER_LOCAL_VALUE (name);
1430   else
1431     {
1432       /* The type of the address of a label is return_address_type_node. */
1433       tree decl = create_label_decl (name);
1434       LABEL_PC (decl) = pc;
1435       label_rtx (decl);
1436       return pushdecl (decl);
1437     }
1438 }
1439
1440 /* Generate a unique name for the purpose of loops and switches
1441    labels, and try-catch-finally blocks label or temporary variables.  */
1442
1443 tree
1444 generate_name ()
1445 {
1446   static int l_number = 0;
1447   char buff [32];
1448   ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1449   l_number++;
1450   return get_identifier (buff);
1451 }
1452
1453 tree
1454 create_label_decl (name)
1455      tree name;
1456 {
1457   tree decl;
1458   push_obstacks (&permanent_obstack, &permanent_obstack);
1459   decl = build_decl (LABEL_DECL, name, 
1460                      TREE_TYPE (return_address_type_node));
1461   pop_obstacks ();
1462   DECL_CONTEXT (decl) = current_function_decl;
1463   DECL_IGNORED_P (decl) = 1;
1464   return decl;
1465 }
1466
1467 /* This maps a bytecode offset (PC) to various flags. */
1468 char *instruction_bits;
1469
1470 static void
1471 note_label (current_pc, target_pc)
1472      int current_pc ATTRIBUTE_UNUSED, target_pc;
1473 {
1474   lookup_label (target_pc);
1475   instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1476 }
1477
1478 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1479    where CONDITION is one of one the compare operators. */
1480
1481 static void
1482 expand_compare (condition, value1, value2, target_pc)
1483      enum tree_code condition;
1484      tree value1, value2;
1485      int target_pc;
1486 {
1487   tree target = lookup_label (target_pc);
1488   tree cond = fold (build (condition, boolean_type_node, value1, value2));
1489   expand_start_cond (truthvalue_conversion (cond), 0);
1490   expand_goto (target);
1491   expand_end_cond ();
1492 }
1493
1494 /* Emit code for a TEST-type opcode. */
1495
1496 static void
1497 expand_test (condition, type, target_pc)
1498      enum tree_code condition;
1499      tree type;
1500      int target_pc;
1501 {
1502   tree value1, value2;
1503   flush_quick_stack ();
1504   value1 = pop_value (type);
1505   value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1506   expand_compare (condition, value1, value2, target_pc);
1507 }
1508
1509 /* Emit code for a COND-type opcode. */
1510
1511 static void
1512 expand_cond (condition, type, target_pc)
1513      enum tree_code condition;
1514      tree type;
1515      int target_pc;
1516 {
1517   tree value1, value2;
1518   flush_quick_stack ();
1519   /* note: pop values in opposite order */
1520   value2 = pop_value (type);
1521   value1 = pop_value (type);
1522   /* Maybe should check value1 and value2 for type compatibility ??? */
1523   expand_compare (condition, value1, value2, target_pc);
1524 }
1525
1526 static void
1527 expand_java_goto (target_pc)
1528      int target_pc;
1529 {
1530   tree target_label = lookup_label (target_pc);
1531   flush_quick_stack ();
1532   expand_goto (target_label);
1533 }
1534
1535 #if 0
1536 static void
1537 expand_java_call (target_pc, return_address)
1538      int target_pc, return_address;
1539 {
1540   tree target_label = lookup_label (target_pc);
1541   tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1542   push_value (value);
1543   flush_quick_stack ();
1544   expand_goto (target_label);
1545 }
1546
1547 static void
1548 expand_java_ret (return_address)
1549      tree return_address ATTRIBUTE_UNUSED;
1550 {
1551   warning ("ret instruction not implemented");
1552 #if 0
1553   tree target_label = lookup_label (target_pc);
1554   flush_quick_stack ();
1555   expand_goto (target_label);
1556 #endif
1557 }
1558 #endif
1559
1560 /* Recursive helper function to pop argument types during verifiation. */
1561
1562 void
1563 pop_argument_types (arg_types)
1564      tree arg_types;
1565 {
1566   if (arg_types == end_params_node)
1567     return;
1568   if (TREE_CODE (arg_types) == TREE_LIST)
1569     {
1570       pop_argument_types (TREE_CHAIN (arg_types));
1571       pop_type (TREE_VALUE (arg_types));
1572       return;
1573     }
1574   abort ();
1575 }
1576
1577 static tree
1578 pop_arguments (arg_types)
1579      tree arg_types;
1580 {
1581   if (arg_types == end_params_node)
1582     return NULL_TREE;
1583   if (TREE_CODE (arg_types) == TREE_LIST)
1584     {
1585       tree tail = pop_arguments (TREE_CHAIN (arg_types));
1586       tree type = TREE_VALUE (arg_types);
1587       tree arg = pop_value (type);
1588       if (PROMOTE_PROTOTYPES
1589           && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1590           && INTEGRAL_TYPE_P (type))
1591         arg = convert (integer_type_node, arg);
1592       return tree_cons (NULL_TREE, arg, tail);
1593     }
1594   abort ();
1595 }
1596
1597 /* Build an expression to initialize the class CLAS.
1598    if EXPR is non-NULL, returns an expression to first call the initializer
1599    (if it is needed) and then calls EXPR. */
1600
1601 tree
1602 build_class_init (clas, expr)
1603      tree clas, expr;
1604 {
1605   tree init, call;
1606   struct init_test_hash_entry *ite;
1607   if (inherits_from_p (current_class, clas))
1608     return expr;
1609
1610   if (always_initialize_class_p)
1611     {
1612       init = build (CALL_EXPR, void_type_node,
1613                     build_address_of (soft_initclass_node),
1614                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1615                     NULL_TREE);
1616       TREE_SIDE_EFFECTS (init) = 1;
1617     }
1618   else
1619     {
1620       ite = (struct init_test_hash_entry *)
1621         hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1622                      (const hash_table_key) clas,
1623                      TRUE, NULL);
1624       
1625       if (ite->init_test_decl == 0)
1626         ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE, 
1627                                           boolean_type_node);
1628       /* Tell the check-init code to ignore this decl.  */
1629       DECL_BIT_INDEX(ite->init_test_decl) = -1;
1630
1631       init = build (CALL_EXPR, void_type_node,
1632                     build_address_of (soft_initclass_node),
1633                     build_tree_list (NULL_TREE, build_class_ref (clas)),
1634                     NULL_TREE);
1635       TREE_SIDE_EFFECTS (init) = 1;
1636       call = build (COMPOUND_EXPR, TREE_TYPE (expr), init, 
1637                     build (MODIFY_EXPR, boolean_type_node,
1638                            ite->init_test_decl, boolean_true_node));
1639       TREE_SIDE_EFFECTS (call) = 1;
1640       init = build (COND_EXPR, void_type_node,
1641                     build (EQ_EXPR, boolean_type_node, 
1642                            ite->init_test_decl, boolean_false_node),
1643                     call, integer_zero_node);
1644       TREE_SIDE_EFFECTS (init) = 1;
1645     }
1646
1647   if (expr != NULL_TREE)
1648     {
1649       expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1650       TREE_SIDE_EFFECTS (expr) = 1;
1651       return expr;
1652     }
1653   return init;
1654 }
1655
1656 static tree methods_ident = NULL_TREE;
1657 static tree ncode_ident = NULL_TREE;
1658 tree dtable_ident = NULL_TREE;
1659
1660 tree
1661 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1662      tree method, method_type ATTRIBUTE_UNUSED, self_type,
1663           method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1664 {
1665   tree func;
1666   if (is_compiled_class (self_type))
1667     {
1668       make_decl_rtl (method, NULL, 1);
1669       func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1670     }
1671   else
1672     {
1673       /* We don't know whether the method has been (statically) compiled.
1674          Compile this code to get a reference to the method's code:
1675          
1676          SELF_TYPE->methods[METHOD_INDEX].ncode
1677          
1678          This is guaranteed to work (assuming SELF_TYPE has
1679          been initialized), since if the method is not compiled yet,
1680          its ncode points to a trampoline that forces compilation. */
1681       
1682       int method_index = 0;
1683       tree meth;
1684       tree ref = build_class_ref (self_type);
1685       ref = build1 (INDIRECT_REF, class_type_node, ref);
1686       if (ncode_ident == NULL_TREE)
1687         ncode_ident = get_identifier ("ncode");
1688       if (methods_ident == NULL_TREE)
1689         methods_ident = get_identifier ("methods");
1690       ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1691                    lookup_field (&class_type_node, methods_ident));
1692       for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1693            ; meth = TREE_CHAIN (meth))
1694         {
1695           if (method == meth)
1696             break;
1697           if (meth == NULL_TREE)
1698             fatal ("method '%s' not found in class",
1699                    IDENTIFIER_POINTER (DECL_NAME (method)));
1700           method_index++;
1701         }
1702       method_index *= int_size_in_bytes (method_type_node);
1703       ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1704                          ref, build_int_2 (method_index, 0)));
1705       ref = build1 (INDIRECT_REF, method_type_node, ref);
1706       func = build (COMPONENT_REF, nativecode_ptr_type_node,
1707                     ref,
1708                     lookup_field (&method_type_node, ncode_ident));
1709     }
1710   return func;
1711 }
1712
1713 tree
1714 invoke_build_dtable (is_invoke_interface, arg_list)
1715      int is_invoke_interface;
1716      tree arg_list;
1717 {
1718   tree dtable, objectref;
1719
1720   TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1721
1722   /* If we're dealing with interfaces and if the objectref
1723      argument is an array then get the dispatch table of the class
1724      Object rather than the one from the objectref.  */
1725   objectref = (is_invoke_interface 
1726                && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1727                object_type_node : TREE_VALUE (arg_list));
1728   
1729   if (dtable_ident == NULL_TREE)
1730     dtable_ident = get_identifier ("vtable");
1731   dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1732   dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1733                   lookup_field (&object_type_node, dtable_ident));
1734
1735   return dtable;
1736 }
1737
1738 tree 
1739 build_invokevirtual (dtable, method)
1740      tree dtable, method;
1741 {
1742   tree func;
1743   tree nativecode_ptr_ptr_type_node
1744     = build_pointer_type (nativecode_ptr_type_node);
1745   tree method_index = convert (sizetype, DECL_VINDEX (method));
1746
1747   /* Add one to skip "class" field of dtable, and one to skip unused
1748      vtable entry (for C++ compatibility). */
1749   method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1750   method_index = size_binop (MULT_EXPR, method_index,
1751                              TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1752   func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1753                       convert (nativecode_ptr_ptr_type_node, method_index)));
1754   func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1755
1756   return func;
1757 }
1758
1759 tree
1760 build_invokeinterface (dtable, method)
1761      tree dtable, method;
1762 {
1763   static tree class_ident = NULL_TREE;
1764   tree lookup_arg;
1765   tree interface;
1766   tree idx;
1767   tree meth;
1768   int i;
1769
1770   /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
1771      ensure that the selected method exists, is public and not
1772      abstract nor static.  */
1773             
1774   if (class_ident == NULL_TREE)
1775     class_ident = get_identifier ("class");
1776   
1777   dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1778   dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1779                   lookup_field (&dtable_type, class_ident));
1780
1781   interface = DECL_CONTEXT (method);
1782   layout_class_methods (interface);
1783   
1784   i = 1;
1785   for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1786     {
1787       if (meth == method)
1788         {
1789           idx = build_int_2 (i, 0);
1790           break;
1791         }
1792       if (meth == NULL_TREE)
1793         fatal ("internal error in build_invokeinterface");
1794     }
1795
1796   lookup_arg = tree_cons (NULL_TREE, dtable,
1797                           tree_cons (NULL_TREE, build_class_ref (interface),
1798                                      build_tree_list (NULL_TREE, idx)));
1799                                                           
1800   return build (CALL_EXPR, ptr_type_node, 
1801                 build_address_of (soft_lookupinterfacemethod_node),
1802                 lookup_arg, NULL_TREE);
1803 }
1804   
1805 /* Expand one of the invoke_* opcodes.
1806    OCPODE is the specific opcode.
1807    METHOD_REF_INDEX is an index into the constant pool.
1808    NARGS is the number of arguments, or -1 if not specified. */
1809
1810 static void
1811 expand_invoke (opcode, method_ref_index, nargs)
1812      int opcode;
1813      int method_ref_index;
1814      int nargs ATTRIBUTE_UNUSED;
1815 {
1816   tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1817   tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1818   tree self_type = get_class_constant
1819     (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1820   const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1821   tree call, func, method, arg_list, method_type;
1822   tree cond = NULL_TREE;
1823
1824   if (! CLASS_LOADED_P (self_type))
1825     {
1826       load_class (self_type, 1);
1827       safe_layout_class (self_type);
1828       if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1829         fatal ("failed to find class '%s'", self_name);
1830     }
1831   layout_class_methods (self_type);
1832
1833   if (ID_INIT_P (method_name))
1834     method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1835                                       method_signature);
1836   else
1837     method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1838                                  method_name, method_signature);
1839   if (method == NULL_TREE)
1840     {
1841       error ("Class '%s' has no method named '%s' matching signature '%s'",
1842              self_name,
1843              IDENTIFIER_POINTER (method_name),
1844              IDENTIFIER_POINTER (method_signature));
1845     }
1846   /* Invoke static can't invoke static/abstract method */
1847   else if (opcode == OPCODE_invokestatic)
1848     {
1849       if (!METHOD_STATIC (method))
1850         {
1851           error ("invokestatic on non static method");
1852           method = NULL_TREE;
1853         }
1854       else if (METHOD_ABSTRACT (method))
1855         {
1856           error ("invokestatic on abstract method");
1857           method = NULL_TREE;
1858         }
1859     }
1860   else
1861     {
1862       if (METHOD_STATIC (method))
1863         {
1864           error ("invoke[non-static] on static method");
1865           method = NULL_TREE;
1866         }
1867     }
1868
1869   if (method == NULL_TREE)
1870     {
1871       method_type = get_type_from_signature (method_signature);
1872       pop_arguments (TYPE_ARG_TYPES (method_type));
1873       if (opcode != OPCODE_invokestatic) 
1874         pop_type (self_type);
1875       method_type = promote_type (TREE_TYPE (method_type));
1876       push_value (convert (method_type, integer_zero_node));
1877       return;
1878     }
1879
1880   method_type = TREE_TYPE (method);
1881   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1882   flush_quick_stack ();
1883
1884   func = NULL_TREE;
1885   if (opcode == OPCODE_invokestatic)
1886     func = build_known_method_ref (method, method_type, self_type,
1887                                    method_signature, arg_list);
1888   else if (opcode == OPCODE_invokespecial
1889            || (opcode == OPCODE_invokevirtual
1890                && (METHOD_PRIVATE (method)
1891                    || METHOD_FINAL (method) 
1892                    || CLASS_FINAL (TYPE_NAME (self_type)))))
1893     {
1894       /* If the object for the method call is null, we throw an
1895          exception.  We don't do this if the object is the current
1896          method's `this'.  In other cases we just rely on an
1897          optimization pass to eliminate redundant checks.  FIXME:
1898          Unfortunately there doesn't seem to be a way to determine
1899          what the current method is right now.  */
1900       /* We use a SAVE_EXPR here to make sure we only evaluate
1901          the new `self' expression once.  */
1902       tree save_arg = save_expr (TREE_VALUE (arg_list));
1903       TREE_VALUE (arg_list) = save_arg;
1904       cond = build (EQ_EXPR, boolean_type_node, save_arg, null_pointer_node);
1905       func = build_known_method_ref (method, method_type, self_type,
1906                                      method_signature, arg_list);
1907     }
1908   else
1909     {
1910       tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 
1911                                          arg_list);
1912       if (opcode == OPCODE_invokevirtual)
1913         func = build_invokevirtual (dtable, method);
1914       else
1915         func = build_invokeinterface (dtable, method);
1916     }
1917   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1918   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1919   TREE_SIDE_EFFECTS (call) = 1;
1920
1921   if (cond != NULL_TREE)
1922     {
1923       /* We have to make the `then' branch a compound expression to
1924          make the types turn out right.  This seems bizarre.  */
1925       call = build (COND_EXPR, TREE_TYPE (call), cond,
1926                     build (COMPOUND_EXPR, TREE_TYPE (call),
1927                            build (CALL_EXPR, void_type_node,
1928                                   build_address_of (soft_nullpointer_node),
1929                                   NULL_TREE, NULL_TREE),
1930                            (FLOAT_TYPE_P (TREE_TYPE (call))
1931                             ? build_real (TREE_TYPE (call), dconst0)
1932                             : build1 (CONVERT_EXPR, TREE_TYPE (call),
1933                                       integer_zero_node))),
1934                     call);
1935       TREE_SIDE_EFFECTS (call) = 1;
1936     }
1937
1938   if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1939     expand_expr_stmt (call);
1940   else
1941     {
1942       push_value (call);
1943       flush_quick_stack ();
1944     }
1945 }
1946
1947 /* Create a stub which will be put into the vtable but which will call
1948    a JNI function.  */
1949
1950 tree
1951 build_jni_stub (method)
1952      tree method;
1953 {
1954   tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
1955   tree jni_func_type, tem;
1956   tree env_var, res_var = NULL_TREE, block;
1957   tree method_args, res_type;
1958   tree meth_var;
1959
1960   tree klass = DECL_CONTEXT (method);
1961   int from_class = ! CLASS_FROM_SOURCE_P (klass);
1962   klass = build_class_ref (klass);
1963
1964   if (! METHOD_NATIVE (method) || ! flag_jni)
1965     abort ();
1966
1967   DECL_ARTIFICIAL (method) = 1;
1968   DECL_EXTERNAL (method) = 0;
1969
1970   env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
1971   DECL_CONTEXT (env_var) = method;
1972
1973   if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
1974     {
1975       res_var = build_decl (VAR_DECL, get_identifier ("res"),
1976                             TREE_TYPE (TREE_TYPE (method)));
1977       DECL_CONTEXT (res_var) = method;
1978       TREE_CHAIN (env_var) = res_var;
1979     }
1980
1981   push_obstacks (&permanent_obstack, &permanent_obstack);
1982   meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
1983   TREE_STATIC (meth_var) = 1;
1984   TREE_PUBLIC (meth_var) = 0;
1985   DECL_EXTERNAL (meth_var) = 0;
1986   make_decl_rtl (meth_var, NULL, 0);
1987   meth_var = pushdecl_top_level (meth_var);
1988   pop_obstacks ();
1989
1990   /* One strange way that the front ends are different is that they
1991      store arguments differently.  */
1992   if (from_class)
1993     method_args = DECL_ARGUMENTS (method);
1994   else
1995     method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
1996   block = build_block (env_var, NULL_TREE, NULL_TREE,
1997                        method_args, NULL_TREE);
1998   TREE_SIDE_EFFECTS (block) = 1;
1999   /* When compiling from source we don't set the type of the block,
2000      because that will prevent patch_return from ever being run.  */
2001   if (from_class)
2002     TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2003
2004   /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame.  */
2005   body = build (MODIFY_EXPR, ptr_type_node, env_var,
2006                 build (CALL_EXPR, ptr_type_node,
2007                        build_address_of (soft_getjnienvnewframe_node),
2008                        build_tree_list (NULL_TREE, klass),
2009                        NULL_TREE));
2010   CAN_COMPLETE_NORMALLY (body) = 1;
2011
2012   /* All the arguments to this method become arguments to the
2013      underlying JNI function.  If we had to wrap object arguments in a
2014      special way, we would do that here.  */
2015   args = NULL_TREE;
2016   for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2017     args = tree_cons (NULL_TREE, tem, args);
2018   args = nreverse (args);
2019   arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2020
2021   /* For a static method the second argument is the class.  For a
2022      non-static method the second argument is `this'; that is already
2023      available in the argument list.  */
2024   if (METHOD_STATIC (method))
2025     {
2026       args = tree_cons (NULL_TREE, klass, args);
2027       arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2028     }
2029
2030   /* The JNIEnv structure is the first argument to the JNI function.  */
2031   args = tree_cons (NULL_TREE, env_var, args);
2032   arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2033
2034   /* We call _Jv_LookupJNIMethod to find the actual underlying
2035      function pointer.  _Jv_LookupJNIMethod will throw the appropriate
2036      exception if this function is not found at runtime.  */
2037   method_sig = build_java_signature (TREE_TYPE (method));
2038   lookup_arg =
2039     build_tree_list (NULL_TREE,
2040                      build_utf8_ref (unmangle_classname
2041                                      (IDENTIFIER_POINTER (method_sig),
2042                                       IDENTIFIER_LENGTH (method_sig))));
2043   tem = DECL_NAME (method);
2044   lookup_arg
2045     = tree_cons (NULL_TREE, klass,
2046                  tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2047
2048   jni_func_type
2049     = build_pointer_type (build_function_type (TREE_TYPE (TREE_TYPE (method)),
2050                                                arg_types));
2051
2052   jnifunc = build (COND_EXPR, ptr_type_node,
2053                    meth_var, meth_var,
2054                    build (MODIFY_EXPR, ptr_type_node,
2055                           meth_var,
2056                           build (CALL_EXPR, ptr_type_node,
2057                                  build_address_of (soft_lookupjnimethod_node),
2058                                  lookup_arg, NULL_TREE)));
2059
2060   /* Now we make the actual JNI call via the resulting function
2061      pointer.    */
2062   call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2063                 build1 (NOP_EXPR, jni_func_type, jnifunc),
2064                 args, NULL_TREE);
2065
2066   /* If the JNI call returned a result, capture it here.  If we had to
2067      unwrap JNI object results, we would do that here.  */
2068   if (res_var != NULL_TREE)
2069     call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2070                   res_var, call);
2071
2072   TREE_SIDE_EFFECTS (call) = 1;
2073   CAN_COMPLETE_NORMALLY (call) = 1;
2074
2075   body = build (COMPOUND_EXPR, void_type_node, body, call);
2076   TREE_SIDE_EFFECTS (body) = 1;
2077
2078   /* Now free the environment we allocated.  */
2079   call = build (CALL_EXPR, ptr_type_node,
2080                 build_address_of (soft_jnipopsystemframe_node),
2081                 build_tree_list (NULL_TREE, env_var),
2082                 NULL_TREE);
2083   TREE_SIDE_EFFECTS (call) = 1;
2084   CAN_COMPLETE_NORMALLY (call) = 1;
2085   body = build (COMPOUND_EXPR, void_type_node, body, call);
2086   TREE_SIDE_EFFECTS (body) = 1;
2087
2088   /* Finally, do the return.  When compiling from source we rely on
2089      patch_return to patch the return value -- because DECL_RESULT is
2090      not set at the time this function is called.  */
2091   if (from_class)
2092     {
2093       res_type = void_type_node;
2094       if (res_var != NULL_TREE)
2095         {
2096           tree drt;
2097           if (! DECL_RESULT (method))
2098             abort ();
2099           /* Make sure we copy the result variable to the actual
2100              result.  We use the type of the DECL_RESULT because it
2101              might be different from the return type of the function:
2102              it might be promoted.  */
2103           drt = TREE_TYPE (DECL_RESULT (method));
2104           if (drt != TREE_TYPE (res_var))
2105             res_var = build1 (CONVERT_EXPR, drt, res_var);
2106           res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2107           TREE_SIDE_EFFECTS (res_var) = 1;
2108         }
2109     }
2110   else
2111     {
2112       /* This is necessary to get patch_return to run.  */
2113       res_type = NULL_TREE;
2114     }
2115   body = build (COMPOUND_EXPR, void_type_node, body,
2116                 build1 (RETURN_EXPR, res_type, res_var));
2117   TREE_SIDE_EFFECTS (body) = 1;
2118
2119   BLOCK_EXPR_BODY (block) = body;
2120   return block;
2121 }
2122
2123 /* Expand an operation to extract from or store into a field.
2124    IS_STATIC is 1 iff the field is static.
2125    IS_PUTTING is 1 for putting into a field;  0 for getting from the field.
2126    FIELD_REF_INDEX is an index into the constant pool.  */
2127
2128 static void
2129 expand_java_field_op (is_static, is_putting, field_ref_index)
2130      int is_static;
2131      int is_putting;
2132      int field_ref_index;
2133 {
2134   tree self_type = 
2135       get_class_constant (current_jcf, 
2136                           COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 
2137                                                      field_ref_index));
2138   const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2139   tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
2140   tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 
2141                                                   field_ref_index);
2142   tree field_type = get_type_from_signature (field_signature);
2143   tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2144   tree field_ref;
2145   int is_error = 0;
2146   tree field_decl = lookup_field (&self_type, field_name);
2147   if (field_decl == error_mark_node)
2148     {
2149       is_error = 1;
2150     }
2151   else if (field_decl == NULL_TREE)
2152     {
2153       error ("Missing field '%s' in '%s'",
2154              IDENTIFIER_POINTER (field_name), self_name);
2155       is_error = 1;
2156     }
2157   else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2158     {
2159       error ("Mismatching signature for field '%s' in '%s'",
2160              IDENTIFIER_POINTER (field_name), self_name);
2161       is_error = 1;
2162     }
2163   field_ref = is_static ? NULL_TREE : pop_value (self_type);
2164   if (is_error)
2165     {
2166       if (! is_putting)
2167         push_value (convert (field_type, integer_zero_node));
2168       flush_quick_stack ();
2169       return;
2170     }
2171
2172   /* Inline references to java.lang.PRIMTYPE.TYPE.
2173      In addition to being a useful (minor) optimization,
2174      this is also needed to avoid circularities in the implementation
2175      of these fields in libjava. */
2176   if (field_name == TYPE_identifier_node && ! is_putting
2177       && ! flag_emit_class_files && field_type == class_ptr_type
2178       && strncmp (self_name, "java.lang.", 10) == 0)
2179     {
2180       tree typ = build_primtype_type_ref (self_name);
2181       if (typ)
2182         {
2183           push_value (typ);
2184           return;
2185         }
2186     }
2187
2188   field_ref = build_field_ref (field_ref, self_type, field_name);
2189   if (is_static)
2190     field_ref = build_class_init (self_type, field_ref);
2191   if (is_putting)
2192     {
2193       flush_quick_stack ();
2194       if (FIELD_FINAL (field_decl))
2195         {
2196           if (DECL_CONTEXT (field_decl) != current_class)
2197             error_with_decl (field_decl,
2198                      "assignment to final field `%s' not in field's class");
2199           else if (FIELD_STATIC (field_decl))
2200             {
2201               if (!DECL_CLINIT_P (current_function_decl))
2202                 error_with_decl (field_decl, 
2203              "assignment to final static field `%s' not in class initializer");
2204             }
2205           else
2206             {
2207               tree cfndecl_name = DECL_NAME (current_function_decl);
2208               if (! DECL_CONSTRUCTOR_P (current_function_decl)
2209                   && !ID_FINIT_P (cfndecl_name))
2210                 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2211             }
2212         }
2213       expand_assignment (field_ref, new_value, 0, 0);
2214     }
2215   else
2216     push_value (field_ref);
2217 }
2218
2219 tree
2220 build_primtype_type_ref (self_name)
2221     const char *self_name;
2222 {
2223   const char *class_name = self_name+10;
2224   tree typ;
2225   if (strncmp(class_name, "Byte", 4) == 0)
2226     typ = byte_type_node;
2227   else if (strncmp(class_name, "Short", 5) == 0)
2228     typ = short_type_node;
2229   else if (strncmp(class_name, "Integer", 7) == 0)
2230     typ = int_type_node;
2231   else if (strncmp(class_name, "Long", 4) == 0)
2232     typ = long_type_node;
2233   else if (strncmp(class_name, "Float", 5) == 0)
2234     typ = float_type_node;
2235   else if (strncmp(class_name, "Double", 6) == 0)
2236     typ = double_type_node;
2237   else if (strncmp(class_name, "Boolean", 7) == 0)
2238     typ = boolean_type_node;
2239   else if (strncmp(class_name, "Char", 4) == 0)
2240     typ = char_type_node;
2241   else if (strncmp(class_name, "Void", 4) == 0)
2242     typ = void_type_node;
2243   else
2244     typ = NULL_TREE;
2245   if (typ != NULL_TREE)
2246     return build_class_ref (typ);
2247   else
2248     return NULL_TREE;
2249 }
2250
2251 void
2252 load_type_state (label)
2253      tree label;
2254 {
2255   int i;
2256   tree vec = LABEL_TYPE_STATE (label);
2257   int cur_length = TREE_VEC_LENGTH (vec);
2258   stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2259   for (i = 0; i < cur_length; i++)
2260     type_map [i] = TREE_VEC_ELT (vec, i);
2261 }
2262
2263 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2264    dependant things, but they rely on gcc routines. This function is
2265    placed here because it uses things defined locally in parse.y. */
2266
2267 static tree
2268 case_identity (t, v)
2269      tree t __attribute__ ((__unused__));
2270      tree v;
2271 {
2272   return v;
2273 }
2274
2275 /* Return the name of the vtable for an array of a given primitive
2276    type.  */
2277 static tree
2278 get_primitive_array_vtable (tree elt)
2279 {
2280   tree r;
2281   if (elt == boolean_type_node)
2282     r = boolean_array_vtable;
2283   else if (elt == byte_type_node)
2284     r = byte_array_vtable;
2285   else if (elt == char_type_node)
2286     r = char_array_vtable;
2287   else if (elt == short_type_node)
2288     r = short_array_vtable;
2289   else if (elt == int_type_node)
2290     r = int_array_vtable;
2291   else if (elt == long_type_node)
2292     r = long_array_vtable;
2293   else if (elt == float_type_node)
2294     r = float_array_vtable;
2295   else if (elt == double_type_node)
2296     r = double_array_vtable;
2297   else
2298     abort ();
2299   return build_address_of (r);
2300 }
2301
2302 struct rtx_def *
2303 java_lang_expand_expr (exp, target, tmode, modifier)
2304      register tree exp;
2305      rtx target ATTRIBUTE_UNUSED;
2306      enum machine_mode tmode ATTRIBUTE_UNUSED;
2307      enum expand_modifier modifier ATTRIBUTE_UNUSED;
2308 {
2309   tree current;
2310
2311   switch (TREE_CODE (exp))
2312     {
2313     case NEW_ARRAY_INIT:
2314       {
2315         rtx tmp;
2316         tree array_type = TREE_TYPE (TREE_TYPE (exp));
2317         tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2318         tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2319         HOST_WIDE_INT ilength = java_array_type_length (array_type);
2320         tree length = build_int_2 (ilength, 0);
2321         tree init = TREE_OPERAND (exp, 0);
2322         tree array_decl;
2323
2324         /* See if we can generate the array statically.  */
2325         if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2326             && JPRIMITIVE_TYPE_P (element_type))
2327           {
2328             tree temp, value, init_decl;
2329             struct rtx_def *r;
2330             push_obstacks (&permanent_obstack, &permanent_obstack);
2331             START_RECORD_CONSTRUCTOR (temp, object_type_node);
2332             PUSH_FIELD_VALUE (temp, "vtable",
2333                               get_primitive_array_vtable (element_type));
2334             if (! flag_hash_synchronization)
2335               PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2336             FINISH_RECORD_CONSTRUCTOR (temp);
2337             START_RECORD_CONSTRUCTOR (value, array_type);
2338             PUSH_SUPER_VALUE (value, temp);
2339             /* FIXME: build a new `length' here to get it on the right
2340                obstack.  */
2341             PUSH_FIELD_VALUE (value, "length", build_int_2 (ilength, 0));
2342             PUSH_FIELD_VALUE (value, "data", init);
2343             FINISH_RECORD_CONSTRUCTOR (value);
2344
2345             init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2346             pushdecl_top_level (init_decl);
2347             TREE_STATIC (init_decl) = 1;
2348             DECL_INITIAL (init_decl) = value;
2349             DECL_IGNORED_P (init_decl) = 1;
2350             TREE_READONLY (init_decl) = 1;
2351             make_decl_rtl (init_decl, NULL, 1);
2352             init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2353             r = expand_expr (init, target, tmode, modifier);
2354             pop_obstacks ();
2355             return r;
2356           }
2357
2358         array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2359         expand_decl (array_decl);
2360         tmp = expand_assignment (array_decl,
2361                                  build_new_array (element_type, length),
2362                                  1, 0);
2363         if (TREE_CONSTANT (init)
2364             && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2365           {
2366             tree init_decl;
2367             push_obstacks (&permanent_obstack, &permanent_obstack);
2368             init_decl = build_decl (VAR_DECL, generate_name (),
2369                                     TREE_TYPE (init));
2370             pushdecl_top_level (init_decl);
2371             TREE_STATIC (init_decl) = 1;
2372             DECL_INITIAL (init_decl) = init;
2373             DECL_IGNORED_P (init_decl) = 1;
2374             TREE_READONLY (init_decl) = 1;
2375             TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2376             make_decl_rtl (init_decl, NULL, 1);
2377             pop_obstacks ();
2378             init = init_decl;
2379           }
2380         expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2381                                   build1 (INDIRECT_REF, array_type, 
2382                                           array_decl), data_fld), init, 0, 0);
2383         return tmp;
2384       }
2385     case BLOCK:
2386       if (BLOCK_EXPR_BODY (exp))
2387         {
2388           tree local;
2389           tree body = BLOCK_EXPR_BODY (exp);
2390           pushlevel (2);        /* 2 and above */
2391           expand_start_bindings (0);
2392           local = BLOCK_EXPR_DECLS (exp);
2393           while (local)
2394             {
2395               tree next = TREE_CHAIN (local);
2396               layout_decl (local, 0);
2397               expand_decl (pushdecl (local));
2398               local = next;
2399             }
2400           /* Avoid deep recursion for long block.  */
2401           while (TREE_CODE (body) == COMPOUND_EXPR)
2402             {
2403               expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2404               emit_queue ();
2405               body = TREE_OPERAND (body, 1);
2406             }
2407           expand_expr (body, const0_rtx, VOIDmode, 0);
2408           emit_queue ();
2409           poplevel (1, 1, 0);
2410           expand_end_bindings (getdecls (), 1, 0);
2411           return const0_rtx;
2412         }
2413       return const0_rtx;
2414
2415     case CASE_EXPR:
2416       {
2417         tree duplicate;
2418         if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2419                       build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), 
2420                       &duplicate) == 2)
2421           {
2422             EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2423             parse_error_context
2424               (wfl_operator, "Duplicate case label: `%s'",
2425                print_int_node (TREE_OPERAND (exp, 0)));
2426           }
2427         return const0_rtx;
2428       }
2429
2430     case DEFAULT_EXPR:
2431       pushcase (NULL_TREE, 0, 
2432                 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2433       return const0_rtx;
2434
2435     case SWITCH_EXPR:
2436       expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2437       expand_expr_stmt (TREE_OPERAND (exp, 1));
2438       expand_end_case (TREE_OPERAND (exp, 0));
2439       return const0_rtx;
2440
2441     case TRY_EXPR:
2442       /* We expand a try[-catch] block */
2443
2444       /* Expand the try block */
2445       push_obstacks (&permanent_obstack, &permanent_obstack);
2446       expand_eh_region_start ();
2447       pop_obstacks ();
2448       expand_expr_stmt (TREE_OPERAND (exp, 0));
2449       push_obstacks (&permanent_obstack, &permanent_obstack);
2450       expand_start_all_catch ();
2451       pop_obstacks ();
2452
2453       /* Expand all catch clauses (EH handlers) */
2454       for (current = TREE_OPERAND (exp, 1); current; 
2455            current = TREE_CHAIN (current))
2456         {
2457           tree type;
2458           tree catch = TREE_OPERAND (current, 0);
2459           tree decl = BLOCK_EXPR_DECLS (catch);
2460           type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2461           start_catch_handler (prepare_eh_table_type (type));
2462           expand_expr_stmt (TREE_OPERAND (current, 0));
2463
2464           expand_resume_after_catch ();
2465           end_catch_handler ();
2466         }
2467       expand_end_all_catch ();
2468       return const0_rtx;
2469
2470     default:
2471       fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2472              tree_code_name [TREE_CODE (exp)]);
2473     }
2474 }
2475
2476 void
2477 expand_byte_code (jcf, method)
2478      JCF *jcf;
2479      tree method;
2480 {
2481   int PC;
2482   int i;
2483   int saw_index;
2484   const unsigned char *linenumber_pointer;
2485   int dead_code_index = -1;
2486
2487 #undef RET /* Defined by config/i386/i386.h */
2488 #undef AND /* Causes problems with opcodes for iand and land. */
2489 #undef PTR
2490 #define BCODE byte_ops
2491 #define BYTE_type_node byte_type_node
2492 #define SHORT_type_node short_type_node
2493 #define INT_type_node int_type_node
2494 #define LONG_type_node long_type_node
2495 #define CHAR_type_node char_type_node
2496 #define PTR_type_node ptr_type_node
2497 #define FLOAT_type_node float_type_node
2498 #define DOUBLE_type_node double_type_node
2499 #define VOID_type_node void_type_node
2500   jint INT_temp;
2501   unsigned char* byte_ops;
2502   long length = DECL_CODE_LENGTH (method);
2503
2504   stack_pointer = 0;
2505   JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2506   byte_ops = jcf->read_ptr;
2507
2508 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2509 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2510 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2511 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2512
2513 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2514
2515   instruction_bits = oballoc (length + 1);
2516   bzero (instruction_bits, length + 1);
2517
2518   /* We make an initial pass of the line number table, to note
2519      which instructions have associated line number entries. */
2520   linenumber_pointer = linenumber_table;
2521   for (i = 0; i < linenumber_count; i++)
2522     {
2523       int pc = GET_u2 (linenumber_pointer);
2524       linenumber_pointer += 4;
2525       if (pc >= length)
2526         warning ("invalid PC in line number table");
2527       else
2528         {
2529           if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2530             instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2531           instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2532         }
2533     }  
2534
2535   /* Do a preliminary pass.
2536    * This figures out which PC can be the targets of jumps. */
2537   for (PC = 0; PC < length;)
2538     {
2539       int oldpc = PC; /* PC at instruction start. */
2540       instruction_bits [PC] |=  BCODE_INSTRUCTION_START;
2541       switch (byte_ops[PC++])
2542         {
2543 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2544         case OPCODE: \
2545           PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2546           break;
2547
2548 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2549
2550 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2551 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2552 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2553 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2554 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2555 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2556 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2557 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2558
2559 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2560   PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2561 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2562   ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2563 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2564 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2565 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2566 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2567
2568 /* two forms of wide instructions */
2569 #define PRE_SPECIAL_WIDE(IGNORE) \
2570   { \
2571     int modified_opcode = IMMEDIATE_u1; \
2572     if (modified_opcode == OPCODE_iinc) \
2573       { \
2574         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2575         (void) IMMEDIATE_s2;    /* constbyte1 and constbyte2 */ \
2576       } \
2577     else \
2578       { \
2579         (void) IMMEDIATE_u2;    /* indexbyte1 and indexbyte2 */ \
2580       } \
2581   }
2582
2583 /* nothing */ /* XXX JH */
2584
2585 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2586
2587 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2588
2589 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2590 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2591           PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2592 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2593 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2594 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2595 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2596 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2597 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2598 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2599
2600 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2601 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2602 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2603   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2604   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2605 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2606   saw_index = 0;  INT_temp = (OPERAND_VALUE); \
2607   if (!saw_index)  NOTE_LABEL(oldpc + INT_temp);
2608
2609 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE)  (void)(OPERAND_VALUE)
2610
2611 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2612   PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2613
2614 #define PRE_LOOKUP_SWITCH                                               \
2615   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4;    \
2616     NOTE_LABEL (default_offset+oldpc);                                  \
2617     if (npairs >= 0)                                                    \
2618       while (--npairs >= 0) {                                           \
2619        jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4;                      \
2620        jint offset = IMMEDIATE_s4;                                      \
2621        NOTE_LABEL (offset+oldpc); }                                     \
2622   }
2623
2624 #define PRE_TABLE_SWITCH                                \
2625   { jint default_offset = IMMEDIATE_s4;                 \
2626     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4;  \
2627     NOTE_LABEL (default_offset+oldpc);                  \
2628     if (low <= high)                                    \
2629      while (low++ <= high) {                            \
2630        jint offset = IMMEDIATE_s4;                      \
2631        NOTE_LABEL (offset+oldpc); }                     \
2632   }
2633
2634 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2635 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2636 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2637   (void)(IMMEDIATE_u2); \
2638   PC += 2 * IS_INTERFACE /* for invokeinterface */;
2639
2640 #include "javaop.def"
2641 #undef JAVAOP
2642         }
2643     } /* for */
2644
2645   if (! verify_jvm_instructions (jcf, byte_ops, length))
2646     return;
2647
2648   /* Translate bytecodes to rtl instructions. */
2649   linenumber_pointer = linenumber_table;
2650   for (PC = 0; PC < length;)
2651     {
2652       if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2653         {
2654           tree label = lookup_label (PC);
2655           flush_quick_stack ();
2656           if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2657             expand_label (label);
2658           if (LABEL_VERIFIED (label) || PC == 0)
2659             load_type_state (label);
2660         }
2661
2662       if (! (instruction_bits [PC] & BCODE_VERIFIED))
2663         {
2664           if (dead_code_index == -1)
2665             {
2666               /* This is the start of a region of unreachable bytecodes.
2667                  They still need to be processed in order for EH ranges
2668                  to get handled correctly.  However, we can simply
2669                  replace these bytecodes with nops.  */
2670               dead_code_index = PC;
2671             }
2672           
2673           /* Turn this bytecode into a nop.  */
2674           byte_ops[PC] = 0x0;
2675         }
2676        else
2677         {
2678           if (dead_code_index != -1)
2679             {
2680               /* We've just reached the end of a region of dead code.  */
2681               warning ("Unreachable bytecode from %d to before %d.",
2682                        dead_code_index, PC);
2683               dead_code_index = -1;
2684             }
2685         }
2686
2687       /* Handle possible line number entry for this PC.
2688
2689          This code handles out-of-order and multiple linenumbers per PC,
2690          but is optimized for the case of line numbers increasing
2691          monotonically with PC. */
2692       if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2693         {
2694           if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2695               || GET_u2 (linenumber_pointer) != PC)
2696             linenumber_pointer = linenumber_table;
2697           while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2698             {
2699               int pc = GET_u2 (linenumber_pointer);
2700               linenumber_pointer += 4;
2701               if (pc == PC)
2702                 {
2703                   lineno = GET_u2 (linenumber_pointer - 2);
2704                   emit_line_note (input_filename, lineno);
2705                   if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2706                     break;
2707                 }
2708             }
2709         }
2710       maybe_pushlevels (PC);
2711       PC = process_jvm_instruction (PC, byte_ops, length);
2712       maybe_poplevels (PC);
2713     } /* for */
2714   
2715   if (dead_code_index != -1)
2716     {
2717       /* We've just reached the end of a region of dead code.  */
2718       warning ("Unreachable bytecode from %d to the end of the method.", 
2719               dead_code_index);
2720     }
2721 }
2722
2723 static void
2724 java_push_constant_from_pool (jcf, index)
2725      JCF *jcf;
2726      int index;
2727 {
2728   tree c;
2729   if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2730     {
2731       tree name;
2732       push_obstacks (&permanent_obstack, &permanent_obstack);
2733       name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2734       index = alloc_name_constant (CONSTANT_String, name);
2735       c = build_ref_from_constant_pool (index);
2736       TREE_TYPE (c) = promote_type (string_type_node);
2737       pop_obstacks ();
2738     }
2739   else
2740     c = get_constant (jcf, index);
2741   push_value (c);
2742
2743
2744 int
2745 process_jvm_instruction (PC, byte_ops, length)
2746      int PC;
2747      const unsigned char* byte_ops;
2748      long length ATTRIBUTE_UNUSED;
2749
2750   const char *opname; /* Temporary ??? */
2751   int oldpc = PC; /* PC at instruction start. */
2752
2753   /* If the instruction is at the beginning of a exception handler,
2754      replace the top of the stack with the thrown object reference */
2755   if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2756     {
2757       tree type = pop_type (ptr_type_node);
2758       push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2759     }
2760
2761   switch (byte_ops[PC++])
2762     {
2763 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2764     case OPCODE: \
2765       opname = #OPNAME; \
2766       OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2767       break;
2768
2769 #define RET(OPERAND_TYPE, OPERAND_VALUE)                                \
2770   {                                                                     \
2771     int saw_index = 0;                                                  \
2772     int index     = OPERAND_VALUE;                                      \
2773     build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2774   }
2775
2776 #define JSR(OPERAND_TYPE, OPERAND_VALUE)                \
2777   {                                                     \
2778     tree where = lookup_label (oldpc+OPERAND_VALUE);    \
2779     tree ret   = lookup_label (PC);                     \
2780     build_java_jsr (where, ret);                        \
2781     load_type_state (ret);                              \
2782   }
2783
2784 /* Push a constant onto the stack. */
2785 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2786   { int saw_index = 0;  int ival = (OPERAND_VALUE); \
2787     if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2788     else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2789
2790 /* internal macro added for use by the WIDE case */
2791 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2792   push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2793
2794 /* Push local variable onto the opcode stack. */
2795 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2796   { \
2797     /* have to do this since OPERAND_VALUE may have side-effects */ \
2798     int opvalue = OPERAND_VALUE; \
2799     LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2800   }
2801
2802 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2803   expand_java_return (OPERAND_TYPE##_type_node)
2804
2805 #define REM_EXPR TRUNC_MOD_EXPR
2806 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2807   expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2808
2809 #define FIELD(IS_STATIC, IS_PUT) \
2810   expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2811
2812 #define TEST(OPERAND_TYPE, CONDITION) \
2813   expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2814
2815 #define COND(OPERAND_TYPE, CONDITION) \
2816   expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2817
2818 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2819   BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2820
2821 #define BRANCH_GOTO(OPERAND_VALUE) \
2822   expand_java_goto (oldpc + OPERAND_VALUE)
2823
2824 #define BRANCH_CALL(OPERAND_VALUE) \
2825   expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2826
2827 #if 0
2828 #define BRANCH_RETURN(OPERAND_VALUE) \
2829   { \
2830     tree type = OPERAND_TYPE##_type_node; \
2831     tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2832     expand_java_ret (value); \
2833   }
2834 #endif
2835
2836 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2837           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2838           fprintf (stderr, "(not implemented)\n")
2839 #define NOT_IMPL1(OPERAND_VALUE) \
2840           fprintf (stderr, "%3d: %s ", oldpc, opname); \
2841           fprintf (stderr, "(not implemented)\n")
2842
2843 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2844
2845 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2846
2847 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2848
2849 #define STACK_SWAP(COUNT) java_stack_swap()
2850
2851 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2852 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2853 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2854
2855 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2856   PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2857
2858 #define LOOKUP_SWITCH \
2859   { jint default_offset = IMMEDIATE_s4;  jint npairs = IMMEDIATE_s4; \
2860     tree selector = pop_value (INT_type_node); \
2861     tree duplicate, label; \
2862     tree type = TREE_TYPE (selector); \
2863     flush_quick_stack (); \
2864     expand_start_case (0, selector, type, "switch statement");\
2865     push_momentary (); \
2866     while (--npairs >= 0) \
2867       { \
2868         jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2869         tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2870         TREE_TYPE (value) = type; \
2871         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2872         pushcase (value, convert, label, &duplicate); \
2873         expand_java_goto (oldpc + offset); \
2874       } \
2875     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2876     pushcase (NULL_TREE, 0, label, &duplicate); \
2877     expand_java_goto (oldpc + default_offset); \
2878     pop_momentary (); \
2879     expand_end_case (selector); \
2880   }
2881
2882 #define TABLE_SWITCH \
2883   { jint default_offset = IMMEDIATE_s4; \
2884     jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2885     tree selector = pop_value (INT_type_node); \
2886     tree duplicate, label; \
2887     tree type = TREE_TYPE (selector); \
2888     flush_quick_stack (); \
2889     expand_start_case (0, selector, type, "switch statement");\
2890     push_momentary (); \
2891     for (; low <= high; low++) \
2892       { \
2893         jint offset = IMMEDIATE_s4; \
2894         tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2895         TREE_TYPE (value) = type; \
2896         label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2897         pushcase (value, convert, label, &duplicate); \
2898         expand_java_goto (oldpc + offset); \
2899       } \
2900     label =  build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2901     pushcase (NULL_TREE, 0, label, &duplicate); \
2902     expand_java_goto (oldpc + default_offset); \
2903     pop_momentary (); \
2904     expand_end_case (selector); \
2905   }
2906
2907 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2908   { int opcode = byte_ops[PC-1]; \
2909     int method_ref_index = IMMEDIATE_u2; \
2910     int nargs; \
2911     if (IS_INTERFACE) { nargs = IMMEDIATE_u1;  (void) IMMEDIATE_u1; } \
2912     else nargs = -1; \
2913     expand_invoke (opcode, method_ref_index, nargs); \
2914   }
2915
2916 /* Handle new, checkcast, instanceof */
2917 #define OBJECT(TYPE, OP) \
2918   expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2919
2920 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2921
2922 #define ARRAY_LOAD(OPERAND_TYPE)                        \
2923   {                                                     \
2924     expand_java_arrayload( OPERAND_TYPE##_type_node );  \
2925   }
2926
2927 #define ARRAY_STORE(OPERAND_TYPE)                       \
2928   {                                                     \
2929     expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2930   }
2931
2932 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2933 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2934 #define ARRAY_NEW_PTR()                                                 \
2935     push_value (build_anewarray (get_class_constant (current_jcf,       \
2936                                                      IMMEDIATE_u2),     \
2937                                  pop_value (int_type_node)));
2938 #define ARRAY_NEW_NUM()                         \
2939   {                                             \
2940     int atype = IMMEDIATE_u1;                   \
2941     push_value (build_newarray (atype, pop_value (int_type_node)));\
2942   }
2943 #define ARRAY_NEW_MULTI()                                       \
2944   {                                                             \
2945     tree class = get_class_constant (current_jcf, IMMEDIATE_u2 );       \
2946     int  ndims = IMMEDIATE_u1;                                  \
2947     expand_java_multianewarray( class, ndims );                 \
2948   }
2949
2950 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2951   push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2952                             pop_value (OPERAND_TYPE##_type_node))));
2953
2954 #define CONVERT2(FROM_TYPE, TO_TYPE)                                     \
2955   {                                                                      \
2956     push_value (build1 (NOP_EXPR, int_type_node,                         \
2957                         (convert (TO_TYPE##_type_node,                   \
2958                                   pop_value (FROM_TYPE##_type_node))))); \
2959   }
2960
2961 #define CONVERT(FROM_TYPE, TO_TYPE)                             \
2962   {                                                             \
2963     push_value (convert (TO_TYPE##_type_node,                   \
2964                          pop_value (FROM_TYPE##_type_node)));   \
2965   }
2966
2967 /* internal macro added for use by the WIDE case 
2968    Added TREE_TYPE (decl) assignment, apbianco  */
2969 #define STORE_INTERNAL(OPTYPE, OPVALUE)                 \
2970   {                                                     \
2971     tree decl, value;                                   \
2972     int var = OPVALUE;                                  \
2973     tree type = OPTYPE;                                 \
2974     value = pop_value (type);                           \
2975     type = TREE_TYPE (value);                           \
2976     decl = find_local_variable (var, type, oldpc);      \
2977     set_local_type (var, type );                        \
2978     expand_assignment (decl, value, 0, 0);              \
2979   }
2980
2981 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2982   { \
2983     /* have to do this since OPERAND_VALUE may have side-effects */ \
2984     int opvalue = OPERAND_VALUE; \
2985     STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2986   }
2987
2988 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2989   SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2990
2991 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2992 #define SPECIAL_EXIT(IGNORED)  MONITOR_OPERATION (soft_monitorexit_node)
2993
2994 #define MONITOR_OPERATION(call)                 \
2995   {                                             \
2996     tree o = pop_value (ptr_type_node);         \
2997     tree c;                                     \
2998     flush_quick_stack ();                       \
2999     c = build_java_monitor (call, o);           \
3000     TREE_SIDE_EFFECTS (c) = 1;                  \
3001     expand_expr_stmt (c);                       \
3002   }
3003
3004 #define SPECIAL_IINC(IGNORED) \
3005   { \
3006     unsigned int local_var_index = IMMEDIATE_u1; \
3007     int ival = IMMEDIATE_s1; \
3008     expand_iinc(local_var_index, ival, oldpc); \
3009   }
3010
3011 #define SPECIAL_WIDE(IGNORED) \
3012   { \
3013     int modified_opcode = IMMEDIATE_u1; \
3014     unsigned int local_var_index = IMMEDIATE_u2; \
3015     switch (modified_opcode) \
3016       { \
3017       case OPCODE_iinc: \
3018         { \
3019           int ival = IMMEDIATE_s2; \
3020           expand_iinc (local_var_index, ival, oldpc); \
3021           break; \
3022         } \
3023       case OPCODE_iload: \
3024       case OPCODE_lload: \
3025       case OPCODE_fload: \
3026       case OPCODE_dload: \
3027       case OPCODE_aload: \
3028         { \
3029           /* duplicate code from LOAD macro */ \
3030           LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3031           break; \
3032         } \
3033       case OPCODE_istore: \
3034       case OPCODE_lstore: \
3035       case OPCODE_fstore: \
3036       case OPCODE_dstore: \
3037       case OPCODE_astore: \
3038         { \
3039           STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3040           break; \
3041         } \
3042       default: \
3043         error ("unrecogized wide sub-instruction"); \
3044       } \
3045   }
3046
3047 #define SPECIAL_THROW(IGNORED) \
3048   build_java_athrow (pop_value (throwable_type_node))
3049
3050 #define SPECIAL_BREAK NOT_IMPL1
3051 #define IMPL          NOT_IMPL
3052
3053 #include "javaop.def"
3054 #undef JAVAOP
3055    default:
3056     fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3057   }
3058   return PC;
3059 }
3060
3061 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3062    order, as specified by Java Language Specification.
3063
3064    The problem is that while expand_expr will evaluate its sub-operands in
3065    left-to-right order, for variables it will just return an rtx (i.e.
3066    an lvalue) for the variable (rather than an rvalue).  So it is possible
3067    that a later sub-operand will change the register, and when the
3068    actual operation is done, it will use the new value, when it should
3069    have used the original value.
3070
3071    We fix this by using save_expr.  This forces the sub-operand to be
3072    copied into a fresh virtual register,
3073
3074    For method invocation, we modify the arguments so that a
3075    left-to-right order evaluation is performed. Saved expressions
3076    will, in CALL_EXPR order, be reused when the call will be expanded.
3077 */
3078
3079 tree
3080 force_evaluation_order (node)
3081      tree  node;
3082 {
3083   if (flag_syntax_only)
3084     return node;
3085   if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3086     {
3087       if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3088         TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3089     }
3090   else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
3091     {
3092       tree arg, cmp;
3093
3094       if (!TREE_OPERAND (node, 1))
3095         return node;
3096
3097       /* This reverses the evaluation order. This is a desired effect. */
3098       for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1); 
3099            arg; arg = TREE_CHAIN (arg))
3100         {
3101           tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3102           cmp = (cmp == NULL_TREE ? saved :
3103                  build (COMPOUND_EXPR, void_type_node, cmp, saved));
3104           TREE_VALUE (arg) = saved;
3105         }
3106       
3107       if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3108         TREE_SIDE_EFFECTS (cmp) = 1;
3109
3110       if (cmp)
3111         {
3112           cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3113           CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3114           TREE_SIDE_EFFECTS (cmp) = 1;
3115           node = cmp;
3116         }
3117     }
3118   return node;
3119 }