* ggc-common.c (ggc_print_statistics): Make arguments to fprintf
[official-gcc.git] / gcc / java / expr.c
blob48d514644fb21472e77bb1ccaf434afc3cc651fe
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)
9 any later version.
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. */
27 #include "config.h"
28 #include "system.h"
29 #include "tree.h"
30 #include "real.h"
31 #include "rtl.h"
32 #include "flags.h"
33 #include "expr.h"
34 #include "java-tree.h"
35 #include "javaop.h"
36 #include "java-opcodes.h"
37 #include "jcf.h"
38 #include "java-except.h"
39 #include "parse.h"
40 #include "toplev.h"
41 #include "except.h"
42 #include "defaults.h"
44 static void flush_quick_stack PROTO ((void));
45 static void push_value PROTO ((tree));
46 static tree pop_value PROTO ((tree));
47 static void java_stack_swap PROTO ((void));
48 static void java_stack_dup PROTO ((int, int));
49 static void build_java_athrow PROTO ((tree));
50 static void build_java_jsr PROTO ((tree, tree));
51 static void build_java_ret PROTO ((tree));
52 static void expand_java_multianewarray PROTO ((tree, int));
53 static void expand_java_arraystore PROTO ((tree));
54 static void expand_java_arrayload PROTO ((tree));
55 static void expand_java_array_length PROTO ((void));
56 static tree build_java_monitor PROTO ((tree, tree));
57 static void expand_java_pushc PROTO ((int, tree));
58 static void expand_java_return PROTO ((tree));
59 static void expand_java_NEW PROTO ((tree));
60 static void expand_java_INSTANCEOF PROTO ((tree));
61 static void expand_java_CHECKCAST PROTO ((tree));
62 static void expand_iinc PROTO ((unsigned int, int, int));
63 static void expand_java_binop PROTO ((tree, enum tree_code));
64 static void note_label PROTO ((int, int));
65 static void expand_compare PROTO ((enum tree_code, tree, tree, int));
66 static void expand_test PROTO ((enum tree_code, tree, int));
67 static void expand_cond PROTO ((enum tree_code, tree, int));
68 static void expand_java_goto PROTO ((int));
69 #if 0
70 static void expand_java_call PROTO ((int, int));
71 static void expand_java_ret PROTO ((tree));
72 #endif
73 static tree pop_arguments PROTO ((tree));
74 static void expand_invoke PROTO ((int, int, int));
75 static void expand_java_field_op PROTO ((int, int, int));
76 static void java_push_constant_from_pool PROTO ((struct JCF *, int));
77 static void java_stack_pop PROTO ((int));
78 static tree build_java_throw_out_of_bounds_exception PROTO ((tree));
79 static tree build_java_check_indexed_type PROTO ((tree, tree));
80 static tree java_array_data_offset PROTO ((tree));
81 static tree case_identity PROTO ((tree, tree));
83 static tree operand_type[59];
84 extern struct obstack permanent_obstack;
86 void
87 init_expr_processing()
89 operand_type[21] = operand_type[54] = int_type_node;
90 operand_type[22] = operand_type[55] = long_type_node;
91 operand_type[23] = operand_type[56] = float_type_node;
92 operand_type[24] = operand_type[57] = double_type_node;
93 operand_type[25] = operand_type[58] = ptr_type_node;
96 /* We store the stack state in two places:
97 Within a basic block, we use the quick_stack, which is a
98 pushdown list (TREE_LISTs) of expression nodes.
99 This is the top part of the stack; below that we use find_stack_slot.
100 At the end of a basic block, the quick_stack must be flushed
101 to the stack slot array (as handled by find_stack_slot).
102 Using quick_stack generates better code (especially when
103 compiled without optimization), because we do not have to
104 explicitly store and load trees to temporary variables.
106 If a variable is on the quick stack, it means the value of variable
107 when the quick stack was last flushed. Conceptually, flush_quick_stack
108 saves all the the quick_stack elements in parellel. However, that is
109 complicated, so it actually saves them (i.e. copies each stack value
110 to is home virtual register) from low indexes. This allows a quick_stack
111 element at index i (counting from the bottom of stack the) to references
112 slot virtuals for register that are >= i, but not those that are deeper.
113 This convention makes most operations easier. For example iadd works
114 even when the stack contains (reg[0], reg[1]): It results in the
115 stack containing (reg[0]+reg[1]), which is OK. However, some stack
116 operations are more complicated. For example dup given a stack
117 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
118 the convention, since stack value 1 would refer to a register with
119 lower index (reg[0]), which flush_quick_stack does not safely handle.
120 So dup cannot just add an extra element to the quick_stack, but iadd can.
123 tree quick_stack = NULL_TREE;
125 /* A free-list of unused permamnet TREE_LIST nodes. */
126 tree tree_list_free_list = NULL_TREE;
128 /* The stack pointer of the Java virtual machine.
129 This does include the size of the quick_stack. */
131 int stack_pointer;
133 const unsigned char *linenumber_table;
134 int linenumber_count;
136 tree
137 truthvalue_conversion (expr)
138 tree expr;
140 /* It is simpler and generates better code to have only TRUTH_*_EXPR
141 or comparison expressions as truth values at this level.
143 This function should normally be identity for Java. */
145 switch (TREE_CODE (expr))
147 case EQ_EXPR:
148 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
149 case TRUTH_ANDIF_EXPR:
150 case TRUTH_ORIF_EXPR:
151 case TRUTH_AND_EXPR:
152 case TRUTH_OR_EXPR:
153 case ERROR_MARK:
154 return expr;
156 case INTEGER_CST:
157 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
159 case REAL_CST:
160 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
162 /* are these legal? XXX JH */
163 case NEGATE_EXPR:
164 case ABS_EXPR:
165 case FLOAT_EXPR:
166 case FFS_EXPR:
167 /* These don't change whether an object is non-zero or zero. */
168 return truthvalue_conversion (TREE_OPERAND (expr, 0));
170 case COND_EXPR:
171 /* Distribute the conversion into the arms of a COND_EXPR. */
172 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
173 truthvalue_conversion (TREE_OPERAND (expr, 1)),
174 truthvalue_conversion (TREE_OPERAND (expr, 2))));
176 case NOP_EXPR:
177 /* If this is widening the argument, we can ignore it. */
178 if (TYPE_PRECISION (TREE_TYPE (expr))
179 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
180 return truthvalue_conversion (TREE_OPERAND (expr, 0));
181 /* fall through to default */
183 default:
184 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
188 #ifdef JAVA_USE_HANDLES
189 /* Given a pointer to a handle, get a pointer to an object. */
191 tree
192 unhand_expr (expr)
193 tree expr;
195 tree field, handle_type;
196 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
197 handle_type = TREE_TYPE (expr);
198 field = TYPE_FIELDS (handle_type);
199 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
200 return expr;
202 #endif
204 /* Save any stack slots that happen to be in the quick_stack into their
205 home virtual register slots.
207 The copy order is from low stack index to high, to support the invariant
208 that the expression for a slot may contain decls for stack slots with
209 higher (or the same) index, but not lower. */
211 static void
212 flush_quick_stack ()
214 int stack_index = stack_pointer;
215 register tree prev, cur, next;
217 /* First reverse the quick_stack, and count the number of slots it has. */
218 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
220 next = TREE_CHAIN (cur);
221 TREE_CHAIN (cur) = prev;
222 prev = cur;
223 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
225 quick_stack = prev;
227 while (quick_stack != NULL_TREE)
229 tree decl;
230 tree node = quick_stack, type;
231 quick_stack = TREE_CHAIN (node);
232 TREE_CHAIN (node) = tree_list_free_list;
233 tree_list_free_list = node;
234 node = TREE_VALUE (node);
235 type = TREE_TYPE (node);
237 decl = find_stack_slot (stack_index, type);
238 if (decl != node)
239 expand_assignment (decl, node, 0, 0);
240 stack_index += 1 + TYPE_IS_WIDE (type);
244 void
245 push_type (type)
246 tree type;
248 int n_words;
249 type = promote_type (type);
250 n_words = 1 + TYPE_IS_WIDE (type);
251 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
252 fatal ("stack overflow");
253 stack_type_map[stack_pointer++] = type;
254 n_words--;
255 while (--n_words >= 0)
256 stack_type_map[stack_pointer++] = TYPE_SECOND;
259 static void
260 push_value (value)
261 tree value;
263 tree type = TREE_TYPE (value);
264 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
266 type = promote_type (type);
267 value = convert (type, value);
269 push_type (type);
270 if (tree_list_free_list == NULL_TREE)
271 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
272 else
274 tree node = tree_list_free_list;
275 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
276 TREE_VALUE (node) = value;
277 TREE_CHAIN (node) = quick_stack;
278 quick_stack = node;
282 /* Pop a type from the type stack.
283 TYPE is the expected type. Return the actual type, which must be
284 convertible to TYPE, otherwise NULL_TREE is returned. */
286 tree
287 pop_type_0 (type)
288 tree type;
290 int n_words;
291 tree t;
292 if (TREE_CODE (type) == RECORD_TYPE)
293 type = promote_type (type);
294 n_words = 1 + TYPE_IS_WIDE (type);
295 if (stack_pointer < n_words)
296 fatal ("stack underflow");
297 while (--n_words > 0)
299 if (stack_type_map[--stack_pointer] != void_type_node)
300 fatal ("Invalid multi-word value on type stack");
302 t = stack_type_map[--stack_pointer];
303 if (type == NULL_TREE || t == type)
304 return t;
305 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
306 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
307 return t;
308 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
310 if (type == ptr_type_node || type == object_ptr_type_node)
311 return t;
312 else if (t == ptr_type_node) /* Special case for null reference. */
313 return type;
314 else if (can_widen_reference_to (t, type))
315 return t;
316 /* This is a kludge, but matches what Sun's verifier does.
317 It can be tricked, but is safe as long as type errors
318 (i.e. interface method calls) are caught at run-time. */
319 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
320 && t == object_ptr_type_node)
321 return t;
323 return NULL_TREE;
326 /* Pop a type from the type stack.
327 TYPE is the expected type. Return the actual type, which must be
328 convertible to TYPE, otherwise call error. */
330 tree
331 pop_type (type)
332 tree type;
334 tree t = pop_type_0 (type);
335 if (t != NULL_TREE)
336 return t;
337 error ("unexpected type on stack");
338 return type;
341 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
342 Handles array types and interfaces. */
345 can_widen_reference_to (source_type, target_type)
346 tree source_type, target_type;
348 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
349 return 1;
351 /* Get rid of pointers */
352 if (TREE_CODE (source_type) == POINTER_TYPE)
353 source_type = TREE_TYPE (source_type);
354 if (TREE_CODE (target_type) == POINTER_TYPE)
355 target_type = TREE_TYPE (target_type);
357 if (source_type == target_type)
358 return 1;
359 else
361 source_type = HANDLE_TO_CLASS_TYPE (source_type);
362 target_type = HANDLE_TO_CLASS_TYPE (target_type);
363 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
365 HOST_WIDE_INT source_length, target_length;
366 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
367 return 0;
368 target_length = java_array_type_length (target_type);
369 if (target_length >= 0)
371 source_length = java_array_type_length (source_type);
372 if (source_length != target_length)
373 return 0;
375 source_type = TYPE_ARRAY_ELEMENT (source_type);
376 target_type = TYPE_ARRAY_ELEMENT (target_type);
377 if (source_type == target_type)
378 return 1;
379 if (TREE_CODE (source_type) != POINTER_TYPE
380 || TREE_CODE (target_type) != POINTER_TYPE)
381 return 0;
382 return can_widen_reference_to (source_type, target_type);
384 else
386 int source_depth = class_depth (source_type);
387 int target_depth = class_depth (target_type);
389 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
391 /* target_type is OK if source_type or source_type ancestors
392 implement target_type. We handle multiple sub-interfaces */
394 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
395 int n = TREE_VEC_LENGTH (basetype_vec), i;
396 for (i=0 ; i < n; i++)
397 if (can_widen_reference_to
398 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
399 target_type))
400 return 1;
401 if (n == 0)
402 return 0;
405 for ( ; source_depth > target_depth; source_depth--)
407 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
409 return source_type == target_type;
414 static tree
415 pop_value (type)
416 tree type;
418 type = pop_type (type);
419 if (quick_stack)
421 tree node = quick_stack;
422 quick_stack = TREE_CHAIN (quick_stack);
423 TREE_CHAIN (node) = tree_list_free_list;
424 tree_list_free_list = node;
425 node = TREE_VALUE (node);
426 return node;
428 else
429 return find_stack_slot (stack_pointer, promote_type (type));
433 /* Pop and discrad the top COUNT stack slots. */
435 static void
436 java_stack_pop (count)
437 int count;
439 while (count > 0)
441 tree type, val;
442 if (stack_pointer == 0)
443 fatal ("stack underflow");
444 type = stack_type_map[stack_pointer - 1];
445 if (type == TYPE_SECOND)
447 count--;
448 if (stack_pointer == 1 || count <= 0)
449 fatal ("stack underflow");
450 type = stack_type_map[stack_pointer - 2];
452 val = pop_value (type);
453 count--;
457 /* Implement the 'swap' operator (to swap two top stack slots). */
459 static void
460 java_stack_swap ()
462 tree type1, type2;
463 rtx temp;
464 tree decl1, decl2;
466 if (stack_pointer < 2
467 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
468 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
469 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
470 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
471 fatal ("bad stack swap");
473 flush_quick_stack ();
474 decl1 = find_stack_slot (stack_pointer - 1, type1);
475 decl2 = find_stack_slot (stack_pointer - 2, type2);
476 temp = copy_to_reg (DECL_RTL (decl1));
477 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
478 emit_move_insn (DECL_RTL (decl2), temp);
479 stack_type_map[stack_pointer - 1] = type2;
480 stack_type_map[stack_pointer - 2] = type1;
483 static void
484 java_stack_dup (size, offset)
485 int size, offset;
487 int low_index = stack_pointer - size - offset;
488 int dst_index;
489 if (low_index < 0)
490 error ("stack underflow - dup* operation");
492 flush_quick_stack ();
494 stack_pointer += size;
495 dst_index = stack_pointer;
497 for (dst_index = stack_pointer; --dst_index >= low_index; )
499 tree type;
500 int src_index = dst_index - size;
501 if (src_index < low_index)
502 src_index = dst_index + size + offset;
503 type = stack_type_map [src_index];
504 if (type == TYPE_SECOND)
506 if (src_index <= low_index)
507 fatal ("dup operation splits 64-bit number");
508 stack_type_map[dst_index] = type;
509 src_index--; dst_index--;
510 type = stack_type_map[src_index];
511 if (! TYPE_IS_WIDE (type))
512 fatal ("internal error - dup operation");
514 else if (TYPE_IS_WIDE (type))
515 fatal ("internal error - dup operation");
516 if (src_index != dst_index)
518 tree src_decl = find_stack_slot (src_index, type);
519 tree dst_decl = find_stack_slot (dst_index, type);
520 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
521 stack_type_map[dst_index] = type;
526 /* Calls _Jv_Throw. Discard the contents of the value stack. */
528 static void
529 build_java_athrow (node)
530 tree node;
532 tree call;
534 call = build (CALL_EXPR,
535 void_type_node,
536 build_address_of (throw_node),
537 build_tree_list (NULL_TREE, node),
538 NULL_TREE);
539 TREE_SIDE_EFFECTS (call) = 1;
540 expand_expr_stmt (call);
541 java_stack_pop (stack_pointer);
544 /* Implementation for jsr/ret */
546 static void
547 build_java_jsr (where, ret)
548 tree where;
549 tree ret;
551 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
552 push_value (ret_label);
553 flush_quick_stack ();
554 expand_goto (where);
555 expand_label (ret);
558 static void
559 build_java_ret (location)
560 tree location;
562 expand_computed_goto (location);
565 /* Implementation of operations on array: new, load, store, length */
567 /* Array core info access macros */
569 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
570 size_binop (CEIL_DIV_EXPR, \
571 (DECL_FIELD_BITPOS \
572 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
573 size_int (BITS_PER_UNIT))
575 tree
576 decode_newarray_type (atype)
577 int atype;
579 switch (atype)
581 case 4: return boolean_type_node;
582 case 5: return char_type_node;
583 case 6: return float_type_node;
584 case 7: return double_type_node;
585 case 8: return byte_type_node;
586 case 9: return short_type_node;
587 case 10: return int_type_node;
588 case 11: return long_type_node;
589 default: return NULL_TREE;
593 /* Map primitive type to the code used by OPCODE_newarray. */
596 encode_newarray_type (type)
597 tree type;
599 if (type == boolean_type_node)
600 return 4;
601 else if (type == char_type_node)
602 return 5;
603 else if (type == float_type_node)
604 return 6;
605 else if (type == double_type_node)
606 return 7;
607 else if (type == byte_type_node)
608 return 8;
609 else if (type == short_type_node)
610 return 9;
611 else if (type == int_type_node)
612 return 10;
613 else if (type == long_type_node)
614 return 11;
615 else
616 fatal ("Can't compute type code - patch_newarray");
619 /* Build a call to _Jv_ThrowBadArrayIndex(), the
620 ArrayIndexOfBoundsException exception handler. */
622 static tree
623 build_java_throw_out_of_bounds_exception (index)
624 tree index;
626 tree node = build (CALL_EXPR, int_type_node,
627 build_address_of (soft_badarrayindex_node),
628 build_tree_list (NULL_TREE, index), NULL_TREE);
629 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
630 return (node);
633 /* Return the length of an array. Doesn't perform any checking on the nature
634 or value of the array NODE. May be used to implement some bytecodes. */
636 tree
637 build_java_array_length_access (node)
638 tree node;
640 tree type = TREE_TYPE (node);
641 HOST_WIDE_INT length;
642 if (!is_array_type_p (type))
643 fatal ("array length on a non-array reference");
644 length = java_array_type_length (type);
645 if (length >= 0)
646 return build_int_2 (length, 0);
647 return fold (build1 (INDIRECT_REF,
648 int_type_node,
649 fold (build (PLUS_EXPR, ptr_type_node,
650 node,
651 JAVA_ARRAY_LENGTH_OFFSET(node)))));
654 /* Optionally checks an array against the NULL pointer, eventually throwing a
655 NullPointerException. It could replace signal handling, but tied to NULL.
656 ARG1: the pointer to check, ARG2: the expression to use if
657 the pointer is non-null and ARG3 the type that should be returned. */
659 tree
660 build_java_arraynull_check (node, expr, type)
661 tree node ATTRIBUTE_UNUSED;
662 tree expr;
663 tree type ATTRIBUTE_UNUSED;
665 #if 0
666 static int java_array_access_throws_null_exception = 0;
667 node = ???;
668 if (java_array_access_throws_null_exception)
669 return (build (COND_EXPR,
670 type,
671 build (EQ_EXPR, int_type_node, node, null_pointer_node),
672 build_java_athrow (node), expr ));
673 else
674 #endif
675 return (expr);
678 static tree
679 java_array_data_offset (array)
680 tree array;
682 tree array_type = TREE_TYPE (TREE_TYPE (array));
683 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
684 if (data_fld == NULL_TREE)
685 return size_in_bytes (array_type);
686 else
687 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
688 / BITS_PER_UNIT, 0);
691 /* Implement array indexing (either as l-value or r-value).
692 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
693 Optionally performs bounds checking and/or test to NULL.
694 At this point, ARRAY should have been verified as an array. */
696 tree
697 build_java_arrayaccess (array, type, index)
698 tree array, type, index;
700 tree arith, node, throw = NULL_TREE;
702 arith = fold (build (PLUS_EXPR, int_type_node,
703 java_array_data_offset (array),
704 fold (build (MULT_EXPR, int_type_node,
705 index, size_in_bytes(type)))));
707 if (flag_bounds_check)
709 /* Generate:
710 * (unsigned jint) INDEX >= (unsigned jint) LEN
711 * && throw ArrayIndexOutOfBoundsException.
712 * Note this is equivalent to and more efficient than:
713 * INDEX < 0 || INDEX >= LEN && throw ... */
714 tree test;
715 tree len = build_java_array_length_access (array);
716 TREE_TYPE (len) = unsigned_int_type_node;
717 test = fold (build (GE_EXPR, boolean_type_node,
718 convert (unsigned_int_type_node, index),
719 len));
720 if (! integer_zerop (test))
722 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
723 build_java_throw_out_of_bounds_exception (index));
724 /* allows expansion within COMPOUND */
725 TREE_SIDE_EFFECTS( throw ) = 1;
729 node = build1 (INDIRECT_REF, type,
730 fold (build (PLUS_EXPR, ptr_type_node,
731 array,
732 (throw ? build (COMPOUND_EXPR, int_type_node,
733 throw, arith )
734 : arith))));
736 return (fold (build_java_arraynull_check (array, node, type)));
739 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
740 ARRAY_NODE. This function is used to retrieve something less vague than
741 a pointer type when indexing the first dimension of something like [[<t>.
742 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
743 return unchanged.
744 As a side effect, it also makes sure that ARRAY_NODE is an array. */
746 static tree
747 build_java_check_indexed_type (array_node, indexed_type)
748 tree array_node;
749 tree indexed_type;
751 tree elt_type;
753 if (!is_array_type_p (TREE_TYPE (array_node)))
754 fatal ("array indexing on a non-array reference");
756 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
758 if (indexed_type == ptr_type_node )
759 return promote_type (elt_type);
761 /* BYTE/BOOLEAN store and load are used for both type */
762 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
763 return boolean_type_node;
765 if (indexed_type != elt_type )
766 fatal ("type array element mismatch");
767 else
768 return indexed_type;
771 /* newarray triggers a call to _Jv_NewArray. This function should be called
772 with an integer code (the type of array to create) and get from the stack
773 the size of the dimmension. */
775 tree
776 build_newarray (atype_value, length)
777 int atype_value;
778 tree length;
780 tree type = build_java_array_type (decode_newarray_type (atype_value),
781 TREE_CODE (length) == INTEGER_CST
782 ? TREE_INT_CST_LOW (length)
783 : -1);
784 return build (CALL_EXPR, promote_type (type),
785 build_address_of (soft_newarray_node),
786 tree_cons (NULL_TREE,
787 build_int_2 (atype_value, 0),
788 build_tree_list (NULL_TREE, length)),
789 NULL_TREE);
792 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
793 of the dimension. */
795 tree
796 build_anewarray (class_type, length)
797 tree class_type;
798 tree length;
800 tree type = build_java_array_type (class_type,
801 TREE_CODE (length) == INTEGER_CST
802 ? TREE_INT_CST_LOW (length)
803 : -1);
804 return build (CALL_EXPR, promote_type (type),
805 build_address_of (soft_anewarray_node),
806 tree_cons (NULL_TREE, length,
807 tree_cons (NULL_TREE, build_class_ref (class_type),
808 build_tree_list (NULL_TREE,
809 null_pointer_node))),
810 NULL_TREE);
813 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
815 tree
816 build_new_array (type, length)
817 tree type;
818 tree length;
820 if (JPRIMITIVE_TYPE_P (type))
821 return build_newarray (encode_newarray_type (type), length);
822 else
823 return build_anewarray (TREE_TYPE (type), length);
826 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
827 class pointer, a number of dimensions and the matching number of
828 dimensions. The argument list is NULL terminated. */
830 static void
831 expand_java_multianewarray (class_type, ndim)
832 tree class_type;
833 int ndim;
835 int i;
836 tree args = build_tree_list( NULL_TREE, null_pointer_node );
838 for( i = 0; i < ndim; i++ )
839 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
841 push_value (build (CALL_EXPR,
842 promote_type (class_type),
843 build_address_of (soft_multianewarray_node),
844 tree_cons (NULL_TREE, build_class_ref (class_type),
845 tree_cons (NULL_TREE,
846 build_int_2 (ndim, 0), args )),
847 NULL_TREE));
850 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
851 ARRAY is an array type. May expand some bound checking and NULL
852 pointer checking. RHS_TYPE_NODE we are going to store. In the case
853 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
854 INT. In those cases, we make the convertion.
856 if ARRAy is a reference type, the assignment is checked at run-time
857 to make sure that the RHS can be assigned to the array element
858 type. It is not necessary to generate this code if ARRAY is final. */
860 static void
861 expand_java_arraystore (rhs_type_node)
862 tree rhs_type_node;
864 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
865 && TYPE_PRECISION (rhs_type_node) <= 32) ?
866 int_type_node : rhs_type_node);
867 tree index = pop_value (int_type_node);
868 tree array = pop_value (ptr_type_node);
870 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
872 flush_quick_stack ();
874 index = save_expr (index);
875 array = save_expr (array);
877 if (TREE_CODE (rhs_type_node) == POINTER_TYPE
878 && !CLASS_FINAL (TYPE_NAME (TREE_TYPE (rhs_type_node))))
880 tree check = build (CALL_EXPR, void_type_node,
881 build_address_of (soft_checkarraystore_node),
882 tree_cons (NULL_TREE, array,
883 build_tree_list (NULL_TREE, rhs_node)),
884 NULL_TREE);
885 TREE_SIDE_EFFECTS (check) = 1;
886 expand_expr_stmt (check);
889 expand_assignment (build_java_arrayaccess (array,
890 rhs_type_node,
891 index),
892 rhs_node, 0, 0);
895 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
896 sure that LHS is an array type. May expand some bound checking and NULL
897 pointer checking.
898 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
899 BOOLEAN/SHORT, we push a promoted type back to the stack.
902 static void
903 expand_java_arrayload (lhs_type_node )
904 tree lhs_type_node;
906 tree load_node;
907 tree index_node = pop_value (int_type_node);
908 tree array_node = pop_value (ptr_type_node);
910 index_node = save_expr (index_node);
911 array_node = save_expr (array_node);
912 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
914 load_node = build_java_arrayaccess (array_node,
915 lhs_type_node,
916 index_node);
918 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
919 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
920 push_value (load_node);
923 /* Expands .length. Makes sure that we deal with and array and may expand
924 a NULL check on the array object. */
926 static void
927 expand_java_array_length ()
929 tree array = pop_value (ptr_type_node);
930 tree length = build_java_array_length_access (array);
932 push_value (build_java_arraynull_check (array, length, int_type_node));
935 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
936 either soft_monitorenter_node or soft_monitorexit_node. */
938 static tree
939 build_java_monitor (call, object)
940 tree call;
941 tree object;
943 return (build (CALL_EXPR,
944 void_type_node,
945 build_address_of (call),
946 build_tree_list (NULL_TREE, object),
947 NULL_TREE));
950 /* Emit code for one of the PUSHC instructions. */
952 static void
953 expand_java_pushc (ival, type)
954 int ival;
955 tree type;
957 tree value;
958 if (type == ptr_type_node && ival == 0)
959 value = null_pointer_node;
960 else if (type == int_type_node || type == long_type_node)
962 value = build_int_2 (ival, ival < 0 ? -1 : 0);
963 TREE_TYPE (value) = type;
965 else if (type == float_type_node || type == double_type_node)
967 REAL_VALUE_TYPE x;
968 #ifdef REAL_ARITHMETIC
969 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
970 #else
971 x = ival;
972 #endif
973 value = build_real (type, x);
975 else
976 fatal ("internal error in expand_java_pushc");
977 push_value (value);
980 static void
981 expand_java_return (type)
982 tree type;
984 if (type == void_type_node)
985 expand_null_return ();
986 else
988 tree retval = pop_value (type);
989 tree res = DECL_RESULT (current_function_decl);
990 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
991 TREE_SIDE_EFFECTS (retval) = 1;
992 expand_return (retval);
996 tree
997 build_address_of (value)
998 tree value;
1000 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1003 static void
1004 expand_java_NEW (type)
1005 tree type;
1007 if (! CLASS_LOADED_P (type))
1008 load_class (type, 1);
1009 layout_class_methods (type);
1010 push_value (build (CALL_EXPR, promote_type (type),
1011 build_address_of (alloc_object_node),
1012 tree_cons (NULL_TREE, build_class_ref (type),
1013 build_tree_list (NULL_TREE,
1014 size_in_bytes (type))),
1015 NULL_TREE));
1018 static void
1019 expand_java_INSTANCEOF (type)
1020 tree type;
1022 tree value = pop_value (object_ptr_type_node);
1023 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
1024 build_address_of (soft_instanceof_node),
1025 tree_cons (NULL_TREE, value,
1026 build_tree_list (NULL_TREE,
1027 build_class_ref (type))),
1028 NULL_TREE);
1029 push_value (value);
1032 static void
1033 expand_java_CHECKCAST (type)
1034 tree type;
1036 tree value = pop_value (ptr_type_node);
1037 value = build (CALL_EXPR, promote_type (type),
1038 build_address_of (soft_checkcast_node),
1039 tree_cons (NULL_TREE, build_class_ref (type),
1040 build_tree_list (NULL_TREE, value)),
1041 NULL_TREE);
1042 push_value (value);
1045 static void
1046 expand_iinc (local_var_index, ival, pc)
1047 unsigned int local_var_index;
1048 int ival;
1049 int pc;
1051 tree local_var, res;
1052 tree constant_value;
1054 flush_quick_stack ();
1055 local_var = find_local_variable (local_var_index, int_type_node, pc);
1056 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1057 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1058 expand_assignment (local_var, res, 0, 0);
1062 tree
1063 build_java_soft_divmod (op, type, op1, op2)
1064 enum tree_code op;
1065 tree type, op1, op2;
1067 tree call = NULL;
1068 tree arg1 = convert (type, op1);
1069 tree arg2 = convert (type, op2);
1071 if (type == int_type_node)
1073 switch (op)
1075 case TRUNC_DIV_EXPR:
1076 call = soft_idiv_node;
1077 break;
1078 case TRUNC_MOD_EXPR:
1079 call = soft_irem_node;
1080 break;
1081 default:
1082 break;
1085 else if (type == long_type_node)
1087 switch (op)
1089 case TRUNC_DIV_EXPR:
1090 call = soft_ldiv_node;
1091 break;
1092 case TRUNC_MOD_EXPR:
1093 call = soft_lrem_node;
1094 break;
1095 default:
1096 break;
1100 if (! call)
1101 fatal ("Internal compiler error in build_java_soft_divmod");
1103 call = build (CALL_EXPR, type,
1104 build_address_of (call),
1105 tree_cons (NULL_TREE, arg1,
1106 build_tree_list (NULL_TREE, arg2)),
1107 NULL_TREE);
1109 return call;
1112 tree
1113 build_java_binop (op, type, arg1, arg2)
1114 enum tree_code op;
1115 tree type, arg1, arg2;
1117 tree mask;
1118 switch (op)
1120 case URSHIFT_EXPR:
1122 tree u_type = unsigned_type (type);
1123 arg1 = convert (u_type, arg1);
1124 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1125 return convert (type, arg1);
1127 case LSHIFT_EXPR:
1128 case RSHIFT_EXPR:
1129 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1130 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1131 break;
1133 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1134 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1135 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1137 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1138 boolean_type_node, arg1, arg2));
1139 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1140 tree second_compare = fold (build (COND_EXPR, int_type_node,
1141 ifexp2, integer_zero_node,
1142 op == COMPARE_L_EXPR
1143 ? integer_negative_one_node
1144 : integer_one_node));
1145 return fold (build (COND_EXPR, int_type_node, ifexp1,
1146 op == COMPARE_L_EXPR ? integer_one_node
1147 : integer_negative_one_node,
1148 second_compare));
1150 case COMPARE_EXPR:
1151 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1153 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1154 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1155 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1156 ifexp2, integer_one_node,
1157 integer_zero_node));
1158 return fold (build (COND_EXPR, int_type_node,
1159 ifexp1, integer_negative_one_node, second_compare));
1161 case TRUNC_DIV_EXPR:
1162 case TRUNC_MOD_EXPR:
1163 if (TREE_CODE (type) == REAL_TYPE
1164 && op == TRUNC_MOD_EXPR)
1166 tree call;
1167 if (type != double_type_node)
1169 arg1 = convert (double_type_node, arg1);
1170 arg2 = convert (double_type_node, arg2);
1172 call = build (CALL_EXPR, double_type_node,
1173 build_address_of (soft_fmod_node),
1174 tree_cons (NULL_TREE, arg1,
1175 build_tree_list (NULL_TREE, arg2)),
1176 NULL_TREE);
1177 if (type != double_type_node)
1178 call = convert (type, call);
1179 return call;
1182 if (TREE_CODE (type) == INTEGER_TYPE
1183 && flag_use_divide_subroutine
1184 && ! flag_syntax_only)
1185 return build_java_soft_divmod (op, type, arg1, arg2);
1187 break;
1188 default: ;
1190 return fold (build (op, type, arg1, arg2));
1193 static void
1194 expand_java_binop (type, op)
1195 tree type; enum tree_code op;
1197 tree larg, rarg;
1198 tree ltype = type;
1199 tree rtype = type;
1200 switch (op)
1202 case LSHIFT_EXPR:
1203 case RSHIFT_EXPR:
1204 case URSHIFT_EXPR:
1205 rtype = int_type_node;
1206 rarg = pop_value (rtype);
1207 break;
1208 default:
1209 rarg = pop_value (rtype);
1211 larg = pop_value (ltype);
1212 push_value (build_java_binop (op, type, larg, rarg));
1215 /* Lookup the field named NAME in *TYPEP or its super classes.
1216 If not found, return NULL_TREE.
1217 (If the *TYPEP is not found, return error_mark_node.)
1218 If found, return the FIELD_DECL, and set *TYPEP to the
1219 class containing the field. */
1221 tree
1222 lookup_field (typep, name)
1223 tree *typep;
1224 tree name;
1226 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1228 load_class (*typep, 1);
1229 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1230 return error_mark_node;
1234 tree field, basetype_vec;
1235 int n, i;
1237 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1238 if (DECL_NAME (field) == name)
1239 return field;
1241 /* Process implemented interfaces. */
1242 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1243 n = TREE_VEC_LENGTH (basetype_vec);
1244 for (i = 0; i < n; i++)
1246 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1247 if ((field = lookup_field (&t, name)))
1248 return field;
1250 *typep = CLASSTYPE_SUPER (*typep);
1251 } while (*typep);
1252 return NULL_TREE;
1255 /* Look up the field named NAME in object SELF_VALUE,
1256 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1257 SELF_VALUE is NULL_TREE if looking for a static field. */
1259 tree
1260 build_field_ref (self_value, self_class, name)
1261 tree self_value, self_class, name;
1263 tree base_class = self_class;
1264 tree field_decl = lookup_field (&base_class, name);
1265 if (field_decl == NULL_TREE)
1267 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1268 return error_mark_node;
1270 if (self_value == NULL_TREE)
1272 return build_static_field_ref (field_decl);
1274 else
1276 tree base_handle_type = promote_type (base_class);
1277 if (base_handle_type != TREE_TYPE (self_value))
1278 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1279 #ifdef JAVA_USE_HANDLES
1280 self_value = unhand_expr (self_value);
1281 #endif
1282 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1283 self_value);
1284 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1285 self_value, field_decl));
1289 tree
1290 lookup_label (pc)
1291 int pc;
1293 tree name;
1294 char buf[32];
1295 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1296 name = get_identifier (buf);
1297 if (IDENTIFIER_LOCAL_VALUE (name))
1298 return IDENTIFIER_LOCAL_VALUE (name);
1299 else
1301 /* The type of the address of a label is return_address_type_node. */
1302 tree decl = create_label_decl (name);
1303 LABEL_PC (decl) = pc;
1304 label_rtx (decl);
1305 return pushdecl (decl);
1309 /* Generate a unique name for the purpose of loops and switches
1310 labels, and try-catch-finally blocks label or temporary variables. */
1312 tree
1313 generate_name ()
1315 static int l_number = 0;
1316 char buff [32];
1317 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1318 l_number++;
1319 return get_identifier (buff);
1322 tree
1323 create_label_decl (name)
1324 tree name;
1326 tree decl;
1327 push_obstacks (&permanent_obstack, &permanent_obstack);
1328 decl = build_decl (LABEL_DECL, name,
1329 TREE_TYPE (return_address_type_node));
1330 pop_obstacks ();
1331 DECL_CONTEXT (decl) = current_function_decl;
1332 DECL_IGNORED_P (decl) = 1;
1333 return decl;
1336 /* This maps a bytecode offset (PC) to various flags. */
1337 char *instruction_bits;
1339 static void
1340 note_label (current_pc, target_pc)
1341 int current_pc ATTRIBUTE_UNUSED, target_pc;
1343 lookup_label (target_pc);
1344 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1347 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1348 where CONDITION is one of one the compare operators. */
1350 static void
1351 expand_compare (condition, value1, value2, target_pc)
1352 enum tree_code condition;
1353 tree value1, value2;
1354 int target_pc;
1356 tree target = lookup_label (target_pc);
1357 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1358 expand_start_cond (truthvalue_conversion (cond), 0);
1359 expand_goto (target);
1360 expand_end_cond ();
1363 /* Emit code for a TEST-type opcode. */
1365 static void
1366 expand_test (condition, type, target_pc)
1367 enum tree_code condition;
1368 tree type;
1369 int target_pc;
1371 tree value1, value2;
1372 flush_quick_stack ();
1373 value1 = pop_value (type);
1374 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1375 expand_compare (condition, value1, value2, target_pc);
1378 /* Emit code for a COND-type opcode. */
1380 static void
1381 expand_cond (condition, type, target_pc)
1382 enum tree_code condition;
1383 tree type;
1384 int target_pc;
1386 tree value1, value2;
1387 flush_quick_stack ();
1388 /* note: pop values in opposite order */
1389 value2 = pop_value (type);
1390 value1 = pop_value (type);
1391 /* Maybe should check value1 and value2 for type compatibility ??? */
1392 expand_compare (condition, value1, value2, target_pc);
1395 static void
1396 expand_java_goto (target_pc)
1397 int target_pc;
1399 tree target_label = lookup_label (target_pc);
1400 flush_quick_stack ();
1401 expand_goto (target_label);
1404 #if 0
1405 static void
1406 expand_java_call (target_pc, return_address)
1407 int target_pc, return_address;
1409 tree target_label = lookup_label (target_pc);
1410 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1411 push_value (value);
1412 flush_quick_stack ();
1413 expand_goto (target_label);
1416 static void
1417 expand_java_ret (return_address)
1418 tree return_address ATTRIBUTE_UNUSED;
1420 warning ("ret instruction not implemented");
1421 #if 0
1422 tree target_label = lookup_label (target_pc);
1423 flush_quick_stack ();
1424 expand_goto (target_label);
1425 #endif
1427 #endif
1429 /* Recursive helper function to pop argument types during verifiation. */
1431 void
1432 pop_argument_types (arg_types)
1433 tree arg_types;
1435 if (arg_types == end_params_node)
1436 return;
1437 if (TREE_CODE (arg_types) == TREE_LIST)
1439 pop_argument_types (TREE_CHAIN (arg_types));
1440 pop_type (TREE_VALUE (arg_types));
1441 return;
1443 abort ();
1446 static tree
1447 pop_arguments (arg_types)
1448 tree arg_types;
1450 if (arg_types == end_params_node)
1451 return NULL_TREE;
1452 if (TREE_CODE (arg_types) == TREE_LIST)
1454 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1455 tree type = TREE_VALUE (arg_types);
1456 tree arg = pop_value (type);
1457 if (PROMOTE_PROTOTYPES
1458 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1459 && INTEGRAL_TYPE_P (type))
1460 arg = convert (integer_type_node, arg);
1461 return tree_cons (NULL_TREE, arg, tail);
1463 abort ();
1466 /* Build an expression to initialize the class CLAS.
1467 if EXPR is non-NULL, returns an expression to first call the initializer
1468 (if it is needed) and then calls EXPR. */
1470 tree
1471 build_class_init (clas, expr)
1472 tree clas, expr;
1474 tree init;
1475 if (inherits_from_p (current_class, clas))
1476 return expr;
1477 init = build (CALL_EXPR, void_type_node,
1478 build_address_of (soft_initclass_node),
1479 build_tree_list (NULL_TREE, build_class_ref (clas)),
1480 NULL_TREE);
1481 TREE_SIDE_EFFECTS (init) = 1;
1482 if (expr != NULL_TREE)
1484 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1485 TREE_SIDE_EFFECTS (expr) = 1;
1486 return expr;
1488 return init;
1491 static tree methods_ident = NULL_TREE;
1492 static tree ncode_ident = NULL_TREE;
1493 tree dtable_ident = NULL_TREE;
1495 tree
1496 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1497 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1498 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1500 tree func;
1501 if (is_compiled_class (self_type))
1503 make_decl_rtl (method, NULL, 1);
1504 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1506 else
1508 /* We don't know whether the method has been (statically) compiled.
1509 Compile this code to get a reference to the method's code:
1511 SELF_TYPE->methods[METHOD_INDEX].ncode
1513 This is guaranteed to work (assuming SELF_TYPE has
1514 been initialized), since if the method is not compiled yet,
1515 its ncode points to a trampoline that forces compilation. */
1517 int method_index = 0;
1518 tree meth;
1519 tree ref = build_class_ref (self_type);
1520 ref = build1 (INDIRECT_REF, class_type_node, ref);
1521 if (ncode_ident == NULL_TREE)
1522 ncode_ident = get_identifier ("ncode");
1523 if (methods_ident == NULL_TREE)
1524 methods_ident = get_identifier ("methods");
1525 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1526 lookup_field (&class_type_node, methods_ident));
1527 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1528 ; meth = TREE_CHAIN (meth))
1530 if (method == meth)
1531 break;
1532 if (meth == NULL_TREE)
1533 fatal ("method '%s' not found in class",
1534 IDENTIFIER_POINTER (DECL_NAME (method)));
1535 method_index++;
1537 method_index *= int_size_in_bytes (method_type_node);
1538 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1539 ref, build_int_2 (method_index, 0)));
1540 ref = build1 (INDIRECT_REF, method_type_node, ref);
1541 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1542 ref,
1543 lookup_field (&method_type_node, ncode_ident));
1545 return func;
1548 tree
1549 invoke_build_dtable (is_invoke_interface, arg_list)
1550 int is_invoke_interface;
1551 tree arg_list;
1553 tree dtable, objectref;
1555 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1557 /* If we're dealing with interfaces and if the objectref
1558 argument is an array then get the dispatch table of the class
1559 Object rather than the one from the objectref. */
1560 objectref = (is_invoke_interface
1561 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1562 object_type_node : TREE_VALUE (arg_list));
1564 if (dtable_ident == NULL_TREE)
1565 dtable_ident = get_identifier ("vtable");
1566 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1567 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1568 lookup_field (&object_type_node, dtable_ident));
1570 return dtable;
1573 tree
1574 build_invokevirtual (dtable, method)
1575 tree dtable, method;
1577 tree func;
1578 tree nativecode_ptr_ptr_type_node
1579 = build_pointer_type (nativecode_ptr_type_node);
1580 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1581 /* Add one to skip "class" field of dtable, and one to skip unused
1582 vtable entry (for C++ compatibility). */
1583 method_index += 2;
1584 method_index
1585 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1586 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1587 dtable, build_int_2 (method_index, 0)));
1588 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1590 return func;
1593 tree
1594 build_invokeinterface (dtable, method_name, method_signature)
1595 tree dtable, method_name, method_signature;
1597 static tree class_ident = NULL_TREE;
1598 tree lookup_arg;
1600 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1601 ensure that the selected method exists, is public and not
1602 abstract nor static. */
1604 if (class_ident == NULL_TREE)
1605 class_ident = get_identifier ("class");
1607 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1608 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1609 lookup_field (&dtable_type, class_ident));
1610 lookup_arg = build_tree_list (NULL_TREE,
1611 (build_utf8_ref
1612 (unmangle_classname
1613 (IDENTIFIER_POINTER(method_signature),
1614 IDENTIFIER_LENGTH(method_signature)))));
1615 lookup_arg = tree_cons (NULL_TREE, dtable,
1616 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1617 lookup_arg));
1618 return build (CALL_EXPR, ptr_type_node,
1619 build_address_of (soft_lookupinterfacemethod_node),
1620 lookup_arg, NULL_TREE);
1623 /* Expand one of the invoke_* opcodes.
1624 OCPODE is the specific opcode.
1625 METHOD_REF_INDEX is an index into the constant pool.
1626 NARGS is the number of arguments, or -1 if not specified. */
1628 static void
1629 expand_invoke (opcode, method_ref_index, nargs)
1630 int opcode;
1631 int method_ref_index;
1632 int nargs ATTRIBUTE_UNUSED;
1634 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1635 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1636 tree self_type = get_class_constant
1637 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1638 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1639 tree call, func, method, arg_list, method_type;
1641 if (! CLASS_LOADED_P (self_type))
1643 load_class (self_type, 1);
1644 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1645 fatal ("failed to find class '%s'", self_name);
1647 layout_class_methods (self_type);
1649 if (method_name == init_identifier_node)
1650 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1651 method_signature);
1652 else
1653 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1654 method_name, method_signature);
1655 if (method == NULL_TREE)
1657 error ("Class '%s' has no method named '%s' matching signature '%s'",
1658 self_name,
1659 IDENTIFIER_POINTER (method_name),
1660 IDENTIFIER_POINTER (method_signature));
1662 /* Invoke static can't invoke static/abstract method */
1663 else if (opcode == OPCODE_invokestatic)
1665 if (!METHOD_STATIC (method))
1667 error ("invokestatic on non static method");
1668 method = NULL_TREE;
1670 else if (METHOD_ABSTRACT (method))
1672 error ("invokestatic on abstract method");
1673 method = NULL_TREE;
1676 else
1678 if (METHOD_STATIC (method))
1680 error ("invoke[non-static] on static method");
1681 method = NULL_TREE;
1685 if (method == NULL_TREE)
1687 method_type = get_type_from_signature (method_signature);
1688 pop_arguments (TYPE_ARG_TYPES (method_type));
1689 if (opcode != OPCODE_invokestatic)
1690 pop_type (self_type);
1691 method_type = promote_type (TREE_TYPE (method_type));
1692 push_value (convert (method_type, integer_zero_node));
1693 return;
1696 method_type = TREE_TYPE (method);
1697 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1698 flush_quick_stack ();
1700 func = NULL_TREE;
1701 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1702 || (opcode == OPCODE_invokevirtual
1703 && (METHOD_PRIVATE (method)
1704 || METHOD_FINAL (method)
1705 || CLASS_FINAL (TYPE_NAME (self_type)))))
1706 func = build_known_method_ref (method, method_type, self_type,
1707 method_signature, arg_list);
1708 else
1710 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1711 arg_list);
1712 if (opcode == OPCODE_invokevirtual)
1713 func = build_invokevirtual (dtable, method);
1714 else
1715 func = build_invokeinterface (dtable, method_name, method_signature);
1717 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1718 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1719 TREE_SIDE_EFFECTS (call) = 1;
1721 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1722 expand_expr_stmt (call);
1723 else
1725 push_value (call);
1726 flush_quick_stack ();
1731 /* Expand an operation to extract from or store into a field.
1732 IS_STATIC is 1 iff the field is static.
1733 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1734 FIELD_REF_INDEX is an index into the constant pool. */
1736 static void
1737 expand_java_field_op (is_static, is_putting, field_ref_index)
1738 int is_static;
1739 int is_putting;
1740 int field_ref_index;
1742 tree self_type =
1743 get_class_constant (current_jcf,
1744 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1745 field_ref_index));
1746 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1747 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
1748 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
1749 field_ref_index);
1750 tree field_type = get_type_from_signature (field_signature);
1751 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1752 tree field_ref;
1753 int is_error = 0;
1754 tree field_decl = lookup_field (&self_type, field_name);
1755 if (field_decl == error_mark_node)
1757 is_error = 1;
1759 else if (field_decl == NULL_TREE)
1761 error ("Missing field '%s' in '%s'",
1762 IDENTIFIER_POINTER (field_name), self_name);
1763 is_error = 1;
1765 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1767 error ("Mismatching signature for field '%s' in '%s'",
1768 IDENTIFIER_POINTER (field_name), self_name);
1769 is_error = 1;
1771 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1772 if (is_error)
1774 if (! is_putting)
1775 push_value (convert (field_type, integer_zero_node));
1776 flush_quick_stack ();
1777 return;
1780 /* Inline references to java.lang.PRIMTYPE.TYPE.
1781 In addition to being a useful (minor) optimization,
1782 this is also needed to avoid circularities in the implementation
1783 of these fields in libjava. */
1784 if (field_name == TYPE_identifier_node && ! is_putting
1785 && ! flag_emit_class_files && field_type == class_ptr_type
1786 && strncmp (self_name, "java.lang.", 10) == 0)
1788 tree typ = build_primtype_type_ref (self_name);
1789 if (typ)
1791 push_value (typ);
1792 return;
1796 field_ref = build_field_ref (field_ref, self_type, field_name);
1797 if (is_static)
1798 field_ref = build_class_init (self_type, field_ref);
1799 if (is_putting)
1801 flush_quick_stack ();
1802 if (FIELD_FINAL (field_decl))
1804 if (DECL_CONTEXT (field_decl) != current_class)
1805 error_with_decl (field_decl,
1806 "assignment to final field `%s' not in field's class");
1807 else if (FIELD_STATIC (field_decl))
1809 if (!IS_CLINIT (current_function_decl))
1810 error_with_decl (field_decl,
1811 "assignment to final static field `%s' not in class initializer");
1813 else
1815 if (! DECL_CONSTRUCTOR_P (current_function_decl))
1816 error_with_decl (field_decl, "assignment to final field `%s' "
1817 "not in constructor");
1820 expand_assignment (field_ref, new_value, 0, 0);
1822 else
1823 push_value (field_ref);
1826 tree
1827 build_primtype_type_ref (self_name)
1828 const char *self_name;
1830 const char *class_name = self_name+10;
1831 tree typ;
1832 if (strncmp(class_name, "Byte", 4) == 0)
1833 typ = byte_type_node;
1834 else if (strncmp(class_name, "Short", 5) == 0)
1835 typ = short_type_node;
1836 else if (strncmp(class_name, "Integer", 7) == 0)
1837 typ = int_type_node;
1838 else if (strncmp(class_name, "Long", 4) == 0)
1839 typ = long_type_node;
1840 else if (strncmp(class_name, "Float", 5) == 0)
1841 typ = float_type_node;
1842 else if (strncmp(class_name, "Double", 6) == 0)
1843 typ = double_type_node;
1844 else if (strncmp(class_name, "Boolean", 7) == 0)
1845 typ = boolean_type_node;
1846 else if (strncmp(class_name, "Char", 4) == 0)
1847 typ = char_type_node;
1848 else if (strncmp(class_name, "Void", 4) == 0)
1849 typ = void_type_node;
1850 else
1851 typ = NULL_TREE;
1852 if (typ != NULL_TREE)
1853 return build_class_ref (typ);
1854 else
1855 return NULL_TREE;
1858 void
1859 load_type_state (label)
1860 tree label;
1862 int i;
1863 tree vec = LABEL_TYPE_STATE (label);
1864 int cur_length = TREE_VEC_LENGTH (vec);
1865 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1866 for (i = 0; i < cur_length; i++)
1867 type_map [i] = TREE_VEC_ELT (vec, i);
1870 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1871 dependant things, but they rely on gcc routines. This function is
1872 placed here because it uses things defined locally in parse.y. */
1874 static tree
1875 case_identity (t, v)
1876 tree t __attribute__ ((__unused__));
1877 tree v;
1879 return v;
1882 struct rtx_def *
1883 java_lang_expand_expr (exp, target, tmode, modifier)
1884 register tree exp;
1885 rtx target ATTRIBUTE_UNUSED;
1886 enum machine_mode tmode ATTRIBUTE_UNUSED;
1887 enum expand_modifier modifier ATTRIBUTE_UNUSED;
1889 tree current;
1891 switch (TREE_CODE (exp))
1893 case NEW_ARRAY_INIT:
1895 rtx tmp;
1896 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1897 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1898 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1899 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1900 tree length = build_int_2 (ilength, 0);
1901 tree init = TREE_OPERAND (exp, 0);
1902 tree array_decl;
1903 #if 0
1904 /* Enable this once we can set the vtable field statically. FIXME */
1905 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1906 && JPRIMITIVE_TYPE_P (element_type))
1908 tree temp, value, init_decl;
1909 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1910 PUSH_FIELD_VALUE (temp, "vtable",
1911 null_pointer_node /* FIXME */
1913 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1914 FINISH_RECORD_CONSTRUCTOR (temp);
1915 START_RECORD_CONSTRUCTOR (value, array_type);
1916 PUSH_SUPER_VALUE (value, temp);
1917 PUSH_FIELD_VALUE (value, "length", length);
1918 PUSH_FIELD_VALUE (value, "data", init);
1919 FINISH_RECORD_CONSTRUCTOR (value);
1921 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1922 pushdecl_top_level (init_decl);
1923 TREE_STATIC (init_decl) = 1;
1924 DECL_INITIAL (init_decl) = value;
1925 DECL_IGNORED_P (init_decl) = 1;
1926 TREE_READONLY (init_decl) = 1;
1927 make_decl_rtl (init_decl, NULL, 1);
1928 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1929 return expand_expr (init, target, tmode, modifier);
1931 #endif
1932 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
1933 expand_decl (array_decl);
1934 tmp = expand_assignment (array_decl,
1935 build_new_array (element_type, length),
1936 1, 0);
1937 if (TREE_CONSTANT (init)
1938 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1940 tree init_decl = build_decl (VAR_DECL, generate_name (),
1941 TREE_TYPE (init));
1942 pushdecl_top_level (init_decl);
1943 TREE_STATIC (init_decl) = 1;
1944 DECL_INITIAL (init_decl) = init;
1945 DECL_IGNORED_P (init_decl) = 1;
1946 TREE_READONLY (init_decl) = 1;
1947 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
1948 make_decl_rtl (init_decl, NULL, 1);
1949 init = init_decl;
1951 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
1952 build1 (INDIRECT_REF, array_type, array_decl),
1953 data_fld),
1954 init, 0, 0);
1955 return tmp;
1957 case BLOCK:
1958 if (BLOCK_EXPR_BODY (exp))
1960 tree local;
1961 tree body = BLOCK_EXPR_BODY (exp);
1962 pushlevel (2); /* 2 and above */
1963 expand_start_bindings (0);
1964 local = BLOCK_EXPR_DECLS (exp);
1965 while (local)
1967 tree next = TREE_CHAIN (local);
1968 layout_decl (local, 0);
1969 expand_decl (pushdecl (local));
1970 local = next;
1972 /* Avoid deep recursion for long block. */
1973 while (TREE_CODE (body) == COMPOUND_EXPR)
1975 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
1976 emit_queue ();
1977 body = TREE_OPERAND (body, 1);
1979 expand_expr (body, const0_rtx, VOIDmode, 0);
1980 emit_queue ();
1981 poplevel (1, 1, 0);
1982 expand_end_bindings (getdecls (), 1, 0);
1983 return const0_rtx;
1985 return const0_rtx;
1987 case CASE_EXPR:
1989 tree duplicate;
1990 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
1991 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
1992 &duplicate) == 2)
1994 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
1995 parse_error_context
1996 (wfl_operator, "Duplicate case label: `%s'",
1997 print_int_node (TREE_OPERAND (exp, 0)));
1999 return const0_rtx;
2002 case DEFAULT_EXPR:
2003 pushcase (NULL_TREE, 0,
2004 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2005 return const0_rtx;
2007 case SWITCH_EXPR:
2008 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2009 expand_expr_stmt (TREE_OPERAND (exp, 1));
2010 expand_end_case (TREE_OPERAND (exp, 0));
2011 return const0_rtx;
2013 case TRY_EXPR:
2014 /* We expand a try[-catch] block */
2016 /* Expand the try block */
2017 expand_eh_region_start ();
2018 expand_expr_stmt (TREE_OPERAND (exp, 0));
2019 expand_start_all_catch ();
2021 /* Expand all catch clauses (EH handlers) */
2022 for (current = TREE_OPERAND (exp, 1); current;
2023 current = TREE_CHAIN (current))
2025 tree type;
2026 tree catch = TREE_OPERAND (current, 0);
2027 tree decl = BLOCK_EXPR_DECLS (catch);
2028 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2029 start_catch_handler (prepare_eh_table_type (type));
2030 expand_expr_stmt (TREE_OPERAND (current, 0));
2032 expand_resume_after_catch ();
2033 end_catch_handler ();
2035 expand_end_all_catch ();
2036 return const0_rtx;
2038 default:
2039 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2040 tree_code_name [TREE_CODE (exp)]);
2044 void
2045 expand_byte_code (jcf, method)
2046 JCF *jcf;
2047 tree method;
2049 int PC;
2050 int i;
2051 int saw_index;
2052 const unsigned char *linenumber_pointer;
2053 int dead_code_index = -1;
2055 #undef RET /* Defined by config/i386/i386.h */
2056 #undef AND /* Causes problems with opcodes for iand and land. */
2057 #undef PTR
2058 #define BCODE byte_ops
2059 #define BYTE_type_node byte_type_node
2060 #define SHORT_type_node short_type_node
2061 #define INT_type_node int_type_node
2062 #define LONG_type_node long_type_node
2063 #define CHAR_type_node char_type_node
2064 #define PTR_type_node ptr_type_node
2065 #define FLOAT_type_node float_type_node
2066 #define DOUBLE_type_node double_type_node
2067 #define VOID_type_node void_type_node
2068 jint INT_temp;
2069 unsigned char* byte_ops;
2070 long length = DECL_CODE_LENGTH (method);
2072 stack_pointer = 0;
2073 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2074 byte_ops = jcf->read_ptr;
2076 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2077 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2078 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2079 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2081 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2083 instruction_bits = oballoc (length + 1);
2084 bzero (instruction_bits, length + 1);
2086 /* We make an initial pass of the line number table, to note
2087 which instructions have associated line number entries. */
2088 linenumber_pointer = linenumber_table;
2089 for (i = 0; i < linenumber_count; i++)
2091 int pc = GET_u2 (linenumber_pointer);
2092 linenumber_pointer += 4;
2093 if (pc >= length)
2094 warning ("invalid PC in line number table");
2095 else
2097 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2098 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2099 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2103 /* Do a preliminary pass.
2104 * This figures out which PC can be the targets of jumps. */
2105 for (PC = 0; PC < length;)
2107 int oldpc = PC; /* PC at instruction start. */
2108 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2109 switch (byte_ops[PC++])
2111 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2112 case OPCODE: \
2113 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2114 break;
2116 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2118 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2119 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2120 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2121 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2122 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2123 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2124 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2125 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2127 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2128 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2129 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2130 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2131 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2132 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2133 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2134 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2136 /* two forms of wide instructions */
2137 #define PRE_SPECIAL_WIDE(IGNORE) \
2139 int modified_opcode = IMMEDIATE_u1; \
2140 if (modified_opcode == OPCODE_iinc) \
2142 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2143 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2145 else \
2147 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2151 /* nothing */ /* XXX JH */
2153 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2155 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2157 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2158 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2159 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2160 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2161 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2162 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2163 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2164 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2165 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2166 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2168 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2169 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2170 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2171 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2172 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2173 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2174 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2175 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2177 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2179 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2180 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2182 #define PRE_LOOKUP_SWITCH \
2183 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2184 NOTE_LABEL (default_offset+oldpc); \
2185 if (npairs >= 0) \
2186 while (--npairs >= 0) { \
2187 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2188 jint offset = IMMEDIATE_s4; \
2189 NOTE_LABEL (offset+oldpc); } \
2192 #define PRE_TABLE_SWITCH \
2193 { jint default_offset = IMMEDIATE_s4; \
2194 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2195 NOTE_LABEL (default_offset+oldpc); \
2196 if (low <= high) \
2197 while (low++ <= high) { \
2198 jint offset = IMMEDIATE_s4; \
2199 NOTE_LABEL (offset+oldpc); } \
2202 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2203 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2204 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2205 (void)(IMMEDIATE_u2); \
2206 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2208 #include "javaop.def"
2209 #undef JAVAOP
2211 } /* for */
2213 if (! verify_jvm_instructions (jcf, byte_ops, length))
2214 return;
2216 /* Translate bytecodes to rtl instructions. */
2217 linenumber_pointer = linenumber_table;
2218 for (PC = 0; PC < length;)
2220 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2222 tree label = lookup_label (PC);
2223 flush_quick_stack ();
2224 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2225 expand_label (label);
2226 if (LABEL_VERIFIED (label) || PC == 0)
2227 load_type_state (label);
2230 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2232 if (dead_code_index == -1)
2234 /* This is the start of a region of unreachable bytecodes.
2235 They still need to be processed in order for EH ranges
2236 to get handled correctly. However, we can simply
2237 replace these bytecodes with nops. */
2238 dead_code_index = PC;
2241 /* Turn this bytecode into a nop. */
2242 byte_ops[PC] = 0x0;
2244 else
2246 if (dead_code_index != -1)
2248 /* We've just reached the end of a region of dead code. */
2249 warning ("Unreachable bytecode from %d to before %d.",
2250 dead_code_index, PC);
2251 dead_code_index = -1;
2255 /* Handle possible line number entry for this PC.
2257 This code handles out-of-order and multiple linenumbers per PC,
2258 but is optimized for the case of line numbers increasing
2259 monotonically with PC. */
2260 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2262 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2263 || GET_u2 (linenumber_pointer) != PC)
2264 linenumber_pointer = linenumber_table;
2265 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2267 int pc = GET_u2 (linenumber_pointer);
2268 linenumber_pointer += 4;
2269 if (pc == PC)
2271 lineno = GET_u2 (linenumber_pointer - 2);
2272 emit_line_note (input_filename, lineno);
2273 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2274 break;
2278 maybe_start_try (PC);
2279 maybe_pushlevels (PC);
2281 PC = process_jvm_instruction (PC, byte_ops, length);
2283 maybe_poplevels (PC);
2284 maybe_end_try (PC);
2285 } /* for */
2287 if (dead_code_index != -1)
2289 /* We've just reached the end of a region of dead code. */
2290 warning ("Unreachable bytecode from %d to the end of the method.",
2291 dead_code_index);
2295 static void
2296 java_push_constant_from_pool (jcf, index)
2297 JCF *jcf;
2298 int index;
2300 tree c;
2301 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2303 tree name;
2304 push_obstacks (&permanent_obstack, &permanent_obstack);
2305 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2306 index = alloc_name_constant (CONSTANT_String, name);
2307 c = build_ref_from_constant_pool (index);
2308 TREE_TYPE (c) = promote_type (string_type_node);
2309 pop_obstacks ();
2311 else
2312 c = get_constant (jcf, index);
2313 push_value (c);
2317 process_jvm_instruction (PC, byte_ops, length)
2318 int PC;
2319 const unsigned char* byte_ops;
2320 long length ATTRIBUTE_UNUSED;
2322 const char *opname; /* Temporary ??? */
2323 int oldpc = PC; /* PC at instruction start. */
2325 /* If the instruction is at the beginning of a exception handler,
2326 replace the top of the stack with the thrown object reference */
2327 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2329 tree type = pop_type (ptr_type_node);
2330 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2333 switch (byte_ops[PC++])
2335 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2336 case OPCODE: \
2337 opname = #OPNAME; \
2338 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2339 break;
2341 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2343 int saw_index = 0; \
2344 int index = OPERAND_VALUE; \
2345 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2348 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2350 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2351 tree ret = lookup_label (PC); \
2352 build_java_jsr (where, ret); \
2353 load_type_state (ret); \
2356 /* Push a constant onto the stack. */
2357 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2358 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2359 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2360 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2362 /* internal macro added for use by the WIDE case */
2363 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2364 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2366 /* Push local variable onto the opcode stack. */
2367 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2369 /* have to do this since OPERAND_VALUE may have side-effects */ \
2370 int opvalue = OPERAND_VALUE; \
2371 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2374 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2375 expand_java_return (OPERAND_TYPE##_type_node)
2377 #define REM_EXPR TRUNC_MOD_EXPR
2378 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2379 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2381 #define FIELD(IS_STATIC, IS_PUT) \
2382 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2384 #define TEST(OPERAND_TYPE, CONDITION) \
2385 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2387 #define COND(OPERAND_TYPE, CONDITION) \
2388 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2390 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2391 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2393 #define BRANCH_GOTO(OPERAND_VALUE) \
2394 expand_java_goto (oldpc + OPERAND_VALUE)
2396 #define BRANCH_CALL(OPERAND_VALUE) \
2397 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2399 #if 0
2400 #define BRANCH_RETURN(OPERAND_VALUE) \
2402 tree type = OPERAND_TYPE##_type_node; \
2403 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2404 expand_java_ret (value); \
2406 #endif
2408 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2409 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2410 fprintf (stderr, "(not implemented)\n")
2411 #define NOT_IMPL1(OPERAND_VALUE) \
2412 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2413 fprintf (stderr, "(not implemented)\n")
2415 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2417 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2419 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2421 #define STACK_SWAP(COUNT) java_stack_swap()
2423 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2424 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2425 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2427 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2428 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2430 #define LOOKUP_SWITCH \
2431 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2432 tree selector = pop_value (INT_type_node); \
2433 tree duplicate, label; \
2434 tree type = TREE_TYPE (selector); \
2435 flush_quick_stack (); \
2436 expand_start_case (0, selector, type, "switch statement");\
2437 push_momentary (); \
2438 while (--npairs >= 0) \
2440 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2441 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2442 TREE_TYPE (value) = type; \
2443 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2444 pushcase (value, convert, label, &duplicate); \
2445 expand_java_goto (oldpc + offset); \
2447 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2448 pushcase (NULL_TREE, 0, label, &duplicate); \
2449 expand_java_goto (oldpc + default_offset); \
2450 pop_momentary (); \
2451 expand_end_case (selector); \
2454 #define TABLE_SWITCH \
2455 { jint default_offset = IMMEDIATE_s4; \
2456 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2457 tree selector = pop_value (INT_type_node); \
2458 tree duplicate, label; \
2459 tree type = TREE_TYPE (selector); \
2460 flush_quick_stack (); \
2461 expand_start_case (0, selector, type, "switch statement");\
2462 push_momentary (); \
2463 for (; low <= high; low++) \
2465 jint offset = IMMEDIATE_s4; \
2466 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2467 TREE_TYPE (value) = type; \
2468 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2469 pushcase (value, convert, label, &duplicate); \
2470 expand_java_goto (oldpc + offset); \
2472 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2473 pushcase (NULL_TREE, 0, label, &duplicate); \
2474 expand_java_goto (oldpc + default_offset); \
2475 pop_momentary (); \
2476 expand_end_case (selector); \
2479 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2480 { int opcode = byte_ops[PC-1]; \
2481 int method_ref_index = IMMEDIATE_u2; \
2482 int nargs; \
2483 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2484 else nargs = -1; \
2485 expand_invoke (opcode, method_ref_index, nargs); \
2488 /* Handle new, checkcast, instanceof */
2489 #define OBJECT(TYPE, OP) \
2490 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2492 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2494 #define ARRAY_LOAD(OPERAND_TYPE) \
2496 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2499 #define ARRAY_STORE(OPERAND_TYPE) \
2501 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2504 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2505 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2506 #define ARRAY_NEW_PTR() \
2507 push_value (build_anewarray (get_class_constant (current_jcf, \
2508 IMMEDIATE_u2), \
2509 pop_value (int_type_node)));
2510 #define ARRAY_NEW_NUM() \
2512 int atype = IMMEDIATE_u1; \
2513 push_value (build_newarray (atype, pop_value (int_type_node)));\
2515 #define ARRAY_NEW_MULTI() \
2517 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2518 int ndims = IMMEDIATE_u1; \
2519 expand_java_multianewarray( class, ndims ); \
2522 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2523 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2524 pop_value (OPERAND_TYPE##_type_node))));
2526 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2528 push_value (build1 (NOP_EXPR, int_type_node, \
2529 (convert (TO_TYPE##_type_node, \
2530 pop_value (FROM_TYPE##_type_node))))); \
2533 #define CONVERT(FROM_TYPE, TO_TYPE) \
2535 push_value (convert (TO_TYPE##_type_node, \
2536 pop_value (FROM_TYPE##_type_node))); \
2539 /* internal macro added for use by the WIDE case
2540 Added TREE_TYPE (decl) assignment, apbianco */
2541 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2543 tree decl, value; \
2544 int var = OPVALUE; \
2545 tree type = OPTYPE; \
2546 value = pop_value (type); \
2547 type = TREE_TYPE (value); \
2548 decl = find_local_variable (var, type, oldpc); \
2549 set_local_type (var, type ); \
2550 expand_assignment (decl, value, 0, 0); \
2553 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2555 /* have to do this since OPERAND_VALUE may have side-effects */ \
2556 int opvalue = OPERAND_VALUE; \
2557 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2560 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2561 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2563 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2564 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2566 #define MONITOR_OPERATION(call) \
2568 tree o = pop_value (ptr_type_node); \
2569 tree c; \
2570 flush_quick_stack (); \
2571 c = build_java_monitor (call, o); \
2572 TREE_SIDE_EFFECTS (c) = 1; \
2573 expand_expr_stmt (c); \
2576 #define SPECIAL_IINC(IGNORED) \
2578 unsigned int local_var_index = IMMEDIATE_u1; \
2579 int ival = IMMEDIATE_s1; \
2580 expand_iinc(local_var_index, ival, oldpc); \
2583 #define SPECIAL_WIDE(IGNORED) \
2585 int modified_opcode = IMMEDIATE_u1; \
2586 unsigned int local_var_index = IMMEDIATE_u2; \
2587 switch (modified_opcode) \
2589 case OPCODE_iinc: \
2591 int ival = IMMEDIATE_s2; \
2592 expand_iinc (local_var_index, ival, oldpc); \
2593 break; \
2595 case OPCODE_iload: \
2596 case OPCODE_lload: \
2597 case OPCODE_fload: \
2598 case OPCODE_dload: \
2599 case OPCODE_aload: \
2601 /* duplicate code from LOAD macro */ \
2602 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2603 break; \
2605 case OPCODE_istore: \
2606 case OPCODE_lstore: \
2607 case OPCODE_fstore: \
2608 case OPCODE_dstore: \
2609 case OPCODE_astore: \
2611 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2612 break; \
2614 default: \
2615 error ("unrecogized wide sub-instruction"); \
2619 #define SPECIAL_THROW(IGNORED) \
2620 build_java_athrow (pop_value (throwable_type_node))
2622 #define SPECIAL_BREAK NOT_IMPL1
2623 #define IMPL NOT_IMPL
2625 #include "javaop.def"
2626 #undef JAVAOP
2627 default:
2628 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2630 return PC;
2633 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2634 order, as specified by Java Language Specification.
2636 The problem is that while expand_expr will evaluate its sub-operands in
2637 left-to-right order, for variables it will just return an rtx (i.e.
2638 an lvalue) for the variable (rather than an rvalue). So it is possible
2639 that a later sub-operand will change the register, and when the
2640 actual operation is done, it will use the new value, when it should
2641 have used the original value.
2643 We fix this by using save_expr. This forces the sub-operand to be
2644 copied into a fresh virtual register,
2646 For method invocation, we modify the arguments so that a
2647 left-to-right order evaluation is performed. Saved expressions
2648 will, in CALL_EXPR order, be reused when the call will be expanded.
2651 tree
2652 force_evaluation_order (node)
2653 tree node;
2655 if (flag_syntax_only)
2656 return node;
2657 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
2659 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2660 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2662 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2664 tree arg, cmp;
2666 if (!TREE_OPERAND (node, 1))
2667 return node;
2669 /* This reverses the evaluation order. This is a desired effect. */
2670 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
2671 arg; arg = TREE_CHAIN (arg))
2673 tree saved = save_expr (TREE_VALUE (arg));
2674 cmp = (cmp == NULL_TREE ? saved :
2675 build (COMPOUND_EXPR, void_type_node, cmp, saved));
2676 TREE_VALUE (arg) = saved;
2679 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
2680 TREE_SIDE_EFFECTS (cmp) = 1;
2682 if (cmp)
2684 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
2685 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
2686 TREE_SIDE_EFFECTS (cmp) = 1;
2687 node = cmp;
2690 return node;