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