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