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
878 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node
))))
880 tree check
= build (CALL_EXPR
, void_type_node
,
881 build_address_of (soft_checkarraystore_node
),
882 tree_cons (NULL_TREE
, array
,
883 build_tree_list (NULL_TREE
, rhs_node
)),
885 TREE_SIDE_EFFECTS (check
) = 1;
886 expand_expr_stmt (check
);
889 expand_assignment (build_java_arrayaccess (array
,
895 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
896 sure that LHS is an array type. May expand some bound checking and NULL
898 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
899 BOOLEAN/SHORT, we push a promoted type back to the stack.
903 expand_java_arrayload (lhs_type_node
)
907 tree index_node
= pop_value (int_type_node
);
908 tree array_node
= pop_value (ptr_type_node
);
910 index_node
= save_expr (index_node
);
911 array_node
= save_expr (array_node
);
912 lhs_type_node
= build_java_check_indexed_type (array_node
, lhs_type_node
);
914 load_node
= build_java_arrayaccess (array_node
,
918 if (INTEGRAL_TYPE_P (lhs_type_node
) && TYPE_PRECISION (lhs_type_node
) <= 32)
919 load_node
= fold (build1 (NOP_EXPR
, int_type_node
, load_node
));
920 push_value (load_node
);
923 /* Expands .length. Makes sure that we deal with and array and may expand
924 a NULL check on the array object. */
927 expand_java_array_length ()
929 tree array
= pop_value (ptr_type_node
);
930 tree length
= build_java_array_length_access (array
);
932 push_value (build_java_arraynull_check (array
, length
, int_type_node
));
935 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
936 either soft_monitorenter_node or soft_monitorexit_node. */
939 build_java_monitor (call
, object
)
943 return (build (CALL_EXPR
,
945 build_address_of (call
),
946 build_tree_list (NULL_TREE
, object
),
950 /* Emit code for one of the PUSHC instructions. */
953 expand_java_pushc (ival
, type
)
958 if (type
== ptr_type_node
&& ival
== 0)
959 value
= null_pointer_node
;
960 else if (type
== int_type_node
|| type
== long_type_node
)
962 value
= build_int_2 (ival
, ival
< 0 ? -1 : 0);
963 TREE_TYPE (value
) = type
;
965 else if (type
== float_type_node
|| type
== double_type_node
)
968 #ifdef REAL_ARITHMETIC
969 REAL_VALUE_FROM_INT (x
, ival
, 0, TYPE_MODE (type
));
973 value
= build_real (type
, x
);
976 fatal ("internal error in expand_java_pushc");
981 expand_java_return (type
)
984 if (type
== void_type_node
)
985 expand_null_return ();
988 tree retval
= pop_value (type
);
989 tree res
= DECL_RESULT (current_function_decl
);
990 retval
= build (MODIFY_EXPR
, TREE_TYPE (res
), res
, retval
);
991 TREE_SIDE_EFFECTS (retval
) = 1;
992 expand_return (retval
);
997 build_address_of (value
)
1000 return build1 (ADDR_EXPR
, build_pointer_type (TREE_TYPE (value
)), value
);
1004 expand_java_NEW (type
)
1007 if (! CLASS_LOADED_P (type
))
1008 load_class (type
, 1);
1009 layout_class_methods (type
);
1010 push_value (build (CALL_EXPR
, promote_type (type
),
1011 build_address_of (alloc_object_node
),
1012 tree_cons (NULL_TREE
, build_class_ref (type
),
1013 build_tree_list (NULL_TREE
,
1014 size_in_bytes (type
))),
1019 expand_java_INSTANCEOF (type
)
1022 tree value
= pop_value (object_ptr_type_node
);
1023 value
= build (CALL_EXPR
, TREE_TYPE (TREE_TYPE (soft_instanceof_node
)),
1024 build_address_of (soft_instanceof_node
),
1025 tree_cons (NULL_TREE
, value
,
1026 build_tree_list (NULL_TREE
,
1027 build_class_ref (type
))),
1033 expand_java_CHECKCAST (type
)
1036 tree value
= pop_value (ptr_type_node
);
1037 value
= build (CALL_EXPR
, promote_type (type
),
1038 build_address_of (soft_checkcast_node
),
1039 tree_cons (NULL_TREE
, build_class_ref (type
),
1040 build_tree_list (NULL_TREE
, value
)),
1046 expand_iinc (local_var_index
, ival
, pc
)
1047 unsigned int local_var_index
;
1051 tree local_var
, res
;
1052 tree constant_value
;
1054 flush_quick_stack ();
1055 local_var
= find_local_variable (local_var_index
, int_type_node
, pc
);
1056 constant_value
= build_int_2 (ival
, ival
< 0 ? -1 : 0);
1057 res
= fold (build (PLUS_EXPR
, int_type_node
, local_var
, constant_value
));
1058 expand_assignment (local_var
, res
, 0, 0);
1063 build_java_soft_divmod (op
, type
, op1
, op2
)
1065 tree type
, op1
, op2
;
1068 tree arg1
= convert (type
, op1
);
1069 tree arg2
= convert (type
, op2
);
1071 if (type
== int_type_node
)
1075 case TRUNC_DIV_EXPR
:
1076 call
= soft_idiv_node
;
1078 case TRUNC_MOD_EXPR
:
1079 call
= soft_irem_node
;
1085 else if (type
== long_type_node
)
1089 case TRUNC_DIV_EXPR
:
1090 call
= soft_ldiv_node
;
1092 case TRUNC_MOD_EXPR
:
1093 call
= soft_lrem_node
;
1101 fatal ("Internal compiler error in build_java_soft_divmod");
1103 call
= build (CALL_EXPR
, type
,
1104 build_address_of (call
),
1105 tree_cons (NULL_TREE
, arg1
,
1106 build_tree_list (NULL_TREE
, arg2
)),
1113 build_java_binop (op
, type
, arg1
, arg2
)
1115 tree type
, arg1
, arg2
;
1122 tree u_type
= unsigned_type (type
);
1123 arg1
= convert (u_type
, arg1
);
1124 arg1
= build_java_binop (RSHIFT_EXPR
, u_type
, arg1
, arg2
);
1125 return convert (type
, arg1
);
1129 mask
= build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1
)) - 1, 0);
1130 arg2
= fold (build (BIT_AND_EXPR
, int_type_node
, arg2
, mask
));
1133 case COMPARE_L_EXPR
: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1134 case COMPARE_G_EXPR
: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1135 arg1
= save_expr (arg1
); arg2
= save_expr (arg2
);
1137 tree ifexp1
= fold ( build (op
== COMPARE_L_EXPR
? GT_EXPR
: LT_EXPR
,
1138 boolean_type_node
, arg1
, arg2
));
1139 tree ifexp2
= fold ( build (EQ_EXPR
, boolean_type_node
, arg1
, arg2
));
1140 tree second_compare
= fold (build (COND_EXPR
, int_type_node
,
1141 ifexp2
, integer_zero_node
,
1142 op
== COMPARE_L_EXPR
1143 ? integer_negative_one_node
1144 : integer_one_node
));
1145 return fold (build (COND_EXPR
, int_type_node
, ifexp1
,
1146 op
== COMPARE_L_EXPR
? integer_one_node
1147 : integer_negative_one_node
,
1151 arg1
= save_expr (arg1
); arg2
= save_expr (arg2
);
1153 tree ifexp1
= fold ( build (LT_EXPR
, boolean_type_node
, arg1
, arg2
));
1154 tree ifexp2
= fold ( build (GT_EXPR
, boolean_type_node
, arg1
, arg2
));
1155 tree second_compare
= fold ( build (COND_EXPR
, int_type_node
,
1156 ifexp2
, integer_one_node
,
1157 integer_zero_node
));
1158 return fold (build (COND_EXPR
, int_type_node
,
1159 ifexp1
, integer_negative_one_node
, second_compare
));
1161 case TRUNC_DIV_EXPR
:
1162 case TRUNC_MOD_EXPR
:
1163 if (TREE_CODE (type
) == REAL_TYPE
1164 && op
== TRUNC_MOD_EXPR
)
1167 if (type
!= double_type_node
)
1169 arg1
= convert (double_type_node
, arg1
);
1170 arg2
= convert (double_type_node
, arg2
);
1172 call
= build (CALL_EXPR
, double_type_node
,
1173 build_address_of (soft_fmod_node
),
1174 tree_cons (NULL_TREE
, arg1
,
1175 build_tree_list (NULL_TREE
, arg2
)),
1177 if (type
!= double_type_node
)
1178 call
= convert (type
, call
);
1182 if (TREE_CODE (type
) == INTEGER_TYPE
1183 && flag_use_divide_subroutine
1184 && ! flag_syntax_only
)
1185 return build_java_soft_divmod (op
, type
, arg1
, arg2
);
1190 return fold (build (op
, type
, arg1
, arg2
));
1194 expand_java_binop (type
, op
)
1195 tree type
; enum tree_code op
;
1205 rtype
= int_type_node
;
1206 rarg
= pop_value (rtype
);
1209 rarg
= pop_value (rtype
);
1211 larg
= pop_value (ltype
);
1212 push_value (build_java_binop (op
, type
, larg
, rarg
));
1215 /* Lookup the field named NAME in *TYPEP or its super classes.
1216 If not found, return NULL_TREE.
1217 (If the *TYPEP is not found, return error_mark_node.)
1218 If found, return the FIELD_DECL, and set *TYPEP to the
1219 class containing the field. */
1222 lookup_field (typep
, name
)
1226 if (CLASS_P (*typep
) && !CLASS_LOADED_P (*typep
))
1228 load_class (*typep
, 1);
1229 if (!TYPE_SIZE (*typep
) || TREE_CODE (TYPE_SIZE (*typep
)) == ERROR_MARK
)
1230 return error_mark_node
;
1234 tree field
, basetype_vec
;
1237 for (field
= TYPE_FIELDS (*typep
); field
; field
= TREE_CHAIN (field
))
1238 if (DECL_NAME (field
) == name
)
1241 /* Process implemented interfaces. */
1242 basetype_vec
= TYPE_BINFO_BASETYPES (*typep
);
1243 n
= TREE_VEC_LENGTH (basetype_vec
);
1244 for (i
= 0; i
< n
; i
++)
1246 tree t
= BINFO_TYPE (TREE_VEC_ELT (basetype_vec
, i
));
1247 if ((field
= lookup_field (&t
, name
)))
1250 *typep
= CLASSTYPE_SUPER (*typep
);
1255 /* Look up the field named NAME in object SELF_VALUE,
1256 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1257 SELF_VALUE is NULL_TREE if looking for a static field. */
1260 build_field_ref (self_value
, self_class
, name
)
1261 tree self_value
, self_class
, name
;
1263 tree base_class
= self_class
;
1264 tree field_decl
= lookup_field (&base_class
, name
);
1265 if (field_decl
== NULL_TREE
)
1267 error ("field `%s' not found", IDENTIFIER_POINTER (name
));
1268 return error_mark_node
;
1270 if (self_value
== NULL_TREE
)
1272 return build_static_field_ref (field_decl
);
1276 tree base_handle_type
= promote_type (base_class
);
1277 if (base_handle_type
!= TREE_TYPE (self_value
))
1278 self_value
= fold (build1 (NOP_EXPR
, base_handle_type
, self_value
));
1279 #ifdef JAVA_USE_HANDLES
1280 self_value
= unhand_expr (self_value
);
1282 self_value
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (self_value
)),
1284 return fold (build (COMPONENT_REF
, TREE_TYPE (field_decl
),
1285 self_value
, field_decl
));
1295 ASM_GENERATE_INTERNAL_LABEL(buf
, "LJpc=", pc
);
1296 name
= get_identifier (buf
);
1297 if (IDENTIFIER_LOCAL_VALUE (name
))
1298 return IDENTIFIER_LOCAL_VALUE (name
);
1301 /* The type of the address of a label is return_address_type_node. */
1302 tree decl
= create_label_decl (name
);
1303 LABEL_PC (decl
) = pc
;
1305 return pushdecl (decl
);
1309 /* Generate a unique name for the purpose of loops and switches
1310 labels, and try-catch-finally blocks label or temporary variables. */
1315 static int l_number
= 0;
1317 ASM_GENERATE_INTERNAL_LABEL(buff
, "LJv", l_number
);
1319 return get_identifier (buff
);
1323 create_label_decl (name
)
1327 push_obstacks (&permanent_obstack
, &permanent_obstack
);
1328 decl
= build_decl (LABEL_DECL
, name
,
1329 TREE_TYPE (return_address_type_node
));
1331 DECL_CONTEXT (decl
) = current_function_decl
;
1332 DECL_IGNORED_P (decl
) = 1;
1336 /* This maps a bytecode offset (PC) to various flags. */
1337 char *instruction_bits
;
1340 note_label (current_pc
, target_pc
)
1341 int current_pc ATTRIBUTE_UNUSED
, target_pc
;
1343 lookup_label (target_pc
);
1344 instruction_bits
[target_pc
] |= BCODE_JUMP_TARGET
;
1347 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1348 where CONDITION is one of one the compare operators. */
1351 expand_compare (condition
, value1
, value2
, target_pc
)
1352 enum tree_code condition
;
1353 tree value1
, value2
;
1356 tree target
= lookup_label (target_pc
);
1357 tree cond
= fold (build (condition
, boolean_type_node
, value1
, value2
));
1358 expand_start_cond (truthvalue_conversion (cond
), 0);
1359 expand_goto (target
);
1363 /* Emit code for a TEST-type opcode. */
1366 expand_test (condition
, type
, target_pc
)
1367 enum tree_code condition
;
1371 tree value1
, value2
;
1372 flush_quick_stack ();
1373 value1
= pop_value (type
);
1374 value2
= (type
== ptr_type_node
) ? null_pointer_node
: integer_zero_node
;
1375 expand_compare (condition
, value1
, value2
, target_pc
);
1378 /* Emit code for a COND-type opcode. */
1381 expand_cond (condition
, type
, target_pc
)
1382 enum tree_code condition
;
1386 tree value1
, value2
;
1387 flush_quick_stack ();
1388 /* note: pop values in opposite order */
1389 value2
= pop_value (type
);
1390 value1
= pop_value (type
);
1391 /* Maybe should check value1 and value2 for type compatibility ??? */
1392 expand_compare (condition
, value1
, value2
, target_pc
);
1396 expand_java_goto (target_pc
)
1399 tree target_label
= lookup_label (target_pc
);
1400 flush_quick_stack ();
1401 expand_goto (target_label
);
1406 expand_java_call (target_pc
, return_address
)
1407 int target_pc
, return_address
;
1409 tree target_label
= lookup_label (target_pc
);
1410 tree value
= build_int_2 (return_address
, return_address
< 0 ? -1 : 0);
1412 flush_quick_stack ();
1413 expand_goto (target_label
);
1417 expand_java_ret (return_address
)
1418 tree return_address ATTRIBUTE_UNUSED
;
1420 warning ("ret instruction not implemented");
1422 tree target_label
= lookup_label (target_pc
);
1423 flush_quick_stack ();
1424 expand_goto (target_label
);
1429 /* Recursive helper function to pop argument types during verifiation. */
1432 pop_argument_types (arg_types
)
1435 if (arg_types
== end_params_node
)
1437 if (TREE_CODE (arg_types
) == TREE_LIST
)
1439 pop_argument_types (TREE_CHAIN (arg_types
));
1440 pop_type (TREE_VALUE (arg_types
));
1447 pop_arguments (arg_types
)
1450 if (arg_types
== end_params_node
)
1452 if (TREE_CODE (arg_types
) == TREE_LIST
)
1454 tree tail
= pop_arguments (TREE_CHAIN (arg_types
));
1455 tree type
= TREE_VALUE (arg_types
);
1456 tree arg
= pop_value (type
);
1457 if (PROMOTE_PROTOTYPES
1458 && TYPE_PRECISION (type
) < TYPE_PRECISION (integer_type_node
)
1459 && INTEGRAL_TYPE_P (type
))
1460 arg
= convert (integer_type_node
, arg
);
1461 return tree_cons (NULL_TREE
, arg
, tail
);
1466 /* Build an expression to initialize the class CLAS.
1467 if EXPR is non-NULL, returns an expression to first call the initializer
1468 (if it is needed) and then calls EXPR. */
1471 build_class_init (clas
, expr
)
1475 if (inherits_from_p (current_class
, clas
))
1477 init
= build (CALL_EXPR
, void_type_node
,
1478 build_address_of (soft_initclass_node
),
1479 build_tree_list (NULL_TREE
, build_class_ref (clas
)),
1481 TREE_SIDE_EFFECTS (init
) = 1;
1482 if (expr
!= NULL_TREE
)
1484 expr
= build (COMPOUND_EXPR
, TREE_TYPE (expr
), init
, expr
);
1485 TREE_SIDE_EFFECTS (expr
) = 1;
1491 static tree methods_ident
= NULL_TREE
;
1492 static tree ncode_ident
= NULL_TREE
;
1493 tree dtable_ident
= NULL_TREE
;
1496 build_known_method_ref (method
, method_type
, self_type
, method_signature
, arg_list
)
1497 tree method
, method_type ATTRIBUTE_UNUSED
, self_type
,
1498 method_signature ATTRIBUTE_UNUSED
, arg_list ATTRIBUTE_UNUSED
;
1501 if (is_compiled_class (self_type
))
1503 make_decl_rtl (method
, NULL
, 1);
1504 func
= build1 (ADDR_EXPR
, method_ptr_type_node
, method
);
1508 /* We don't know whether the method has been (statically) compiled.
1509 Compile this code to get a reference to the method's code:
1511 SELF_TYPE->methods[METHOD_INDEX].ncode
1513 This is guaranteed to work (assuming SELF_TYPE has
1514 been initialized), since if the method is not compiled yet,
1515 its ncode points to a trampoline that forces compilation. */
1517 int method_index
= 0;
1519 tree ref
= build_class_ref (self_type
);
1520 ref
= build1 (INDIRECT_REF
, class_type_node
, ref
);
1521 if (ncode_ident
== NULL_TREE
)
1522 ncode_ident
= get_identifier ("ncode");
1523 if (methods_ident
== NULL_TREE
)
1524 methods_ident
= get_identifier ("methods");
1525 ref
= build (COMPONENT_REF
, method_ptr_type_node
, ref
,
1526 lookup_field (&class_type_node
, methods_ident
));
1527 for (meth
= TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type
));
1528 ; meth
= TREE_CHAIN (meth
))
1532 if (meth
== NULL_TREE
)
1533 fatal ("method '%s' not found in class",
1534 IDENTIFIER_POINTER (DECL_NAME (method
)));
1537 method_index
*= int_size_in_bytes (method_type_node
);
1538 ref
= fold (build (PLUS_EXPR
, method_ptr_type_node
,
1539 ref
, build_int_2 (method_index
, 0)));
1540 ref
= build1 (INDIRECT_REF
, method_type_node
, ref
);
1541 func
= build (COMPONENT_REF
, nativecode_ptr_type_node
,
1543 lookup_field (&method_type_node
, ncode_ident
));
1549 invoke_build_dtable (is_invoke_interface
, arg_list
)
1550 int is_invoke_interface
;
1553 tree dtable
, objectref
;
1555 TREE_VALUE (arg_list
) = save_expr (TREE_VALUE (arg_list
));
1557 /* If we're dealing with interfaces and if the objectref
1558 argument is an array then get the dispatch table of the class
1559 Object rather than the one from the objectref. */
1560 objectref
= (is_invoke_interface
1561 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list
))) ?
1562 object_type_node
: TREE_VALUE (arg_list
));
1564 if (dtable_ident
== NULL_TREE
)
1565 dtable_ident
= get_identifier ("vtable");
1566 dtable
= build1 (INDIRECT_REF
, object_type_node
, objectref
);
1567 dtable
= build (COMPONENT_REF
, dtable_ptr_type
, dtable
,
1568 lookup_field (&object_type_node
, dtable_ident
));
1574 build_invokevirtual (dtable
, method
)
1575 tree dtable
, method
;
1578 tree nativecode_ptr_ptr_type_node
1579 = build_pointer_type (nativecode_ptr_type_node
);
1580 int method_index
= TREE_INT_CST_LOW (DECL_VINDEX (method
));
1581 /* Add one to skip "class" field of dtable, and one to skip unused
1582 vtable entry (for C++ compatibility). */
1585 *= int_size_in_bytes (nativecode_ptr_ptr_type_node
);
1586 func
= fold (build (PLUS_EXPR
, nativecode_ptr_ptr_type_node
,
1587 dtable
, build_int_2 (method_index
, 0)));
1588 func
= build1 (INDIRECT_REF
, nativecode_ptr_type_node
, func
);
1594 build_invokeinterface (dtable
, method_name
, method_signature
)
1595 tree dtable
, method_name
, method_signature
;
1597 static tree class_ident
= NULL_TREE
;
1600 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1601 ensure that the selected method exists, is public and not
1602 abstract nor static. */
1604 if (class_ident
== NULL_TREE
)
1605 class_ident
= get_identifier ("class");
1607 dtable
= build1 (INDIRECT_REF
, dtable_type
, dtable
);
1608 dtable
= build (COMPONENT_REF
, class_ptr_type
, dtable
,
1609 lookup_field (&dtable_type
, class_ident
));
1610 lookup_arg
= build_tree_list (NULL_TREE
,
1613 (IDENTIFIER_POINTER(method_signature
),
1614 IDENTIFIER_LENGTH(method_signature
)))));
1615 lookup_arg
= tree_cons (NULL_TREE
, dtable
,
1616 tree_cons (NULL_TREE
, build_utf8_ref (method_name
),
1618 return build (CALL_EXPR
, ptr_type_node
,
1619 build_address_of (soft_lookupinterfacemethod_node
),
1620 lookup_arg
, NULL_TREE
);
1623 /* Expand one of the invoke_* opcodes.
1624 OCPODE is the specific opcode.
1625 METHOD_REF_INDEX is an index into the constant pool.
1626 NARGS is the number of arguments, or -1 if not specified. */
1629 expand_invoke (opcode
, method_ref_index
, nargs
)
1631 int method_ref_index
;
1632 int nargs ATTRIBUTE_UNUSED
;
1634 tree method_signature
= COMPONENT_REF_SIGNATURE(¤t_jcf
->cpool
, method_ref_index
);
1635 tree method_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, method_ref_index
);
1636 tree self_type
= get_class_constant
1637 (current_jcf
, COMPONENT_REF_CLASS_INDEX(¤t_jcf
->cpool
, method_ref_index
));
1638 const char *self_name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type
)));
1639 tree call
, func
, method
, arg_list
, method_type
;
1641 if (! CLASS_LOADED_P (self_type
))
1643 load_class (self_type
, 1);
1644 if (TREE_CODE (TYPE_SIZE (self_type
)) == ERROR_MARK
)
1645 fatal ("failed to find class '%s'", self_name
);
1647 layout_class_methods (self_type
);
1649 if (method_name
== init_identifier_node
)
1650 method
= lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type
),
1653 method
= lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type
),
1654 method_name
, method_signature
);
1655 if (method
== NULL_TREE
)
1657 error ("Class '%s' has no method named '%s' matching signature '%s'",
1659 IDENTIFIER_POINTER (method_name
),
1660 IDENTIFIER_POINTER (method_signature
));
1662 /* Invoke static can't invoke static/abstract method */
1663 else if (opcode
== OPCODE_invokestatic
)
1665 if (!METHOD_STATIC (method
))
1667 error ("invokestatic on non static method");
1670 else if (METHOD_ABSTRACT (method
))
1672 error ("invokestatic on abstract method");
1678 if (METHOD_STATIC (method
))
1680 error ("invoke[non-static] on static method");
1685 if (method
== NULL_TREE
)
1687 method_type
= get_type_from_signature (method_signature
);
1688 pop_arguments (TYPE_ARG_TYPES (method_type
));
1689 if (opcode
!= OPCODE_invokestatic
)
1690 pop_type (self_type
);
1691 method_type
= promote_type (TREE_TYPE (method_type
));
1692 push_value (convert (method_type
, integer_zero_node
));
1696 method_type
= TREE_TYPE (method
);
1697 arg_list
= pop_arguments (TYPE_ARG_TYPES (method_type
));
1698 flush_quick_stack ();
1701 if (opcode
== OPCODE_invokestatic
|| opcode
== OPCODE_invokespecial
1702 || (opcode
== OPCODE_invokevirtual
1703 && (METHOD_PRIVATE (method
)
1704 || METHOD_FINAL (method
)
1705 || CLASS_FINAL (TYPE_NAME (self_type
)))))
1706 func
= build_known_method_ref (method
, method_type
, self_type
,
1707 method_signature
, arg_list
);
1710 tree dtable
= invoke_build_dtable (opcode
== OPCODE_invokeinterface
,
1712 if (opcode
== OPCODE_invokevirtual
)
1713 func
= build_invokevirtual (dtable
, method
);
1715 func
= build_invokeinterface (dtable
, method_name
, method_signature
);
1717 func
= build1 (NOP_EXPR
, build_pointer_type (method_type
), func
);
1718 call
= build (CALL_EXPR
, TREE_TYPE (method_type
), func
, arg_list
, NULL_TREE
);
1719 TREE_SIDE_EFFECTS (call
) = 1;
1721 if (TREE_CODE (TREE_TYPE (method_type
)) == VOID_TYPE
)
1722 expand_expr_stmt (call
);
1726 flush_quick_stack ();
1731 /* Expand an operation to extract from or store into a field.
1732 IS_STATIC is 1 iff the field is static.
1733 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1734 FIELD_REF_INDEX is an index into the constant pool. */
1737 expand_java_field_op (is_static
, is_putting
, field_ref_index
)
1740 int field_ref_index
;
1743 get_class_constant (current_jcf
,
1744 COMPONENT_REF_CLASS_INDEX (¤t_jcf
->cpool
,
1746 const char *self_name
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type
)));
1747 tree field_name
= COMPONENT_REF_NAME (¤t_jcf
->cpool
, field_ref_index
);
1748 tree field_signature
= COMPONENT_REF_SIGNATURE (¤t_jcf
->cpool
,
1750 tree field_type
= get_type_from_signature (field_signature
);
1751 tree new_value
= is_putting
? pop_value (field_type
) : NULL_TREE
;
1754 tree field_decl
= lookup_field (&self_type
, field_name
);
1755 if (field_decl
== error_mark_node
)
1759 else if (field_decl
== NULL_TREE
)
1761 error ("Missing field '%s' in '%s'",
1762 IDENTIFIER_POINTER (field_name
), self_name
);
1765 else if (build_java_signature (TREE_TYPE (field_decl
)) != field_signature
)
1767 error ("Mismatching signature for field '%s' in '%s'",
1768 IDENTIFIER_POINTER (field_name
), self_name
);
1771 field_ref
= is_static
? NULL_TREE
: pop_value (self_type
);
1775 push_value (convert (field_type
, integer_zero_node
));
1776 flush_quick_stack ();
1780 /* Inline references to java.lang.PRIMTYPE.TYPE.
1781 In addition to being a useful (minor) optimization,
1782 this is also needed to avoid circularities in the implementation
1783 of these fields in libjava. */
1784 if (field_name
== TYPE_identifier_node
&& ! is_putting
1785 && ! flag_emit_class_files
&& field_type
== class_ptr_type
1786 && strncmp (self_name
, "java.lang.", 10) == 0)
1788 tree typ
= build_primtype_type_ref (self_name
);
1796 field_ref
= build_field_ref (field_ref
, self_type
, field_name
);
1798 field_ref
= build_class_init (self_type
, field_ref
);
1801 flush_quick_stack ();
1802 if (FIELD_FINAL (field_decl
))
1804 if (DECL_CONTEXT (field_decl
) != current_class
)
1805 error_with_decl (field_decl
,
1806 "assignment to final field `%s' not in field's class");
1807 else if (FIELD_STATIC (field_decl
))
1809 if (!IS_CLINIT (current_function_decl
))
1810 error_with_decl (field_decl
,
1811 "assignment to final static field `%s' not in class initializer");
1815 if (! DECL_CONSTRUCTOR_P (current_function_decl
))
1816 error_with_decl (field_decl
, "assignment to final field `%s' "
1817 "not in constructor");
1820 expand_assignment (field_ref
, new_value
, 0, 0);
1823 push_value (field_ref
);
1827 build_primtype_type_ref (self_name
)
1828 const char *self_name
;
1830 const char *class_name
= self_name
+10;
1832 if (strncmp(class_name
, "Byte", 4) == 0)
1833 typ
= byte_type_node
;
1834 else if (strncmp(class_name
, "Short", 5) == 0)
1835 typ
= short_type_node
;
1836 else if (strncmp(class_name
, "Integer", 7) == 0)
1837 typ
= int_type_node
;
1838 else if (strncmp(class_name
, "Long", 4) == 0)
1839 typ
= long_type_node
;
1840 else if (strncmp(class_name
, "Float", 5) == 0)
1841 typ
= float_type_node
;
1842 else if (strncmp(class_name
, "Double", 6) == 0)
1843 typ
= double_type_node
;
1844 else if (strncmp(class_name
, "Boolean", 7) == 0)
1845 typ
= boolean_type_node
;
1846 else if (strncmp(class_name
, "Char", 4) == 0)
1847 typ
= char_type_node
;
1848 else if (strncmp(class_name
, "Void", 4) == 0)
1849 typ
= void_type_node
;
1852 if (typ
!= NULL_TREE
)
1853 return build_class_ref (typ
);
1859 load_type_state (label
)
1863 tree vec
= LABEL_TYPE_STATE (label
);
1864 int cur_length
= TREE_VEC_LENGTH (vec
);
1865 stack_pointer
= cur_length
- DECL_MAX_LOCALS(current_function_decl
);
1866 for (i
= 0; i
< cur_length
; i
++)
1867 type_map
[i
] = TREE_VEC_ELT (vec
, i
);
1870 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1871 dependant things, but they rely on gcc routines. This function is
1872 placed here because it uses things defined locally in parse.y. */
1875 case_identity (t
, v
)
1876 tree t
__attribute__ ((__unused__
));
1883 java_lang_expand_expr (exp
, target
, tmode
, modifier
)
1885 rtx target ATTRIBUTE_UNUSED
;
1886 enum machine_mode tmode ATTRIBUTE_UNUSED
;
1887 enum expand_modifier modifier ATTRIBUTE_UNUSED
;
1891 switch (TREE_CODE (exp
))
1893 case NEW_ARRAY_INIT
:
1896 tree array_type
= TREE_TYPE (TREE_TYPE (exp
));
1897 tree element_type
= TYPE_ARRAY_ELEMENT (array_type
);
1898 tree data_fld
= TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type
)));
1899 HOST_WIDE_INT ilength
= java_array_type_length (array_type
);
1900 tree length
= build_int_2 (ilength
, 0);
1901 tree init
= TREE_OPERAND (exp
, 0);
1904 /* Enable this once we can set the vtable field statically. FIXME */
1905 if (TREE_CONSTANT (init
) && TREE_STATIC (exp
)
1906 && JPRIMITIVE_TYPE_P (element_type
))
1908 tree temp
, value
, init_decl
;
1909 START_RECORD_CONSTRUCTOR (temp
, object_type_node
);
1910 PUSH_FIELD_VALUE (temp
, "vtable",
1911 null_pointer_node
/* FIXME */
1913 PUSH_FIELD_VALUE (temp
, "sync_info", null_pointer_node
);
1914 FINISH_RECORD_CONSTRUCTOR (temp
);
1915 START_RECORD_CONSTRUCTOR (value
, array_type
);
1916 PUSH_SUPER_VALUE (value
, temp
);
1917 PUSH_FIELD_VALUE (value
, "length", length
);
1918 PUSH_FIELD_VALUE (value
, "data", init
);
1919 FINISH_RECORD_CONSTRUCTOR (value
);
1921 init_decl
= build_decl (VAR_DECL
, generate_name (), array_type
);
1922 pushdecl_top_level (init_decl
);
1923 TREE_STATIC (init_decl
) = 1;
1924 DECL_INITIAL (init_decl
) = value
;
1925 DECL_IGNORED_P (init_decl
) = 1;
1926 TREE_READONLY (init_decl
) = 1;
1927 make_decl_rtl (init_decl
, NULL
, 1);
1928 init
= build1 (ADDR_EXPR
, TREE_TYPE (exp
), init_decl
);
1929 return expand_expr (init
, target
, tmode
, modifier
);
1932 array_decl
= build_decl (VAR_DECL
, NULL_TREE
, TREE_TYPE (exp
));
1933 expand_decl (array_decl
);
1934 tmp
= expand_assignment (array_decl
,
1935 build_new_array (element_type
, length
),
1937 if (TREE_CONSTANT (init
)
1938 && ilength
>= 10 && JPRIMITIVE_TYPE_P (element_type
))
1940 tree init_decl
= build_decl (VAR_DECL
, generate_name (),
1942 pushdecl_top_level (init_decl
);
1943 TREE_STATIC (init_decl
) = 1;
1944 DECL_INITIAL (init_decl
) = init
;
1945 DECL_IGNORED_P (init_decl
) = 1;
1946 TREE_READONLY (init_decl
) = 1;
1947 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl
)) = 1;
1948 make_decl_rtl (init_decl
, NULL
, 1);
1951 expand_assignment (build (COMPONENT_REF
, TREE_TYPE (data_fld
),
1952 build1 (INDIRECT_REF
, array_type
, array_decl
),
1958 if (BLOCK_EXPR_BODY (exp
))
1961 tree body
= BLOCK_EXPR_BODY (exp
);
1962 pushlevel (2); /* 2 and above */
1963 expand_start_bindings (0);
1964 local
= BLOCK_EXPR_DECLS (exp
);
1967 tree next
= TREE_CHAIN (local
);
1968 layout_decl (local
, 0);
1969 expand_decl (pushdecl (local
));
1972 /* Avoid deep recursion for long block. */
1973 while (TREE_CODE (body
) == COMPOUND_EXPR
)
1975 expand_expr (TREE_OPERAND (body
, 0), const0_rtx
, VOIDmode
, 0);
1977 body
= TREE_OPERAND (body
, 1);
1979 expand_expr (body
, const0_rtx
, VOIDmode
, 0);
1982 expand_end_bindings (getdecls (), 1, 0);
1990 if (pushcase (TREE_OPERAND (exp
, 0), case_identity
,
1991 build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
),
1994 EXPR_WFL_LINECOL (wfl_operator
) = EXPR_WFL_LINECOL (exp
);
1996 (wfl_operator
, "Duplicate case label: `%s'",
1997 print_int_node (TREE_OPERAND (exp
, 0)));
2003 pushcase (NULL_TREE
, 0,
2004 build_decl (LABEL_DECL
, NULL_TREE
, NULL_TREE
), NULL
);
2008 expand_start_case (0, TREE_OPERAND (exp
, 0), int_type_node
, "switch");
2009 expand_expr_stmt (TREE_OPERAND (exp
, 1));
2010 expand_end_case (TREE_OPERAND (exp
, 0));
2014 /* We expand a try[-catch] block */
2016 /* Expand the try block */
2017 expand_eh_region_start ();
2018 expand_expr_stmt (TREE_OPERAND (exp
, 0));
2019 expand_start_all_catch ();
2021 /* Expand all catch clauses (EH handlers) */
2022 for (current
= TREE_OPERAND (exp
, 1); current
;
2023 current
= TREE_CHAIN (current
))
2026 tree
catch = TREE_OPERAND (current
, 0);
2027 tree decl
= BLOCK_EXPR_DECLS (catch);
2028 type
= (decl
? TREE_TYPE (TREE_TYPE (decl
)) : NULL_TREE
);
2029 start_catch_handler (prepare_eh_table_type (type
));
2030 expand_expr_stmt (TREE_OPERAND (current
, 0));
2032 expand_resume_after_catch ();
2033 end_catch_handler ();
2035 expand_end_all_catch ();
2039 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2040 tree_code_name
[TREE_CODE (exp
)]);
2045 expand_byte_code (jcf
, method
)
2052 const unsigned char *linenumber_pointer
;
2053 int dead_code_index
= -1;
2055 #undef RET /* Defined by config/i386/i386.h */
2056 #undef AND /* Causes problems with opcodes for iand and land. */
2058 #define BCODE byte_ops
2059 #define BYTE_type_node byte_type_node
2060 #define SHORT_type_node short_type_node
2061 #define INT_type_node int_type_node
2062 #define LONG_type_node long_type_node
2063 #define CHAR_type_node char_type_node
2064 #define PTR_type_node ptr_type_node
2065 #define FLOAT_type_node float_type_node
2066 #define DOUBLE_type_node double_type_node
2067 #define VOID_type_node void_type_node
2069 unsigned char* byte_ops
;
2070 long length
= DECL_CODE_LENGTH (method
);
2073 JCF_SEEK (jcf
, DECL_CODE_OFFSET (method
));
2074 byte_ops
= jcf
->read_ptr
;
2076 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2077 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2078 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2079 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2081 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2083 instruction_bits
= oballoc (length
+ 1);
2084 bzero (instruction_bits
, length
+ 1);
2086 /* We make an initial pass of the line number table, to note
2087 which instructions have associated line number entries. */
2088 linenumber_pointer
= linenumber_table
;
2089 for (i
= 0; i
< linenumber_count
; i
++)
2091 int pc
= GET_u2 (linenumber_pointer
);
2092 linenumber_pointer
+= 4;
2094 warning ("invalid PC in line number table");
2097 if ((instruction_bits
[pc
] & BCODE_HAS_LINENUMBER
) != 0)
2098 instruction_bits
[pc
] |= BCODE_HAS_MULTI_LINENUMBERS
;
2099 instruction_bits
[pc
] |= BCODE_HAS_LINENUMBER
;
2103 /* Do a preliminary pass.
2104 * This figures out which PC can be the targets of jumps. */
2105 for (PC
= 0; PC
< length
;)
2107 int oldpc
= PC
; /* PC at instruction start. */
2108 instruction_bits
[PC
] |= BCODE_INSTRUCTION_START
;
2109 switch (byte_ops
[PC
++])
2111 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2113 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2116 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2118 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2119 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2120 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2121 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2122 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2123 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2124 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2125 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2127 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2128 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2129 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2130 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2131 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2132 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2133 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2134 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2136 /* two forms of wide instructions */
2137 #define PRE_SPECIAL_WIDE(IGNORE) \
2139 int modified_opcode = IMMEDIATE_u1; \
2140 if (modified_opcode == OPCODE_iinc) \
2142 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2143 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2147 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2151 /* nothing */ /* XXX JH */
2153 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2155 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2157 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2158 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2159 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2160 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2161 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2162 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2163 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2164 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2165 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2166 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2168 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2169 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2170 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2171 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2172 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2173 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2174 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2175 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2177 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2179 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2180 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2182 #define PRE_LOOKUP_SWITCH \
2183 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2184 NOTE_LABEL (default_offset+oldpc); \
2186 while (--npairs >= 0) { \
2187 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2188 jint offset = IMMEDIATE_s4; \
2189 NOTE_LABEL (offset+oldpc); } \
2192 #define PRE_TABLE_SWITCH \
2193 { jint default_offset = IMMEDIATE_s4; \
2194 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2195 NOTE_LABEL (default_offset+oldpc); \
2197 while (low++ <= high) { \
2198 jint offset = IMMEDIATE_s4; \
2199 NOTE_LABEL (offset+oldpc); } \
2202 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2203 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2204 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2205 (void)(IMMEDIATE_u2); \
2206 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2208 #include "javaop.def"
2213 if (! verify_jvm_instructions (jcf
, byte_ops
, length
))
2216 /* Translate bytecodes to rtl instructions. */
2217 linenumber_pointer
= linenumber_table
;
2218 for (PC
= 0; PC
< length
;)
2220 if ((instruction_bits
[PC
] & BCODE_TARGET
) != 0 || PC
== 0)
2222 tree label
= lookup_label (PC
);
2223 flush_quick_stack ();
2224 if ((instruction_bits
[PC
] & BCODE_TARGET
) != 0)
2225 expand_label (label
);
2226 if (LABEL_VERIFIED (label
) || PC
== 0)
2227 load_type_state (label
);
2230 if (! (instruction_bits
[PC
] & BCODE_VERIFIED
))
2232 if (dead_code_index
== -1)
2234 /* This is the start of a region of unreachable bytecodes.
2235 They still need to be processed in order for EH ranges
2236 to get handled correctly. However, we can simply
2237 replace these bytecodes with nops. */
2238 dead_code_index
= PC
;
2241 /* Turn this bytecode into a nop. */
2246 if (dead_code_index
!= -1)
2248 /* We've just reached the end of a region of dead code. */
2249 warning ("Unreachable bytecode from %d to before %d.",
2250 dead_code_index
, PC
);
2251 dead_code_index
= -1;
2255 /* Handle possible line number entry for this PC.
2257 This code handles out-of-order and multiple linenumbers per PC,
2258 but is optimized for the case of line numbers increasing
2259 monotonically with PC. */
2260 if ((instruction_bits
[PC
] & BCODE_HAS_LINENUMBER
) != 0)
2262 if ((instruction_bits
[PC
] & BCODE_HAS_MULTI_LINENUMBERS
) != 0
2263 || GET_u2 (linenumber_pointer
) != PC
)
2264 linenumber_pointer
= linenumber_table
;
2265 while (linenumber_pointer
< linenumber_table
+ linenumber_count
* 4)
2267 int pc
= GET_u2 (linenumber_pointer
);
2268 linenumber_pointer
+= 4;
2271 lineno
= GET_u2 (linenumber_pointer
- 2);
2272 emit_line_note (input_filename
, lineno
);
2273 if (!(instruction_bits
[PC
] & BCODE_HAS_MULTI_LINENUMBERS
))
2278 maybe_start_try (PC
);
2279 maybe_pushlevels (PC
);
2281 PC
= process_jvm_instruction (PC
, byte_ops
, length
);
2283 maybe_poplevels (PC
);
2287 if (dead_code_index
!= -1)
2289 /* We've just reached the end of a region of dead code. */
2290 warning ("Unreachable bytecode from %d to the end of the method.",
2296 java_push_constant_from_pool (jcf
, index
)
2301 if (JPOOL_TAG (jcf
, index
) == CONSTANT_String
)
2304 push_obstacks (&permanent_obstack
, &permanent_obstack
);
2305 name
= get_name_constant (jcf
, JPOOL_USHORT1 (jcf
, index
));
2306 index
= alloc_name_constant (CONSTANT_String
, name
);
2307 c
= build_ref_from_constant_pool (index
);
2308 TREE_TYPE (c
) = promote_type (string_type_node
);
2312 c
= get_constant (jcf
, index
);
2317 process_jvm_instruction (PC
, byte_ops
, length
)
2319 const unsigned char* byte_ops
;
2320 long length ATTRIBUTE_UNUSED
;
2322 const char *opname
; /* Temporary ??? */
2323 int oldpc
= PC
; /* PC at instruction start. */
2325 /* If the instruction is at the beginning of a exception handler,
2326 replace the top of the stack with the thrown object reference */
2327 if (instruction_bits
[PC
] & BCODE_EXCEPTION_TARGET
)
2329 tree type
= pop_type (ptr_type_node
);
2330 push_value (build1 (NOP_EXPR
, type
, soft_exceptioninfo_call_node
));
2333 switch (byte_ops
[PC
++])
2335 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2338 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2341 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2343 int saw_index = 0; \
2344 int index = OPERAND_VALUE; \
2345 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2348 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2350 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2351 tree ret = lookup_label (PC); \
2352 build_java_jsr (where, ret); \
2353 load_type_state (ret); \
2356 /* Push a constant onto the stack. */
2357 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2358 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2359 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2360 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2362 /* internal macro added for use by the WIDE case */
2363 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2364 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2366 /* Push local variable onto the opcode stack. */
2367 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2369 /* have to do this since OPERAND_VALUE may have side-effects */ \
2370 int opvalue = OPERAND_VALUE; \
2371 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2374 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2375 expand_java_return (OPERAND_TYPE##_type_node)
2377 #define REM_EXPR TRUNC_MOD_EXPR
2378 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2379 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2381 #define FIELD(IS_STATIC, IS_PUT) \
2382 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2384 #define TEST(OPERAND_TYPE, CONDITION) \
2385 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2387 #define COND(OPERAND_TYPE, CONDITION) \
2388 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2390 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2391 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2393 #define BRANCH_GOTO(OPERAND_VALUE) \
2394 expand_java_goto (oldpc + OPERAND_VALUE)
2396 #define BRANCH_CALL(OPERAND_VALUE) \
2397 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2400 #define BRANCH_RETURN(OPERAND_VALUE) \
2402 tree type = OPERAND_TYPE##_type_node; \
2403 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2404 expand_java_ret (value); \
2408 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2409 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2410 fprintf (stderr, "(not implemented)\n")
2411 #define NOT_IMPL1(OPERAND_VALUE) \
2412 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2413 fprintf (stderr, "(not implemented)\n")
2415 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2417 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2419 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2421 #define STACK_SWAP(COUNT) java_stack_swap()
2423 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2424 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2425 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2427 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2428 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2430 #define LOOKUP_SWITCH \
2431 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2432 tree selector = pop_value (INT_type_node); \
2433 tree duplicate, label; \
2434 tree type = TREE_TYPE (selector); \
2435 flush_quick_stack (); \
2436 expand_start_case (0, selector, type, "switch statement");\
2437 push_momentary (); \
2438 while (--npairs >= 0) \
2440 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2441 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2442 TREE_TYPE (value) = type; \
2443 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2444 pushcase (value, convert, label, &duplicate); \
2445 expand_java_goto (oldpc + offset); \
2447 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2448 pushcase (NULL_TREE, 0, label, &duplicate); \
2449 expand_java_goto (oldpc + default_offset); \
2451 expand_end_case (selector); \
2454 #define TABLE_SWITCH \
2455 { jint default_offset = IMMEDIATE_s4; \
2456 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2457 tree selector = pop_value (INT_type_node); \
2458 tree duplicate, label; \
2459 tree type = TREE_TYPE (selector); \
2460 flush_quick_stack (); \
2461 expand_start_case (0, selector, type, "switch statement");\
2462 push_momentary (); \
2463 for (; low <= high; low++) \
2465 jint offset = IMMEDIATE_s4; \
2466 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2467 TREE_TYPE (value) = type; \
2468 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2469 pushcase (value, convert, label, &duplicate); \
2470 expand_java_goto (oldpc + offset); \
2472 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2473 pushcase (NULL_TREE, 0, label, &duplicate); \
2474 expand_java_goto (oldpc + default_offset); \
2476 expand_end_case (selector); \
2479 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2480 { int opcode = byte_ops[PC-1]; \
2481 int method_ref_index = IMMEDIATE_u2; \
2483 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2485 expand_invoke (opcode, method_ref_index, nargs); \
2488 /* Handle new, checkcast, instanceof */
2489 #define OBJECT(TYPE, OP) \
2490 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2492 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2494 #define ARRAY_LOAD(OPERAND_TYPE) \
2496 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2499 #define ARRAY_STORE(OPERAND_TYPE) \
2501 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2504 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2505 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2506 #define ARRAY_NEW_PTR() \
2507 push_value (build_anewarray (get_class_constant (current_jcf, \
2509 pop_value (int_type_node)));
2510 #define ARRAY_NEW_NUM() \
2512 int atype = IMMEDIATE_u1; \
2513 push_value (build_newarray (atype, pop_value (int_type_node)));\
2515 #define ARRAY_NEW_MULTI() \
2517 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2518 int ndims = IMMEDIATE_u1; \
2519 expand_java_multianewarray( class, ndims ); \
2522 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2523 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2524 pop_value (OPERAND_TYPE##_type_node))));
2526 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2528 push_value (build1 (NOP_EXPR, int_type_node, \
2529 (convert (TO_TYPE##_type_node, \
2530 pop_value (FROM_TYPE##_type_node))))); \
2533 #define CONVERT(FROM_TYPE, TO_TYPE) \
2535 push_value (convert (TO_TYPE##_type_node, \
2536 pop_value (FROM_TYPE##_type_node))); \
2539 /* internal macro added for use by the WIDE case
2540 Added TREE_TYPE (decl) assignment, apbianco */
2541 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2544 int var = OPVALUE; \
2545 tree type = OPTYPE; \
2546 value = pop_value (type); \
2547 type = TREE_TYPE (value); \
2548 decl = find_local_variable (var, type, oldpc); \
2549 set_local_type (var, type ); \
2550 expand_assignment (decl, value, 0, 0); \
2553 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2555 /* have to do this since OPERAND_VALUE may have side-effects */ \
2556 int opvalue = OPERAND_VALUE; \
2557 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2560 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2561 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2563 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2564 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2566 #define MONITOR_OPERATION(call) \
2568 tree o = pop_value (ptr_type_node); \
2570 flush_quick_stack (); \
2571 c = build_java_monitor (call, o); \
2572 TREE_SIDE_EFFECTS (c) = 1; \
2573 expand_expr_stmt (c); \
2576 #define SPECIAL_IINC(IGNORED) \
2578 unsigned int local_var_index = IMMEDIATE_u1; \
2579 int ival = IMMEDIATE_s1; \
2580 expand_iinc(local_var_index, ival, oldpc); \
2583 #define SPECIAL_WIDE(IGNORED) \
2585 int modified_opcode = IMMEDIATE_u1; \
2586 unsigned int local_var_index = IMMEDIATE_u2; \
2587 switch (modified_opcode) \
2591 int ival = IMMEDIATE_s2; \
2592 expand_iinc (local_var_index, ival, oldpc); \
2595 case OPCODE_iload: \
2596 case OPCODE_lload: \
2597 case OPCODE_fload: \
2598 case OPCODE_dload: \
2599 case OPCODE_aload: \
2601 /* duplicate code from LOAD macro */ \
2602 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2605 case OPCODE_istore: \
2606 case OPCODE_lstore: \
2607 case OPCODE_fstore: \
2608 case OPCODE_dstore: \
2609 case OPCODE_astore: \
2611 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2615 error ("unrecogized wide sub-instruction"); \
2619 #define SPECIAL_THROW(IGNORED) \
2620 build_java_athrow (pop_value (throwable_type_node))
2622 #define SPECIAL_BREAK NOT_IMPL1
2623 #define IMPL NOT_IMPL
2625 #include "javaop.def"
2628 fprintf (stderr
, "%3d: unknown(%3d)\n", oldpc
, byte_ops
[PC
]);
2633 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2634 order, as specified by Java Language Specification.
2636 The problem is that while expand_expr will evaluate its sub-operands in
2637 left-to-right order, for variables it will just return an rtx (i.e.
2638 an lvalue) for the variable (rather than an rvalue). So it is possible
2639 that a later sub-operand will change the register, and when the
2640 actual operation is done, it will use the new value, when it should
2641 have used the original value.
2643 We fix this by using save_expr. This forces the sub-operand to be
2644 copied into a fresh virtual register,
2646 For method invocation, we modify the arguments so that a
2647 left-to-right order evaluation is performed. Saved expressions
2648 will, in CALL_EXPR order, be reused when the call will be expanded.
2652 force_evaluation_order (node
)
2655 if (flag_syntax_only
)
2657 if (TREE_CODE_CLASS (TREE_CODE (node
)) == '2')
2659 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node
, 1)))
2660 TREE_OPERAND (node
, 0) = save_expr (TREE_OPERAND (node
, 0));
2662 else if (TREE_CODE (node
) == CALL_EXPR
|| TREE_CODE (node
) == NEW_CLASS_EXPR
)
2666 if (!TREE_OPERAND (node
, 1))
2669 /* This reverses the evaluation order. This is a desired effect. */
2670 for (cmp
= NULL_TREE
, arg
= TREE_OPERAND (node
, 1);
2671 arg
; arg
= TREE_CHAIN (arg
))
2673 tree saved
= save_expr (TREE_VALUE (arg
));
2674 cmp
= (cmp
== NULL_TREE
? saved
:
2675 build (COMPOUND_EXPR
, void_type_node
, cmp
, saved
));
2676 TREE_VALUE (arg
) = saved
;
2679 if (cmp
&& TREE_CODE (cmp
) == COMPOUND_EXPR
)
2680 TREE_SIDE_EFFECTS (cmp
) = 1;
2684 cmp
= save_expr (build (COMPOUND_EXPR
, TREE_TYPE (node
), cmp
, node
));
2685 CAN_COMPLETE_NORMALLY (cmp
) = CAN_COMPLETE_NORMALLY (node
);
2686 TREE_SIDE_EFFECTS (cmp
) = 1;