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