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"
44 static void flush_quick_stack
PROTO ((void));
45 static void push_value
PROTO ((tree
));
46 static tree pop_value
PROTO ((tree
));
47 static void java_stack_swap
PROTO ((void));
48 static void java_stack_dup
PROTO ((int, int));
49 static void build_java_athrow
PROTO ((tree
));
50 static void build_java_jsr
PROTO ((tree
, tree
));
51 static void build_java_ret
PROTO ((tree
));
52 static void expand_java_multianewarray
PROTO ((tree
, int));
53 static void expand_java_arraystore
PROTO ((tree
));
54 static void expand_java_arrayload
PROTO ((tree
));
55 static void expand_java_array_length
PROTO ((void));
56 static tree build_java_monitor
PROTO ((tree
, tree
));
57 static void expand_java_pushc
PROTO ((int, tree
));
58 static void expand_java_return
PROTO ((tree
));
59 static void expand_java_NEW
PROTO ((tree
));
60 static void expand_java_INSTANCEOF
PROTO ((tree
));
61 static void expand_java_CHECKCAST
PROTO ((tree
));
62 static void expand_iinc
PROTO ((unsigned int, int, int));
63 static void expand_java_binop
PROTO ((tree
, enum tree_code
));
64 static void note_label
PROTO ((int, int));
65 static void expand_compare
PROTO ((enum tree_code
, tree
, tree
, int));
66 static void expand_test
PROTO ((enum tree_code
, tree
, int));
67 static void expand_cond
PROTO ((enum tree_code
, tree
, int));
68 static void expand_java_goto
PROTO ((int));
70 static void expand_java_call
PROTO ((int, int));
71 static void expand_java_ret
PROTO ((tree
));
73 static tree pop_arguments
PROTO ((tree
));
74 static void expand_invoke
PROTO ((int, int, int));
75 static void expand_java_field_op
PROTO ((int, int, int));
76 static void java_push_constant_from_pool
PROTO ((struct JCF
*, int));
77 static void java_stack_pop
PROTO ((int));
78 static tree build_java_throw_out_of_bounds_exception
PROTO ((tree
));
79 static tree build_java_check_indexed_type
PROTO ((tree
, tree
));
80 static tree java_array_data_offset
PROTO ((tree
));
81 static tree case_identity
PROTO ((tree
, tree
));
83 static tree operand_type
[59];
84 extern struct obstack permanent_obstack
;
87 init_expr_processing()
89 operand_type
[21] = operand_type
[54] = int_type_node
;
90 operand_type
[22] = operand_type
[55] = long_type_node
;
91 operand_type
[23] = operand_type
[56] = float_type_node
;
92 operand_type
[24] = operand_type
[57] = double_type_node
;
93 operand_type
[25] = operand_type
[58] = ptr_type_node
;
96 /* We store the stack state in two places:
97 Within a basic block, we use the quick_stack, which is a
98 pushdown list (TREE_LISTs) of expression nodes.
99 This is the top part of the stack; below that we use find_stack_slot.
100 At the end of a basic block, the quick_stack must be flushed
101 to the stack slot array (as handled by find_stack_slot).
102 Using quick_stack generates better code (especially when
103 compiled without optimization), because we do not have to
104 explicitly store and load trees to temporary variables.
106 If a variable is on the quick stack, it means the value of variable
107 when the quick stack was last flushed. Conceptually, flush_quick_stack
108 saves all the the quick_stack elements in parellel. However, that is
109 complicated, so it actually saves them (i.e. copies each stack value
110 to is home virtual register) from low indexes. This allows a quick_stack
111 element at index i (counting from the bottom of stack the) to references
112 slot virtuals for register that are >= i, but not those that are deeper.
113 This convention makes most operations easier. For example iadd works
114 even when the stack contains (reg[0], reg[1]): It results in the
115 stack containing (reg[0]+reg[1]), which is OK. However, some stack
116 operations are more complicated. For example dup given a stack
117 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
118 the convention, since stack value 1 would refer to a register with
119 lower index (reg[0]), which flush_quick_stack does not safely handle.
120 So dup cannot just add an extra element to the quick_stack, but iadd can.
123 tree quick_stack
= NULL_TREE
;
125 /* A free-list of unused permamnet TREE_LIST nodes. */
126 tree tree_list_free_list
= NULL_TREE
;
128 /* The stack pointer of the Java virtual machine.
129 This does include the size of the quick_stack. */
133 const unsigned char *linenumber_table
;
134 int linenumber_count
;
137 truthvalue_conversion (expr
)
140 /* It is simpler and generates better code to have only TRUTH_*_EXPR
141 or comparison expressions as truth values at this level.
143 This function should normally be identity for Java. */
145 switch (TREE_CODE (expr
))
148 case NE_EXPR
: case LE_EXPR
: case GE_EXPR
: case LT_EXPR
: case GT_EXPR
:
149 case TRUTH_ANDIF_EXPR
:
150 case TRUTH_ORIF_EXPR
:
157 return integer_zerop (expr
) ? boolean_false_node
: boolean_true_node
;
160 return real_zerop (expr
) ? boolean_false_node
: boolean_true_node
;
162 /* are these legal? XXX JH */
167 /* These don't change whether an object is non-zero or zero. */
168 return truthvalue_conversion (TREE_OPERAND (expr
, 0));
171 /* Distribute the conversion into the arms of a COND_EXPR. */
172 return fold (build (COND_EXPR
, boolean_type_node
, TREE_OPERAND (expr
, 0),
173 truthvalue_conversion (TREE_OPERAND (expr
, 1)),
174 truthvalue_conversion (TREE_OPERAND (expr
, 2))));
177 /* If this is widening the argument, we can ignore it. */
178 if (TYPE_PRECISION (TREE_TYPE (expr
))
179 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr
, 0))))
180 return truthvalue_conversion (TREE_OPERAND (expr
, 0));
181 /* fall through to default */
184 return fold (build (NE_EXPR
, boolean_type_node
, expr
, boolean_false_node
));
188 #ifdef JAVA_USE_HANDLES
189 /* Given a pointer to a handle, get a pointer to an object. */
195 tree field
, handle_type
;
196 expr
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (expr
)), expr
);
197 handle_type
= TREE_TYPE (expr
);
198 field
= TYPE_FIELDS (handle_type
);
199 expr
= build (COMPONENT_REF
, TREE_TYPE (field
), expr
, field
);
204 /* Save any stack slots that happen to be in the quick_stack into their
205 home virtual register slots.
207 The copy order is from low stack index to high, to support the invariant
208 that the expression for a slot may contain decls for stack slots with
209 higher (or the same) index, but not lower. */
214 int stack_index
= stack_pointer
;
215 register tree prev
, cur
, next
;
217 /* First reverse the quick_stack, and count the number of slots it has. */
218 for (cur
= quick_stack
, prev
= NULL_TREE
; cur
!= NULL_TREE
; cur
= next
)
220 next
= TREE_CHAIN (cur
);
221 TREE_CHAIN (cur
) = prev
;
223 stack_index
-= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur
)));
227 while (quick_stack
!= NULL_TREE
)
230 tree node
= quick_stack
, type
;
231 quick_stack
= TREE_CHAIN (node
);
232 TREE_CHAIN (node
) = tree_list_free_list
;
233 tree_list_free_list
= node
;
234 node
= TREE_VALUE (node
);
235 type
= TREE_TYPE (node
);
237 decl
= find_stack_slot (stack_index
, type
);
239 expand_assignment (decl
, node
, 0, 0);
240 stack_index
+= 1 + TYPE_IS_WIDE (type
);
249 type
= promote_type (type
);
250 n_words
= 1 + TYPE_IS_WIDE (type
);
251 if (stack_pointer
+ n_words
> DECL_MAX_STACK (current_function_decl
))
252 fatal ("stack overflow");
253 stack_type_map
[stack_pointer
++] = type
;
255 while (--n_words
>= 0)
256 stack_type_map
[stack_pointer
++] = TYPE_SECOND
;
263 tree type
= TREE_TYPE (value
);
264 if (TYPE_PRECISION (type
) < 32 && INTEGRAL_TYPE_P (type
))
266 type
= promote_type (type
);
267 value
= convert (type
, value
);
270 if (tree_list_free_list
== NULL_TREE
)
271 quick_stack
= perm_tree_cons (NULL_TREE
, value
, quick_stack
);
274 tree node
= tree_list_free_list
;
275 tree_list_free_list
= TREE_CHAIN (tree_list_free_list
);
276 TREE_VALUE (node
) = value
;
277 TREE_CHAIN (node
) = quick_stack
;
282 /* Pop a type from the type stack.
283 TYPE is the expected type. Return the actual type, which must be
284 convertible to TYPE, otherwise NULL_TREE is returned. */
292 if (TREE_CODE (type
) == RECORD_TYPE
)
293 type
= promote_type (type
);
294 n_words
= 1 + TYPE_IS_WIDE (type
);
295 if (stack_pointer
< n_words
)
296 fatal ("stack underflow");
297 while (--n_words
> 0)
299 if (stack_type_map
[--stack_pointer
] != void_type_node
)
300 fatal ("Invalid multi-word value on type stack");
302 t
= stack_type_map
[--stack_pointer
];
303 if (type
== NULL_TREE
|| t
== type
)
305 if (INTEGRAL_TYPE_P (type
) && INTEGRAL_TYPE_P (t
)
306 && TYPE_PRECISION (type
) <= 32 && TYPE_PRECISION (t
) <= 32)
308 if (TREE_CODE (type
) == POINTER_TYPE
&& TREE_CODE (t
) == POINTER_TYPE
)
310 if (type
== ptr_type_node
|| type
== object_ptr_type_node
)
312 else if (t
== ptr_type_node
) /* Special case for null reference. */
314 else if (can_widen_reference_to (t
, type
))
316 /* This is a kludge, but matches what Sun's verifier does.
317 It can be tricked, but is safe as long as type errors
318 (i.e. interface method calls) are caught at run-time. */
319 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type
)))
320 && t
== object_ptr_type_node
)
326 /* Pop a type from the type stack.
327 TYPE is the expected type. Return the actual type, which must be
328 convertible to TYPE, otherwise call error. */
334 tree t
= pop_type_0 (type
);
337 error ("unexpected type on stack");
341 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
342 Handles array types and interfaces. */
345 can_widen_reference_to (source_type
, target_type
)
346 tree source_type
, target_type
;
348 if (source_type
== ptr_type_node
|| target_type
== object_ptr_type_node
)
351 /* Get rid of pointers */
352 if (TREE_CODE (source_type
) == POINTER_TYPE
)
353 source_type
= TREE_TYPE (source_type
);
354 if (TREE_CODE (target_type
) == POINTER_TYPE
)
355 target_type
= TREE_TYPE (target_type
);
357 if (source_type
== target_type
)
361 source_type
= HANDLE_TO_CLASS_TYPE (source_type
);
362 target_type
= HANDLE_TO_CLASS_TYPE (target_type
);
363 if (TYPE_ARRAY_P (source_type
) || TYPE_ARRAY_P (target_type
))
365 HOST_WIDE_INT source_length
, target_length
;
366 if (TYPE_ARRAY_P (source_type
) != TYPE_ARRAY_P (target_type
))
368 target_length
= java_array_type_length (target_type
);
369 if (target_length
>= 0)
371 source_length
= java_array_type_length (source_type
);
372 if (source_length
!= target_length
)
375 source_type
= TYPE_ARRAY_ELEMENT (source_type
);
376 target_type
= TYPE_ARRAY_ELEMENT (target_type
);
377 if (source_type
== target_type
)
379 if (TREE_CODE (source_type
) != POINTER_TYPE
380 || TREE_CODE (target_type
) != POINTER_TYPE
)
382 return can_widen_reference_to (source_type
, target_type
);
386 int source_depth
= class_depth (source_type
);
387 int target_depth
= class_depth (target_type
);
389 if (CLASS_INTERFACE (TYPE_NAME (target_type
)))
391 /* target_type is OK if source_type or source_type ancestors
392 implement target_type. We handle multiple sub-interfaces */
394 tree basetype_vec
= TYPE_BINFO_BASETYPES (source_type
);
395 int n
= TREE_VEC_LENGTH (basetype_vec
), i
;
396 for (i
=0 ; i
< n
; i
++)
397 if (can_widen_reference_to
398 (TREE_TYPE (TREE_VEC_ELT (basetype_vec
, i
)),
405 for ( ; source_depth
> target_depth
; source_depth
--)
407 source_type
= TYPE_BINFO_BASETYPE (source_type
, 0);
409 return source_type
== target_type
;
418 type
= pop_type (type
);
421 tree node
= quick_stack
;
422 quick_stack
= TREE_CHAIN (quick_stack
);
423 TREE_CHAIN (node
) = tree_list_free_list
;
424 tree_list_free_list
= node
;
425 node
= TREE_VALUE (node
);
429 return find_stack_slot (stack_pointer
, promote_type (type
));
433 /* Pop and discrad the top COUNT stack slots. */
436 java_stack_pop (count
)
442 if (stack_pointer
== 0)
443 fatal ("stack underflow");
444 type
= stack_type_map
[stack_pointer
- 1];
445 if (type
== TYPE_SECOND
)
448 if (stack_pointer
== 1 || count
<= 0)
449 fatal ("stack underflow");
450 type
= stack_type_map
[stack_pointer
- 2];
452 val
= pop_value (type
);
457 /* Implement the 'swap' operator (to swap two top stack slots). */
466 if (stack_pointer
< 2
467 || (type1
= stack_type_map
[stack_pointer
- 1]) == TYPE_UNKNOWN
468 || (type2
= stack_type_map
[stack_pointer
- 2]) == TYPE_UNKNOWN
469 || type1
== TYPE_SECOND
|| type2
== TYPE_SECOND
470 || TYPE_IS_WIDE (type1
) || TYPE_IS_WIDE (type2
))
471 fatal ("bad stack swap");
473 flush_quick_stack ();
474 decl1
= find_stack_slot (stack_pointer
- 1, type1
);
475 decl2
= find_stack_slot (stack_pointer
- 2, type2
);
476 temp
= copy_to_reg (DECL_RTL (decl1
));
477 emit_move_insn (DECL_RTL (decl1
), DECL_RTL (decl2
));
478 emit_move_insn (DECL_RTL (decl2
), temp
);
479 stack_type_map
[stack_pointer
- 1] = type2
;
480 stack_type_map
[stack_pointer
- 2] = type1
;
484 java_stack_dup (size
, offset
)
487 int low_index
= stack_pointer
- size
- offset
;
490 error ("stack underflow - dup* operation");
492 flush_quick_stack ();
494 stack_pointer
+= size
;
495 dst_index
= stack_pointer
;
497 for (dst_index
= stack_pointer
; --dst_index
>= low_index
; )
500 int src_index
= dst_index
- size
;
501 if (src_index
< low_index
)
502 src_index
= dst_index
+ size
+ offset
;
503 type
= stack_type_map
[src_index
];
504 if (type
== TYPE_SECOND
)
506 if (src_index
<= low_index
)
507 fatal ("dup operation splits 64-bit number");
508 stack_type_map
[dst_index
] = type
;
509 src_index
--; dst_index
--;
510 type
= stack_type_map
[src_index
];
511 if (! TYPE_IS_WIDE (type
))
512 fatal ("internal error - dup operation");
514 else if (TYPE_IS_WIDE (type
))
515 fatal ("internal error - dup operation");
516 if (src_index
!= dst_index
)
518 tree src_decl
= find_stack_slot (src_index
, type
);
519 tree dst_decl
= find_stack_slot (dst_index
, type
);
520 emit_move_insn (DECL_RTL (dst_decl
), DECL_RTL (src_decl
));
521 stack_type_map
[dst_index
] = type
;
526 /* Calls _Jv_Throw. Discard the contents of the value stack. */
529 build_java_athrow (node
)
534 call
= build (CALL_EXPR
,
536 build_address_of (throw_node
),
537 build_tree_list (NULL_TREE
, node
),
539 TREE_SIDE_EFFECTS (call
) = 1;
540 expand_expr_stmt (call
);
541 java_stack_pop (stack_pointer
);
544 /* Implementation for jsr/ret */
547 build_java_jsr (where
, ret
)
551 tree ret_label
= fold (build1 (ADDR_EXPR
, return_address_type_node
, ret
));
552 push_value (ret_label
);
553 flush_quick_stack ();
559 build_java_ret (location
)
562 expand_computed_goto (location
);
565 /* Implementation of operations on array: new, load, store, length */
567 /* Array core info access macros */
569 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
570 size_binop (CEIL_DIV_EXPR, \
572 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
573 size_int (BITS_PER_UNIT))
576 decode_newarray_type (atype
)
581 case 4: return boolean_type_node
;
582 case 5: return char_type_node
;
583 case 6: return float_type_node
;
584 case 7: return double_type_node
;
585 case 8: return byte_type_node
;
586 case 9: return short_type_node
;
587 case 10: return int_type_node
;
588 case 11: return long_type_node
;
589 default: return NULL_TREE
;
593 /* Map primitive type to the code used by OPCODE_newarray. */
596 encode_newarray_type (type
)
599 if (type
== boolean_type_node
)
601 else if (type
== char_type_node
)
603 else if (type
== float_type_node
)
605 else if (type
== double_type_node
)
607 else if (type
== byte_type_node
)
609 else if (type
== short_type_node
)
611 else if (type
== int_type_node
)
613 else if (type
== long_type_node
)
616 fatal ("Can't compute type code - patch_newarray");
619 /* Build a call to _Jv_ThrowBadArrayIndex(), the
620 ArrayIndexOfBoundsException exception handler. */
623 build_java_throw_out_of_bounds_exception (index
)
626 tree node
= build (CALL_EXPR
, int_type_node
,
627 build_address_of (soft_badarrayindex_node
),
628 build_tree_list (NULL_TREE
, index
), NULL_TREE
);
629 TREE_SIDE_EFFECTS (node
) = 1; /* Allows expansion within ANDIF */
633 /* Return the length of an array. Doesn't perform any checking on the nature
634 or value of the array NODE. May be used to implement some bytecodes. */
637 build_java_array_length_access (node
)
640 tree type
= TREE_TYPE (node
);
641 HOST_WIDE_INT length
;
642 if (!is_array_type_p (type
))
643 fatal ("array length on a non-array reference");
644 length
= java_array_type_length (type
);
646 return build_int_2 (length
, 0);
647 return fold (build1 (INDIRECT_REF
,
649 fold (build (PLUS_EXPR
, ptr_type_node
,
651 JAVA_ARRAY_LENGTH_OFFSET(node
)))));
654 /* Optionally checks an array against the NULL pointer, eventually throwing a
655 NullPointerException. It could replace signal handling, but tied to NULL.
656 ARG1: the pointer to check, ARG2: the expression to use if
657 the pointer is non-null and ARG3 the type that should be returned. */
660 build_java_arraynull_check (node
, expr
, type
)
661 tree node ATTRIBUTE_UNUSED
;
663 tree type ATTRIBUTE_UNUSED
;
666 static int java_array_access_throws_null_exception
= 0;
668 if (java_array_access_throws_null_exception
)
669 return (build (COND_EXPR
,
671 build (EQ_EXPR
, int_type_node
, node
, null_pointer_node
),
672 build_java_athrow (node
), expr
));
679 java_array_data_offset (array
)
682 tree array_type
= TREE_TYPE (TREE_TYPE (array
));
683 tree data_fld
= TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type
)));
684 if (data_fld
== NULL_TREE
)
685 return size_in_bytes (array_type
);
687 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld
))
691 /* Implement array indexing (either as l-value or r-value).
692 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
693 Optionally performs bounds checking and/or test to NULL.
694 At this point, ARRAY should have been verified as an array. */
697 build_java_arrayaccess (array
, type
, index
)
698 tree array
, type
, index
;
700 tree arith
, node
, throw = NULL_TREE
;
702 arith
= fold (build (PLUS_EXPR
, int_type_node
,
703 java_array_data_offset (array
),
704 fold (build (MULT_EXPR
, int_type_node
,
705 index
, size_in_bytes(type
)))));
707 if (flag_bounds_check
)
710 * (unsigned jint) INDEX >= (unsigned jint) LEN
711 * && throw ArrayIndexOutOfBoundsException.
712 * Note this is equivalent to and more efficient than:
713 * INDEX < 0 || INDEX >= LEN && throw ... */
715 tree len
= build_java_array_length_access (array
);
716 TREE_TYPE (len
) = unsigned_int_type_node
;
717 test
= fold (build (GE_EXPR
, boolean_type_node
,
718 convert (unsigned_int_type_node
, index
),
720 if (! integer_zerop (test
))
722 throw = build (TRUTH_ANDIF_EXPR
, int_type_node
, test
,
723 build_java_throw_out_of_bounds_exception (index
));
724 /* allows expansion within COMPOUND */
725 TREE_SIDE_EFFECTS( throw ) = 1;
729 node
= build1 (INDIRECT_REF
, type
,
730 fold (build (PLUS_EXPR
, ptr_type_node
,
732 (throw ? build (COMPOUND_EXPR
, int_type_node
,
736 return (fold (build_java_arraynull_check (array
, node
, type
)));
739 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
740 ARRAY_NODE. This function is used to retrieve something less vague than
741 a pointer type when indexing the first dimension of something like [[<t>.
742 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
744 As a side effect, it also makes sure that ARRAY_NODE is an array. */
747 build_java_check_indexed_type (array_node
, indexed_type
)
753 if (!is_array_type_p (TREE_TYPE (array_node
)))
754 fatal ("array indexing on a non-array reference");
756 elt_type
= (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node
))));
758 if (indexed_type
== ptr_type_node
)
759 return promote_type (elt_type
);
761 /* BYTE/BOOLEAN store and load are used for both type */
762 if (indexed_type
== byte_type_node
&& elt_type
== boolean_type_node
)
763 return boolean_type_node
;
765 if (indexed_type
!= elt_type
)
766 fatal ("type array element mismatch");
771 /* newarray triggers a call to _Jv_NewArray. This function should be called
772 with an integer code (the type of array to create) and get from the stack
773 the size of the dimmension. */
776 build_newarray (atype_value
, length
)
780 tree type
= build_java_array_type (decode_newarray_type (atype_value
),
781 TREE_CODE (length
) == INTEGER_CST
782 ? TREE_INT_CST_LOW (length
)
784 return build (CALL_EXPR
, promote_type (type
),
785 build_address_of (soft_newarray_node
),
786 tree_cons (NULL_TREE
,
787 build_int_2 (atype_value
, 0),
788 build_tree_list (NULL_TREE
, length
)),
792 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
796 build_anewarray (class_type
, length
)
800 tree type
= build_java_array_type (class_type
,
801 TREE_CODE (length
) == INTEGER_CST
802 ? TREE_INT_CST_LOW (length
)
804 return build (CALL_EXPR
, promote_type (type
),
805 build_address_of (soft_anewarray_node
),
806 tree_cons (NULL_TREE
, length
,
807 tree_cons (NULL_TREE
, build_class_ref (class_type
),
808 build_tree_list (NULL_TREE
,
809 null_pointer_node
))),
813 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
816 build_new_array (type
, length
)
820 if (JPRIMITIVE_TYPE_P (type
))
821 return build_newarray (encode_newarray_type (type
), length
);
823 return build_anewarray (TREE_TYPE (type
), length
);
826 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
827 class pointer, a number of dimensions and the matching number of
828 dimensions. The argument list is NULL terminated. */
831 expand_java_multianewarray (class_type
, ndim
)
836 tree args
= build_tree_list( NULL_TREE
, null_pointer_node
);
838 for( i
= 0; i
< ndim
; i
++ )
839 args
= tree_cons (NULL_TREE
, pop_value (int_type_node
), args
);
841 push_value (build (CALL_EXPR
,
842 promote_type (class_type
),
843 build_address_of (soft_multianewarray_node
),
844 tree_cons (NULL_TREE
, build_class_ref (class_type
),
845 tree_cons (NULL_TREE
,
846 build_int_2 (ndim
, 0), args
)),
850 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
851 ARRAY is an array type. May expand some bound checking and NULL
852 pointer checking. RHS_TYPE_NODE we are going to store. In the case
853 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
854 INT. In those cases, we make the convertion.
856 if ARRAy is a reference type, the assignment is checked at run-time
857 to make sure that the RHS can be assigned to the array element
858 type. It is not necessary to generate this code if ARRAY is final. */
861 expand_java_arraystore (rhs_type_node
)
864 tree rhs_node
= pop_value ((INTEGRAL_TYPE_P (rhs_type_node
)
865 && TYPE_PRECISION (rhs_type_node
) <= 32) ?
866 int_type_node
: rhs_type_node
);
867 tree index
= pop_value (int_type_node
);
868 tree array
= pop_value (ptr_type_node
);
870 rhs_type_node
= build_java_check_indexed_type (array
, rhs_type_node
);
872 flush_quick_stack ();
874 index
= save_expr (index
);
875 array
= save_expr (array
);
877 if (TREE_CODE (rhs_type_node
) == POINTER_TYPE
)
879 tree check
= build (CALL_EXPR
, void_type_node
,
880 build_address_of (soft_checkarraystore_node
),
881 tree_cons (NULL_TREE
, array
,
882 build_tree_list (NULL_TREE
, rhs_node
)),
884 TREE_SIDE_EFFECTS (check
) = 1;
885 expand_expr_stmt (check
);
888 expand_assignment (build_java_arrayaccess (array
,
894 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
895 sure that LHS is an array type. May expand some bound checking and NULL
897 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
898 BOOLEAN/SHORT, we push a promoted type back to the stack.
902 expand_java_arrayload (lhs_type_node
)
906 tree index_node
= pop_value (int_type_node
);
907 tree array_node
= pop_value (ptr_type_node
);
909 index_node
= save_expr (index_node
);
910 array_node
= save_expr (array_node
);
911 lhs_type_node
= build_java_check_indexed_type (array_node
, lhs_type_node
);
913 load_node
= build_java_arrayaccess (array_node
,
917 if (INTEGRAL_TYPE_P (lhs_type_node
) && TYPE_PRECISION (lhs_type_node
) <= 32)
918 load_node
= fold (build1 (NOP_EXPR
, int_type_node
, load_node
));
919 push_value (load_node
);
922 /* Expands .length. Makes sure that we deal with and array and may expand
923 a NULL check on the array object. */
926 expand_java_array_length ()
928 tree array
= pop_value (ptr_type_node
);
929 tree length
= build_java_array_length_access (array
);
931 push_value (build_java_arraynull_check (array
, length
, int_type_node
));
934 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
935 either soft_monitorenter_node or soft_monitorexit_node. */
938 build_java_monitor (call
, object
)
942 return (build (CALL_EXPR
,
944 build_address_of (call
),
945 build_tree_list (NULL_TREE
, object
),
949 /* Emit code for one of the PUSHC instructions. */
952 expand_java_pushc (ival
, type
)
957 if (type
== ptr_type_node
&& ival
== 0)
958 value
= null_pointer_node
;
959 else if (type
== int_type_node
|| type
== long_type_node
)
961 value
= build_int_2 (ival
, ival
< 0 ? -1 : 0);
962 TREE_TYPE (value
) = type
;
964 else if (type
== float_type_node
|| type
== double_type_node
)
967 #ifdef REAL_ARITHMETIC
968 REAL_VALUE_FROM_INT (x
, ival
, 0, TYPE_MODE (type
));
972 value
= build_real (type
, x
);
975 fatal ("internal error in expand_java_pushc");
980 expand_java_return (type
)
983 if (type
== void_type_node
)
984 expand_null_return ();
987 tree retval
= pop_value (type
);
988 tree res
= DECL_RESULT (current_function_decl
);
989 retval
= build (MODIFY_EXPR
, TREE_TYPE (res
), res
, retval
);
990 TREE_SIDE_EFFECTS (retval
) = 1;
991 expand_return (retval
);
996 build_address_of (value
)
999 return build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (value
)), value
);
1003 expand_java_NEW (type
)
1006 if (! CLASS_LOADED_P (type
))
1007 load_class (type
, 1);
1008 layout_class_methods (type
);
1009 push_value (build (CALL_EXPR
, promote_type (type
),
1010 build_address_of (alloc_object_node
),
1011 tree_cons (NULL_TREE
, build_class_ref (type
),
1012 build_tree_list (NULL_TREE
,
1013 size_in_bytes (type
))),
1018 expand_java_INSTANCEOF (type
)
1021 tree value
= pop_value (object_ptr_type_node
);
1022 value
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (soft_instanceof_node
)),
1023 build_address_of (soft_instanceof_node
),
1024 tree_cons (NULL_TREE
, value
,
1025 build_tree_list (NULL_TREE
,
1026 build_class_ref (type
))),
1032 expand_java_CHECKCAST (type
)
1035 tree value
= pop_value (ptr_type_node
);
1036 value
= build (CALL_EXPR
, promote_type (type
),
1037 build_address_of (soft_checkcast_node
),
1038 tree_cons (NULL_TREE
, build_class_ref (type
),
1039 build_tree_list (NULL_TREE
, value
)),
1045 expand_iinc (local_var_index
, ival
, pc
)
1046 unsigned int local_var_index
;
1050 tree local_var
, res
;
1051 tree constant_value
;
1053 flush_quick_stack ();
1054 local_var
= find_local_variable (local_var_index
, int_type_node
, pc
);
1055 constant_value
= build_int_2 (ival
, ival
< 0 ? -1 : 0);
1056 res
= fold (build (PLUS_EXPR
, int_type_node
, local_var
, constant_value
));
1057 expand_assignment (local_var
, res
, 0, 0);
1062 build_java_soft_divmod (op
, type
, op1
, op2
)
1064 tree type
, op1
, op2
;
1067 tree arg1
= convert (type
, op1
);
1068 tree arg2
= convert (type
, op2
);
1070 if (type
== int_type_node
)
1074 case TRUNC_DIV_EXPR
:
1075 call
= soft_idiv_node
;
1077 case TRUNC_MOD_EXPR
:
1078 call
= soft_irem_node
;
1084 else if (type
== long_type_node
)
1088 case TRUNC_DIV_EXPR
:
1089 call
= soft_ldiv_node
;
1091 case TRUNC_MOD_EXPR
:
1092 call
= soft_lrem_node
;
1100 fatal ("Internal compiler error in build_java_soft_divmod");
1102 call
= build (CALL_EXPR
, type
,
1103 build_address_of (call
),
1104 tree_cons (NULL_TREE
, arg1
,
1105 build_tree_list (NULL_TREE
, arg2
)),
1112 build_java_binop (op
, type
, arg1
, arg2
)
1114 tree type
, arg1
, arg2
;
1121 tree u_type
= unsigned_type (type
);
1122 arg1
= convert (u_type
, arg1
);
1123 arg1
= build_java_binop (RSHIFT_EXPR
, u_type
, arg1
, arg2
);
1124 return convert (type
, arg1
);
1128 mask
= build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1
)) - 1, 0);
1129 arg2
= fold (build (BIT_AND_EXPR
, int_type_node
, arg2
, mask
));
1132 case COMPARE_L_EXPR
: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1133 case COMPARE_G_EXPR
: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1134 arg1
= save_expr (arg1
); arg2
= save_expr (arg2
);
1136 tree ifexp1
= fold ( build (op
== COMPARE_L_EXPR
? GT_EXPR
: LT_EXPR
,
1137 boolean_type_node
, arg1
, arg2
));
1138 tree ifexp2
= fold ( build (EQ_EXPR
, boolean_type_node
, arg1
, arg2
));
1139 tree second_compare
= fold (build (COND_EXPR
, int_type_node
,
1140 ifexp2
, integer_zero_node
,
1141 op
== COMPARE_L_EXPR
1142 ? integer_negative_one_node
1143 : integer_one_node
));
1144 return fold (build (COND_EXPR
, int_type_node
, ifexp1
,
1145 op
== COMPARE_L_EXPR
? integer_one_node
1146 : integer_negative_one_node
,
1150 arg1
= save_expr (arg1
); arg2
= save_expr (arg2
);
1152 tree ifexp1
= fold ( build (LT_EXPR
, boolean_type_node
, arg1
, arg2
));
1153 tree ifexp2
= fold ( build (GT_EXPR
, boolean_type_node
, arg1
, arg2
));
1154 tree second_compare
= fold ( build (COND_EXPR
, int_type_node
,
1155 ifexp2
, integer_one_node
,
1156 integer_zero_node
));
1157 return fold (build (COND_EXPR
, int_type_node
,
1158 ifexp1
, integer_negative_one_node
, second_compare
));
1160 case TRUNC_DIV_EXPR
:
1161 case TRUNC_MOD_EXPR
:
1162 if (TREE_CODE (type
) == REAL_TYPE
1163 && op
== TRUNC_MOD_EXPR
)
1166 if (type
!= double_type_node
)
1168 arg1
= convert (double_type_node
, arg1
);
1169 arg2
= convert (double_type_node
, arg2
);
1171 call
= build (CALL_EXPR
, double_type_node
,
1172 build_address_of (soft_fmod_node
),
1173 tree_cons (NULL_TREE
, arg1
,
1174 build_tree_list (NULL_TREE
, arg2
)),
1176 if (type
!= double_type_node
)
1177 call
= convert (type
, call
);
1181 if (TREE_CODE (type
) == INTEGER_TYPE
1182 && flag_use_divide_subroutine
1183 && ! flag_syntax_only
)
1184 return build_java_soft_divmod (op
, type
, arg1
, arg2
);
1189 return fold (build (op
, type
, arg1
, arg2
));
1193 expand_java_binop (type
, op
)
1194 tree type
; enum tree_code op
;
1204 rtype
= int_type_node
;
1205 rarg
= pop_value (rtype
);
1208 rarg
= pop_value (rtype
);
1210 larg
= pop_value (ltype
);
1211 push_value (build_java_binop (op
, type
, larg
, rarg
));
1214 /* Lookup the field named NAME in *TYPEP or its super classes.
1215 If not found, return NULL_TREE.
1216 (If the *TYPEP is not found, return error_mark_node.)
1217 If found, return the FIELD_DECL, and set *TYPEP to the
1218 class containing the field. */
1221 lookup_field (typep
, name
)
1225 if (CLASS_P (*typep
) && !CLASS_LOADED_P (*typep
))
1227 load_class (*typep
, 1);
1228 if (!TYPE_SIZE (*typep
) || TREE_CODE (TYPE_SIZE (*typep
)) == ERROR_MARK
)
1229 return error_mark_node
;
1233 tree field
, basetype_vec
;
1236 for (field
= TYPE_FIELDS (*typep
); field
; field
= TREE_CHAIN (field
))
1237 if (DECL_NAME (field
) == name
)
1240 /* Process implemented interfaces. */
1241 basetype_vec
= TYPE_BINFO_BASETYPES (*typep
);
1242 n
= TREE_VEC_LENGTH (basetype_vec
);
1243 for (i
= 0; i
< n
; i
++)
1245 tree t
= BINFO_TYPE (TREE_VEC_ELT (basetype_vec
, i
));
1246 if ((field
= lookup_field (&t
, name
)))
1249 *typep
= CLASSTYPE_SUPER (*typep
);
1254 /* Look up the field named NAME in object SELF_VALUE,
1255 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1256 SELF_VALUE is NULL_TREE if looking for a static field. */
1259 build_field_ref (self_value
, self_class
, name
)
1260 tree self_value
, self_class
, name
;
1262 tree base_class
= self_class
;
1263 tree field_decl
= lookup_field (&base_class
, name
);
1264 if (field_decl
== NULL_TREE
)
1266 error ("field `%s' not found", IDENTIFIER_POINTER (name
));
1267 return error_mark_node
;
1269 if (self_value
== NULL_TREE
)
1271 return build_static_field_ref (field_decl
);
1275 tree base_handle_type
= promote_type (base_class
);
1276 if (base_handle_type
!= TREE_TYPE (self_value
))
1277 self_value
= fold (build1 (NOP_EXPR
, base_handle_type
, self_value
));
1278 #ifdef JAVA_USE_HANDLES
1279 self_value
= unhand_expr (self_value
);
1281 self_value
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (self_value
)),
1283 return fold (build (COMPONENT_REF
, TREE_TYPE (field_decl
),
1284 self_value
, field_decl
));
1294 ASM_GENERATE_INTERNAL_LABEL(buf
, "LJpc=", pc
);
1295 name
= get_identifier (buf
);
1296 if (IDENTIFIER_LOCAL_VALUE (name
))
1297 return IDENTIFIER_LOCAL_VALUE (name
);
1300 /* The type of the address of a label is return_address_type_node. */
1301 tree decl
= create_label_decl (name
);
1302 LABEL_PC (decl
) = pc
;
1304 return pushdecl (decl
);
1308 /* Generate a unique name for the purpose of loops and switches
1309 labels, and try-catch-finally blocks label or temporary variables. */
1314 static int l_number
= 0;
1316 ASM_GENERATE_INTERNAL_LABEL(buff
, "LJv", l_number
);
1318 return get_identifier (buff
);
1322 create_label_decl (name
)
1326 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1327 decl
= build_decl (LABEL_DECL
, name
,
1328 TREE_TYPE (return_address_type_node
));
1330 DECL_CONTEXT (decl
) = current_function_decl
;
1331 DECL_IGNORED_P (decl
) = 1;
1335 /* This maps a bytecode offset (PC) to various flags. */
1336 char *instruction_bits
;
1339 note_label (current_pc
, target_pc
)
1340 int current_pc ATTRIBUTE_UNUSED
, target_pc
;
1342 lookup_label (target_pc
);
1343 instruction_bits
[target_pc
] |= BCODE_JUMP_TARGET
;
1346 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1347 where CONDITION is one of one the compare operators. */
1350 expand_compare (condition
, value1
, value2
, target_pc
)
1351 enum tree_code condition
;
1352 tree value1
, value2
;
1355 tree target
= lookup_label (target_pc
);
1356 tree cond
= fold (build (condition
, boolean_type_node
, value1
, value2
));
1357 expand_start_cond (truthvalue_conversion (cond
), 0);
1358 expand_goto (target
);
1362 /* Emit code for a TEST-type opcode. */
1365 expand_test (condition
, type
, target_pc
)
1366 enum tree_code condition
;
1370 tree value1
, value2
;
1371 flush_quick_stack ();
1372 value1
= pop_value (type
);
1373 value2
= (type
== ptr_type_node
) ? null_pointer_node
: integer_zero_node
;
1374 expand_compare (condition
, value1
, value2
, target_pc
);
1377 /* Emit code for a COND-type opcode. */
1380 expand_cond (condition
, type
, target_pc
)
1381 enum tree_code condition
;
1385 tree value1
, value2
;
1386 flush_quick_stack ();
1387 /* note: pop values in opposite order */
1388 value2
= pop_value (type
);
1389 value1
= pop_value (type
);
1390 /* Maybe should check value1 and value2 for type compatibility ??? */
1391 expand_compare (condition
, value1
, value2
, target_pc
);
1395 expand_java_goto (target_pc
)
1398 tree target_label
= lookup_label (target_pc
);
1399 flush_quick_stack ();
1400 expand_goto (target_label
);
1405 expand_java_call (target_pc
, return_address
)
1406 int target_pc
, return_address
;
1408 tree target_label
= lookup_label (target_pc
);
1409 tree value
= build_int_2 (return_address
, return_address
< 0 ? -1 : 0);
1411 flush_quick_stack ();
1412 expand_goto (target_label
);
1416 expand_java_ret (return_address
)
1417 tree return_address ATTRIBUTE_UNUSED
;
1419 warning ("ret instruction not implemented");
1421 tree target_label
= lookup_label (target_pc
);
1422 flush_quick_stack ();
1423 expand_goto (target_label
);
1428 /* Recursive helper function to pop argument types during verifiation. */
1431 pop_argument_types (arg_types
)
1434 if (arg_types
== end_params_node
)
1436 if (TREE_CODE (arg_types
) == TREE_LIST
)
1438 pop_argument_types (TREE_CHAIN (arg_types
));
1439 pop_type (TREE_VALUE (arg_types
));
1446 pop_arguments (arg_types
)
1449 if (arg_types
== end_params_node
)
1451 if (TREE_CODE (arg_types
) == TREE_LIST
)
1453 tree tail
= pop_arguments (TREE_CHAIN (arg_types
));
1454 tree type
= TREE_VALUE (arg_types
);
1455 tree arg
= pop_value (type
);
1456 if (PROMOTE_PROTOTYPES
1457 && TYPE_PRECISION (type
) < TYPE_PRECISION (integer_type_node
)
1458 && INTEGRAL_TYPE_P (type
))
1459 arg
= convert (integer_type_node
, arg
);
1460 return tree_cons (NULL_TREE
, arg
, tail
);
1465 /* Build an expression to initialize the class CLAS.
1466 if EXPR is non-NULL, returns an expression to first call the initializer
1467 (if it is needed) and then calls EXPR. */
1470 build_class_init (clas
, expr
)
1474 if (inherits_from_p (current_class
, clas
))
1476 init
= build (CALL_EXPR
, void_type_node
,
1477 build_address_of (soft_initclass_node
),
1478 build_tree_list (NULL_TREE
, build_class_ref (clas
)),
1480 TREE_SIDE_EFFECTS (init
) = 1;
1481 if (expr
!= NULL_TREE
)
1483 expr
= build (COMPOUND_EXPR
, TREE_TYPE (expr
), init
, expr
);
1484 TREE_SIDE_EFFECTS (expr
) = 1;
1490 static tree methods_ident
= NULL_TREE
;
1491 static tree ncode_ident
= NULL_TREE
;
1492 tree dtable_ident
= NULL_TREE
;
1495 build_known_method_ref (method
, method_type
, self_type
, method_signature
, arg_list
)
1496 tree method
, method_type ATTRIBUTE_UNUSED
, self_type
,
1497 method_signature ATTRIBUTE_UNUSED
, arg_list ATTRIBUTE_UNUSED
;
1500 if (is_compiled_class (self_type
))
1502 make_decl_rtl (method
, NULL
, 1);
1503 func
= build1 (ADDR_EXPR
, method_ptr_type_node
, method
);
1507 /* We don't know whether the method has been (statically) compiled.
1508 Compile this code to get a reference to the method's code:
1510 SELF_TYPE->methods[METHOD_INDEX].ncode
1512 This is guaranteed to work (assuming SELF_TYPE has
1513 been initialized), since if the method is not compiled yet,
1514 its ncode points to a trampoline that forces compilation. */
1516 int method_index
= 0;
1518 tree ref
= build_class_ref (self_type
);
1519 ref
= build1 (INDIRECT_REF
, class_type_node
, ref
);
1520 if (ncode_ident
== NULL_TREE
)
1521 ncode_ident
= get_identifier ("ncode");
1522 if (methods_ident
== NULL_TREE
)
1523 methods_ident
= get_identifier ("methods");
1524 ref
= build (COMPONENT_REF
, method_ptr_type_node
, ref
,
1525 lookup_field (&class_type_node
, methods_ident
));
1526 for (meth
= TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type
));
1527 ; meth
= TREE_CHAIN (meth
))
1531 if (meth
== NULL_TREE
)
1532 fatal ("method '%s' not found in class",
1533 IDENTIFIER_POINTER (DECL_NAME (method
)));
1536 method_index
*= int_size_in_bytes (method_type_node
);
1537 ref
= fold (build (PLUS_EXPR
, method_ptr_type_node
,
1538 ref
, build_int_2 (method_index
, 0)));
1539 ref
= build1 (INDIRECT_REF
, method_type_node
, ref
);
1540 func
= build (COMPONENT_REF
, nativecode_ptr_type_node
,
1542 lookup_field (&method_type_node
, ncode_ident
));
1548 invoke_build_dtable (is_invoke_interface
, arg_list
)
1549 int is_invoke_interface
;
1552 tree dtable
, objectref
;
1554 TREE_VALUE (arg_list
) = save_expr (TREE_VALUE (arg_list
));
1556 /* If we're dealing with interfaces and if the objectref
1557 argument is an array then get the dispatch table of the class
1558 Object rather than the one from the objectref. */
1559 objectref
= (is_invoke_interface
1560 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list
))) ?
1561 object_type_node
: TREE_VALUE (arg_list
));
1563 if (dtable_ident
== NULL_TREE
)
1564 dtable_ident
= get_identifier ("vtable");
1565 dtable
= build1 (INDIRECT_REF
, object_type_node
, objectref
);
1566 dtable
= build (COMPONENT_REF
, dtable_ptr_type
, dtable
,
1567 lookup_field (&object_type_node
, dtable_ident
));
1573 build_invokevirtual (dtable
, method
)
1574 tree dtable
, method
;
1577 tree nativecode_ptr_ptr_type_node
1578 = build_pointer_type (nativecode_ptr_type_node
);
1579 int method_index
= TREE_INT_CST_LOW (DECL_VINDEX (method
));
1580 /* Add one to skip "class" field of dtable, and one to skip unused
1581 vtable entry (for C++ compatibility). */
1584 *= int_size_in_bytes (nativecode_ptr_ptr_type_node
);
1585 func
= fold (build (PLUS_EXPR
, nativecode_ptr_ptr_type_node
,
1586 dtable
, build_int_2 (method_index
, 0)));
1587 func
= build1 (INDIRECT_REF
, nativecode_ptr_type_node
, func
);
1593 build_invokeinterface (dtable
, method_name
, method_signature
)
1594 tree dtable
, method_name
, method_signature
;
1596 static tree class_ident
= NULL_TREE
;
1599 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1600 ensure that the selected method exists, is public and not
1601 abstract nor static. */
1603 if (class_ident
== NULL_TREE
)
1604 class_ident
= get_identifier ("class");
1606 dtable
= build1 (INDIRECT_REF
, dtable_type
, dtable
);
1607 dtable
= build (COMPONENT_REF
, class_ptr_type
, dtable
,
1608 lookup_field (&dtable_type
, class_ident
));
1609 lookup_arg
= build_tree_list (NULL_TREE
,
1612 (IDENTIFIER_POINTER(method_signature
),
1613 IDENTIFIER_LENGTH(method_signature
)))));
1614 lookup_arg
= tree_cons (NULL_TREE
, dtable
,
1615 tree_cons (NULL_TREE
, build_utf8_ref (method_name
),
1617 return build (CALL_EXPR
, ptr_type_node
,
1618 build_address_of (soft_lookupinterfacemethod_node
),
1619 lookup_arg
, NULL_TREE
);
1622 /* Expand one of the invoke_* opcodes.
1623 OCPODE is the specific opcode.
1624 METHOD_REF_INDEX is an index into the constant pool.
1625 NARGS is the number of arguments, or -1 if not specified. */
1628 expand_invoke (opcode
, method_ref_index
, nargs
)
1630 int method_ref_index
;
1631 int nargs ATTRIBUTE_UNUSED
;
1633 tree method_signature
= COMPONENT_REF_SIGNATURE(¤t_jcf
->cpool
, method_ref_index
);
1634 tree method_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, method_ref_index
);
1635 tree self_type
= get_class_constant
1636 (current_jcf
, COMPONENT_REF_CLASS_INDEX(¤t_jcf
->cpool
, method_ref_index
));
1637 const char *self_name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type
)));
1638 tree call
, func
, method
, arg_list
, method_type
;
1640 if (! CLASS_LOADED_P (self_type
))
1642 load_class (self_type
, 1);
1643 if (TREE_CODE (TYPE_SIZE (self_type
)) == ERROR_MARK
)
1644 fatal ("failed to find class '%s'", self_name
);
1646 layout_class_methods (self_type
);
1648 if (method_name
== init_identifier_node
)
1649 method
= lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type
),
1652 method
= lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type
),
1653 method_name
, method_signature
);
1654 if (method
== NULL_TREE
)
1656 error ("Class '%s' has no method named '%s' matching signature '%s'",
1658 IDENTIFIER_POINTER (method_name
),
1659 IDENTIFIER_POINTER (method_signature
));
1661 /* Invoke static can't invoke static/abstract method */
1662 else if (opcode
== OPCODE_invokestatic
)
1664 if (!METHOD_STATIC (method
))
1666 error ("invokestatic on non static method");
1669 else if (METHOD_ABSTRACT (method
))
1671 error ("invokestatic on abstract method");
1677 if (METHOD_STATIC (method
))
1679 error ("invoke[non-static] on static method");
1684 if (method
== NULL_TREE
)
1686 method_type
= get_type_from_signature (method_signature
);
1687 pop_arguments (TYPE_ARG_TYPES (method_type
));
1688 if (opcode
!= OPCODE_invokestatic
)
1689 pop_type (self_type
);
1690 method_type
= promote_type (TREE_TYPE (method_type
));
1691 push_value (convert (method_type
, integer_zero_node
));
1695 method_type
= TREE_TYPE (method
);
1696 arg_list
= pop_arguments (TYPE_ARG_TYPES (method_type
));
1697 flush_quick_stack ();
1700 if (opcode
== OPCODE_invokestatic
|| opcode
== OPCODE_invokespecial
1701 || (opcode
== OPCODE_invokevirtual
1702 && (METHOD_PRIVATE (method
)
1703 || METHOD_FINAL (method
)
1704 || CLASS_FINAL (TYPE_NAME (self_type
)))))
1705 func
= build_known_method_ref (method
, method_type
, self_type
,
1706 method_signature
, arg_list
);
1709 tree dtable
= invoke_build_dtable (opcode
== OPCODE_invokeinterface
,
1711 if (opcode
== OPCODE_invokevirtual
)
1712 func
= build_invokevirtual (dtable
, method
);
1714 func
= build_invokeinterface (dtable
, method_name
, method_signature
);
1716 func
= build1 (NOP_EXPR
, build_pointer_type (method_type
), func
);
1717 call
= build (CALL_EXPR
, TREE_TYPE (method_type
), func
, arg_list
, NULL_TREE
);
1718 TREE_SIDE_EFFECTS (call
) = 1;
1720 if (TREE_CODE (TREE_TYPE (method_type
)) == VOID_TYPE
)
1721 expand_expr_stmt (call
);
1725 flush_quick_stack ();
1730 /* Expand an operation to extract from or store into a field.
1731 IS_STATIC is 1 iff the field is static.
1732 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1733 FIELD_REF_INDEX is an index into the constant pool. */
1736 expand_java_field_op (is_static
, is_putting
, field_ref_index
)
1739 int field_ref_index
;
1742 get_class_constant (current_jcf
,
1743 COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
1745 const char *self_name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type
)));
1746 tree field_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, field_ref_index
);
1747 tree field_signature
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
,
1749 tree field_type
= get_type_from_signature (field_signature
);
1750 tree new_value
= is_putting
? pop_value (field_type
) : NULL_TREE
;
1753 tree field_decl
= lookup_field (&self_type
, field_name
);
1754 if (field_decl
== error_mark_node
)
1758 else if (field_decl
== NULL_TREE
)
1760 error ("Missing field '%s' in '%s'",
1761 IDENTIFIER_POINTER (field_name
), self_name
);
1764 else if (build_java_signature (TREE_TYPE (field_decl
)) != field_signature
)
1766 error ("Mismatching signature for field '%s' in '%s'",
1767 IDENTIFIER_POINTER (field_name
), self_name
);
1770 field_ref
= is_static
? NULL_TREE
: pop_value (self_type
);
1774 push_value (convert (field_type
, integer_zero_node
));
1775 flush_quick_stack ();
1779 /* Inline references to java.lang.PRIMTYPE.TYPE.
1780 In addition to being a useful (minor) optimization,
1781 this is also needed to avoid circularities in the implementation
1782 of these fields in libjava. */
1783 if (field_name
== TYPE_identifier_node
&& ! is_putting
1784 && ! flag_emit_class_files
&& field_type
== class_ptr_type
1785 && strncmp (self_name
, "java.lang.", 10) == 0)
1787 tree typ
= build_primtype_type_ref (self_name
);
1795 field_ref
= build_field_ref (field_ref
, self_type
, field_name
);
1797 field_ref
= build_class_init (self_type
, field_ref
);
1800 flush_quick_stack ();
1801 if (FIELD_FINAL (field_decl
))
1803 if (DECL_CONTEXT (field_decl
) != current_class
)
1804 error_with_decl (field_decl
,
1805 "assignment to final field `%s' not in field's class");
1806 else if (FIELD_STATIC (field_decl
))
1808 if (!IS_CLINIT (current_function_decl
))
1809 error_with_decl (field_decl
,
1810 "assignment to final static field `%s' not in class initializer");
1814 if (! DECL_CONSTRUCTOR_P (current_function_decl
))
1815 error_with_decl (field_decl
, "assignment to final field `%s' "
1816 "not in constructor");
1819 expand_assignment (field_ref
, new_value
, 0, 0);
1822 push_value (field_ref
);
1826 build_primtype_type_ref (self_name
)
1827 const char *self_name
;
1829 const char *class_name
= self_name
+10;
1831 if (strncmp(class_name
, "Byte", 4) == 0)
1832 typ
= byte_type_node
;
1833 else if (strncmp(class_name
, "Short", 5) == 0)
1834 typ
= short_type_node
;
1835 else if (strncmp(class_name
, "Integer", 7) == 0)
1836 typ
= int_type_node
;
1837 else if (strncmp(class_name
, "Long", 4) == 0)
1838 typ
= long_type_node
;
1839 else if (strncmp(class_name
, "Float", 5) == 0)
1840 typ
= float_type_node
;
1841 else if (strncmp(class_name
, "Double", 6) == 0)
1842 typ
= double_type_node
;
1843 else if (strncmp(class_name
, "Boolean", 7) == 0)
1844 typ
= boolean_type_node
;
1845 else if (strncmp(class_name
, "Char", 4) == 0)
1846 typ
= char_type_node
;
1847 else if (strncmp(class_name
, "Void", 4) == 0)
1848 typ
= void_type_node
;
1851 if (typ
!= NULL_TREE
)
1852 return build_class_ref (typ
);
1858 load_type_state (label
)
1862 tree vec
= LABEL_TYPE_STATE (label
);
1863 int cur_length
= TREE_VEC_LENGTH (vec
);
1864 stack_pointer
= cur_length
- DECL_MAX_LOCALS(current_function_decl
);
1865 for (i
= 0; i
< cur_length
; i
++)
1866 type_map
[i
] = TREE_VEC_ELT (vec
, i
);
1869 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1870 dependant things, but they rely on gcc routines. This function is
1871 placed here because it uses things defined locally in parse.y. */
1874 case_identity (t
, v
)
1875 tree t
__attribute__ ((__unused__
));
1882 java_lang_expand_expr (exp
, target
, tmode
, modifier
)
1884 rtx target ATTRIBUTE_UNUSED
;
1885 enum machine_mode tmode ATTRIBUTE_UNUSED
;
1886 enum expand_modifier modifier ATTRIBUTE_UNUSED
;
1890 switch (TREE_CODE (exp
))
1892 case NEW_ARRAY_INIT
:
1895 tree array_type
= TREE_TYPE (TREE_TYPE (exp
));
1896 tree element_type
= TYPE_ARRAY_ELEMENT (array_type
);
1897 tree data_fld
= TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type
)));
1898 HOST_WIDE_INT ilength
= java_array_type_length (array_type
);
1899 tree length
= build_int_2 (ilength
, 0);
1900 tree init
= TREE_OPERAND (exp
, 0);
1903 /* Enable this once we can set the vtable field statically. FIXME */
1904 if (TREE_CONSTANT (init
) && TREE_STATIC (exp
)
1905 && JPRIMITIVE_TYPE_P (element_type
))
1907 tree temp
, value
, init_decl
;
1908 START_RECORD_CONSTRUCTOR (temp
, object_type_node
);
1909 PUSH_FIELD_VALUE (temp
, "vtable",
1910 null_pointer_node
/* FIXME */
1912 PUSH_FIELD_VALUE (temp
, "sync_info", null_pointer_node
);
1913 FINISH_RECORD_CONSTRUCTOR (temp
);
1914 START_RECORD_CONSTRUCTOR (value
, array_type
);
1915 PUSH_SUPER_VALUE (value
, temp
);
1916 PUSH_FIELD_VALUE (value
, "length", length
);
1917 PUSH_FIELD_VALUE (value
, "data", init
);
1918 FINISH_RECORD_CONSTRUCTOR (value
);
1920 init_decl
= build_decl (VAR_DECL
, generate_name (), array_type
);
1921 pushdecl_top_level (init_decl
);
1922 TREE_STATIC (init_decl
) = 1;
1923 DECL_INITIAL (init_decl
) = value
;
1924 DECL_IGNORED_P (init_decl
) = 1;
1925 TREE_READONLY (init_decl
) = 1;
1926 make_decl_rtl (init_decl
, NULL
, 1);
1927 init
= build1 (ADDR_EXPR
, TREE_TYPE (exp
), init_decl
);
1928 return expand_expr (init
, target
, tmode
, modifier
);
1931 array_decl
= build_decl (VAR_DECL
, NULL_TREE
, TREE_TYPE (exp
));
1932 expand_decl (array_decl
);
1933 tmp
= expand_assignment (array_decl
,
1934 build_new_array (element_type
, length
),
1936 if (TREE_CONSTANT (init
)
1937 && ilength
>= 10 && JPRIMITIVE_TYPE_P (element_type
))
1939 tree init_decl
= build_decl (VAR_DECL
, generate_name (),
1941 pushdecl_top_level (init_decl
);
1942 TREE_STATIC (init_decl
) = 1;
1943 DECL_INITIAL (init_decl
) = init
;
1944 DECL_IGNORED_P (init_decl
) = 1;
1945 TREE_READONLY (init_decl
) = 1;
1946 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl
)) = 1;
1947 make_decl_rtl (init_decl
, NULL
, 1);
1950 expand_assignment (build (COMPONENT_REF
, TREE_TYPE (data_fld
),
1951 build1 (INDIRECT_REF
, array_type
, array_decl
),
1957 if (BLOCK_EXPR_BODY (exp
))
1960 tree body
= BLOCK_EXPR_BODY (exp
);
1961 pushlevel (2); /* 2 and above */
1962 expand_start_bindings (0);
1963 local
= BLOCK_EXPR_DECLS (exp
);
1966 tree next
= TREE_CHAIN (local
);
1967 layout_decl (local
, 0);
1968 expand_decl (pushdecl (local
));
1971 /* Avoid deep recursion for long block. */
1972 while (TREE_CODE (body
) == COMPOUND_EXPR
)
1974 expand_expr (TREE_OPERAND (body
, 0), const0_rtx
, VOIDmode
, 0);
1976 body
= TREE_OPERAND (body
, 1);
1978 expand_expr (body
, const0_rtx
, VOIDmode
, 0);
1981 expand_end_bindings (getdecls (), 1, 0);
1989 if (pushcase (TREE_OPERAND (exp
, 0), case_identity
,
1990 build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
),
1993 EXPR_WFL_LINECOL (wfl_operator
) = EXPR_WFL_LINECOL (exp
);
1995 (wfl_operator
, "Duplicate case label: `%s'",
1996 print_int_node (TREE_OPERAND (exp
, 0)));
2002 pushcase (NULL_TREE
, 0,
2003 build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
), NULL
);
2007 expand_start_case (0, TREE_OPERAND (exp
, 0), int_type_node
, "switch");
2008 expand_expr_stmt (TREE_OPERAND (exp
, 1));
2009 expand_end_case (TREE_OPERAND (exp
, 0));
2013 /* We expand a try[-catch] block */
2015 /* Expand the try block */
2016 expand_eh_region_start ();
2017 expand_expr_stmt (TREE_OPERAND (exp
, 0));
2018 expand_start_all_catch ();
2020 /* Expand all catch clauses (EH handlers) */
2021 for (current
= TREE_OPERAND (exp
, 1); current
;
2022 current
= TREE_CHAIN (current
))
2025 tree
catch = TREE_OPERAND (current
, 0);
2026 tree decl
= BLOCK_EXPR_DECLS (catch);
2027 type
= (decl
? TREE_TYPE (TREE_TYPE (decl
)) : NULL_TREE
);
2028 start_catch_handler (prepare_eh_table_type (type
));
2029 expand_expr_stmt (TREE_OPERAND (current
, 0));
2031 expand_resume_after_catch ();
2032 end_catch_handler ();
2034 expand_end_all_catch ();
2038 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2039 tree_code_name
[TREE_CODE (exp
)]);
2044 expand_byte_code (jcf
, method
)
2051 const unsigned char *linenumber_pointer
;
2052 int dead_code_index
= -1;
2054 #undef RET /* Defined by config/i386/i386.h */
2055 #undef AND /* Causes problems with opcodes for iand and land. */
2057 #define BCODE byte_ops
2058 #define BYTE_type_node byte_type_node
2059 #define SHORT_type_node short_type_node
2060 #define INT_type_node int_type_node
2061 #define LONG_type_node long_type_node
2062 #define CHAR_type_node char_type_node
2063 #define PTR_type_node ptr_type_node
2064 #define FLOAT_type_node float_type_node
2065 #define DOUBLE_type_node double_type_node
2066 #define VOID_type_node void_type_node
2068 unsigned char* byte_ops
;
2069 long length
= DECL_CODE_LENGTH (method
);
2072 JCF_SEEK (jcf
, DECL_CODE_OFFSET (method
));
2073 byte_ops
= jcf
->read_ptr
;
2075 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2076 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2077 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2078 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2080 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2082 instruction_bits
= oballoc (length
+ 1);
2083 bzero (instruction_bits
, length
+ 1);
2085 /* We make an initial pass of the line number table, to note
2086 which instructions have associated line number entries. */
2087 linenumber_pointer
= linenumber_table
;
2088 for (i
= 0; i
< linenumber_count
; i
++)
2090 int pc
= GET_u2 (linenumber_pointer
);
2091 linenumber_pointer
+= 4;
2093 warning ("invalid PC in line number table");
2096 if ((instruction_bits
[pc
] & BCODE_HAS_LINENUMBER
) != 0)
2097 instruction_bits
[pc
] |= BCODE_HAS_MULTI_LINENUMBERS
;
2098 instruction_bits
[pc
] |= BCODE_HAS_LINENUMBER
;
2102 /* Do a preliminary pass.
2103 * This figures out which PC can be the targets of jumps. */
2104 for (PC
= 0; PC
< length
;)
2106 int oldpc
= PC
; /* PC at instruction start. */
2107 instruction_bits
[PC
] |= BCODE_INSTRUCTION_START
;
2108 switch (byte_ops
[PC
++])
2110 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2112 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2115 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2117 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2118 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2119 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2120 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2121 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2122 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2123 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2124 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2126 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2127 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2128 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2129 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2130 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2131 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2132 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2133 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2135 /* two forms of wide instructions */
2136 #define PRE_SPECIAL_WIDE(IGNORE) \
2138 int modified_opcode = IMMEDIATE_u1; \
2139 if (modified_opcode == OPCODE_iinc) \
2141 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2142 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2146 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2150 /* nothing */ /* XXX JH */
2152 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2154 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2156 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2157 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2158 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2159 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2160 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2161 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2162 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2163 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2164 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2165 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2167 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2168 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2169 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2170 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2171 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2172 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2173 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2174 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2176 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2178 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2179 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2181 #define PRE_LOOKUP_SWITCH \
2182 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2183 NOTE_LABEL (default_offset+oldpc); \
2185 while (--npairs >= 0) { \
2186 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2187 jint offset = IMMEDIATE_s4; \
2188 NOTE_LABEL (offset+oldpc); } \
2191 #define PRE_TABLE_SWITCH \
2192 { jint default_offset = IMMEDIATE_s4; \
2193 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2194 NOTE_LABEL (default_offset+oldpc); \
2196 while (low++ <= high) { \
2197 jint offset = IMMEDIATE_s4; \
2198 NOTE_LABEL (offset+oldpc); } \
2201 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2202 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2203 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2204 (void)(IMMEDIATE_u2); \
2205 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2207 #include "javaop.def"
2212 if (! verify_jvm_instructions (jcf
, byte_ops
, length
))
2215 /* Translate bytecodes to rtl instructions. */
2216 linenumber_pointer
= linenumber_table
;
2217 for (PC
= 0; PC
< length
;)
2219 if ((instruction_bits
[PC
] & BCODE_TARGET
) != 0 || PC
== 0)
2221 tree label
= lookup_label (PC
);
2222 flush_quick_stack ();
2223 if ((instruction_bits
[PC
] & BCODE_TARGET
) != 0)
2224 expand_label (label
);
2225 if (LABEL_VERIFIED (label
) || PC
== 0)
2226 load_type_state (label
);
2229 if (! (instruction_bits
[PC
] & BCODE_VERIFIED
))
2231 if (dead_code_index
== -1)
2233 /* This is the start of a region of unreachable bytecodes.
2234 They still need to be processed in order for EH ranges
2235 to get handled correctly. However, we can simply
2236 replace these bytecodes with nops. */
2237 dead_code_index
= PC
;
2240 /* Turn this bytecode into a nop. */
2245 if (dead_code_index
!= -1)
2247 /* We've just reached the end of a region of dead code. */
2248 warning ("Unreachable bytecode from %d to before %d.",
2249 dead_code_index
, PC
);
2250 dead_code_index
= -1;
2254 /* Handle possible line number entry for this PC.
2256 This code handles out-of-order and multiple linenumbers per PC,
2257 but is optimized for the case of line numbers increasing
2258 monotonically with PC. */
2259 if ((instruction_bits
[PC
] & BCODE_HAS_LINENUMBER
) != 0)
2261 if ((instruction_bits
[PC
] & BCODE_HAS_MULTI_LINENUMBERS
) != 0
2262 || GET_u2 (linenumber_pointer
) != PC
)
2263 linenumber_pointer
= linenumber_table
;
2264 while (linenumber_pointer
< linenumber_table
+ linenumber_count
* 4)
2266 int pc
= GET_u2 (linenumber_pointer
);
2267 linenumber_pointer
+= 4;
2270 lineno
= GET_u2 (linenumber_pointer
- 2);
2271 emit_line_note (input_filename
, lineno
);
2272 if (!(instruction_bits
[PC
] & BCODE_HAS_MULTI_LINENUMBERS
))
2277 maybe_start_try (PC
);
2278 maybe_pushlevels (PC
);
2280 PC
= process_jvm_instruction (PC
, byte_ops
, length
);
2282 maybe_poplevels (PC
);
2286 if (dead_code_index
!= -1)
2288 /* We've just reached the end of a region of dead code. */
2289 warning ("Unreachable bytecode from %d to the end of the method.",
2295 java_push_constant_from_pool (jcf
, index
)
2300 if (JPOOL_TAG (jcf
, index
) == CONSTANT_String
)
2303 push_obstacks (&permanent_obstack
, &permanent_obstack
);
2304 name
= get_name_constant (jcf
, JPOOL_USHORT1 (jcf
, index
));
2305 index
= alloc_name_constant (CONSTANT_String
, name
);
2306 c
= build_ref_from_constant_pool (index
);
2307 TREE_TYPE (c
) = promote_type (string_type_node
);
2311 c
= get_constant (jcf
, index
);
2316 process_jvm_instruction (PC
, byte_ops
, length
)
2318 const unsigned char* byte_ops
;
2319 long length ATTRIBUTE_UNUSED
;
2321 const char *opname
; /* Temporary ??? */
2322 int oldpc
= PC
; /* PC at instruction start. */
2324 /* If the instruction is at the beginning of a exception handler,
2325 replace the top of the stack with the thrown object reference */
2326 if (instruction_bits
[PC
] & BCODE_EXCEPTION_TARGET
)
2328 tree type
= pop_type (ptr_type_node
);
2329 push_value (build1 (NOP_EXPR
, type
, soft_exceptioninfo_call_node
));
2332 switch (byte_ops
[PC
++])
2334 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2337 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2340 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2342 int saw_index = 0; \
2343 int index = OPERAND_VALUE; \
2344 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2347 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2349 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2350 tree ret = lookup_label (PC); \
2351 build_java_jsr (where, ret); \
2352 load_type_state (ret); \
2355 /* Push a constant onto the stack. */
2356 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2357 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2358 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2359 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2361 /* internal macro added for use by the WIDE case */
2362 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2363 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2365 /* Push local variable onto the opcode stack. */
2366 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2368 /* have to do this since OPERAND_VALUE may have side-effects */ \
2369 int opvalue = OPERAND_VALUE; \
2370 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2373 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2374 expand_java_return (OPERAND_TYPE##_type_node)
2376 #define REM_EXPR TRUNC_MOD_EXPR
2377 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2378 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2380 #define FIELD(IS_STATIC, IS_PUT) \
2381 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2383 #define TEST(OPERAND_TYPE, CONDITION) \
2384 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2386 #define COND(OPERAND_TYPE, CONDITION) \
2387 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2389 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2390 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2392 #define BRANCH_GOTO(OPERAND_VALUE) \
2393 expand_java_goto (oldpc + OPERAND_VALUE)
2395 #define BRANCH_CALL(OPERAND_VALUE) \
2396 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2399 #define BRANCH_RETURN(OPERAND_VALUE) \
2401 tree type = OPERAND_TYPE##_type_node; \
2402 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2403 expand_java_ret (value); \
2407 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2408 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2409 fprintf (stderr, "(not implemented)\n")
2410 #define NOT_IMPL1(OPERAND_VALUE) \
2411 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2412 fprintf (stderr, "(not implemented)\n")
2414 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2416 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2418 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2420 #define STACK_SWAP(COUNT) java_stack_swap()
2422 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2423 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2424 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2426 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2427 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2429 #define LOOKUP_SWITCH \
2430 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2431 tree selector = pop_value (INT_type_node); \
2432 tree duplicate, label; \
2433 tree type = TREE_TYPE (selector); \
2434 flush_quick_stack (); \
2435 expand_start_case (0, selector, type, "switch statement");\
2436 push_momentary (); \
2437 while (--npairs >= 0) \
2439 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2440 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2441 TREE_TYPE (value) = type; \
2442 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2443 pushcase (value, convert, label, &duplicate); \
2444 expand_java_goto (oldpc + offset); \
2446 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2447 pushcase (NULL_TREE, 0, label, &duplicate); \
2448 expand_java_goto (oldpc + default_offset); \
2450 expand_end_case (selector); \
2453 #define TABLE_SWITCH \
2454 { jint default_offset = IMMEDIATE_s4; \
2455 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2456 tree selector = pop_value (INT_type_node); \
2457 tree duplicate, label; \
2458 tree type = TREE_TYPE (selector); \
2459 flush_quick_stack (); \
2460 expand_start_case (0, selector, type, "switch statement");\
2461 push_momentary (); \
2462 for (; low <= high; low++) \
2464 jint offset = IMMEDIATE_s4; \
2465 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2466 TREE_TYPE (value) = type; \
2467 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2468 pushcase (value, convert, label, &duplicate); \
2469 expand_java_goto (oldpc + offset); \
2471 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2472 pushcase (NULL_TREE, 0, label, &duplicate); \
2473 expand_java_goto (oldpc + default_offset); \
2475 expand_end_case (selector); \
2478 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2479 { int opcode = byte_ops[PC-1]; \
2480 int method_ref_index = IMMEDIATE_u2; \
2482 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2484 expand_invoke (opcode, method_ref_index, nargs); \
2487 /* Handle new, checkcast, instanceof */
2488 #define OBJECT(TYPE, OP) \
2489 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2491 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2493 #define ARRAY_LOAD(OPERAND_TYPE) \
2495 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2498 #define ARRAY_STORE(OPERAND_TYPE) \
2500 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2503 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2504 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2505 #define ARRAY_NEW_PTR() \
2506 push_value (build_anewarray (get_class_constant (current_jcf, \
2508 pop_value (int_type_node)));
2509 #define ARRAY_NEW_NUM() \
2511 int atype = IMMEDIATE_u1; \
2512 push_value (build_newarray (atype, pop_value (int_type_node)));\
2514 #define ARRAY_NEW_MULTI() \
2516 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2517 int ndims = IMMEDIATE_u1; \
2518 expand_java_multianewarray( class, ndims ); \
2521 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2522 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2523 pop_value (OPERAND_TYPE##_type_node))));
2525 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2527 push_value (build1 (NOP_EXPR, int_type_node, \
2528 (convert (TO_TYPE##_type_node, \
2529 pop_value (FROM_TYPE##_type_node))))); \
2532 #define CONVERT(FROM_TYPE, TO_TYPE) \
2534 push_value (convert (TO_TYPE##_type_node, \
2535 pop_value (FROM_TYPE##_type_node))); \
2538 /* internal macro added for use by the WIDE case
2539 Added TREE_TYPE (decl) assignment, apbianco */
2540 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2543 int var = OPVALUE; \
2544 tree type = OPTYPE; \
2545 value = pop_value (type); \
2546 type = TREE_TYPE (value); \
2547 decl = find_local_variable (var, type, oldpc); \
2548 set_local_type (var, type ); \
2549 expand_assignment (decl, value, 0, 0); \
2552 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2554 /* have to do this since OPERAND_VALUE may have side-effects */ \
2555 int opvalue = OPERAND_VALUE; \
2556 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2559 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2560 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2562 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2563 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2565 #define MONITOR_OPERATION(call) \
2567 tree o = pop_value (ptr_type_node); \
2569 flush_quick_stack (); \
2570 c = build_java_monitor (call, o); \
2571 TREE_SIDE_EFFECTS (c) = 1; \
2572 expand_expr_stmt (c); \
2575 #define SPECIAL_IINC(IGNORED) \
2577 unsigned int local_var_index = IMMEDIATE_u1; \
2578 int ival = IMMEDIATE_s1; \
2579 expand_iinc(local_var_index, ival, oldpc); \
2582 #define SPECIAL_WIDE(IGNORED) \
2584 int modified_opcode = IMMEDIATE_u1; \
2585 unsigned int local_var_index = IMMEDIATE_u2; \
2586 switch (modified_opcode) \
2590 int ival = IMMEDIATE_s2; \
2591 expand_iinc (local_var_index, ival, oldpc); \
2594 case OPCODE_iload: \
2595 case OPCODE_lload: \
2596 case OPCODE_fload: \
2597 case OPCODE_dload: \
2598 case OPCODE_aload: \
2600 /* duplicate code from LOAD macro */ \
2601 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2604 case OPCODE_istore: \
2605 case OPCODE_lstore: \
2606 case OPCODE_fstore: \
2607 case OPCODE_dstore: \
2608 case OPCODE_astore: \
2610 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2614 error ("unrecogized wide sub-instruction"); \
2618 #define SPECIAL_THROW(IGNORED) \
2619 build_java_athrow (pop_value (throwable_type_node))
2621 #define SPECIAL_BREAK NOT_IMPL1
2622 #define IMPL NOT_IMPL
2624 #include "javaop.def"
2627 fprintf (stderr
, "%3d: unknown(%3d)\n", oldpc
, byte_ops
[PC
]);
2632 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2633 order, as specified by Java Language Specification.
2635 The problem is that while expand_expr will evaluate its sub-operands in
2636 left-to-right order, for variables it will just return an rtx (i.e.
2637 an lvalue) for the variable (rather than an rvalue). So it is possible
2638 that a later sub-operand will change the register, and when the
2639 actual operation is done, it will use the new value, when it should
2640 have used the original value.
2642 We fix this by using save_expr. This forces the sub-operand to be
2643 copied into a fresh virtual register,
2645 For method invocation, we modify the arguments so that a
2646 left-to-right order evaluation is performed. Saved expressions
2647 will, in CALL_EXPR order, be reused when the call will be expanded.
2651 force_evaluation_order (node
)
2654 if (flag_syntax_only
)
2656 if (TREE_CODE_CLASS (TREE_CODE (node
)) == '2')
2658 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node
, 1)))
2659 TREE_OPERAND (node
, 0) = save_expr (TREE_OPERAND (node
, 0));
2661 else if (TREE_CODE (node
) == CALL_EXPR
|| TREE_CODE (node
) == NEW_CLASS_EXPR
)
2665 if (!TREE_OPERAND (node
, 1))
2668 /* This reverses the evaluation order. This is a desired effect. */
2669 for (cmp
= NULL_TREE
, arg
= TREE_OPERAND (node
, 1);
2670 arg
; arg
= TREE_CHAIN (arg
))
2672 tree saved
= save_expr (TREE_VALUE (arg
));
2673 cmp
= (cmp
== NULL_TREE
? saved
:
2674 build (COMPOUND_EXPR
, void_type_node
, cmp
, saved
));
2675 TREE_VALUE (arg
) = saved
;
2678 if (cmp
&& TREE_CODE (cmp
) == COMPOUND_EXPR
)
2679 TREE_SIDE_EFFECTS (cmp
) = 1;
2683 cmp
= save_expr (build (COMPOUND_EXPR
, TREE_TYPE (node
), cmp
, node
));
2684 CAN_COMPLETE_NORMALLY (cmp
) = CAN_COMPLETE_NORMALLY (node
);
2685 TREE_SIDE_EFFECTS (cmp
) = 1;