OSDN Git Service

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