1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
34 #include "java-tree.h"
36 #include "java-opcodes.h"
38 #include "java-except.h"
43 static tree operand_type[59];
44 extern struct obstack permanent_obstack;
47 init_expr_processing()
49 operand_type[21] = operand_type[54] = int_type_node;
50 operand_type[22] = operand_type[55] = long_type_node;
51 operand_type[23] = operand_type[56] = float_type_node;
52 operand_type[24] = operand_type[57] = double_type_node;
53 operand_type[25] = operand_type[58] = ptr_type_node;
56 /* We store the stack state in two places:
57 Within a basic block, we use the quick_stack, which is a
58 pushdown list (TREE_LISTs) of expression nodes.
59 This is the top part of the stack; below that we use find_stack_slot.
60 At the end of a basic block, the quick_stack must be flushed
61 to the stack slot array (as handled by find_stack_slot).
62 Using quick_stack generates better code (especially when
63 compiled without optimization), because we do not have to
64 explicitly store and load trees to temporary variables.
66 If a variable is on the quick stack, it means the value of variable
67 when the quick stack was last flushed. Conceptually, flush_quick_stack
68 saves all the the quick_stack elements in parellel. However, that is
69 complicated, so it actually saves them (i.e. copies each stack value
70 to is home virtual register) from low indexes. This allows a quick_stack
71 element at index i (counting from the bottom of stack the) to references
72 slot virtuals for register that are >= i, but not those that are deeper.
73 This convention makes most operations easier. For example iadd works
74 even when the stack contains (reg[0], reg[1]): It results in the
75 stack containing (reg[0]+reg[1]), which is OK. However, some stack
76 operations are more complicated. For example dup given a stack
77 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
78 the convention, since stack value 1 would refer to a register with
79 lower index (reg[0]), which flush_quick_stack does not safely handle.
80 So dup cannot just add an extra element to the quick_stack, but iadd can.
83 tree quick_stack = NULL_TREE;
85 /* A free-list of unused permamnet TREE_LIST nodes. */
86 tree tree_list_free_list = NULL_TREE;
88 /* The stack pointer of the Java virtual machine.
89 This does include the size of the quick_stack. */
93 unsigned char *linenumber_table;
97 truthvalue_conversion (expr)
100 /* It is simpler and generates better code to have only TRUTH_*_EXPR
101 or comparison expressions as truth values at this level.
103 This function should normally be identity for Java. */
105 switch (TREE_CODE (expr))
108 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
109 case TRUTH_ANDIF_EXPR:
110 case TRUTH_ORIF_EXPR:
117 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
120 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
122 /* are these legal? XXX JH */
127 /* These don't change whether an object is non-zero or zero. */
128 return truthvalue_conversion (TREE_OPERAND (expr, 0));
131 /* Distribute the conversion into the arms of a COND_EXPR. */
132 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
133 truthvalue_conversion (TREE_OPERAND (expr, 1)),
134 truthvalue_conversion (TREE_OPERAND (expr, 2))));
137 /* If this is widening the argument, we can ignore it. */
138 if (TYPE_PRECISION (TREE_TYPE (expr))
139 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
140 return truthvalue_conversion (TREE_OPERAND (expr, 0));
141 /* fall through to default */
144 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
148 #ifdef JAVA_USE_HANDLES
149 /* Given a pointer to a handle, get a pointer to an object. */
155 tree field, handle_type;
156 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
157 handle_type = TREE_TYPE (expr);
158 field = TYPE_FIELDS (handle_type);
159 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
164 /* Save any stack slots that happen to be in the quick_stack into their
165 home virtual register slots.
167 The copy order is from low stack index to high, to support the invariant
168 that the expression for a slot may contain decls for stack slots with
169 higher (or the same) index, but not lower. */
174 int stack_index = stack_pointer;
175 register tree prev, cur, next;
177 /* First reverse the quick_stack, and count the number of slots it has. */
178 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
180 next = TREE_CHAIN (cur);
181 TREE_CHAIN (cur) = prev;
183 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
187 while (quick_stack != NULL_TREE)
190 tree node = quick_stack, type;
191 quick_stack = TREE_CHAIN (node);
192 TREE_CHAIN (node) = tree_list_free_list;
193 tree_list_free_list = node;
194 node = TREE_VALUE (node);
195 type = TREE_TYPE (node);
197 decl = find_stack_slot (stack_index, type);
199 expand_assignment (decl, node, 0, 0);
200 stack_index += 1 + TYPE_IS_WIDE (type);
209 type = promote_type (type);
210 n_words = 1 + TYPE_IS_WIDE (type);
211 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
212 fatal ("stack overflow");
213 stack_type_map[stack_pointer++] = type;
215 while (--n_words >= 0)
216 stack_type_map[stack_pointer++] = TYPE_SECOND;
223 tree type = TREE_TYPE (value);
224 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
226 type = promote_type (type);
227 value = convert (type, value);
230 if (tree_list_free_list == NULL_TREE)
231 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
234 tree node = tree_list_free_list;
235 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
236 TREE_VALUE (node) = value;
237 TREE_CHAIN (node) = quick_stack;
248 if (TREE_CODE (type) == RECORD_TYPE)
249 type = promote_type (type);
250 n_words = 1 + TYPE_IS_WIDE (type);
251 if (stack_pointer < n_words)
252 fatal ("stack underflow");
253 while (--n_words > 0)
255 if (stack_type_map[--stack_pointer] != void_type_node)
256 fatal ("Invalid multi-word value on type stack");
258 t = stack_type_map[--stack_pointer];
259 if (type == NULL_TREE || t == type)
261 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
262 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
264 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
266 if (type == ptr_type_node || type == object_ptr_type_node)
268 else if (t == ptr_type_node) /* Special case for null reference. */
270 else if (can_widen_reference_to (t, type))
272 /* This is a kludge, but matches what Sun's verifier does.
273 It can be tricked, but is safe as long as type errors
274 (i.e. interface method calls) are caught at run-time. */
275 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
276 && t == object_ptr_type_node)
279 error ("unexpected type on stack");
283 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
284 Handles array types and interfaces. */
287 can_widen_reference_to (source_type, target_type)
288 tree source_type, target_type;
290 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
293 /* Get rid of pointers */
294 if (TREE_CODE (source_type) == POINTER_TYPE)
295 source_type = TREE_TYPE (source_type);
296 if (TREE_CODE (target_type) == POINTER_TYPE)
297 target_type = TREE_TYPE (target_type);
299 if (source_type == target_type)
303 source_type = HANDLE_TO_CLASS_TYPE (source_type);
304 target_type = HANDLE_TO_CLASS_TYPE (target_type);
305 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
307 HOST_WIDE_INT source_length, target_length;
308 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
310 target_length = java_array_type_length (target_type);
311 if (target_length >= 0)
313 source_length = java_array_type_length (source_type);
314 if (source_length != target_length)
317 source_type = TYPE_ARRAY_ELEMENT (source_type);
318 target_type = TYPE_ARRAY_ELEMENT (target_type);
319 if (source_type == target_type)
321 if (TREE_CODE (source_type) != POINTER_TYPE
322 || TREE_CODE (target_type) != POINTER_TYPE)
324 return can_widen_reference_to (source_type, target_type);
328 int source_depth = class_depth (source_type);
329 int target_depth = class_depth (target_type);
331 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
333 /* target_type is OK if source_type or source_type ancestors
334 implement target_type. We handle multiple sub-interfaces */
336 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
337 int n = TREE_VEC_LENGTH (basetype_vec), i;
338 for (i=0 ; i < n; i++)
339 if (can_widen_reference_to
340 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
347 for ( ; source_depth > target_depth; source_depth--)
349 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
351 return source_type == target_type;
360 type = pop_type (type);
363 tree node = quick_stack;
364 quick_stack = TREE_CHAIN (quick_stack);
365 TREE_CHAIN (node) = tree_list_free_list;
366 tree_list_free_list = node;
367 node = TREE_VALUE (node);
371 return find_stack_slot (stack_pointer, promote_type (type));
375 /* Pop and discrad the top COUNT stack slots. */
378 java_stack_pop (count)
384 if (stack_pointer == 0)
385 fatal ("stack underflow");
386 type = stack_type_map[stack_pointer - 1];
387 if (type == TYPE_SECOND)
390 if (stack_pointer == 1 || count <= 0)
391 fatal ("stack underflow");
392 type = stack_type_map[stack_pointer - 2];
394 val = pop_value (type);
399 /* Implement the 'swap' operator (to swap two top stack slots). */
408 if (stack_pointer < 2
409 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
410 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
411 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
412 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
413 fatal ("bad stack swap");
415 flush_quick_stack ();
416 decl1 = find_stack_slot (stack_pointer - 1, type1);
417 decl2 = find_stack_slot (stack_pointer - 2, type2);
418 temp = copy_to_reg (DECL_RTL (decl1));
419 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
420 emit_move_insn (DECL_RTL (decl2), temp);
421 stack_type_map[stack_pointer - 1] = type2;
422 stack_type_map[stack_pointer - 2] = type1;
426 java_stack_dup (size, offset)
429 int low_index = stack_pointer - size - offset;
432 error ("stack underflow - dup* operation");
434 flush_quick_stack ();
436 stack_pointer += size;
437 dst_index = stack_pointer;
439 for (dst_index = stack_pointer; --dst_index >= low_index; )
442 int src_index = dst_index - size;
443 if (src_index < low_index)
444 src_index = dst_index + size + offset;
445 type = stack_type_map [src_index];
446 if (type == TYPE_SECOND)
448 if (src_index <= low_index)
449 fatal ("dup operation splits 64-bit number");
450 stack_type_map[dst_index] = type;
451 src_index--; dst_index--;
452 type = stack_type_map[src_index];
453 if (! TYPE_IS_WIDE (type))
454 fatal ("internal error - dup operation");
456 else if (TYPE_IS_WIDE (type))
457 fatal ("internal error - dup operation");
458 if (src_index != dst_index)
460 tree src_decl = find_stack_slot (src_index, type);
461 tree dst_decl = find_stack_slot (dst_index, type);
462 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
463 stack_type_map[dst_index] = type;
468 /* Calls _Jv_Throw. Discard the contents of the value stack. */
471 build_java_athrow (node)
476 call = build (CALL_EXPR,
478 build_address_of (throw_node),
479 build_tree_list (NULL_TREE, node),
481 TREE_SIDE_EFFECTS (call) = 1;
482 expand_expr_stmt (call);
483 java_stack_pop (stack_pointer);
486 /* Implementation for jsr/ret */
489 build_java_jsr (where, ret)
493 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
494 push_value (ret_label);
495 flush_quick_stack ();
501 build_java_ret (location)
504 expand_computed_goto (location);
507 /* Implementation of operations on array: new, load, store, length */
509 /* Array core info access macros */
511 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
512 size_binop (CEIL_DIV_EXPR, \
514 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
515 size_int (BITS_PER_UNIT))
518 decode_newarray_type (int atype)
522 case 4: return boolean_type_node;
523 case 5: return char_type_node;
524 case 6: return float_type_node;
525 case 7: return double_type_node;
526 case 8: return byte_type_node;
527 case 9: return short_type_node;
528 case 10: return int_type_node;
529 case 11: return long_type_node;
530 default: return NULL_TREE;
534 /* Map primitive type to the code used by OPCODE_newarray. */
537 encode_newarray_type (type)
540 if (type == boolean_type_node)
542 else if (type == char_type_node)
544 else if (type == float_type_node)
546 else if (type == double_type_node)
548 else if (type == byte_type_node)
550 else if (type == short_type_node)
552 else if (type == int_type_node)
554 else if (type == long_type_node)
557 fatal ("Can't compute type code - patch_newarray");
560 /* Build a call to _Jv_ThrowBadArrayIndex(), the
561 ArrayIndexOfBoundsException exception handler. */
564 build_java_throw_out_of_bounds_exception (index)
567 tree node = build (CALL_EXPR, int_type_node,
568 build_address_of (soft_badarrayindex_node),
569 build_tree_list (NULL_TREE, index), NULL_TREE);
570 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
574 /* Return the length of an array. Doesn't perform any checking on the nature
575 or value of the array NODE. May be used to implement some bytecodes. */
578 build_java_array_length_access (node)
581 tree type = TREE_TYPE (node);
582 HOST_WIDE_INT length;
583 if (!is_array_type_p (type))
584 fatal ("array length on a non-array reference");
585 length = java_array_type_length (type);
587 return build_int_2 (length, 0);
588 return fold (build1 (INDIRECT_REF,
590 fold (build (PLUS_EXPR, ptr_type_node,
592 JAVA_ARRAY_LENGTH_OFFSET(node)))));
595 /* Optionally checks an array against the NULL pointer, eventually throwing a
596 NullPointerException. It could replace signal handling, but tied to NULL.
597 ARG1: the pointer to check, ARG2: the expression to use if
598 the pointer is non-null and ARG3 the type that should be returned. */
601 build_java_arraynull_check (node, expr, type)
607 static int java_array_access_throws_null_exception = 0;
609 if (java_array_access_throws_null_exception)
610 return (build (COND_EXPR,
612 build (EQ_EXPR, int_type_node, node, null_pointer_node),
613 build_java_athrow (node), expr ));
620 java_array_data_offset (array)
623 tree array_type = TREE_TYPE (TREE_TYPE (array));
624 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
625 if (data_fld == NULL_TREE)
626 return size_in_bytes (array_type);
628 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
632 /* Implement array indexing (either as l-value or r-value).
633 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
634 Optionally performs bounds checking and/or test to NULL.
635 At this point, ARRAY should have been verified as an array. */
638 build_java_arrayaccess (array, type, index)
639 tree array, type, index;
641 tree arith, node, throw = NULL_TREE;
643 arith = fold (build (PLUS_EXPR, int_type_node,
644 java_array_data_offset (array),
645 fold (build (MULT_EXPR, int_type_node,
646 index, size_in_bytes(type)))));
648 if (flag_bounds_check)
651 * (unsigned jint) INDEX >= (unsigned jint) LEN
652 * && throw ArrayIndexOutOfBoundsException.
653 * Note this is equivalent to and more efficient than:
654 * INDEX < 0 || INDEX >= LEN && throw ... */
656 tree len = build_java_array_length_access (array);
657 TREE_TYPE (len) = unsigned_int_type_node;
658 test = fold (build (GE_EXPR, boolean_type_node,
659 convert (unsigned_int_type_node, index),
661 if (! integer_zerop (test))
663 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
664 build_java_throw_out_of_bounds_exception (index));
665 /* allows expansion within COMPOUND */
666 TREE_SIDE_EFFECTS( throw ) = 1;
670 node = build1 (INDIRECT_REF, type,
671 fold (build (PLUS_EXPR, ptr_type_node,
673 (throw ? build (COMPOUND_EXPR, int_type_node,
677 return (fold (build_java_arraynull_check (array, node, type)));
680 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
681 ARRAY_NODE. This function is used to retrieve something less vague than
682 a pointer type when indexing the first dimension of something like [[<t>.
683 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
685 As a side effect, it also makes sure that ARRAY_NODE is an array. */
688 build_java_check_indexed_type (array_node, indexed_type)
694 if (!is_array_type_p (TREE_TYPE (array_node)))
695 fatal ("array indexing on a non-array reference");
697 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
699 if (indexed_type == ptr_type_node )
700 return promote_type (elt_type);
702 /* BYTE/BOOLEAN store and load are used for both type */
703 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
704 return boolean_type_node;
706 if (indexed_type != elt_type )
707 fatal ("type array element mismatch");
712 /* newarray triggers a call to _Jv_NewArray. This function should be called
713 with an integer code (the type of array to create) and get from the stack
714 the size of the dimmension. */
717 build_newarray (atype_value, length)
721 tree type = build_java_array_type (decode_newarray_type (atype_value),
722 TREE_CODE (length) == INTEGER_CST
723 ? TREE_INT_CST_LOW (length)
725 return build (CALL_EXPR, promote_type (type),
726 build_address_of (soft_newarray_node),
727 tree_cons (NULL_TREE,
728 build_int_2 (atype_value, 0),
729 build_tree_list (NULL_TREE, length)),
733 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
737 build_anewarray (class_type, length)
741 tree type = build_java_array_type (class_type,
742 TREE_CODE (length) == INTEGER_CST
743 ? TREE_INT_CST_LOW (length)
745 return build (CALL_EXPR, promote_type (type),
746 build_address_of (soft_anewarray_node),
747 tree_cons (NULL_TREE, length,
748 tree_cons (NULL_TREE, build_class_ref (class_type),
749 build_tree_list (NULL_TREE,
750 null_pointer_node))),
754 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
757 build_new_array (type, length)
761 if (JPRIMITIVE_TYPE_P (type))
762 return build_newarray (encode_newarray_type (type), length);
764 return build_anewarray (TREE_TYPE (type), length);
767 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
768 class pointer, a number of dimensions and the matching number of
769 dimensions. The argument list is NULL terminated. */
772 expand_java_multianewarray (class_type, ndim)
777 tree args = build_tree_list( NULL_TREE, null_pointer_node );
779 for( i = 0; i < ndim; i++ )
780 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
782 push_value (build (CALL_EXPR,
783 promote_type (class_type),
784 build_address_of (soft_multianewarray_node),
785 tree_cons (NULL_TREE, build_class_ref (class_type),
786 tree_cons (NULL_TREE,
787 build_int_2 (ndim, 0), args )),
791 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
792 ARRAY is an array type. May expand some bound checking and NULL
793 pointer checking. RHS_TYPE_NODE we are going to store. In the case
794 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
795 INT. In those cases, we make the convertion.
797 if ARRAy is a reference type, the assignment is checked at run-time
798 to make sure that the RHS can be assigned to the array element
799 type. It is not necessary to generate this code if ARRAY is final. */
802 expand_java_arraystore (rhs_type_node)
805 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
806 && TYPE_PRECISION (rhs_type_node) <= 32) ?
807 int_type_node : rhs_type_node);
808 tree index = pop_value (int_type_node);
809 tree array = pop_value (ptr_type_node);
811 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
813 flush_quick_stack ();
815 index = save_expr (index);
816 array = save_expr (array);
818 if (TREE_CODE (rhs_type_node) == POINTER_TYPE
819 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
821 tree check = build (CALL_EXPR, void_type_node,
822 build_address_of (soft_checkarraystore_node),
823 tree_cons (NULL_TREE, array,
824 build_tree_list (NULL_TREE, rhs_node)),
826 TREE_SIDE_EFFECTS (check) = 1;
827 expand_expr_stmt (check);
830 expand_assignment (build_java_arrayaccess (array,
836 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
837 sure that LHS is an array type. May expand some bound checking and NULL
839 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
840 BOOLEAN/SHORT, we push a promoted type back to the stack.
844 expand_java_arrayload (lhs_type_node )
848 tree index_node = pop_value (int_type_node);
849 tree array_node = pop_value (ptr_type_node);
851 index_node = save_expr (index_node);
852 array_node = save_expr (array_node);
853 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
855 load_node = build_java_arrayaccess (array_node,
859 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
860 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
861 push_value (load_node);
864 /* Expands .length. Makes sure that we deal with and array and may expand
865 a NULL check on the array object. */
868 expand_java_array_length ()
870 tree array = pop_value (ptr_type_node);
871 tree length = build_java_array_length_access (array);
873 push_value (build_java_arraynull_check (array, length, int_type_node));
876 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
877 either soft_monitorenter_node or soft_monitorexit_node. */
880 build_java_monitor (call, object)
884 return (build (CALL_EXPR,
886 build_address_of (call),
887 build_tree_list (NULL_TREE, object),
891 /* Emit code for one of the PUSHC instructions. */
894 expand_java_pushc (ival, type)
899 if (type == ptr_type_node && ival == 0)
900 value = null_pointer_node;
901 else if (type == int_type_node || type == long_type_node)
903 value = build_int_2 (ival, ival < 0 ? -1 : 0);
904 TREE_TYPE (value) = type;
906 else if (type == float_type_node || type == double_type_node)
909 #ifdef REAL_ARITHMETIC
910 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
914 value = build_real (type, x);
917 fatal ("internal error in expand_java_pushc");
922 expand_java_return (type)
925 if (type == void_type_node)
926 expand_null_return ();
929 tree retval = pop_value (type);
930 tree res = DECL_RESULT (current_function_decl);
931 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
932 TREE_SIDE_EFFECTS (retval) = 1;
933 expand_return (retval);
938 build_address_of (value)
941 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
945 expand_java_NEW (type)
948 if (! CLASS_LOADED_P (type))
949 load_class (type, 1);
950 layout_class_methods (type);
951 push_value (build (CALL_EXPR, promote_type (type),
952 build_address_of (alloc_object_node),
953 tree_cons (NULL_TREE, build_class_ref (type),
954 build_tree_list (NULL_TREE,
955 size_in_bytes (type))),
960 expand_java_INSTANCEOF (type)
963 tree value = pop_value (object_ptr_type_node);
964 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
965 build_address_of (soft_instanceof_node),
966 tree_cons (NULL_TREE, value,
967 build_tree_list (NULL_TREE,
968 build_class_ref (type))),
974 expand_java_CHECKCAST (type)
977 tree value = pop_value (ptr_type_node);
978 value = build (CALL_EXPR, promote_type (type),
979 build_address_of (soft_checkcast_node),
980 tree_cons (NULL_TREE, build_class_ref (type),
981 build_tree_list (NULL_TREE, value)),
987 expand_iinc (unsigned int local_var_index, int ival, int pc)
992 flush_quick_stack ();
993 local_var = find_local_variable (local_var_index, int_type_node, pc);
994 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
995 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
996 expand_assignment (local_var, res, 0, 0);
1000 build_java_binop (op, type, arg1, arg2)
1002 tree type, arg1, arg2;
1009 tree u_type = unsigned_type (type);
1010 arg1 = convert (u_type, arg1);
1011 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1012 return convert (type, arg1);
1016 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1017 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1020 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1021 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1022 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1024 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1025 boolean_type_node, arg1, arg2));
1026 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1027 tree second_compare = fold (build (COND_EXPR, int_type_node,
1028 ifexp2, integer_zero_node,
1029 op == COMPARE_L_EXPR
1030 ? integer_negative_one_node
1031 : integer_one_node));
1032 return fold (build (COND_EXPR, int_type_node, ifexp1,
1033 op == COMPARE_L_EXPR ? integer_one_node
1034 : integer_negative_one_node,
1038 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1040 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1041 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1042 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1043 ifexp2, integer_one_node,
1044 integer_zero_node));
1045 return fold (build (COND_EXPR, int_type_node,
1046 ifexp1, integer_negative_one_node, second_compare));
1049 case TRUNC_MOD_EXPR:
1050 if (TREE_CODE (type) == REAL_TYPE)
1053 if (type != double_type_node)
1055 arg1 = convert (double_type_node, arg1);
1056 arg2 = convert (double_type_node, arg2);
1058 call = build (CALL_EXPR, double_type_node,
1059 build_address_of (soft_fmod_node),
1060 tree_cons (NULL_TREE, arg1,
1061 build_tree_list (NULL_TREE, arg2)),
1063 if (type != double_type_node)
1064 call = convert (type, call);
1070 return fold (build (op, type, arg1, arg2));
1074 expand_java_binop (type, op)
1075 tree type; enum tree_code op;
1085 rtype = int_type_node;
1086 rarg = pop_value (rtype);
1089 rarg = pop_value (rtype);
1091 larg = pop_value (ltype);
1092 push_value (build_java_binop (op, type, larg, rarg));
1095 /* Lookup the field named NAME in *TYPEP or its super classes.
1096 If not found, return NULL_TREE.
1097 (If the *TYPEP is not found, return error_mark_node.)
1098 If found, return the FIELD_DECL, and set *TYPEP to the
1099 class containing the field. */
1102 lookup_field (typep, name)
1106 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1108 load_class (*typep, 1);
1109 if (TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1110 return error_mark_node;
1115 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1117 if (DECL_NAME (field) == name)
1120 *typep = CLASSTYPE_SUPER (*typep);
1125 /* Look up the field named NAME in object SELF_VALUE,
1126 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1127 SELF_VALUE is NULL_TREE if looking for a static field. */
1130 build_field_ref (self_value, self_class, name)
1131 tree self_value, self_class, name;
1133 tree base_class = self_class;
1134 tree field_decl = lookup_field (&base_class, name);
1135 if (field_decl == NULL_TREE)
1137 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1138 return error_mark_node;
1140 if (self_value == NULL_TREE)
1142 return build_static_field_ref (field_decl);
1146 tree base_handle_type = promote_type (base_class);
1147 if (base_handle_type != TREE_TYPE (self_value))
1148 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1149 #ifdef JAVA_USE_HANDLES
1150 self_value = unhand_expr (self_value);
1152 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1154 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1155 self_value, field_decl));
1165 sprintf (buf, "LJpc=%d", pc);
1166 name = get_identifier (buf);
1167 if (IDENTIFIER_LOCAL_VALUE (name))
1168 return IDENTIFIER_LOCAL_VALUE (name);
1171 /* The type of the address of a label is return_address_type_node. */
1172 tree decl = create_label_decl (name);
1173 LABEL_PC (decl) = pc;
1175 return pushdecl (decl);
1179 /* Generate a unique name for the purpose of loops and switches
1180 labels, and try-catch-finally blocks label or temporary variables. */
1185 static int l_number = 0;
1187 sprintf (buff, "$LJv%d", l_number++);
1188 return get_identifier (buff);
1192 create_label_decl (name)
1196 push_obstacks (&permanent_obstack, &permanent_obstack);
1197 decl = build_decl (LABEL_DECL, name,
1198 TREE_TYPE (return_address_type_node));
1200 DECL_CONTEXT (decl) = current_function_decl;
1201 DECL_IGNORED_P (decl) = 1;
1205 /* This maps a bytecode offset (PC) to various flags. */
1206 char *instruction_bits;
1209 note_label (current_pc, target_pc)
1210 int current_pc, target_pc;
1212 lookup_label (target_pc);
1213 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1216 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1217 where CONDITION is one of one the compare operators. */
1220 expand_compare (condition, value1, value2, target_pc)
1221 enum tree_code condition;
1222 tree value1, value2;
1225 tree target = lookup_label (target_pc);
1226 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1227 expand_start_cond (truthvalue_conversion (cond), 0);
1228 expand_goto (target);
1232 /* Emit code for a TEST-type opcode. */
1235 expand_test (condition, type, target_pc)
1236 enum tree_code condition;
1240 tree value1, value2;
1241 flush_quick_stack ();
1242 value1 = pop_value (type);
1243 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1244 expand_compare (condition, value1, value2, target_pc);
1247 /* Emit code for a COND-type opcode. */
1250 expand_cond (condition, type, target_pc)
1251 enum tree_code condition;
1255 tree value1, value2;
1256 flush_quick_stack ();
1257 /* note: pop values in opposite order */
1258 value2 = pop_value (type);
1259 value1 = pop_value (type);
1260 /* Maybe should check value1 and value2 for type compatibility ??? */
1261 expand_compare (condition, value1, value2, target_pc);
1265 expand_java_goto (target_pc)
1268 tree target_label = lookup_label (target_pc);
1269 flush_quick_stack ();
1270 expand_goto (target_label);
1274 expand_java_call (target_pc, return_address)
1275 int target_pc, return_address;
1277 tree target_label = lookup_label (target_pc);
1278 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1280 flush_quick_stack ();
1281 expand_goto (target_label);
1285 expand_java_ret (return_address)
1286 tree return_address;
1288 warning ("ret instruction not implemented");
1290 tree target_label = lookup_label (target_pc);
1291 flush_quick_stack ();
1292 expand_goto (target_label);
1296 /* Recursive helper function to pop argument types during verifiation. */
1299 pop_argument_types (arg_types)
1302 if (arg_types == end_params_node)
1304 if (TREE_CODE (arg_types) == TREE_LIST)
1306 pop_argument_types (TREE_CHAIN (arg_types));
1307 pop_type (TREE_VALUE (arg_types));
1314 pop_arguments (arg_types)
1317 if (arg_types == end_params_node)
1319 if (TREE_CODE (arg_types) == TREE_LIST)
1321 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1322 tree type = TREE_VALUE (arg_types);
1323 tree arg = pop_value (type);
1324 #ifdef PROMOTE_PROTOTYPES
1325 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1326 && INTEGRAL_TYPE_P (type))
1327 arg = convert (integer_type_node, arg);
1329 return tree_cons (NULL_TREE, arg, tail);
1334 /* Build an expression to initialize the class CLAS.
1335 if EXPR is non-NULL, returns an expression to first call the initializer
1336 (if it is needed) and then calls EXPR. */
1339 build_class_init (clas, expr)
1343 if (inherits_from_p (current_class, clas))
1345 init = build (CALL_EXPR, void_type_node,
1346 build_address_of (soft_initclass_node),
1347 build_tree_list (NULL_TREE, build_class_ref (clas)),
1349 TREE_SIDE_EFFECTS (init) = 1;
1350 if (expr != NULL_TREE)
1352 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1353 TREE_SIDE_EFFECTS (expr) = 1;
1359 static tree methods_ident = NULL_TREE;
1360 static tree ncode_ident = NULL_TREE;
1361 tree dtable_ident = NULL_TREE;
1364 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1365 tree method, method_type, self_type, method_signature, arg_list;
1368 if (is_compiled_class (self_type))
1370 make_decl_rtl (method, NULL, 1);
1371 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1375 /* We don't know whether the method has been (statically) compiled.
1376 Compile this code to get a reference to the method's code:
1378 SELF_TYPE->methods[METHOD_INDEX].ncode
1380 This is guaranteed to work (assuming SELF_TYPE has
1381 been initialized), since if the method is not compiled yet,
1382 its ncode points to a trampoline that forces compilation. */
1384 int method_index = 0;
1386 tree ref = build_class_ref (self_type);
1387 ref = build1 (INDIRECT_REF, class_type_node, ref);
1388 if (ncode_ident == NULL_TREE)
1389 ncode_ident = get_identifier ("ncode");
1390 if (methods_ident == NULL_TREE)
1391 methods_ident = get_identifier ("methods");
1392 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1393 lookup_field (&class_type_node, methods_ident));
1394 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1395 ; meth = TREE_CHAIN (meth))
1399 if (meth == NULL_TREE)
1400 fatal ("method '%s' not found in class",
1401 IDENTIFIER_POINTER (DECL_NAME (method)));
1404 method_index *= int_size_in_bytes (method_type_node);
1405 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1406 ref, build_int_2 (method_index, 0)));
1407 ref = build1 (INDIRECT_REF, method_type_node, ref);
1408 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1410 lookup_field (&method_type_node, ncode_ident));
1416 invoke_build_dtable (is_invoke_interface, arg_list)
1417 int is_invoke_interface;
1420 tree dtable, objectref;
1422 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1424 /* If we're dealing with interfaces and if the objectref
1425 argument is an array then get the dispatch table of the class
1426 Object rather than the one from the objectref. */
1427 objectref = (is_invoke_interface
1428 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1429 object_type_node : TREE_VALUE (arg_list));
1431 if (dtable_ident == NULL_TREE)
1432 dtable_ident = get_identifier ("vtable");
1433 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1434 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1435 lookup_field (&object_type_node, dtable_ident));
1441 build_invokevirtual (dtable, method)
1442 tree dtable, method;
1445 tree nativecode_ptr_ptr_type_node
1446 = build_pointer_type (nativecode_ptr_type_node);
1447 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1448 /* Add one to skip "class" field of dtable, and one to skip unused
1449 vtable entry (for C++ compatibility). */
1452 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1453 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1454 dtable, build_int_2 (method_index, 0)));
1455 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1461 build_invokeinterface (dtable, method_name, method_signature)
1462 tree dtable, method_name, method_signature;
1464 static tree class_ident = NULL_TREE;
1467 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1468 ensure that the selected method exists, is public and not
1469 abstract nor static. */
1471 if (class_ident == NULL_TREE)
1472 class_ident = get_identifier ("class");
1474 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1475 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1476 lookup_field (&dtable_type, class_ident));
1477 lookup_arg = build_tree_list (NULL_TREE,
1480 (IDENTIFIER_POINTER(method_signature),
1481 IDENTIFIER_LENGTH(method_signature)))));
1482 lookup_arg = tree_cons (NULL_TREE, dtable,
1483 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1485 return build (CALL_EXPR, ptr_type_node,
1486 build_address_of (soft_lookupinterfacemethod_node),
1487 lookup_arg, NULL_TREE);
1490 /* Expand one of the invoke_* opcodes.
1491 OCPODE is the specific opcode.
1492 METHOD_REF_INDEX is an index into the constant pool.
1493 NARGS is the number of arguments, or -1 if not specified. */
1496 expand_invoke (opcode, method_ref_index, nargs)
1498 int method_ref_index;
1501 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1502 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1503 tree self_type = get_class_constant
1504 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1505 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1506 tree call, func, method, arg_list, method_type;
1508 if (! CLASS_LOADED_P (self_type))
1510 load_class (self_type, 1);
1511 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1512 fatal ("failed to find class '%s'", self_name);
1514 layout_class_methods (self_type);
1516 if (method_name == init_identifier_node)
1517 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1520 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1521 method_name, method_signature);
1522 if (method == NULL_TREE)
1524 error ("Class '%s' has no method named '%s' matching signature '%s'",
1526 IDENTIFIER_POINTER (method_name),
1527 IDENTIFIER_POINTER (method_signature));
1529 /* Invoke static can't invoke static/abstract method */
1530 else if (opcode == OPCODE_invokestatic)
1532 if (!METHOD_STATIC (method))
1534 error ("invokestatic on non static method");
1537 else if (METHOD_ABSTRACT (method))
1539 error ("invokestatic on abstract method");
1545 if (METHOD_STATIC (method))
1547 error ("invoke[non-static] on static method");
1552 if (method == NULL_TREE)
1554 method_type = get_type_from_signature (method_signature);
1555 pop_arguments (TYPE_ARG_TYPES (method_type));
1556 if (opcode != OPCODE_invokestatic)
1557 pop_type (self_type);
1558 method_type = promote_type (TREE_TYPE (method_type));
1559 push_value (convert (method_type, integer_zero_node));
1563 method_type = TREE_TYPE (method);
1564 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1565 flush_quick_stack ();
1568 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1569 || (opcode == OPCODE_invokevirtual
1570 && (METHOD_PRIVATE (method)
1571 || METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
1572 func = build_known_method_ref (method, method_type, self_type,
1573 method_signature, arg_list);
1576 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1578 if (opcode == OPCODE_invokevirtual)
1579 func = build_invokevirtual (dtable, method);
1581 func = build_invokeinterface (dtable, method_name, method_signature);
1583 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1584 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1585 TREE_SIDE_EFFECTS (call) = 1;
1587 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1588 expand_expr_stmt (call);
1592 flush_quick_stack ();
1597 /* Expand an operation to extract from or store into a field.
1598 IS_STATIC is 1 iff the field is static.
1599 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1600 FIELD_REF_INDEX is an index into the constant pool. */
1603 expand_java_field_op (is_static, is_putting, field_ref_index)
1606 int field_ref_index;
1608 tree self_type = get_class_constant
1609 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, field_ref_index));
1610 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1611 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
1612 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, field_ref_index);
1613 tree field_type = get_type_from_signature (field_signature);
1614 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1617 tree field_decl = lookup_field (&self_type, field_name);
1618 if (field_decl == error_mark_node)
1622 else if (field_decl == NULL_TREE)
1624 error ("Missing field '%s' in '%s'",
1625 IDENTIFIER_POINTER (field_name), self_name);
1628 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1630 error ("Mismatching signature for field '%s' in '%s'",
1631 IDENTIFIER_POINTER (field_name), self_name);
1634 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1638 push_value (convert (field_type, integer_zero_node));
1639 flush_quick_stack ();
1643 /* Inline references to java.lang.PRIMTYPE.TYPE.
1644 In addition to being a useful (minor) optimization,
1645 this is also needed to avoid circularities in the implementation
1646 of these fields in libjava. */
1647 if (field_name == TYPE_identifier_node && ! is_putting
1648 && ! flag_emit_class_files && field_type == class_ptr_type
1649 && strncmp (self_name, "java.lang.", 10) == 0)
1651 tree typ = build_primtype_type_ref (self_name);
1659 field_ref = build_field_ref (field_ref, self_type, field_name);
1661 field_ref = build_class_init (self_type, field_ref);
1664 flush_quick_stack ();
1665 if (FIELD_FINAL (field_decl))
1667 if (DECL_CONTEXT (field_decl) != current_class)
1668 error_with_decl (field_decl,
1669 "assignment to final field `%s' not in field's class");
1670 else if (FIELD_STATIC (field_decl))
1672 if (DECL_NAME (current_function_decl) != clinit_identifier_node)
1673 error_with_decl (field_decl,
1674 "assignment to final static field `%s' not in class initializer");
1678 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1679 error_with_decl (field_decl,
1680 "assignment to final field `%s' not in constructor");
1683 expand_assignment (field_ref, new_value, 0, 0);
1686 push_value (field_ref);
1690 build_primtype_type_ref (self_name)
1693 char *class_name = self_name+10;
1695 if (strncmp(class_name, "Byte", 4) == 0)
1696 typ = byte_type_node;
1697 else if (strncmp(class_name, "Short", 5) == 0)
1698 typ = short_type_node;
1699 else if (strncmp(class_name, "Integer", 7) == 0)
1700 typ = int_type_node;
1701 else if (strncmp(class_name, "Long", 4) == 0)
1702 typ = long_type_node;
1703 else if (strncmp(class_name, "Float", 5) == 0)
1704 typ = float_type_node;
1705 else if (strncmp(class_name, "Double", 6) == 0)
1706 typ = double_type_node;
1707 else if (strncmp(class_name, "Boolean", 7) == 0)
1708 typ = boolean_type_node;
1709 else if (strncmp(class_name, "Char", 4) == 0)
1710 typ = char_type_node;
1711 else if (strncmp(class_name, "Void", 4) == 0)
1712 typ = void_type_node;
1715 if (typ != NULL_TREE)
1716 return build_class_ref (typ);
1722 load_type_state (label)
1726 tree vec = LABEL_TYPE_STATE (label);
1727 int cur_length = TREE_VEC_LENGTH (vec);
1728 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1729 for (i = 0; i < cur_length; i++)
1730 type_map [i] = TREE_VEC_ELT (vec, i);
1733 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1734 dependant things, but they rely on gcc routines. This function is
1735 placed here because it uses things defined locally in parse.y. */
1738 case_identity (t, v)
1739 tree t __attribute__ ((__unused__));
1746 java_lang_expand_expr (exp, target, tmode, modifier)
1749 enum machine_mode tmode;
1750 enum expand_modifier modifier;
1756 switch (TREE_CODE (exp))
1758 case NEW_ARRAY_INIT:
1761 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1762 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1763 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1764 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1765 tree length = build_int_2 (ilength, 0);
1766 tree init = TREE_OPERAND (exp, 0);
1769 /* Enable this once we can set the vtable field statically. FIXME */
1770 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1771 && JPRIMITIVE_TYPE_P (element_type))
1773 tree temp, value, init_decl;
1774 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1775 PUSH_FIELD_VALUE (temp, "vtable",
1776 null_pointer_node /* FIXME */
1778 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1779 FINISH_RECORD_CONSTRUCTOR (temp);
1780 START_RECORD_CONSTRUCTOR (value, array_type);
1781 PUSH_SUPER_VALUE (value, temp);
1782 PUSH_FIELD_VALUE (value, "length", length);
1783 PUSH_FIELD_VALUE (value, "data", init);
1784 FINISH_RECORD_CONSTRUCTOR (value);
1786 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1787 pushdecl_top_level (init_decl);
1788 TREE_STATIC (init_decl) = 1;
1789 DECL_INITIAL (init_decl) = value;
1790 DECL_IGNORED_P (init_decl) = 1;
1791 TREE_READONLY (init_decl) = 1;
1792 make_decl_rtl (init_decl, NULL, 1);
1793 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1794 return expand_expr (init, target, tmode, modifier);
1797 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1798 expand_decl (array_decl);
1799 tmp = expand_assignment (array_decl,
1800 build_new_array (element_type, length),
1802 if (TREE_CONSTANT (init)
1803 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1805 tree init_decl = build_decl (VAR_DECL, generate_name (),
1807 pushdecl_top_level (init_decl);
1808 TREE_STATIC (init_decl) = 1;
1809 DECL_INITIAL (init_decl) = init;
1810 DECL_IGNORED_P (init_decl) = 1;
1811 TREE_READONLY (init_decl) = 1;
1812 make_decl_rtl (init_decl, NULL, 1);
1815 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1816 build1 (INDIRECT_REF, array_type, array_decl),
1822 if (BLOCK_EXPR_BODY (exp))
1825 tree body = BLOCK_EXPR_BODY (exp);
1826 struct rtx_def *to_return;
1827 pushlevel (2); /* 2 and above */
1828 expand_start_bindings (0);
1829 local = BLOCK_EXPR_DECLS (exp);
1832 tree next = TREE_CHAIN (local);
1833 layout_decl (local, 0);
1834 expand_decl (pushdecl (local));
1837 /* Avoid deep recursion for long block. */
1838 while (TREE_CODE (body) == COMPOUND_EXPR)
1840 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1842 body = TREE_OPERAND (body, 1);
1844 to_return = expand_expr (body, target, tmode, modifier);
1846 expand_end_bindings (getdecls (), 1, 0);
1854 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1855 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1858 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1860 (wfl_operator, "Duplicate case label: `%s'",
1861 print_int_node (TREE_OPERAND (exp, 0)));
1867 pushcase (NULL_TREE, 0,
1868 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1872 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
1873 expand_expr_stmt (TREE_OPERAND (exp, 1));
1874 expand_end_case (TREE_OPERAND (exp, 0));
1878 /* We expand a try[-catch] block */
1880 /* Expand the try block */
1881 expand_eh_region_start ();
1882 expand_expr_stmt (TREE_OPERAND (exp, 0));
1883 expand_start_all_catch ();
1885 /* Expand all catch clauses (EH handlers) */
1886 for (current = TREE_OPERAND (exp, 1); current;
1887 current = TREE_CHAIN (current))
1889 extern rtx return_label;
1891 tree catch = TREE_OPERAND (current, 0);
1892 tree decl = BLOCK_EXPR_DECLS (catch);
1893 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
1894 start_catch_handler (prepare_eh_table_type (type));
1895 expand_expr_stmt (TREE_OPERAND (current, 0));
1897 expand_resume_after_catch ();
1898 end_catch_handler ();
1900 expand_end_all_catch ();
1904 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
1905 tree_code_name [TREE_CODE (exp)]);
1910 expand_byte_code (jcf, method)
1917 unsigned char *linenumber_pointer;
1919 #undef RET /* Defined by config/i386/i386.h */
1920 #undef AND /* Causes problems with opcodes for iand and land. */
1922 #define BCODE byte_ops
1923 #define BYTE_type_node byte_type_node
1924 #define SHORT_type_node short_type_node
1925 #define INT_type_node int_type_node
1926 #define LONG_type_node long_type_node
1927 #define CHAR_type_node char_type_node
1928 #define PTR_type_node ptr_type_node
1929 #define FLOAT_type_node float_type_node
1930 #define DOUBLE_type_node double_type_node
1931 #define VOID_type_node void_type_node
1933 unsigned char* byte_ops;
1934 long length = DECL_CODE_LENGTH (method);
1937 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
1938 byte_ops = jcf->read_ptr;
1940 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1941 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1942 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1943 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1945 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
1947 instruction_bits = oballoc (length + 1);
1948 bzero (instruction_bits, length + 1);
1950 /* We make an initial pass of the line number table, to note
1951 which instructions have associated line number entries. */
1952 linenumber_pointer = linenumber_table;
1953 for (i = 0; i < linenumber_count; i++)
1955 int pc = GET_u2 (linenumber_pointer);
1956 linenumber_pointer += 4;
1958 warning ("invalid PC in line number table");
1961 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
1962 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
1963 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
1967 /* Do a preliminary pass.
1968 * This figures out which PC can be the targets of jumps. */
1969 for (PC = 0; PC < length;)
1971 int oldpc = PC; /* PC at instruction start. */
1972 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
1973 switch (byte_ops[PC++])
1975 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
1977 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
1980 #define NOTE_LABEL(PC) note_label(oldpc, PC)
1982 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1983 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1984 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1985 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1986 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1987 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1988 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1989 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1991 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
1992 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
1993 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
1994 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
1995 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
1996 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
1997 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
1998 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2000 /* two forms of wide instructions */
2001 #define PRE_SPECIAL_WIDE(IGNORE) \
2003 int modified_opcode = IMMEDIATE_u1; \
2004 if (modified_opcode == OPCODE_iinc) \
2006 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2007 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2011 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2015 /* nothing */ /* XXX JH */
2017 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2019 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2021 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2022 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2023 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2024 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2025 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2026 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2027 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2028 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2029 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2030 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2032 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2033 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2034 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2035 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2036 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2037 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2038 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2039 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2041 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2043 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2044 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2046 #define PRE_LOOKUP_SWITCH \
2047 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2048 NOTE_LABEL (default_offset+oldpc); \
2050 while (--npairs >= 0) { \
2051 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2052 NOTE_LABEL (offset+oldpc); } \
2055 #define PRE_TABLE_SWITCH \
2056 { jint default_offset = IMMEDIATE_s4; \
2057 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2058 NOTE_LABEL (default_offset+oldpc); \
2060 while (low++ <= high) { \
2061 jint offset = IMMEDIATE_s4; \
2062 NOTE_LABEL (offset+oldpc); } \
2065 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2066 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2067 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2068 (void)(IMMEDIATE_u2); \
2069 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2071 #include "javaop.def"
2076 if (! verify_jvm_instructions (jcf, byte_ops, length))
2079 /* Translate bytecodes to rtl instructions. */
2080 linenumber_pointer = linenumber_table;
2081 for (PC = 0; PC < length;)
2083 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2085 tree label = lookup_label (PC);
2086 flush_quick_stack ();
2087 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2088 expand_label (label);
2089 if (LABEL_VERIFIED (label) || PC == 0)
2090 load_type_state (label);
2093 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2095 /* never executed - skip */
2096 warning ("Some bytecode operations (starting at pc %d) can never be executed", PC);
2098 && ! (instruction_bits [PC] & BCODE_VERIFIED))
2104 /* Handle possible line number entry for this PC.
2106 This code handles out-of-order and multiple linenumbers per PC,
2107 but is optimized for the case of line numbers increasing
2108 monotonically with PC. */
2109 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2111 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2112 || GET_u2 (linenumber_pointer) != PC)
2113 linenumber_pointer = linenumber_table;
2114 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2116 int pc = GET_u2 (linenumber_pointer);
2117 linenumber_pointer += 4;
2120 lineno = GET_u2 (linenumber_pointer - 2);
2121 emit_line_note (input_filename, lineno);
2122 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2127 maybe_start_try (PC);
2128 maybe_pushlevels (PC);
2130 PC = process_jvm_instruction (PC, byte_ops, length);
2132 maybe_poplevels (PC);
2138 java_push_constant_from_pool (jcf, index)
2143 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2146 push_obstacks (&permanent_obstack, &permanent_obstack);
2147 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2148 index = alloc_name_constant (CONSTANT_String, name);
2149 c = build_ref_from_constant_pool (index);
2150 TREE_TYPE (c) = promote_type (string_type_node);
2154 c = get_constant (jcf, index);
2159 process_jvm_instruction (PC, byte_ops, length)
2161 unsigned char* byte_ops;
2164 const char *opname; /* Temporary ??? */
2165 int oldpc = PC; /* PC at instruction start. */
2167 /* If the instruction is at the beginning of a exception handler,
2168 replace the top of the stack with the thrown object reference */
2169 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2171 tree type = pop_type (ptr_type_node);
2172 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2175 switch (byte_ops[PC++])
2177 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2180 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2183 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2185 int saw_index = 0; \
2186 int index = OPERAND_VALUE; \
2187 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2190 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2192 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2193 tree ret = lookup_label (PC); \
2194 build_java_jsr (where, ret); \
2195 load_type_state (ret); \
2198 /* Push a constant onto the stack. */
2199 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2200 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2201 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2202 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2204 /* internal macro added for use by the WIDE case */
2205 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2206 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2208 /* Push local variable onto the opcode stack. */
2209 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2211 /* have to do this since OPERAND_VALUE may have side-effects */ \
2212 int opvalue = OPERAND_VALUE; \
2213 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2216 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2217 expand_java_return (OPERAND_TYPE##_type_node)
2219 #define REM_EXPR TRUNC_MOD_EXPR
2220 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2221 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2223 #define FIELD(IS_STATIC, IS_PUT) \
2224 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2226 #define TEST(OPERAND_TYPE, CONDITION) \
2227 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2229 #define COND(OPERAND_TYPE, CONDITION) \
2230 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2232 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2233 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2235 #define BRANCH_GOTO(OPERAND_VALUE) \
2236 expand_java_goto (oldpc + OPERAND_VALUE)
2238 #define BRANCH_CALL(OPERAND_VALUE) \
2239 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2242 #define BRANCH_RETURN(OPERAND_VALUE) \
2244 tree type = OPERAND_TYPE##_type_node; \
2245 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2246 expand_java_ret (value); \
2250 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2251 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2252 fprintf (stderr, "(not implemented)\n")
2253 #define NOT_IMPL1(OPERAND_VALUE) \
2254 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2255 fprintf (stderr, "(not implemented)\n")
2257 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2259 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2261 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2263 #define STACK_SWAP(COUNT) java_stack_swap()
2265 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2266 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2267 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2269 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2270 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2272 #define LOOKUP_SWITCH \
2273 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2274 tree selector = pop_value (INT_type_node); \
2275 tree duplicate, label; \
2276 tree type = TREE_TYPE (selector); \
2277 flush_quick_stack (); \
2278 expand_start_case (0, selector, type, "switch statement");\
2279 push_momentary (); \
2280 while (--npairs >= 0) \
2282 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2283 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2284 TREE_TYPE (value) = type; \
2285 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2286 pushcase (value, convert, label, &duplicate); \
2287 expand_java_goto (oldpc + offset); \
2289 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2290 pushcase (NULL_TREE, 0, label, &duplicate); \
2291 expand_java_goto (oldpc + default_offset); \
2293 expand_end_case (selector); \
2296 #define TABLE_SWITCH \
2297 { jint default_offset = IMMEDIATE_s4; \
2298 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2299 tree selector = pop_value (INT_type_node); \
2300 tree duplicate, label; \
2301 tree type = TREE_TYPE (selector); \
2302 flush_quick_stack (); \
2303 expand_start_case (0, selector, type, "switch statement");\
2304 push_momentary (); \
2305 for (; low <= high; low++) \
2307 jint offset = IMMEDIATE_s4; \
2308 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2309 TREE_TYPE (value) = type; \
2310 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2311 pushcase (value, convert, label, &duplicate); \
2312 expand_java_goto (oldpc + offset); \
2314 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2315 pushcase (NULL_TREE, 0, label, &duplicate); \
2316 expand_java_goto (oldpc + default_offset); \
2318 expand_end_case (selector); \
2321 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2322 { int opcode = byte_ops[PC-1]; \
2323 int method_ref_index = IMMEDIATE_u2; \
2325 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2327 expand_invoke (opcode, method_ref_index, nargs); \
2330 /* Handle new, checkcast, instanceof */
2331 #define OBJECT(TYPE, OP) \
2332 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2334 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2336 #define ARRAY_LOAD(OPERAND_TYPE) \
2338 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2341 #define ARRAY_STORE(OPERAND_TYPE) \
2343 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2346 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2347 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2348 #define ARRAY_NEW_PTR() \
2349 push_value (build_anewarray (get_class_constant (current_jcf, \
2351 pop_value (int_type_node)));
2352 #define ARRAY_NEW_NUM() \
2354 int atype = IMMEDIATE_u1; \
2355 push_value (build_newarray (atype, pop_value (int_type_node)));\
2357 #define ARRAY_NEW_MULTI() \
2359 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2360 int ndims = IMMEDIATE_u1; \
2361 expand_java_multianewarray( class, ndims ); \
2364 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2365 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2366 pop_value (OPERAND_TYPE##_type_node))));
2368 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2370 push_value (build1 (NOP_EXPR, int_type_node, \
2371 (convert (TO_TYPE##_type_node, \
2372 pop_value (FROM_TYPE##_type_node))))); \
2375 #define CONVERT(FROM_TYPE, TO_TYPE) \
2377 push_value (convert (TO_TYPE##_type_node, \
2378 pop_value (FROM_TYPE##_type_node))); \
2381 /* internal macro added for use by the WIDE case
2382 Added TREE_TYPE (decl) assignment, apbianco */
2383 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2386 int var = OPVALUE; \
2387 tree type = OPTYPE; \
2388 value = pop_value (type); \
2389 type = TREE_TYPE (value); \
2390 decl = find_local_variable (var, type, oldpc); \
2391 set_local_type (var, type ); \
2392 expand_assignment (decl, value, 0, 0); \
2395 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2397 /* have to do this since OPERAND_VALUE may have side-effects */ \
2398 int opvalue = OPERAND_VALUE; \
2399 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2402 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2403 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2405 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2406 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2408 #define MONITOR_OPERATION(call) \
2410 tree o = pop_value (ptr_type_node); \
2412 flush_quick_stack (); \
2413 c = build_java_monitor (call, o); \
2414 TREE_SIDE_EFFECTS (c) = 1; \
2415 expand_expr_stmt (c); \
2418 #define SPECIAL_IINC(IGNORED) \
2420 unsigned int local_var_index = IMMEDIATE_u1; \
2421 int ival = IMMEDIATE_s1; \
2422 expand_iinc(local_var_index, ival, oldpc); \
2425 #define SPECIAL_WIDE(IGNORED) \
2427 int modified_opcode = IMMEDIATE_u1; \
2428 unsigned int local_var_index = IMMEDIATE_u2; \
2429 switch (modified_opcode) \
2433 int ival = IMMEDIATE_s2; \
2434 expand_iinc (local_var_index, ival, oldpc); \
2437 case OPCODE_iload: \
2438 case OPCODE_lload: \
2439 case OPCODE_fload: \
2440 case OPCODE_dload: \
2441 case OPCODE_aload: \
2443 /* duplicate code from LOAD macro */ \
2444 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2447 case OPCODE_istore: \
2448 case OPCODE_lstore: \
2449 case OPCODE_fstore: \
2450 case OPCODE_dstore: \
2451 case OPCODE_astore: \
2453 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2457 error ("unrecogized wide sub-instruction"); \
2461 #define SPECIAL_THROW(IGNORED) \
2462 build_java_athrow (pop_value (throwable_type_node))
2464 #define SPECIAL_BREAK NOT_IMPL1
2465 #define IMPL NOT_IMPL
2467 #include "javaop.def"
2470 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2475 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2476 order, as specified by Java Language Specification.
2478 The problem is that while expand_expr will evaluate its sub-operands in
2479 left-to-right order, for variables it will just return an rtx (i.e.
2480 an lvalue) for the variable (rather than an rvalue). So it is possible
2481 that a later sub-operand will change the register, and when the
2482 actual operation is done, it will use the new value, when it should
2483 have used the original value.
2485 We fix this by using save_expr. This forces the sub-operand to be
2486 copied into a fresh virtual register,
2490 force_evaluation_order (node)
2493 if (flag_syntax_only)
2495 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2'
2496 && TREE_CODE (node) == ARRAY_REF)
2498 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2499 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2501 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2503 tree last_side_effecting_arg = NULL_TREE;
2504 tree arg = TREE_OPERAND (node, 1);
2505 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
2507 if (TREE_SIDE_EFFECTS (TREE_VALUE (arg)))
2508 last_side_effecting_arg = arg;
2510 arg = TREE_OPERAND (node, 1);
2511 for (; arg != NULL_TREE; arg = TREE_CHAIN (arg))
2513 if (arg == last_side_effecting_arg)
2515 TREE_VALUE (arg) = save_expr (TREE_VALUE (arg));