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"
41 static tree operand_type[59];
42 extern struct obstack permanent_obstack;
45 init_expr_processing()
47 operand_type[21] = operand_type[54] = int_type_node;
48 operand_type[22] = operand_type[55] = long_type_node;
49 operand_type[23] = operand_type[56] = float_type_node;
50 operand_type[24] = operand_type[57] = double_type_node;
51 operand_type[25] = operand_type[58] = ptr_type_node;
54 /* We store the stack state in two places:
55 Within a basic block, we use the quick_stack, which is a
56 pushdown list (TREE_LISTs) of expression nodes.
57 This is the top part of the stack; below that we use find_stack_slot.
58 At the end of a basic block, the quick_stack must be flushed
59 to the stack slot array (as handled by find_stack_slot).
60 Using quick_stack generates better code (especially when
61 compiled without optimization), because we do not have to
62 explicitly store and load trees to temporary variables.
64 If a variable is on the quick stack, it means the value of variable
65 when the quick stack was last flushed. Conceptually, flush_quick_stack
66 saves all the the quick_stack elements in parellel. However, that is
67 complicated, so it actually saves them (i.e. copies each stack value
68 to is home virtual register) from low indexes. This allows a quick_stack
69 element at index i (counting from the bottom of stack the) to references
70 slot virtuals for register that are >= i, but not those that are deeper.
71 This convention makes most operations easier. For example iadd works
72 even when the stack contains (reg[0], reg[1]): It results in the
73 stack containing (reg[0]+reg[1]), which is OK. However, some stack
74 operations are more complicated. For example dup given a stack
75 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
76 the convention, since stack value 1 would refer to a register with
77 lower index (reg[0]), which flush_quick_stack does not safely handle.
78 So dup cannot just add an extra element to the quick_stack, but iadd can.
81 tree quick_stack = NULL_TREE;
83 /* A free-list of unused permamnet TREE_LIST nodes. */
84 tree tree_list_free_list = NULL_TREE;
86 /* The stack pointer of the Java virtual machine.
87 This does include the size of the quick_stack. */
91 unsigned char *linenumber_table;
95 truthvalue_conversion (expr)
98 /* It is simpler and generates better code to have only TRUTH_*_EXPR
99 or comparison expressions as truth values at this level.
101 This function should normally be identity for Java. */
103 switch (TREE_CODE (expr))
106 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
107 case TRUTH_ANDIF_EXPR:
108 case TRUTH_ORIF_EXPR:
115 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
118 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
120 /* are these legal? XXX JH */
125 /* These don't change whether an object is non-zero or zero. */
126 return truthvalue_conversion (TREE_OPERAND (expr, 0));
129 /* Distribute the conversion into the arms of a COND_EXPR. */
130 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
131 truthvalue_conversion (TREE_OPERAND (expr, 1)),
132 truthvalue_conversion (TREE_OPERAND (expr, 2))));
135 /* If this is widening the argument, we can ignore it. */
136 if (TYPE_PRECISION (TREE_TYPE (expr))
137 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
138 return truthvalue_conversion (TREE_OPERAND (expr, 0));
139 /* fall through to default */
142 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
146 #ifdef JAVA_USE_HANDLES
147 /* Given a pointer to a handle, get a pointer to an object. */
153 tree field, handle_type;
154 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
155 handle_type = TREE_TYPE (expr);
156 field = TYPE_FIELDS (handle_type);
157 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
162 /* Save any stack slots that happen to be in the quick_stack into their
163 home virtual register slots.
165 The copy order is from low stack index to high, to support the invariant
166 that the expression for a slot may contain decls for stack slots with
167 higher (or the same) index, but not lower. */
172 int stack_index = stack_pointer;
173 register tree prev, cur, next;
175 /* First reverse the quick_stack, and count the number of slots it has. */
176 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
178 next = TREE_CHAIN (cur);
179 TREE_CHAIN (cur) = prev;
181 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
185 while (quick_stack != NULL_TREE)
188 tree node = quick_stack, type;
189 quick_stack = TREE_CHAIN (node);
190 TREE_CHAIN (node) = tree_list_free_list;
191 tree_list_free_list = node;
192 node = TREE_VALUE (node);
193 type = TREE_TYPE (node);
195 decl = find_stack_slot (stack_index, type);
197 expand_assignment (decl, node, 0, 0);
198 stack_index += 1 + TYPE_IS_WIDE (type);
207 type = promote_type (type);
208 n_words = 1 + TYPE_IS_WIDE (type);
209 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
210 fatal ("stack overflow");
211 stack_type_map[stack_pointer++] = type;
213 while (--n_words >= 0)
214 stack_type_map[stack_pointer++] = TYPE_SECOND;
221 tree type = TREE_TYPE (value);
222 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
224 type = promote_type (type);
225 value = convert (type, value);
228 if (tree_list_free_list == NULL_TREE)
229 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
232 tree node = tree_list_free_list;
233 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
234 TREE_VALUE (node) = value;
235 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 int n_words = 1 + TYPE_IS_WIDE (type);
361 type = pop_type (type);
364 tree node = quick_stack;
365 quick_stack = TREE_CHAIN (quick_stack);
366 TREE_CHAIN (node) = tree_list_free_list;
367 tree_list_free_list = node;
368 node = TREE_VALUE (node);
372 return find_stack_slot (stack_pointer, promote_type (type));
376 /* Pop and discrad the top COUNT stack slots. */
379 java_stack_pop (count)
385 if (stack_pointer == 0)
386 fatal ("stack underflow");
387 type = stack_type_map[stack_pointer - 1];
388 if (type == TYPE_SECOND)
391 if (stack_pointer == 1 || count <= 0)
392 fatal ("stack underflow");
393 type = stack_type_map[stack_pointer - 2];
395 val = pop_value (type);
400 /* Implement the 'swap' operator (to swap two top stack slots). */
409 if (stack_pointer < 2
410 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
411 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
412 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
413 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
414 fatal ("bad stack swap");
416 flush_quick_stack ();
417 decl1 = find_stack_slot (stack_pointer - 1, type1);
418 decl2 = find_stack_slot (stack_pointer - 2, type2);
419 temp = copy_to_reg (DECL_RTL (decl1));
420 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
421 emit_move_insn (DECL_RTL (decl2), temp);
422 stack_type_map[stack_pointer - 1] = type2;
423 stack_type_map[stack_pointer - 2] = type1;
427 java_stack_dup (size, offset)
430 int low_index = stack_pointer - size - offset;
433 error ("stack underflow - dup* operation");
435 flush_quick_stack ();
437 stack_pointer += size;
438 dst_index = stack_pointer;
440 for (dst_index = stack_pointer; --dst_index >= low_index; )
443 int src_index = dst_index - size;
444 if (src_index < low_index)
445 src_index = dst_index + size + offset;
446 type = stack_type_map [src_index];
447 if (type == TYPE_SECOND)
449 if (src_index <= low_index)
450 fatal ("dup operation splits 64-bit number");
451 stack_type_map[dst_index] = type;
452 src_index--; dst_index--;
453 type = stack_type_map[src_index];
454 if (! TYPE_IS_WIDE (type))
455 fatal ("internal error - dup operation");
457 else if (TYPE_IS_WIDE (type))
458 fatal ("internal error - dup operation");
459 if (src_index != dst_index)
461 tree src_decl = find_stack_slot (src_index, type);
462 tree dst_decl = find_stack_slot (dst_index, type);
463 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
464 stack_type_map[dst_index] = type;
469 /* Calls _Jv_Throw. Discard the contents of the value stack. */
472 build_java_athrow (node)
477 call = build (CALL_EXPR,
479 build_address_of (throw_node),
480 build_tree_list (NULL_TREE, node),
482 TREE_SIDE_EFFECTS (call) = 1;
483 expand_expr_stmt (call);
484 java_stack_pop (stack_pointer);
487 /* Implementation for jsr/ret */
490 build_java_jsr (where, ret)
494 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
495 push_value (ret_label);
496 flush_quick_stack ();
502 build_java_ret (location)
505 expand_computed_goto (location);
508 /* Implementation of operations on array: new, load, store, length */
510 /* Array core info access macros */
512 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
513 size_binop (CEIL_DIV_EXPR, \
515 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
516 size_int (BITS_PER_UNIT))
519 decode_newarray_type (int atype)
523 case 4: return boolean_type_node;
524 case 5: return char_type_node;
525 case 6: return float_type_node;
526 case 7: return double_type_node;
527 case 8: return byte_type_node;
528 case 9: return short_type_node;
529 case 10: return int_type_node;
530 case 11: return long_type_node;
531 default: return NULL_TREE;
535 /* Map primitive type to the code used by OPCODE_newarray. */
538 encode_newarray_type (type)
541 if (type == boolean_type_node)
543 else if (type == char_type_node)
545 else if (type == float_type_node)
547 else if (type == double_type_node)
549 else if (type == byte_type_node)
551 else if (type == short_type_node)
553 else if (type == int_type_node)
555 else if (type == long_type_node)
558 fatal ("Can't compute type code - patch_newarray");
561 /* Build a call to _Jv_ThrowBadArrayIndex(), the
562 ArrayIndexOfBoundsException exception handler. */
565 build_java_throw_out_of_bounds_exception (index)
568 tree node = build (CALL_EXPR, int_type_node,
569 build_address_of (soft_badarrayindex_node),
570 build_tree_list (NULL_TREE, index), NULL_TREE);
571 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
575 /* Return the length of an array. Doesn't perform any checking on the nature
576 or value of the array NODE. May be used to implement some bytecodes. */
579 build_java_array_length_access (node)
582 tree type = TREE_TYPE (node);
583 HOST_WIDE_INT length;
584 if (!is_array_type_p (type))
585 fatal ("array length on a non-array reference");
586 length = java_array_type_length (type);
588 return build_int_2 (length, 0);
589 return fold (build1 (INDIRECT_REF,
591 fold (build (PLUS_EXPR, ptr_type_node,
593 JAVA_ARRAY_LENGTH_OFFSET(node)))));
596 /* Optionally checks an array against the NULL pointer, eventually throwing a
597 NullPointerException. It could replace signal handling, but tied to NULL.
598 ARG1: the pointer to check, ARG2: the expression to use if
599 the pointer is non-null and ARG3 the type that should be returned. */
602 build_java_arraynull_check (node, expr, type)
608 static int java_array_access_throws_null_exception = 0;
610 if (java_array_access_throws_null_exception)
611 return (build (COND_EXPR,
613 build (EQ_EXPR, int_type_node, node, null_pointer_node),
614 build_java_athrow (node), expr ));
621 java_array_data_offset (array)
624 tree array_type = TREE_TYPE (TREE_TYPE (array));
625 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
626 if (data_fld == NULL_TREE)
627 return size_in_bytes (array_type);
629 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
633 /* Implement array indexing (either as l-value or r-value).
634 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
635 Optionally performs bounds checking and/or test to NULL.
636 At this point, ARRAY should have been verified as an array. */
639 build_java_arrayaccess (array, type, index)
640 tree array, type, index;
642 tree arith, node, throw = NULL_TREE;
644 arith = fold (build (PLUS_EXPR, int_type_node,
645 java_array_data_offset (array),
646 fold (build (MULT_EXPR, int_type_node,
647 index, size_in_bytes(type)))));
649 if (flag_bounds_check)
652 * (unsigned jint) INDEX >= (unsigned jint) LEN
653 * && throw ArrayIndexOutOfBoundsException.
654 * Note this is equivalent to and more efficient than:
655 * INDEX < 0 || INDEX >= LEN && throw ... */
657 tree len = build_java_array_length_access (array);
658 TREE_TYPE (len) = unsigned_int_type_node;
659 test = fold (build (GE_EXPR, boolean_type_node,
660 convert (unsigned_int_type_node, index),
662 if (! integer_zerop (test))
664 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
665 build_java_throw_out_of_bounds_exception (index));
666 /* allows expansion within COMPOUND */
667 TREE_SIDE_EFFECTS( throw ) = 1;
671 node = build1 (INDIRECT_REF, type,
672 fold (build (PLUS_EXPR, ptr_type_node,
674 (throw ? build (COMPOUND_EXPR, int_type_node,
678 return (fold (build_java_arraynull_check (array, node, type)));
681 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
682 ARRAY_NODE. This function is used to retrieve something less vague than
683 a pointer type when indexing the first dimension of something like [[<t>.
684 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
686 As a side effect, it also makes sure that ARRAY_NODE is an array. */
689 build_java_check_indexed_type (array_node, indexed_type)
695 if (!is_array_type_p (TREE_TYPE (array_node)))
696 fatal ("array indexing on a non-array reference");
698 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
700 if (indexed_type == ptr_type_node )
701 return promote_type (elt_type);
703 /* BYTE/BOOLEAN store and load are used for both type */
704 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
705 return boolean_type_node;
707 if (indexed_type != elt_type )
708 fatal ("type array element mismatch");
713 /* newarray triggers a call to _Jv_NewArray. This function should be called
714 with an integer code (the type of array to create) and get from the stack
715 the size of the dimmension. */
718 build_newarray (atype_value, length)
722 tree type = build_java_array_type (decode_newarray_type (atype_value),
723 TREE_CODE (length) == INTEGER_CST
724 ? TREE_INT_CST_LOW (length)
726 return build (CALL_EXPR, promote_type (type),
727 build_address_of (soft_newarray_node),
728 tree_cons (NULL_TREE,
729 build_int_2 (atype_value, 0),
730 build_tree_list (NULL_TREE, length)),
734 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
738 build_anewarray (class_type, length)
742 tree type = build_java_array_type (class_type,
743 TREE_CODE (length) == INTEGER_CST
744 ? TREE_INT_CST_LOW (length)
746 return build (CALL_EXPR, promote_type (type),
747 build_address_of (soft_anewarray_node),
748 tree_cons (NULL_TREE, length,
749 tree_cons (NULL_TREE, build_class_ref (class_type),
750 build_tree_list (NULL_TREE,
751 null_pointer_node))),
755 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
758 build_new_array (type, length)
762 if (JPRIMITIVE_TYPE_P (type))
763 return build_newarray (encode_newarray_type (type), length);
765 return build_anewarray (TREE_TYPE (type), length);
768 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
769 class pointer, a number of dimensions and the matching number of
770 dimensions. The argument list is NULL terminated. */
773 expand_java_multianewarray (class_type, ndim)
778 tree args = build_tree_list( NULL_TREE, null_pointer_node );
780 for( i = 0; i < ndim; i++ )
781 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
783 push_value (build (CALL_EXPR,
784 promote_type (class_type),
785 build_address_of (soft_multianewarray_node),
786 tree_cons (NULL_TREE, build_class_ref (class_type),
787 tree_cons (NULL_TREE,
788 build_int_2 (ndim, 0), args )),
792 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
793 ARRAY is an array type. May expand some bound checking and NULL
794 pointer checking. RHS_TYPE_NODE we are going to store. In the case
795 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
796 INT. In those cases, we make the convertion.
798 if ARRAy is a reference type, the assignment is checked at run-time
799 to make sure that the RHS can be assigned to the array element
800 type. It is not necessary to generate this code if ARRAY is final. */
803 expand_java_arraystore (rhs_type_node)
806 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
807 && TYPE_PRECISION (rhs_type_node) <= 32) ?
808 int_type_node : rhs_type_node);
809 tree index = pop_value (int_type_node);
810 tree array = pop_value (ptr_type_node);
812 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
814 flush_quick_stack ();
816 index = save_expr (index);
817 array = save_expr (array);
819 if (TREE_CODE (rhs_type_node) == POINTER_TYPE
820 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
822 tree check = build (CALL_EXPR, void_type_node,
823 build_address_of (soft_checkarraystore_node),
824 tree_cons (NULL_TREE, array,
825 build_tree_list (NULL_TREE, rhs_node)),
827 TREE_SIDE_EFFECTS (check) = 1;
828 expand_expr_stmt (check);
831 expand_assignment (build_java_arrayaccess (array,
837 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
838 sure that LHS is an array type. May expand some bound checking and NULL
840 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
841 BOOLEAN/SHORT, we push a promoted type back to the stack.
845 expand_java_arrayload (lhs_type_node )
850 tree index_node = pop_value (int_type_node);
851 tree array_node = pop_value (ptr_type_node);
853 index_node = save_expr (index_node);
854 array_node = save_expr (array_node);
855 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
857 load_node = build_java_arrayaccess (array_node,
861 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
862 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
863 push_value (load_node);
866 /* Expands .length. Makes sure that we deal with and array and may expand
867 a NULL check on the array object. */
870 expand_java_array_length ()
872 tree array = pop_value (ptr_type_node);
873 tree length = build_java_array_length_access (array);
875 push_value (build_java_arraynull_check (array, length, int_type_node));
878 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
879 either soft_monitorenter_node or soft_monitorexit_node. */
882 build_java_monitor (call, object)
886 return (build (CALL_EXPR,
888 build_address_of (call),
889 build_tree_list (NULL_TREE, object),
893 /* Emit code for one of the PUSHC instructions. */
896 expand_java_pushc (ival, type)
901 if (type == ptr_type_node && ival == 0)
902 value = null_pointer_node;
903 else if (type == int_type_node || type == long_type_node)
905 value = build_int_2 (ival, ival < 0 ? -1 : 0);
906 TREE_TYPE (value) = type;
908 else if (type == float_type_node || type == double_type_node)
911 #ifdef REAL_ARITHMETIC
912 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
916 value = build_real (type, x);
919 fatal ("internal error in expand_java_pushc");
924 expand_java_return (type)
927 if (type == void_type_node)
928 expand_null_return ();
931 tree retval = pop_value (type);
932 tree res = DECL_RESULT (current_function_decl);
933 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
934 TREE_SIDE_EFFECTS (retval) = 1;
935 expand_return (retval);
940 build_address_of (value)
943 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
947 expand_java_NEW (type)
950 if (! CLASS_LOADED_P (type))
951 load_class (type, 1);
952 layout_class_methods (type);
953 push_value (build (CALL_EXPR, promote_type (type),
954 build_address_of (alloc_object_node),
955 tree_cons (NULL_TREE, build_class_ref (type),
956 build_tree_list (NULL_TREE,
957 size_in_bytes (type))),
962 expand_java_INSTANCEOF (type)
965 tree value = pop_value (object_ptr_type_node);
966 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
967 build_address_of (soft_instanceof_node),
968 tree_cons (NULL_TREE, value,
969 build_tree_list (NULL_TREE,
970 build_class_ref (type))),
976 expand_java_CHECKCAST (type)
979 tree value = pop_value (ptr_type_node);
980 value = build (CALL_EXPR, promote_type (type),
981 build_address_of (soft_checkcast_node),
982 tree_cons (NULL_TREE, build_class_ref (type),
983 build_tree_list (NULL_TREE, value)),
989 expand_iinc (unsigned int local_var_index, int ival, int pc)
994 flush_quick_stack ();
995 local_var = find_local_variable (local_var_index, int_type_node, pc);
996 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
997 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
998 expand_assignment (local_var, res, 0, 0);
1002 build_java_binop (op, type, arg1, arg2)
1004 tree type, arg1, arg2;
1011 tree u_type = unsigned_type (type);
1012 arg1 = convert (u_type, arg1);
1013 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1014 return convert (type, arg1);
1018 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1019 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1022 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1023 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1024 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1026 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1027 boolean_type_node, arg1, arg2));
1028 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1029 tree second_compare = fold (build (COND_EXPR, int_type_node,
1030 ifexp2, integer_zero_node,
1031 op == COMPARE_L_EXPR
1032 ? integer_negative_one_node
1033 : integer_one_node));
1034 return fold (build (COND_EXPR, int_type_node, ifexp1,
1035 op == COMPARE_L_EXPR ? integer_one_node
1036 : integer_negative_one_node,
1040 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1042 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1043 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1044 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1045 ifexp2, integer_one_node,
1046 integer_zero_node));
1047 return fold (build (COND_EXPR, int_type_node,
1048 ifexp1, integer_negative_one_node, second_compare));
1051 case TRUNC_MOD_EXPR:
1052 if (TREE_CODE (type) == REAL_TYPE)
1055 if (type != double_type_node)
1057 arg1 = convert (double_type_node, arg1);
1058 arg2 = convert (double_type_node, arg2);
1060 call = build (CALL_EXPR, double_type_node,
1061 build_address_of (soft_fmod_node),
1062 tree_cons (NULL_TREE, arg1,
1063 build_tree_list (NULL_TREE, arg2)),
1065 if (type != double_type_node)
1066 call = convert (type, call);
1072 return fold (build (op, type, arg1, arg2));
1076 expand_java_binop (type, op)
1077 tree type; enum tree_code op;
1087 rtype = int_type_node;
1088 rarg = pop_value (rtype);
1091 rarg = pop_value (rtype);
1093 larg = pop_value (ltype);
1094 push_value (build_java_binop (op, type, larg, rarg));
1097 /* Lookup the field named NAME in *TYPEP or its super classes.
1098 If not found, return NULL_TREE.
1099 (If the *TYPEP is not found, return error_mark_node.)
1100 If found, return the FIELD_DECL, and set *TYPEP to the
1101 class containing the field. */
1104 lookup_field (typep, name)
1108 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1110 load_class (*typep, 1);
1111 if (TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1112 return error_mark_node;
1117 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1119 if (DECL_NAME (field) == name)
1122 *typep = CLASSTYPE_SUPER (*typep);
1127 /* Look up the field named NAME in object SELF_VALUE,
1128 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1129 SELF_VALUE is NULL_TREE if looking for a static field. */
1132 build_field_ref (self_value, self_class, name)
1133 tree self_value, self_class, name;
1135 tree base_class = self_class;
1136 tree field_decl = lookup_field (&base_class, name);
1137 if (field_decl == NULL_TREE)
1139 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1140 return error_mark_node;
1142 if (self_value == NULL_TREE)
1144 return build_static_field_ref (field_decl);
1148 tree base_handle_type = promote_type (base_class);
1149 if (base_handle_type != TREE_TYPE (self_value))
1150 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1151 #ifdef JAVA_USE_HANDLES
1152 self_value = unhand_expr (self_value);
1154 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1156 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1157 self_value, field_decl));
1167 sprintf (buf, "LJpc=%d", pc);
1168 name = get_identifier (buf);
1169 if (IDENTIFIER_LOCAL_VALUE (name))
1170 return IDENTIFIER_LOCAL_VALUE (name);
1173 /* The type of the address of a label is return_address_type_node. */
1174 tree decl = create_label_decl (name);
1175 LABEL_PC (decl) = pc;
1177 return pushdecl (decl);
1181 /* Generate a unique name for the purpose of loops and switches
1182 labels, and try-catch-finally blocks label or temporary variables. */
1187 static int l_number = 0;
1189 sprintf (buff, "$L%d", l_number++);
1190 return get_identifier (buff);
1194 create_label_decl (name)
1198 push_obstacks (&permanent_obstack, &permanent_obstack);
1199 decl = build_decl (LABEL_DECL, name,
1200 TREE_TYPE (return_address_type_node));
1202 DECL_CONTEXT (decl) = current_function_decl;
1203 DECL_IGNORED_P (decl) = 1;
1207 /* This maps a bytecode offset (PC) to various flags. */
1208 char *instruction_bits;
1211 note_label (current_pc, target_pc)
1212 int current_pc, target_pc;
1214 lookup_label (target_pc);
1215 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1218 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1219 where CONDITION is one of one the compare operators. */
1222 expand_compare (condition, value1, value2, target_pc)
1223 enum tree_code condition;
1224 tree value1, value2;
1227 tree target = lookup_label (target_pc);
1228 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1229 expand_start_cond (truthvalue_conversion (cond), 0);
1230 expand_goto (target);
1234 /* Emit code for a TEST-type opcode. */
1237 expand_test (condition, type, target_pc)
1238 enum tree_code condition;
1242 tree value1, value2;
1243 flush_quick_stack ();
1244 value1 = pop_value (type);
1245 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1246 expand_compare (condition, value1, value2, target_pc);
1249 /* Emit code for a COND-type opcode. */
1252 expand_cond (condition, type, target_pc)
1253 enum tree_code condition;
1257 tree value1, value2;
1258 flush_quick_stack ();
1259 /* note: pop values in opposite order */
1260 value2 = pop_value (type);
1261 value1 = pop_value (type);
1262 /* Maybe should check value1 and value2 for type compatibility ??? */
1263 expand_compare (condition, value1, value2, target_pc);
1267 expand_java_goto (target_pc)
1270 tree target_label = lookup_label (target_pc);
1271 flush_quick_stack ();
1272 expand_goto (target_label);
1276 expand_java_call (target_pc, return_address)
1277 int target_pc, return_address;
1279 tree target_label = lookup_label (target_pc);
1280 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1282 flush_quick_stack ();
1283 expand_goto (target_label);
1287 expand_java_ret (return_address)
1288 tree return_address;
1290 warning ("ret instruction not implemented");
1292 tree target_label = lookup_label (target_pc);
1293 flush_quick_stack ();
1294 expand_goto (target_label);
1298 /* Recursive helper function to pop argument types during verifiation. */
1301 pop_argument_types (arg_types)
1304 if (arg_types == end_params_node)
1306 if (TREE_CODE (arg_types) == TREE_LIST)
1308 pop_argument_types (TREE_CHAIN (arg_types));
1309 pop_type (TREE_VALUE (arg_types));
1316 pop_arguments (arg_types)
1319 if (arg_types == end_params_node)
1321 if (TREE_CODE (arg_types) == TREE_LIST)
1323 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1324 tree type = TREE_VALUE (arg_types);
1325 tree arg = pop_value (type);
1326 #ifdef PROMOTE_PROTOTYPES
1327 if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1328 && INTEGRAL_TYPE_P (type))
1329 arg = convert (integer_type_node, arg);
1331 return tree_cons (NULL_TREE, arg, tail);
1336 /* Build an expression to initialize the class CLAS.
1337 if EXPR is non-NULL, returns an expression to first call the initializer
1338 (if it is needed) and then calls EXPR. */
1341 build_class_init (clas, expr)
1345 if (inherits_from_p (current_class, clas))
1347 init = build (CALL_EXPR, void_type_node,
1348 build_address_of (soft_initclass_node),
1349 build_tree_list (NULL_TREE, build_class_ref (clas)),
1351 TREE_SIDE_EFFECTS (init) = 1;
1352 if (expr != NULL_TREE)
1354 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1355 TREE_SIDE_EFFECTS (expr) = 1;
1361 static tree methods_ident = NULL_TREE;
1362 static tree ncode_ident = NULL_TREE;
1363 tree dtable_ident = NULL_TREE;
1366 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1367 tree method, method_type, self_type, method_signature, arg_list;
1370 if (is_compiled_class (self_type))
1372 make_decl_rtl (method, NULL, 1);
1373 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1377 /* We don't know whether the method has been (statically) compiled.
1378 Compile this code to get a reference to the method's code:
1380 SELF_TYPE->methods[METHOD_INDEX].ncode
1382 This is guaranteed to work (assuming SELF_TYPE has
1383 been initialized), since if the method is not compiled yet,
1384 its ncode points to a trampoline that forces compilation. */
1386 int method_index = 0;
1388 tree ref = build_class_ref (self_type);
1389 ref = build1 (INDIRECT_REF, class_type_node, ref);
1390 if (ncode_ident == NULL_TREE)
1391 ncode_ident = get_identifier ("ncode");
1392 if (methods_ident == NULL_TREE)
1393 methods_ident = get_identifier ("methods");
1394 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1395 lookup_field (&class_type_node, methods_ident));
1396 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1397 ; meth = TREE_CHAIN (meth))
1401 if (meth == NULL_TREE)
1402 fatal ("method '%s' not found in class",
1403 IDENTIFIER_POINTER (DECL_NAME (method)));
1406 method_index *= int_size_in_bytes (method_type_node);
1407 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1408 ref, build_int_2 (method_index, 0)));
1409 ref = build1 (INDIRECT_REF, method_type_node, ref);
1410 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1412 lookup_field (&method_type_node, ncode_ident));
1418 invoke_build_dtable (is_invoke_interface, arg_list)
1419 int is_invoke_interface;
1422 tree dtable, objectref;
1424 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1426 /* If we're dealing with interfaces and if the objectref
1427 argument is an array then get the dispatch table of the class
1428 Object rather than the one from the objectref. */
1429 objectref = (is_invoke_interface
1430 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1431 object_type_node : TREE_VALUE (arg_list));
1433 if (dtable_ident == NULL_TREE)
1434 dtable_ident = get_identifier ("vtable");
1435 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1436 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1437 lookup_field (&object_type_node, dtable_ident));
1443 build_invokevirtual (dtable, method)
1444 tree dtable, method;
1447 tree nativecode_ptr_ptr_type_node
1448 = build_pointer_type (nativecode_ptr_type_node);
1449 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1450 /* Add one to skip "class" field of dtable, and one to skip unused
1451 vtable entry (for C++ compatibility). */
1454 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1455 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1456 dtable, build_int_2 (method_index, 0)));
1457 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1463 build_invokeinterface (dtable, method_name, method_signature)
1464 tree dtable, method_name, method_signature;
1466 static tree class_ident = NULL_TREE;
1469 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1470 ensure that the selected method exists, is public and not
1471 abstract nor static. */
1473 if (class_ident == NULL_TREE)
1474 class_ident = get_identifier ("class");
1476 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1477 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1478 lookup_field (&dtable_type, class_ident));
1479 lookup_arg = build_tree_list (NULL_TREE, build_utf8_ref (method_signature));
1480 lookup_arg = tree_cons (NULL_TREE, dtable,
1481 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1483 return build (CALL_EXPR, ptr_type_node,
1484 build_address_of (soft_lookupinterfacemethod_node),
1485 lookup_arg, NULL_TREE);
1488 /* Expand one of the invoke_* opcodes.
1489 OCPODE is the specific opcode.
1490 METHOD_REF_INDEX is an index into the constant pool.
1491 NARGS is the number of arguments, or -1 if not specified. */
1494 expand_invoke (opcode, method_ref_index, nargs)
1496 int method_ref_index;
1499 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
1500 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
1501 tree self_type = get_class_constant
1502 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
1503 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1504 tree call, func, method, arg_list, method_type;
1506 if (! CLASS_LOADED_P (self_type))
1508 load_class (self_type, 1);
1509 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1510 fatal ("failed to find class '%s'", self_name);
1512 layout_class_methods (self_type);
1514 if (method_name == init_identifier_node)
1515 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1518 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1519 method_name, method_signature);
1520 if (method == NULL_TREE)
1522 error ("Class '%s' has no method named '%s' matching signature '%s'",
1524 IDENTIFIER_POINTER (method_name),
1525 IDENTIFIER_POINTER (method_signature));
1527 /* Invoke static can't invoke static/abstract method */
1528 else if (opcode == OPCODE_invokestatic)
1530 if (!METHOD_STATIC (method))
1532 error ("invokestatic on non static method");
1535 else if (METHOD_ABSTRACT (method))
1537 error ("invokestatic on abstract method");
1543 if (METHOD_STATIC (method))
1545 error ("invoke[non-static] on static method");
1550 if (method == NULL_TREE)
1552 method_type = get_type_from_signature (method_signature);
1553 pop_arguments (TYPE_ARG_TYPES (method_type));
1554 if (opcode != OPCODE_invokestatic)
1555 pop_type (self_type);
1556 method_type = promote_type (TREE_TYPE (method_type));
1557 push_value (convert (method_type, integer_zero_node));
1561 method_type = TREE_TYPE (method);
1562 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1563 flush_quick_stack ();
1566 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1567 || (opcode == OPCODE_invokevirtual
1568 && (METHOD_PRIVATE (method)
1569 || METHOD_FINAL (method) || CLASS_FINAL (TYPE_NAME (self_type)))))
1570 func = build_known_method_ref (method, method_type, self_type,
1571 method_signature, arg_list);
1574 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1576 if (opcode == OPCODE_invokevirtual)
1577 func = build_invokevirtual (dtable, method);
1579 func = build_invokeinterface (dtable, method_name, method_signature);
1581 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1582 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1583 TREE_SIDE_EFFECTS (call) = 1;
1585 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1586 expand_expr_stmt (call);
1590 flush_quick_stack ();
1595 /* Expand an operation to extract from or store into a field.
1596 IS_STATIC is 1 iff the field is static.
1597 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1598 FIELD_REF_INDEX is an index into the constant pool. */
1601 expand_java_field_op (is_static, is_putting, field_ref_index)
1604 int field_ref_index;
1606 tree self_type = get_class_constant
1607 (current_jcf, COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool, field_ref_index));
1608 char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1609 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
1610 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool, field_ref_index);
1611 tree field_type = get_type_from_signature (field_signature);
1612 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1615 tree field_decl = lookup_field (&self_type, field_name);
1616 if (field_decl == error_mark_node)
1620 else if (field_decl == NULL_TREE)
1622 error ("Missing field '%s' in '%s'",
1623 IDENTIFIER_POINTER (field_name), self_name);
1626 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1628 error ("Mismatching signature for field '%s' in '%s'",
1629 IDENTIFIER_POINTER (field_name), self_name);
1632 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1636 push_value (convert (field_type, integer_zero_node));
1637 flush_quick_stack ();
1641 /* Inline references to java.lang.PRIMTYPE.TYPE.
1642 In addition to being a useful (minor) optimization,
1643 this is also needed to avoid circularities in the implementation
1644 of these fields in libjava. */
1645 if (field_name == TYPE_identifier_node && ! is_putting
1646 && ! flag_emit_class_files && field_type == class_ptr_type
1647 && strncmp (self_name, "java.lang.", 10) == 0)
1649 tree typ = build_primtype_type_ref (self_name);
1657 field_ref = build_field_ref (field_ref, self_type, field_name);
1659 field_ref = build_class_init (self_type, field_ref);
1662 flush_quick_stack ();
1663 if (FIELD_FINAL (field_decl))
1665 if (DECL_CONTEXT (field_decl) != current_class)
1666 error_with_decl (field_decl,
1667 "assignment to final field `%s' not in field's class");
1668 else if (FIELD_STATIC (field_decl))
1670 if (DECL_NAME (current_function_decl) != clinit_identifier_node)
1671 error_with_decl (field_decl,
1672 "assignment to final static field `%s' not in class initializer");
1676 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1677 error_with_decl (field_decl,
1678 "assignment to final field `%s' not in constructor");
1681 expand_assignment (field_ref, new_value, 0, 0);
1684 push_value (field_ref);
1688 build_primtype_type_ref (self_name)
1691 char *class_name = self_name+10;
1693 if (strncmp(class_name, "Byte", 4) == 0)
1694 typ = byte_type_node;
1695 else if (strncmp(class_name, "Short", 5) == 0)
1696 typ = short_type_node;
1697 else if (strncmp(class_name, "Integer", 7) == 0)
1698 typ = int_type_node;
1699 else if (strncmp(class_name, "Long", 4) == 0)
1700 typ = long_type_node;
1701 else if (strncmp(class_name, "Float", 5) == 0)
1702 typ = float_type_node;
1703 else if (strncmp(class_name, "Double", 6) == 0)
1704 typ = double_type_node;
1705 else if (strncmp(class_name, "Boolean", 7) == 0)
1706 typ = boolean_type_node;
1707 else if (strncmp(class_name, "Char", 4) == 0)
1708 typ = char_type_node;
1709 else if (strncmp(class_name, "Void", 4) == 0)
1710 typ = void_type_node;
1713 if (typ != NULL_TREE)
1714 return build_class_ref (typ);
1720 load_type_state (label)
1724 tree vec = LABEL_TYPE_STATE (label);
1725 int cur_length = TREE_VEC_LENGTH (vec);
1726 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1727 for (i = 0; i < cur_length; i++)
1728 type_map [i] = TREE_VEC_ELT (vec, i);
1731 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1732 dependant things, but they rely on gcc routines. This function is
1733 placed here because it uses things defined locally in parse.y. */
1736 case_identity (t, v)
1737 tree t __attribute__ ((__unused__));
1744 java_lang_expand_expr (exp, target, tmode, modifier)
1747 enum machine_mode tmode;
1748 enum expand_modifier modifier;
1751 tree type = TREE_TYPE (exp);
1752 register enum machine_mode mode = TYPE_MODE (type);
1753 int unsignedp = TREE_UNSIGNED (type);
1757 switch (TREE_CODE (exp))
1759 case NEW_ARRAY_INIT:
1762 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1763 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1764 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1765 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1766 tree length = build_int_2 (ilength, 0);
1767 tree init = TREE_OPERAND (exp, 0);
1770 /* Enable this once we can set the vtable field statically. FIXME */
1771 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1772 && JPRIMITIVE_TYPE_P (element_type))
1774 tree temp, value, init_decl;
1775 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1776 PUSH_FIELD_VALUE (temp, "vtable",
1777 null_pointer_node /* FIXME */
1779 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1780 FINISH_RECORD_CONSTRUCTOR (temp);
1781 START_RECORD_CONSTRUCTOR (value, array_type);
1782 PUSH_SUPER_VALUE (value, temp);
1783 PUSH_FIELD_VALUE (value, "length", length);
1784 PUSH_FIELD_VALUE (value, "data", init);
1785 FINISH_RECORD_CONSTRUCTOR (value);
1787 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1788 pushdecl_top_level (init_decl);
1789 TREE_STATIC (init_decl) = 1;
1790 DECL_INITIAL (init_decl) = value;
1791 DECL_IGNORED_P (init_decl) = 1;
1792 TREE_READONLY (init_decl) = 1;
1793 make_decl_rtl (init_decl, NULL, 1);
1794 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1795 return expand_expr (init, target, tmode, modifier);
1798 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1799 expand_decl (array_decl);
1800 tmp = expand_assignment (array_decl,
1801 build_new_array (element_type, length),
1803 if (TREE_CONSTANT (init)
1804 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1806 tree init_decl = build_decl (VAR_DECL, generate_name (),
1808 pushdecl_top_level (init_decl);
1809 TREE_STATIC (init_decl) = 1;
1810 DECL_INITIAL (init_decl) = init;
1811 DECL_IGNORED_P (init_decl) = 1;
1812 TREE_READONLY (init_decl) = 1;
1813 make_decl_rtl (init_decl, NULL, 1);
1816 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1817 build1 (INDIRECT_REF, array_type, array_decl),
1823 if (BLOCK_EXPR_BODY (exp))
1826 tree body = BLOCK_EXPR_BODY (exp);
1827 struct rtx_def *to_return;
1828 pushlevel (2); /* 2 and above */
1829 expand_start_bindings (0);
1830 local = BLOCK_EXPR_DECLS (exp);
1833 tree next = TREE_CHAIN (local);
1834 layout_decl (local, 0);
1835 expand_decl (pushdecl (local));
1838 /* Avoid deep recursion for long block. */
1839 while (TREE_CODE (body) == COMPOUND_EXPR)
1841 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1843 body = TREE_OPERAND (body, 1);
1845 to_return = expand_expr (body, target, tmode, modifier);
1847 expand_end_bindings (getdecls (), 1, 0);
1855 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1856 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1859 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1861 (wfl_operator, "Duplicate case label: `%s'",
1862 print_int_node (TREE_OPERAND (exp, 0)));
1868 pushcase (NULL_TREE, 0,
1869 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
1873 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
1874 expand_expr_stmt (TREE_OPERAND (exp, 1));
1875 expand_end_case (TREE_OPERAND (exp, 0));
1879 /* We expand a try[-catch][-finally] block */
1881 /* Expand the try block */
1882 expand_eh_region_start ();
1883 expand_expr_stmt (TREE_OPERAND (exp, 0));
1884 expand_start_all_catch ();
1885 has_finally_p = (TREE_OPERAND (exp, 2) ? 1 : 0);
1887 /* Expand all catch clauses (EH handlers) */
1888 for (current = TREE_OPERAND (exp, 1); current;
1889 current = TREE_CHAIN (current))
1891 extern rtx return_label;
1893 /* If we have a finally, the last exception handler is the
1894 one that is supposed to catch everything. */
1895 if (has_finally_p && !TREE_CHAIN (current))
1899 tree catch = java_get_catch_block (current, has_finally_p);
1900 tree decl = BLOCK_EXPR_DECLS (catch);
1901 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
1903 start_catch_handler (prepare_eh_table_type (type));
1904 expand_expr_stmt (TREE_OPERAND (current, 0));
1906 /* Need to expand a goto to the end of the function here,
1907 but not for the catch everything handler. */
1911 emit_jump (return_label);
1913 fatal ("No return_label for this function - "
1914 "java_lang_expand_expr");
1916 end_catch_handler ();
1919 /* Expand the finally block, if any */
1922 tree finally = TREE_OPERAND (exp, 2);
1923 if (FINALLY_EXPR_LABEL (finally))
1924 emit_label (label_rtx (FINALLY_EXPR_LABEL (finally)));
1925 expand_expr_stmt (FINALLY_EXPR_BLOCK (finally));
1927 expand_end_all_catch ();
1931 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
1932 tree_code_name [TREE_CODE (exp)]);
1937 expand_byte_code (jcf, method)
1944 unsigned char *linenumber_pointer;
1945 struct eh_range *prev_eh_ranges = NULL_EH_RANGE;
1946 struct eh_range *eh_ranges;
1948 #undef RET /* Defined by config/i386/i386.h */
1949 #undef AND /* Causes problems with opcodes for iand and land. */
1951 #define BCODE byte_ops
1952 #define BYTE_type_node byte_type_node
1953 #define SHORT_type_node short_type_node
1954 #define INT_type_node int_type_node
1955 #define LONG_type_node long_type_node
1956 #define CHAR_type_node char_type_node
1957 #define PTR_type_node ptr_type_node
1958 #define FLOAT_type_node float_type_node
1959 #define DOUBLE_type_node double_type_node
1960 #define VOID_type_node void_type_node
1962 unsigned char* byte_ops;
1963 long length = DECL_CODE_LENGTH (method);
1966 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
1967 byte_ops = jcf->read_ptr;
1969 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1970 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1971 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
1972 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
1974 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
1976 instruction_bits = oballoc (length + 1);
1977 bzero (instruction_bits, length + 1);
1979 /* We make an initial pass of the line number table, to note
1980 which instructions have associated line number entries. */
1981 linenumber_pointer = linenumber_table;
1982 for (i = 0; i < linenumber_count; i++)
1984 int pc = GET_u2 (linenumber_pointer);
1985 linenumber_pointer += 4;
1987 warning ("invalid PC in line number table");
1990 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
1991 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
1992 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
1996 /* Do a preliminary pass.
1997 * This figures out which PC can be the targets of jumps. */
1998 for (PC = 0; PC < length;)
2000 int oldpc = PC; /* PC at instruction start. */
2001 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2002 switch (byte_ops[PC++])
2004 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2006 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2009 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2011 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2012 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2013 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2014 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2015 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2016 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2017 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2018 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2020 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2021 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2022 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2023 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2024 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2025 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2026 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2027 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2029 /* two forms of wide instructions */
2030 #define PRE_SPECIAL_WIDE(IGNORE) \
2032 int modified_opcode = IMMEDIATE_u1; \
2033 if (modified_opcode == OPCODE_iinc) \
2035 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2036 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2040 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2044 /* nothing */ /* XXX JH */
2046 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2048 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2050 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2051 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2052 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2053 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2054 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2055 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2056 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2057 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2058 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2059 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2061 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2062 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2063 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2064 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2065 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2066 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2067 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2068 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2070 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2072 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2073 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2075 #define PRE_LOOKUP_SWITCH \
2076 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2077 NOTE_LABEL (default_offset+oldpc); \
2079 while (--npairs >= 0) { \
2080 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2081 NOTE_LABEL (offset+oldpc); } \
2084 #define PRE_TABLE_SWITCH \
2085 { jint default_offset = IMMEDIATE_s4; \
2086 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2087 NOTE_LABEL (default_offset+oldpc); \
2089 while (low++ <= high) { \
2090 jint offset = IMMEDIATE_s4; \
2091 NOTE_LABEL (offset+oldpc); } \
2094 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2095 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2096 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2097 (void)(IMMEDIATE_u2); \
2098 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2100 #include "javaop.def"
2105 if (! verify_jvm_instructions (jcf, byte_ops, length))
2108 /* Translate bytecodes to rtl instructions. */
2109 linenumber_pointer = linenumber_table;
2110 for (PC = 0; PC < length;)
2112 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2114 tree label = lookup_label (PC);
2115 flush_quick_stack ();
2116 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2117 expand_label (label);
2118 if (LABEL_VERIFIED (label) || PC == 0)
2119 load_type_state (label);
2122 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2124 /* never executed - skip */
2125 warning ("Some bytecode operations (starting at pc %d) can never be executed", PC);
2127 && ! (instruction_bits [PC] & BCODE_VERIFIED))
2133 /* Handle possible line number entry for this PC.
2135 This code handles out-of-order and multiple linenumbers per PC,
2136 but is optimized for the case of line numbers increasing
2137 monotonically with PC. */
2138 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2140 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2141 || GET_u2 (linenumber_pointer) != PC)
2142 linenumber_pointer = linenumber_table;
2143 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2145 int pc = GET_u2 (linenumber_pointer);
2146 linenumber_pointer += 4;
2149 lineno = GET_u2 (linenumber_pointer - 2);
2150 emit_line_note (input_filename, lineno);
2151 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2156 maybe_start_try (PC);
2157 maybe_pushlevels (PC);
2159 PC = process_jvm_instruction (PC, byte_ops, length);
2161 maybe_poplevels (PC);
2167 java_push_constant_from_pool (jcf, index)
2172 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2175 push_obstacks (&permanent_obstack, &permanent_obstack);
2176 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2177 index = alloc_name_constant (CONSTANT_String, name);
2178 c = build_ref_from_constant_pool (index);
2179 TREE_TYPE (c) = promote_type (string_type_node);
2183 c = get_constant (jcf, index);
2188 process_jvm_instruction (PC, byte_ops, length)
2190 unsigned char* byte_ops;
2193 char *opname; /* Temporary ??? */
2194 int oldpc = PC; /* PC at instruction start. */
2196 /* If the instruction is at the beginning of a exception handler,
2197 replace the top of the stack with the thrown object reference */
2198 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2200 pop_value (ptr_type_node);
2201 push_value (soft_exceptioninfo_call_node);
2204 switch (byte_ops[PC++])
2206 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2209 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2212 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2214 int saw_index = 0; \
2215 int index = OPERAND_VALUE; \
2216 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2219 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2221 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2222 tree ret = lookup_label (PC); \
2223 build_java_jsr (where, ret); \
2224 load_type_state (ret); \
2227 /* Push a constant onto the stack. */
2228 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2229 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2230 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2231 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2233 /* internal macro added for use by the WIDE case */
2234 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2235 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2237 /* Push local variable onto the opcode stack. */
2238 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2240 /* have to do this since OPERAND_VALUE may have side-effects */ \
2241 int opvalue = OPERAND_VALUE; \
2242 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2245 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2246 expand_java_return (OPERAND_TYPE##_type_node)
2248 #define REM_EXPR TRUNC_MOD_EXPR
2249 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2250 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2252 #define FIELD(IS_STATIC, IS_PUT) \
2253 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2255 #define TEST(OPERAND_TYPE, CONDITION) \
2256 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2258 #define COND(OPERAND_TYPE, CONDITION) \
2259 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2261 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2262 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2264 #define BRANCH_GOTO(OPERAND_VALUE) \
2265 expand_java_goto (oldpc + OPERAND_VALUE)
2267 #define BRANCH_CALL(OPERAND_VALUE) \
2268 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2271 #define BRANCH_RETURN(OPERAND_VALUE) \
2273 tree type = OPERAND_TYPE##_type_node; \
2274 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2275 expand_java_ret (value); \
2279 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2280 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2281 fprintf (stderr, "(not implemented)\n")
2282 #define NOT_IMPL1(OPERAND_VALUE) \
2283 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2284 fprintf (stderr, "(not implemented)\n")
2286 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2288 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2290 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2292 #define STACK_SWAP(COUNT) java_stack_swap()
2294 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2295 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2296 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2298 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2299 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2301 #define LOOKUP_SWITCH \
2302 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2303 tree selector = pop_value (INT_type_node); \
2304 tree duplicate, label; \
2305 tree type = TREE_TYPE (selector); \
2306 flush_quick_stack (); \
2307 expand_start_case (0, selector, type, "switch statement");\
2308 push_momentary (); \
2309 while (--npairs >= 0) \
2311 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2312 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2313 TREE_TYPE (value) = type; \
2314 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2315 pushcase (value, convert, label, &duplicate); \
2316 expand_java_goto (oldpc + offset); \
2318 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2319 pushcase (NULL_TREE, 0, label, &duplicate); \
2320 expand_java_goto (oldpc + default_offset); \
2322 expand_end_case (selector); \
2325 #define TABLE_SWITCH \
2326 { jint default_offset = IMMEDIATE_s4; \
2327 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2328 tree selector = pop_value (INT_type_node); \
2329 tree duplicate, label; \
2330 tree type = TREE_TYPE (selector); \
2331 flush_quick_stack (); \
2332 expand_start_case (0, selector, type, "switch statement");\
2333 push_momentary (); \
2334 for (; low <= high; low++) \
2336 jint offset = IMMEDIATE_s4; \
2337 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2338 TREE_TYPE (value) = type; \
2339 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2340 pushcase (value, convert, label, &duplicate); \
2341 expand_java_goto (oldpc + offset); \
2343 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2344 pushcase (NULL_TREE, 0, label, &duplicate); \
2345 expand_java_goto (oldpc + default_offset); \
2347 expand_end_case (selector); \
2350 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2351 { int opcode = byte_ops[PC-1]; \
2352 int method_ref_index = IMMEDIATE_u2; \
2354 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2356 expand_invoke (opcode, method_ref_index, nargs); \
2359 /* Handle new, checkcast, instanceof */
2360 #define OBJECT(TYPE, OP) \
2361 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2363 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2365 #define ARRAY_LOAD(OPERAND_TYPE) \
2367 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2370 #define ARRAY_STORE(OPERAND_TYPE) \
2372 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2375 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2376 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2377 #define ARRAY_NEW_PTR() \
2378 push_value (build_anewarray (get_class_constant (current_jcf, \
2380 pop_value (int_type_node)));
2381 #define ARRAY_NEW_NUM() \
2383 int atype = IMMEDIATE_u1; \
2384 push_value (build_newarray (atype, pop_value (int_type_node)));\
2386 #define ARRAY_NEW_MULTI() \
2388 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2389 int ndims = IMMEDIATE_u1; \
2390 expand_java_multianewarray( class, ndims ); \
2393 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2394 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2395 pop_value (OPERAND_TYPE##_type_node))));
2397 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2399 push_value (build1 (NOP_EXPR, int_type_node, \
2400 (convert (TO_TYPE##_type_node, \
2401 pop_value (FROM_TYPE##_type_node))))); \
2404 #define CONVERT(FROM_TYPE, TO_TYPE) \
2406 push_value (convert (TO_TYPE##_type_node, \
2407 pop_value (FROM_TYPE##_type_node))); \
2410 /* internal macro added for use by the WIDE case
2411 Added TREE_TYPE (decl) assignment, apbianco */
2412 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2415 int var = OPVALUE; \
2416 tree type = OPTYPE; \
2417 value = pop_value (type); \
2418 type = TREE_TYPE (value); \
2419 decl = find_local_variable (var, type, oldpc); \
2420 set_local_type (var, type ); \
2421 expand_assignment (decl, value, 0, 0); \
2424 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2426 /* have to do this since OPERAND_VALUE may have side-effects */ \
2427 int opvalue = OPERAND_VALUE; \
2428 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2431 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2432 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2434 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2435 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2437 #define MONITOR_OPERATION(call) \
2439 tree o = pop_value (ptr_type_node); \
2441 flush_quick_stack (); \
2442 c = build_java_monitor (call, o); \
2443 TREE_SIDE_EFFECTS (c) = 1; \
2444 expand_expr_stmt (c); \
2447 #define SPECIAL_IINC(IGNORED) \
2449 unsigned int local_var_index = IMMEDIATE_u1; \
2450 int ival = IMMEDIATE_s1; \
2451 expand_iinc(local_var_index, ival, oldpc); \
2454 #define SPECIAL_WIDE(IGNORED) \
2456 int modified_opcode = IMMEDIATE_u1; \
2457 unsigned int local_var_index = IMMEDIATE_u2; \
2458 switch (modified_opcode) \
2462 int ival = IMMEDIATE_s2; \
2463 expand_iinc (local_var_index, ival, oldpc); \
2466 case OPCODE_iload: \
2467 case OPCODE_lload: \
2468 case OPCODE_fload: \
2469 case OPCODE_dload: \
2470 case OPCODE_aload: \
2472 /* duplicate code from LOAD macro */ \
2473 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2476 case OPCODE_istore: \
2477 case OPCODE_lstore: \
2478 case OPCODE_fstore: \
2479 case OPCODE_dstore: \
2480 case OPCODE_astore: \
2482 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2486 error ("unrecogized wide sub-instruction"); \
2490 #define SPECIAL_THROW(IGNORED) \
2491 build_java_athrow (pop_value (throwable_type_node))
2493 #define SPECIAL_BREAK NOT_IMPL1
2494 #define IMPL NOT_IMPL
2496 #include "javaop.def"
2499 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);