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. */
33 #include "java-tree.h"
35 #include "java-opcodes.h"
37 #include "java-except.h"
42 static tree operand_type[59];
43 extern struct obstack permanent_obstack;
46 init_expr_processing()
48 operand_type[21] = operand_type[54] = int_type_node;
49 operand_type[22] = operand_type[55] = long_type_node;
50 operand_type[23] = operand_type[56] = float_type_node;
51 operand_type[24] = operand_type[57] = double_type_node;
52 operand_type[25] = operand_type[58] = ptr_type_node;
55 /* We store the stack state in two places:
56 Within a basic block, we use the quick_stack, which is a
57 pushdown list (TREE_LISTs) of expression nodes.
58 This is the top part of the stack; below that we use find_stack_slot.
59 At the end of a basic block, the quick_stack must be flushed
60 to the stack slot array (as handled by find_stack_slot).
61 Using quick_stack generates better code (especially when
62 compiled without optimization), because we do not have to
63 explicitly store and load trees to temporary variables.
65 If a variable is on the quick stack, it means the value of variable
66 when the quick stack was last flushed. Conceptually, flush_quick_stack
67 saves all the the quick_stack elements in parellel. However, that is
68 complicated, so it actually saves them (i.e. copies each stack value
69 to is home virtual register) from low indexes. This allows a quick_stack
70 element at index i (counting from the bottom of stack the) to references
71 slot virtuals for register that are >= i, but not those that are deeper.
72 This convention makes most operations easier. For example iadd works
73 even when the stack contains (reg[0], reg[1]): It results in the
74 stack containing (reg[0]+reg[1]), which is OK. However, some stack
75 operations are more complicated. For example dup given a stack
76 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
77 the convention, since stack value 1 would refer to a register with
78 lower index (reg[0]), which flush_quick_stack does not safely handle.
79 So dup cannot just add an extra element to the quick_stack, but iadd can.
82 tree quick_stack = NULL_TREE;
84 /* A free-list of unused permamnet TREE_LIST nodes. */
85 tree tree_list_free_list = NULL_TREE;
87 /* The stack pointer of the Java virtual machine.
88 This does include the size of the quick_stack. */
92 unsigned char *linenumber_table;
96 truthvalue_conversion (expr)
99 /* It is simpler and generates better code to have only TRUTH_*_EXPR
100 or comparison expressions as truth values at this level.
102 This function should normally be identity for Java. */
104 switch (TREE_CODE (expr))
107 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
108 case TRUTH_ANDIF_EXPR:
109 case TRUTH_ORIF_EXPR:
116 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
119 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
121 /* are these legal? XXX JH */
126 /* These don't change whether an object is non-zero or zero. */
127 return truthvalue_conversion (TREE_OPERAND (expr, 0));
130 /* Distribute the conversion into the arms of a COND_EXPR. */
131 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
132 truthvalue_conversion (TREE_OPERAND (expr, 1)),
133 truthvalue_conversion (TREE_OPERAND (expr, 2))));
136 /* If this is widening the argument, we can ignore it. */
137 if (TYPE_PRECISION (TREE_TYPE (expr))
138 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
139 return truthvalue_conversion (TREE_OPERAND (expr, 0));
140 /* fall through to default */
143 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
147 #ifdef JAVA_USE_HANDLES
148 /* Given a pointer to a handle, get a pointer to an object. */
154 tree field, handle_type;
155 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
156 handle_type = TREE_TYPE (expr);
157 field = TYPE_FIELDS (handle_type);
158 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
163 /* Save any stack slots that happen to be in the quick_stack into their
164 home virtual register slots.
166 The copy order is from low stack index to high, to support the invariant
167 that the expression for a slot may contain decls for stack slots with
168 higher (or the same) index, but not lower. */
173 int stack_index = stack_pointer;
174 register tree prev, cur, next;
176 /* First reverse the quick_stack, and count the number of slots it has. */
177 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
179 next = TREE_CHAIN (cur);
180 TREE_CHAIN (cur) = prev;
182 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
186 while (quick_stack != NULL_TREE)
189 tree node = quick_stack, type;
190 quick_stack = TREE_CHAIN (node);
191 TREE_CHAIN (node) = tree_list_free_list;
192 tree_list_free_list = node;
193 node = TREE_VALUE (node);
194 type = TREE_TYPE (node);
196 decl = find_stack_slot (stack_index, type);
198 expand_assignment (decl, node, 0, 0);
199 stack_index += 1 + TYPE_IS_WIDE (type);
208 type = promote_type (type);
209 n_words = 1 + TYPE_IS_WIDE (type);
210 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
211 fatal ("stack overflow");
212 stack_type_map[stack_pointer++] = type;
214 while (--n_words >= 0)
215 stack_type_map[stack_pointer++] = TYPE_SECOND;
222 tree type = TREE_TYPE (value);
223 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
225 type = promote_type (type);
226 value = convert (type, value);
229 if (tree_list_free_list == NULL_TREE)
230 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
233 tree node = tree_list_free_list;
234 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
235 TREE_VALUE (node) = value;
236 TREE_CHAIN (node) = quick_stack;
247 if (TREE_CODE (type) == RECORD_TYPE)
248 type = promote_type (type);
249 n_words = 1 + TYPE_IS_WIDE (type);
250 if (stack_pointer < n_words)
251 fatal ("stack underflow");
252 while (--n_words > 0)
254 if (stack_type_map[--stack_pointer] != void_type_node)
255 fatal ("Invalid multi-word value on type stack");
257 t = stack_type_map[--stack_pointer];
258 if (type == NULL_TREE || t == type)
260 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
261 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
263 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
265 if (type == ptr_type_node || type == object_ptr_type_node)
267 else if (t == ptr_type_node) /* Special case for null reference. */
269 else if (can_widen_reference_to (t, type))
271 /* This is a kludge, but matches what Sun's verifier does.
272 It can be tricked, but is safe as long as type errors
273 (i.e. interface method calls) are caught at run-time. */
274 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
275 && t == object_ptr_type_node)
278 error ("unexpected type on stack");
282 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
283 Handles array types and interfaces. */
286 can_widen_reference_to (source_type, target_type)
287 tree source_type, target_type;
289 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
292 /* Get rid of pointers */
293 if (TREE_CODE (source_type) == POINTER_TYPE)
294 source_type = TREE_TYPE (source_type);
295 if (TREE_CODE (target_type) == POINTER_TYPE)
296 target_type = TREE_TYPE (target_type);
298 if (source_type == target_type)
302 source_type = HANDLE_TO_CLASS_TYPE (source_type);
303 target_type = HANDLE_TO_CLASS_TYPE (target_type);
304 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
306 HOST_WIDE_INT source_length, target_length;
307 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
309 target_length = java_array_type_length (target_type);
310 if (target_length >= 0)
312 source_length = java_array_type_length (source_type);
313 if (source_length != target_length)
316 source_type = TYPE_ARRAY_ELEMENT (source_type);
317 target_type = TYPE_ARRAY_ELEMENT (target_type);
318 if (source_type == target_type)
320 if (TREE_CODE (source_type) != POINTER_TYPE
321 || TREE_CODE (target_type) != POINTER_TYPE)
323 return can_widen_reference_to (source_type, target_type);
327 int source_depth = class_depth (source_type);
328 int target_depth = class_depth (target_type);
330 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
332 /* target_type is OK if source_type or source_type ancestors
333 implement target_type. We handle multiple sub-interfaces */
335 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
336 int n = TREE_VEC_LENGTH (basetype_vec), i;
337 for (i=0 ; i < n; i++)
338 if (can_widen_reference_to
339 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
346 for ( ; source_depth > target_depth; source_depth--)
348 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
350 return source_type == target_type;
359 type = pop_type (type);
362 tree node = quick_stack;
363 quick_stack = TREE_CHAIN (quick_stack);
364 TREE_CHAIN (node) = tree_list_free_list;
365 tree_list_free_list = node;
366 node = TREE_VALUE (node);
370 return find_stack_slot (stack_pointer, promote_type (type));
374 /* Pop and discrad the top COUNT stack slots. */
377 java_stack_pop (count)
383 if (stack_pointer == 0)
384 fatal ("stack underflow");
385 type = stack_type_map[stack_pointer - 1];
386 if (type == TYPE_SECOND)
389 if (stack_pointer == 1 || count <= 0)
390 fatal ("stack underflow");
391 type = stack_type_map[stack_pointer - 2];
393 val = pop_value (type);
398 /* Implement the 'swap' operator (to swap two top stack slots). */
407 if (stack_pointer < 2
408 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
409 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
410 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
411 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
412 fatal ("bad stack swap");
414 flush_quick_stack ();
415 decl1 = find_stack_slot (stack_pointer - 1, type1);
416 decl2 = find_stack_slot (stack_pointer - 2, type2);
417 temp = copy_to_reg (DECL_RTL (decl1));
418 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
419 emit_move_insn (DECL_RTL (decl2), temp);
420 stack_type_map[stack_pointer - 1] = type2;
421 stack_type_map[stack_pointer - 2] = type1;
425 java_stack_dup (size, offset)
428 int low_index = stack_pointer - size - offset;
431 error ("stack underflow - dup* operation");
433 flush_quick_stack ();
435 stack_pointer += size;
436 dst_index = stack_pointer;
438 for (dst_index = stack_pointer; --dst_index >= low_index; )
441 int src_index = dst_index - size;
442 if (src_index < low_index)
443 src_index = dst_index + size + offset;
444 type = stack_type_map [src_index];
445 if (type == TYPE_SECOND)
447 if (src_index <= low_index)
448 fatal ("dup operation splits 64-bit number");
449 stack_type_map[dst_index] = type;
450 src_index--; dst_index--;
451 type = stack_type_map[src_index];
452 if (! TYPE_IS_WIDE (type))
453 fatal ("internal error - dup operation");
455 else if (TYPE_IS_WIDE (type))
456 fatal ("internal error - dup operation");
457 if (src_index != dst_index)
459 tree src_decl = find_stack_slot (src_index, type);
460 tree dst_decl = find_stack_slot (dst_index, type);
461 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
462 stack_type_map[dst_index] = type;
467 /* Calls _Jv_Throw. Discard the contents of the value stack. */
470 build_java_athrow (node)
475 call = build (CALL_EXPR,
477 build_address_of (throw_node),
478 build_tree_list (NULL_TREE, node),
480 TREE_SIDE_EFFECTS (call) = 1;
481 expand_expr_stmt (call);
482 java_stack_pop (stack_pointer);
485 /* Implementation for jsr/ret */
488 build_java_jsr (where, ret)
492 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
493 push_value (ret_label);
494 flush_quick_stack ();
500 build_java_ret (location)
503 expand_computed_goto (location);
506 /* Implementation of operations on array: new, load, store, length */
508 /* Array core info access macros */
510 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
511 size_binop (CEIL_DIV_EXPR, \
513 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
514 size_int (BITS_PER_UNIT))
517 decode_newarray_type (int atype)
521 case 4: return boolean_type_node;
522 case 5: return char_type_node;
523 case 6: return float_type_node;
524 case 7: return double_type_node;
525 case 8: return byte_type_node;
526 case 9: return short_type_node;
527 case 10: return int_type_node;
528 case 11: return long_type_node;
529 default: return NULL_TREE;
533 /* Map primitive type to the code used by OPCODE_newarray. */
536 encode_newarray_type (type)
539 if (type == boolean_type_node)
541 else if (type == char_type_node)
543 else if (type == float_type_node)
545 else if (type == double_type_node)
547 else if (type == byte_type_node)
549 else if (type == short_type_node)
551 else if (type == int_type_node)
553 else if (type == long_type_node)
556 fatal ("Can't compute type code - patch_newarray");
559 /* Build a call to _Jv_ThrowBadArrayIndex(), the
560 ArrayIndexOfBoundsException exception handler. */
563 build_java_throw_out_of_bounds_exception (index)
566 tree node = build (CALL_EXPR, int_type_node,
567 build_address_of (soft_badarrayindex_node),
568 build_tree_list (NULL_TREE, index), NULL_TREE);
569 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
573 /* Return the length of an array. Doesn't perform any checking on the nature
574 or value of the array NODE. May be used to implement some bytecodes. */
577 build_java_array_length_access (node)
580 tree type = TREE_TYPE (node);
581 HOST_WIDE_INT length;
582 if (!is_array_type_p (type))
583 fatal ("array length on a non-array reference");
584 length = java_array_type_length (type);
586 return build_int_2 (length, 0);
587 return fold (build1 (INDIRECT_REF,
589 fold (build (PLUS_EXPR, ptr_type_node,
591 JAVA_ARRAY_LENGTH_OFFSET(node)))));
594 /* Optionally checks an array against the NULL pointer, eventually throwing a
595 NullPointerException. It could replace signal handling, but tied to NULL.
596 ARG1: the pointer to check, ARG2: the expression to use if
597 the pointer is non-null and ARG3 the type that should be returned. */
600 build_java_arraynull_check (node, expr, type)
606 static int java_array_access_throws_null_exception = 0;
608 if (java_array_access_throws_null_exception)
609 return (build (COND_EXPR,
611 build (EQ_EXPR, int_type_node, node, null_pointer_node),
612 build_java_athrow (node), expr ));
619 java_array_data_offset (array)
622 tree array_type = TREE_TYPE (TREE_TYPE (array));
623 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
624 if (data_fld == NULL_TREE)
625 return size_in_bytes (array_type);
627 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
631 /* Implement array indexing (either as l-value or r-value).
632 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
633 Optionally performs bounds checking and/or test to NULL.
634 At this point, ARRAY should have been verified as an array. */
637 build_java_arrayaccess (array, type, index)
638 tree array, type, index;
640 tree arith, node, throw = NULL_TREE;
642 arith = fold (build (PLUS_EXPR, int_type_node,
643 java_array_data_offset (array),
644 fold (build (MULT_EXPR, int_type_node,
645 index, size_in_bytes(type)))));
647 if (flag_bounds_check)
650 * (unsigned jint) INDEX >= (unsigned jint) LEN
651 * && throw ArrayIndexOutOfBoundsException.
652 * Note this is equivalent to and more efficient than:
653 * INDEX < 0 || INDEX >= LEN && throw ... */
655 tree len = build_java_array_length_access (array);
656 TREE_TYPE (len) = unsigned_int_type_node;
657 test = fold (build (GE_EXPR, boolean_type_node,
658 convert (unsigned_int_type_node, index),
660 if (! integer_zerop (test))
662 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
663 build_java_throw_out_of_bounds_exception (index));
664 /* allows expansion within COMPOUND */
665 TREE_SIDE_EFFECTS( throw ) = 1;
669 node = build1 (INDIRECT_REF, type,
670 fold (build (PLUS_EXPR, ptr_type_node,
672 (throw ? build (COMPOUND_EXPR, int_type_node,
676 return (fold (build_java_arraynull_check (array, node, type)));
679 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
680 ARRAY_NODE. This function is used to retrieve something less vague than
681 a pointer type when indexing the first dimension of something like [[<t>.
682 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
684 As a side effect, it also makes sure that ARRAY_NODE is an array. */
687 build_java_check_indexed_type (array_node, indexed_type)
693 if (!is_array_type_p (TREE_TYPE (array_node)))
694 fatal ("array indexing on a non-array reference");
696 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
698 if (indexed_type == ptr_type_node )
699 return promote_type (elt_type);
701 /* BYTE/BOOLEAN store and load are used for both type */
702 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
703 return boolean_type_node;
705 if (indexed_type != elt_type )
706 fatal ("type array element mismatch");
711 /* newarray triggers a call to _Jv_NewArray. This function should be called
712 with an integer code (the type of array to create) and get from the stack
713 the size of the dimmension. */
716 build_newarray (atype_value, length)
720 tree type = build_java_array_type (decode_newarray_type (atype_value),
721 TREE_CODE (length) == INTEGER_CST
722 ? TREE_INT_CST_LOW (length)
724 return build (CALL_EXPR, promote_type (type),
725 build_address_of (soft_newarray_node),
726 tree_cons (NULL_TREE,
727 build_int_2 (atype_value, 0),
728 build_tree_list (NULL_TREE, length)),
732 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
736 build_anewarray (class_type, length)
740 tree type = build_java_array_type (class_type,
741 TREE_CODE (length) == INTEGER_CST
742 ? TREE_INT_CST_LOW (length)
744 return build (CALL_EXPR, promote_type (type),
745 build_address_of (soft_anewarray_node),
746 tree_cons (NULL_TREE, length,
747 tree_cons (NULL_TREE, build_class_ref (class_type),
748 build_tree_list (NULL_TREE,
749 null_pointer_node))),
753 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
756 build_new_array (type, length)
760 if (JPRIMITIVE_TYPE_P (type))
761 return build_newarray (encode_newarray_type (type), length);
763 return build_anewarray (TREE_TYPE (type), length);
766 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
767 class pointer, a number of dimensions and the matching number of
768 dimensions. The argument list is NULL terminated. */
771 expand_java_multianewarray (class_type, ndim)
776 tree args = build_tree_list( NULL_TREE, null_pointer_node );
778 for( i = 0; i < ndim; i++ )
779 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
781 push_value (build (CALL_EXPR,
782 promote_type (class_type),
783 build_address_of (soft_multianewarray_node),
784 tree_cons (NULL_TREE, build_class_ref (class_type),
785 tree_cons (NULL_TREE,
786 build_int_2 (ndim, 0), args )),
790 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
791 ARRAY is an array type. May expand some bound checking and NULL
792 pointer checking. RHS_TYPE_NODE we are going to store. In the case
793 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
794 INT. In those cases, we make the convertion.
796 if ARRAy is a reference type, the assignment is checked at run-time
797 to make sure that the RHS can be assigned to the array element
798 type. It is not necessary to generate this code if ARRAY is final. */
801 expand_java_arraystore (rhs_type_node)
804 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
805 && TYPE_PRECISION (rhs_type_node) <= 32) ?
806 int_type_node : rhs_type_node);
807 tree index = pop_value (int_type_node);
808 tree array = pop_value (ptr_type_node);
810 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
812 flush_quick_stack ();
814 index = save_expr (index);
815 array = save_expr (array);
817 if (TREE_CODE (rhs_type_node) == POINTER_TYPE
818 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
820 tree check = build (CALL_EXPR, void_type_node,
821 build_address_of (soft_checkarraystore_node),
822 tree_cons (NULL_TREE, array,
823 build_tree_list (NULL_TREE, rhs_node)),
825 TREE_SIDE_EFFECTS (check) = 1;
826 expand_expr_stmt (check);
829 expand_assignment (build_java_arrayaccess (array,
835 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
836 sure that LHS is an array type. May expand some bound checking and NULL
838 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
839 BOOLEAN/SHORT, we push a promoted type back to the stack.
843 expand_java_arrayload (lhs_type_node )
847 tree index_node = pop_value (int_type_node);
848 tree array_node = pop_value (ptr_type_node);
850 index_node = save_expr (index_node);
851 array_node = save_expr (array_node);
852 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
854 load_node = build_java_arrayaccess (array_node,
858 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
859 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
860 push_value (load_node);
863 /* Expands .length. Makes sure that we deal with and array and may expand
864 a NULL check on the array object. */
867 expand_java_array_length ()
869 tree array = pop_value (ptr_type_node);
870 tree length = build_java_array_length_access (array);
872 push_value (build_java_arraynull_check (array, length, int_type_node));
875 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
876 either soft_monitorenter_node or soft_monitorexit_node. */
879 build_java_monitor (call, object)
883 return (build (CALL_EXPR,
885 build_address_of (call),
886 build_tree_list (NULL_TREE, object),
890 /* Emit code for one of the PUSHC instructions. */
893 expand_java_pushc (ival, type)
898 if (type == ptr_type_node && ival == 0)
899 value = null_pointer_node;
900 else if (type == int_type_node || type == long_type_node)
902 value = build_int_2 (ival, ival < 0 ? -1 : 0);
903 TREE_TYPE (value) = type;
905 else if (type == float_type_node || type == double_type_node)
908 #ifdef REAL_ARITHMETIC
909 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
913 value = build_real (type, x);
916 fatal ("internal error in expand_java_pushc");
921 expand_java_return (type)
924 if (type == void_type_node)
925 expand_null_return ();
928 tree retval = pop_value (type);
929 tree res = DECL_RESULT (current_function_decl);
930 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
931 TREE_SIDE_EFFECTS (retval) = 1;
932 expand_return (retval);
937 build_address_of (value)
940 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
944 expand_java_NEW (type)
947 if (! CLASS_LOADED_P (type))
948 load_class (type, 1);
949 layout_class_methods (type);
950 push_value (build (CALL_EXPR, promote_type (type),
951 build_address_of (alloc_object_node),
952 tree_cons (NULL_TREE, build_class_ref (type),
953 build_tree_list (NULL_TREE,
954 size_in_bytes (type))),
959 expand_java_INSTANCEOF (type)
962 tree value = pop_value (object_ptr_type_node);
963 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
964 build_address_of (soft_instanceof_node),
965 tree_cons (NULL_TREE, value,
966 build_tree_list (NULL_TREE,
967 build_class_ref (type))),
973 expand_java_CHECKCAST (type)
976 tree value = pop_value (ptr_type_node);
977 value = build (CALL_EXPR, promote_type (type),
978 build_address_of (soft_checkcast_node),
979 tree_cons (NULL_TREE, build_class_ref (type),
980 build_tree_list (NULL_TREE, value)),
986 expand_iinc (unsigned int local_var_index, int ival, int pc)
991 flush_quick_stack ();
992 local_var = find_local_variable (local_var_index, int_type_node, pc);
993 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
994 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
995 expand_assignment (local_var, res, 0, 0);
999 build_java_binop (op, type, arg1, arg2)
1001 tree type, arg1, arg2;
1008 tree u_type = unsigned_type (type);
1009 arg1 = convert (u_type, arg1);
1010 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1011 return convert (type, arg1);
1015 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1016 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1019 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1020 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1021 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1023 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1024 boolean_type_node, arg1, arg2));
1025 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1026 tree second_compare = fold (build (COND_EXPR, int_type_node,
1027 ifexp2, integer_zero_node,
1028 op == COMPARE_L_EXPR
1029 ? integer_negative_one_node
1030 : integer_one_node));
1031 return fold (build (COND_EXPR, int_type_node, ifexp1,
1032 op == COMPARE_L_EXPR ? integer_one_node
1033 : integer_negative_one_node,
1037 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1039 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1040 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1041 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1042 ifexp2, integer_one_node,
1043 integer_zero_node));
1044 return fold (build (COND_EXPR, int_type_node,
1045 ifexp1, integer_negative_one_node, second_compare));
1048 case TRUNC_MOD_EXPR:
1049 if (TREE_CODE (type) == REAL_TYPE)
1052 if (type != double_type_node)
1054 arg1 = convert (double_type_node, arg1);
1055 arg2 = convert (double_type_node, arg2);
1057 call = build (CALL_EXPR, double_type_node,
1058 build_address_of (soft_fmod_node),
1059 tree_cons (NULL_TREE, arg1,
1060 build_tree_list (NULL_TREE, arg2)),
1062 if (type != double_type_node)
1063 call = convert (type, call);
1069 return fold (build (op, type, arg1, arg2));
1073 expand_java_binop (type, op)
1074 tree type; enum tree_code op;
1084 rtype = int_type_node;
1085 rarg = pop_value (rtype);
1088 rarg = pop_value (rtype);
1090 larg = pop_value (ltype);
1091 push_value (build_java_binop (op, type, larg, rarg));
1094 /* Lookup the field named NAME in *TYPEP or its super classes.
1095 If not found, return NULL_TREE.
1096 (If the *TYPEP is not found, return error_mark_node.)
1097 If found, return the FIELD_DECL, and set *TYPEP to the
1098 class containing the field. */
1101 lookup_field (typep, name)
1105 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1107 load_class (*typep, 1);
1108 if (TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1109 return error_mark_node;
1114 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1116 if (DECL_NAME (field) == name)
1119 *typep = CLASSTYPE_SUPER (*typep);
1124 /* Look up the field named NAME in object SELF_VALUE,
1125 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1126 SELF_VALUE is NULL_TREE if looking for a static field. */
1129 build_field_ref (self_value, self_class, name)
1130 tree self_value, self_class, name;
1132 tree base_class = self_class;
1133 tree field_decl = lookup_field (&base_class, name);
1134 if (field_decl == NULL_TREE)
1136 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1137 return error_mark_node;
1139 if (self_value == NULL_TREE)
1141 return build_static_field_ref (field_decl);
1145 tree base_handle_type = promote_type (base_class);
1146 if (base_handle_type != TREE_TYPE (self_value))
1147 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1148 #ifdef JAVA_USE_HANDLES
1149 self_value = unhand_expr (self_value);
1151 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1153 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1154 self_value, field_decl));
1164 sprintf (buf, "LJpc=%d", pc);
1165 name = get_identifier (buf);
1166 if (IDENTIFIER_LOCAL_VALUE (name))
1167 return IDENTIFIER_LOCAL_VALUE (name);
1170 /* The type of the address of a label is return_address_type_node. */
1171 tree decl = create_label_decl (name);
1172 LABEL_PC (decl) = pc;
1174 return pushdecl (decl);
1178 /* Generate a unique name for the purpose of loops and switches
1179 labels, and try-catch-finally blocks label or temporary variables. */
1184 static int l_number = 0;
1186 sprintf (buff, "$LJv%d", l_number++);
1187 return get_identifier (buff);
1191 create_label_decl (name)
1195 push_obstacks (&permanent_obstack, &permanent_obstack);
1196 decl = build_decl (LABEL_DECL, name,
1197 TREE_TYPE (return_address_type_node));
1199 DECL_CONTEXT (decl) = current_function_decl;
1200 DECL_IGNORED_P (decl) = 1;
1204 /* This maps a bytecode offset (PC) to various flags. */
1205 char *instruction_bits;
1208 note_label (current_pc, target_pc)
1209 int current_pc, target_pc;
1211 lookup_label (target_pc);
1212 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1215 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1216 where CONDITION is one of one the compare operators. */
1219 expand_compare (condition, value1, value2, target_pc)
1220 enum tree_code condition;
1221 tree value1, value2;
1224 tree target = lookup_label (target_pc);
1225 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1226 expand_start_cond (truthvalue_conversion (cond), 0);
1227 expand_goto (target);
1231 /* Emit code for a TEST-type opcode. */
1234 expand_test (condition, type, target_pc)
1235 enum tree_code condition;
1239 tree value1, value2;
1240 flush_quick_stack ();
1241 value1 = pop_value (type);
1242 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1243 expand_compare (condition, value1, value2, target_pc);
1246 /* Emit code for a COND-type opcode. */
1249 expand_cond (condition, type, target_pc)
1250 enum tree_code condition;
1254 tree value1, value2;
1255 flush_quick_stack ();
1256 /* note: pop values in opposite order */
1257 value2 = pop_value (type);
1258 value1 = pop_value (type);
1259 /* Maybe should check value1 and value2 for type compatibility ??? */
1260 expand_compare (condition, value1, value2, target_pc);
1264 expand_java_goto (target_pc)
1267 tree target_label = lookup_label (target_pc);
1268 flush_quick_stack ();
1269 expand_goto (target_label);
1273 expand_java_call (target_pc, return_address)
1274 int target_pc, return_address;
1276 tree target_label = lookup_label (target_pc);
1277 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1279 flush_quick_stack ();
1280 expand_goto (target_label);
1284 expand_java_ret (return_address)
1285 tree return_address;
1287 warning ("ret instruction not implemented");
1289 tree target_label = lookup_label (target_pc);
1290 flush_quick_stack ();
1291 expand_goto (target_label);
1295 /* Recursive helper function to pop argument types during verifiation. */
1298 pop_argument_types (arg_types)
1301 if (arg_types == end_params_node)
1303 if (TREE_CODE (arg_types) == TREE_LIST)
1305 pop_argument_types (TREE_CHAIN (arg_types));
1306 pop_type (TREE_VALUE (arg_types));
1313 pop_arguments (arg_types)
1316 if (arg_types == end_params_node)
1318 if (TREE_CODE (arg_types) == TREE_LIST)
1320 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1321 tree type = TREE_VALUE (arg_types);
1322 tree arg = pop_value (type);
1323 #ifdef PROMOTE_PROTOTYPES
1324 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1325 && INTEGRAL_TYPE_P (type))
1326 arg = convert (integer_type_node, arg);
1328 return tree_cons (NULL_TREE, arg, tail);
1333 /* Build an expression to initialize the class CLAS.
1334 if EXPR is non-NULL, returns an expression to first call the initializer
1335 (if it is needed) and then calls EXPR. */
1338 build_class_init (clas, expr)
1342 if (inherits_from_p (current_class, clas))
1344 init = build (CALL_EXPR, void_type_node,
1345 build_address_of (soft_initclass_node),
1346 build_tree_list (NULL_TREE, build_class_ref (clas)),
1348 TREE_SIDE_EFFECTS (init) = 1;
1349 if (expr != NULL_TREE)
1351 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1352 TREE_SIDE_EFFECTS (expr) = 1;
1358 static tree methods_ident = NULL_TREE;
1359 static tree ncode_ident = NULL_TREE;
1360 tree dtable_ident = NULL_TREE;
1363 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1364 tree method, method_type, self_type, method_signature, arg_list;
1367 if (is_compiled_class (self_type))
1369 make_decl_rtl (method, NULL, 1);
1370 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1374 /* We don't know whether the method has been (statically) compiled.
1375 Compile this code to get a reference to the method's code:
1377 SELF_TYPE->methods[METHOD_INDEX].ncode
1379 This is guaranteed to work (assuming SELF_TYPE has
1380 been initialized), since if the method is not compiled yet,
1381 its ncode points to a trampoline that forces compilation. */
1383 int method_index = 0;
1385 tree ref = build_class_ref (self_type);
1386 ref = build1 (INDIRECT_REF, class_type_node, ref);
1387 if (ncode_ident == NULL_TREE)
1388 ncode_ident = get_identifier ("ncode");
1389 if (methods_ident == NULL_TREE)
1390 methods_ident = get_identifier ("methods");
1391 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1392 lookup_field (&class_type_node, methods_ident));
1393 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1394 ; meth = TREE_CHAIN (meth))
1398 if (meth == NULL_TREE)
1399 fatal ("method '%s' not found in class",
1400 IDENTIFIER_POINTER (DECL_NAME (method)));
1403 method_index *= int_size_in_bytes (method_type_node);
1404 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1405 ref, build_int_2 (method_index, 0)));
1406 ref = build1 (INDIRECT_REF, method_type_node, ref);
1407 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1409 lookup_field (&method_type_node, ncode_ident));
1415 invoke_build_dtable (is_invoke_interface, arg_list)
1416 int is_invoke_interface;
1419 tree dtable, objectref;
1421 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1423 /* If we're dealing with interfaces and if the objectref
1424 argument is an array then get the dispatch table of the class
1425 Object rather than the one from the objectref. */
1426 objectref = (is_invoke_interface
1427 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1428 object_type_node : TREE_VALUE (arg_list));
1430 if (dtable_ident == NULL_TREE)
1431 dtable_ident = get_identifier ("vtable");
1432 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1433 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1434 lookup_field (&object_type_node, dtable_ident));
1440 build_invokevirtual (dtable, method)
1441 tree dtable, method;
1444 tree nativecode_ptr_ptr_type_node
1445 = build_pointer_type (nativecode_ptr_type_node);
1446 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1447 /* Add one to skip "class" field of dtable, and one to skip unused
1448 vtable entry (for C++ compatibility). */
1451 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1452 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1453 dtable, build_int_2 (method_index, 0)));
1454 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1460 build_invokeinterface (dtable, method_name, method_signature)
1461 tree dtable, method_name, method_signature;
1463 static tree class_ident = NULL_TREE;
1466 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1467 ensure that the selected method exists, is public and not
1468 abstract nor static. */
1470 if (class_ident == NULL_TREE)
1471 class_ident = get_identifier ("class");
1473 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1474 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1475 lookup_field (&dtable_type, class_ident));
1476 lookup_arg = build_tree_list (NULL_TREE,
1479 (IDENTIFIER_POINTER(method_signature),
1480 IDENTIFIER_LENGTH(method_signature)))));
1481 lookup_arg = tree_cons (NULL_TREE, dtable,
1482 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1484 return build (CALL_EXPR, ptr_type_node,
1485 build_address_of (soft_lookupinterfacemethod_node),
1486 lookup_arg, NULL_TREE);
1489 /* Expand one of the invoke_* opcodes.
1490 OCPODE is the specific opcode.
1491 METHOD_REF_INDEX is an index into the constant pool.
1492 NARGS is the number of arguments, or -1 if not specified. */
1495 expand_invoke (opcode, method_ref_index, nargs)
1497 int method_ref_index;
1500 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1501 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1502 tree self_type = get_class_constant
1503 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1504 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1505 tree call, func, method, arg_list, method_type;
1507 if (! CLASS_LOADED_P (self_type))
1509 load_class (self_type, 1);
1510 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1511 fatal ("failed to find class '%s'", self_name);
1513 layout_class_methods (self_type);
1515 if (method_name == init_identifier_node)
1516 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1519 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1520 method_name, method_signature);
1521 if (method == NULL_TREE)
1523 error ("Class '%s' has no method named '%s' matching signature '%s'",
1525 IDENTIFIER_POINTER (method_name),
1526 IDENTIFIER_POINTER (method_signature));
1528 /* Invoke static can't invoke static/abstract method */
1529 else if (opcode == OPCODE_invokestatic)
1531 if (!METHOD_STATIC (method))
1533 error ("invokestatic on non static method");
1536 else if (METHOD_ABSTRACT (method))
1538 error ("invokestatic on abstract method");
1544 if (METHOD_STATIC (method))
1546 error ("invoke[non-static] on static method");
1551 if (method == NULL_TREE)
1553 method_type = get_type_from_signature (method_signature);
1554 pop_arguments (TYPE_ARG_TYPES (method_type));
1555 if (opcode != OPCODE_invokestatic)
1556 pop_type (self_type);
1557 method_type = promote_type (TREE_TYPE (method_type));
1558 push_value (convert (method_type, integer_zero_node));
1562 method_type = TREE_TYPE (method);
1563 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1564 flush_quick_stack ();
1567 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1568 || (opcode == OPCODE_invokevirtual
1569 && (METHOD_PRIVATE (method)
1570 || METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
1571 func = build_known_method_ref (method, method_type, self_type,
1572 method_signature, arg_list);
1575 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1577 if (opcode == OPCODE_invokevirtual)
1578 func = build_invokevirtual (dtable, method);
1580 func = build_invokeinterface (dtable, method_name, method_signature);
1582 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1583 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1584 TREE_SIDE_EFFECTS (call) = 1;
1586 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1587 expand_expr_stmt (call);
1591 flush_quick_stack ();
1596 /* Expand an operation to extract from or store into a field.
1597 IS_STATIC is 1 iff the field is static.
1598 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1599 FIELD_REF_INDEX is an index into the constant pool. */
1602 expand_java_field_op (is_static, is_putting, field_ref_index)
1605 int field_ref_index;
1607 tree self_type = get_class_constant
1608 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, field_ref_index));
1609 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1610 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
1611 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, field_ref_index);
1612 tree field_type = get_type_from_signature (field_signature);
1613 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1616 tree field_decl = lookup_field (&self_type, field_name);
1617 if (field_decl == error_mark_node)
1621 else if (field_decl == NULL_TREE)
1623 error ("Missing field '%s' in '%s'",
1624 IDENTIFIER_POINTER (field_name), self_name);
1627 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1629 error ("Mismatching signature for field '%s' in '%s'",
1630 IDENTIFIER_POINTER (field_name), self_name);
1633 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1637 push_value (convert (field_type, integer_zero_node));
1638 flush_quick_stack ();
1642 /* Inline references to java.lang.PRIMTYPE.TYPE.
1643 In addition to being a useful (minor) optimization,
1644 this is also needed to avoid circularities in the implementation
1645 of these fields in libjava. */
1646 if (field_name == TYPE_identifier_node && ! is_putting
1647 && ! flag_emit_class_files && field_type == class_ptr_type
1648 && strncmp (self_name, "java.lang.", 10) == 0)
1650 tree typ = build_primtype_type_ref (self_name);
1658 field_ref = build_field_ref (field_ref, self_type, field_name);
1660 field_ref = build_class_init (self_type, field_ref);
1663 flush_quick_stack ();
1664 if (FIELD_FINAL (field_decl))
1666 if (DECL_CONTEXT (field_decl) != current_class)
1667 error_with_decl (field_decl,
1668 "assignment to final field `%s' not in field's class");
1669 else if (FIELD_STATIC (field_decl))
1671 if (DECL_NAME (current_function_decl) != clinit_identifier_node)
1672 error_with_decl (field_decl,
1673 "assignment to final static field `%s' not in class initializer");
1677 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1678 error_with_decl (field_decl,
1679 "assignment to final field `%s' not in constructor");
1682 expand_assignment (field_ref, new_value, 0, 0);
1685 push_value (field_ref);
1689 build_primtype_type_ref (self_name)
1692 char *class_name = self_name+10;
1694 if (strncmp(class_name, "Byte", 4) == 0)
1695 typ = byte_type_node;
1696 else if (strncmp(class_name, "Short", 5) == 0)
1697 typ = short_type_node;
1698 else if (strncmp(class_name, "Integer", 7) == 0)
1699 typ = int_type_node;
1700 else if (strncmp(class_name, "Long", 4) == 0)
1701 typ = long_type_node;
1702 else if (strncmp(class_name, "Float", 5) == 0)
1703 typ = float_type_node;
1704 else if (strncmp(class_name, "Double", 6) == 0)
1705 typ = double_type_node;
1706 else if (strncmp(class_name, "Boolean", 7) == 0)
1707 typ = boolean_type_node;
1708 else if (strncmp(class_name, "Char", 4) == 0)
1709 typ = char_type_node;
1710 else if (strncmp(class_name, "Void", 4) == 0)
1711 typ = void_type_node;
1714 if (typ != NULL_TREE)
1715 return build_class_ref (typ);
1721 load_type_state (label)
1725 tree vec = LABEL_TYPE_STATE (label);
1726 int cur_length = TREE_VEC_LENGTH (vec);
1727 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1728 for (i = 0; i < cur_length; i++)
1729 type_map [i] = TREE_VEC_ELT (vec, i);
1732 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1733 dependant things, but they rely on gcc routines. This function is
1734 placed here because it uses things defined locally in parse.y. */
1737 case_identity (t, v)
1738 tree t __attribute__ ((__unused__));
1745 java_lang_expand_expr (exp, target, tmode, modifier)
1748 enum machine_mode tmode;
1749 enum expand_modifier modifier;
1755 switch (TREE_CODE (exp))
1757 case NEW_ARRAY_INIT:
1760 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1761 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1762 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1763 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1764 tree length = build_int_2 (ilength, 0);
1765 tree init = TREE_OPERAND (exp, 0);
1768 /* Enable this once we can set the vtable field statically. FIXME */
1769 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1770 && JPRIMITIVE_TYPE_P (element_type))
1772 tree temp, value, init_decl;
1773 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1774 PUSH_FIELD_VALUE (temp, "vtable",
1775 null_pointer_node /* FIXME */
1777 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1778 FINISH_RECORD_CONSTRUCTOR (temp);
1779 START_RECORD_CONSTRUCTOR (value, array_type);
1780 PUSH_SUPER_VALUE (value, temp);
1781 PUSH_FIELD_VALUE (value, "length", length);
1782 PUSH_FIELD_VALUE (value, "data", init);
1783 FINISH_RECORD_CONSTRUCTOR (value);
1785 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1786 pushdecl_top_level (init_decl);
1787 TREE_STATIC (init_decl) = 1;
1788 DECL_INITIAL (init_decl) = value;
1789 DECL_IGNORED_P (init_decl) = 1;
1790 TREE_READONLY (init_decl) = 1;
1791 make_decl_rtl (init_decl, NULL, 1);
1792 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1793 return expand_expr (init, target, tmode, modifier);
1796 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1797 expand_decl (array_decl);
1798 tmp = expand_assignment (array_decl,
1799 build_new_array (element_type, length),
1801 if (TREE_CONSTANT (init)
1802 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1804 tree init_decl = build_decl (VAR_DECL, generate_name (),
1806 pushdecl_top_level (init_decl);
1807 TREE_STATIC (init_decl) = 1;
1808 DECL_INITIAL (init_decl) = init;
1809 DECL_IGNORED_P (init_decl) = 1;
1810 TREE_READONLY (init_decl) = 1;
1811 make_decl_rtl (init_decl, NULL, 1);
1814 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1815 build1 (INDIRECT_REF, array_type, array_decl),
1821 if (BLOCK_EXPR_BODY (exp))
1824 tree body = BLOCK_EXPR_BODY (exp);
1825 struct rtx_def *to_return;
1826 pushlevel (2); /* 2 and above */
1827 expand_start_bindings (0);
1828 local = BLOCK_EXPR_DECLS (exp);
1831 tree next = TREE_CHAIN (local);
1832 layout_decl (local, 0);
1833 expand_decl (pushdecl (local));
1836 /* Avoid deep recursion for long block. */
1837 while (TREE_CODE (body) == COMPOUND_EXPR)
1839 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1841 body = TREE_OPERAND (body, 1);
1843 to_return = expand_expr (body, target, tmode, modifier);
1845 expand_end_bindings (getdecls (), 1, 0);
1853 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1854 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1857 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1859 (wfl_operator, "Duplicate case label: `%s'",
1860 print_int_node (TREE_OPERAND (exp, 0)));
1866 pushcase (NULL_TREE, 0,
1867 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1871 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
1872 expand_expr_stmt (TREE_OPERAND (exp, 1));
1873 expand_end_case (TREE_OPERAND (exp, 0));
1877 /* We expand a try[-catch] block */
1879 /* Expand the try block */
1880 expand_eh_region_start ();
1881 expand_expr_stmt (TREE_OPERAND (exp, 0));
1882 expand_start_all_catch ();
1884 /* Expand all catch clauses (EH handlers) */
1885 for (current = TREE_OPERAND (exp, 1); current;
1886 current = TREE_CHAIN (current))
1888 extern rtx return_label;
1890 tree catch = TREE_OPERAND (current, 0);
1891 tree decl = BLOCK_EXPR_DECLS (catch);
1892 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
1893 start_catch_handler (prepare_eh_table_type (type));
1894 expand_expr_stmt (TREE_OPERAND (current, 0));
1896 expand_resume_after_catch ();
1897 end_catch_handler ();
1899 expand_end_all_catch ();
1903 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
1904 tree_code_name [TREE_CODE (exp)]);
1909 expand_byte_code (jcf, method)
1916 unsigned char *linenumber_pointer;
1918 #undef RET /* Defined by config/i386/i386.h */
1919 #undef AND /* Causes problems with opcodes for iand and land. */
1921 #define BCODE byte_ops
1922 #define BYTE_type_node byte_type_node
1923 #define SHORT_type_node short_type_node
1924 #define INT_type_node int_type_node
1925 #define LONG_type_node long_type_node
1926 #define CHAR_type_node char_type_node
1927 #define PTR_type_node ptr_type_node
1928 #define FLOAT_type_node float_type_node
1929 #define DOUBLE_type_node double_type_node
1930 #define VOID_type_node void_type_node
1932 unsigned char* byte_ops;
1933 long length = DECL_CODE_LENGTH (method);
1936 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
1937 byte_ops = jcf->read_ptr;
1939 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1940 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1941 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1942 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1944 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
1946 instruction_bits = oballoc (length + 1);
1947 bzero (instruction_bits, length + 1);
1949 /* We make an initial pass of the line number table, to note
1950 which instructions have associated line number entries. */
1951 linenumber_pointer = linenumber_table;
1952 for (i = 0; i < linenumber_count; i++)
1954 int pc = GET_u2 (linenumber_pointer);
1955 linenumber_pointer += 4;
1957 warning ("invalid PC in line number table");
1960 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
1961 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
1962 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
1966 /* Do a preliminary pass.
1967 * This figures out which PC can be the targets of jumps. */
1968 for (PC = 0; PC < length;)
1970 int oldpc = PC; /* PC at instruction start. */
1971 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
1972 switch (byte_ops[PC++])
1974 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
1976 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
1979 #define NOTE_LABEL(PC) note_label(oldpc, PC)
1981 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1982 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1983 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
1984 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1985 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1986 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1987 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1988 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
1990 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
1991 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
1992 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
1993 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
1994 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
1995 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
1996 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
1997 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
1999 /* two forms of wide instructions */
2000 #define PRE_SPECIAL_WIDE(IGNORE) \
2002 int modified_opcode = IMMEDIATE_u1; \
2003 if (modified_opcode == OPCODE_iinc) \
2005 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2006 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2010 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2014 /* nothing */ /* XXX JH */
2016 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2018 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2020 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2021 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2022 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2023 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2024 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2025 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2026 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2027 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2028 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2029 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2031 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2032 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2033 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2034 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2035 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2036 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2037 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2038 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2040 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2042 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2043 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2045 #define PRE_LOOKUP_SWITCH \
2046 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2047 NOTE_LABEL (default_offset+oldpc); \
2049 while (--npairs >= 0) { \
2050 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2051 NOTE_LABEL (offset+oldpc); } \
2054 #define PRE_TABLE_SWITCH \
2055 { jint default_offset = IMMEDIATE_s4; \
2056 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2057 NOTE_LABEL (default_offset+oldpc); \
2059 while (low++ <= high) { \
2060 jint offset = IMMEDIATE_s4; \
2061 NOTE_LABEL (offset+oldpc); } \
2064 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2065 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2066 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2067 (void)(IMMEDIATE_u2); \
2068 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2070 #include "javaop.def"
2075 if (! verify_jvm_instructions (jcf, byte_ops, length))
2078 /* Translate bytecodes to rtl instructions. */
2079 linenumber_pointer = linenumber_table;
2080 for (PC = 0; PC < length;)
2082 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2084 tree label = lookup_label (PC);
2085 flush_quick_stack ();
2086 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2087 expand_label (label);
2088 if (LABEL_VERIFIED (label) || PC == 0)
2089 load_type_state (label);
2092 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2094 /* never executed - skip */
2095 warning ("Some bytecode operations (starting at pc %d) can never be executed", PC);
2097 && ! (instruction_bits [PC] & BCODE_VERIFIED))
2103 /* Handle possible line number entry for this PC.
2105 This code handles out-of-order and multiple linenumbers per PC,
2106 but is optimized for the case of line numbers increasing
2107 monotonically with PC. */
2108 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2110 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2111 || GET_u2 (linenumber_pointer) != PC)
2112 linenumber_pointer = linenumber_table;
2113 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2115 int pc = GET_u2 (linenumber_pointer);
2116 linenumber_pointer += 4;
2119 lineno = GET_u2 (linenumber_pointer - 2);
2120 emit_line_note (input_filename, lineno);
2121 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2126 maybe_start_try (PC);
2127 maybe_pushlevels (PC);
2129 PC = process_jvm_instruction (PC, byte_ops, length);
2131 maybe_poplevels (PC);
2137 java_push_constant_from_pool (jcf, index)
2142 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2145 push_obstacks (&permanent_obstack, &permanent_obstack);
2146 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2147 index = alloc_name_constant (CONSTANT_String, name);
2148 c = build_ref_from_constant_pool (index);
2149 TREE_TYPE (c) = promote_type (string_type_node);
2153 c = get_constant (jcf, index);
2158 process_jvm_instruction (PC, byte_ops, length)
2160 unsigned char* byte_ops;
2163 const char *opname; /* Temporary ??? */
2164 int oldpc = PC; /* PC at instruction start. */
2166 /* If the instruction is at the beginning of a exception handler,
2167 replace the top of the stack with the thrown object reference */
2168 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2170 tree type = pop_type (ptr_type_node);
2171 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2174 switch (byte_ops[PC++])
2176 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2179 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2182 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2184 int saw_index = 0; \
2185 int index = OPERAND_VALUE; \
2186 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2189 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2191 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2192 tree ret = lookup_label (PC); \
2193 build_java_jsr (where, ret); \
2194 load_type_state (ret); \
2197 /* Push a constant onto the stack. */
2198 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2199 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2200 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2201 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2203 /* internal macro added for use by the WIDE case */
2204 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2205 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2207 /* Push local variable onto the opcode stack. */
2208 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2210 /* have to do this since OPERAND_VALUE may have side-effects */ \
2211 int opvalue = OPERAND_VALUE; \
2212 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2215 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2216 expand_java_return (OPERAND_TYPE##_type_node)
2218 #define REM_EXPR TRUNC_MOD_EXPR
2219 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2220 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2222 #define FIELD(IS_STATIC, IS_PUT) \
2223 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2225 #define TEST(OPERAND_TYPE, CONDITION) \
2226 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2228 #define COND(OPERAND_TYPE, CONDITION) \
2229 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2231 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2232 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2234 #define BRANCH_GOTO(OPERAND_VALUE) \
2235 expand_java_goto (oldpc + OPERAND_VALUE)
2237 #define BRANCH_CALL(OPERAND_VALUE) \
2238 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2241 #define BRANCH_RETURN(OPERAND_VALUE) \
2243 tree type = OPERAND_TYPE##_type_node; \
2244 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2245 expand_java_ret (value); \
2249 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2250 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2251 fprintf (stderr, "(not implemented)\n")
2252 #define NOT_IMPL1(OPERAND_VALUE) \
2253 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2254 fprintf (stderr, "(not implemented)\n")
2256 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2258 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2260 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2262 #define STACK_SWAP(COUNT) java_stack_swap()
2264 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2265 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2266 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2268 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2269 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2271 #define LOOKUP_SWITCH \
2272 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2273 tree selector = pop_value (INT_type_node); \
2274 tree duplicate, label; \
2275 tree type = TREE_TYPE (selector); \
2276 flush_quick_stack (); \
2277 expand_start_case (0, selector, type, "switch statement");\
2278 push_momentary (); \
2279 while (--npairs >= 0) \
2281 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2282 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2283 TREE_TYPE (value) = type; \
2284 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2285 pushcase (value, convert, label, &duplicate); \
2286 expand_java_goto (oldpc + offset); \
2288 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2289 pushcase (NULL_TREE, 0, label, &duplicate); \
2290 expand_java_goto (oldpc + default_offset); \
2292 expand_end_case (selector); \
2295 #define TABLE_SWITCH \
2296 { jint default_offset = IMMEDIATE_s4; \
2297 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2298 tree selector = pop_value (INT_type_node); \
2299 tree duplicate, label; \
2300 tree type = TREE_TYPE (selector); \
2301 flush_quick_stack (); \
2302 expand_start_case (0, selector, type, "switch statement");\
2303 push_momentary (); \
2304 for (; low <= high; low++) \
2306 jint offset = IMMEDIATE_s4; \
2307 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2308 TREE_TYPE (value) = type; \
2309 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2310 pushcase (value, convert, label, &duplicate); \
2311 expand_java_goto (oldpc + offset); \
2313 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2314 pushcase (NULL_TREE, 0, label, &duplicate); \
2315 expand_java_goto (oldpc + default_offset); \
2317 expand_end_case (selector); \
2320 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2321 { int opcode = byte_ops[PC-1]; \
2322 int method_ref_index = IMMEDIATE_u2; \
2324 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2326 expand_invoke (opcode, method_ref_index, nargs); \
2329 /* Handle new, checkcast, instanceof */
2330 #define OBJECT(TYPE, OP) \
2331 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2333 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2335 #define ARRAY_LOAD(OPERAND_TYPE) \
2337 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2340 #define ARRAY_STORE(OPERAND_TYPE) \
2342 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2345 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2346 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2347 #define ARRAY_NEW_PTR() \
2348 push_value (build_anewarray (get_class_constant (current_jcf, \
2350 pop_value (int_type_node)));
2351 #define ARRAY_NEW_NUM() \
2353 int atype = IMMEDIATE_u1; \
2354 push_value (build_newarray (atype, pop_value (int_type_node)));\
2356 #define ARRAY_NEW_MULTI() \
2358 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2359 int ndims = IMMEDIATE_u1; \
2360 expand_java_multianewarray( class, ndims ); \
2363 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2364 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2365 pop_value (OPERAND_TYPE##_type_node))));
2367 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2369 push_value (build1 (NOP_EXPR, int_type_node, \
2370 (convert (TO_TYPE##_type_node, \
2371 pop_value (FROM_TYPE##_type_node))))); \
2374 #define CONVERT(FROM_TYPE, TO_TYPE) \
2376 push_value (convert (TO_TYPE##_type_node, \
2377 pop_value (FROM_TYPE##_type_node))); \
2380 /* internal macro added for use by the WIDE case
2381 Added TREE_TYPE (decl) assignment, apbianco */
2382 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2385 int var = OPVALUE; \
2386 tree type = OPTYPE; \
2387 value = pop_value (type); \
2388 type = TREE_TYPE (value); \
2389 decl = find_local_variable (var, type, oldpc); \
2390 set_local_type (var, type ); \
2391 expand_assignment (decl, value, 0, 0); \
2394 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2396 /* have to do this since OPERAND_VALUE may have side-effects */ \
2397 int opvalue = OPERAND_VALUE; \
2398 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2401 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2402 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2404 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2405 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2407 #define MONITOR_OPERATION(call) \
2409 tree o = pop_value (ptr_type_node); \
2411 flush_quick_stack (); \
2412 c = build_java_monitor (call, o); \
2413 TREE_SIDE_EFFECTS (c) = 1; \
2414 expand_expr_stmt (c); \
2417 #define SPECIAL_IINC(IGNORED) \
2419 unsigned int local_var_index = IMMEDIATE_u1; \
2420 int ival = IMMEDIATE_s1; \
2421 expand_iinc(local_var_index, ival, oldpc); \
2424 #define SPECIAL_WIDE(IGNORED) \
2426 int modified_opcode = IMMEDIATE_u1; \
2427 unsigned int local_var_index = IMMEDIATE_u2; \
2428 switch (modified_opcode) \
2432 int ival = IMMEDIATE_s2; \
2433 expand_iinc (local_var_index, ival, oldpc); \
2436 case OPCODE_iload: \
2437 case OPCODE_lload: \
2438 case OPCODE_fload: \
2439 case OPCODE_dload: \
2440 case OPCODE_aload: \
2442 /* duplicate code from LOAD macro */ \
2443 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2446 case OPCODE_istore: \
2447 case OPCODE_lstore: \
2448 case OPCODE_fstore: \
2449 case OPCODE_dstore: \
2450 case OPCODE_astore: \
2452 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2456 error ("unrecogized wide sub-instruction"); \
2460 #define SPECIAL_THROW(IGNORED) \
2461 build_java_athrow (pop_value (throwable_type_node))
2463 #define SPECIAL_BREAK NOT_IMPL1
2464 #define IMPL NOT_IMPL
2466 #include "javaop.def"
2469 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);