f92fc8dabb6458851a2b0d5fdc0062d167ab7d12
[gcc.git] / gcc / java / expr.c
1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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.
20
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. */
24
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
26
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"
43
44 static void flush_quick_stack PARAMS ((void));
45 static void push_value PARAMS ((tree));
46 static tree pop_value PARAMS ((tree));
47 static void java_stack_swap PARAMS ((void));
48 static void java_stack_dup PARAMS ((int, int));
49 static void build_java_athrow PARAMS ((tree));
50 static void build_java_jsr PARAMS ((tree, tree));
51 static void build_java_ret PARAMS ((tree));
52 static void expand_java_multianewarray PARAMS ((tree, int));
53 static void expand_java_arraystore PARAMS ((tree));
54 static void expand_java_arrayload PARAMS ((tree));
55 static void expand_java_array_length PARAMS ((void));
56 static tree build_java_monitor PARAMS ((tree, tree));
57 static void expand_java_pushc PARAMS ((int, tree));
58 static void expand_java_return PARAMS ((tree));
59 static void expand_java_NEW PARAMS ((tree));
60 static void expand_java_INSTANCEOF PARAMS ((tree));
61 static void expand_java_CHECKCAST PARAMS ((tree));
62 static void expand_iinc PARAMS ((unsigned int, int, int));
63 static void expand_java_binop PARAMS ((tree, enum tree_code));
64 static void note_label PARAMS ((int, int));
65 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
66 static void expand_test PARAMS ((enum tree_code, tree, int));
67 static void expand_cond PARAMS ((enum tree_code, tree, int));
68 static void expand_java_goto PARAMS ((int));
69 #if 0
70 static void expand_java_call PARAMS ((int, int));
71 static void expand_java_ret PARAMS ((tree));
72 #endif
73 static tree pop_arguments PARAMS ((tree));
74 static void expand_invoke PARAMS ((int, int, int));
75 static void expand_java_field_op PARAMS ((int, int, int));
76 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
77 static void java_stack_pop PARAMS ((int));
78 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
79 static tree build_java_check_indexed_type PARAMS ((tree, tree));
80 static tree java_array_data_offset PARAMS ((tree));
81 static tree case_identity PARAMS ((tree, tree));
82
83 static tree operand_type[59];
84 extern struct obstack permanent_obstack;
85
86 /* Set to non-zero value in order to emit class initilization code
87 before static field references. */
88 int always_initialize_class_p;
89
90 void
91 init_expr_processing()
92 {
93 operand_type[21] = operand_type[54] = int_type_node;
94 operand_type[22] = operand_type[55] = long_type_node;
95 operand_type[23] = operand_type[56] = float_type_node;
96 operand_type[24] = operand_type[57] = double_type_node;
97 operand_type[25] = operand_type[58] = ptr_type_node;
98 }
99
100 /* We store the stack state in two places:
101 Within a basic block, we use the quick_stack, which is a
102 pushdown list (TREE_LISTs) of expression nodes.
103 This is the top part of the stack; below that we use find_stack_slot.
104 At the end of a basic block, the quick_stack must be flushed
105 to the stack slot array (as handled by find_stack_slot).
106 Using quick_stack generates better code (especially when
107 compiled without optimization), because we do not have to
108 explicitly store and load trees to temporary variables.
109
110 If a variable is on the quick stack, it means the value of variable
111 when the quick stack was last flushed. Conceptually, flush_quick_stack
112 saves all the the quick_stack elements in parellel. However, that is
113 complicated, so it actually saves them (i.e. copies each stack value
114 to is home virtual register) from low indexes. This allows a quick_stack
115 element at index i (counting from the bottom of stack the) to references
116 slot virtuals for register that are >= i, but not those that are deeper.
117 This convention makes most operations easier. For example iadd works
118 even when the stack contains (reg[0], reg[1]): It results in the
119 stack containing (reg[0]+reg[1]), which is OK. However, some stack
120 operations are more complicated. For example dup given a stack
121 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
122 the convention, since stack value 1 would refer to a register with
123 lower index (reg[0]), which flush_quick_stack does not safely handle.
124 So dup cannot just add an extra element to the quick_stack, but iadd can.
125 */
126
127 tree quick_stack = NULL_TREE;
128
129 /* A free-list of unused permamnet TREE_LIST nodes. */
130 tree tree_list_free_list = NULL_TREE;
131
132 /* The stack pointer of the Java virtual machine.
133 This does include the size of the quick_stack. */
134
135 int stack_pointer;
136
137 const unsigned char *linenumber_table;
138 int linenumber_count;
139
140 tree
141 truthvalue_conversion (expr)
142 tree expr;
143 {
144 /* It is simpler and generates better code to have only TRUTH_*_EXPR
145 or comparison expressions as truth values at this level.
146
147 This function should normally be identity for Java. */
148
149 switch (TREE_CODE (expr))
150 {
151 case EQ_EXPR:
152 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
153 case TRUTH_ANDIF_EXPR:
154 case TRUTH_ORIF_EXPR:
155 case TRUTH_AND_EXPR:
156 case TRUTH_OR_EXPR:
157 case ERROR_MARK:
158 return expr;
159
160 case INTEGER_CST:
161 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
162
163 case REAL_CST:
164 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
165
166 /* are these legal? XXX JH */
167 case NEGATE_EXPR:
168 case ABS_EXPR:
169 case FLOAT_EXPR:
170 case FFS_EXPR:
171 /* These don't change whether an object is non-zero or zero. */
172 return truthvalue_conversion (TREE_OPERAND (expr, 0));
173
174 case COND_EXPR:
175 /* Distribute the conversion into the arms of a COND_EXPR. */
176 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
177 truthvalue_conversion (TREE_OPERAND (expr, 1)),
178 truthvalue_conversion (TREE_OPERAND (expr, 2))));
179
180 case NOP_EXPR:
181 /* If this is widening the argument, we can ignore it. */
182 if (TYPE_PRECISION (TREE_TYPE (expr))
183 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
184 return truthvalue_conversion (TREE_OPERAND (expr, 0));
185 /* fall through to default */
186
187 default:
188 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
189 }
190 }
191
192 #ifdef JAVA_USE_HANDLES
193 /* Given a pointer to a handle, get a pointer to an object. */
194
195 tree
196 unhand_expr (expr)
197 tree expr;
198 {
199 tree field, handle_type;
200 expr = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
201 handle_type = TREE_TYPE (expr);
202 field = TYPE_FIELDS (handle_type);
203 expr = build (COMPONENT_REF, TREE_TYPE (field), expr, field);
204 return expr;
205 }
206 #endif
207
208 /* Save any stack slots that happen to be in the quick_stack into their
209 home virtual register slots.
210
211 The copy order is from low stack index to high, to support the invariant
212 that the expression for a slot may contain decls for stack slots with
213 higher (or the same) index, but not lower. */
214
215 static void
216 flush_quick_stack ()
217 {
218 int stack_index = stack_pointer;
219 register tree prev, cur, next;
220
221 /* First reverse the quick_stack, and count the number of slots it has. */
222 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
223 {
224 next = TREE_CHAIN (cur);
225 TREE_CHAIN (cur) = prev;
226 prev = cur;
227 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
228 }
229 quick_stack = prev;
230
231 while (quick_stack != NULL_TREE)
232 {
233 tree decl;
234 tree node = quick_stack, type;
235 quick_stack = TREE_CHAIN (node);
236 TREE_CHAIN (node) = tree_list_free_list;
237 tree_list_free_list = node;
238 node = TREE_VALUE (node);
239 type = TREE_TYPE (node);
240
241 decl = find_stack_slot (stack_index, type);
242 if (decl != node)
243 expand_assignment (decl, node, 0, 0);
244 stack_index += 1 + TYPE_IS_WIDE (type);
245 }
246 }
247
248 void
249 push_type (type)
250 tree type;
251 {
252 int n_words;
253 type = promote_type (type);
254 n_words = 1 + TYPE_IS_WIDE (type);
255 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
256 fatal ("stack overflow");
257 stack_type_map[stack_pointer++] = type;
258 n_words--;
259 while (--n_words >= 0)
260 stack_type_map[stack_pointer++] = TYPE_SECOND;
261 }
262
263 static void
264 push_value (value)
265 tree value;
266 {
267 tree type = TREE_TYPE (value);
268 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
269 {
270 type = promote_type (type);
271 value = convert (type, value);
272 }
273 push_type (type);
274 if (tree_list_free_list == NULL_TREE)
275 quick_stack = perm_tree_cons (NULL_TREE, value, quick_stack);
276 else
277 {
278 tree node = tree_list_free_list;
279 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
280 TREE_VALUE (node) = value;
281 TREE_CHAIN (node) = quick_stack;
282 quick_stack = node;
283 }
284 }
285
286 /* Pop a type from the type stack.
287 TYPE is the expected type. Return the actual type, which must be
288 convertible to TYPE, otherwise NULL_TREE is returned. */
289
290 tree
291 pop_type_0 (type)
292 tree type;
293 {
294 int n_words;
295 tree t;
296 if (TREE_CODE (type) == RECORD_TYPE)
297 type = promote_type (type);
298 n_words = 1 + TYPE_IS_WIDE (type);
299 if (stack_pointer < n_words)
300 fatal ("stack underflow");
301 while (--n_words > 0)
302 {
303 if (stack_type_map[--stack_pointer] != void_type_node)
304 fatal ("Invalid multi-word value on type stack");
305 }
306 t = stack_type_map[--stack_pointer];
307 if (type == NULL_TREE || t == type)
308 return t;
309 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
310 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
311 return t;
312 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
313 {
314 if (type == ptr_type_node || type == object_ptr_type_node)
315 return t;
316 else if (t == ptr_type_node) /* Special case for null reference. */
317 return type;
318 else if (can_widen_reference_to (t, type))
319 return t;
320 /* This is a kludge, but matches what Sun's verifier does.
321 It can be tricked, but is safe as long as type errors
322 (i.e. interface method calls) are caught at run-time. */
323 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type)))
324 && t == object_ptr_type_node)
325 return t;
326 }
327 return NULL_TREE;
328 }
329
330 /* Pop a type from the type stack.
331 TYPE is the expected type. Return the actual type, which must be
332 convertible to TYPE, otherwise call error. */
333
334 tree
335 pop_type (type)
336 tree type;
337 {
338 tree t = pop_type_0 (type);
339 if (t != NULL_TREE)
340 return t;
341 error ("unexpected type on stack");
342 return type;
343 }
344
345 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
346 Handles array types and interfaces. */
347
348 int
349 can_widen_reference_to (source_type, target_type)
350 tree source_type, target_type;
351 {
352 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
353 return 1;
354
355 /* Get rid of pointers */
356 if (TREE_CODE (source_type) == POINTER_TYPE)
357 source_type = TREE_TYPE (source_type);
358 if (TREE_CODE (target_type) == POINTER_TYPE)
359 target_type = TREE_TYPE (target_type);
360
361 if (source_type == target_type)
362 return 1;
363 else
364 {
365 source_type = HANDLE_TO_CLASS_TYPE (source_type);
366 target_type = HANDLE_TO_CLASS_TYPE (target_type);
367 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
368 {
369 HOST_WIDE_INT source_length, target_length;
370 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
371 return 0;
372 target_length = java_array_type_length (target_type);
373 if (target_length >= 0)
374 {
375 source_length = java_array_type_length (source_type);
376 if (source_length != target_length)
377 return 0;
378 }
379 source_type = TYPE_ARRAY_ELEMENT (source_type);
380 target_type = TYPE_ARRAY_ELEMENT (target_type);
381 if (source_type == target_type)
382 return 1;
383 if (TREE_CODE (source_type) != POINTER_TYPE
384 || TREE_CODE (target_type) != POINTER_TYPE)
385 return 0;
386 return can_widen_reference_to (source_type, target_type);
387 }
388 else
389 {
390 int source_depth = class_depth (source_type);
391 int target_depth = class_depth (target_type);
392
393 /* class_depth can return a negative depth if an error occurred */
394 if (source_depth < 0 || target_depth < 0)
395 return 0;
396
397 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
398 {
399 /* target_type is OK if source_type or source_type ancestors
400 implement target_type. We handle multiple sub-interfaces */
401
402 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
403 int n = TREE_VEC_LENGTH (basetype_vec), i;
404 for (i=0 ; i < n; i++)
405 if (can_widen_reference_to
406 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
407 target_type))
408 return 1;
409 if (n == 0)
410 return 0;
411 }
412
413 for ( ; source_depth > target_depth; source_depth--)
414 {
415 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
416 }
417 return source_type == target_type;
418 }
419 }
420 }
421
422 static tree
423 pop_value (type)
424 tree type;
425 {
426 type = pop_type (type);
427 if (quick_stack)
428 {
429 tree node = quick_stack;
430 quick_stack = TREE_CHAIN (quick_stack);
431 TREE_CHAIN (node) = tree_list_free_list;
432 tree_list_free_list = node;
433 node = TREE_VALUE (node);
434 return node;
435 }
436 else
437 return find_stack_slot (stack_pointer, promote_type (type));
438 }
439
440
441 /* Pop and discrad the top COUNT stack slots. */
442
443 static void
444 java_stack_pop (count)
445 int count;
446 {
447 while (count > 0)
448 {
449 tree type, val;
450 if (stack_pointer == 0)
451 fatal ("stack underflow");
452 type = stack_type_map[stack_pointer - 1];
453 if (type == TYPE_SECOND)
454 {
455 count--;
456 if (stack_pointer == 1 || count <= 0)
457 fatal ("stack underflow");
458 type = stack_type_map[stack_pointer - 2];
459 }
460 val = pop_value (type);
461 count--;
462 }
463 }
464
465 /* Implement the 'swap' operator (to swap two top stack slots). */
466
467 static void
468 java_stack_swap ()
469 {
470 tree type1, type2;
471 rtx temp;
472 tree decl1, decl2;
473
474 if (stack_pointer < 2
475 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
476 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
477 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
478 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
479 fatal ("bad stack swap");
480
481 flush_quick_stack ();
482 decl1 = find_stack_slot (stack_pointer - 1, type1);
483 decl2 = find_stack_slot (stack_pointer - 2, type2);
484 temp = copy_to_reg (DECL_RTL (decl1));
485 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
486 emit_move_insn (DECL_RTL (decl2), temp);
487 stack_type_map[stack_pointer - 1] = type2;
488 stack_type_map[stack_pointer - 2] = type1;
489 }
490
491 static void
492 java_stack_dup (size, offset)
493 int size, offset;
494 {
495 int low_index = stack_pointer - size - offset;
496 int dst_index;
497 if (low_index < 0)
498 error ("stack underflow - dup* operation");
499
500 flush_quick_stack ();
501
502 stack_pointer += size;
503 dst_index = stack_pointer;
504
505 for (dst_index = stack_pointer; --dst_index >= low_index; )
506 {
507 tree type;
508 int src_index = dst_index - size;
509 if (src_index < low_index)
510 src_index = dst_index + size + offset;
511 type = stack_type_map [src_index];
512 if (type == TYPE_SECOND)
513 {
514 if (src_index <= low_index)
515 fatal ("dup operation splits 64-bit number");
516 stack_type_map[dst_index] = type;
517 src_index--; dst_index--;
518 type = stack_type_map[src_index];
519 if (! TYPE_IS_WIDE (type))
520 fatal ("internal error - dup operation");
521 }
522 else if (TYPE_IS_WIDE (type))
523 fatal ("internal error - dup operation");
524 if (src_index != dst_index)
525 {
526 tree src_decl = find_stack_slot (src_index, type);
527 tree dst_decl = find_stack_slot (dst_index, type);
528 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
529 stack_type_map[dst_index] = type;
530 }
531 }
532 }
533
534 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
535 value stack. */
536
537 static void
538 build_java_athrow (node)
539 tree node;
540 {
541 tree call;
542
543 call = build (CALL_EXPR,
544 void_type_node,
545 build_address_of (throw_node[exceptions_via_longjmp ? 1 : 0]),
546 build_tree_list (NULL_TREE, node),
547 NULL_TREE);
548 TREE_SIDE_EFFECTS (call) = 1;
549 expand_expr_stmt (call);
550 java_stack_pop (stack_pointer);
551 }
552
553 /* Implementation for jsr/ret */
554
555 static void
556 build_java_jsr (where, ret)
557 tree where;
558 tree ret;
559 {
560 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
561 push_value (ret_label);
562 flush_quick_stack ();
563 expand_goto (where);
564 expand_label (ret);
565 }
566
567 static void
568 build_java_ret (location)
569 tree location;
570 {
571 expand_computed_goto (location);
572 }
573
574 /* Implementation of operations on array: new, load, store, length */
575
576 /* Array core info access macros */
577
578 #define JAVA_ARRAY_LENGTH_OFFSET(A) \
579 size_binop (CEIL_DIV_EXPR, \
580 (DECL_FIELD_BITPOS \
581 (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
582 bitsize_int (BITS_PER_UNIT))
583
584 tree
585 decode_newarray_type (atype)
586 int atype;
587 {
588 switch (atype)
589 {
590 case 4: return boolean_type_node;
591 case 5: return char_type_node;
592 case 6: return float_type_node;
593 case 7: return double_type_node;
594 case 8: return byte_type_node;
595 case 9: return short_type_node;
596 case 10: return int_type_node;
597 case 11: return long_type_node;
598 default: return NULL_TREE;
599 }
600 }
601
602 /* Map primitive type to the code used by OPCODE_newarray. */
603
604 int
605 encode_newarray_type (type)
606 tree type;
607 {
608 if (type == boolean_type_node)
609 return 4;
610 else if (type == char_type_node)
611 return 5;
612 else if (type == float_type_node)
613 return 6;
614 else if (type == double_type_node)
615 return 7;
616 else if (type == byte_type_node)
617 return 8;
618 else if (type == short_type_node)
619 return 9;
620 else if (type == int_type_node)
621 return 10;
622 else if (type == long_type_node)
623 return 11;
624 else
625 fatal ("Can't compute type code - patch_newarray");
626 }
627
628 /* Build a call to _Jv_ThrowBadArrayIndex(), the
629 ArrayIndexOfBoundsException exception handler. */
630
631 static tree
632 build_java_throw_out_of_bounds_exception (index)
633 tree index;
634 {
635 tree node = build (CALL_EXPR, int_type_node,
636 build_address_of (soft_badarrayindex_node),
637 build_tree_list (NULL_TREE, index), NULL_TREE);
638 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
639 return (node);
640 }
641
642 /* Return the length of an array. Doesn't perform any checking on the nature
643 or value of the array NODE. May be used to implement some bytecodes. */
644
645 tree
646 build_java_array_length_access (node)
647 tree node;
648 {
649 tree type = TREE_TYPE (node);
650 HOST_WIDE_INT length;
651 if (!is_array_type_p (type))
652 fatal ("array length on a non-array reference");
653 length = java_array_type_length (type);
654 if (length >= 0)
655 return build_int_2 (length, 0);
656 return fold (build1 (INDIRECT_REF,
657 int_type_node,
658 fold (build (PLUS_EXPR, ptr_type_node,
659 node,
660 JAVA_ARRAY_LENGTH_OFFSET(node)))));
661 }
662
663 /* Optionally checks an array against the NULL pointer, eventually throwing a
664 NullPointerException. It could replace signal handling, but tied to NULL.
665 ARG1: the pointer to check, ARG2: the expression to use if
666 the pointer is non-null and ARG3 the type that should be returned. */
667
668 tree
669 build_java_arraynull_check (node, expr, type)
670 tree node ATTRIBUTE_UNUSED;
671 tree expr;
672 tree type ATTRIBUTE_UNUSED;
673 {
674 #if 0
675 static int java_array_access_throws_null_exception = 0;
676 node = ???;
677 if (java_array_access_throws_null_exception)
678 return (build (COND_EXPR,
679 type,
680 build (EQ_EXPR, int_type_node, node, null_pointer_node),
681 build_java_athrow (node), expr ));
682 else
683 #endif
684 return (expr);
685 }
686
687 static tree
688 java_array_data_offset (array)
689 tree array;
690 {
691 tree array_type = TREE_TYPE (TREE_TYPE (array));
692 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
693 if (data_fld == NULL_TREE)
694 return size_in_bytes (array_type);
695 else
696 return build_int_2 (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (data_fld))
697 / BITS_PER_UNIT, 0);
698 }
699
700 /* Implement array indexing (either as l-value or r-value).
701 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
702 Optionally performs bounds checking and/or test to NULL.
703 At this point, ARRAY should have been verified as an array. */
704
705 tree
706 build_java_arrayaccess (array, type, index)
707 tree array, type, index;
708 {
709 tree arith, node, throw = NULL_TREE;
710
711 arith = fold (build (PLUS_EXPR, int_type_node,
712 java_array_data_offset (array),
713 fold (build (MULT_EXPR, int_type_node,
714 index, size_in_bytes(type)))));
715
716 if (flag_bounds_check)
717 {
718 /* Generate:
719 * (unsigned jint) INDEX >= (unsigned jint) LEN
720 * && throw ArrayIndexOutOfBoundsException.
721 * Note this is equivalent to and more efficient than:
722 * INDEX < 0 || INDEX >= LEN && throw ... */
723 tree test;
724 tree len = build_java_array_length_access (array);
725 TREE_TYPE (len) = unsigned_int_type_node;
726 test = fold (build (GE_EXPR, boolean_type_node,
727 convert (unsigned_int_type_node, index),
728 len));
729 if (! integer_zerop (test))
730 {
731 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
732 build_java_throw_out_of_bounds_exception (index));
733 /* allows expansion within COMPOUND */
734 TREE_SIDE_EFFECTS( throw ) = 1;
735 }
736 }
737
738 node = build1 (INDIRECT_REF, type,
739 fold (build (PLUS_EXPR, ptr_type_node,
740 array,
741 (throw ? build (COMPOUND_EXPR, int_type_node,
742 throw, arith )
743 : arith))));
744
745 return (fold (build_java_arraynull_check (array, node, type)));
746 }
747
748 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
749 ARRAY_NODE. This function is used to retrieve something less vague than
750 a pointer type when indexing the first dimension of something like [[<t>.
751 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
752 return unchanged.
753 As a side effect, it also makes sure that ARRAY_NODE is an array. */
754
755 static tree
756 build_java_check_indexed_type (array_node, indexed_type)
757 tree array_node;
758 tree indexed_type;
759 {
760 tree elt_type;
761
762 if (!is_array_type_p (TREE_TYPE (array_node)))
763 fatal ("array indexing on a non-array reference");
764
765 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
766
767 if (indexed_type == ptr_type_node )
768 return promote_type (elt_type);
769
770 /* BYTE/BOOLEAN store and load are used for both type */
771 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
772 return boolean_type_node;
773
774 if (indexed_type != elt_type )
775 fatal ("type array element mismatch");
776 else
777 return indexed_type;
778 }
779
780 /* newarray triggers a call to _Jv_NewArray. This function should be called
781 with an integer code (the type of array to create) and get from the stack
782 the size of the dimmension. */
783
784 tree
785 build_newarray (atype_value, length)
786 int atype_value;
787 tree length;
788 {
789 tree type
790 = build_java_array_type (decode_newarray_type (atype_value),
791 TREE_CODE (length) == INTEGER_CST
792 ? (HOST_WIDE_INT) TREE_INT_CST_LOW (length) : -1);
793
794 return build (CALL_EXPR, promote_type (type),
795 build_address_of (soft_newarray_node),
796 tree_cons (NULL_TREE,
797 build_int_2 (atype_value, 0),
798 build_tree_list (NULL_TREE, length)),
799 NULL_TREE);
800 }
801
802 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
803 of the dimension. */
804
805 tree
806 build_anewarray (class_type, length)
807 tree class_type;
808 tree length;
809 {
810 tree type
811 = build_java_array_type (class_type,
812 TREE_CODE (length) == INTEGER_CST
813 ? (HOST_WIDE_INT) TREE_INT_CST_LOW (length) : -1);
814
815 return build (CALL_EXPR, promote_type (type),
816 build_address_of (soft_anewarray_node),
817 tree_cons (NULL_TREE, length,
818 tree_cons (NULL_TREE, build_class_ref (class_type),
819 build_tree_list (NULL_TREE,
820 null_pointer_node))),
821 NULL_TREE);
822 }
823
824 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
825
826 tree
827 build_new_array (type, length)
828 tree type;
829 tree length;
830 {
831 if (JPRIMITIVE_TYPE_P (type))
832 return build_newarray (encode_newarray_type (type), length);
833 else
834 return build_anewarray (TREE_TYPE (type), length);
835 }
836
837 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
838 class pointer, a number of dimensions and the matching number of
839 dimensions. The argument list is NULL terminated. */
840
841 static void
842 expand_java_multianewarray (class_type, ndim)
843 tree class_type;
844 int ndim;
845 {
846 int i;
847 tree args = build_tree_list( NULL_TREE, null_pointer_node );
848
849 for( i = 0; i < ndim; i++ )
850 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
851
852 push_value (build (CALL_EXPR,
853 promote_type (class_type),
854 build_address_of (soft_multianewarray_node),
855 tree_cons (NULL_TREE, build_class_ref (class_type),
856 tree_cons (NULL_TREE,
857 build_int_2 (ndim, 0), args )),
858 NULL_TREE));
859 }
860
861 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
862 ARRAY is an array type. May expand some bound checking and NULL
863 pointer checking. RHS_TYPE_NODE we are going to store. In the case
864 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
865 INT. In those cases, we make the convertion.
866
867 if ARRAy is a reference type, the assignment is checked at run-time
868 to make sure that the RHS can be assigned to the array element
869 type. It is not necessary to generate this code if ARRAY is final. */
870
871 static void
872 expand_java_arraystore (rhs_type_node)
873 tree rhs_type_node;
874 {
875 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
876 && TYPE_PRECISION (rhs_type_node) <= 32) ?
877 int_type_node : rhs_type_node);
878 tree index = pop_value (int_type_node);
879 tree array = pop_value (ptr_type_node);
880
881 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
882
883 flush_quick_stack ();
884
885 index = save_expr (index);
886 array = save_expr (array);
887
888 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
889 {
890 tree check = build (CALL_EXPR, void_type_node,
891 build_address_of (soft_checkarraystore_node),
892 tree_cons (NULL_TREE, array,
893 build_tree_list (NULL_TREE, rhs_node)),
894 NULL_TREE);
895 TREE_SIDE_EFFECTS (check) = 1;
896 expand_expr_stmt (check);
897 }
898
899 expand_assignment (build_java_arrayaccess (array,
900 rhs_type_node,
901 index),
902 rhs_node, 0, 0);
903 }
904
905 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
906 sure that LHS is an array type. May expand some bound checking and NULL
907 pointer checking.
908 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
909 BOOLEAN/SHORT, we push a promoted type back to the stack.
910 */
911
912 static void
913 expand_java_arrayload (lhs_type_node )
914 tree lhs_type_node;
915 {
916 tree load_node;
917 tree index_node = pop_value (int_type_node);
918 tree array_node = pop_value (ptr_type_node);
919
920 index_node = save_expr (index_node);
921 array_node = save_expr (array_node);
922 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
923
924 load_node = build_java_arrayaccess (array_node,
925 lhs_type_node,
926 index_node);
927
928 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
929 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
930 push_value (load_node);
931 }
932
933 /* Expands .length. Makes sure that we deal with and array and may expand
934 a NULL check on the array object. */
935
936 static void
937 expand_java_array_length ()
938 {
939 tree array = pop_value (ptr_type_node);
940 tree length = build_java_array_length_access (array);
941
942 push_value (build_java_arraynull_check (array, length, int_type_node));
943 }
944
945 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
946 either soft_monitorenter_node or soft_monitorexit_node. */
947
948 static tree
949 build_java_monitor (call, object)
950 tree call;
951 tree object;
952 {
953 return (build (CALL_EXPR,
954 void_type_node,
955 build_address_of (call),
956 build_tree_list (NULL_TREE, object),
957 NULL_TREE));
958 }
959
960 /* Emit code for one of the PUSHC instructions. */
961
962 static void
963 expand_java_pushc (ival, type)
964 int ival;
965 tree type;
966 {
967 tree value;
968 if (type == ptr_type_node && ival == 0)
969 value = null_pointer_node;
970 else if (type == int_type_node || type == long_type_node)
971 {
972 value = build_int_2 (ival, ival < 0 ? -1 : 0);
973 TREE_TYPE (value) = type;
974 }
975 else if (type == float_type_node || type == double_type_node)
976 {
977 REAL_VALUE_TYPE x;
978 #ifdef REAL_ARITHMETIC
979 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
980 #else
981 x = ival;
982 #endif
983 value = build_real (type, x);
984 }
985 else
986 fatal ("internal error in expand_java_pushc");
987 push_value (value);
988 }
989
990 #ifndef INT_TYPE_SIZE
991 #define INT_TYPE_SIZE BITS_PER_WORD
992 #endif
993
994 static void
995 expand_java_return (type)
996 tree type;
997 {
998 if (type == void_type_node)
999 expand_null_return ();
1000 else
1001 {
1002 tree retval = pop_value (type);
1003 tree res = DECL_RESULT (current_function_decl);
1004 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1005
1006 /* Handle the situation where the native integer type is smaller
1007 than the JVM integer. It can happen for many cross compilers.
1008 The whole if expression just goes away if INT_TYPE_SIZE < 32
1009 is false. */
1010 if (INT_TYPE_SIZE < 32
1011 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1012 < GET_MODE_SIZE (TYPE_MODE (type))))
1013 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1014
1015 TREE_SIDE_EFFECTS (retval) = 1;
1016 expand_return (retval);
1017 }
1018 }
1019
1020 tree
1021 build_address_of (value)
1022 tree value;
1023 {
1024 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1025 }
1026
1027 static void
1028 expand_java_NEW (type)
1029 tree type;
1030 {
1031 if (! CLASS_LOADED_P (type))
1032 load_class (type, 1);
1033 safe_layout_class (type);
1034 push_value (build (CALL_EXPR, promote_type (type),
1035 build_address_of (alloc_object_node),
1036 tree_cons (NULL_TREE, build_class_ref (type),
1037 build_tree_list (NULL_TREE,
1038 size_in_bytes (type))),
1039 NULL_TREE));
1040 }
1041
1042 static void
1043 expand_java_INSTANCEOF (type)
1044 tree type;
1045 {
1046 tree value = pop_value (object_ptr_type_node);
1047 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
1048 build_address_of (soft_instanceof_node),
1049 tree_cons (NULL_TREE, value,
1050 build_tree_list (NULL_TREE,
1051 build_class_ref (type))),
1052 NULL_TREE);
1053 push_value (value);
1054 }
1055
1056 static void
1057 expand_java_CHECKCAST (type)
1058 tree type;
1059 {
1060 tree value = pop_value (ptr_type_node);
1061 value = build (CALL_EXPR, promote_type (type),
1062 build_address_of (soft_checkcast_node),
1063 tree_cons (NULL_TREE, build_class_ref (type),
1064 build_tree_list (NULL_TREE, value)),
1065 NULL_TREE);
1066 push_value (value);
1067 }
1068
1069 static void
1070 expand_iinc (local_var_index, ival, pc)
1071 unsigned int local_var_index;
1072 int ival;
1073 int pc;
1074 {
1075 tree local_var, res;
1076 tree constant_value;
1077
1078 flush_quick_stack ();
1079 local_var = find_local_variable (local_var_index, int_type_node, pc);
1080 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1081 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1082 expand_assignment (local_var, res, 0, 0);
1083 }
1084
1085
1086 tree
1087 build_java_soft_divmod (op, type, op1, op2)
1088 enum tree_code op;
1089 tree type, op1, op2;
1090 {
1091 tree call = NULL;
1092 tree arg1 = convert (type, op1);
1093 tree arg2 = convert (type, op2);
1094
1095 if (type == int_type_node)
1096 {
1097 switch (op)
1098 {
1099 case TRUNC_DIV_EXPR:
1100 call = soft_idiv_node;
1101 break;
1102 case TRUNC_MOD_EXPR:
1103 call = soft_irem_node;
1104 break;
1105 default:
1106 break;
1107 }
1108 }
1109 else if (type == long_type_node)
1110 {
1111 switch (op)
1112 {
1113 case TRUNC_DIV_EXPR:
1114 call = soft_ldiv_node;
1115 break;
1116 case TRUNC_MOD_EXPR:
1117 call = soft_lrem_node;
1118 break;
1119 default:
1120 break;
1121 }
1122 }
1123
1124 if (! call)
1125 fatal ("Internal compiler error in build_java_soft_divmod");
1126
1127 call = build (CALL_EXPR, type,
1128 build_address_of (call),
1129 tree_cons (NULL_TREE, arg1,
1130 build_tree_list (NULL_TREE, arg2)),
1131 NULL_TREE);
1132
1133 return call;
1134 }
1135
1136 tree
1137 build_java_binop (op, type, arg1, arg2)
1138 enum tree_code op;
1139 tree type, arg1, arg2;
1140 {
1141 tree mask;
1142 switch (op)
1143 {
1144 case URSHIFT_EXPR:
1145 {
1146 tree u_type = unsigned_type (type);
1147 arg1 = convert (u_type, arg1);
1148 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1149 return convert (type, arg1);
1150 }
1151 case LSHIFT_EXPR:
1152 case RSHIFT_EXPR:
1153 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1154 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1155 break;
1156
1157 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1158 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1159 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1160 {
1161 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1162 boolean_type_node, arg1, arg2));
1163 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1164 tree second_compare = fold (build (COND_EXPR, int_type_node,
1165 ifexp2, integer_zero_node,
1166 op == COMPARE_L_EXPR
1167 ? integer_negative_one_node
1168 : integer_one_node));
1169 return fold (build (COND_EXPR, int_type_node, ifexp1,
1170 op == COMPARE_L_EXPR ? integer_one_node
1171 : integer_negative_one_node,
1172 second_compare));
1173 }
1174 case COMPARE_EXPR:
1175 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1176 {
1177 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1178 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1179 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1180 ifexp2, integer_one_node,
1181 integer_zero_node));
1182 return fold (build (COND_EXPR, int_type_node,
1183 ifexp1, integer_negative_one_node, second_compare));
1184 }
1185 case TRUNC_DIV_EXPR:
1186 case TRUNC_MOD_EXPR:
1187 if (TREE_CODE (type) == REAL_TYPE
1188 && op == TRUNC_MOD_EXPR)
1189 {
1190 tree call;
1191 if (type != double_type_node)
1192 {
1193 arg1 = convert (double_type_node, arg1);
1194 arg2 = convert (double_type_node, arg2);
1195 }
1196 call = build (CALL_EXPR, double_type_node,
1197 build_address_of (soft_fmod_node),
1198 tree_cons (NULL_TREE, arg1,
1199 build_tree_list (NULL_TREE, arg2)),
1200 NULL_TREE);
1201 if (type != double_type_node)
1202 call = convert (type, call);
1203 return call;
1204 }
1205
1206 if (TREE_CODE (type) == INTEGER_TYPE
1207 && flag_use_divide_subroutine
1208 && ! flag_syntax_only)
1209 return build_java_soft_divmod (op, type, arg1, arg2);
1210
1211 break;
1212 default: ;
1213 }
1214 return fold (build (op, type, arg1, arg2));
1215 }
1216
1217 static void
1218 expand_java_binop (type, op)
1219 tree type; enum tree_code op;
1220 {
1221 tree larg, rarg;
1222 tree ltype = type;
1223 tree rtype = type;
1224 switch (op)
1225 {
1226 case LSHIFT_EXPR:
1227 case RSHIFT_EXPR:
1228 case URSHIFT_EXPR:
1229 rtype = int_type_node;
1230 rarg = pop_value (rtype);
1231 break;
1232 default:
1233 rarg = pop_value (rtype);
1234 }
1235 larg = pop_value (ltype);
1236 push_value (build_java_binop (op, type, larg, rarg));
1237 }
1238
1239 /* Lookup the field named NAME in *TYPEP or its super classes.
1240 If not found, return NULL_TREE.
1241 (If the *TYPEP is not found, return error_mark_node.)
1242 If found, return the FIELD_DECL, and set *TYPEP to the
1243 class containing the field. */
1244
1245 tree
1246 lookup_field (typep, name)
1247 tree *typep;
1248 tree name;
1249 {
1250 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1251 {
1252 load_class (*typep, 1);
1253 safe_layout_class (*typep);
1254 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1255 return error_mark_node;
1256 }
1257 do
1258 {
1259 tree field, basetype_vec;
1260 int n, i;
1261
1262 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1263 if (DECL_NAME (field) == name)
1264 return field;
1265
1266 /* If *typep is an innerclass, lookup the field in its enclosing
1267 contexts */
1268 if (INNER_CLASS_TYPE_P (*typep))
1269 {
1270 tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (*typep)));
1271
1272 if ((field = lookup_field (&outer_type, name)))
1273 return field;
1274 }
1275
1276 /* Process implemented interfaces. */
1277 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1278 n = TREE_VEC_LENGTH (basetype_vec);
1279 for (i = 0; i < n; i++)
1280 {
1281 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1282 if ((field = lookup_field (&t, name)))
1283 return field;
1284 }
1285 *typep = CLASSTYPE_SUPER (*typep);
1286 } while (*typep);
1287 return NULL_TREE;
1288 }
1289
1290 /* Look up the field named NAME in object SELF_VALUE,
1291 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1292 SELF_VALUE is NULL_TREE if looking for a static field. */
1293
1294 tree
1295 build_field_ref (self_value, self_class, name)
1296 tree self_value, self_class, name;
1297 {
1298 tree base_class = self_class;
1299 tree field_decl = lookup_field (&base_class, name);
1300 if (field_decl == NULL_TREE)
1301 {
1302 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1303 return error_mark_node;
1304 }
1305 if (self_value == NULL_TREE)
1306 {
1307 return build_static_field_ref (field_decl);
1308 }
1309 else
1310 {
1311 tree base_handle_type = promote_type (base_class);
1312 if (base_handle_type != TREE_TYPE (self_value))
1313 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1314 #ifdef JAVA_USE_HANDLES
1315 self_value = unhand_expr (self_value);
1316 #endif
1317 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1318 self_value);
1319 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1320 self_value, field_decl));
1321 }
1322 }
1323
1324 tree
1325 lookup_label (pc)
1326 int pc;
1327 {
1328 tree name;
1329 char buf[32];
1330 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1331 name = get_identifier (buf);
1332 if (IDENTIFIER_LOCAL_VALUE (name))
1333 return IDENTIFIER_LOCAL_VALUE (name);
1334 else
1335 {
1336 /* The type of the address of a label is return_address_type_node. */
1337 tree decl = create_label_decl (name);
1338 LABEL_PC (decl) = pc;
1339 label_rtx (decl);
1340 return pushdecl (decl);
1341 }
1342 }
1343
1344 /* Generate a unique name for the purpose of loops and switches
1345 labels, and try-catch-finally blocks label or temporary variables. */
1346
1347 tree
1348 generate_name ()
1349 {
1350 static int l_number = 0;
1351 char buff [32];
1352 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1353 l_number++;
1354 return get_identifier (buff);
1355 }
1356
1357 tree
1358 create_label_decl (name)
1359 tree name;
1360 {
1361 tree decl;
1362 push_obstacks (&permanent_obstack, &permanent_obstack);
1363 decl = build_decl (LABEL_DECL, name,
1364 TREE_TYPE (return_address_type_node));
1365 pop_obstacks ();
1366 DECL_CONTEXT (decl) = current_function_decl;
1367 DECL_IGNORED_P (decl) = 1;
1368 return decl;
1369 }
1370
1371 /* This maps a bytecode offset (PC) to various flags. */
1372 char *instruction_bits;
1373
1374 static void
1375 note_label (current_pc, target_pc)
1376 int current_pc ATTRIBUTE_UNUSED, target_pc;
1377 {
1378 lookup_label (target_pc);
1379 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1380 }
1381
1382 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1383 where CONDITION is one of one the compare operators. */
1384
1385 static void
1386 expand_compare (condition, value1, value2, target_pc)
1387 enum tree_code condition;
1388 tree value1, value2;
1389 int target_pc;
1390 {
1391 tree target = lookup_label (target_pc);
1392 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1393 expand_start_cond (truthvalue_conversion (cond), 0);
1394 expand_goto (target);
1395 expand_end_cond ();
1396 }
1397
1398 /* Emit code for a TEST-type opcode. */
1399
1400 static void
1401 expand_test (condition, type, target_pc)
1402 enum tree_code condition;
1403 tree type;
1404 int target_pc;
1405 {
1406 tree value1, value2;
1407 flush_quick_stack ();
1408 value1 = pop_value (type);
1409 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1410 expand_compare (condition, value1, value2, target_pc);
1411 }
1412
1413 /* Emit code for a COND-type opcode. */
1414
1415 static void
1416 expand_cond (condition, type, target_pc)
1417 enum tree_code condition;
1418 tree type;
1419 int target_pc;
1420 {
1421 tree value1, value2;
1422 flush_quick_stack ();
1423 /* note: pop values in opposite order */
1424 value2 = pop_value (type);
1425 value1 = pop_value (type);
1426 /* Maybe should check value1 and value2 for type compatibility ??? */
1427 expand_compare (condition, value1, value2, target_pc);
1428 }
1429
1430 static void
1431 expand_java_goto (target_pc)
1432 int target_pc;
1433 {
1434 tree target_label = lookup_label (target_pc);
1435 flush_quick_stack ();
1436 expand_goto (target_label);
1437 }
1438
1439 #if 0
1440 static void
1441 expand_java_call (target_pc, return_address)
1442 int target_pc, return_address;
1443 {
1444 tree target_label = lookup_label (target_pc);
1445 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1446 push_value (value);
1447 flush_quick_stack ();
1448 expand_goto (target_label);
1449 }
1450
1451 static void
1452 expand_java_ret (return_address)
1453 tree return_address ATTRIBUTE_UNUSED;
1454 {
1455 warning ("ret instruction not implemented");
1456 #if 0
1457 tree target_label = lookup_label (target_pc);
1458 flush_quick_stack ();
1459 expand_goto (target_label);
1460 #endif
1461 }
1462 #endif
1463
1464 /* Recursive helper function to pop argument types during verifiation. */
1465
1466 void
1467 pop_argument_types (arg_types)
1468 tree arg_types;
1469 {
1470 if (arg_types == end_params_node)
1471 return;
1472 if (TREE_CODE (arg_types) == TREE_LIST)
1473 {
1474 pop_argument_types (TREE_CHAIN (arg_types));
1475 pop_type (TREE_VALUE (arg_types));
1476 return;
1477 }
1478 abort ();
1479 }
1480
1481 static tree
1482 pop_arguments (arg_types)
1483 tree arg_types;
1484 {
1485 if (arg_types == end_params_node)
1486 return NULL_TREE;
1487 if (TREE_CODE (arg_types) == TREE_LIST)
1488 {
1489 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1490 tree type = TREE_VALUE (arg_types);
1491 tree arg = pop_value (type);
1492 if (PROMOTE_PROTOTYPES
1493 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1494 && INTEGRAL_TYPE_P (type))
1495 arg = convert (integer_type_node, arg);
1496 return tree_cons (NULL_TREE, arg, tail);
1497 }
1498 abort ();
1499 }
1500
1501 /* Build an expression to initialize the class CLAS.
1502 if EXPR is non-NULL, returns an expression to first call the initializer
1503 (if it is needed) and then calls EXPR. */
1504
1505 tree
1506 build_class_init (clas, expr)
1507 tree clas, expr;
1508 {
1509 tree init, call;
1510 struct init_test_hash_entry *ite;
1511 if (inherits_from_p (current_class, clas))
1512 return expr;
1513
1514 if (always_initialize_class_p)
1515 {
1516 init = build (CALL_EXPR, void_type_node,
1517 build_address_of (soft_initclass_node),
1518 build_tree_list (NULL_TREE, build_class_ref (clas)),
1519 NULL_TREE);
1520 TREE_SIDE_EFFECTS (init) = 1;
1521 }
1522 else
1523 {
1524 ite = (struct init_test_hash_entry *)
1525 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1526 (const hash_table_key) clas,
1527 TRUE, NULL);
1528
1529 if (ite->init_test_decl == 0)
1530 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1531 boolean_type_node);
1532 /* Tell the check-init code to ignore this decl. */
1533 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1534
1535 init = build (CALL_EXPR, void_type_node,
1536 build_address_of (soft_initclass_node),
1537 build_tree_list (NULL_TREE, build_class_ref (clas)),
1538 NULL_TREE);
1539 TREE_SIDE_EFFECTS (init) = 1;
1540 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1541 build (MODIFY_EXPR, boolean_type_node,
1542 ite->init_test_decl, boolean_true_node));
1543 TREE_SIDE_EFFECTS (call) = 1;
1544 init = build (COND_EXPR, void_type_node,
1545 build (EQ_EXPR, boolean_type_node,
1546 ite->init_test_decl, boolean_false_node),
1547 call, integer_zero_node);
1548 TREE_SIDE_EFFECTS (init) = 1;
1549 }
1550
1551 if (expr != NULL_TREE)
1552 {
1553 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1554 TREE_SIDE_EFFECTS (expr) = 1;
1555 return expr;
1556 }
1557 return init;
1558 }
1559
1560 static tree methods_ident = NULL_TREE;
1561 static tree ncode_ident = NULL_TREE;
1562 tree dtable_ident = NULL_TREE;
1563
1564 tree
1565 build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
1566 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1567 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1568 {
1569 tree func;
1570 if (is_compiled_class (self_type))
1571 {
1572 make_decl_rtl (method, NULL, 1);
1573 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1574 }
1575 else
1576 {
1577 /* We don't know whether the method has been (statically) compiled.
1578 Compile this code to get a reference to the method's code:
1579
1580 SELF_TYPE->methods[METHOD_INDEX].ncode
1581
1582 This is guaranteed to work (assuming SELF_TYPE has
1583 been initialized), since if the method is not compiled yet,
1584 its ncode points to a trampoline that forces compilation. */
1585
1586 int method_index = 0;
1587 tree meth;
1588 tree ref = build_class_ref (self_type);
1589 ref = build1 (INDIRECT_REF, class_type_node, ref);
1590 if (ncode_ident == NULL_TREE)
1591 ncode_ident = get_identifier ("ncode");
1592 if (methods_ident == NULL_TREE)
1593 methods_ident = get_identifier ("methods");
1594 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1595 lookup_field (&class_type_node, methods_ident));
1596 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1597 ; meth = TREE_CHAIN (meth))
1598 {
1599 if (method == meth)
1600 break;
1601 if (meth == NULL_TREE)
1602 fatal ("method '%s' not found in class",
1603 IDENTIFIER_POINTER (DECL_NAME (method)));
1604 method_index++;
1605 }
1606 method_index *= int_size_in_bytes (method_type_node);
1607 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1608 ref, build_int_2 (method_index, 0)));
1609 ref = build1 (INDIRECT_REF, method_type_node, ref);
1610 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1611 ref,
1612 lookup_field (&method_type_node, ncode_ident));
1613 }
1614 return func;
1615 }
1616
1617 tree
1618 invoke_build_dtable (is_invoke_interface, arg_list)
1619 int is_invoke_interface;
1620 tree arg_list;
1621 {
1622 tree dtable, objectref;
1623
1624 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1625
1626 /* If we're dealing with interfaces and if the objectref
1627 argument is an array then get the dispatch table of the class
1628 Object rather than the one from the objectref. */
1629 objectref = (is_invoke_interface
1630 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1631 object_type_node : TREE_VALUE (arg_list));
1632
1633 if (dtable_ident == NULL_TREE)
1634 dtable_ident = get_identifier ("vtable");
1635 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1636 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1637 lookup_field (&object_type_node, dtable_ident));
1638
1639 return dtable;
1640 }
1641
1642 tree
1643 build_invokevirtual (dtable, method)
1644 tree dtable, method;
1645 {
1646 tree func;
1647 tree nativecode_ptr_ptr_type_node
1648 = build_pointer_type (nativecode_ptr_type_node);
1649 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1650 /* Add one to skip "class" field of dtable, and one to skip unused
1651 vtable entry (for C++ compatibility). */
1652 method_index += 2;
1653 method_index
1654 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1655 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1656 dtable, build_int_2 (method_index, 0)));
1657 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1658
1659 return func;
1660 }
1661
1662 tree
1663 build_invokeinterface (dtable, method)
1664 tree dtable, method;
1665 {
1666 static tree class_ident = NULL_TREE;
1667 tree lookup_arg;
1668 tree interface;
1669 tree idx;
1670 tree meth;
1671 int i;
1672
1673 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1674 ensure that the selected method exists, is public and not
1675 abstract nor static. */
1676
1677 if (class_ident == NULL_TREE)
1678 class_ident = get_identifier ("class");
1679
1680 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1681 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1682 lookup_field (&dtable_type, class_ident));
1683
1684 interface = DECL_CONTEXT (method);
1685
1686 i = 1;
1687 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
1688 {
1689 if (meth == method)
1690 {
1691 idx = build_int_2 (i, 0);
1692 break;
1693 }
1694 if (meth == NULL_TREE)
1695 fatal ("internal error in build_invokeinterface");
1696 }
1697
1698 lookup_arg = tree_cons (NULL_TREE, dtable,
1699 tree_cons (NULL_TREE, build_class_ref (interface),
1700 build_tree_list (NULL_TREE, idx)));
1701
1702 return build (CALL_EXPR, ptr_type_node,
1703 build_address_of (soft_lookupinterfacemethod_node),
1704 lookup_arg, NULL_TREE);
1705 }
1706
1707 /* Expand one of the invoke_* opcodes.
1708 OCPODE is the specific opcode.
1709 METHOD_REF_INDEX is an index into the constant pool.
1710 NARGS is the number of arguments, or -1 if not specified. */
1711
1712 static void
1713 expand_invoke (opcode, method_ref_index, nargs)
1714 int opcode;
1715 int method_ref_index;
1716 int nargs ATTRIBUTE_UNUSED;
1717 {
1718 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1719 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1720 tree self_type = get_class_constant
1721 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
1722 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1723 tree call, func, method, arg_list, method_type;
1724
1725 if (! CLASS_LOADED_P (self_type))
1726 {
1727 load_class (self_type, 1);
1728 safe_layout_class (self_type);
1729 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1730 fatal ("failed to find class '%s'", self_name);
1731 }
1732 layout_class_methods (self_type);
1733
1734 if (ID_INIT_P (method_name))
1735 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1736 method_signature);
1737 else
1738 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1739 method_name, method_signature);
1740 if (method == NULL_TREE)
1741 {
1742 error ("Class '%s' has no method named '%s' matching signature '%s'",
1743 self_name,
1744 IDENTIFIER_POINTER (method_name),
1745 IDENTIFIER_POINTER (method_signature));
1746 }
1747 /* Invoke static can't invoke static/abstract method */
1748 else if (opcode == OPCODE_invokestatic)
1749 {
1750 if (!METHOD_STATIC (method))
1751 {
1752 error ("invokestatic on non static method");
1753 method = NULL_TREE;
1754 }
1755 else if (METHOD_ABSTRACT (method))
1756 {
1757 error ("invokestatic on abstract method");
1758 method = NULL_TREE;
1759 }
1760 }
1761 else
1762 {
1763 if (METHOD_STATIC (method))
1764 {
1765 error ("invoke[non-static] on static method");
1766 method = NULL_TREE;
1767 }
1768 }
1769
1770 if (method == NULL_TREE)
1771 {
1772 method_type = get_type_from_signature (method_signature);
1773 pop_arguments (TYPE_ARG_TYPES (method_type));
1774 if (opcode != OPCODE_invokestatic)
1775 pop_type (self_type);
1776 method_type = promote_type (TREE_TYPE (method_type));
1777 push_value (convert (method_type, integer_zero_node));
1778 return;
1779 }
1780
1781 method_type = TREE_TYPE (method);
1782 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1783 flush_quick_stack ();
1784
1785 func = NULL_TREE;
1786 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1787 || (opcode == OPCODE_invokevirtual
1788 && (METHOD_PRIVATE (method)
1789 || METHOD_FINAL (method)
1790 || CLASS_FINAL (TYPE_NAME (self_type)))))
1791 func = build_known_method_ref (method, method_type, self_type,
1792 method_signature, arg_list);
1793 else
1794 {
1795 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1796 arg_list);
1797 if (opcode == OPCODE_invokevirtual)
1798 func = build_invokevirtual (dtable, method);
1799 else
1800 func = build_invokeinterface (dtable, method);
1801 }
1802 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1803 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1804 TREE_SIDE_EFFECTS (call) = 1;
1805
1806 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1807 expand_expr_stmt (call);
1808 else
1809 {
1810 push_value (call);
1811 flush_quick_stack ();
1812 }
1813 }
1814
1815
1816 /* Expand an operation to extract from or store into a field.
1817 IS_STATIC is 1 iff the field is static.
1818 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1819 FIELD_REF_INDEX is an index into the constant pool. */
1820
1821 static void
1822 expand_java_field_op (is_static, is_putting, field_ref_index)
1823 int is_static;
1824 int is_putting;
1825 int field_ref_index;
1826 {
1827 tree self_type =
1828 get_class_constant (current_jcf,
1829 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1830 field_ref_index));
1831 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
1832 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
1833 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
1834 field_ref_index);
1835 tree field_type = get_type_from_signature (field_signature);
1836 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1837 tree field_ref;
1838 int is_error = 0;
1839 tree field_decl = lookup_field (&self_type, field_name);
1840 if (field_decl == error_mark_node)
1841 {
1842 is_error = 1;
1843 }
1844 else if (field_decl == NULL_TREE)
1845 {
1846 error ("Missing field '%s' in '%s'",
1847 IDENTIFIER_POINTER (field_name), self_name);
1848 is_error = 1;
1849 }
1850 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1851 {
1852 error ("Mismatching signature for field '%s' in '%s'",
1853 IDENTIFIER_POINTER (field_name), self_name);
1854 is_error = 1;
1855 }
1856 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1857 if (is_error)
1858 {
1859 if (! is_putting)
1860 push_value (convert (field_type, integer_zero_node));
1861 flush_quick_stack ();
1862 return;
1863 }
1864
1865 /* Inline references to java.lang.PRIMTYPE.TYPE.
1866 In addition to being a useful (minor) optimization,
1867 this is also needed to avoid circularities in the implementation
1868 of these fields in libjava. */
1869 if (field_name == TYPE_identifier_node && ! is_putting
1870 && ! flag_emit_class_files && field_type == class_ptr_type
1871 && strncmp (self_name, "java.lang.", 10) == 0)
1872 {
1873 tree typ = build_primtype_type_ref (self_name);
1874 if (typ)
1875 {
1876 push_value (typ);
1877 return;
1878 }
1879 }
1880
1881 field_ref = build_field_ref (field_ref, self_type, field_name);
1882 if (is_static)
1883 field_ref = build_class_init (self_type, field_ref);
1884 if (is_putting)
1885 {
1886 flush_quick_stack ();
1887 if (FIELD_FINAL (field_decl))
1888 {
1889 if (DECL_CONTEXT (field_decl) != current_class)
1890 error_with_decl (field_decl,
1891 "assignment to final field `%s' not in field's class");
1892 else if (FIELD_STATIC (field_decl))
1893 {
1894 if (!DECL_CLINIT_P (current_function_decl))
1895 error_with_decl (field_decl,
1896 "assignment to final static field `%s' not in class initializer");
1897 }
1898 else
1899 {
1900 tree cfndecl_name = DECL_NAME (current_function_decl);
1901 if (! DECL_CONSTRUCTOR_P (current_function_decl)
1902 && (cfndecl_name != finit_identifier_node))
1903 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
1904 }
1905 }
1906 expand_assignment (field_ref, new_value, 0, 0);
1907 }
1908 else
1909 push_value (field_ref);
1910 }
1911
1912 tree
1913 build_primtype_type_ref (self_name)
1914 const char *self_name;
1915 {
1916 const char *class_name = self_name+10;
1917 tree typ;
1918 if (strncmp(class_name, "Byte", 4) == 0)
1919 typ = byte_type_node;
1920 else if (strncmp(class_name, "Short", 5) == 0)
1921 typ = short_type_node;
1922 else if (strncmp(class_name, "Integer", 7) == 0)
1923 typ = int_type_node;
1924 else if (strncmp(class_name, "Long", 4) == 0)
1925 typ = long_type_node;
1926 else if (strncmp(class_name, "Float", 5) == 0)
1927 typ = float_type_node;
1928 else if (strncmp(class_name, "Double", 6) == 0)
1929 typ = double_type_node;
1930 else if (strncmp(class_name, "Boolean", 7) == 0)
1931 typ = boolean_type_node;
1932 else if (strncmp(class_name, "Char", 4) == 0)
1933 typ = char_type_node;
1934 else if (strncmp(class_name, "Void", 4) == 0)
1935 typ = void_type_node;
1936 else
1937 typ = NULL_TREE;
1938 if (typ != NULL_TREE)
1939 return build_class_ref (typ);
1940 else
1941 return NULL_TREE;
1942 }
1943
1944 void
1945 load_type_state (label)
1946 tree label;
1947 {
1948 int i;
1949 tree vec = LABEL_TYPE_STATE (label);
1950 int cur_length = TREE_VEC_LENGTH (vec);
1951 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1952 for (i = 0; i < cur_length; i++)
1953 type_map [i] = TREE_VEC_ELT (vec, i);
1954 }
1955
1956 /* Do the expansion of a Java switch. With Gcc, switches are front-end
1957 dependant things, but they rely on gcc routines. This function is
1958 placed here because it uses things defined locally in parse.y. */
1959
1960 static tree
1961 case_identity (t, v)
1962 tree t __attribute__ ((__unused__));
1963 tree v;
1964 {
1965 return v;
1966 }
1967
1968 struct rtx_def *
1969 java_lang_expand_expr (exp, target, tmode, modifier)
1970 register tree exp;
1971 rtx target ATTRIBUTE_UNUSED;
1972 enum machine_mode tmode ATTRIBUTE_UNUSED;
1973 enum expand_modifier modifier ATTRIBUTE_UNUSED;
1974 {
1975 tree current;
1976
1977 switch (TREE_CODE (exp))
1978 {
1979 case NEW_ARRAY_INIT:
1980 {
1981 rtx tmp;
1982 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1983 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1984 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1985 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1986 tree length = build_int_2 (ilength, 0);
1987 tree init = TREE_OPERAND (exp, 0);
1988 tree array_decl;
1989 #if 0
1990 /* Enable this once we can set the vtable field statically. FIXME */
1991 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
1992 && JPRIMITIVE_TYPE_P (element_type))
1993 {
1994 tree temp, value, init_decl;
1995 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1996 PUSH_FIELD_VALUE (temp, "vtable",
1997 null_pointer_node /* FIXME */
1998 );
1999 if (! flag_hash_synchronization)
2000 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2001 FINISH_RECORD_CONSTRUCTOR (temp);
2002 START_RECORD_CONSTRUCTOR (value, array_type);
2003 PUSH_SUPER_VALUE (value, temp);
2004 PUSH_FIELD_VALUE (value, "length", length);
2005 PUSH_FIELD_VALUE (value, "data", init);
2006 FINISH_RECORD_CONSTRUCTOR (value);
2007
2008 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2009 pushdecl_top_level (init_decl);
2010 TREE_STATIC (init_decl) = 1;
2011 DECL_INITIAL (init_decl) = value;
2012 DECL_IGNORED_P (init_decl) = 1;
2013 TREE_READONLY (init_decl) = 1;
2014 make_decl_rtl (init_decl, NULL, 1);
2015 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2016 return expand_expr (init, target, tmode, modifier);
2017 }
2018 #endif
2019 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2020 expand_decl (array_decl);
2021 tmp = expand_assignment (array_decl,
2022 build_new_array (element_type, length),
2023 1, 0);
2024 if (TREE_CONSTANT (init)
2025 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2026 {
2027 tree init_decl = build_decl (VAR_DECL, generate_name (),
2028 TREE_TYPE (init));
2029 pushdecl_top_level (init_decl);
2030 TREE_STATIC (init_decl) = 1;
2031 DECL_INITIAL (init_decl) = init;
2032 DECL_IGNORED_P (init_decl) = 1;
2033 TREE_READONLY (init_decl) = 1;
2034 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2035 make_decl_rtl (init_decl, NULL, 1);
2036 init = init_decl;
2037 }
2038 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2039 build1 (INDIRECT_REF, array_type, array_decl),
2040 data_fld),
2041 init, 0, 0);
2042 return tmp;
2043 }
2044 case BLOCK:
2045 if (BLOCK_EXPR_BODY (exp))
2046 {
2047 tree local;
2048 tree body = BLOCK_EXPR_BODY (exp);
2049 pushlevel (2); /* 2 and above */
2050 expand_start_bindings (0);
2051 local = BLOCK_EXPR_DECLS (exp);
2052 while (local)
2053 {
2054 tree next = TREE_CHAIN (local);
2055 layout_decl (local, 0);
2056 expand_decl (pushdecl (local));
2057 local = next;
2058 }
2059 /* Avoid deep recursion for long block. */
2060 while (TREE_CODE (body) == COMPOUND_EXPR)
2061 {
2062 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2063 emit_queue ();
2064 body = TREE_OPERAND (body, 1);
2065 }
2066 expand_expr (body, const0_rtx, VOIDmode, 0);
2067 emit_queue ();
2068 poplevel (1, 1, 0);
2069 expand_end_bindings (getdecls (), 1, 0);
2070 return const0_rtx;
2071 }
2072 return const0_rtx;
2073
2074 case CASE_EXPR:
2075 {
2076 tree duplicate;
2077 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2078 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2079 &duplicate) == 2)
2080 {
2081 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2082 parse_error_context
2083 (wfl_operator, "Duplicate case label: `%s'",
2084 print_int_node (TREE_OPERAND (exp, 0)));
2085 }
2086 return const0_rtx;
2087 }
2088
2089 case DEFAULT_EXPR:
2090 pushcase (NULL_TREE, 0,
2091 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2092 return const0_rtx;
2093
2094 case SWITCH_EXPR:
2095 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2096 expand_expr_stmt (TREE_OPERAND (exp, 1));
2097 expand_end_case (TREE_OPERAND (exp, 0));
2098 return const0_rtx;
2099
2100 case TRY_EXPR:
2101 /* We expand a try[-catch] block */
2102
2103 /* Expand the try block */
2104 push_obstacks (&permanent_obstack, &permanent_obstack);
2105 expand_eh_region_start ();
2106 pop_obstacks ();
2107 expand_expr_stmt (TREE_OPERAND (exp, 0));
2108 push_obstacks (&permanent_obstack, &permanent_obstack);
2109 expand_start_all_catch ();
2110 pop_obstacks ();
2111
2112 /* Expand all catch clauses (EH handlers) */
2113 for (current = TREE_OPERAND (exp, 1); current;
2114 current = TREE_CHAIN (current))
2115 {
2116 tree type;
2117 tree catch = TREE_OPERAND (current, 0);
2118 tree decl = BLOCK_EXPR_DECLS (catch);
2119 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2120 start_catch_handler (prepare_eh_table_type (type));
2121 expand_expr_stmt (TREE_OPERAND (current, 0));
2122
2123 expand_resume_after_catch ();
2124 end_catch_handler ();
2125 }
2126 expand_end_all_catch ();
2127 return const0_rtx;
2128
2129 default:
2130 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2131 tree_code_name [TREE_CODE (exp)]);
2132 }
2133 }
2134
2135 void
2136 expand_byte_code (jcf, method)
2137 JCF *jcf;
2138 tree method;
2139 {
2140 int PC;
2141 int i;
2142 int saw_index;
2143 const unsigned char *linenumber_pointer;
2144 int dead_code_index = -1;
2145
2146 #undef RET /* Defined by config/i386/i386.h */
2147 #undef AND /* Causes problems with opcodes for iand and land. */
2148 #undef PTR
2149 #define BCODE byte_ops
2150 #define BYTE_type_node byte_type_node
2151 #define SHORT_type_node short_type_node
2152 #define INT_type_node int_type_node
2153 #define LONG_type_node long_type_node
2154 #define CHAR_type_node char_type_node
2155 #define PTR_type_node ptr_type_node
2156 #define FLOAT_type_node float_type_node
2157 #define DOUBLE_type_node double_type_node
2158 #define VOID_type_node void_type_node
2159 jint INT_temp;
2160 unsigned char* byte_ops;
2161 long length = DECL_CODE_LENGTH (method);
2162
2163 stack_pointer = 0;
2164 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2165 byte_ops = jcf->read_ptr;
2166
2167 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2168 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2169 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2170 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2171
2172 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2173
2174 instruction_bits = oballoc (length + 1);
2175 bzero (instruction_bits, length + 1);
2176
2177 /* We make an initial pass of the line number table, to note
2178 which instructions have associated line number entries. */
2179 linenumber_pointer = linenumber_table;
2180 for (i = 0; i < linenumber_count; i++)
2181 {
2182 int pc = GET_u2 (linenumber_pointer);
2183 linenumber_pointer += 4;
2184 if (pc >= length)
2185 warning ("invalid PC in line number table");
2186 else
2187 {
2188 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2189 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2190 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2191 }
2192 }
2193
2194 /* Do a preliminary pass.
2195 * This figures out which PC can be the targets of jumps. */
2196 for (PC = 0; PC < length;)
2197 {
2198 int oldpc = PC; /* PC at instruction start. */
2199 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2200 switch (byte_ops[PC++])
2201 {
2202 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2203 case OPCODE: \
2204 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2205 break;
2206
2207 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2208
2209 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2210 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2211 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2212 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2213 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2214 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2215 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2216 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2217
2218 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2219 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2220 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2221 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2222 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2223 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2224 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2225 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2226
2227 /* two forms of wide instructions */
2228 #define PRE_SPECIAL_WIDE(IGNORE) \
2229 { \
2230 int modified_opcode = IMMEDIATE_u1; \
2231 if (modified_opcode == OPCODE_iinc) \
2232 { \
2233 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2234 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2235 } \
2236 else \
2237 { \
2238 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2239 } \
2240 }
2241
2242 /* nothing */ /* XXX JH */
2243
2244 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2245
2246 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2247
2248 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2249 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2250 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2251 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2252 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2253 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2254 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2255 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2256 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2257 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2258
2259 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2260 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2261 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2262 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2263 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2264 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2265 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2266 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2267
2268 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2269
2270 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2271 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2272
2273 #define PRE_LOOKUP_SWITCH \
2274 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2275 NOTE_LABEL (default_offset+oldpc); \
2276 if (npairs >= 0) \
2277 while (--npairs >= 0) { \
2278 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2279 jint offset = IMMEDIATE_s4; \
2280 NOTE_LABEL (offset+oldpc); } \
2281 }
2282
2283 #define PRE_TABLE_SWITCH \
2284 { jint default_offset = IMMEDIATE_s4; \
2285 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2286 NOTE_LABEL (default_offset+oldpc); \
2287 if (low <= high) \
2288 while (low++ <= high) { \
2289 jint offset = IMMEDIATE_s4; \
2290 NOTE_LABEL (offset+oldpc); } \
2291 }
2292
2293 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2294 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2295 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2296 (void)(IMMEDIATE_u2); \
2297 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2298
2299 #include "javaop.def"
2300 #undef JAVAOP
2301 }
2302 } /* for */
2303
2304 if (! verify_jvm_instructions (jcf, byte_ops, length))
2305 return;
2306
2307 /* Translate bytecodes to rtl instructions. */
2308 linenumber_pointer = linenumber_table;
2309 for (PC = 0; PC < length;)
2310 {
2311 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2312 {
2313 tree label = lookup_label (PC);
2314 flush_quick_stack ();
2315 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2316 expand_label (label);
2317 if (LABEL_VERIFIED (label) || PC == 0)
2318 load_type_state (label);
2319 }
2320
2321 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2322 {
2323 if (dead_code_index == -1)
2324 {
2325 /* This is the start of a region of unreachable bytecodes.
2326 They still need to be processed in order for EH ranges
2327 to get handled correctly. However, we can simply
2328 replace these bytecodes with nops. */
2329 dead_code_index = PC;
2330 }
2331
2332 /* Turn this bytecode into a nop. */
2333 byte_ops[PC] = 0x0;
2334 }
2335 else
2336 {
2337 if (dead_code_index != -1)
2338 {
2339 /* We've just reached the end of a region of dead code. */
2340 warning ("Unreachable bytecode from %d to before %d.",
2341 dead_code_index, PC);
2342 dead_code_index = -1;
2343 }
2344 }
2345
2346 /* Handle possible line number entry for this PC.
2347
2348 This code handles out-of-order and multiple linenumbers per PC,
2349 but is optimized for the case of line numbers increasing
2350 monotonically with PC. */
2351 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2352 {
2353 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2354 || GET_u2 (linenumber_pointer) != PC)
2355 linenumber_pointer = linenumber_table;
2356 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2357 {
2358 int pc = GET_u2 (linenumber_pointer);
2359 linenumber_pointer += 4;
2360 if (pc == PC)
2361 {
2362 lineno = GET_u2 (linenumber_pointer - 2);
2363 emit_line_note (input_filename, lineno);
2364 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2365 break;
2366 }
2367 }
2368 }
2369 maybe_pushlevels (PC);
2370 PC = process_jvm_instruction (PC, byte_ops, length);
2371 maybe_poplevels (PC);
2372 } /* for */
2373
2374 if (dead_code_index != -1)
2375 {
2376 /* We've just reached the end of a region of dead code. */
2377 warning ("Unreachable bytecode from %d to the end of the method.",
2378 dead_code_index);
2379 }
2380 }
2381
2382 static void
2383 java_push_constant_from_pool (jcf, index)
2384 JCF *jcf;
2385 int index;
2386 {
2387 tree c;
2388 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2389 {
2390 tree name;
2391 push_obstacks (&permanent_obstack, &permanent_obstack);
2392 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2393 index = alloc_name_constant (CONSTANT_String, name);
2394 c = build_ref_from_constant_pool (index);
2395 TREE_TYPE (c) = promote_type (string_type_node);
2396 pop_obstacks ();
2397 }
2398 else
2399 c = get_constant (jcf, index);
2400 push_value (c);
2401 }
2402
2403 int
2404 process_jvm_instruction (PC, byte_ops, length)
2405 int PC;
2406 const unsigned char* byte_ops;
2407 long length ATTRIBUTE_UNUSED;
2408 {
2409 const char *opname; /* Temporary ??? */
2410 int oldpc = PC; /* PC at instruction start. */
2411
2412 /* If the instruction is at the beginning of a exception handler,
2413 replace the top of the stack with the thrown object reference */
2414 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2415 {
2416 tree type = pop_type (ptr_type_node);
2417 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
2418 }
2419
2420 switch (byte_ops[PC++])
2421 {
2422 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2423 case OPCODE: \
2424 opname = #OPNAME; \
2425 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2426 break;
2427
2428 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2429 { \
2430 int saw_index = 0; \
2431 int index = OPERAND_VALUE; \
2432 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2433 }
2434
2435 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2436 { \
2437 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2438 tree ret = lookup_label (PC); \
2439 build_java_jsr (where, ret); \
2440 load_type_state (ret); \
2441 }
2442
2443 /* Push a constant onto the stack. */
2444 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2445 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2446 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2447 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2448
2449 /* internal macro added for use by the WIDE case */
2450 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2451 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2452
2453 /* Push local variable onto the opcode stack. */
2454 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2455 { \
2456 /* have to do this since OPERAND_VALUE may have side-effects */ \
2457 int opvalue = OPERAND_VALUE; \
2458 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2459 }
2460
2461 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2462 expand_java_return (OPERAND_TYPE##_type_node)
2463
2464 #define REM_EXPR TRUNC_MOD_EXPR
2465 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2466 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2467
2468 #define FIELD(IS_STATIC, IS_PUT) \
2469 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2470
2471 #define TEST(OPERAND_TYPE, CONDITION) \
2472 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2473
2474 #define COND(OPERAND_TYPE, CONDITION) \
2475 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2476
2477 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2478 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2479
2480 #define BRANCH_GOTO(OPERAND_VALUE) \
2481 expand_java_goto (oldpc + OPERAND_VALUE)
2482
2483 #define BRANCH_CALL(OPERAND_VALUE) \
2484 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2485
2486 #if 0
2487 #define BRANCH_RETURN(OPERAND_VALUE) \
2488 { \
2489 tree type = OPERAND_TYPE##_type_node; \
2490 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2491 expand_java_ret (value); \
2492 }
2493 #endif
2494
2495 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2496 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2497 fprintf (stderr, "(not implemented)\n")
2498 #define NOT_IMPL1(OPERAND_VALUE) \
2499 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2500 fprintf (stderr, "(not implemented)\n")
2501
2502 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2503
2504 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2505
2506 #define STACK_POP(COUNT) java_stack_pop (COUNT)
2507
2508 #define STACK_SWAP(COUNT) java_stack_swap()
2509
2510 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2511 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2512 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2513
2514 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2515 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2516
2517 #define LOOKUP_SWITCH \
2518 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2519 tree selector = pop_value (INT_type_node); \
2520 tree duplicate, label; \
2521 tree type = TREE_TYPE (selector); \
2522 flush_quick_stack (); \
2523 expand_start_case (0, selector, type, "switch statement");\
2524 push_momentary (); \
2525 while (--npairs >= 0) \
2526 { \
2527 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2528 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2529 TREE_TYPE (value) = type; \
2530 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2531 pushcase (value, convert, label, &duplicate); \
2532 expand_java_goto (oldpc + offset); \
2533 } \
2534 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2535 pushcase (NULL_TREE, 0, label, &duplicate); \
2536 expand_java_goto (oldpc + default_offset); \
2537 pop_momentary (); \
2538 expand_end_case (selector); \
2539 }
2540
2541 #define TABLE_SWITCH \
2542 { jint default_offset = IMMEDIATE_s4; \
2543 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2544 tree selector = pop_value (INT_type_node); \
2545 tree duplicate, label; \
2546 tree type = TREE_TYPE (selector); \
2547 flush_quick_stack (); \
2548 expand_start_case (0, selector, type, "switch statement");\
2549 push_momentary (); \
2550 for (; low <= high; low++) \
2551 { \
2552 jint offset = IMMEDIATE_s4; \
2553 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2554 TREE_TYPE (value) = type; \
2555 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2556 pushcase (value, convert, label, &duplicate); \
2557 expand_java_goto (oldpc + offset); \
2558 } \
2559 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2560 pushcase (NULL_TREE, 0, label, &duplicate); \
2561 expand_java_goto (oldpc + default_offset); \
2562 pop_momentary (); \
2563 expand_end_case (selector); \
2564 }
2565
2566 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2567 { int opcode = byte_ops[PC-1]; \
2568 int method_ref_index = IMMEDIATE_u2; \
2569 int nargs; \
2570 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2571 else nargs = -1; \
2572 expand_invoke (opcode, method_ref_index, nargs); \
2573 }
2574
2575 /* Handle new, checkcast, instanceof */
2576 #define OBJECT(TYPE, OP) \
2577 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2578
2579 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2580
2581 #define ARRAY_LOAD(OPERAND_TYPE) \
2582 { \
2583 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2584 }
2585
2586 #define ARRAY_STORE(OPERAND_TYPE) \
2587 { \
2588 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2589 }
2590
2591 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2592 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2593 #define ARRAY_NEW_PTR() \
2594 push_value (build_anewarray (get_class_constant (current_jcf, \
2595 IMMEDIATE_u2), \
2596 pop_value (int_type_node)));
2597 #define ARRAY_NEW_NUM() \
2598 { \
2599 int atype = IMMEDIATE_u1; \
2600 push_value (build_newarray (atype, pop_value (int_type_node)));\
2601 }
2602 #define ARRAY_NEW_MULTI() \
2603 { \
2604 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2605 int ndims = IMMEDIATE_u1; \
2606 expand_java_multianewarray( class, ndims ); \
2607 }
2608
2609 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2610 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2611 pop_value (OPERAND_TYPE##_type_node))));
2612
2613 #define CONVERT2(FROM_TYPE, TO_TYPE) \
2614 { \
2615 push_value (build1 (NOP_EXPR, int_type_node, \
2616 (convert (TO_TYPE##_type_node, \
2617 pop_value (FROM_TYPE##_type_node))))); \
2618 }
2619
2620 #define CONVERT(FROM_TYPE, TO_TYPE) \
2621 { \
2622 push_value (convert (TO_TYPE##_type_node, \
2623 pop_value (FROM_TYPE##_type_node))); \
2624 }
2625
2626 /* internal macro added for use by the WIDE case
2627 Added TREE_TYPE (decl) assignment, apbianco */
2628 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
2629 { \
2630 tree decl, value; \
2631 int var = OPVALUE; \
2632 tree type = OPTYPE; \
2633 value = pop_value (type); \
2634 type = TREE_TYPE (value); \
2635 decl = find_local_variable (var, type, oldpc); \
2636 set_local_type (var, type ); \
2637 expand_assignment (decl, value, 0, 0); \
2638 }
2639
2640 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2641 { \
2642 /* have to do this since OPERAND_VALUE may have side-effects */ \
2643 int opvalue = OPERAND_VALUE; \
2644 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2645 }
2646
2647 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2648 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2649
2650 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2651 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2652
2653 #define MONITOR_OPERATION(call) \
2654 { \
2655 tree o = pop_value (ptr_type_node); \
2656 tree c; \
2657 flush_quick_stack (); \
2658 c = build_java_monitor (call, o); \
2659 TREE_SIDE_EFFECTS (c) = 1; \
2660 expand_expr_stmt (c); \
2661 }
2662
2663 #define SPECIAL_IINC(IGNORED) \
2664 { \
2665 unsigned int local_var_index = IMMEDIATE_u1; \
2666 int ival = IMMEDIATE_s1; \
2667 expand_iinc(local_var_index, ival, oldpc); \
2668 }
2669
2670 #define SPECIAL_WIDE(IGNORED) \
2671 { \
2672 int modified_opcode = IMMEDIATE_u1; \
2673 unsigned int local_var_index = IMMEDIATE_u2; \
2674 switch (modified_opcode) \
2675 { \
2676 case OPCODE_iinc: \
2677 { \
2678 int ival = IMMEDIATE_s2; \
2679 expand_iinc (local_var_index, ival, oldpc); \
2680 break; \
2681 } \
2682 case OPCODE_iload: \
2683 case OPCODE_lload: \
2684 case OPCODE_fload: \
2685 case OPCODE_dload: \
2686 case OPCODE_aload: \
2687 { \
2688 /* duplicate code from LOAD macro */ \
2689 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2690 break; \
2691 } \
2692 case OPCODE_istore: \
2693 case OPCODE_lstore: \
2694 case OPCODE_fstore: \
2695 case OPCODE_dstore: \
2696 case OPCODE_astore: \
2697 { \
2698 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2699 break; \
2700 } \
2701 default: \
2702 error ("unrecogized wide sub-instruction"); \
2703 } \
2704 }
2705
2706 #define SPECIAL_THROW(IGNORED) \
2707 build_java_athrow (pop_value (throwable_type_node))
2708
2709 #define SPECIAL_BREAK NOT_IMPL1
2710 #define IMPL NOT_IMPL
2711
2712 #include "javaop.def"
2713 #undef JAVAOP
2714 default:
2715 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2716 }
2717 return PC;
2718 }
2719
2720 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2721 order, as specified by Java Language Specification.
2722
2723 The problem is that while expand_expr will evaluate its sub-operands in
2724 left-to-right order, for variables it will just return an rtx (i.e.
2725 an lvalue) for the variable (rather than an rvalue). So it is possible
2726 that a later sub-operand will change the register, and when the
2727 actual operation is done, it will use the new value, when it should
2728 have used the original value.
2729
2730 We fix this by using save_expr. This forces the sub-operand to be
2731 copied into a fresh virtual register,
2732
2733 For method invocation, we modify the arguments so that a
2734 left-to-right order evaluation is performed. Saved expressions
2735 will, in CALL_EXPR order, be reused when the call will be expanded.
2736 */
2737
2738 tree
2739 force_evaluation_order (node)
2740 tree node;
2741 {
2742 if (flag_syntax_only)
2743 return node;
2744 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
2745 {
2746 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2747 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2748 }
2749 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2750 {
2751 tree arg, cmp;
2752
2753 if (!TREE_OPERAND (node, 1))
2754 return node;
2755
2756 /* This reverses the evaluation order. This is a desired effect. */
2757 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
2758 arg; arg = TREE_CHAIN (arg))
2759 {
2760 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
2761 cmp = (cmp == NULL_TREE ? saved :
2762 build (COMPOUND_EXPR, void_type_node, cmp, saved));
2763 TREE_VALUE (arg) = saved;
2764 }
2765
2766 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
2767 TREE_SIDE_EFFECTS (cmp) = 1;
2768
2769 if (cmp)
2770 {
2771 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
2772 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
2773 TREE_SIDE_EFFECTS (cmp) = 1;
2774 node = cmp;
2775 }
2776 }
2777 return node;
2778 }