1 /* Process expressions for the GNU compiler for the Java(TM) language.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
21
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
25
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
28 #include "config.h"
29 #include "system.h"
30 #include "tree.h"
31 #include "real.h"
32 #include "rtl.h"
33 #include "flags.h"
34 #include "expr.h"
35 #include "java-tree.h"
36 #include "javaop.h"
37 #include "java-opcodes.h"
38 #include "jcf.h"
39 #include "java-except.h"
40 #include "parse.h"
41 #include "toplev.h"
42 #include "except.h"
43 #include "ggc.h"
44
45 static void flush_quick_stack PARAMS ((void));
46 static void push_value PARAMS ((tree));
47 static tree pop_value PARAMS ((tree));
48 static void java_stack_swap PARAMS ((void));
49 static void java_stack_dup PARAMS ((int, int));
50 static void build_java_athrow PARAMS ((tree));
51 static void build_java_jsr PARAMS ((int, int));
52 static void build_java_ret PARAMS ((tree));
53 static void expand_java_multianewarray PARAMS ((tree, int));
54 static void expand_java_arraystore PARAMS ((tree));
55 static void expand_java_arrayload PARAMS ((tree));
56 static void expand_java_array_length PARAMS ((void));
57 static tree build_java_monitor PARAMS ((tree, tree));
58 static void expand_java_pushc PARAMS ((int, tree));
59 static void expand_java_return PARAMS ((tree));
60 static void expand_load_internal PARAMS ((int, tree, int));
61 static void expand_java_NEW PARAMS ((tree));
62 static void expand_java_INSTANCEOF PARAMS ((tree));
63 static void expand_java_CHECKCAST PARAMS ((tree));
64 static void expand_iinc PARAMS ((unsigned int, int, int));
65 static void expand_java_binop PARAMS ((tree, enum tree_code));
66 static void note_label PARAMS ((int, int));
67 static void expand_compare PARAMS ((enum tree_code, tree, tree, int));
68 static void expand_test PARAMS ((enum tree_code, tree, int));
69 static void expand_cond PARAMS ((enum tree_code, tree, int));
70 static void expand_java_goto PARAMS ((int));
71 #if 0
72 static void expand_java_call PARAMS ((int, int));
73 static void expand_java_ret PARAMS ((tree));
74 #endif
75 static tree pop_arguments PARAMS ((tree));
76 static void expand_invoke PARAMS ((int, int, int));
77 static void expand_java_field_op PARAMS ((int, int, int));
78 static void java_push_constant_from_pool PARAMS ((struct JCF *, int));
79 static void java_stack_pop PARAMS ((int));
80 static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
81 static tree build_java_check_indexed_type PARAMS ((tree, tree));
82 static tree case_identity PARAMS ((tree, tree));
83 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
84 static int emit_init_test_initialization PARAMS ((void **entry,
85 void * ptr));
86 static int get_offset_table_index PARAMS ((tree));
87
88 static GTY(()) tree operand_type[59];
89
90 static GTY(()) tree methods_ident;
91 static GTY(()) tree ncode_ident;
92 tree dtable_ident = NULL_TREE;
93
94 /* Set to nonzero value in order to emit class initilization code
95 before static field references. */
96 int always_initialize_class_p;
97
98 /* We store the stack state in two places:
99 Within a basic block, we use the quick_stack, which is a
100 pushdown list (TREE_LISTs) of expression nodes.
101 This is the top part of the stack; below that we use find_stack_slot.
102 At the end of a basic block, the quick_stack must be flushed
103 to the stack slot array (as handled by find_stack_slot).
104 Using quick_stack generates better code (especially when
105 compiled without optimization), because we do not have to
106 explicitly store and load trees to temporary variables.
107
108 If a variable is on the quick stack, it means the value of variable
109 when the quick stack was last flushed. Conceptually, flush_quick_stack
110 saves all the the quick_stack elements in parellel. However, that is
111 complicated, so it actually saves them (i.e. copies each stack value
112 to is home virtual register) from low indexes. This allows a quick_stack
113 element at index i (counting from the bottom of stack the) to references
114 slot virtuals for register that are >= i, but not those that are deeper.
115 This convention makes most operations easier. For example iadd works
116 even when the stack contains (reg[0], reg[1]): It results in the
117 stack containing (reg[0]+reg[1]), which is OK. However, some stack
118 operations are more complicated. For example dup given a stack
119 containing (reg[0]) would yield (reg[0], reg[0]), which would violate
120 the convention, since stack value 1 would refer to a register with
121 lower index (reg[0]), which flush_quick_stack does not safely handle.
122 So dup cannot just add an extra element to the quick_stack, but iadd can.
123 */
124
125 static GTY(()) tree quick_stack;
126
127 /* A free-list of unused permamnet TREE_LIST nodes. */
128 static GTY((deletable (""))) tree tree_list_free_list;
129
130 /* The stack pointer of the Java virtual machine.
131 This does include the size of the quick_stack. */
132
133 int stack_pointer;
134
135 const unsigned char *linenumber_table;
136 int linenumber_count;
137
138 void
init_expr_processing()139 init_expr_processing()
140 {
141 operand_type[21] = operand_type[54] = int_type_node;
142 operand_type[22] = operand_type[55] = long_type_node;
143 operand_type[23] = operand_type[56] = float_type_node;
144 operand_type[24] = operand_type[57] = double_type_node;
145 operand_type[25] = operand_type[58] = ptr_type_node;
146 }
147
148 tree
java_truthvalue_conversion(expr)149 java_truthvalue_conversion (expr)
150 tree expr;
151 {
152 /* It is simpler and generates better code to have only TRUTH_*_EXPR
153 or comparison expressions as truth values at this level.
154
155 This function should normally be identity for Java. */
156
157 switch (TREE_CODE (expr))
158 {
159 case EQ_EXPR:
160 case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR:
161 case TRUTH_ANDIF_EXPR:
162 case TRUTH_ORIF_EXPR:
163 case TRUTH_AND_EXPR:
164 case TRUTH_OR_EXPR:
165 case ERROR_MARK:
166 return expr;
167
168 case INTEGER_CST:
169 return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
170
171 case REAL_CST:
172 return real_zerop (expr) ? boolean_false_node : boolean_true_node;
173
174 /* are these legal? XXX JH */
175 case NEGATE_EXPR:
176 case ABS_EXPR:
177 case FLOAT_EXPR:
178 case FFS_EXPR:
179 /* These don't change whether an object is nonzero or zero. */
180 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
181
182 case COND_EXPR:
183 /* Distribute the conversion into the arms of a COND_EXPR. */
184 return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
185 java_truthvalue_conversion (TREE_OPERAND (expr, 1)),
186 java_truthvalue_conversion (TREE_OPERAND (expr, 2))));
187
188 case NOP_EXPR:
189 /* If this is widening the argument, we can ignore it. */
190 if (TYPE_PRECISION (TREE_TYPE (expr))
191 >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0))))
192 return java_truthvalue_conversion (TREE_OPERAND (expr, 0));
193 /* fall through to default */
194
195 default:
196 return fold (build (NE_EXPR, boolean_type_node, expr, boolean_false_node));
197 }
198 }
199
200 /* Save any stack slots that happen to be in the quick_stack into their
201 home virtual register slots.
202
203 The copy order is from low stack index to high, to support the invariant
204 that the expression for a slot may contain decls for stack slots with
205 higher (or the same) index, but not lower. */
206
207 static void
flush_quick_stack()208 flush_quick_stack ()
209 {
210 int stack_index = stack_pointer;
211 register tree prev, cur, next;
212
213 /* First reverse the quick_stack, and count the number of slots it has. */
214 for (cur = quick_stack, prev = NULL_TREE; cur != NULL_TREE; cur = next)
215 {
216 next = TREE_CHAIN (cur);
217 TREE_CHAIN (cur) = prev;
218 prev = cur;
219 stack_index -= 1 + TYPE_IS_WIDE (TREE_TYPE (TREE_VALUE (cur)));
220 }
221 quick_stack = prev;
222
223 while (quick_stack != NULL_TREE)
224 {
225 tree decl;
226 tree node = quick_stack, type;
227 quick_stack = TREE_CHAIN (node);
228 TREE_CHAIN (node) = tree_list_free_list;
229 tree_list_free_list = node;
230 node = TREE_VALUE (node);
231 type = TREE_TYPE (node);
232
233 decl = find_stack_slot (stack_index, type);
234 if (decl != node)
235 expand_assignment (decl, node, 0, 0);
236 stack_index += 1 + TYPE_IS_WIDE (type);
237 }
238 }
239
240 /* Push TYPE on the type stack.
241 Return true on success, 0 on overflow. */
242
243 int
push_type_0(type)244 push_type_0 (type)
245 tree type;
246 {
247 int n_words;
248 type = promote_type (type);
249 n_words = 1 + TYPE_IS_WIDE (type);
250 if (stack_pointer + n_words > DECL_MAX_STACK (current_function_decl))
251 return 0;
252 stack_type_map[stack_pointer++] = type;
253 n_words--;
254 while (--n_words >= 0)
255 stack_type_map[stack_pointer++] = TYPE_SECOND;
256 return 1;
257 }
258
259 void
push_type(type)260 push_type (type)
261 tree type;
262 {
263 if (! push_type_0 (type))
264 abort ();
265 }
266
267 static void
push_value(value)268 push_value (value)
269 tree value;
270 {
271 tree type = TREE_TYPE (value);
272 if (TYPE_PRECISION (type) < 32 && INTEGRAL_TYPE_P (type))
273 {
274 type = promote_type (type);
275 value = convert (type, value);
276 }
277 push_type (type);
278 if (tree_list_free_list == NULL_TREE)
279 quick_stack = tree_cons (NULL_TREE, value, quick_stack);
280 else
281 {
282 tree node = tree_list_free_list;
283 tree_list_free_list = TREE_CHAIN (tree_list_free_list);
284 TREE_VALUE (node) = value;
285 TREE_CHAIN (node) = quick_stack;
286 quick_stack = node;
287 }
288 }
289
290 /* Pop a type from the type stack.
291 TYPE is the expected type. Return the actual type, which must be
292 convertible to TYPE.
293 On an error, *MESSAGEP is set to a freshly malloc'd error message. */
294
295 tree
pop_type_0(type,messagep)296 pop_type_0 (type, messagep)
297 tree type;
298 char **messagep;
299 {
300 int n_words;
301 tree t;
302 *messagep = NULL;
303 if (TREE_CODE (type) == RECORD_TYPE)
304 type = promote_type (type);
305 n_words = 1 + TYPE_IS_WIDE (type);
306 if (stack_pointer < n_words)
307 {
308 *messagep = xstrdup ("stack underflow");
309 return type;
310 }
311 while (--n_words > 0)
312 {
313 if (stack_type_map[--stack_pointer] != void_type_node)
314 {
315 *messagep = xstrdup ("Invalid multi-word value on type stack");
316 return type;
317 }
318 }
319 t = stack_type_map[--stack_pointer];
320 if (type == NULL_TREE || t == type)
321 return t;
322 if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (t)
323 && TYPE_PRECISION (type) <= 32 && TYPE_PRECISION (t) <= 32)
324 return t;
325 if (TREE_CODE (type) == POINTER_TYPE && TREE_CODE (t) == POINTER_TYPE)
326 {
327 if (type == ptr_type_node || type == object_ptr_type_node)
328 return t;
329 else if (t == ptr_type_node) /* Special case for null reference. */
330 return type;
331 else if (can_widen_reference_to (t, type))
332 return t;
333 /* This is a kludge, but matches what Sun's verifier does.
334 It can be tricked, but is safe as long as type errors
335 (i.e. interface method calls) are caught at run-time. */
336 else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
337 return object_ptr_type_node;
338 }
339
340 /* lang_printable_name uses a static buffer, so we must save the result
341 from calling it the first time. */
342 {
343 char *temp = xstrdup (lang_printable_name (type, 0));
344 *messagep = concat ("expected type '", temp,
345 "' but stack contains '", lang_printable_name (t, 0),
346 "'", NULL);
347 free (temp);
348 }
349 return type;
350 }
351
352 /* Pop a type from the type stack.
353 TYPE is the expected type. Return the actual type, which must be
354 convertible to TYPE, otherwise call error. */
355
356 tree
pop_type(type)357 pop_type (type)
358 tree type;
359 {
360 char *message = NULL;
361 type = pop_type_0 (type, &message);
362 if (message != NULL)
363 {
364 error ("%s", message);
365 free (message);
366 }
367 return type;
368 }
369
370 /* Return 1f if SOURCE_TYPE can be safely widened to TARGET_TYPE.
371 Handles array types and interfaces. */
372
373 int
can_widen_reference_to(source_type,target_type)374 can_widen_reference_to (source_type, target_type)
375 tree source_type, target_type;
376 {
377 if (source_type == ptr_type_node || target_type == object_ptr_type_node)
378 return 1;
379
380 /* Get rid of pointers */
381 if (TREE_CODE (source_type) == POINTER_TYPE)
382 source_type = TREE_TYPE (source_type);
383 if (TREE_CODE (target_type) == POINTER_TYPE)
384 target_type = TREE_TYPE (target_type);
385
386 if (source_type == target_type)
387 return 1;
388 else
389 {
390 if (TYPE_ARRAY_P (source_type) || TYPE_ARRAY_P (target_type))
391 {
392 HOST_WIDE_INT source_length, target_length;
393 if (TYPE_ARRAY_P (source_type) != TYPE_ARRAY_P (target_type))
394 {
395 /* An array implements Cloneable and Serializable. */
396 tree name = DECL_NAME (TYPE_NAME (target_type));
397 return (name == java_lang_cloneable_identifier_node
398 || name == java_io_serializable_identifier_node);
399 }
400 target_length = java_array_type_length (target_type);
401 if (target_length >= 0)
402 {
403 source_length = java_array_type_length (source_type);
404 if (source_length != target_length)
405 return 0;
406 }
407 source_type = TYPE_ARRAY_ELEMENT (source_type);
408 target_type = TYPE_ARRAY_ELEMENT (target_type);
409 if (source_type == target_type)
410 return 1;
411 if (TREE_CODE (source_type) != POINTER_TYPE
412 || TREE_CODE (target_type) != POINTER_TYPE)
413 return 0;
414 return can_widen_reference_to (source_type, target_type);
415 }
416 else
417 {
418 int source_depth = class_depth (source_type);
419 int target_depth = class_depth (target_type);
420
421 /* class_depth can return a negative depth if an error occurred */
422 if (source_depth < 0 || target_depth < 0)
423 return 0;
424
425 if (CLASS_INTERFACE (TYPE_NAME (target_type)))
426 {
427 /* target_type is OK if source_type or source_type ancestors
428 implement target_type. We handle multiple sub-interfaces */
429
430 tree basetype_vec = TYPE_BINFO_BASETYPES (source_type);
431 int n = TREE_VEC_LENGTH (basetype_vec), i;
432 for (i=0 ; i < n; i++)
433 if (can_widen_reference_to
434 (TREE_TYPE (TREE_VEC_ELT (basetype_vec, i)),
435 target_type))
436 return 1;
437 if (n == 0)
438 return 0;
439 }
440
441 for ( ; source_depth > target_depth; source_depth--)
442 {
443 source_type = TYPE_BINFO_BASETYPE (source_type, 0);
444 }
445 return source_type == target_type;
446 }
447 }
448 }
449
450 static tree
pop_value(type)451 pop_value (type)
452 tree type;
453 {
454 type = pop_type (type);
455 if (quick_stack)
456 {
457 tree node = quick_stack;
458 quick_stack = TREE_CHAIN (quick_stack);
459 TREE_CHAIN (node) = tree_list_free_list;
460 tree_list_free_list = node;
461 node = TREE_VALUE (node);
462 return node;
463 }
464 else
465 return find_stack_slot (stack_pointer, promote_type (type));
466 }
467
468
469 /* Pop and discrad the top COUNT stack slots. */
470
471 static void
java_stack_pop(count)472 java_stack_pop (count)
473 int count;
474 {
475 while (count > 0)
476 {
477 tree type, val;
478
479 if (stack_pointer == 0)
480 abort ();
481
482 type = stack_type_map[stack_pointer - 1];
483 if (type == TYPE_SECOND)
484 {
485 count--;
486 if (stack_pointer == 1 || count <= 0)
487 abort ();
488
489 type = stack_type_map[stack_pointer - 2];
490 }
491 val = pop_value (type);
492 count--;
493 }
494 }
495
496 /* Implement the 'swap' operator (to swap two top stack slots). */
497
498 static void
java_stack_swap()499 java_stack_swap ()
500 {
501 tree type1, type2;
502 rtx temp;
503 tree decl1, decl2;
504
505 if (stack_pointer < 2
506 || (type1 = stack_type_map[stack_pointer - 1]) == TYPE_UNKNOWN
507 || (type2 = stack_type_map[stack_pointer - 2]) == TYPE_UNKNOWN
508 || type1 == TYPE_SECOND || type2 == TYPE_SECOND
509 || TYPE_IS_WIDE (type1) || TYPE_IS_WIDE (type2))
510 /* Bad stack swap. */
511 abort ();
512
513 flush_quick_stack ();
514 decl1 = find_stack_slot (stack_pointer - 1, type1);
515 decl2 = find_stack_slot (stack_pointer - 2, type2);
516 temp = copy_to_reg (DECL_RTL (decl1));
517 emit_move_insn (DECL_RTL (decl1), DECL_RTL (decl2));
518 emit_move_insn (DECL_RTL (decl2), temp);
519 stack_type_map[stack_pointer - 1] = type2;
520 stack_type_map[stack_pointer - 2] = type1;
521 }
522
523 static void
java_stack_dup(size,offset)524 java_stack_dup (size, offset)
525 int size, offset;
526 {
527 int low_index = stack_pointer - size - offset;
528 int dst_index;
529 if (low_index < 0)
530 error ("stack underflow - dup* operation");
531
532 flush_quick_stack ();
533
534 stack_pointer += size;
535 dst_index = stack_pointer;
536
537 for (dst_index = stack_pointer; --dst_index >= low_index; )
538 {
539 tree type;
540 int src_index = dst_index - size;
541 if (src_index < low_index)
542 src_index = dst_index + size + offset;
543 type = stack_type_map [src_index];
544 if (type == TYPE_SECOND)
545 {
546 if (src_index <= low_index)
547 /* Dup operation splits 64-bit number. */
548 abort ();
549
550 stack_type_map[dst_index] = type;
551 src_index--; dst_index--;
552 type = stack_type_map[src_index];
553 if (! TYPE_IS_WIDE (type))
554 abort ();
555 }
556 else if (TYPE_IS_WIDE (type))
557 abort ();
558
559 if (src_index != dst_index)
560 {
561 tree src_decl = find_stack_slot (src_index, type);
562 tree dst_decl = find_stack_slot (dst_index, type);
563 emit_move_insn (DECL_RTL (dst_decl), DECL_RTL (src_decl));
564 stack_type_map[dst_index] = type;
565 }
566 }
567 }
568
569 /* Calls _Jv_Throw or _Jv_Sjlj_Throw. Discard the contents of the
570 value stack. */
571
572 static void
build_java_athrow(node)573 build_java_athrow (node)
574 tree node;
575 {
576 tree call;
577
578 call = build (CALL_EXPR,
579 void_type_node,
580 build_address_of (throw_node),
581 build_tree_list (NULL_TREE, node),
582 NULL_TREE);
583 TREE_SIDE_EFFECTS (call) = 1;
584 expand_expr_stmt (call);
585 java_stack_pop (stack_pointer);
586 }
587
588 /* Implementation for jsr/ret */
589
590 static void
build_java_jsr(target_pc,return_pc)591 build_java_jsr (target_pc, return_pc)
592 int target_pc, return_pc;
593 {
594 tree where = lookup_label (target_pc);
595 tree ret = lookup_label (return_pc);
596 tree ret_label = fold (build1 (ADDR_EXPR, return_address_type_node, ret));
597 push_value (ret_label);
598 flush_quick_stack ();
599 emit_jump (label_rtx (where));
600 expand_label (ret);
601 if (instruction_bits [return_pc] & BCODE_VERIFIED)
602 load_type_state (ret);
603 }
604
605 static void
build_java_ret(location)606 build_java_ret (location)
607 tree location;
608 {
609 expand_computed_goto (location);
610 }
611
612 /* Implementation of operations on array: new, load, store, length */
613
614 tree
decode_newarray_type(atype)615 decode_newarray_type (atype)
616 int atype;
617 {
618 switch (atype)
619 {
620 case 4: return boolean_type_node;
621 case 5: return char_type_node;
622 case 6: return float_type_node;
623 case 7: return double_type_node;
624 case 8: return byte_type_node;
625 case 9: return short_type_node;
626 case 10: return int_type_node;
627 case 11: return long_type_node;
628 default: return NULL_TREE;
629 }
630 }
631
632 /* Map primitive type to the code used by OPCODE_newarray. */
633
634 int
encode_newarray_type(type)635 encode_newarray_type (type)
636 tree type;
637 {
638 if (type == boolean_type_node)
639 return 4;
640 else if (type == char_type_node)
641 return 5;
642 else if (type == float_type_node)
643 return 6;
644 else if (type == double_type_node)
645 return 7;
646 else if (type == byte_type_node)
647 return 8;
648 else if (type == short_type_node)
649 return 9;
650 else if (type == int_type_node)
651 return 10;
652 else if (type == long_type_node)
653 return 11;
654 else
655 abort ();
656 }
657
658 /* Build a call to _Jv_ThrowBadArrayIndex(), the
659 ArrayIndexOfBoundsException exception handler. */
660
661 static tree
build_java_throw_out_of_bounds_exception(index)662 build_java_throw_out_of_bounds_exception (index)
663 tree index;
664 {
665 tree node = build (CALL_EXPR, int_type_node,
666 build_address_of (soft_badarrayindex_node),
667 build_tree_list (NULL_TREE, index), NULL_TREE);
668 TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
669 return (node);
670 }
671
672 /* Return the length of an array. Doesn't perform any checking on the nature
673 or value of the array NODE. May be used to implement some bytecodes. */
674
675 tree
build_java_array_length_access(node)676 build_java_array_length_access (node)
677 tree node;
678 {
679 tree type = TREE_TYPE (node);
680 tree array_type = TREE_TYPE (type);
681 HOST_WIDE_INT length;
682
683 /* JVM spec: If the arrayref is null, the arraylength instruction
684 throws a NullPointerException. The only way we could get a node
685 of type ptr_type_node at this point is `aconst_null; arraylength'
686 or something equivalent. */
687 if (type == ptr_type_node)
688 return build (CALL_EXPR, int_type_node,
689 build_address_of (soft_nullpointer_node),
690 NULL_TREE, NULL_TREE);
691
692 if (!is_array_type_p (type))
693 abort ();
694
695 length = java_array_type_length (type);
696 if (length >= 0)
697 return build_int_2 (length, 0);
698
699 node = build (COMPONENT_REF, int_type_node,
700 build_java_indirect_ref (array_type, node,
701 flag_check_references),
702 lookup_field (&array_type, get_identifier ("length")));
703 IS_ARRAY_LENGTH_ACCESS (node) = 1;
704 return node;
705 }
706
707 /* Optionally checks a reference against the NULL pointer. ARG1: the
708 expr, ARG2: we should check the reference. Don't generate extra
709 checks if we're not generating code. */
710
711 tree
java_check_reference(expr,check)712 java_check_reference (expr, check)
713 tree expr;
714 int check;
715 {
716 if (!flag_syntax_only && check)
717 {
718 tree cond;
719 expr = save_expr (expr);
720 cond = build (COND_EXPR, void_type_node,
721 build (EQ_EXPR, boolean_type_node, expr, null_pointer_node),
722 build (CALL_EXPR, void_type_node,
723 build_address_of (soft_nullpointer_node),
724 NULL_TREE, NULL_TREE),
725 empty_stmt_node);
726 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
727 }
728
729 return expr;
730 }
731
732 /* Reference an object: just like an INDIRECT_REF, but with checking. */
733
734 tree
build_java_indirect_ref(type,expr,check)735 build_java_indirect_ref (type, expr, check)
736 tree type;
737 tree expr;
738 int check;
739 {
740 return build1 (INDIRECT_REF, type, java_check_reference (expr, check));
741 }
742
743 /* Implement array indexing (either as l-value or r-value).
744 Returns a tree for ARRAY[INDEX], assume TYPE is the element type.
745 Optionally performs bounds checking and/or test to NULL.
746 At this point, ARRAY should have been verified as an array. */
747
748 tree
build_java_arrayaccess(array,type,index)749 build_java_arrayaccess (array, type, index)
750 tree array, type, index;
751 {
752 tree node, throw = NULL_TREE;
753 tree data_field;
754 tree ref;
755 tree array_type = TREE_TYPE (TREE_TYPE (array));
756
757 if (flag_bounds_check)
758 {
759 /* Generate:
760 * (unsigned jint) INDEX >= (unsigned jint) LEN
761 * && throw ArrayIndexOutOfBoundsException.
762 * Note this is equivalent to and more efficient than:
763 * INDEX < 0 || INDEX >= LEN && throw ... */
764 tree test;
765 tree len = build_java_array_length_access (array);
766 TREE_TYPE (len) = unsigned_int_type_node;
767 test = fold (build (GE_EXPR, boolean_type_node,
768 convert (unsigned_int_type_node, index),
769 len));
770 if (! integer_zerop (test))
771 {
772 throw = build (TRUTH_ANDIF_EXPR, int_type_node, test,
773 build_java_throw_out_of_bounds_exception (index));
774 /* allows expansion within COMPOUND */
775 TREE_SIDE_EFFECTS( throw ) = 1;
776 }
777 }
778
779 /* If checking bounds, wrap the index expr with a COMPOUND_EXPR in order
780 to have the bounds check evaluated first. */
781 if (throw != NULL_TREE)
782 index = build (COMPOUND_EXPR, int_type_node, throw, index);
783
784 data_field = lookup_field (&array_type, get_identifier ("data"));
785
786 ref = build (COMPONENT_REF, TREE_TYPE (data_field),
787 build_java_indirect_ref (array_type, array,
788 flag_check_references),
789 data_field);
790
791 node = build (ARRAY_REF, type, ref, index);
792 return node;
793 }
794
795 /* Generate code to throw an ArrayStoreException if OBJECT is not assignable
796 (at runtime) to an element of ARRAY. A NOP_EXPR is returned if it can
797 determine that no check is required. */
798
799 tree
build_java_arraystore_check(array,object)800 build_java_arraystore_check (array, object)
801 tree array;
802 tree object;
803 {
804 tree check, element_type, source;
805 tree array_type_p = TREE_TYPE (array);
806 tree object_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (object)));
807
808 if (! is_array_type_p (array_type_p))
809 abort ();
810
811 /* Get the TYPE_DECL for ARRAY's element type. */
812 element_type = TYPE_NAME (TREE_TYPE (TREE_TYPE (TREE_TYPE (array_type_p))));
813
814 if (TREE_CODE (element_type) != TYPE_DECL
815 || TREE_CODE (object_type) != TYPE_DECL)
816 abort ();
817
818 if (!flag_store_check)
819 return build1 (NOP_EXPR, array_type_p, array);
820
821 /* No check is needed if the element type is final or is itself an array.
822 Also check that element_type matches object_type, since in the bytecode
823 compilation case element_type may be the actual element type of the arra
824 rather than its declared type. */
825 if (element_type == object_type
826 && (TYPE_ARRAY_P (TREE_TYPE (element_type))
827 || CLASS_FINAL (element_type)))
828 return build1 (NOP_EXPR, array_type_p, array);
829
830 /* OBJECT might be wrapped by a SAVE_EXPR. */
831 if (TREE_CODE (object) == SAVE_EXPR)
832 source = TREE_OPERAND (object, 0);
833 else
834 source = object;
835
836 /* Avoid the check if OBJECT was just loaded from the same array. */
837 if (TREE_CODE (source) == ARRAY_REF)
838 {
839 tree target;
840 source = TREE_OPERAND (source, 0); /* COMPONENT_REF. */
841 source = TREE_OPERAND (source, 0); /* INDIRECT_REF. */
842 source = TREE_OPERAND (source, 0); /* Source array's DECL or SAVE_EXPR. */
843 if (TREE_CODE (source) == SAVE_EXPR)
844 source = TREE_OPERAND (source, 0);
845
846 target = array;
847 if (TREE_CODE (target) == SAVE_EXPR)
848 target = TREE_OPERAND (target, 0);
849
850 if (source == target)
851 return build1 (NOP_EXPR, array_type_p, array);
852 }
853
854 /* Build an invocation of _Jv_CheckArrayStore */
855 check = build (CALL_EXPR, void_type_node,
856 build_address_of (soft_checkarraystore_node),
857 tree_cons (NULL_TREE, array,
858 build_tree_list (NULL_TREE, object)),
859 NULL_TREE);
860 TREE_SIDE_EFFECTS (check) = 1;
861
862 return check;
863 }
864
865 /* Makes sure that INDEXED_TYPE is appropriate. If not, make it from
866 ARRAY_NODE. This function is used to retrieve something less vague than
867 a pointer type when indexing the first dimension of something like [[<t>.
868 May return a corrected type, if necessary, otherwise INDEXED_TYPE is
869 return unchanged.
870 As a side effect, it also makes sure that ARRAY_NODE is an array. */
871
872 static tree
build_java_check_indexed_type(array_node,indexed_type)873 build_java_check_indexed_type (array_node, indexed_type)
874 tree array_node;
875 tree indexed_type;
876 {
877 tree elt_type;
878
879 if (!is_array_type_p (TREE_TYPE (array_node)))
880 abort ();
881
882 elt_type = (TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (array_node))));
883
884 if (indexed_type == ptr_type_node )
885 return promote_type (elt_type);
886
887 /* BYTE/BOOLEAN store and load are used for both type */
888 if (indexed_type == byte_type_node && elt_type == boolean_type_node )
889 return boolean_type_node;
890
891 if (indexed_type != elt_type )
892 abort ();
893 else
894 return indexed_type;
895 }
896
897 /* newarray triggers a call to _Jv_NewPrimArray. This function should be
898 called with an integer code (the type of array to create), and the length
899 of the array to create. */
900
901 tree
build_newarray(atype_value,length)902 build_newarray (atype_value, length)
903 int atype_value;
904 tree length;
905 {
906 tree type_arg;
907
908 tree prim_type = decode_newarray_type (atype_value);
909 tree type
910 = build_java_array_type (prim_type,
911 host_integerp (length, 0) == INTEGER_CST
912 ? tree_low_cst (length, 0) : -1);
913
914 /* If compiling to native, pass a reference to the primitive type class
915 and save the runtime some work. However, the bytecode generator
916 expects to find the type_code int here. */
917 if (flag_emit_class_files)
918 type_arg = build_int_2 (atype_value, 0);
919 else
920 type_arg = build_class_ref (prim_type);
921
922 return build (CALL_EXPR, promote_type (type),
923 build_address_of (soft_newarray_node),
924 tree_cons (NULL_TREE,
925 type_arg,
926 build_tree_list (NULL_TREE, length)),
927 NULL_TREE);
928 }
929
930 /* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
931 of the dimension. */
932
933 tree
build_anewarray(class_type,length)934 build_anewarray (class_type, length)
935 tree class_type;
936 tree length;
937 {
938 tree type
939 = build_java_array_type (class_type,
940 host_integerp (length, 0)
941 ? tree_low_cst (length, 0) : -1);
942
943 return build (CALL_EXPR, promote_type (type),
944 build_address_of (soft_anewarray_node),
945 tree_cons (NULL_TREE, length,
946 tree_cons (NULL_TREE, build_class_ref (class_type),
947 build_tree_list (NULL_TREE,
948 null_pointer_node))),
949 NULL_TREE);
950 }
951
952 /* Return a node the evaluates 'new TYPE[LENGTH]'. */
953
954 tree
build_new_array(type,length)955 build_new_array (type, length)
956 tree type;
957 tree length;
958 {
959 if (JPRIMITIVE_TYPE_P (type))
960 return build_newarray (encode_newarray_type (type), length);
961 else
962 return build_anewarray (TREE_TYPE (type), length);
963 }
964
965 /* Generates a call to _Jv_NewMultiArray. multianewarray expects a
966 class pointer, a number of dimensions and the matching number of
967 dimensions. The argument list is NULL terminated. */
968
969 static void
expand_java_multianewarray(class_type,ndim)970 expand_java_multianewarray (class_type, ndim)
971 tree class_type;
972 int ndim;
973 {
974 int i;
975 tree args = build_tree_list( NULL_TREE, null_pointer_node );
976
977 for( i = 0; i < ndim; i++ )
978 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
979
980 push_value (build (CALL_EXPR,
981 promote_type (class_type),
982 build_address_of (soft_multianewarray_node),
983 tree_cons (NULL_TREE, build_class_ref (class_type),
984 tree_cons (NULL_TREE,
985 build_int_2 (ndim, 0), args )),
986 NULL_TREE));
987 }
988
989 /* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
990 ARRAY is an array type. May expand some bound checking and NULL
991 pointer checking. RHS_TYPE_NODE we are going to store. In the case
992 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
993 INT. In those cases, we make the convertion.
994
995 if ARRAy is a reference type, the assignment is checked at run-time
996 to make sure that the RHS can be assigned to the array element
997 type. It is not necessary to generate this code if ARRAY is final. */
998
999 static void
expand_java_arraystore(rhs_type_node)1000 expand_java_arraystore (rhs_type_node)
1001 tree rhs_type_node;
1002 {
1003 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
1004 && TYPE_PRECISION (rhs_type_node) <= 32) ?
1005 int_type_node : rhs_type_node);
1006 tree index = pop_value (int_type_node);
1007 tree array = pop_value (ptr_type_node);
1008
1009 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
1010
1011 flush_quick_stack ();
1012
1013 index = save_expr (index);
1014 array = save_expr (array);
1015
1016 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
1017 {
1018 tree check = build_java_arraystore_check (array, rhs_node);
1019 expand_expr_stmt (check);
1020 }
1021
1022 expand_assignment (build_java_arrayaccess (array,
1023 rhs_type_node,
1024 index),
1025 rhs_node, 0, 0);
1026 }
1027
1028 /* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
1029 sure that LHS is an array type. May expand some bound checking and NULL
1030 pointer checking.
1031 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
1032 BOOLEAN/SHORT, we push a promoted type back to the stack.
1033 */
1034
1035 static void
expand_java_arrayload(lhs_type_node)1036 expand_java_arrayload (lhs_type_node )
1037 tree lhs_type_node;
1038 {
1039 tree load_node;
1040 tree index_node = pop_value (int_type_node);
1041 tree array_node = pop_value (ptr_type_node);
1042
1043 index_node = save_expr (index_node);
1044 array_node = save_expr (array_node);
1045
1046 if (TREE_TYPE (array_node) == ptr_type_node)
1047 /* The only way we could get a node of type ptr_type_node at this
1048 point is `aconst_null; arraylength' or something equivalent, so
1049 unconditionally throw NullPointerException. */
1050 load_node = build (CALL_EXPR, lhs_type_node,
1051 build_address_of (soft_nullpointer_node),
1052 NULL_TREE, NULL_TREE);
1053 else
1054 {
1055 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
1056 load_node = build_java_arrayaccess (array_node,
1057 lhs_type_node,
1058 index_node);
1059 }
1060 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
1061 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
1062 push_value (load_node);
1063 }
1064
1065 /* Expands .length. Makes sure that we deal with and array and may expand
1066 a NULL check on the array object. */
1067
1068 static void
expand_java_array_length()1069 expand_java_array_length ()
1070 {
1071 tree array = pop_value (ptr_type_node);
1072 tree length = build_java_array_length_access (array);
1073
1074 push_value (length);
1075 }
1076
1077 /* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
1078 either soft_monitorenter_node or soft_monitorexit_node. */
1079
1080 static tree
build_java_monitor(call,object)1081 build_java_monitor (call, object)
1082 tree call;
1083 tree object;
1084 {
1085 return (build (CALL_EXPR,
1086 void_type_node,
1087 build_address_of (call),
1088 build_tree_list (NULL_TREE, object),
1089 NULL_TREE));
1090 }
1091
1092 /* Emit code for one of the PUSHC instructions. */
1093
1094 static void
expand_java_pushc(ival,type)1095 expand_java_pushc (ival, type)
1096 int ival;
1097 tree type;
1098 {
1099 tree value;
1100 if (type == ptr_type_node && ival == 0)
1101 value = null_pointer_node;
1102 else if (type == int_type_node || type == long_type_node)
1103 {
1104 value = build_int_2 (ival, ival < 0 ? -1 : 0);
1105 TREE_TYPE (value) = type;
1106 }
1107 else if (type == float_type_node || type == double_type_node)
1108 {
1109 REAL_VALUE_TYPE x;
1110 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
1111 value = build_real (type, x);
1112 }
1113 else
1114 abort ();
1115
1116 push_value (value);
1117 }
1118
1119 static void
expand_java_return(type)1120 expand_java_return (type)
1121 tree type;
1122 {
1123 if (type == void_type_node)
1124 expand_null_return ();
1125 else
1126 {
1127 tree retval = pop_value (type);
1128 tree res = DECL_RESULT (current_function_decl);
1129 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
1130
1131 /* Handle the situation where the native integer type is smaller
1132 than the JVM integer. It can happen for many cross compilers.
1133 The whole if expression just goes away if INT_TYPE_SIZE < 32
1134 is false. */
1135 if (INT_TYPE_SIZE < 32
1136 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1137 < GET_MODE_SIZE (TYPE_MODE (type))))
1138 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1139
1140 TREE_SIDE_EFFECTS (retval) = 1;
1141 expand_return (retval);
1142 }
1143 }
1144
1145 static void
expand_load_internal(index,type,pc)1146 expand_load_internal (index, type, pc)
1147 int index;
1148 tree type;
1149 int pc;
1150 {
1151 tree copy;
1152 tree var = find_local_variable (index, type, pc);
1153
1154 /* Now VAR is the VAR_DECL (or PARM_DECL) that we are going to push
1155 on the stack. If there is an assignment to this VAR_DECL between
1156 the stack push and the use, then the wrong code could be
1157 generated. To avoid this we create a new local and copy our
1158 value into it. Then we push this new local on the stack.
1159 Hopefully this all gets optimized out. */
1160 copy = build_decl (VAR_DECL, NULL_TREE, type);
1161 DECL_CONTEXT (copy) = current_function_decl;
1162 layout_decl (copy, 0);
1163 DECL_REGISTER (copy) = 1;
1164 expand_decl (copy);
1165 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (copy);
1166 DECL_INITIAL (copy) = var;
1167 expand_decl_init (copy);
1168 push_value (copy);
1169 }
1170
1171 tree
build_address_of(value)1172 build_address_of (value)
1173 tree value;
1174 {
1175 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1176 }
1177
class_has_finalize_method(type)1178 bool class_has_finalize_method (type)
1179 tree type;
1180 {
1181 tree super = CLASSTYPE_SUPER (type);
1182
1183 if (super == NULL_TREE)
1184 return false; /* Every class with a real finalizer inherits */
1185 /* from java.lang.Object. */
1186 else
1187 return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
1188 }
1189
1190 static void
expand_java_NEW(type)1191 expand_java_NEW (type)
1192 tree type;
1193 {
1194 tree alloc_node;
1195
1196 alloc_node = (class_has_finalize_method (type) ? alloc_object_node
1197 : alloc_no_finalizer_node);
1198 if (! CLASS_LOADED_P (type))
1199 load_class (type, 1);
1200 safe_layout_class (type);
1201 push_value (build (CALL_EXPR, promote_type (type),
1202 build_address_of (alloc_node),
1203 tree_cons (NULL_TREE, build_class_ref (type),
1204 build_tree_list (NULL_TREE,
1205 size_in_bytes (type))),
1206 NULL_TREE));
1207 }
1208
1209 /* This returns an expression which will extract the class of an
1210 object. */
1211
1212 tree
build_get_class(value)1213 build_get_class (value)
1214 tree value;
1215 {
1216 tree class_field = lookup_field (&dtable_type, get_identifier ("class"));
1217 tree vtable_field = lookup_field (&object_type_node,
1218 get_identifier ("vtable"));
1219 return build (COMPONENT_REF, class_ptr_type,
1220 build1 (INDIRECT_REF, dtable_type,
1221 build (COMPONENT_REF, dtable_ptr_type,
1222 build_java_indirect_ref (object_type_node, value,
1223 flag_check_references),
1224 vtable_field)),
1225 class_field);
1226 }
1227
1228 /* This builds the tree representation of the `instanceof' operator.
1229 It tries various tricks to optimize this in cases where types are
1230 known. */
1231
1232 tree
build_instanceof(value,type)1233 build_instanceof (value, type)
1234 tree value, type;
1235 {
1236 tree expr;
1237 tree itype = TREE_TYPE (TREE_TYPE (soft_instanceof_node));
1238 tree valtype = TREE_TYPE (TREE_TYPE (value));
1239 tree valclass = TYPE_NAME (valtype);
1240 tree klass;
1241
1242 /* When compiling from bytecode, we need to ensure that TYPE has
1243 been loaded. */
1244 if (CLASS_P (type) && ! CLASS_LOADED_P (type))
1245 {
1246 load_class (type, 1);
1247 safe_layout_class (type);
1248 if (! TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) == ERROR_MARK)
1249 return error_mark_node;
1250 }
1251 klass = TYPE_NAME (type);
1252
1253 if (type == object_type_node || inherits_from_p (valtype, type))
1254 {
1255 /* Anything except `null' is an instance of Object. Likewise,
1256 if the object is known to be an instance of the class, then
1257 we only need to check for `null'. */
1258 expr = build (NE_EXPR, itype, value, null_pointer_node);
1259 }
1260 else if (! TYPE_ARRAY_P (type)
1261 && ! TYPE_ARRAY_P (valtype)
1262 && DECL_P (klass) && DECL_P (valclass)
1263 && ! CLASS_INTERFACE (valclass)
1264 && ! CLASS_INTERFACE (klass)
1265 && ! inherits_from_p (type, valtype)
1266 && (CLASS_FINAL (klass)
1267 || ! inherits_from_p (valtype, type)))
1268 {
1269 /* The classes are from different branches of the derivation
1270 tree, so we immediately know the answer. */
1271 expr = boolean_false_node;
1272 }
1273 else if (DECL_P (klass) && CLASS_FINAL (klass))
1274 {
1275 tree save = save_expr (value);
1276 expr = build (COND_EXPR, itype,
1277 save,
1278 build (EQ_EXPR, itype,
1279 build_get_class (save),
1280 build_class_ref (type)),
1281 boolean_false_node);
1282 }
1283 else
1284 {
1285 expr = build (CALL_EXPR, itype,
1286 build_address_of (soft_instanceof_node),
1287 tree_cons (NULL_TREE, value,
1288 build_tree_list (NULL_TREE,
1289 build_class_ref (type))),
1290 NULL_TREE);
1291 }
1292 TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
1293 return expr;
1294 }
1295
1296 static void
expand_java_INSTANCEOF(type)1297 expand_java_INSTANCEOF (type)
1298 tree type;
1299 {
1300 tree value = pop_value (object_ptr_type_node);
1301 value = build_instanceof (value, type);
1302 push_value (value);
1303 }
1304
1305 static void
expand_java_CHECKCAST(type)1306 expand_java_CHECKCAST (type)
1307 tree type;
1308 {
1309 tree value = pop_value (ptr_type_node);
1310 value = build (CALL_EXPR, promote_type (type),
1311 build_address_of (soft_checkcast_node),
1312 tree_cons (NULL_TREE, build_class_ref (type),
1313 build_tree_list (NULL_TREE, value)),
1314 NULL_TREE);
1315 push_value (value);
1316 }
1317
1318 static void
expand_iinc(local_var_index,ival,pc)1319 expand_iinc (local_var_index, ival, pc)
1320 unsigned int local_var_index;
1321 int ival;
1322 int pc;
1323 {
1324 tree local_var, res;
1325 tree constant_value;
1326
1327 flush_quick_stack ();
1328 local_var = find_local_variable (local_var_index, int_type_node, pc);
1329 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1330 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1331 expand_assignment (local_var, res, 0, 0);
1332 }
1333
1334
1335 tree
build_java_soft_divmod(op,type,op1,op2)1336 build_java_soft_divmod (op, type, op1, op2)
1337 enum tree_code op;
1338 tree type, op1, op2;
1339 {
1340 tree call = NULL;
1341 tree arg1 = convert (type, op1);
1342 tree arg2 = convert (type, op2);
1343
1344 if (type == int_type_node)
1345 {
1346 switch (op)
1347 {
1348 case TRUNC_DIV_EXPR:
1349 call = soft_idiv_node;
1350 break;
1351 case TRUNC_MOD_EXPR:
1352 call = soft_irem_node;
1353 break;
1354 default:
1355 break;
1356 }
1357 }
1358 else if (type == long_type_node)
1359 {
1360 switch (op)
1361 {
1362 case TRUNC_DIV_EXPR:
1363 call = soft_ldiv_node;
1364 break;
1365 case TRUNC_MOD_EXPR:
1366 call = soft_lrem_node;
1367 break;
1368 default:
1369 break;
1370 }
1371 }
1372
1373 if (! call)
1374 abort ();
1375
1376 call = build (CALL_EXPR, type,
1377 build_address_of (call),
1378 tree_cons (NULL_TREE, arg1,
1379 build_tree_list (NULL_TREE, arg2)),
1380 NULL_TREE);
1381
1382 return call;
1383 }
1384
1385 tree
build_java_binop(op,type,arg1,arg2)1386 build_java_binop (op, type, arg1, arg2)
1387 enum tree_code op;
1388 tree type, arg1, arg2;
1389 {
1390 tree mask;
1391 switch (op)
1392 {
1393 case URSHIFT_EXPR:
1394 {
1395 tree u_type = java_unsigned_type (type);
1396 arg1 = convert (u_type, arg1);
1397 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1398 return convert (type, arg1);
1399 }
1400 case LSHIFT_EXPR:
1401 case RSHIFT_EXPR:
1402 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1403 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1404 break;
1405
1406 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1407 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1408 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1409 {
1410 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1411 boolean_type_node, arg1, arg2));
1412 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1413 tree second_compare = fold (build (COND_EXPR, int_type_node,
1414 ifexp2, integer_zero_node,
1415 op == COMPARE_L_EXPR
1416 ? integer_minus_one_node
1417 : integer_one_node));
1418 return fold (build (COND_EXPR, int_type_node, ifexp1,
1419 op == COMPARE_L_EXPR ? integer_one_node
1420 : integer_minus_one_node,
1421 second_compare));
1422 }
1423 case COMPARE_EXPR:
1424 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1425 {
1426 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1427 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1428 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1429 ifexp2, integer_one_node,
1430 integer_zero_node));
1431 return fold (build (COND_EXPR, int_type_node,
1432 ifexp1, integer_minus_one_node, second_compare));
1433 }
1434 case TRUNC_DIV_EXPR:
1435 case TRUNC_MOD_EXPR:
1436 if (TREE_CODE (type) == REAL_TYPE
1437 && op == TRUNC_MOD_EXPR)
1438 {
1439 tree call;
1440 if (type != double_type_node)
1441 {
1442 arg1 = convert (double_type_node, arg1);
1443 arg2 = convert (double_type_node, arg2);
1444 }
1445 call = build (CALL_EXPR, double_type_node,
1446 build_address_of (soft_fmod_node),
1447 tree_cons (NULL_TREE, arg1,
1448 build_tree_list (NULL_TREE, arg2)),
1449 NULL_TREE);
1450 if (type != double_type_node)
1451 call = convert (type, call);
1452 return call;
1453 }
1454
1455 if (TREE_CODE (type) == INTEGER_TYPE
1456 && flag_use_divide_subroutine
1457 && ! flag_syntax_only)
1458 return build_java_soft_divmod (op, type, arg1, arg2);
1459
1460 break;
1461 default: ;
1462 }
1463 return fold (build (op, type, arg1, arg2));
1464 }
1465
1466 static void
expand_java_binop(type,op)1467 expand_java_binop (type, op)
1468 tree type; enum tree_code op;
1469 {
1470 tree larg, rarg;
1471 tree ltype = type;
1472 tree rtype = type;
1473 switch (op)
1474 {
1475 case LSHIFT_EXPR:
1476 case RSHIFT_EXPR:
1477 case URSHIFT_EXPR:
1478 rtype = int_type_node;
1479 rarg = pop_value (rtype);
1480 break;
1481 default:
1482 rarg = pop_value (rtype);
1483 }
1484 larg = pop_value (ltype);
1485 push_value (build_java_binop (op, type, larg, rarg));
1486 }
1487
1488 /* Lookup the field named NAME in *TYPEP or its super classes.
1489 If not found, return NULL_TREE.
1490 (If the *TYPEP is not found, or if the field reference is
1491 ambiguous, return error_mark_node.)
1492 If found, return the FIELD_DECL, and set *TYPEP to the
1493 class containing the field. */
1494
1495 tree
lookup_field(typep,name)1496 lookup_field (typep, name)
1497 tree *typep;
1498 tree name;
1499 {
1500 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1501 {
1502 load_class (*typep, 1);
1503 safe_layout_class (*typep);
1504 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
1505 return error_mark_node;
1506 }
1507 do
1508 {
1509 tree field, basetype_vec;
1510 tree save_field;
1511 int n, i;
1512
1513 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1514 if (DECL_NAME (field) == name)
1515 return field;
1516
1517 /* Process implemented interfaces. */
1518 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1519 n = TREE_VEC_LENGTH (basetype_vec);
1520 save_field = NULL_TREE;
1521 for (i = 0; i < n; i++)
1522 {
1523 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1524 if ((field = lookup_field (&t, name)))
1525 {
1526 if (save_field == field)
1527 continue;
1528 if (save_field == NULL_TREE)
1529 save_field = field;
1530 else
1531 {
1532 tree i1 = DECL_CONTEXT (save_field);
1533 tree i2 = DECL_CONTEXT (field);
1534 error ("reference `%s' is ambiguous: appears in interface `%s' and interface `%s'",
1535 IDENTIFIER_POINTER (name),
1536 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i1))),
1537 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (i2))));
1538 return error_mark_node;
1539 }
1540 }
1541 }
1542
1543 if (save_field != NULL_TREE)
1544 return save_field;
1545
1546 *typep = CLASSTYPE_SUPER (*typep);
1547 } while (*typep);
1548 return NULL_TREE;
1549 }
1550
1551 /* Look up the field named NAME in object SELF_VALUE,
1552 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1553 SELF_VALUE is NULL_TREE if looking for a static field. */
1554
1555 tree
build_field_ref(self_value,self_class,name)1556 build_field_ref (self_value, self_class, name)
1557 tree self_value, self_class, name;
1558 {
1559 tree base_class = self_class;
1560 tree field_decl = lookup_field (&base_class, name);
1561 if (field_decl == NULL_TREE)
1562 {
1563 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1564 return error_mark_node;
1565 }
1566 if (self_value == NULL_TREE)
1567 {
1568 return build_static_field_ref (field_decl);
1569 }
1570 else
1571 {
1572 int check = (flag_check_references
1573 && ! (DECL_P (self_value)
1574 && DECL_NAME (self_value) == this_identifier_node));
1575
1576 tree base_type = promote_type (base_class);
1577 if (base_type != TREE_TYPE (self_value))
1578 self_value = fold (build1 (NOP_EXPR, base_type, self_value));
1579 self_value = build_java_indirect_ref (TREE_TYPE (TREE_TYPE (self_value)),
1580 self_value, check);
1581 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1582 self_value, field_decl));
1583 }
1584 }
1585
1586 tree
lookup_label(pc)1587 lookup_label (pc)
1588 int pc;
1589 {
1590 tree name;
1591 char buf[32];
1592 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
1593 name = get_identifier (buf);
1594 if (IDENTIFIER_LOCAL_VALUE (name))
1595 return IDENTIFIER_LOCAL_VALUE (name);
1596 else
1597 {
1598 /* The type of the address of a label is return_address_type_node. */
1599 tree decl = create_label_decl (name);
1600 LABEL_PC (decl) = pc;
1601 label_rtx (decl);
1602 return pushdecl (decl);
1603 }
1604 }
1605
1606 /* Generate a unique name for the purpose of loops and switches
1607 labels, and try-catch-finally blocks label or temporary variables. */
1608
1609 tree
generate_name()1610 generate_name ()
1611 {
1612 static int l_number = 0;
1613 char buff [32];
1614 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1615 l_number++;
1616 return get_identifier (buff);
1617 }
1618
1619 tree
create_label_decl(name)1620 create_label_decl (name)
1621 tree name;
1622 {
1623 tree decl;
1624 decl = build_decl (LABEL_DECL, name,
1625 TREE_TYPE (return_address_type_node));
1626 DECL_CONTEXT (decl) = current_function_decl;
1627 DECL_IGNORED_P (decl) = 1;
1628 return decl;
1629 }
1630
1631 /* This maps a bytecode offset (PC) to various flags. */
1632 char *instruction_bits;
1633
1634 static void
note_label(current_pc,target_pc)1635 note_label (current_pc, target_pc)
1636 int current_pc ATTRIBUTE_UNUSED, target_pc;
1637 {
1638 lookup_label (target_pc);
1639 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1640 }
1641
1642 /* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1643 where CONDITION is one of one the compare operators. */
1644
1645 static void
expand_compare(condition,value1,value2,target_pc)1646 expand_compare (condition, value1, value2, target_pc)
1647 enum tree_code condition;
1648 tree value1, value2;
1649 int target_pc;
1650 {
1651 tree target = lookup_label (target_pc);
1652 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1653 expand_start_cond (java_truthvalue_conversion (cond), 0);
1654 expand_goto (target);
1655 expand_end_cond ();
1656 }
1657
1658 /* Emit code for a TEST-type opcode. */
1659
1660 static void
expand_test(condition,type,target_pc)1661 expand_test (condition, type, target_pc)
1662 enum tree_code condition;
1663 tree type;
1664 int target_pc;
1665 {
1666 tree value1, value2;
1667 flush_quick_stack ();
1668 value1 = pop_value (type);
1669 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1670 expand_compare (condition, value1, value2, target_pc);
1671 }
1672
1673 /* Emit code for a COND-type opcode. */
1674
1675 static void
expand_cond(condition,type,target_pc)1676 expand_cond (condition, type, target_pc)
1677 enum tree_code condition;
1678 tree type;
1679 int target_pc;
1680 {
1681 tree value1, value2;
1682 flush_quick_stack ();
1683 /* note: pop values in opposite order */
1684 value2 = pop_value (type);
1685 value1 = pop_value (type);
1686 /* Maybe should check value1 and value2 for type compatibility ??? */
1687 expand_compare (condition, value1, value2, target_pc);
1688 }
1689
1690 static void
expand_java_goto(target_pc)1691 expand_java_goto (target_pc)
1692 int target_pc;
1693 {
1694 tree target_label = lookup_label (target_pc);
1695 flush_quick_stack ();
1696 expand_goto (target_label);
1697 }
1698
1699 #if 0
1700 static void
1701 expand_java_call (target_pc, return_address)
1702 int target_pc, return_address;
1703 {
1704 tree target_label = lookup_label (target_pc);
1705 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1706 push_value (value);
1707 flush_quick_stack ();
1708 expand_goto (target_label);
1709 }
1710
1711 static void
1712 expand_java_ret (return_address)
1713 tree return_address ATTRIBUTE_UNUSED;
1714 {
1715 warning ("ret instruction not implemented");
1716 #if 0
1717 tree target_label = lookup_label (target_pc);
1718 flush_quick_stack ();
1719 expand_goto (target_label);
1720 #endif
1721 }
1722 #endif
1723
1724 static tree
pop_arguments(arg_types)1725 pop_arguments (arg_types)
1726 tree arg_types;
1727 {
1728 if (arg_types == end_params_node)
1729 return NULL_TREE;
1730 if (TREE_CODE (arg_types) == TREE_LIST)
1731 {
1732 tree tail = pop_arguments (TREE_CHAIN (arg_types));
1733 tree type = TREE_VALUE (arg_types);
1734 tree arg = pop_value (type);
1735 if (PROMOTE_PROTOTYPES
1736 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
1737 && INTEGRAL_TYPE_P (type))
1738 arg = convert (integer_type_node, arg);
1739 return tree_cons (NULL_TREE, arg, tail);
1740 }
1741 abort ();
1742 }
1743
1744 /* Build an expression to initialize the class CLAS.
1745 if EXPR is non-NULL, returns an expression to first call the initializer
1746 (if it is needed) and then calls EXPR. */
1747
1748 tree
build_class_init(clas,expr)1749 build_class_init (clas, expr)
1750 tree clas, expr;
1751 {
1752 tree init;
1753
1754 /* An optimization: if CLAS is a superclass of the class we're
1755 compiling, we don't need to initialize it. However, if CLAS is
1756 an interface, it won't necessarily be initialized, even if we
1757 implement it. */
1758 if ((! CLASS_INTERFACE (TYPE_NAME (clas))
1759 && inherits_from_p (current_class, clas))
1760 || current_class == clas)
1761 return expr;
1762
1763 if (always_initialize_class_p)
1764 {
1765 init = build (CALL_EXPR, void_type_node,
1766 build_address_of (soft_initclass_node),
1767 build_tree_list (NULL_TREE, build_class_ref (clas)),
1768 NULL_TREE);
1769 TREE_SIDE_EFFECTS (init) = 1;
1770 }
1771 else
1772 {
1773 tree *init_test_decl;
1774 init_test_decl = java_treetreehash_new
1775 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
1776
1777 if (*init_test_decl == NULL)
1778 {
1779 /* Build a declaration and mark it as a flag used to track
1780 static class initializations. */
1781 *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1782 boolean_type_node);
1783 MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
1784 LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
1785 DECL_CONTEXT (*init_test_decl) = current_function_decl;
1786 DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
1787 /* Tell the check-init code to ignore this decl when not
1788 optimizing class initialization. */
1789 if (!STATIC_CLASS_INIT_OPT_P ())
1790 DECL_BIT_INDEX(*init_test_decl) = -1;
1791 }
1792
1793 init = build (CALL_EXPR, void_type_node,
1794 build_address_of (soft_initclass_node),
1795 build_tree_list (NULL_TREE, build_class_ref (clas)),
1796 NULL_TREE);
1797 TREE_SIDE_EFFECTS (init) = 1;
1798 init = build (COND_EXPR, void_type_node,
1799 build (EQ_EXPR, boolean_type_node,
1800 *init_test_decl, boolean_false_node),
1801 init, integer_zero_node);
1802 TREE_SIDE_EFFECTS (init) = 1;
1803 init = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1804 build (MODIFY_EXPR, boolean_type_node,
1805 *init_test_decl, boolean_true_node));
1806 TREE_SIDE_EFFECTS (init) = 1;
1807 }
1808
1809 if (expr != NULL_TREE)
1810 {
1811 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1812 TREE_SIDE_EFFECTS (expr) = 1;
1813 return expr;
1814 }
1815 return init;
1816 }
1817
1818 tree
build_known_method_ref(method,method_type,self_type,method_signature,arg_list)1819 build_known_method_ref (method, method_type, self_type,
1820 method_signature, arg_list)
1821 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1822 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
1823 {
1824 tree func;
1825 if (is_compiled_class (self_type))
1826 {
1827 make_decl_rtl (method, NULL);
1828 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1829 }
1830 else
1831 {
1832 /* We don't know whether the method has been (statically) compiled.
1833 Compile this code to get a reference to the method's code:
1834
1835 SELF_TYPE->methods[METHOD_INDEX].ncode
1836
1837 This is guaranteed to work (assuming SELF_TYPE has
1838 been initialized), since if the method is not compiled yet,
1839 its ncode points to a trampoline that forces compilation. */
1840
1841 int method_index = 0;
1842 tree meth;
1843 tree ref = build_class_ref (self_type);
1844 ref = build1 (INDIRECT_REF, class_type_node, ref);
1845 if (ncode_ident == NULL_TREE)
1846 ncode_ident = get_identifier ("ncode");
1847 if (methods_ident == NULL_TREE)
1848 methods_ident = get_identifier ("methods");
1849 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1850 lookup_field (&class_type_node, methods_ident));
1851 for (meth = TYPE_METHODS (self_type);
1852 ; meth = TREE_CHAIN (meth))
1853 {
1854 if (method == meth)
1855 break;
1856 if (meth == NULL_TREE)
1857 fatal_error ("method '%s' not found in class",
1858 IDENTIFIER_POINTER (DECL_NAME (method)));
1859 method_index++;
1860 }
1861 method_index *= int_size_in_bytes (method_type_node);
1862 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1863 ref, build_int_2 (method_index, 0)));
1864 ref = build1 (INDIRECT_REF, method_type_node, ref);
1865 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1866 ref,
1867 lookup_field (&method_type_node, ncode_ident));
1868 }
1869 return func;
1870 }
1871
1872 tree
invoke_build_dtable(is_invoke_interface,arg_list)1873 invoke_build_dtable (is_invoke_interface, arg_list)
1874 int is_invoke_interface;
1875 tree arg_list;
1876 {
1877 tree dtable, objectref;
1878
1879 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1880
1881 /* If we're dealing with interfaces and if the objectref
1882 argument is an array then get the dispatch table of the class
1883 Object rather than the one from the objectref. */
1884 objectref = (is_invoke_interface
1885 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1886 object_type_node : TREE_VALUE (arg_list));
1887
1888 if (dtable_ident == NULL_TREE)
1889 dtable_ident = get_identifier ("vtable");
1890 dtable = build_java_indirect_ref (object_type_node, objectref,
1891 flag_check_references);
1892 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1893 lookup_field (&object_type_node, dtable_ident));
1894
1895 return dtable;
1896 }
1897
1898 /* Determine the index in the virtual offset table (otable) for a call to
1899 METHOD. If this method has not been seen before, it will be added to the
1900 otable_methods. If it has, the existing otable slot will be reused. */
1901
1902 int
get_offset_table_index(method)1903 get_offset_table_index (method)
1904 tree method;
1905 {
1906 int i = 1;
1907 tree method_list;
1908
1909 if (otable_methods == NULL_TREE)
1910 {
1911 otable_methods = build_tree_list (method, method);
1912 return 1;
1913 }
1914
1915 method_list = otable_methods;
1916
1917 while (1)
1918 {
1919 if (TREE_VALUE (method_list) == method)
1920 return i;
1921 i++;
1922 if (TREE_CHAIN (method_list) == NULL_TREE)
1923 break;
1924 else
1925 method_list = TREE_CHAIN (method_list);
1926 }
1927
1928 TREE_CHAIN (method_list) = build_tree_list (method, method);
1929 return i;
1930 }
1931
1932 tree
build_invokevirtual(dtable,method)1933 build_invokevirtual (dtable, method)
1934 tree dtable, method;
1935 {
1936 tree func;
1937 tree nativecode_ptr_ptr_type_node
1938 = build_pointer_type (nativecode_ptr_type_node);
1939 tree method_index;
1940 tree otable_index;
1941
1942 if (flag_indirect_dispatch)
1943 {
1944 otable_index = build_int_2 (get_offset_table_index (method), 0);
1945 method_index = build (ARRAY_REF, integer_type_node, otable_decl,
1946 otable_index);
1947 }
1948 else
1949 {
1950 method_index = convert (sizetype, DECL_VINDEX (method));
1951
1952 if (TARGET_VTABLE_USES_DESCRIPTORS)
1953 /* Add one to skip bogus descriptor for class and GC descriptor. */
1954 method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
1955 else
1956 /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
1957 method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
1958
1959 method_index = size_binop (MULT_EXPR, method_index,
1960 TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
1961
1962 if (TARGET_VTABLE_USES_DESCRIPTORS)
1963 method_index = size_binop (MULT_EXPR, method_index,
1964 size_int (TARGET_VTABLE_USES_DESCRIPTORS));
1965 }
1966
1967 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node, dtable,
1968 convert (nativecode_ptr_ptr_type_node, method_index)));
1969
1970 if (TARGET_VTABLE_USES_DESCRIPTORS)
1971 func = build1 (NOP_EXPR, nativecode_ptr_type_node, func);
1972 else
1973 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1974
1975 return func;
1976 }
1977
1978 static GTY(()) tree class_ident;
1979 tree
build_invokeinterface(dtable,method)1980 build_invokeinterface (dtable, method)
1981 tree dtable, method;
1982 {
1983 tree lookup_arg;
1984 tree interface;
1985 tree idx;
1986 tree meth;
1987 tree otable_index;
1988 int i;
1989
1990 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1991 ensure that the selected method exists, is public and not
1992 abstract nor static. */
1993
1994 if (class_ident == NULL_TREE)
1995 {
1996 class_ident = get_identifier ("class");
1997 }
1998
1999 dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
2000 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
2001 lookup_field (&dtable_type, class_ident));
2002
2003 interface = DECL_CONTEXT (method);
2004 layout_class_methods (interface);
2005
2006 if (flag_indirect_dispatch)
2007 {
2008 otable_index = build_int_2 (get_offset_table_index (method), 0);
2009 idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
2010 }
2011 else
2012 {
2013 i = 1;
2014 for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
2015 {
2016 if (meth == method)
2017 {
2018 idx = build_int_2 (i, 0);
2019 break;
2020 }
2021 if (meth == NULL_TREE)
2022 abort ();
2023 }
2024 }
2025
2026 lookup_arg = tree_cons (NULL_TREE, dtable,
2027 tree_cons (NULL_TREE, build_class_ref (interface),
2028 build_tree_list (NULL_TREE, idx)));
2029
2030 return build (CALL_EXPR, ptr_type_node,
2031 build_address_of (soft_lookupinterfacemethod_node),
2032 lookup_arg, NULL_TREE);
2033 }
2034
2035 /* Expand one of the invoke_* opcodes.
2036 OCPODE is the specific opcode.
2037 METHOD_REF_INDEX is an index into the constant pool.
2038 NARGS is the number of arguments, or -1 if not specified. */
2039
2040 static void
expand_invoke(opcode,method_ref_index,nargs)2041 expand_invoke (opcode, method_ref_index, nargs)
2042 int opcode;
2043 int method_ref_index;
2044 int nargs ATTRIBUTE_UNUSED;
2045 {
2046 tree method_signature = COMPONENT_REF_SIGNATURE(¤t_jcf->cpool, method_ref_index);
2047 tree method_name = COMPONENT_REF_NAME (¤t_jcf->cpool, method_ref_index);
2048 tree self_type = get_class_constant
2049 (current_jcf, COMPONENT_REF_CLASS_INDEX(¤t_jcf->cpool, method_ref_index));
2050 const char *const self_name
2051 = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2052 tree call, func, method, arg_list, method_type;
2053 tree check = NULL_TREE;
2054
2055 if (! CLASS_LOADED_P (self_type))
2056 {
2057 load_class (self_type, 1);
2058 safe_layout_class (self_type);
2059 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
2060 fatal_error ("failed to find class '%s'", self_name);
2061 }
2062 layout_class_methods (self_type);
2063
2064 if (ID_INIT_P (method_name))
2065 method = lookup_java_constructor (self_type, method_signature);
2066 else
2067 method = lookup_java_method (self_type, method_name, method_signature);
2068 if (method == NULL_TREE)
2069 {
2070 error ("class '%s' has no method named '%s' matching signature '%s'",
2071 self_name,
2072 IDENTIFIER_POINTER (method_name),
2073 IDENTIFIER_POINTER (method_signature));
2074 }
2075 /* Invoke static can't invoke static/abstract method */
2076 else if (opcode == OPCODE_invokestatic)
2077 {
2078 if (!METHOD_STATIC (method))
2079 {
2080 error ("invokestatic on non static method");
2081 method = NULL_TREE;
2082 }
2083 else if (METHOD_ABSTRACT (method))
2084 {
2085 error ("invokestatic on abstract method");
2086 method = NULL_TREE;
2087 }
2088 }
2089 else
2090 {
2091 if (METHOD_STATIC (method))
2092 {
2093 error ("invoke[non-static] on static method");
2094 method = NULL_TREE;
2095 }
2096 }
2097
2098 if (method == NULL_TREE)
2099 {
2100 method_type = get_type_from_signature (method_signature);
2101 pop_arguments (TYPE_ARG_TYPES (method_type));
2102 if (opcode != OPCODE_invokestatic)
2103 pop_type (self_type);
2104 method_type = promote_type (TREE_TYPE (method_type));
2105 push_value (convert (method_type, integer_zero_node));
2106 return;
2107 }
2108
2109 method_type = TREE_TYPE (method);
2110 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
2111 flush_quick_stack ();
2112
2113 func = NULL_TREE;
2114 if (opcode == OPCODE_invokestatic)
2115 func = build_known_method_ref (method, method_type, self_type,
2116 method_signature, arg_list);
2117 else if (opcode == OPCODE_invokespecial
2118 || (opcode == OPCODE_invokevirtual
2119 && (METHOD_PRIVATE (method)
2120 || METHOD_FINAL (method)
2121 || CLASS_FINAL (TYPE_NAME (self_type)))))
2122 {
2123 /* If the object for the method call is null, we throw an
2124 exception. We don't do this if the object is the current
2125 method's `this'. In other cases we just rely on an
2126 optimization pass to eliminate redundant checks. FIXME:
2127 Unfortunately there doesn't seem to be a way to determine
2128 what the current method is right now.
2129 We do omit the check if we're calling <init>. */
2130 /* We use a SAVE_EXPR here to make sure we only evaluate
2131 the new `self' expression once. */
2132 tree save_arg = save_expr (TREE_VALUE (arg_list));
2133 TREE_VALUE (arg_list) = save_arg;
2134 check = java_check_reference (save_arg, ! DECL_INIT_P (method));
2135 func = build_known_method_ref (method, method_type, self_type,
2136 method_signature, arg_list);
2137 }
2138 else
2139 {
2140 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
2141 arg_list);
2142 if (opcode == OPCODE_invokevirtual)
2143 func = build_invokevirtual (dtable, method);
2144 else
2145 func = build_invokeinterface (dtable, method);
2146 }
2147 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
2148
2149 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
2150 TREE_SIDE_EFFECTS (call) = 1;
2151 call = check_for_builtin (method, call);
2152
2153 if (check != NULL_TREE)
2154 {
2155 call = build (COMPOUND_EXPR, TREE_TYPE (call), check, call);
2156 TREE_SIDE_EFFECTS (call) = 1;
2157 }
2158
2159 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
2160 expand_expr_stmt (call);
2161 else
2162 {
2163 push_value (call);
2164 flush_quick_stack ();
2165 }
2166 }
2167
2168 /* Create a stub which will be put into the vtable but which will call
2169 a JNI function. */
2170
2171 tree
build_jni_stub(method)2172 build_jni_stub (method)
2173 tree method;
2174 {
2175 tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
2176 tree jni_func_type, tem;
2177 tree env_var, res_var = NULL_TREE, block;
2178 tree method_args, res_type;
2179 tree meth_var;
2180
2181 int args_size = 0;
2182
2183 tree klass = DECL_CONTEXT (method);
2184 int from_class = ! CLASS_FROM_SOURCE_P (klass);
2185 klass = build_class_ref (klass);
2186
2187 if (! METHOD_NATIVE (method) || ! flag_jni)
2188 abort ();
2189
2190 DECL_ARTIFICIAL (method) = 1;
2191 DECL_EXTERNAL (method) = 0;
2192
2193 env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
2194 DECL_CONTEXT (env_var) = method;
2195
2196 if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
2197 {
2198 res_var = build_decl (VAR_DECL, get_identifier ("res"),
2199 TREE_TYPE (TREE_TYPE (method)));
2200 DECL_CONTEXT (res_var) = method;
2201 TREE_CHAIN (env_var) = res_var;
2202 }
2203
2204 meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
2205 TREE_STATIC (meth_var) = 1;
2206 TREE_PUBLIC (meth_var) = 0;
2207 DECL_EXTERNAL (meth_var) = 0;
2208 DECL_CONTEXT (meth_var) = method;
2209 DECL_ARTIFICIAL (meth_var) = 1;
2210 DECL_INITIAL (meth_var) = null_pointer_node;
2211 TREE_USED (meth_var) = 1;
2212 chainon (env_var, meth_var);
2213 layout_decl (meth_var, 0);
2214 make_decl_rtl (meth_var, NULL);
2215 rest_of_decl_compilation (meth_var, NULL, 0, 0);
2216
2217 /* One strange way that the front ends are different is that they
2218 store arguments differently. */
2219 if (from_class)
2220 method_args = DECL_ARGUMENTS (method);
2221 else
2222 method_args = BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (method));
2223 block = build_block (env_var, NULL_TREE, NULL_TREE,
2224 method_args, NULL_TREE);
2225 TREE_SIDE_EFFECTS (block) = 1;
2226 /* When compiling from source we don't set the type of the block,
2227 because that will prevent patch_return from ever being run. */
2228 if (from_class)
2229 TREE_TYPE (block) = TREE_TYPE (TREE_TYPE (method));
2230
2231 /* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
2232 body = build (MODIFY_EXPR, ptr_type_node, env_var,
2233 build (CALL_EXPR, ptr_type_node,
2234 build_address_of (soft_getjnienvnewframe_node),
2235 build_tree_list (NULL_TREE, klass),
2236 NULL_TREE));
2237 CAN_COMPLETE_NORMALLY (body) = 1;
2238
2239 /* All the arguments to this method become arguments to the
2240 underlying JNI function. If we had to wrap object arguments in a
2241 special way, we would do that here. */
2242 args = NULL_TREE;
2243 for (tem = method_args; tem != NULL_TREE; tem = TREE_CHAIN (tem))
2244 {
2245 int arg_bits = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem)));
2246 #ifdef PARM_BOUNDARY
2247 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
2248 * PARM_BOUNDARY);
2249 #endif
2250 args_size += (arg_bits / BITS_PER_UNIT);
2251
2252 args = tree_cons (NULL_TREE, tem, args);
2253 }
2254 args = nreverse (args);
2255 arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
2256
2257 /* For a static method the second argument is the class. For a
2258 non-static method the second argument is `this'; that is already
2259 available in the argument list. */
2260 if (METHOD_STATIC (method))
2261 {
2262 args_size += int_size_in_bytes (TREE_TYPE (klass));
2263 args = tree_cons (NULL_TREE, klass, args);
2264 arg_types = tree_cons (NULL_TREE, object_ptr_type_node, arg_types);
2265 }
2266
2267 /* The JNIEnv structure is the first argument to the JNI function. */
2268 args_size += int_size_in_bytes (TREE_TYPE (env_var));
2269 args = tree_cons (NULL_TREE, env_var, args);
2270 arg_types = tree_cons (NULL_TREE, ptr_type_node, arg_types);
2271
2272 /* We call _Jv_LookupJNIMethod to find the actual underlying
2273 function pointer. _Jv_LookupJNIMethod will throw the appropriate
2274 exception if this function is not found at runtime. */
2275 tem = build_tree_list (NULL_TREE, build_int_2 (args_size, 0));
2276 method_sig = build_java_signature (TREE_TYPE (method));
2277 lookup_arg = tree_cons (NULL_TREE,
2278 build_utf8_ref (unmangle_classname
2279 (IDENTIFIER_POINTER (method_sig),
2280 IDENTIFIER_LENGTH (method_sig))),
2281 tem);
2282 tem = DECL_NAME (method);
2283 lookup_arg
2284 = tree_cons (NULL_TREE, klass,
2285 tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
2286
2287 tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
2288
2289 #ifdef MODIFY_JNI_METHOD_CALL
2290 tem = MODIFY_JNI_METHOD_CALL (tem);
2291 #endif
2292
2293 jni_func_type = build_pointer_type (tem);
2294
2295 jnifunc = build (COND_EXPR, ptr_type_node,
2296 meth_var, meth_var,
2297 build (MODIFY_EXPR, ptr_type_node,
2298 meth_var,
2299 build (CALL_EXPR, ptr_type_node,
2300 build_address_of (soft_lookupjnimethod_node),
2301 lookup_arg, NULL_TREE)));
2302
2303 /* Now we make the actual JNI call via the resulting function
2304 pointer. */
2305 call = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
2306 build1 (NOP_EXPR, jni_func_type, jnifunc),
2307 args, NULL_TREE);
2308
2309 /* If the JNI call returned a result, capture it here. If we had to
2310 unwrap JNI object results, we would do that here. */
2311 if (res_var != NULL_TREE)
2312 call = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
2313 res_var, call);
2314
2315 TREE_SIDE_EFFECTS (call) = 1;
2316 CAN_COMPLETE_NORMALLY (call) = 1;
2317
2318 body = build (COMPOUND_EXPR, void_type_node, body, call);
2319 TREE_SIDE_EFFECTS (body) = 1;
2320
2321 /* Now free the environment we allocated. */
2322 call = build (CALL_EXPR, ptr_type_node,
2323 build_address_of (soft_jnipopsystemframe_node),
2324 build_tree_list (NULL_TREE, env_var),
2325 NULL_TREE);
2326 TREE_SIDE_EFFECTS (call) = 1;
2327 CAN_COMPLETE_NORMALLY (call) = 1;
2328 body = build (COMPOUND_EXPR, void_type_node, body, call);
2329 TREE_SIDE_EFFECTS (body) = 1;
2330
2331 /* Finally, do the return. When compiling from source we rely on
2332 patch_return to patch the return value -- because DECL_RESULT is
2333 not set at the time this function is called. */
2334 if (from_class)
2335 {
2336 res_type = void_type_node;
2337 if (res_var != NULL_TREE)
2338 {
2339 tree drt;
2340 if (! DECL_RESULT (method))
2341 abort ();
2342 /* Make sure we copy the result variable to the actual
2343 result. We use the type of the DECL_RESULT because it
2344 might be different from the return type of the function:
2345 it might be promoted. */
2346 drt = TREE_TYPE (DECL_RESULT (method));
2347 if (drt != TREE_TYPE (res_var))
2348 res_var = build1 (CONVERT_EXPR, drt, res_var);
2349 res_var = build (MODIFY_EXPR, drt, DECL_RESULT (method), res_var);
2350 TREE_SIDE_EFFECTS (res_var) = 1;
2351 }
2352 }
2353 else
2354 {
2355 /* This is necessary to get patch_return to run. */
2356 res_type = NULL_TREE;
2357 }
2358 body = build (COMPOUND_EXPR, void_type_node, body,
2359 build1 (RETURN_EXPR, res_type, res_var));
2360 TREE_SIDE_EFFECTS (body) = 1;
2361
2362 BLOCK_EXPR_BODY (block) = body;
2363 return block;
2364 }
2365
2366 /* Expand an operation to extract from or store into a field.
2367 IS_STATIC is 1 iff the field is static.
2368 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
2369 FIELD_REF_INDEX is an index into the constant pool. */
2370
2371 static void
expand_java_field_op(is_static,is_putting,field_ref_index)2372 expand_java_field_op (is_static, is_putting, field_ref_index)
2373 int is_static;
2374 int is_putting;
2375 int field_ref_index;
2376 {
2377 tree self_type =
2378 get_class_constant (current_jcf,
2379 COMPONENT_REF_CLASS_INDEX (¤t_jcf->cpool,
2380 field_ref_index));
2381 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
2382 tree field_name = COMPONENT_REF_NAME (¤t_jcf->cpool, field_ref_index);
2383 tree field_signature = COMPONENT_REF_SIGNATURE (¤t_jcf->cpool,
2384 field_ref_index);
2385 tree field_type = get_type_from_signature (field_signature);
2386 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
2387 tree field_ref;
2388 int is_error = 0;
2389 tree field_decl = lookup_field (&self_type, field_name);
2390 if (field_decl == error_mark_node)
2391 {
2392 is_error = 1;
2393 }
2394 else if (field_decl == NULL_TREE)
2395 {
2396 error ("missing field '%s' in '%s'",
2397 IDENTIFIER_POINTER (field_name), self_name);
2398 is_error = 1;
2399 }
2400 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
2401 {
2402 error ("mismatching signature for field '%s' in '%s'",
2403 IDENTIFIER_POINTER (field_name), self_name);
2404 is_error = 1;
2405 }
2406 field_ref = is_static ? NULL_TREE : pop_value (self_type);
2407 if (is_error)
2408 {
2409 if (! is_putting)
2410 push_value (convert (field_type, integer_zero_node));
2411 flush_quick_stack ();
2412 return;
2413 }
2414
2415 field_ref = build_field_ref (field_ref, self_type, field_name);
2416 if (is_static)
2417 field_ref = build_class_init (self_type, field_ref);
2418 if (is_putting)
2419 {
2420 flush_quick_stack ();
2421 if (FIELD_FINAL (field_decl))
2422 {
2423 if (DECL_CONTEXT (field_decl) != current_class)
2424 error_with_decl (field_decl,
2425 "assignment to final field `%s' not in field's class");
2426 else if (FIELD_STATIC (field_decl))
2427 {
2428 if (!DECL_CLINIT_P (current_function_decl))
2429 warning_with_decl (field_decl,
2430 "assignment to final static field `%s' not in class initializer");
2431 }
2432 else
2433 {
2434 tree cfndecl_name = DECL_NAME (current_function_decl);
2435 if (! DECL_CONSTRUCTOR_P (current_function_decl)
2436 && !ID_FINIT_P (cfndecl_name))
2437 warning_with_decl (field_decl, "assignment to final field `%s' not in constructor");
2438 }
2439 }
2440 expand_assignment (field_ref, new_value, 0, 0);
2441 }
2442 else
2443 push_value (field_ref);
2444 }
2445
2446 void
load_type_state(label)2447 load_type_state (label)
2448 tree label;
2449 {
2450 int i;
2451 tree vec = LABEL_TYPE_STATE (label);
2452 int cur_length = TREE_VEC_LENGTH (vec);
2453 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
2454 for (i = 0; i < cur_length; i++)
2455 type_map [i] = TREE_VEC_ELT (vec, i);
2456 }
2457
2458 /* Do the expansion of a Java switch. With Gcc, switches are front-end
2459 dependent things, but they rely on gcc routines. This function is
2460 placed here because it uses things defined locally in parse.y. */
2461
2462 static tree
case_identity(t,v)2463 case_identity (t, v)
2464 tree t __attribute__ ((__unused__));
2465 tree v;
2466 {
2467 return v;
2468 }
2469
2470 /* Return the name of the vtable for an array of a given primitive
2471 type. */
2472 static tree
get_primitive_array_vtable(tree elt)2473 get_primitive_array_vtable (tree elt)
2474 {
2475 tree r;
2476 if (elt == boolean_type_node)
2477 r = boolean_array_vtable;
2478 else if (elt == byte_type_node)
2479 r = byte_array_vtable;
2480 else if (elt == char_type_node)
2481 r = char_array_vtable;
2482 else if (elt == short_type_node)
2483 r = short_array_vtable;
2484 else if (elt == int_type_node)
2485 r = int_array_vtable;
2486 else if (elt == long_type_node)
2487 r = long_array_vtable;
2488 else if (elt == float_type_node)
2489 r = float_array_vtable;
2490 else if (elt == double_type_node)
2491 r = double_array_vtable;
2492 else
2493 abort ();
2494 return build_address_of (r);
2495 }
2496
2497 struct rtx_def *
java_expand_expr(exp,target,tmode,modifier)2498 java_expand_expr (exp, target, tmode, modifier)
2499 register tree exp;
2500 rtx target;
2501 enum machine_mode tmode;
2502 int modifier; /* Actually an enum expand_modifier. */
2503 {
2504 tree current;
2505
2506 switch (TREE_CODE (exp))
2507 {
2508 case NEW_ARRAY_INIT:
2509 {
2510 rtx tmp;
2511 tree array_type = TREE_TYPE (TREE_TYPE (exp));
2512 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
2513 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
2514 HOST_WIDE_INT ilength = java_array_type_length (array_type);
2515 tree length = build_int_2 (ilength, 0);
2516 tree init = TREE_OPERAND (exp, 0);
2517 tree array_decl;
2518
2519 /* See if we can generate the array statically. */
2520 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
2521 && JPRIMITIVE_TYPE_P (element_type))
2522 {
2523 tree temp, value, init_decl;
2524 struct rtx_def *r;
2525 START_RECORD_CONSTRUCTOR (temp, object_type_node);
2526 PUSH_FIELD_VALUE (temp, "vtable",
2527 get_primitive_array_vtable (element_type));
2528 if (! flag_hash_synchronization)
2529 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
2530 FINISH_RECORD_CONSTRUCTOR (temp);
2531 START_RECORD_CONSTRUCTOR (value, array_type);
2532 PUSH_SUPER_VALUE (value, temp);
2533 PUSH_FIELD_VALUE (value, "length", length);
2534 PUSH_FIELD_VALUE (value, "data", init);
2535 FINISH_RECORD_CONSTRUCTOR (value);
2536
2537 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
2538 pushdecl_top_level (init_decl);
2539 TREE_STATIC (init_decl) = 1;
2540 DECL_INITIAL (init_decl) = value;
2541 DECL_IGNORED_P (init_decl) = 1;
2542 TREE_READONLY (init_decl) = 1;
2543 /* Hash synchronization requires at least 64-bit alignment. */
2544 if (flag_hash_synchronization && POINTER_SIZE < 64)
2545 DECL_ALIGN (init_decl) = 64;
2546 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2547 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2548 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
2549 r = expand_expr (init, target, tmode, modifier);
2550 return r;
2551 }
2552
2553 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
2554 expand_decl (array_decl);
2555 tmp = expand_assignment (array_decl,
2556 build_new_array (element_type, length),
2557 1, 0);
2558 if (TREE_CONSTANT (init)
2559 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
2560 {
2561 tree init_decl;
2562 init_decl = build_decl (VAR_DECL, generate_name (),
2563 TREE_TYPE (init));
2564 pushdecl_top_level (init_decl);
2565 TREE_STATIC (init_decl) = 1;
2566 DECL_INITIAL (init_decl) = init;
2567 DECL_IGNORED_P (init_decl) = 1;
2568 TREE_READONLY (init_decl) = 1;
2569 rest_of_decl_compilation (init_decl, NULL, 1, 0);
2570 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
2571 init = init_decl;
2572 }
2573 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2574 build_java_indirect_ref (array_type,
2575 array_decl, flag_check_references),
2576 data_fld), init, 0, 0);
2577 return tmp;
2578 }
2579 case BLOCK:
2580 if (BLOCK_EXPR_BODY (exp))
2581 {
2582 tree local;
2583 rtx last;
2584 tree body = BLOCK_EXPR_BODY (exp);
2585 /* Set to 1 or more when we found a static class
2586 initialization flag. */
2587 int found_class_initialization_flag = 0;
2588
2589 pushlevel (2); /* 2 and above */
2590 expand_start_bindings (0);
2591 local = BLOCK_EXPR_DECLS (exp);
2592 while (local)
2593 {
2594 tree next = TREE_CHAIN (local);
2595 found_class_initialization_flag +=
2596 LOCAL_CLASS_INITIALIZATION_FLAG_P (local);
2597 layout_decl (local, 0);
2598 expand_decl (pushdecl (local));
2599 local = next;
2600 }
2601
2602 /* Emit initialization code for test flags if we saw one. */
2603 if (! always_initialize_class_p
2604 && current_function_decl
2605 && found_class_initialization_flag)
2606 htab_traverse
2607 (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
2608 emit_init_test_initialization, NULL);
2609
2610 /* Avoid deep recursion for long block. */
2611 while (TREE_CODE (body) == COMPOUND_EXPR)
2612 {
2613 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
2614 emit_queue ();
2615 body = TREE_OPERAND (body, 1);
2616 }
2617 last = expand_expr (body, NULL_RTX, VOIDmode, 0);
2618 emit_queue ();
2619 expand_end_bindings (getdecls (), 1, 0);
2620 poplevel (1, 1, 0);
2621 return last;
2622 }
2623 return const0_rtx;
2624
2625 case CASE_EXPR:
2626 {
2627 tree duplicate;
2628 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
2629 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2630 &duplicate) == 2)
2631 {
2632 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2633 parse_error_context
2634 (wfl_operator, "Duplicate case label: `%s'",
2635 print_int_node (TREE_OPERAND (exp, 0)));
2636 }
2637 return const0_rtx;
2638 }
2639
2640 case DEFAULT_EXPR:
2641 pushcase (NULL_TREE, 0,
2642 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
2643 return const0_rtx;
2644
2645 case SWITCH_EXPR:
2646 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2647 expand_expr_stmt (TREE_OPERAND (exp, 1));
2648 expand_end_case (TREE_OPERAND (exp, 0));
2649 return const0_rtx;
2650
2651 case TRY_EXPR:
2652 /* We expand a try[-catch] block */
2653
2654 /* Expand the try block */
2655 expand_eh_region_start ();
2656 expand_expr_stmt (TREE_OPERAND (exp, 0));
2657 expand_start_all_catch ();
2658
2659 /* Expand all catch clauses (EH handlers) */
2660 for (current = TREE_OPERAND (exp, 1); current;
2661 current = TREE_CHAIN (current))
2662 {
2663 tree catch = TREE_OPERAND (current, 0);
2664 tree decl = BLOCK_EXPR_DECLS (catch);
2665 tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
2666
2667 expand_start_catch (type);
2668 expand_expr_stmt (TREE_OPERAND (current, 0));
2669 expand_end_catch ();
2670 }
2671 expand_end_all_catch ();
2672 return const0_rtx;
2673
2674 case JAVA_EXC_OBJ_EXPR:
2675 return expand_expr (build_exception_object_ref (TREE_TYPE (exp)),
2676 target, tmode, modifier);
2677
2678 case LABEL_EXPR:
2679 /* Used only by expanded inline functions. */
2680 expand_label (TREE_OPERAND (exp, 0));
2681 return const0_rtx;
2682
2683 default:
2684 internal_error ("can't expand %s", tree_code_name [TREE_CODE (exp)]);
2685 }
2686 }
2687
2688 /* Go over METHOD's bytecode and note instruction starts in
2689 instruction_bits[]. */
2690
2691 void
note_instructions(jcf,method)2692 note_instructions (jcf, method)
2693 JCF *jcf;
2694 tree method;
2695 {
2696 int PC;
2697 unsigned char* byte_ops;
2698 long length = DECL_CODE_LENGTH (method);
2699
2700 int saw_index;
2701 jint INT_temp;
2702
2703 #undef RET /* Defined by config/i386/i386.h */
2704 #undef AND /* Causes problems with opcodes for iand and land. */
2705 #undef PTR
2706 #define BCODE byte_ops
2707 #define BYTE_type_node byte_type_node
2708 #define SHORT_type_node short_type_node
2709 #define INT_type_node int_type_node
2710 #define LONG_type_node long_type_node
2711 #define CHAR_type_node char_type_node
2712 #define PTR_type_node ptr_type_node
2713 #define FLOAT_type_node float_type_node
2714 #define DOUBLE_type_node double_type_node
2715 #define VOID_type_node void_type_node
2716 #define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2717 #define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2718 #define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2719 #define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2720
2721 #define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
2722
2723 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2724 byte_ops = jcf->read_ptr;
2725 instruction_bits = xrealloc (instruction_bits, length + 1);
2726 memset (instruction_bits, 0, length + 1);
2727
2728 /* This pass figures out which PC can be the targets of jumps. */
2729 for (PC = 0; PC < length;)
2730 {
2731 int oldpc = PC; /* PC at instruction start. */
2732 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2733 switch (byte_ops[PC++])
2734 {
2735 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2736 case OPCODE: \
2737 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2738 break;
2739
2740 #define NOTE_LABEL(PC) note_label(oldpc, PC)
2741
2742 #define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2743 #define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2744 #define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2745 #define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2746 #define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2747 #define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2748 #define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2749 #define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2750
2751 #define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2752 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2753 #define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2754 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2755 #define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2756 #define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2757 #define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2758 #define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2759
2760 /* two forms of wide instructions */
2761 #define PRE_SPECIAL_WIDE(IGNORE) \
2762 { \
2763 int modified_opcode = IMMEDIATE_u1; \
2764 if (modified_opcode == OPCODE_iinc) \
2765 { \
2766 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2767 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2768 } \
2769 else \
2770 { \
2771 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2772 } \
2773 }
2774
2775 #define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2776
2777 #define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2778
2779 #define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2780 #define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2781 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2782 #define PRE_ARRAY_LOAD(TYPE) /* nothing */
2783 #define PRE_ARRAY_STORE(TYPE) /* nothing */
2784 #define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2785 #define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2786 #define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2787 #define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2788 #define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2789
2790 #define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2791 #define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2792 #define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2793 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2794 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2795 #define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2796 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2797 NOTE_LABEL (PC); \
2798 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2799
2800 #define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2801
2802 #define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2803 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2804
2805 #define PRE_LOOKUP_SWITCH \
2806 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2807 NOTE_LABEL (default_offset+oldpc); \
2808 if (npairs >= 0) \
2809 while (--npairs >= 0) { \
2810 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2811 jint offset = IMMEDIATE_s4; \
2812 NOTE_LABEL (offset+oldpc); } \
2813 }
2814
2815 #define PRE_TABLE_SWITCH \
2816 { jint default_offset = IMMEDIATE_s4; \
2817 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2818 NOTE_LABEL (default_offset+oldpc); \
2819 if (low <= high) \
2820 while (low++ <= high) { \
2821 jint offset = IMMEDIATE_s4; \
2822 NOTE_LABEL (offset+oldpc); } \
2823 }
2824
2825 #define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2826 #define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2827 #define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2828 (void)(IMMEDIATE_u2); \
2829 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2830
2831 #include "javaop.def"
2832 #undef JAVAOP
2833 }
2834 } /* for */
2835 }
2836
2837 void
expand_byte_code(jcf,method)2838 expand_byte_code (jcf, method)
2839 JCF *jcf;
2840 tree method;
2841 {
2842 int PC;
2843 int i;
2844 const unsigned char *linenumber_pointer;
2845 int dead_code_index = -1;
2846 unsigned char* byte_ops;
2847 long length = DECL_CODE_LENGTH (method);
2848
2849 stack_pointer = 0;
2850 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2851 byte_ops = jcf->read_ptr;
2852
2853 /* We make an initial pass of the line number table, to note
2854 which instructions have associated line number entries. */
2855 linenumber_pointer = linenumber_table;
2856 for (i = 0; i < linenumber_count; i++)
2857 {
2858 int pc = GET_u2 (linenumber_pointer);
2859 linenumber_pointer += 4;
2860 if (pc >= length)
2861 warning ("invalid PC in line number table");
2862 else
2863 {
2864 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2865 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2866 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2867 }
2868 }
2869
2870 if (! verify_jvm_instructions (jcf, byte_ops, length))
2871 return;
2872
2873 /* Translate bytecodes to rtl instructions. */
2874 linenumber_pointer = linenumber_table;
2875 for (PC = 0; PC < length;)
2876 {
2877 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2878 {
2879 tree label = lookup_label (PC);
2880 flush_quick_stack ();
2881 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2882 expand_label (label);
2883 if (LABEL_VERIFIED (label) || PC == 0)
2884 load_type_state (label);
2885 }
2886
2887 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2888 {
2889 if (dead_code_index == -1)
2890 {
2891 /* This is the start of a region of unreachable bytecodes.
2892 They still need to be processed in order for EH ranges
2893 to get handled correctly. However, we can simply
2894 replace these bytecodes with nops. */
2895 dead_code_index = PC;
2896 }
2897
2898 /* Turn this bytecode into a nop. */
2899 byte_ops[PC] = 0x0;
2900 }
2901 else
2902 {
2903 if (dead_code_index != -1)
2904 {
2905 /* We've just reached the end of a region of dead code. */
2906 warning ("unreachable bytecode from %d to before %d",
2907 dead_code_index, PC);
2908 dead_code_index = -1;
2909 }
2910 }
2911
2912 /* Handle possible line number entry for this PC.
2913
2914 This code handles out-of-order and multiple linenumbers per PC,
2915 but is optimized for the case of line numbers increasing
2916 monotonically with PC. */
2917 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2918 {
2919 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2920 || GET_u2 (linenumber_pointer) != PC)
2921 linenumber_pointer = linenumber_table;
2922 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2923 {
2924 int pc = GET_u2 (linenumber_pointer);
2925 linenumber_pointer += 4;
2926 if (pc == PC)
2927 {
2928 lineno = GET_u2 (linenumber_pointer - 2);
2929 emit_line_note (input_filename, lineno);
2930 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2931 break;
2932 }
2933 }
2934 }
2935 maybe_pushlevels (PC);
2936 PC = process_jvm_instruction (PC, byte_ops, length);
2937 maybe_poplevels (PC);
2938 } /* for */
2939
2940 if (dead_code_index != -1)
2941 {
2942 /* We've just reached the end of a region of dead code. */
2943 warning ("unreachable bytecode from %d to the end of the method",
2944 dead_code_index);
2945 }
2946 }
2947
2948 static void
java_push_constant_from_pool(jcf,index)2949 java_push_constant_from_pool (jcf, index)
2950 JCF *jcf;
2951 int index;
2952 {
2953 tree c;
2954 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2955 {
2956 tree name;
2957 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2958 index = alloc_name_constant (CONSTANT_String, name);
2959 c = build_ref_from_constant_pool (index);
2960 TREE_TYPE (c) = promote_type (string_type_node);
2961 }
2962 else
2963 c = get_constant (jcf, index);
2964 push_value (c);
2965 }
2966
2967 int
process_jvm_instruction(PC,byte_ops,length)2968 process_jvm_instruction (PC, byte_ops, length)
2969 int PC;
2970 const unsigned char* byte_ops;
2971 long length ATTRIBUTE_UNUSED;
2972 {
2973 const char *opname; /* Temporary ??? */
2974 int oldpc = PC; /* PC at instruction start. */
2975
2976 /* If the instruction is at the beginning of a exception handler,
2977 replace the top of the stack with the thrown object reference */
2978 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2979 {
2980 tree type = pop_type (ptr_type_node);
2981 push_value (build (JAVA_EXC_OBJ_EXPR, type));
2982 }
2983
2984 switch (byte_ops[PC++])
2985 {
2986 #define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2987 case OPCODE: \
2988 opname = #OPNAME; \
2989 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2990 break;
2991
2992 #define RET(OPERAND_TYPE, OPERAND_VALUE) \
2993 { \
2994 int saw_index = 0; \
2995 int index = OPERAND_VALUE; \
2996 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2997 }
2998
2999 #define JSR(OPERAND_TYPE, OPERAND_VALUE) \
3000 { \
3001 /* OPERAND_VALUE may have side-effects on PC */ \
3002 int opvalue = OPERAND_VALUE; \
3003 build_java_jsr (oldpc + opvalue, PC); \
3004 }
3005
3006 /* Push a constant onto the stack. */
3007 #define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
3008 { int saw_index = 0; int ival = (OPERAND_VALUE); \
3009 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
3010 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
3011
3012 /* internal macro added for use by the WIDE case */
3013 #define LOAD_INTERNAL(OPTYPE, OPVALUE) \
3014 expand_load_internal (OPVALUE, type_map[OPVALUE], oldpc);
3015
3016 /* Push local variable onto the opcode stack. */
3017 #define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
3018 { \
3019 /* have to do this since OPERAND_VALUE may have side-effects */ \
3020 int opvalue = OPERAND_VALUE; \
3021 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3022 }
3023
3024 #define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
3025 expand_java_return (OPERAND_TYPE##_type_node)
3026
3027 #define REM_EXPR TRUNC_MOD_EXPR
3028 #define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
3029 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
3030
3031 #define FIELD(IS_STATIC, IS_PUT) \
3032 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
3033
3034 #define TEST(OPERAND_TYPE, CONDITION) \
3035 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3036
3037 #define COND(OPERAND_TYPE, CONDITION) \
3038 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
3039
3040 #define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
3041 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
3042
3043 #define BRANCH_GOTO(OPERAND_VALUE) \
3044 expand_java_goto (oldpc + OPERAND_VALUE)
3045
3046 #define BRANCH_CALL(OPERAND_VALUE) \
3047 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
3048
3049 #if 0
3050 #define BRANCH_RETURN(OPERAND_VALUE) \
3051 { \
3052 tree type = OPERAND_TYPE##_type_node; \
3053 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
3054 expand_java_ret (value); \
3055 }
3056 #endif
3057
3058 #define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
3059 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3060 fprintf (stderr, "(not implemented)\n")
3061 #define NOT_IMPL1(OPERAND_VALUE) \
3062 fprintf (stderr, "%3d: %s ", oldpc, opname); \
3063 fprintf (stderr, "(not implemented)\n")
3064
3065 #define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
3066
3067 #define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
3068
3069 #define STACK_POP(COUNT) java_stack_pop (COUNT)
3070
3071 #define STACK_SWAP(COUNT) java_stack_swap()
3072
3073 #define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
3074 #define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
3075 #define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
3076
3077 #define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
3078 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
3079
3080 #define LOOKUP_SWITCH \
3081 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
3082 tree selector = pop_value (INT_type_node); \
3083 tree duplicate, label; \
3084 tree type = TREE_TYPE (selector); \
3085 flush_quick_stack (); \
3086 expand_start_case (0, selector, type, "switch statement");\
3087 while (--npairs >= 0) \
3088 { \
3089 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
3090 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
3091 TREE_TYPE (value) = type; \
3092 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3093 pushcase (value, convert, label, &duplicate); \
3094 expand_java_goto (oldpc + offset); \
3095 } \
3096 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3097 pushcase (NULL_TREE, 0, label, &duplicate); \
3098 expand_java_goto (oldpc + default_offset); \
3099 expand_end_case (selector); \
3100 }
3101
3102 #define TABLE_SWITCH \
3103 { jint default_offset = IMMEDIATE_s4; \
3104 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
3105 tree selector = pop_value (INT_type_node); \
3106 tree duplicate, label; \
3107 tree type = TREE_TYPE (selector); \
3108 flush_quick_stack (); \
3109 expand_start_case (0, selector, type, "switch statement");\
3110 for (; low <= high; low++) \
3111 { \
3112 jint offset = IMMEDIATE_s4; \
3113 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
3114 TREE_TYPE (value) = type; \
3115 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3116 pushcase (value, convert, label, &duplicate); \
3117 expand_java_goto (oldpc + offset); \
3118 } \
3119 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
3120 pushcase (NULL_TREE, 0, label, &duplicate); \
3121 expand_java_goto (oldpc + default_offset); \
3122 expand_end_case (selector); \
3123 }
3124
3125 #define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
3126 { int opcode = byte_ops[PC-1]; \
3127 int method_ref_index = IMMEDIATE_u2; \
3128 int nargs; \
3129 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
3130 else nargs = -1; \
3131 expand_invoke (opcode, method_ref_index, nargs); \
3132 }
3133
3134 /* Handle new, checkcast, instanceof */
3135 #define OBJECT(TYPE, OP) \
3136 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
3137
3138 #define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
3139
3140 #define ARRAY_LOAD(OPERAND_TYPE) \
3141 { \
3142 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
3143 }
3144
3145 #define ARRAY_STORE(OPERAND_TYPE) \
3146 { \
3147 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
3148 }
3149
3150 #define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
3151 #define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
3152 #define ARRAY_NEW_PTR() \
3153 push_value (build_anewarray (get_class_constant (current_jcf, \
3154 IMMEDIATE_u2), \
3155 pop_value (int_type_node)));
3156 #define ARRAY_NEW_NUM() \
3157 { \
3158 int atype = IMMEDIATE_u1; \
3159 push_value (build_newarray (atype, pop_value (int_type_node)));\
3160 }
3161 #define ARRAY_NEW_MULTI() \
3162 { \
3163 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
3164 int ndims = IMMEDIATE_u1; \
3165 expand_java_multianewarray( class, ndims ); \
3166 }
3167
3168 #define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
3169 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
3170 pop_value (OPERAND_TYPE##_type_node))));
3171
3172 #define CONVERT2(FROM_TYPE, TO_TYPE) \
3173 { \
3174 push_value (build1 (NOP_EXPR, int_type_node, \
3175 (convert (TO_TYPE##_type_node, \
3176 pop_value (FROM_TYPE##_type_node))))); \
3177 }
3178
3179 #define CONVERT(FROM_TYPE, TO_TYPE) \
3180 { \
3181 push_value (convert (TO_TYPE##_type_node, \
3182 pop_value (FROM_TYPE##_type_node))); \
3183 }
3184
3185 /* internal macro added for use by the WIDE case
3186 Added TREE_TYPE (decl) assignment, apbianco */
3187 #define STORE_INTERNAL(OPTYPE, OPVALUE) \
3188 { \
3189 tree decl, value; \
3190 int var = OPVALUE; \
3191 tree type = OPTYPE; \
3192 value = pop_value (type); \
3193 type = TREE_TYPE (value); \
3194 decl = find_local_variable (var, type, oldpc); \
3195 set_local_type (var, type ); \
3196 expand_assignment (decl, value, 0, 0); \
3197 }
3198
3199 #define STORE(OPERAND_TYPE, OPERAND_VALUE) \
3200 { \
3201 /* have to do this since OPERAND_VALUE may have side-effects */ \
3202 int opvalue = OPERAND_VALUE; \
3203 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
3204 }
3205
3206 #define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
3207 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
3208
3209 #define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
3210 #define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
3211
3212 #define MONITOR_OPERATION(call) \
3213 { \
3214 tree o = pop_value (ptr_type_node); \
3215 tree c; \
3216 flush_quick_stack (); \
3217 c = build_java_monitor (call, o); \
3218 TREE_SIDE_EFFECTS (c) = 1; \
3219 expand_expr_stmt (c); \
3220 }
3221
3222 #define SPECIAL_IINC(IGNORED) \
3223 { \
3224 unsigned int local_var_index = IMMEDIATE_u1; \
3225 int ival = IMMEDIATE_s1; \
3226 expand_iinc(local_var_index, ival, oldpc); \
3227 }
3228
3229 #define SPECIAL_WIDE(IGNORED) \
3230 { \
3231 int modified_opcode = IMMEDIATE_u1; \
3232 unsigned int local_var_index = IMMEDIATE_u2; \
3233 switch (modified_opcode) \
3234 { \
3235 case OPCODE_iinc: \
3236 { \
3237 int ival = IMMEDIATE_s2; \
3238 expand_iinc (local_var_index, ival, oldpc); \
3239 break; \
3240 } \
3241 case OPCODE_iload: \
3242 case OPCODE_lload: \
3243 case OPCODE_fload: \
3244 case OPCODE_dload: \
3245 case OPCODE_aload: \
3246 { \
3247 /* duplicate code from LOAD macro */ \
3248 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
3249 break; \
3250 } \
3251 case OPCODE_istore: \
3252 case OPCODE_lstore: \
3253 case OPCODE_fstore: \
3254 case OPCODE_dstore: \
3255 case OPCODE_astore: \
3256 { \
3257 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
3258 break; \
3259 } \
3260 default: \
3261 error ("unrecogized wide sub-instruction"); \
3262 } \
3263 }
3264
3265 #define SPECIAL_THROW(IGNORED) \
3266 build_java_athrow (pop_value (throwable_type_node))
3267
3268 #define SPECIAL_BREAK NOT_IMPL1
3269 #define IMPL NOT_IMPL
3270
3271 #include "javaop.def"
3272 #undef JAVAOP
3273 default:
3274 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
3275 }
3276 return PC;
3277 }
3278
3279 /* Return the opcode at PC in the code section pointed to by
3280 CODE_OFFSET. */
3281
3282 static unsigned char
peek_opcode_at_pc(jcf,code_offset,pc)3283 peek_opcode_at_pc (jcf, code_offset, pc)
3284 JCF *jcf;
3285 int code_offset, pc;
3286 {
3287 unsigned char opcode;
3288 long absolute_offset = (long)JCF_TELL (jcf);
3289
3290 JCF_SEEK (jcf, code_offset);
3291 opcode = jcf->read_ptr [pc];
3292 JCF_SEEK (jcf, absolute_offset);
3293 return opcode;
3294 }
3295
3296 /* Some bytecode compilers are emitting accurate LocalVariableTable
3297 attributes. Here's an example:
3298
3299 PC <t>store_<n>
3300 PC+1 ...
3301
3302 Attribute "LocalVariableTable"
3303 slot #<n>: ... (PC: PC+1 length: L)
3304
3305 This is accurate because the local in slot <n> really exists after
3306 the opcode at PC is executed, hence from PC+1 to PC+1+L.
3307
3308 This procedure recognizes this situation and extends the live range
3309 of the local in SLOT to START_PC-1 or START_PC-2 (depending on the
3310 length of the store instruction.)
3311
3312 This function is used by `give_name_to_locals' so that a local's
3313 DECL features a DECL_LOCAL_START_PC such that the first related
3314 store operation will use DECL as a destination, not a unrelated
3315 temporary created for the occasion.
3316
3317 This function uses a global (instruction_bits) `note_instructions' should
3318 have allocated and filled properly. */
3319
3320 int
maybe_adjust_start_pc(jcf,code_offset,start_pc,slot)3321 maybe_adjust_start_pc (jcf, code_offset, start_pc, slot)
3322 struct JCF *jcf;
3323 int code_offset, start_pc, slot;
3324 {
3325 int first, index, opcode;
3326 int pc, insn_pc;
3327 int wide_found = 0;
3328
3329 if (!start_pc)
3330 return start_pc;
3331
3332 first = index = -1;
3333
3334 /* Find last previous instruction and remember it */
3335 for (pc = start_pc-1; pc; pc--)
3336 if (instruction_bits [pc] & BCODE_INSTRUCTION_START)
3337 break;
3338 insn_pc = pc;
3339
3340 /* Retrieve the instruction, handle `wide'. */
3341 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3342 if (opcode == OPCODE_wide)
3343 {
3344 wide_found = 1;
3345 opcode = (int) peek_opcode_at_pc (jcf, code_offset, pc++);
3346 }
3347
3348 switch (opcode)
3349 {
3350 case OPCODE_astore_0:
3351 case OPCODE_astore_1:
3352 case OPCODE_astore_2:
3353 case OPCODE_astore_3:
3354 first = OPCODE_astore_0;
3355 break;
3356
3357 case OPCODE_istore_0:
3358 case OPCODE_istore_1:
3359 case OPCODE_istore_2:
3360 case OPCODE_istore_3:
3361 first = OPCODE_istore_0;
3362 break;
3363
3364 case OPCODE_lstore_0:
3365 case OPCODE_lstore_1:
3366 case OPCODE_lstore_2:
3367 case OPCODE_lstore_3:
3368 first = OPCODE_lstore_0;
3369 break;
3370
3371 case OPCODE_fstore_0:
3372 case OPCODE_fstore_1:
3373 case OPCODE_fstore_2:
3374 case OPCODE_fstore_3:
3375 first = OPCODE_fstore_0;
3376 break;
3377
3378 case OPCODE_dstore_0:
3379 case OPCODE_dstore_1:
3380 case OPCODE_dstore_2:
3381 case OPCODE_dstore_3:
3382 first = OPCODE_dstore_0;
3383 break;
3384
3385 case OPCODE_astore:
3386 case OPCODE_istore:
3387 case OPCODE_lstore:
3388 case OPCODE_fstore:
3389 case OPCODE_dstore:
3390 index = peek_opcode_at_pc (jcf, code_offset, pc);
3391 if (wide_found)
3392 {
3393 int other = peek_opcode_at_pc (jcf, code_offset, ++pc);
3394 index = (other << 8) + index;
3395 }
3396 break;
3397 }
3398
3399 /* Now we decide: first >0 means we have a <t>store_<n>, index >0
3400 means we have a <t>store. */
3401 if ((first > 0 && opcode - first == slot) || (index > 0 && index == slot))
3402 start_pc = insn_pc;
3403
3404 return start_pc;
3405 }
3406
3407 /* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
3408 order, as specified by Java Language Specification.
3409
3410 The problem is that while expand_expr will evaluate its sub-operands in
3411 left-to-right order, for variables it will just return an rtx (i.e.
3412 an lvalue) for the variable (rather than an rvalue). So it is possible
3413 that a later sub-operand will change the register, and when the
3414 actual operation is done, it will use the new value, when it should
3415 have used the original value.
3416
3417 We fix this by using save_expr. This forces the sub-operand to be
3418 copied into a fresh virtual register,
3419
3420 For method invocation, we modify the arguments so that a
3421 left-to-right order evaluation is performed. Saved expressions
3422 will, in CALL_EXPR order, be reused when the call will be expanded.
3423 */
3424
3425 tree
force_evaluation_order(node)3426 force_evaluation_order (node)
3427 tree node;
3428 {
3429 if (flag_syntax_only)
3430 return node;
3431 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
3432 {
3433 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
3434 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
3435 }
3436 else if (TREE_CODE (node) == CALL_EXPR
3437 || TREE_CODE (node) == NEW_CLASS_EXPR
3438 || (TREE_CODE (node) == COMPOUND_EXPR
3439 && TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
3440 && TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
3441 {
3442 tree arg, cmp;
3443
3444 if (!TREE_OPERAND (node, 1))
3445 return node;
3446
3447 arg = node;
3448
3449 /* Position arg properly, account for wrapped around ctors. */
3450 if (TREE_CODE (node) == COMPOUND_EXPR)
3451 arg = TREE_OPERAND (node, 0);
3452
3453 arg = TREE_OPERAND (arg, 1);
3454
3455 /* Not having a list of argument here is an error. */
3456 if (TREE_CODE (arg) != TREE_LIST)
3457 abort ();
3458
3459 /* This reverses the evaluation order. This is a desired effect. */
3460 for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
3461 {
3462 tree saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
3463 cmp = (cmp == NULL_TREE ? saved :
3464 build (COMPOUND_EXPR, void_type_node, cmp, saved));
3465 TREE_VALUE (arg) = saved;
3466 }
3467
3468 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
3469 TREE_SIDE_EFFECTS (cmp) = 1;
3470
3471 if (cmp)
3472 {
3473 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
3474 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
3475 TREE_SIDE_EFFECTS (cmp) = 1;
3476 node = cmp;
3477 }
3478 }
3479 return node;
3480 }
3481
3482 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
3483 method in order to emit initialization code for each test flag. */
3484
3485 static int
emit_init_test_initialization(entry,x)3486 emit_init_test_initialization (entry, x)
3487 void * * entry;
3488 void * x ATTRIBUTE_UNUSED;
3489 {
3490 struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
3491 tree klass = build_class_ref (ite->key);
3492 tree rhs;
3493
3494 /* If the DECL_INITIAL of the test flag is set to true, it
3495 means that the class is already initialized the time it
3496 is in use. */
3497 if (DECL_INITIAL (ite->value) == boolean_true_node)
3498 rhs = boolean_true_node;
3499 /* Otherwise, we initialize the class init check variable by looking
3500 at the `state' field of the class to see if it is already
3501 initialized. This makes things a bit faster if the class is
3502 already initialized, which should be the common case. */
3503 else
3504 rhs = build (GE_EXPR, boolean_type_node,
3505 build (COMPONENT_REF, byte_type_node,
3506 build1 (INDIRECT_REF, class_type_node, klass),
3507 lookup_field (&class_type_node,
3508 get_identifier ("state"))),
3509 build_int_2 (JV_STATE_DONE, 0));
3510
3511 expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node,
3512 ite->value, rhs));
3513 return true;
3514 }
3515
3516 #include "gt-java-expr.h"
3517
3518