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