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);
1056 build_java_binop (op, type, arg1, arg2)
1058 tree type, arg1, arg2;
1065 tree u_type = unsigned_type (type);
1066 arg1 = convert (u_type, arg1);
1067 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1068 return convert (type, arg1);
1072 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1073 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1076 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1077 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1078 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1080 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1081 boolean_type_node, arg1, arg2));
1082 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1083 tree second_compare = fold (build (COND_EXPR, int_type_node,
1084 ifexp2, integer_zero_node,
1085 op == COMPARE_L_EXPR
1086 ? integer_negative_one_node
1087 : integer_one_node));
1088 return fold (build (COND_EXPR, int_type_node, ifexp1,
1089 op == COMPARE_L_EXPR ? integer_one_node
1090 : integer_negative_one_node,
1094 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1096 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1097 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1098 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1099 ifexp2, integer_one_node,
1100 integer_zero_node));
1101 return fold (build (COND_EXPR, int_type_node,
1102 ifexp1, integer_negative_one_node, second_compare));
1105 case TRUNC_MOD_EXPR:
1106 if (TREE_CODE (type) == REAL_TYPE)
1109 if (type != double_type_node)
1111 arg1 = convert (double_type_node, arg1);
1112 arg2 = convert (double_type_node, arg2);
1114 call = build (CALL_EXPR, double_type_node,
1115 build_address_of (soft_fmod_node),
1116 tree_cons (NULL_TREE, arg1,
1117 build_tree_list (NULL_TREE, arg2)),
1119 if (type != double_type_node)
1120 call = convert (type, call);
1126 return fold (build (op, type, arg1, arg2));
1130 expand_java_binop (type, op)
1131 tree type; enum tree_code op;
1141 rtype = int_type_node;
1142 rarg = pop_value (rtype);
1145 rarg = pop_value (rtype);
1147 larg = pop_value (ltype);
1148 push_value (build_java_binop (op, type, larg, rarg));
1151 /* Lookup the field named NAME in *TYPEP or its super classes.
1152 If not found, return NULL_TREE.
1153 (If the *TYPEP is not found, return error_mark_node.)
1154 If found, return the FIELD_DECL, and set *TYPEP to the
1155 class containing the field. */
1158 lookup_field (typep, name)
1162 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1164 load_class (*typep, 1);
1165 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1166 return error_mark_node;
1170 tree field, basetype_vec;
1173 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1174 if (DECL_NAME (field) == name)
1177 /* Process implemented interfaces. */
1178 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1179 n = TREE_VEC_LENGTH (basetype_vec);
1180 for (i = 0; i < n; i++)
1182 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1183 if ((field = lookup_field (&t, name)))
1186 *typep = CLASSTYPE_SUPER (*typep);
1191 /* Look up the field named NAME in object SELF_VALUE,
1192 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1193 SELF_VALUE is NULL_TREE if looking for a static field. */
1196 build_field_ref (self_value, self_class, name)
1197 tree self_value, self_class, name;
1199 tree base_class = self_class;
1200 tree field_decl = lookup_field (&base_class, name);
1201 if (field_decl == NULL_TREE)
1203 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1204 return error_mark_node;
1206 if (self_value == NULL_TREE)
1208 return build_static_field_ref (field_decl);
1212 tree base_handle_type = promote_type (base_class);
1213 if (base_handle_type != TREE_TYPE (self_value))
1214 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1215 #ifdef JAVA_USE_HANDLES
1216 self_value = unhand_expr (self_value);
1218 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1220 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1221 self_value, field_decl));
1231 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1232 name = get_identifier (buf);
1233 if (IDENTIFIER_LOCAL_VALUE (name))
1234 return IDENTIFIER_LOCAL_VALUE (name);
1237 /* The type of the address of a label is return_address_type_node. */
1238 tree decl = create_label_decl (name);
1239 LABEL_PC (decl) = pc;
1241 return pushdecl (decl);
1245 /* Generate a unique name for the purpose of loops and switches
1246 labels, and try-catch-finally blocks label or temporary variables. */
1251 static int l_number = 0;
1253 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1255 return get_identifier (buff);
1259 create_label_decl (name)
1263 push_obstacks (&permanent_obstack, &permanent_obstack);
1264 decl = build_decl (LABEL_DECL, name,
1265 TREE_TYPE (return_address_type_node));
1267 DECL_CONTEXT (decl) = current_function_decl;
1268 DECL_IGNORED_P (decl) = 1;
1272 /* This maps a bytecode offset (PC) to various flags. */
1273 char *instruction_bits;
1276 note_label (current_pc, target_pc)
1277 int current_pc ATTRIBUTE_UNUSED, target_pc;
1279 lookup_label (target_pc);
1280 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1283 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1284 where CONDITION is one of one the compare operators. */
1287 expand_compare (condition, value1, value2, target_pc)
1288 enum tree_code condition;
1289 tree value1, value2;
1292 tree target = lookup_label (target_pc);
1293 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1294 expand_start_cond (truthvalue_conversion (cond), 0);
1295 expand_goto (target);
1299 /* Emit code for a TEST-type opcode. */
1302 expand_test (condition, type, target_pc)
1303 enum tree_code condition;
1307 tree value1, value2;
1308 flush_quick_stack ();
1309 value1 = pop_value (type);
1310 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1311 expand_compare (condition, value1, value2, target_pc);
1314 /* Emit code for a COND-type opcode. */
1317 expand_cond (condition, type, target_pc)
1318 enum tree_code condition;
1322 tree value1, value2;
1323 flush_quick_stack ();
1324 /* note: pop values in opposite order */
1325 value2 = pop_value (type);
1326 value1 = pop_value (type);
1327 /* Maybe should check value1 and value2 for type compatibility ??? */
1328 expand_compare (condition, value1, value2, target_pc);
1332 expand_java_goto (target_pc)
1335 tree target_label = lookup_label (target_pc);
1336 flush_quick_stack ();
1337 expand_goto (target_label);
1342 expand_java_call (target_pc, return_address)
1343 int target_pc, return_address;
1345 tree target_label = lookup_label (target_pc);
1346 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1348 flush_quick_stack ();
1349 expand_goto (target_label);
1353 expand_java_ret (return_address)
1354 tree return_address ATTRIBUTE_UNUSED;
1356 warning ("ret instruction not implemented");
1358 tree target_label = lookup_label (target_pc);
1359 flush_quick_stack ();
1360 expand_goto (target_label);
1365 /* Recursive helper function to pop argument types during verifiation. */
1368 pop_argument_types (arg_types)
1371 if (arg_types == end_params_node)
1373 if (TREE_CODE (arg_types) == TREE_LIST)
1375 pop_argument_types (TREE_CHAIN (arg_types));
1376 pop_type (TREE_VALUE (arg_types));
1383 pop_arguments (arg_types)
1386 if (arg_types == end_params_node)
1388 if (TREE_CODE (arg_types) == TREE_LIST)
1390 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1391 tree type = TREE_VALUE (arg_types);
1392 tree arg = pop_value (type);
1393 #ifdef PROMOTE_PROTOTYPES
1394 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1395 && INTEGRAL_TYPE_P (type))
1396 arg = convert (integer_type_node, arg);
1398 return tree_cons (NULL_TREE, arg, tail);
1403 /* Build an expression to initialize the class CLAS.
1404 if EXPR is non-NULL, returns an expression to first call the initializer
1405 (if it is needed) and then calls EXPR. */
1408 build_class_init (clas, expr)
1412 if (inherits_from_p (current_class, clas))
1414 init = build (CALL_EXPR, void_type_node,
1415 build_address_of (soft_initclass_node),
1416 build_tree_list (NULL_TREE, build_class_ref (clas)),
1418 TREE_SIDE_EFFECTS (init) = 1;
1419 if (expr != NULL_TREE)
1421 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1422 TREE_SIDE_EFFECTS (expr) = 1;
1428 static tree methods_ident = NULL_TREE;
1429 static tree ncode_ident = NULL_TREE;
1430 tree dtable_ident = NULL_TREE;
1433 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1434 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1435 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1438 if (is_compiled_class (self_type))
1440 make_decl_rtl (method, NULL, 1);
1441 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1445 /* We don't know whether the method has been (statically) compiled.
1446 Compile this code to get a reference to the method's code:
1448 SELF_TYPE->methods[METHOD_INDEX].ncode
1450 This is guaranteed to work (assuming SELF_TYPE has
1451 been initialized), since if the method is not compiled yet,
1452 its ncode points to a trampoline that forces compilation. */
1454 int method_index = 0;
1456 tree ref = build_class_ref (self_type);
1457 ref = build1 (INDIRECT_REF, class_type_node, ref);
1458 if (ncode_ident == NULL_TREE)
1459 ncode_ident = get_identifier ("ncode");
1460 if (methods_ident == NULL_TREE)
1461 methods_ident = get_identifier ("methods");
1462 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1463 lookup_field (&class_type_node, methods_ident));
1464 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1465 ; meth = TREE_CHAIN (meth))
1469 if (meth == NULL_TREE)
1470 fatal ("method '%s' not found in class",
1471 IDENTIFIER_POINTER (DECL_NAME (method)));
1474 method_index *= int_size_in_bytes (method_type_node);
1475 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1476 ref, build_int_2 (method_index, 0)));
1477 ref = build1 (INDIRECT_REF, method_type_node, ref);
1478 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1480 lookup_field (&method_type_node, ncode_ident));
1486 invoke_build_dtable (is_invoke_interface, arg_list)
1487 int is_invoke_interface;
1490 tree dtable, objectref;
1492 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1494 /* If we're dealing with interfaces and if the objectref
1495 argument is an array then get the dispatch table of the class
1496 Object rather than the one from the objectref. */
1497 objectref = (is_invoke_interface
1498 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1499 object_type_node : TREE_VALUE (arg_list));
1501 if (dtable_ident == NULL_TREE)
1502 dtable_ident = get_identifier ("vtable");
1503 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1504 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1505 lookup_field (&object_type_node, dtable_ident));
1511 build_invokevirtual (dtable, method)
1512 tree dtable, method;
1515 tree nativecode_ptr_ptr_type_node
1516 = build_pointer_type (nativecode_ptr_type_node);
1517 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1518 /* Add one to skip "class" field of dtable, and one to skip unused
1519 vtable entry (for C++ compatibility). */
1522 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1523 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1524 dtable, build_int_2 (method_index, 0)));
1525 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1531 build_invokeinterface (dtable, method_name, method_signature)
1532 tree dtable, method_name, method_signature;
1534 static tree class_ident = NULL_TREE;
1537 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1538 ensure that the selected method exists, is public and not
1539 abstract nor static. */
1541 if (class_ident == NULL_TREE)
1542 class_ident = get_identifier ("class");
1544 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1545 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1546 lookup_field (&dtable_type, class_ident));
1547 lookup_arg = build_tree_list (NULL_TREE,
1550 (IDENTIFIER_POINTER(method_signature),
1551 IDENTIFIER_LENGTH(method_signature)))));
1552 lookup_arg = tree_cons (NULL_TREE, dtable,
1553 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1555 return build (CALL_EXPR, ptr_type_node,
1556 build_address_of (soft_lookupinterfacemethod_node),
1557 lookup_arg, NULL_TREE);
1560 /* Expand one of the invoke_* opcodes.
1561 OCPODE is the specific opcode.
1562 METHOD_REF_INDEX is an index into the constant pool.
1563 NARGS is the number of arguments, or -1 if not specified. */
1566 expand_invoke (opcode, method_ref_index, nargs)
1568 int method_ref_index;
1569 int nargs ATTRIBUTE_UNUSED;
1571 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1572 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1573 tree self_type = get_class_constant
1574 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1575 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1576 tree call, func, method, arg_list, method_type;
1578 if (! CLASS_LOADED_P (self_type))
1580 load_class (self_type, 1);
1581 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1582 fatal ("failed to find class '%s'", self_name);
1584 layout_class_methods (self_type);
1586 if (method_name == init_identifier_node)
1587 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1590 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1591 method_name, method_signature);
1592 if (method == NULL_TREE)
1594 error ("Class '%s' has no method named '%s' matching signature '%s'",
1596 IDENTIFIER_POINTER (method_name),
1597 IDENTIFIER_POINTER (method_signature));
1599 /* Invoke static can't invoke static/abstract method */
1600 else if (opcode == OPCODE_invokestatic)
1602 if (!METHOD_STATIC (method))
1604 error ("invokestatic on non static method");
1607 else if (METHOD_ABSTRACT (method))
1609 error ("invokestatic on abstract method");
1615 if (METHOD_STATIC (method))
1617 error ("invoke[non-static] on static method");
1622 if (method == NULL_TREE)
1624 method_type = get_type_from_signature (method_signature);
1625 pop_arguments (TYPE_ARG_TYPES (method_type));
1626 if (opcode != OPCODE_invokestatic)
1627 pop_type (self_type);
1628 method_type = promote_type (TREE_TYPE (method_type));
1629 push_value (convert (method_type, integer_zero_node));
1633 method_type = TREE_TYPE (method);
1634 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1635 flush_quick_stack ();
1638 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1639 || (opcode == OPCODE_invokevirtual
1640 && (METHOD_PRIVATE (method)
1641 || METHOD_FINAL (method)
1642 || CLASS_FINAL (TYPE_NAME (self_type)))))
1643 func = build_known_method_ref (method, method_type, self_type,
1644 method_signature, arg_list);
1647 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1649 if (opcode == OPCODE_invokevirtual)
1650 func = build_invokevirtual (dtable, method);
1652 func = build_invokeinterface (dtable, method_name, method_signature);
1654 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1655 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1656 TREE_SIDE_EFFECTS (call) = 1;
1658 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1659 expand_expr_stmt (call);
1663 flush_quick_stack ();
1668 /* Expand an operation to extract from or store into a field.
1669 IS_STATIC is 1 iff the field is static.
1670 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1671 FIELD_REF_INDEX is an index into the constant pool. */
1674 expand_java_field_op (is_static, is_putting, field_ref_index)
1677 int field_ref_index;
1680 get_class_constant (current_jcf,
1681 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
1683 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1684 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
1685 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
1687 tree field_type = get_type_from_signature (field_signature);
1688 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1691 tree field_decl = lookup_field (&self_type, field_name);
1692 if (field_decl == error_mark_node)
1696 else if (field_decl == NULL_TREE)
1698 error ("Missing field '%s' in '%s'",
1699 IDENTIFIER_POINTER (field_name), self_name);
1702 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1704 error ("Mismatching signature for field '%s' in '%s'",
1705 IDENTIFIER_POINTER (field_name), self_name);
1708 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1712 push_value (convert (field_type, integer_zero_node));
1713 flush_quick_stack ();
1717 /* Inline references to java.lang.PRIMTYPE.TYPE.
1718 In addition to being a useful (minor) optimization,
1719 this is also needed to avoid circularities in the implementation
1720 of these fields in libjava. */
1721 if (field_name == TYPE_identifier_node && ! is_putting
1722 && ! flag_emit_class_files && field_type == class_ptr_type
1723 && strncmp (self_name, "java.lang.", 10) == 0)
1725 tree typ = build_primtype_type_ref (self_name);
1733 field_ref = build_field_ref (field_ref, self_type, field_name);
1735 field_ref = build_class_init (self_type, field_ref);
1738 flush_quick_stack ();
1739 if (FIELD_FINAL (field_decl))
1741 if (DECL_CONTEXT (field_decl) != current_class)
1742 error_with_decl (field_decl,
1743 "assignment to final field `%s' not in field's class");
1744 else if (FIELD_STATIC (field_decl))
1746 if (!IS_CLINIT (current_function_decl))
1747 error_with_decl (field_decl,
1748 "assignment to final static field `%s' not in class initializer");
1752 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1753 error_with_decl (field_decl, "assignment to final field `%s' "
1754 "not in constructor");
1757 expand_assignment (field_ref, new_value, 0, 0);
1760 push_value (field_ref);
1764 build_primtype_type_ref (self_name)
1767 char *class_name = self_name+10;
1769 if (strncmp(class_name, "Byte", 4) == 0)
1770 typ = byte_type_node;
1771 else if (strncmp(class_name, "Short", 5) == 0)
1772 typ = short_type_node;
1773 else if (strncmp(class_name, "Integer", 7) == 0)
1774 typ = int_type_node;
1775 else if (strncmp(class_name, "Long", 4) == 0)
1776 typ = long_type_node;
1777 else if (strncmp(class_name, "Float", 5) == 0)
1778 typ = float_type_node;
1779 else if (strncmp(class_name, "Double", 6) == 0)
1780 typ = double_type_node;
1781 else if (strncmp(class_name, "Boolean", 7) == 0)
1782 typ = boolean_type_node;
1783 else if (strncmp(class_name, "Char", 4) == 0)
1784 typ = char_type_node;
1785 else if (strncmp(class_name, "Void", 4) == 0)
1786 typ = void_type_node;
1789 if (typ != NULL_TREE)
1790 return build_class_ref (typ);
1796 load_type_state (label)
1800 tree vec = LABEL_TYPE_STATE (label);
1801 int cur_length = TREE_VEC_LENGTH (vec);
1802 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1803 for (i = 0; i < cur_length; i++)
1804 type_map [i] = TREE_VEC_ELT (vec, i);
1807 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1808 dependant things, but they rely on gcc routines. This function is
1809 placed here because it uses things defined locally in parse.y. */
1812 case_identity (t, v)
1813 tree t __attribute__ ((__unused__));
1820 java_lang_expand_expr (exp, target, tmode, modifier)
1823 enum machine_mode tmode;
1824 enum expand_modifier modifier;
1828 switch (TREE_CODE (exp))
1830 case NEW_ARRAY_INIT:
1833 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1834 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1835 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1836 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1837 tree length = build_int_2 (ilength, 0);
1838 tree init = TREE_OPERAND (exp, 0);
1841 /* Enable this once we can set the vtable field statically. FIXME */
1842 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1843 && JPRIMITIVE_TYPE_P (element_type))
1845 tree temp, value, init_decl;
1846 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1847 PUSH_FIELD_VALUE (temp, "vtable",
1848 null_pointer_node /* FIXME */
1850 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1851 FINISH_RECORD_CONSTRUCTOR (temp);
1852 START_RECORD_CONSTRUCTOR (value, array_type);
1853 PUSH_SUPER_VALUE (value, temp);
1854 PUSH_FIELD_VALUE (value, "length", length);
1855 PUSH_FIELD_VALUE (value, "data", init);
1856 FINISH_RECORD_CONSTRUCTOR (value);
1858 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1859 pushdecl_top_level (init_decl);
1860 TREE_STATIC (init_decl) = 1;
1861 DECL_INITIAL (init_decl) = value;
1862 DECL_IGNORED_P (init_decl) = 1;
1863 TREE_READONLY (init_decl) = 1;
1864 make_decl_rtl (init_decl, NULL, 1);
1865 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1866 return expand_expr (init, target, tmode, modifier);
1869 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1870 expand_decl (array_decl);
1871 tmp = expand_assignment (array_decl,
1872 build_new_array (element_type, length),
1874 if (TREE_CONSTANT (init)
1875 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1877 tree init_decl = build_decl (VAR_DECL, generate_name (),
1879 pushdecl_top_level (init_decl);
1880 TREE_STATIC (init_decl) = 1;
1881 DECL_INITIAL (init_decl) = init;
1882 DECL_IGNORED_P (init_decl) = 1;
1883 TREE_READONLY (init_decl) = 1;
1884 make_decl_rtl (init_decl, NULL, 1);
1887 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1888 build1 (INDIRECT_REF, array_type, array_decl),
1894 if (BLOCK_EXPR_BODY (exp))
1897 tree body = BLOCK_EXPR_BODY (exp);
1898 struct rtx_def *to_return;
1899 pushlevel (2); /* 2 and above */
1900 expand_start_bindings (0);
1901 local = BLOCK_EXPR_DECLS (exp);
1904 tree next = TREE_CHAIN (local);
1905 layout_decl (local, 0);
1906 expand_decl (pushdecl (local));
1909 /* Avoid deep recursion for long block. */
1910 while (TREE_CODE (body) == COMPOUND_EXPR)
1912 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1914 body = TREE_OPERAND (body, 1);
1916 to_return = expand_expr (body, target, tmode, modifier);
1918 expand_end_bindings (getdecls (), 1, 0);
1926 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1927 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1930 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1932 (wfl_operator, "Duplicate case label: `%s'",
1933 print_int_node (TREE_OPERAND (exp, 0)));
1939 pushcase (NULL_TREE, 0,
1940 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1944 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
1945 expand_expr_stmt (TREE_OPERAND (exp, 1));
1946 expand_end_case (TREE_OPERAND (exp, 0));
1950 /* We expand a try[-catch] block */
1952 /* Expand the try block */
1953 expand_eh_region_start ();
1954 expand_expr_stmt (TREE_OPERAND (exp, 0));
1955 expand_start_all_catch ();
1957 /* Expand all catch clauses (EH handlers) */
1958 for (current = TREE_OPERAND (exp, 1); current;
1959 current = TREE_CHAIN (current))
1962 tree catch = TREE_OPERAND (current, 0);
1963 tree decl = BLOCK_EXPR_DECLS (catch);
1964 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
1965 start_catch_handler (prepare_eh_table_type (type));
1966 expand_expr_stmt (TREE_OPERAND (current, 0));
1968 expand_resume_after_catch ();
1969 end_catch_handler ();
1971 expand_end_all_catch ();
1975 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
1976 tree_code_name [TREE_CODE (exp)]);
1981 expand_byte_code (jcf, method)
1988 unsigned char *linenumber_pointer;
1990 #undef RET /* Defined by config/i386/i386.h */
1991 #undef AND /* Causes problems with opcodes for iand and land. */
1993 #define BCODE byte_ops
1994 #define BYTE_type_node byte_type_node
1995 #define SHORT_type_node short_type_node
1996 #define INT_type_node int_type_node
1997 #define LONG_type_node long_type_node
1998 #define CHAR_type_node char_type_node
1999 #define PTR_type_node ptr_type_node
2000 #define FLOAT_type_node float_type_node
2001 #define DOUBLE_type_node double_type_node
2002 #define VOID_type_node void_type_node
2004 unsigned char* byte_ops;
2005 long length = DECL_CODE_LENGTH (method);
2008 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2009 byte_ops = jcf->read_ptr;
2011 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2012 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2013 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2014 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2016 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2018 instruction_bits = oballoc (length + 1);
2019 bzero (instruction_bits, length + 1);
2021 /* We make an initial pass of the line number table, to note
2022 which instructions have associated line number entries. */
2023 linenumber_pointer = linenumber_table;
2024 for (i = 0; i < linenumber_count; i++)
2026 int pc = GET_u2 (linenumber_pointer);
2027 linenumber_pointer += 4;
2029 warning ("invalid PC in line number table");
2032 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2033 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2034 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2038 /* Do a preliminary pass.
2039 * This figures out which PC can be the targets of jumps. */
2040 for (PC = 0; PC < length;)
2042 int oldpc = PC; /* PC at instruction start. */
2043 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2044 switch (byte_ops[PC++])
2046 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2048 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2051 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2053 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2054 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2055 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2056 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2057 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2058 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2059 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2060 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2062 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2063 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2064 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2065 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2066 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2067 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2068 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2069 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2071 /* two forms of wide instructions */
2072 #define PRE_SPECIAL_WIDE(IGNORE) \
2074 int modified_opcode = IMMEDIATE_u1; \
2075 if (modified_opcode == OPCODE_iinc) \
2077 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2078 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2082 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2086 /* nothing */ /* XXX JH */
2088 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2090 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2092 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2093 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2094 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2095 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2096 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2097 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2098 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2099 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2100 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2101 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2103 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2104 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2105 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2106 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2107 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2108 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2109 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2110 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2112 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2114 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2115 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2117 #define PRE_LOOKUP_SWITCH \
2118 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2119 NOTE_LABEL (default_offset+oldpc); \
2121 while (--npairs >= 0) { \
2122 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2123 jint offset = IMMEDIATE_s4; \
2124 NOTE_LABEL (offset+oldpc); } \
2127 #define PRE_TABLE_SWITCH \
2128 { jint default_offset = IMMEDIATE_s4; \
2129 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2130 NOTE_LABEL (default_offset+oldpc); \
2132 while (low++ <= high) { \
2133 jint offset = IMMEDIATE_s4; \
2134 NOTE_LABEL (offset+oldpc); } \
2137 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2138 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2139 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2140 (void)(IMMEDIATE_u2); \
2141 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2143 #include "javaop.def"
2148 if (! verify_jvm_instructions (jcf, byte_ops, length))
2151 /* Translate bytecodes to rtl instructions. */
2152 linenumber_pointer = linenumber_table;
2153 for (PC = 0; PC < length;)
2155 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2157 tree label = lookup_label (PC);
2158 flush_quick_stack ();
2159 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2160 expand_label (label);
2161 if (LABEL_VERIFIED (label) || PC == 0)
2162 load_type_state (label);
2165 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2167 /* never executed - skip */
2168 warning ("Some bytecode operations (starting at pc %d) can never be executed", PC);
2170 && ! (instruction_bits [PC] & BCODE_VERIFIED))
2176 /* Handle possible line number entry for this PC.
2178 This code handles out-of-order and multiple linenumbers per PC,
2179 but is optimized for the case of line numbers increasing
2180 monotonically with PC. */
2181 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2183 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2184 || GET_u2 (linenumber_pointer) != PC)
2185 linenumber_pointer = linenumber_table;
2186 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2188 int pc = GET_u2 (linenumber_pointer);
2189 linenumber_pointer += 4;
2192 lineno = GET_u2 (linenumber_pointer - 2);
2193 emit_line_note (input_filename, lineno);
2194 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2199 maybe_start_try (PC);
2200 maybe_pushlevels (PC);
2202 PC = process_jvm_instruction (PC, byte_ops, length);
2204 maybe_poplevels (PC);
2210 java_push_constant_from_pool (jcf, index)
2215 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2218 push_obstacks (&permanent_obstack, &permanent_obstack);
2219 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2220 index = alloc_name_constant (CONSTANT_String, name);
2221 c = build_ref_from_constant_pool (index);
2222 TREE_TYPE (c) = promote_type (string_type_node);
2226 c = get_constant (jcf, index);
2231 process_jvm_instruction (PC, byte_ops, length)
2233 unsigned char* byte_ops;
2234 long length ATTRIBUTE_UNUSED;
2236 const char *opname; /* Temporary ??? */
2237 int oldpc = PC; /* PC at instruction start. */
2239 /* If the instruction is at the beginning of a exception handler,
2240 replace the top of the stack with the thrown object reference */
2241 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2243 tree type = pop_type (ptr_type_node);
2244 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2247 switch (byte_ops[PC++])
2249 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2252 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2255 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2257 int saw_index = 0; \
2258 int index = OPERAND_VALUE; \
2259 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2262 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2264 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2265 tree ret = lookup_label (PC); \
2266 build_java_jsr (where, ret); \
2267 load_type_state (ret); \
2270 /* Push a constant onto the stack. */
2271 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2272 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2273 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2274 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2276 /* internal macro added for use by the WIDE case */
2277 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2278 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2280 /* Push local variable onto the opcode stack. */
2281 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2283 /* have to do this since OPERAND_VALUE may have side-effects */ \
2284 int opvalue = OPERAND_VALUE; \
2285 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2288 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2289 expand_java_return (OPERAND_TYPE##_type_node)
2291 #define REM_EXPR TRUNC_MOD_EXPR
2292 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2293 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2295 #define FIELD(IS_STATIC, IS_PUT) \
2296 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2298 #define TEST(OPERAND_TYPE, CONDITION) \
2299 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2301 #define COND(OPERAND_TYPE, CONDITION) \
2302 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2304 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2305 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2307 #define BRANCH_GOTO(OPERAND_VALUE) \
2308 expand_java_goto (oldpc + OPERAND_VALUE)
2310 #define BRANCH_CALL(OPERAND_VALUE) \
2311 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2314 #define BRANCH_RETURN(OPERAND_VALUE) \
2316 tree type = OPERAND_TYPE##_type_node; \
2317 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2318 expand_java_ret (value); \
2322 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2323 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2324 fprintf (stderr, "(not implemented)\n")
2325 #define NOT_IMPL1(OPERAND_VALUE) \
2326 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2327 fprintf (stderr, "(not implemented)\n")
2329 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2331 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2333 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2335 #define STACK_SWAP(COUNT) java_stack_swap()
2337 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2338 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2339 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2341 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2342 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2344 #define LOOKUP_SWITCH \
2345 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2346 tree selector = pop_value (INT_type_node); \
2347 tree duplicate, label; \
2348 tree type = TREE_TYPE (selector); \
2349 flush_quick_stack (); \
2350 expand_start_case (0, selector, type, "switch statement");\
2351 push_momentary (); \
2352 while (--npairs >= 0) \
2354 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2355 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2356 TREE_TYPE (value) = type; \
2357 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2358 pushcase (value, convert, label, &duplicate); \
2359 expand_java_goto (oldpc + offset); \
2361 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2362 pushcase (NULL_TREE, 0, label, &duplicate); \
2363 expand_java_goto (oldpc + default_offset); \
2365 expand_end_case (selector); \
2368 #define TABLE_SWITCH \
2369 { jint default_offset = IMMEDIATE_s4; \
2370 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2371 tree selector = pop_value (INT_type_node); \
2372 tree duplicate, label; \
2373 tree type = TREE_TYPE (selector); \
2374 flush_quick_stack (); \
2375 expand_start_case (0, selector, type, "switch statement");\
2376 push_momentary (); \
2377 for (; low <= high; low++) \
2379 jint offset = IMMEDIATE_s4; \
2380 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2381 TREE_TYPE (value) = type; \
2382 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2383 pushcase (value, convert, label, &duplicate); \
2384 expand_java_goto (oldpc + offset); \
2386 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2387 pushcase (NULL_TREE, 0, label, &duplicate); \
2388 expand_java_goto (oldpc + default_offset); \
2390 expand_end_case (selector); \
2393 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2394 { int opcode = byte_ops[PC-1]; \
2395 int method_ref_index = IMMEDIATE_u2; \
2397 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2399 expand_invoke (opcode, method_ref_index, nargs); \
2402 /* Handle new, checkcast, instanceof */
2403 #define OBJECT(TYPE, OP) \
2404 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2406 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2408 #define ARRAY_LOAD(OPERAND_TYPE) \
2410 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2413 #define ARRAY_STORE(OPERAND_TYPE) \
2415 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2418 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2419 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2420 #define ARRAY_NEW_PTR() \
2421 push_value (build_anewarray (get_class_constant (current_jcf, \
2423 pop_value (int_type_node)));
2424 #define ARRAY_NEW_NUM() \
2426 int atype = IMMEDIATE_u1; \
2427 push_value (build_newarray (atype, pop_value (int_type_node)));\
2429 #define ARRAY_NEW_MULTI() \
2431 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2432 int ndims = IMMEDIATE_u1; \
2433 expand_java_multianewarray( class, ndims ); \
2436 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2437 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2438 pop_value (OPERAND_TYPE##_type_node))));
2440 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2442 push_value (build1 (NOP_EXPR, int_type_node, \
2443 (convert (TO_TYPE##_type_node, \
2444 pop_value (FROM_TYPE##_type_node))))); \
2447 #define CONVERT(FROM_TYPE, TO_TYPE) \
2449 push_value (convert (TO_TYPE##_type_node, \
2450 pop_value (FROM_TYPE##_type_node))); \
2453 /* internal macro added for use by the WIDE case
2454 Added TREE_TYPE (decl) assignment, apbianco */
2455 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2458 int var = OPVALUE; \
2459 tree type = OPTYPE; \
2460 value = pop_value (type); \
2461 type = TREE_TYPE (value); \
2462 decl = find_local_variable (var, type, oldpc); \
2463 set_local_type (var, type ); \
2464 expand_assignment (decl, value, 0, 0); \
2467 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2469 /* have to do this since OPERAND_VALUE may have side-effects */ \
2470 int opvalue = OPERAND_VALUE; \
2471 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2474 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2475 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2477 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2478 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2480 #define MONITOR_OPERATION(call) \
2482 tree o = pop_value (ptr_type_node); \
2484 flush_quick_stack (); \
2485 c = build_java_monitor (call, o); \
2486 TREE_SIDE_EFFECTS (c) = 1; \
2487 expand_expr_stmt (c); \
2490 #define SPECIAL_IINC(IGNORED) \
2492 unsigned int local_var_index = IMMEDIATE_u1; \
2493 int ival = IMMEDIATE_s1; \
2494 expand_iinc(local_var_index, ival, oldpc); \
2497 #define SPECIAL_WIDE(IGNORED) \
2499 int modified_opcode = IMMEDIATE_u1; \
2500 unsigned int local_var_index = IMMEDIATE_u2; \
2501 switch (modified_opcode) \
2505 int ival = IMMEDIATE_s2; \
2506 expand_iinc (local_var_index, ival, oldpc); \
2509 case OPCODE_iload: \
2510 case OPCODE_lload: \
2511 case OPCODE_fload: \
2512 case OPCODE_dload: \
2513 case OPCODE_aload: \
2515 /* duplicate code from LOAD macro */ \
2516 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2519 case OPCODE_istore: \
2520 case OPCODE_lstore: \
2521 case OPCODE_fstore: \
2522 case OPCODE_dstore: \
2523 case OPCODE_astore: \
2525 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2529 error ("unrecogized wide sub-instruction"); \
2533 #define SPECIAL_THROW(IGNORED) \
2534 build_java_athrow (pop_value (throwable_type_node))
2536 #define SPECIAL_BREAK NOT_IMPL1
2537 #define IMPL NOT_IMPL
2539 #include "javaop.def"
2542 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2547 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2548 order, as specified by Java Language Specification.
2550 The problem is that while expand_expr will evaluate its sub-operands in
2551 left-to-right order, for variables it will just return an rtx (i.e.
2552 an lvalue) for the variable (rather than an rvalue). So it is possible
2553 that a later sub-operand will change the register, and when the
2554 actual operation is done, it will use the new value, when it should
2555 have used the original value.
2557 We fix this by using save_expr. This forces the sub-operand to be
2558 copied into a fresh virtual register,
2562 force_evaluation_order (node)
2565 if (flag_syntax_only)
2567 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
2569 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2570 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2572 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2574 tree last_side_effecting_arg = NULL_TREE;
2575 tree arg = TREE_OPERAND (node, 1);
2576 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
2578 if (TREE_SIDE_EFFECTS (TREE_VALUE (arg)))
2579 last_side_effecting_arg = arg;
2581 arg = TREE_OPERAND (node, 1);
2582 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
2584 if (arg == last_side_effecting_arg)
2586 TREE_VALUE (arg) = save_expr (TREE_VALUE (arg));