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