1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
34 #include "java-tree.h"
36 #include "java-opcodes.h"
38 #include "java-except.h"
43 static void flush_quick_stack PROTO ((void));
44 static void push_value PROTO ((tree));
45 static tree pop_value PROTO ((tree));
46 static void java_stack_swap PROTO ((void));
47 static void java_stack_dup PROTO ((int, int));
48 static tree build_java_athrow PROTO ((tree));
49 static void build_java_jsr PROTO ((tree, tree));
50 static void build_java_ret PROTO ((tree));
51 static void expand_java_multianewarray PROTO ((tree, int));
52 static void expand_java_arraystore PROTO ((tree));
53 static void expand_java_arrayload PROTO ((tree));
54 static void expand_java_array_length PROTO ((void));
55 static tree build_java_monitor PROTO ((tree, tree));
56 static void expand_java_pushc PROTO ((int, tree));
57 static void expand_java_return PROTO ((tree));
58 static void expand_java_NEW PROTO ((tree));
59 static void expand_java_INSTANCEOF PROTO ((tree));
60 static void expand_java_CHECKCAST PROTO ((tree));
61 static void expand_iinc PROTO ((unsigned int, int, int));
62 static void expand_java_binop PROTO ((tree, enum tree_code));
63 static void note_label PROTO ((int, int));
64 static void expand_compare PROTO ((enum tree_code, tree, tree, int));
65 static void expand_test PROTO ((enum tree_code, tree, int));
66 static void expand_cond PROTO ((enum tree_code, tree, int));
67 static void expand_java_goto PROTO ((int));
69 static void expand_java_call PROTO ((int, int));
70 static void expand_java_ret PROTO ((tree));
72 static tree pop_arguments PROTO ((tree));
73 static void expand_invoke PROTO ((int, int, int));
74 static void expand_java_field_op PROTO ((int, int, int));
75 static void java_push_constant_from_pool PROTO ((struct JCF *, int));
77 static tree operand_type[59];
78 extern struct obstack permanent_obstack;
81 init_expr_processing()
83 operand_type[21] = operand_type[54] = int_type_node;
84 operand_type[22] = operand_type[55] = long_type_node;
85 operand_type[23] = operand_type[56] = float_type_node;
86 operand_type[24] = operand_type[57] = double_type_node;
87 operand_type[25] = operand_type[58] = ptr_type_node;
90 /* We store the stack state in two places:
91 Within a basic block, we use the quick_stack, which is a
92 pushdown list (TREE_LISTs) of expression nodes.
93 This is the top part of the stack; below that we use find_stack_slot.
94 At the end of a basic block, the quick_stack must be flushed
95 to the stack slot array (as handled by find_stack_slot).
96 Using quick_stack generates better code (especially when
97 compiled without optimization), because we do not have to
98 explicitly store and load trees to temporary variables.
100 If a variable is on the quick stack, it means the value of variable
101 when the quick stack was last flushed. Conceptually, flush_quick_stack
102 saves all the the quick_stack elements in parellel. However, that is
103 complicated, so it actually saves them (i.e. copies each stack value
104 to is home virtual register) from low indexes. This allows a quick_stack
105 element at index i (counting from the bottom of stack the) to references
106 slot virtuals for register that are >= i, but not those that are deeper.
107 This convention makes most operations easier. For example iadd works
108 even when the stack contains (reg[0], reg[1]): It results in the
109 stack containing (reg[0]+reg[1]), which is OK. However, some stack
110 operations are more complicated. For example dup given a stack
111 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
112 the convention, since stack value 1 would refer to a register with
113 lower index (reg[0]), which flush_quick_stack does not safely handle.
114 So dup cannot just add an extra element to the quick_stack, but iadd can.
117 tree quick_stack = NULL_TREE;
119 /* A free-list of unused permamnet TREE_LIST nodes. */
120 tree tree_list_free_list = NULL_TREE;
122 /* The stack pointer of the Java virtual machine.
123 This does include the size of the quick_stack. */
127 unsigned char *linenumber_table;
128 int linenumber_count;
131 truthvalue_conversion (expr)
134 /* It is simpler and generates better code to have only TRUTH_*_EXPR
135 or comparison expressions as truth values at this level.
137 This function should normally be identity for Java. */
139 switch (TREE_CODE (expr))
142 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
143 case TRUTH_ANDIF_EXPR:
144 case TRUTH_ORIF_EXPR:
151 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
154 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
156 /* are these legal? XXX JH */
161 /* These don't change whether an object is non-zero or zero. */
162 return truthvalue_conversion (TREE_OPERAND (expr, 0));
165 /* Distribute the conversion into the arms of a COND_EXPR. */
166 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
167 truthvalue_conversion (TREE_OPERAND (expr, 1)),
168 truthvalue_conversion (TREE_OPERAND (expr, 2))));
171 /* If this is widening the argument, we can ignore it. */
172 if (TYPE_PRECISION (TREE_TYPE (expr))
173 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
174 return truthvalue_conversion (TREE_OPERAND (expr, 0));
175 /* fall through to default */
178 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
182 #ifdef JAVA_USE_HANDLES
183 /* Given a pointer to a handle, get a pointer to an object. */
189 tree field, handle_type;
190 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
191 handle_type = TREE_TYPE (expr);
192 field = TYPE_FIELDS (handle_type);
193 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
198 /* Save any stack slots that happen to be in the quick_stack into their
199 home virtual register slots.
201 The copy order is from low stack index to high, to support the invariant
202 that the expression for a slot may contain decls for stack slots with
203 higher (or the same) index, but not lower. */
208 int stack_index = stack_pointer;
209 register tree prev, cur, next;
211 /* First reverse the quick_stack, and count the number of slots it has. */
212 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
214 next = TREE_CHAIN (cur);
215 TREE_CHAIN (cur) = prev;
217 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
221 while (quick_stack != NULL_TREE)
224 tree node = quick_stack, type;
225 quick_stack = TREE_CHAIN (node);
226 TREE_CHAIN (node) = tree_list_free_list;
227 tree_list_free_list = node;
228 node = TREE_VALUE (node);
229 type = TREE_TYPE (node);
231 decl = find_stack_slot (stack_index, type);
233 expand_assignment (decl, node, 0, 0);
234 stack_index += 1 + TYPE_IS_WIDE (type);
243 type = promote_type (type);
244 n_words = 1 + TYPE_IS_WIDE (type);
245 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
246 fatal ("stack overflow");
247 stack_type_map[stack_pointer++] = type;
249 while (--n_words >= 0)
250 stack_type_map[stack_pointer++] = TYPE_SECOND;
257 tree type = TREE_TYPE (value);
258 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
260 type = promote_type (type);
261 value = convert (type, value);
264 if (tree_list_free_list == NULL_TREE)
265 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
268 tree node = tree_list_free_list;
269 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
270 TREE_VALUE (node) = value;
271 TREE_CHAIN (node) = quick_stack;
276 /* Pop a type from the type stack.
277 TYPE is the expected type. Return the actual type, which must be
278 convertible to TYPE, otherwise NULL_TREE is returned. */
286 if (TREE_CODE (type) == RECORD_TYPE)
287 type = promote_type (type);
288 n_words = 1 + TYPE_IS_WIDE (type);
289 if (stack_pointer < n_words)
290 fatal ("stack underflow");
291 while (--n_words > 0)
293 if (stack_type_map[--stack_pointer] != void_type_node)
294 fatal ("Invalid multi-word value on type stack");
296 t = stack_type_map[--stack_pointer];
297 if (type == NULL_TREE || t == type)
299 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
300 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
302 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
304 if (type == ptr_type_node || type == object_ptr_type_node)
306 else if (t == ptr_type_node) /* Special case for null reference. */
308 else if (can_widen_reference_to (t, type))
310 /* This is a kludge, but matches what Sun's verifier does.
311 It can be tricked, but is safe as long as type errors
312 (i.e. interface method calls) are caught at run-time. */
313 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
314 && t == object_ptr_type_node)
320 /* Pop a type from the type stack.
321 TYPE is the expected type. Return the actual type, which must be
322 convertible to TYPE, otherwise call error. */
328 tree t = pop_type_0 (type);
331 error ("unexpected type on stack");
335 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
336 Handles array types and interfaces. */
339 can_widen_reference_to (source_type, target_type)
340 tree source_type, target_type;
342 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
345 /* Get rid of pointers */
346 if (TREE_CODE (source_type) == POINTER_TYPE)
347 source_type = TREE_TYPE (source_type);
348 if (TREE_CODE (target_type) == POINTER_TYPE)
349 target_type = TREE_TYPE (target_type);
351 if (source_type == target_type)
355 source_type = HANDLE_TO_CLASS_TYPE (source_type);
356 target_type = HANDLE_TO_CLASS_TYPE (target_type);
357 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
359 HOST_WIDE_INT source_length, target_length;
360 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
362 target_length = java_array_type_length (target_type);
363 if (target_length >= 0)
365 source_length = java_array_type_length (source_type);
366 if (source_length != target_length)
369 source_type = TYPE_ARRAY_ELEMENT (source_type);
370 target_type = TYPE_ARRAY_ELEMENT (target_type);
371 if (source_type == target_type)
373 if (TREE_CODE (source_type) != POINTER_TYPE
374 || TREE_CODE (target_type) != POINTER_TYPE)
376 return can_widen_reference_to (source_type, target_type);
380 int source_depth = class_depth (source_type);
381 int target_depth = class_depth (target_type);
383 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
385 /* target_type is OK if source_type or source_type ancestors
386 implement target_type. We handle multiple sub-interfaces */
388 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
389 int n = TREE_VEC_LENGTH (basetype_vec), i;
390 for (i=0 ; i < n; i++)
391 if (can_widen_reference_to
392 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
399 for ( ; source_depth > target_depth; source_depth--)
401 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
403 return source_type == target_type;
412 type = pop_type (type);
415 tree node = quick_stack;
416 quick_stack = TREE_CHAIN (quick_stack);
417 TREE_CHAIN (node) = tree_list_free_list;
418 tree_list_free_list = node;
419 node = TREE_VALUE (node);
423 return find_stack_slot (stack_pointer, promote_type (type));
427 /* Pop and discrad the top COUNT stack slots. */
430 java_stack_pop (count)
436 if (stack_pointer == 0)
437 fatal ("stack underflow");
438 type = stack_type_map[stack_pointer - 1];
439 if (type == TYPE_SECOND)
442 if (stack_pointer == 1 || count <= 0)
443 fatal ("stack underflow");
444 type = stack_type_map[stack_pointer - 2];
446 val = pop_value (type);
451 /* Implement the 'swap' operator (to swap two top stack slots). */
460 if (stack_pointer < 2
461 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
462 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
463 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
464 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
465 fatal ("bad stack swap");
467 flush_quick_stack ();
468 decl1 = find_stack_slot (stack_pointer - 1, type1);
469 decl2 = find_stack_slot (stack_pointer - 2, type2);
470 temp = copy_to_reg (DECL_RTL (decl1));
471 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
472 emit_move_insn (DECL_RTL (decl2), temp);
473 stack_type_map[stack_pointer - 1] = type2;
474 stack_type_map[stack_pointer - 2] = type1;
478 java_stack_dup (size, offset)
481 int low_index = stack_pointer - size - offset;
484 error ("stack underflow - dup* operation");
486 flush_quick_stack ();
488 stack_pointer += size;
489 dst_index = stack_pointer;
491 for (dst_index = stack_pointer; --dst_index >= low_index; )
494 int src_index = dst_index - size;
495 if (src_index < low_index)
496 src_index = dst_index + size + offset;
497 type = stack_type_map [src_index];
498 if (type == TYPE_SECOND)
500 if (src_index <= low_index)
501 fatal ("dup operation splits 64-bit number");
502 stack_type_map[dst_index] = type;
503 src_index--; dst_index--;
504 type = stack_type_map[src_index];
505 if (! TYPE_IS_WIDE (type))
506 fatal ("internal error - dup operation");
508 else if (TYPE_IS_WIDE (type))
509 fatal ("internal error - dup operation");
510 if (src_index != dst_index)
512 tree src_decl = find_stack_slot (src_index, type);
513 tree dst_decl = find_stack_slot (dst_index, type);
514 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
515 stack_type_map[dst_index] = type;
520 /* Calls _Jv_Throw. Discard the contents of the value stack. */
523 build_java_athrow (node)
528 call = build (CALL_EXPR,
530 build_address_of (throw_node),
531 build_tree_list (NULL_TREE, node),
533 TREE_SIDE_EFFECTS (call) = 1;
534 expand_expr_stmt (call);
535 java_stack_pop (stack_pointer);
538 /* Implementation for jsr/ret */
541 build_java_jsr (where, ret)
545 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
546 push_value (ret_label);
547 flush_quick_stack ();
553 build_java_ret (location)
556 expand_computed_goto (location);
559 /* Implementation of operations on array: new, load, store, length */
561 /* Array core info access macros */
563 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
564 size_binop (CEIL_DIV_EXPR, \
566 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
567 size_int (BITS_PER_UNIT))
570 decode_newarray_type (atype)
575 case 4: return boolean_type_node;
576 case 5: return char_type_node;
577 case 6: return float_type_node;
578 case 7: return double_type_node;
579 case 8: return byte_type_node;
580 case 9: return short_type_node;
581 case 10: return int_type_node;
582 case 11: return long_type_node;
583 default: return NULL_TREE;
587 /* Map primitive type to the code used by OPCODE_newarray. */
590 encode_newarray_type (type)
593 if (type == boolean_type_node)
595 else if (type == char_type_node)
597 else if (type == float_type_node)
599 else if (type == double_type_node)
601 else if (type == byte_type_node)
603 else if (type == short_type_node)
605 else if (type == int_type_node)
607 else if (type == long_type_node)
610 fatal ("Can't compute type code - patch_newarray");
613 /* Build a call to _Jv_ThrowBadArrayIndex(), the
614 ArrayIndexOfBoundsException exception handler. */
617 build_java_throw_out_of_bounds_exception (index)
620 tree node = build (CALL_EXPR, int_type_node,
621 build_address_of (soft_badarrayindex_node),
622 build_tree_list (NULL_TREE, index), NULL_TREE);
623 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
627 /* Return the length of an array. Doesn't perform any checking on the nature
628 or value of the array NODE. May be used to implement some bytecodes. */
631 build_java_array_length_access (node)
634 tree type = TREE_TYPE (node);
635 HOST_WIDE_INT length;
636 if (!is_array_type_p (type))
637 fatal ("array length on a non-array reference");
638 length = java_array_type_length (type);
640 return build_int_2 (length, 0);
641 return fold (build1 (INDIRECT_REF,
643 fold (build (PLUS_EXPR, ptr_type_node,
645 JAVA_ARRAY_LENGTH_OFFSET(node)))));
648 /* Optionally checks an array against the NULL pointer, eventually throwing a
649 NullPointerException. It could replace signal handling, but tied to NULL.
650 ARG1: the pointer to check, ARG2: the expression to use if
651 the pointer is non-null and ARG3 the type that should be returned. */
654 build_java_arraynull_check (node, expr, type)
655 tree node ATTRIBUTE_UNUSED;
657 tree type ATTRIBUTE_UNUSED;
660 static int java_array_access_throws_null_exception = 0;
662 if (java_array_access_throws_null_exception)
663 return (build (COND_EXPR,
665 build (EQ_EXPR, int_type_node, node, null_pointer_node),
666 build_java_athrow (node), expr ));
673 java_array_data_offset (array)
676 tree array_type = TREE_TYPE (TREE_TYPE (array));
677 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
678 if (data_fld == NULL_TREE)
679 return size_in_bytes (array_type);
681 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
685 /* Implement array indexing (either as l-value or r-value).
686 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
687 Optionally performs bounds checking and/or test to NULL.
688 At this point, ARRAY should have been verified as an array. */
691 build_java_arrayaccess (array, type, index)
692 tree array, type, index;
694 tree arith, node, throw = NULL_TREE;
696 arith = fold (build (PLUS_EXPR, int_type_node,
697 java_array_data_offset (array),
698 fold (build (MULT_EXPR, int_type_node,
699 index, size_in_bytes(type)))));
701 if (flag_bounds_check)
704 * (unsigned jint) INDEX >= (unsigned jint) LEN
705 * && throw ArrayIndexOutOfBoundsException.
706 * Note this is equivalent to and more efficient than:
707 * INDEX < 0 || INDEX >= LEN && throw ... */
709 tree len = build_java_array_length_access (array);
710 TREE_TYPE (len) = unsigned_int_type_node;
711 test = fold (build (GE_EXPR, boolean_type_node,
712 convert (unsigned_int_type_node, index),
714 if (! integer_zerop (test))
716 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
717 build_java_throw_out_of_bounds_exception (index));
718 /* allows expansion within COMPOUND */
719 TREE_SIDE_EFFECTS( throw ) = 1;
723 node = build1 (INDIRECT_REF, type,
724 fold (build (PLUS_EXPR, ptr_type_node,
726 (throw ? build (COMPOUND_EXPR, int_type_node,
730 return (fold (build_java_arraynull_check (array, node, type)));
733 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
734 ARRAY_NODE. This function is used to retrieve something less vague than
735 a pointer type when indexing the first dimension of something like [[<t>.
736 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
738 As a side effect, it also makes sure that ARRAY_NODE is an array. */
741 build_java_check_indexed_type (array_node, indexed_type)
747 if (!is_array_type_p (TREE_TYPE (array_node)))
748 fatal ("array indexing on a non-array reference");
750 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
752 if (indexed_type == ptr_type_node )
753 return promote_type (elt_type);
755 /* BYTE/BOOLEAN store and load are used for both type */
756 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
757 return boolean_type_node;
759 if (indexed_type != elt_type )
760 fatal ("type array element mismatch");
765 /* newarray triggers a call to _Jv_NewArray. This function should be called
766 with an integer code (the type of array to create) and get from the stack
767 the size of the dimmension. */
770 build_newarray (atype_value, length)
774 tree type = build_java_array_type (decode_newarray_type (atype_value),
775 TREE_CODE (length) == INTEGER_CST
776 ? TREE_INT_CST_LOW (length)
778 return build (CALL_EXPR, promote_type (type),
779 build_address_of (soft_newarray_node),
780 tree_cons (NULL_TREE,
781 build_int_2 (atype_value, 0),
782 build_tree_list (NULL_TREE, length)),
786 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
790 build_anewarray (class_type, length)
794 tree type = build_java_array_type (class_type,
795 TREE_CODE (length) == INTEGER_CST
796 ? TREE_INT_CST_LOW (length)
798 return build (CALL_EXPR, promote_type (type),
799 build_address_of (soft_anewarray_node),
800 tree_cons (NULL_TREE, length,
801 tree_cons (NULL_TREE, build_class_ref (class_type),
802 build_tree_list (NULL_TREE,
803 null_pointer_node))),
807 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
810 build_new_array (type, length)
814 if (JPRIMITIVE_TYPE_P (type))
815 return build_newarray (encode_newarray_type (type), length);
817 return build_anewarray (TREE_TYPE (type), length);
820 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
821 class pointer, a number of dimensions and the matching number of
822 dimensions. The argument list is NULL terminated. */
825 expand_java_multianewarray (class_type, ndim)
830 tree args = build_tree_list( NULL_TREE, null_pointer_node );
832 for( i = 0; i < ndim; i++ )
833 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
835 push_value (build (CALL_EXPR,
836 promote_type (class_type),
837 build_address_of (soft_multianewarray_node),
838 tree_cons (NULL_TREE, build_class_ref (class_type),
839 tree_cons (NULL_TREE,
840 build_int_2 (ndim, 0), args )),
844 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
845 ARRAY is an array type. May expand some bound checking and NULL
846 pointer checking. RHS_TYPE_NODE we are going to store. In the case
847 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
848 INT. In those cases, we make the convertion.
850 if ARRAy is a reference type, the assignment is checked at run-time
851 to make sure that the RHS can be assigned to the array element
852 type. It is not necessary to generate this code if ARRAY is final. */
855 expand_java_arraystore (rhs_type_node)
858 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
859 && TYPE_PRECISION (rhs_type_node) <= 32) ?
860 int_type_node : rhs_type_node);
861 tree index = pop_value (int_type_node);
862 tree array = pop_value (ptr_type_node);
864 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
866 flush_quick_stack ();
868 index = save_expr (index);
869 array = save_expr (array);
871 if (TREE_CODE (rhs_type_node) == POINTER_TYPE
872 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
874 tree check = build (CALL_EXPR, void_type_node,
875 build_address_of (soft_checkarraystore_node),
876 tree_cons (NULL_TREE, array,
877 build_tree_list (NULL_TREE, rhs_node)),
879 TREE_SIDE_EFFECTS (check) = 1;
880 expand_expr_stmt (check);
883 expand_assignment (build_java_arrayaccess (array,
889 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
890 sure that LHS is an array type. May expand some bound checking and NULL
892 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
893 BOOLEAN/SHORT, we push a promoted type back to the stack.
897 expand_java_arrayload (lhs_type_node )
901 tree index_node = pop_value (int_type_node);
902 tree array_node = pop_value (ptr_type_node);
904 index_node = save_expr (index_node);
905 array_node = save_expr (array_node);
906 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
908 load_node = build_java_arrayaccess (array_node,
912 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
913 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
914 push_value (load_node);
917 /* Expands .length. Makes sure that we deal with and array and may expand
918 a NULL check on the array object. */
921 expand_java_array_length ()
923 tree array = pop_value (ptr_type_node);
924 tree length = build_java_array_length_access (array);
926 push_value (build_java_arraynull_check (array, length, int_type_node));
929 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
930 either soft_monitorenter_node or soft_monitorexit_node. */
933 build_java_monitor (call, object)
937 return (build (CALL_EXPR,
939 build_address_of (call),
940 build_tree_list (NULL_TREE, object),
944 /* Emit code for one of the PUSHC instructions. */
947 expand_java_pushc (ival, type)
952 if (type == ptr_type_node && ival == 0)
953 value = null_pointer_node;
954 else if (type == int_type_node || type == long_type_node)
956 value = build_int_2 (ival, ival < 0 ? -1 : 0);
957 TREE_TYPE (value) = type;
959 else if (type == float_type_node || type == double_type_node)
962 #ifdef REAL_ARITHMETIC
963 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
967 value = build_real (type, x);
970 fatal ("internal error in expand_java_pushc");
975 expand_java_return (type)
978 if (type == void_type_node)
979 expand_null_return ();
982 tree retval = pop_value (type);
983 tree res = DECL_RESULT (current_function_decl);
984 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
985 TREE_SIDE_EFFECTS (retval) = 1;
986 expand_return (retval);
991 build_address_of (value)
994 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
998 expand_java_NEW (type)
1001 if (! CLASS_LOADED_P (type))
1002 load_class (type, 1);
1003 layout_class_methods (type);
1004 push_value (build (CALL_EXPR, promote_type (type),
1005 build_address_of (alloc_object_node),
1006 tree_cons (NULL_TREE, build_class_ref (type),
1007 build_tree_list (NULL_TREE,
1008 size_in_bytes (type))),
1013 expand_java_INSTANCEOF (type)
1016 tree value = pop_value (object_ptr_type_node);
1017 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
1018 build_address_of (soft_instanceof_node),
1019 tree_cons (NULL_TREE, value,
1020 build_tree_list (NULL_TREE,
1021 build_class_ref (type))),
1027 expand_java_CHECKCAST (type)
1030 tree value = pop_value (ptr_type_node);
1031 value = build (CALL_EXPR, promote_type (type),
1032 build_address_of (soft_checkcast_node),
1033 tree_cons (NULL_TREE, build_class_ref (type),
1034 build_tree_list (NULL_TREE, value)),
1040 expand_iinc (local_var_index, ival, pc)
1041 unsigned int local_var_index;
1045 tree local_var, res;
1046 tree constant_value;
1048 flush_quick_stack ();
1049 local_var = find_local_variable (local_var_index, int_type_node, pc);
1050 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1051 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1052 expand_assignment (local_var, res, 0, 0);
1057 build_java_soft_divmod (op, type, op1, op2)
1059 tree type, op1, op2;
1062 tree arg1 = convert (type, op1);
1063 tree arg2 = convert (type, op2);
1065 if (type == int_type_node)
1069 case TRUNC_DIV_EXPR:
1070 call = soft_idiv_node;
1072 case TRUNC_MOD_EXPR:
1073 call = soft_irem_node;
1079 else if (type == long_type_node)
1083 case TRUNC_DIV_EXPR:
1084 call = soft_ldiv_node;
1086 case TRUNC_MOD_EXPR:
1087 call = soft_lrem_node;
1095 fatal ("Internal compiler error in build_java_soft_divmod");
1097 call = build (CALL_EXPR, type,
1098 build_address_of (call),
1099 tree_cons (NULL_TREE, arg1,
1100 build_tree_list (NULL_TREE, arg2)),
1107 build_java_binop (op, type, arg1, arg2)
1109 tree type, arg1, arg2;
1116 tree u_type = unsigned_type (type);
1117 arg1 = convert (u_type, arg1);
1118 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1119 return convert (type, arg1);
1123 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1124 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1127 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1128 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1129 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1131 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1132 boolean_type_node, arg1, arg2));
1133 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1134 tree second_compare = fold (build (COND_EXPR, int_type_node,
1135 ifexp2, integer_zero_node,
1136 op == COMPARE_L_EXPR
1137 ? integer_negative_one_node
1138 : integer_one_node));
1139 return fold (build (COND_EXPR, int_type_node, ifexp1,
1140 op == COMPARE_L_EXPR ? integer_one_node
1141 : integer_negative_one_node,
1145 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1147 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1148 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1149 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1150 ifexp2, integer_one_node,
1151 integer_zero_node));
1152 return fold (build (COND_EXPR, int_type_node,
1153 ifexp1, integer_negative_one_node, second_compare));
1155 case TRUNC_DIV_EXPR:
1156 case TRUNC_MOD_EXPR:
1157 if (TREE_CODE (type) == REAL_TYPE
1158 && op == TRUNC_MOD_EXPR)
1161 if (type != double_type_node)
1163 arg1 = convert (double_type_node, arg1);
1164 arg2 = convert (double_type_node, arg2);
1166 call = build (CALL_EXPR, double_type_node,
1167 build_address_of (soft_fmod_node),
1168 tree_cons (NULL_TREE, arg1,
1169 build_tree_list (NULL_TREE, arg2)),
1171 if (type != double_type_node)
1172 call = convert (type, call);
1176 if (TREE_CODE (type) == INTEGER_TYPE
1177 && flag_use_divide_subroutine
1178 && ! flag_syntax_only)
1179 return build_java_soft_divmod (op, type, arg1, arg2);
1184 return fold (build (op, type, arg1, arg2));
1188 expand_java_binop (type, op)
1189 tree type; enum tree_code op;
1199 rtype = int_type_node;
1200 rarg = pop_value (rtype);
1203 rarg = pop_value (rtype);
1205 larg = pop_value (ltype);
1206 push_value (build_java_binop (op, type, larg, rarg));
1209 /* Lookup the field named NAME in *TYPEP or its super classes.
1210 If not found, return NULL_TREE.
1211 (If the *TYPEP is not found, return error_mark_node.)
1212 If found, return the FIELD_DECL, and set *TYPEP to the
1213 class containing the field. */
1216 lookup_field (typep, name)
1220 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1222 load_class (*typep, 1);
1223 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1224 return error_mark_node;
1228 tree field, basetype_vec;
1231 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1232 if (DECL_NAME (field) == name)
1235 /* Process implemented interfaces. */
1236 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1237 n = TREE_VEC_LENGTH (basetype_vec);
1238 for (i = 0; i < n; i++)
1240 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1241 if ((field = lookup_field (&t, name)))
1244 *typep = CLASSTYPE_SUPER (*typep);
1249 /* Look up the field named NAME in object SELF_VALUE,
1250 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1251 SELF_VALUE is NULL_TREE if looking for a static field. */
1254 build_field_ref (self_value, self_class, name)
1255 tree self_value, self_class, name;
1257 tree base_class = self_class;
1258 tree field_decl = lookup_field (&base_class, name);
1259 if (field_decl == NULL_TREE)
1261 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1262 return error_mark_node;
1264 if (self_value == NULL_TREE)
1266 return build_static_field_ref (field_decl);
1270 tree base_handle_type = promote_type (base_class);
1271 if (base_handle_type != TREE_TYPE (self_value))
1272 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1273 #ifdef JAVA_USE_HANDLES
1274 self_value = unhand_expr (self_value);
1276 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1278 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1279 self_value, field_decl));
1289 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1290 name = get_identifier (buf);
1291 if (IDENTIFIER_LOCAL_VALUE (name))
1292 return IDENTIFIER_LOCAL_VALUE (name);
1295 /* The type of the address of a label is return_address_type_node. */
1296 tree decl = create_label_decl (name);
1297 LABEL_PC (decl) = pc;
1299 return pushdecl (decl);
1303 /* Generate a unique name for the purpose of loops and switches
1304 labels, and try-catch-finally blocks label or temporary variables. */
1309 static int l_number = 0;
1311 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1313 return get_identifier (buff);
1317 create_label_decl (name)
1321 push_obstacks (&permanent_obstack, &permanent_obstack);
1322 decl = build_decl (LABEL_DECL, name,
1323 TREE_TYPE (return_address_type_node));
1325 DECL_CONTEXT (decl) = current_function_decl;
1326 DECL_IGNORED_P (decl) = 1;
1330 /* This maps a bytecode offset (PC) to various flags. */
1331 char *instruction_bits;
1334 note_label (current_pc, target_pc)
1335 int current_pc ATTRIBUTE_UNUSED, target_pc;
1337 lookup_label (target_pc);
1338 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1341 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1342 where CONDITION is one of one the compare operators. */
1345 expand_compare (condition, value1, value2, target_pc)
1346 enum tree_code condition;
1347 tree value1, value2;
1350 tree target = lookup_label (target_pc);
1351 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1352 expand_start_cond (truthvalue_conversion (cond), 0);
1353 expand_goto (target);
1357 /* Emit code for a TEST-type opcode. */
1360 expand_test (condition, type, target_pc)
1361 enum tree_code condition;
1365 tree value1, value2;
1366 flush_quick_stack ();
1367 value1 = pop_value (type);
1368 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1369 expand_compare (condition, value1, value2, target_pc);
1372 /* Emit code for a COND-type opcode. */
1375 expand_cond (condition, type, target_pc)
1376 enum tree_code condition;
1380 tree value1, value2;
1381 flush_quick_stack ();
1382 /* note: pop values in opposite order */
1383 value2 = pop_value (type);
1384 value1 = pop_value (type);
1385 /* Maybe should check value1 and value2 for type compatibility ??? */
1386 expand_compare (condition, value1, value2, target_pc);
1390 expand_java_goto (target_pc)
1393 tree target_label = lookup_label (target_pc);
1394 flush_quick_stack ();
1395 expand_goto (target_label);
1400 expand_java_call (target_pc, return_address)
1401 int target_pc, return_address;
1403 tree target_label = lookup_label (target_pc);
1404 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1406 flush_quick_stack ();
1407 expand_goto (target_label);
1411 expand_java_ret (return_address)
1412 tree return_address ATTRIBUTE_UNUSED;
1414 warning ("ret instruction not implemented");
1416 tree target_label = lookup_label (target_pc);
1417 flush_quick_stack ();
1418 expand_goto (target_label);
1423 /* Recursive helper function to pop argument types during verifiation. */
1426 pop_argument_types (arg_types)
1429 if (arg_types == end_params_node)
1431 if (TREE_CODE (arg_types) == TREE_LIST)
1433 pop_argument_types (TREE_CHAIN (arg_types));
1434 pop_type (TREE_VALUE (arg_types));
1441 pop_arguments (arg_types)
1444 if (arg_types == end_params_node)
1446 if (TREE_CODE (arg_types) == TREE_LIST)
1448 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1449 tree type = TREE_VALUE (arg_types);
1450 tree arg = pop_value (type);
1451 if (PROMOTE_PROTOTYPES
1452 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1453 && INTEGRAL_TYPE_P (type))
1454 arg = convert (integer_type_node, arg);
1455 return tree_cons (NULL_TREE, arg, tail);
1460 /* Build an expression to initialize the class CLAS.
1461 if EXPR is non-NULL, returns an expression to first call the initializer
1462 (if it is needed) and then calls EXPR. */
1465 build_class_init (clas, expr)
1469 if (inherits_from_p (current_class, clas))
1471 init = build (CALL_EXPR, void_type_node,
1472 build_address_of (soft_initclass_node),
1473 build_tree_list (NULL_TREE, build_class_ref (clas)),
1475 TREE_SIDE_EFFECTS (init) = 1;
1476 if (expr != NULL_TREE)
1478 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1479 TREE_SIDE_EFFECTS (expr) = 1;
1485 static tree methods_ident = NULL_TREE;
1486 static tree ncode_ident = NULL_TREE;
1487 tree dtable_ident = NULL_TREE;
1490 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1491 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1492 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1495 if (is_compiled_class (self_type))
1497 make_decl_rtl (method, NULL, 1);
1498 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1502 /* We don't know whether the method has been (statically) compiled.
1503 Compile this code to get a reference to the method's code:
1505 SELF_TYPE->methods[METHOD_INDEX].ncode
1507 This is guaranteed to work (assuming SELF_TYPE has
1508 been initialized), since if the method is not compiled yet,
1509 its ncode points to a trampoline that forces compilation. */
1511 int method_index = 0;
1513 tree ref = build_class_ref (self_type);
1514 ref = build1 (INDIRECT_REF, class_type_node, ref);
1515 if (ncode_ident == NULL_TREE)
1516 ncode_ident = get_identifier ("ncode");
1517 if (methods_ident == NULL_TREE)
1518 methods_ident = get_identifier ("methods");
1519 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1520 lookup_field (&class_type_node, methods_ident));
1521 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1522 ; meth = TREE_CHAIN (meth))
1526 if (meth == NULL_TREE)
1527 fatal ("method '%s' not found in class",
1528 IDENTIFIER_POINTER (DECL_NAME (method)));
1531 method_index *= int_size_in_bytes (method_type_node);
1532 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1533 ref, build_int_2 (method_index, 0)));
1534 ref = build1 (INDIRECT_REF, method_type_node, ref);
1535 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1537 lookup_field (&method_type_node, ncode_ident));
1543 invoke_build_dtable (is_invoke_interface, arg_list)
1544 int is_invoke_interface;
1547 tree dtable, objectref;
1549 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1551 /* If we're dealing with interfaces and if the objectref
1552 argument is an array then get the dispatch table of the class
1553 Object rather than the one from the objectref. */
1554 objectref = (is_invoke_interface
1555 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1556 object_type_node : TREE_VALUE (arg_list));
1558 if (dtable_ident == NULL_TREE)
1559 dtable_ident = get_identifier ("vtable");
1560 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1561 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1562 lookup_field (&object_type_node, dtable_ident));
1568 build_invokevirtual (dtable, method)
1569 tree dtable, method;
1572 tree nativecode_ptr_ptr_type_node
1573 = build_pointer_type (nativecode_ptr_type_node);
1574 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1575 /* Add one to skip "class" field of dtable, and one to skip unused
1576 vtable entry (for C++ compatibility). */
1579 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1580 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1581 dtable, build_int_2 (method_index, 0)));
1582 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1588 build_invokeinterface (dtable, method_name, method_signature)
1589 tree dtable, method_name, method_signature;
1591 static tree class_ident = NULL_TREE;
1594 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1595 ensure that the selected method exists, is public and not
1596 abstract nor static. */
1598 if (class_ident == NULL_TREE)
1599 class_ident = get_identifier ("class");
1601 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1602 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1603 lookup_field (&dtable_type, class_ident));
1604 lookup_arg = build_tree_list (NULL_TREE,
1607 (IDENTIFIER_POINTER(method_signature),
1608 IDENTIFIER_LENGTH(method_signature)))));
1609 lookup_arg = tree_cons (NULL_TREE, dtable,
1610 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1612 return build (CALL_EXPR, ptr_type_node,
1613 build_address_of (soft_lookupinterfacemethod_node),
1614 lookup_arg, NULL_TREE);
1617 /* Expand one of the invoke_* opcodes.
1618 OCPODE is the specific opcode.
1619 METHOD_REF_INDEX is an index into the constant pool.
1620 NARGS is the number of arguments, or -1 if not specified. */
1623 expand_invoke (opcode, method_ref_index, nargs)
1625 int method_ref_index;
1626 int nargs ATTRIBUTE_UNUSED;
1628 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1629 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1630 tree self_type = get_class_constant
1631 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1632 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1633 tree call, func, method, arg_list, method_type;
1635 if (! CLASS_LOADED_P (self_type))
1637 load_class (self_type, 1);
1638 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1639 fatal ("failed to find class '%s'", self_name);
1641 layout_class_methods (self_type);
1643 if (method_name == init_identifier_node)
1644 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1647 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1648 method_name, method_signature);
1649 if (method == NULL_TREE)
1651 error ("Class '%s' has no method named '%s' matching signature '%s'",
1653 IDENTIFIER_POINTER (method_name),
1654 IDENTIFIER_POINTER (method_signature));
1656 /* Invoke static can't invoke static/abstract method */
1657 else if (opcode == OPCODE_invokestatic)
1659 if (!METHOD_STATIC (method))
1661 error ("invokestatic on non static method");
1664 else if (METHOD_ABSTRACT (method))
1666 error ("invokestatic on abstract method");
1672 if (METHOD_STATIC (method))
1674 error ("invoke[non-static] on static method");
1679 if (method == NULL_TREE)
1681 method_type = get_type_from_signature (method_signature);
1682 pop_arguments (TYPE_ARG_TYPES (method_type));
1683 if (opcode != OPCODE_invokestatic)
1684 pop_type (self_type);
1685 method_type = promote_type (TREE_TYPE (method_type));
1686 push_value (convert (method_type, integer_zero_node));
1690 method_type = TREE_TYPE (method);
1691 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1692 flush_quick_stack ();
1695 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1696 || (opcode == OPCODE_invokevirtual
1697 && (METHOD_PRIVATE (method)
1698 || METHOD_FINAL (method)
1699 || CLASS_FINAL (TYPE_NAME (self_type)))))
1700 func = build_known_method_ref (method, method_type, self_type,
1701 method_signature, arg_list);
1704 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1706 if (opcode == OPCODE_invokevirtual)
1707 func = build_invokevirtual (dtable, method);
1709 func = build_invokeinterface (dtable, method_name, method_signature);
1711 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1712 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1713 TREE_SIDE_EFFECTS (call) = 1;
1715 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1716 expand_expr_stmt (call);
1720 flush_quick_stack ();
1725 /* Expand an operation to extract from or store into a field.
1726 IS_STATIC is 1 iff the field is static.
1727 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1728 FIELD_REF_INDEX is an index into the constant pool. */
1731 expand_java_field_op (is_static, is_putting, field_ref_index)
1734 int field_ref_index;
1737 get_class_constant (current_jcf,
1738 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
1740 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1741 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
1742 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
1744 tree field_type = get_type_from_signature (field_signature);
1745 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1748 tree field_decl = lookup_field (&self_type, field_name);
1749 if (field_decl == error_mark_node)
1753 else if (field_decl == NULL_TREE)
1755 error ("Missing field '%s' in '%s'",
1756 IDENTIFIER_POINTER (field_name), self_name);
1759 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1761 error ("Mismatching signature for field '%s' in '%s'",
1762 IDENTIFIER_POINTER (field_name), self_name);
1765 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1769 push_value (convert (field_type, integer_zero_node));
1770 flush_quick_stack ();
1774 /* Inline references to java.lang.PRIMTYPE.TYPE.
1775 In addition to being a useful (minor) optimization,
1776 this is also needed to avoid circularities in the implementation
1777 of these fields in libjava. */
1778 if (field_name == TYPE_identifier_node && ! is_putting
1779 && ! flag_emit_class_files && field_type == class_ptr_type
1780 && strncmp (self_name, "java.lang.", 10) == 0)
1782 tree typ = build_primtype_type_ref (self_name);
1790 field_ref = build_field_ref (field_ref, self_type, field_name);
1792 field_ref = build_class_init (self_type, field_ref);
1795 flush_quick_stack ();
1796 if (FIELD_FINAL (field_decl))
1798 if (DECL_CONTEXT (field_decl) != current_class)
1799 error_with_decl (field_decl,
1800 "assignment to final field `%s' not in field's class");
1801 else if (FIELD_STATIC (field_decl))
1803 if (!IS_CLINIT (current_function_decl))
1804 error_with_decl (field_decl,
1805 "assignment to final static field `%s' not in class initializer");
1809 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1810 error_with_decl (field_decl, "assignment to final field `%s' "
1811 "not in constructor");
1814 expand_assignment (field_ref, new_value, 0, 0);
1817 push_value (field_ref);
1821 build_primtype_type_ref (self_name)
1824 char *class_name = self_name+10;
1826 if (strncmp(class_name, "Byte", 4) == 0)
1827 typ = byte_type_node;
1828 else if (strncmp(class_name, "Short", 5) == 0)
1829 typ = short_type_node;
1830 else if (strncmp(class_name, "Integer", 7) == 0)
1831 typ = int_type_node;
1832 else if (strncmp(class_name, "Long", 4) == 0)
1833 typ = long_type_node;
1834 else if (strncmp(class_name, "Float", 5) == 0)
1835 typ = float_type_node;
1836 else if (strncmp(class_name, "Double", 6) == 0)
1837 typ = double_type_node;
1838 else if (strncmp(class_name, "Boolean", 7) == 0)
1839 typ = boolean_type_node;
1840 else if (strncmp(class_name, "Char", 4) == 0)
1841 typ = char_type_node;
1842 else if (strncmp(class_name, "Void", 4) == 0)
1843 typ = void_type_node;
1846 if (typ != NULL_TREE)
1847 return build_class_ref (typ);
1853 load_type_state (label)
1857 tree vec = LABEL_TYPE_STATE (label);
1858 int cur_length = TREE_VEC_LENGTH (vec);
1859 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1860 for (i = 0; i < cur_length; i++)
1861 type_map [i] = TREE_VEC_ELT (vec, i);
1864 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1865 dependant things, but they rely on gcc routines. This function is
1866 placed here because it uses things defined locally in parse.y. */
1869 case_identity (t, v)
1870 tree t __attribute__ ((__unused__));
1877 java_lang_expand_expr (exp, target, tmode, modifier)
1879 rtx target ATTRIBUTE_UNUSED;
1880 enum machine_mode tmode ATTRIBUTE_UNUSED;
1881 enum expand_modifier modifier ATTRIBUTE_UNUSED;
1885 switch (TREE_CODE (exp))
1887 case NEW_ARRAY_INIT:
1890 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1891 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1892 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1893 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1894 tree length = build_int_2 (ilength, 0);
1895 tree init = TREE_OPERAND (exp, 0);
1898 /* Enable this once we can set the vtable field statically. FIXME */
1899 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1900 && JPRIMITIVE_TYPE_P (element_type))
1902 tree temp, value, init_decl;
1903 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1904 PUSH_FIELD_VALUE (temp, "vtable",
1905 null_pointer_node /* FIXME */
1907 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1908 FINISH_RECORD_CONSTRUCTOR (temp);
1909 START_RECORD_CONSTRUCTOR (value, array_type);
1910 PUSH_SUPER_VALUE (value, temp);
1911 PUSH_FIELD_VALUE (value, "length", length);
1912 PUSH_FIELD_VALUE (value, "data", init);
1913 FINISH_RECORD_CONSTRUCTOR (value);
1915 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1916 pushdecl_top_level (init_decl);
1917 TREE_STATIC (init_decl) = 1;
1918 DECL_INITIAL (init_decl) = value;
1919 DECL_IGNORED_P (init_decl) = 1;
1920 TREE_READONLY (init_decl) = 1;
1921 make_decl_rtl (init_decl, NULL, 1);
1922 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1923 return expand_expr (init, target, tmode, modifier);
1926 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1927 expand_decl (array_decl);
1928 tmp = expand_assignment (array_decl,
1929 build_new_array (element_type, length),
1931 if (TREE_CONSTANT (init)
1932 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1934 tree init_decl = build_decl (VAR_DECL, generate_name (),
1936 pushdecl_top_level (init_decl);
1937 TREE_STATIC (init_decl) = 1;
1938 DECL_INITIAL (init_decl) = init;
1939 DECL_IGNORED_P (init_decl) = 1;
1940 TREE_READONLY (init_decl) = 1;
1941 make_decl_rtl (init_decl, NULL, 1);
1944 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1945 build1 (INDIRECT_REF, array_type, array_decl),
1951 if (BLOCK_EXPR_BODY (exp))
1954 tree body = BLOCK_EXPR_BODY (exp);
1955 pushlevel (2); /* 2 and above */
1956 expand_start_bindings (0);
1957 local = BLOCK_EXPR_DECLS (exp);
1960 tree next = TREE_CHAIN (local);
1961 layout_decl (local, 0);
1962 expand_decl (pushdecl (local));
1965 /* Avoid deep recursion for long block. */
1966 while (TREE_CODE (body) == COMPOUND_EXPR)
1968 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1970 body = TREE_OPERAND (body, 1);
1972 expand_expr (body, const0_rtx, VOIDmode, 0);
1975 expand_end_bindings (getdecls (), 1, 0);
1983 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1984 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1987 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1989 (wfl_operator, "Duplicate case label: `%s'",
1990 print_int_node (TREE_OPERAND (exp, 0)));
1996 pushcase (NULL_TREE, 0,
1997 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2001 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2002 expand_expr_stmt (TREE_OPERAND (exp, 1));
2003 expand_end_case (TREE_OPERAND (exp, 0));
2007 /* We expand a try[-catch] block */
2009 /* Expand the try block */
2010 expand_eh_region_start ();
2011 expand_expr_stmt (TREE_OPERAND (exp, 0));
2012 expand_start_all_catch ();
2014 /* Expand all catch clauses (EH handlers) */
2015 for (current = TREE_OPERAND (exp, 1); current;
2016 current = TREE_CHAIN (current))
2019 tree catch = TREE_OPERAND (current, 0);
2020 tree decl = BLOCK_EXPR_DECLS (catch);
2021 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2022 start_catch_handler (prepare_eh_table_type (type));
2023 expand_expr_stmt (TREE_OPERAND (current, 0));
2025 expand_resume_after_catch ();
2026 end_catch_handler ();
2028 expand_end_all_catch ();
2032 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2033 tree_code_name [TREE_CODE (exp)]);
2038 expand_byte_code (jcf, method)
2045 unsigned char *linenumber_pointer;
2046 int dead_code_index = -1;
2048 #undef RET /* Defined by config/i386/i386.h */
2049 #undef AND /* Causes problems with opcodes for iand and land. */
2051 #define BCODE byte_ops
2052 #define BYTE_type_node byte_type_node
2053 #define SHORT_type_node short_type_node
2054 #define INT_type_node int_type_node
2055 #define LONG_type_node long_type_node
2056 #define CHAR_type_node char_type_node
2057 #define PTR_type_node ptr_type_node
2058 #define FLOAT_type_node float_type_node
2059 #define DOUBLE_type_node double_type_node
2060 #define VOID_type_node void_type_node
2062 unsigned char* byte_ops;
2063 long length = DECL_CODE_LENGTH (method);
2066 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2067 byte_ops = jcf->read_ptr;
2069 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2070 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2071 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2072 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2074 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2076 instruction_bits = oballoc (length + 1);
2077 bzero (instruction_bits, length + 1);
2079 /* We make an initial pass of the line number table, to note
2080 which instructions have associated line number entries. */
2081 linenumber_pointer = linenumber_table;
2082 for (i = 0; i < linenumber_count; i++)
2084 int pc = GET_u2 (linenumber_pointer);
2085 linenumber_pointer += 4;
2087 warning ("invalid PC in line number table");
2090 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2091 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2092 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2096 /* Do a preliminary pass.
2097 * This figures out which PC can be the targets of jumps. */
2098 for (PC = 0; PC < length;)
2100 int oldpc = PC; /* PC at instruction start. */
2101 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2102 switch (byte_ops[PC++])
2104 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2106 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2109 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2111 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2112 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2113 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2114 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2115 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2116 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2117 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2118 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2120 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2121 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2122 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2123 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2124 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2125 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2126 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2127 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2129 /* two forms of wide instructions */
2130 #define PRE_SPECIAL_WIDE(IGNORE) \
2132 int modified_opcode = IMMEDIATE_u1; \
2133 if (modified_opcode == OPCODE_iinc) \
2135 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2136 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2140 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2144 /* nothing */ /* XXX JH */
2146 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2148 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2150 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2151 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2152 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2153 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2154 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2155 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2156 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2157 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2158 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2159 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2161 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2162 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2163 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2164 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2165 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2166 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2167 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2168 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2170 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2172 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2173 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2175 #define PRE_LOOKUP_SWITCH \
2176 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2177 NOTE_LABEL (default_offset+oldpc); \
2179 while (--npairs >= 0) { \
2180 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2181 jint offset = IMMEDIATE_s4; \
2182 NOTE_LABEL (offset+oldpc); } \
2185 #define PRE_TABLE_SWITCH \
2186 { jint default_offset = IMMEDIATE_s4; \
2187 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2188 NOTE_LABEL (default_offset+oldpc); \
2190 while (low++ <= high) { \
2191 jint offset = IMMEDIATE_s4; \
2192 NOTE_LABEL (offset+oldpc); } \
2195 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2196 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2197 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2198 (void)(IMMEDIATE_u2); \
2199 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2201 #include "javaop.def"
2206 if (! verify_jvm_instructions (jcf, byte_ops, length))
2209 /* Translate bytecodes to rtl instructions. */
2210 linenumber_pointer = linenumber_table;
2211 for (PC = 0; PC < length;)
2213 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2215 tree label = lookup_label (PC);
2216 flush_quick_stack ();
2217 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2218 expand_label (label);
2219 if (LABEL_VERIFIED (label) || PC == 0)
2220 load_type_state (label);
2223 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2225 if (dead_code_index == -1)
2227 /* This is the start of a region of unreachable bytecodes.
2228 They still need to be processed in order for EH ranges
2229 to get handled correctly. However, we can simply
2230 replace these bytecodes with nops. */
2231 dead_code_index = PC;
2234 /* Turn this bytecode into a nop. */
2239 if (dead_code_index != -1)
2241 /* We've just reached the end of a region of dead code. */
2242 warning ("Unreachable bytecode from %d to before %d.",
2243 dead_code_index, PC);
2244 dead_code_index = -1;
2248 /* Handle possible line number entry for this PC.
2250 This code handles out-of-order and multiple linenumbers per PC,
2251 but is optimized for the case of line numbers increasing
2252 monotonically with PC. */
2253 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2255 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2256 || GET_u2 (linenumber_pointer) != PC)
2257 linenumber_pointer = linenumber_table;
2258 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2260 int pc = GET_u2 (linenumber_pointer);
2261 linenumber_pointer += 4;
2264 lineno = GET_u2 (linenumber_pointer - 2);
2265 emit_line_note (input_filename, lineno);
2266 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2271 maybe_start_try (PC);
2272 maybe_pushlevels (PC);
2274 PC = process_jvm_instruction (PC, byte_ops, length);
2276 maybe_poplevels (PC);
2280 if (dead_code_index != -1)
2282 /* We've just reached the end of a region of dead code. */
2283 warning ("Unreachable bytecode from %d to the end of the method.",
2289 java_push_constant_from_pool (jcf, index)
2294 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2297 push_obstacks (&permanent_obstack, &permanent_obstack);
2298 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2299 index = alloc_name_constant (CONSTANT_String, name);
2300 c = build_ref_from_constant_pool (index);
2301 TREE_TYPE (c) = promote_type (string_type_node);
2305 c = get_constant (jcf, index);
2310 process_jvm_instruction (PC, byte_ops, length)
2312 unsigned char* byte_ops;
2313 long length ATTRIBUTE_UNUSED;
2315 const char *opname; /* Temporary ??? */
2316 int oldpc = PC; /* PC at instruction start. */
2318 /* If the instruction is at the beginning of a exception handler,
2319 replace the top of the stack with the thrown object reference */
2320 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2322 tree type = pop_type (ptr_type_node);
2323 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2326 switch (byte_ops[PC++])
2328 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2331 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2334 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2336 int saw_index = 0; \
2337 int index = OPERAND_VALUE; \
2338 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2341 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2343 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2344 tree ret = lookup_label (PC); \
2345 build_java_jsr (where, ret); \
2346 load_type_state (ret); \
2349 /* Push a constant onto the stack. */
2350 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2351 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2352 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2353 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2355 /* internal macro added for use by the WIDE case */
2356 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2357 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2359 /* Push local variable onto the opcode stack. */
2360 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2362 /* have to do this since OPERAND_VALUE may have side-effects */ \
2363 int opvalue = OPERAND_VALUE; \
2364 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2367 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2368 expand_java_return (OPERAND_TYPE##_type_node)
2370 #define REM_EXPR TRUNC_MOD_EXPR
2371 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2372 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2374 #define FIELD(IS_STATIC, IS_PUT) \
2375 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2377 #define TEST(OPERAND_TYPE, CONDITION) \
2378 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2380 #define COND(OPERAND_TYPE, CONDITION) \
2381 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2383 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2384 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2386 #define BRANCH_GOTO(OPERAND_VALUE) \
2387 expand_java_goto (oldpc + OPERAND_VALUE)
2389 #define BRANCH_CALL(OPERAND_VALUE) \
2390 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2393 #define BRANCH_RETURN(OPERAND_VALUE) \
2395 tree type = OPERAND_TYPE##_type_node; \
2396 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2397 expand_java_ret (value); \
2401 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2402 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2403 fprintf (stderr, "(not implemented)\n")
2404 #define NOT_IMPL1(OPERAND_VALUE) \
2405 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2406 fprintf (stderr, "(not implemented)\n")
2408 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2410 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2412 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2414 #define STACK_SWAP(COUNT) java_stack_swap()
2416 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2417 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2418 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2420 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2421 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2423 #define LOOKUP_SWITCH \
2424 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2425 tree selector = pop_value (INT_type_node); \
2426 tree duplicate, label; \
2427 tree type = TREE_TYPE (selector); \
2428 flush_quick_stack (); \
2429 expand_start_case (0, selector, type, "switch statement");\
2430 push_momentary (); \
2431 while (--npairs >= 0) \
2433 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2434 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2435 TREE_TYPE (value) = type; \
2436 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2437 pushcase (value, convert, label, &duplicate); \
2438 expand_java_goto (oldpc + offset); \
2440 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2441 pushcase (NULL_TREE, 0, label, &duplicate); \
2442 expand_java_goto (oldpc + default_offset); \
2444 expand_end_case (selector); \
2447 #define TABLE_SWITCH \
2448 { jint default_offset = IMMEDIATE_s4; \
2449 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2450 tree selector = pop_value (INT_type_node); \
2451 tree duplicate, label; \
2452 tree type = TREE_TYPE (selector); \
2453 flush_quick_stack (); \
2454 expand_start_case (0, selector, type, "switch statement");\
2455 push_momentary (); \
2456 for (; low <= high; low++) \
2458 jint offset = IMMEDIATE_s4; \
2459 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2460 TREE_TYPE (value) = type; \
2461 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2462 pushcase (value, convert, label, &duplicate); \
2463 expand_java_goto (oldpc + offset); \
2465 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2466 pushcase (NULL_TREE, 0, label, &duplicate); \
2467 expand_java_goto (oldpc + default_offset); \
2469 expand_end_case (selector); \
2472 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2473 { int opcode = byte_ops[PC-1]; \
2474 int method_ref_index = IMMEDIATE_u2; \
2476 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2478 expand_invoke (opcode, method_ref_index, nargs); \
2481 /* Handle new, checkcast, instanceof */
2482 #define OBJECT(TYPE, OP) \
2483 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2485 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2487 #define ARRAY_LOAD(OPERAND_TYPE) \
2489 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2492 #define ARRAY_STORE(OPERAND_TYPE) \
2494 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2497 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2498 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2499 #define ARRAY_NEW_PTR() \
2500 push_value (build_anewarray (get_class_constant (current_jcf, \
2502 pop_value (int_type_node)));
2503 #define ARRAY_NEW_NUM() \
2505 int atype = IMMEDIATE_u1; \
2506 push_value (build_newarray (atype, pop_value (int_type_node)));\
2508 #define ARRAY_NEW_MULTI() \
2510 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2511 int ndims = IMMEDIATE_u1; \
2512 expand_java_multianewarray( class, ndims ); \
2515 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2516 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2517 pop_value (OPERAND_TYPE##_type_node))));
2519 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2521 push_value (build1 (NOP_EXPR, int_type_node, \
2522 (convert (TO_TYPE##_type_node, \
2523 pop_value (FROM_TYPE##_type_node))))); \
2526 #define CONVERT(FROM_TYPE, TO_TYPE) \
2528 push_value (convert (TO_TYPE##_type_node, \
2529 pop_value (FROM_TYPE##_type_node))); \
2532 /* internal macro added for use by the WIDE case
2533 Added TREE_TYPE (decl) assignment, apbianco */
2534 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2537 int var = OPVALUE; \
2538 tree type = OPTYPE; \
2539 value = pop_value (type); \
2540 type = TREE_TYPE (value); \
2541 decl = find_local_variable (var, type, oldpc); \
2542 set_local_type (var, type ); \
2543 expand_assignment (decl, value, 0, 0); \
2546 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2548 /* have to do this since OPERAND_VALUE may have side-effects */ \
2549 int opvalue = OPERAND_VALUE; \
2550 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2553 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2554 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2556 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2557 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2559 #define MONITOR_OPERATION(call) \
2561 tree o = pop_value (ptr_type_node); \
2563 flush_quick_stack (); \
2564 c = build_java_monitor (call, o); \
2565 TREE_SIDE_EFFECTS (c) = 1; \
2566 expand_expr_stmt (c); \
2569 #define SPECIAL_IINC(IGNORED) \
2571 unsigned int local_var_index = IMMEDIATE_u1; \
2572 int ival = IMMEDIATE_s1; \
2573 expand_iinc(local_var_index, ival, oldpc); \
2576 #define SPECIAL_WIDE(IGNORED) \
2578 int modified_opcode = IMMEDIATE_u1; \
2579 unsigned int local_var_index = IMMEDIATE_u2; \
2580 switch (modified_opcode) \
2584 int ival = IMMEDIATE_s2; \
2585 expand_iinc (local_var_index, ival, oldpc); \
2588 case OPCODE_iload: \
2589 case OPCODE_lload: \
2590 case OPCODE_fload: \
2591 case OPCODE_dload: \
2592 case OPCODE_aload: \
2594 /* duplicate code from LOAD macro */ \
2595 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2598 case OPCODE_istore: \
2599 case OPCODE_lstore: \
2600 case OPCODE_fstore: \
2601 case OPCODE_dstore: \
2602 case OPCODE_astore: \
2604 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2608 error ("unrecogized wide sub-instruction"); \
2612 #define SPECIAL_THROW(IGNORED) \
2613 build_java_athrow (pop_value (throwable_type_node))
2615 #define SPECIAL_BREAK NOT_IMPL1
2616 #define IMPL NOT_IMPL
2618 #include "javaop.def"
2621 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2626 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2627 order, as specified by Java Language Specification.
2629 The problem is that while expand_expr will evaluate its sub-operands in
2630 left-to-right order, for variables it will just return an rtx (i.e.
2631 an lvalue) for the variable (rather than an rvalue). So it is possible
2632 that a later sub-operand will change the register, and when the
2633 actual operation is done, it will use the new value, when it should
2634 have used the original value.
2636 We fix this by using save_expr. This forces the sub-operand to be
2637 copied into a fresh virtual register,
2639 For method invocation, we modify the arguments so that a
2640 left-to-right order evaluation is performed. Saved expressions
2641 will, in CALL_EXPR order, be reused when the call will be expanded.
2645 force_evaluation_order (node)
2648 if (flag_syntax_only)
2650 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
2652 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2653 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2655 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2659 if (!TREE_OPERAND (node, 1))
2662 /* This reverses the evaluation order. This is a desired effect. */
2663 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
2664 arg; arg = TREE_CHAIN (arg))
2666 tree saved = save_expr (TREE_VALUE (arg));
2667 cmp = (cmp == NULL_TREE ? saved :
2668 build (COMPOUND_EXPR, void_type_node, cmp, saved));
2669 TREE_VALUE (arg) = saved;
2672 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
2673 TREE_SIDE_EFFECTS (cmp) = 1;
2677 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
2678 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
2679 TREE_SIDE_EFFECTS (cmp) = 1;