OSDN Git Service

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