]> gcc.gnu.org Git - gcc.git/blame - gcc/java/expr.c
Fix copyrights
[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)))))), \
582 size_int (BITS_PER_UNIT))
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{
789 tree type = build_java_array_type (decode_newarray_type (atype_value),
790 TREE_CODE (length) == INTEGER_CST
791 ? TREE_INT_CST_LOW (length)
792 : -1);
793 return build (CALL_EXPR, promote_type (type),
794 build_address_of (soft_newarray_node),
795 tree_cons (NULL_TREE,
796 build_int_2 (atype_value, 0),
797 build_tree_list (NULL_TREE, length)),
798 NULL_TREE);
799}
800
801/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
802 of the dimension. */
fdec99c6 803
e04a16fb
AG
804tree
805build_anewarray (class_type, length)
806 tree class_type;
807 tree length;
808{
e4de5a10 809 tree type = build_java_array_type (class_type,
e04a16fb
AG
810 TREE_CODE (length) == INTEGER_CST
811 ? TREE_INT_CST_LOW (length)
812 : -1);
813 return build (CALL_EXPR, promote_type (type),
814 build_address_of (soft_anewarray_node),
815 tree_cons (NULL_TREE, length,
816 tree_cons (NULL_TREE, build_class_ref (class_type),
817 build_tree_list (NULL_TREE,
818 null_pointer_node))),
819 NULL_TREE);
820}
821
fdec99c6
PB
822/* Return a node the evaluates 'new TYPE[LENGTH]'. */
823
824tree
825build_new_array (type, length)
826 tree type;
827 tree length;
828{
829 if (JPRIMITIVE_TYPE_P (type))
830 return build_newarray (encode_newarray_type (type), length);
831 else
832 return build_anewarray (TREE_TYPE (type), length);
833}
834
e4de5a10
PB
835/* Generates a call to _Jv_NewMultiArray. multianewarray expects a
836 class pointer, a number of dimensions and the matching number of
837 dimensions. The argument list is NULL terminated. */
e04a16fb 838
4bcde32e 839static void
e04a16fb
AG
840expand_java_multianewarray (class_type, ndim)
841 tree class_type;
842 int ndim;
843{
844 int i;
845 tree args = build_tree_list( NULL_TREE, null_pointer_node );
846
847 for( i = 0; i < ndim; i++ )
848 args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
849
850 push_value (build (CALL_EXPR,
851 promote_type (class_type),
852 build_address_of (soft_multianewarray_node),
853 tree_cons (NULL_TREE, build_class_ref (class_type),
854 tree_cons (NULL_TREE,
855 build_int_2 (ndim, 0), args )),
856 NULL_TREE));
857}
858
859/* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
860 ARRAY is an array type. May expand some bound checking and NULL
861 pointer checking. RHS_TYPE_NODE we are going to store. In the case
862 of the CHAR/BYTE/BOOLEAN SHORT, the type popped of the stack is an
863 INT. In those cases, we make the convertion.
864
865 if ARRAy is a reference type, the assignment is checked at run-time
866 to make sure that the RHS can be assigned to the array element
867 type. It is not necessary to generate this code if ARRAY is final. */
868
4bcde32e 869static void
e04a16fb
AG
870expand_java_arraystore (rhs_type_node)
871 tree rhs_type_node;
872{
873 tree rhs_node = pop_value ((INTEGRAL_TYPE_P (rhs_type_node)
874 && TYPE_PRECISION (rhs_type_node) <= 32) ?
875 int_type_node : rhs_type_node);
876 tree index = pop_value (int_type_node);
877 tree array = pop_value (ptr_type_node);
878
879 rhs_type_node = build_java_check_indexed_type (array, rhs_type_node);
880
881 flush_quick_stack ();
882
883 index = save_expr (index);
884 array = save_expr (array);
885
afc390b1 886 if (TREE_CODE (rhs_type_node) == POINTER_TYPE)
e04a16fb
AG
887 {
888 tree check = build (CALL_EXPR, void_type_node,
889 build_address_of (soft_checkarraystore_node),
890 tree_cons (NULL_TREE, array,
891 build_tree_list (NULL_TREE, rhs_node)),
892 NULL_TREE);
893 TREE_SIDE_EFFECTS (check) = 1;
894 expand_expr_stmt (check);
895 }
896
897 expand_assignment (build_java_arrayaccess (array,
898 rhs_type_node,
899 index),
900 rhs_node, 0, 0);
901}
902
903/* Expand the evaluation of ARRAY[INDEX]. build_java_check_indexed_type makes
904 sure that LHS is an array type. May expand some bound checking and NULL
905 pointer checking.
906 LHS_TYPE_NODE is the type of ARRAY[INDEX]. But in the case of CHAR/BYTE/
907 BOOLEAN/SHORT, we push a promoted type back to the stack.
908*/
909
4bcde32e 910static void
e04a16fb
AG
911expand_java_arrayload (lhs_type_node )
912 tree lhs_type_node;
913{
914 tree load_node;
e04a16fb
AG
915 tree index_node = pop_value (int_type_node);
916 tree array_node = pop_value (ptr_type_node);
917
918 index_node = save_expr (index_node);
919 array_node = save_expr (array_node);
920 lhs_type_node = build_java_check_indexed_type (array_node, lhs_type_node);
921
922 load_node = build_java_arrayaccess (array_node,
923 lhs_type_node,
924 index_node);
925
926 if (INTEGRAL_TYPE_P (lhs_type_node) && TYPE_PRECISION (lhs_type_node) <= 32)
927 load_node = fold (build1 (NOP_EXPR, int_type_node, load_node));
928 push_value (load_node);
929}
930
931/* Expands .length. Makes sure that we deal with and array and may expand
932 a NULL check on the array object. */
933
4bcde32e 934static void
e04a16fb
AG
935expand_java_array_length ()
936{
937 tree array = pop_value (ptr_type_node);
938 tree length = build_java_array_length_access (array);
939
940 push_value (build_java_arraynull_check (array, length, int_type_node));
941}
942
e4de5a10
PB
943/* Emit code for the call to _Jv_Monitor{Enter,Exit}. CALL can be
944 either soft_monitorenter_node or soft_monitorexit_node. */
e04a16fb 945
4bcde32e 946static tree
e04a16fb
AG
947build_java_monitor (call, object)
948 tree call;
949 tree object;
950{
951 return (build (CALL_EXPR,
952 void_type_node,
953 build_address_of (call),
954 build_tree_list (NULL_TREE, object),
955 NULL_TREE));
956}
957
958/* Emit code for one of the PUSHC instructions. */
959
4bcde32e 960static void
e04a16fb
AG
961expand_java_pushc (ival, type)
962 int ival;
963 tree type;
964{
965 tree value;
966 if (type == ptr_type_node && ival == 0)
967 value = null_pointer_node;
968 else if (type == int_type_node || type == long_type_node)
969 {
970 value = build_int_2 (ival, ival < 0 ? -1 : 0);
971 TREE_TYPE (value) = type;
972 }
973 else if (type == float_type_node || type == double_type_node)
974 {
975 REAL_VALUE_TYPE x;
976#ifdef REAL_ARITHMETIC
977 REAL_VALUE_FROM_INT (x, ival, 0, TYPE_MODE (type));
978#else
979 x = ival;
980#endif
981 value = build_real (type, x);
982 }
983 else
984 fatal ("internal error in expand_java_pushc");
985 push_value (value);
986}
987
a0f4cca6
PN
988#ifndef INT_TYPE_SIZE
989#define INT_TYPE_SIZE BITS_PER_WORD
990#endif
991
4bcde32e 992static void
e04a16fb
AG
993expand_java_return (type)
994 tree type;
995{
996 if (type == void_type_node)
997 expand_null_return ();
998 else
999 {
1000 tree retval = pop_value (type);
1001 tree res = DECL_RESULT (current_function_decl);
1002 retval = build (MODIFY_EXPR, TREE_TYPE (res), res, retval);
a0f4cca6
PN
1003
1004 /* Handle the situation where the native integer type is smaller
1005 than the JVM integer. It can happen for many cross compilers.
1006 The whole if expression just goes away if INT_TYPE_SIZE < 32
1007 is false. */
1008 if (INT_TYPE_SIZE < 32
1009 && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (res)))
1010 < GET_MODE_SIZE (TYPE_MODE (type))))
1011 retval = build1(NOP_EXPR, TREE_TYPE(res), retval);
1012
e04a16fb
AG
1013 TREE_SIDE_EFFECTS (retval) = 1;
1014 expand_return (retval);
1015 }
1016}
1017
1018tree
1019build_address_of (value)
1020 tree value;
1021{
1022 return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
1023}
1024
4bcde32e 1025static void
e04a16fb
AG
1026expand_java_NEW (type)
1027 tree type;
1028{
1029 if (! CLASS_LOADED_P (type))
1030 load_class (type, 1);
ee07f4f4 1031 safe_layout_class (type);
e04a16fb
AG
1032 push_value (build (CALL_EXPR, promote_type (type),
1033 build_address_of (alloc_object_node),
1034 tree_cons (NULL_TREE, build_class_ref (type),
1035 build_tree_list (NULL_TREE,
1036 size_in_bytes (type))),
1037 NULL_TREE));
1038}
1039
4bcde32e 1040static void
e04a16fb
AG
1041expand_java_INSTANCEOF (type)
1042 tree type;
1043{
1044 tree value = pop_value (object_ptr_type_node);
1045 value = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (soft_instanceof_node)),
1046 build_address_of (soft_instanceof_node),
1047 tree_cons (NULL_TREE, value,
1048 build_tree_list (NULL_TREE,
1049 build_class_ref (type))),
1050 NULL_TREE);
1051 push_value (value);
1052}
1053
4bcde32e 1054static void
e04a16fb
AG
1055expand_java_CHECKCAST (type)
1056 tree type;
1057{
1058 tree value = pop_value (ptr_type_node);
1059 value = build (CALL_EXPR, promote_type (type),
1060 build_address_of (soft_checkcast_node),
1061 tree_cons (NULL_TREE, build_class_ref (type),
1062 build_tree_list (NULL_TREE, value)),
1063 NULL_TREE);
1064 push_value (value);
1065}
1066
4bcde32e
KG
1067static void
1068expand_iinc (local_var_index, ival, pc)
1069 unsigned int local_var_index;
1070 int ival;
1071 int pc;
e04a16fb
AG
1072{
1073 tree local_var, res;
1074 tree constant_value;
1075
1076 flush_quick_stack ();
1077 local_var = find_local_variable (local_var_index, int_type_node, pc);
1078 constant_value = build_int_2 (ival, ival < 0 ? -1 : 0);
1079 res = fold (build (PLUS_EXPR, int_type_node, local_var, constant_value));
1080 expand_assignment (local_var, res, 0, 0);
1081}
1082
aa4759c1
AH
1083
1084tree
1085build_java_soft_divmod (op, type, op1, op2)
1086 enum tree_code op;
1087 tree type, op1, op2;
1088{
1089 tree call = NULL;
1090 tree arg1 = convert (type, op1);
1091 tree arg2 = convert (type, op2);
1092
1093 if (type == int_type_node)
1094 {
1095 switch (op)
1096 {
1097 case TRUNC_DIV_EXPR:
1098 call = soft_idiv_node;
1099 break;
1100 case TRUNC_MOD_EXPR:
1101 call = soft_irem_node;
1102 break;
cd531a2e
KG
1103 default:
1104 break;
aa4759c1
AH
1105 }
1106 }
1107 else if (type == long_type_node)
1108 {
1109 switch (op)
1110 {
1111 case TRUNC_DIV_EXPR:
1112 call = soft_ldiv_node;
1113 break;
1114 case TRUNC_MOD_EXPR:
1115 call = soft_lrem_node;
1116 break;
cd531a2e
KG
1117 default:
1118 break;
aa4759c1
AH
1119 }
1120 }
1121
1122 if (! call)
1123 fatal ("Internal compiler error in build_java_soft_divmod");
1124
1125 call = build (CALL_EXPR, type,
1126 build_address_of (call),
1127 tree_cons (NULL_TREE, arg1,
1128 build_tree_list (NULL_TREE, arg2)),
1129 NULL_TREE);
1130
1131 return call;
1132}
1133
e04a16fb
AG
1134tree
1135build_java_binop (op, type, arg1, arg2)
1136 enum tree_code op;
1137 tree type, arg1, arg2;
1138{
1139 tree mask;
1140 switch (op)
1141 {
1142 case URSHIFT_EXPR:
1143 {
1144 tree u_type = unsigned_type (type);
1145 arg1 = convert (u_type, arg1);
1146 arg1 = build_java_binop (RSHIFT_EXPR, u_type, arg1, arg2);
1147 return convert (type, arg1);
1148 }
1149 case LSHIFT_EXPR:
1150 case RSHIFT_EXPR:
1151 mask = build_int_2 (TYPE_PRECISION (TREE_TYPE (arg1)) - 1, 0);
1152 arg2 = fold (build (BIT_AND_EXPR, int_type_node, arg2, mask));
1153 break;
1154
1155 case COMPARE_L_EXPR: /* arg1 > arg2 ? 1 : arg1 == arg2 ? 0 : -1 */
1156 case COMPARE_G_EXPR: /* arg1 < arg2 ? -1 : arg1 == arg2 ? 0 : 1 */
1157 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1158 {
1159 tree ifexp1 = fold ( build (op == COMPARE_L_EXPR ? GT_EXPR : LT_EXPR,
1160 boolean_type_node, arg1, arg2));
1161 tree ifexp2 = fold ( build (EQ_EXPR, boolean_type_node, arg1, arg2));
1162 tree second_compare = fold (build (COND_EXPR, int_type_node,
1163 ifexp2, integer_zero_node,
1164 op == COMPARE_L_EXPR
1165 ? integer_negative_one_node
1166 : integer_one_node));
1167 return fold (build (COND_EXPR, int_type_node, ifexp1,
1168 op == COMPARE_L_EXPR ? integer_one_node
1169 : integer_negative_one_node,
1170 second_compare));
1171 }
1172 case COMPARE_EXPR:
1173 arg1 = save_expr (arg1); arg2 = save_expr (arg2);
1174 {
1175 tree ifexp1 = fold ( build (LT_EXPR, boolean_type_node, arg1, arg2));
1176 tree ifexp2 = fold ( build (GT_EXPR, boolean_type_node, arg1, arg2));
1177 tree second_compare = fold ( build (COND_EXPR, int_type_node,
1178 ifexp2, integer_one_node,
1179 integer_zero_node));
1180 return fold (build (COND_EXPR, int_type_node,
1181 ifexp1, integer_negative_one_node, second_compare));
aa4759c1
AH
1182 }
1183 case TRUNC_DIV_EXPR:
e04a16fb 1184 case TRUNC_MOD_EXPR:
aa4759c1
AH
1185 if (TREE_CODE (type) == REAL_TYPE
1186 && op == TRUNC_MOD_EXPR)
e04a16fb
AG
1187 {
1188 tree call;
1189 if (type != double_type_node)
1190 {
1191 arg1 = convert (double_type_node, arg1);
1192 arg2 = convert (double_type_node, arg2);
1193 }
1194 call = build (CALL_EXPR, double_type_node,
1195 build_address_of (soft_fmod_node),
1196 tree_cons (NULL_TREE, arg1,
1197 build_tree_list (NULL_TREE, arg2)),
1198 NULL_TREE);
1199 if (type != double_type_node)
1200 call = convert (type, call);
1201 return call;
1202 }
aa4759c1
AH
1203
1204 if (TREE_CODE (type) == INTEGER_TYPE
1205 && flag_use_divide_subroutine
1206 && ! flag_syntax_only)
1207 return build_java_soft_divmod (op, type, arg1, arg2);
1208
e04a16fb 1209 break;
0bd2e6db 1210 default: ;
e04a16fb
AG
1211 }
1212 return fold (build (op, type, arg1, arg2));
1213}
1214
4bcde32e 1215static void
e04a16fb
AG
1216expand_java_binop (type, op)
1217 tree type; enum tree_code op;
1218{
1219 tree larg, rarg;
1220 tree ltype = type;
1221 tree rtype = type;
1222 switch (op)
1223 {
1224 case LSHIFT_EXPR:
1225 case RSHIFT_EXPR:
1226 case URSHIFT_EXPR:
1227 rtype = int_type_node;
1228 rarg = pop_value (rtype);
1229 break;
1230 default:
1231 rarg = pop_value (rtype);
1232 }
1233 larg = pop_value (ltype);
1234 push_value (build_java_binop (op, type, larg, rarg));
1235}
1236
1237/* Lookup the field named NAME in *TYPEP or its super classes.
1238 If not found, return NULL_TREE.
1239 (If the *TYPEP is not found, return error_mark_node.)
1240 If found, return the FIELD_DECL, and set *TYPEP to the
1241 class containing the field. */
1242
1243tree
1244lookup_field (typep, name)
1245 tree *typep;
1246 tree name;
1247{
1248 if (CLASS_P (*typep) && !CLASS_LOADED_P (*typep))
1249 {
1250 load_class (*typep, 1);
ee07f4f4 1251 safe_layout_class (*typep);
93024893 1252 if (!TYPE_SIZE (*typep) || TREE_CODE (TYPE_SIZE (*typep)) == ERROR_MARK)
e04a16fb
AG
1253 return error_mark_node;
1254 }
1255 do
1256 {
7f1d4866
APB
1257 tree field, basetype_vec;
1258 int n, i;
1259
1260 for (field = TYPE_FIELDS (*typep); field; field = TREE_CHAIN (field))
1261 if (DECL_NAME (field) == name)
1262 return field;
1263
1264 /* Process implemented interfaces. */
1265 basetype_vec = TYPE_BINFO_BASETYPES (*typep);
1266 n = TREE_VEC_LENGTH (basetype_vec);
1267 for (i = 0; i < n; i++)
e04a16fb 1268 {
7f1d4866
APB
1269 tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
1270 if ((field = lookup_field (&t, name)))
e04a16fb
AG
1271 return field;
1272 }
1273 *typep = CLASSTYPE_SUPER (*typep);
1274 } while (*typep);
1275 return NULL_TREE;
1276}
1277
1278/* Look up the field named NAME in object SELF_VALUE,
1279 which has class SELF_CLASS (a non-handle RECORD_TYPE).
1280 SELF_VALUE is NULL_TREE if looking for a static field. */
1281
1282tree
1283build_field_ref (self_value, self_class, name)
1284 tree self_value, self_class, name;
1285{
1286 tree base_class = self_class;
1287 tree field_decl = lookup_field (&base_class, name);
1288 if (field_decl == NULL_TREE)
1289 {
1290 error ("field `%s' not found", IDENTIFIER_POINTER (name));
1291 return error_mark_node;
1292 }
1293 if (self_value == NULL_TREE)
1294 {
1295 return build_static_field_ref (field_decl);
1296 }
1297 else
1298 {
1299 tree base_handle_type = promote_type (base_class);
1300 if (base_handle_type != TREE_TYPE (self_value))
1301 self_value = fold (build1 (NOP_EXPR, base_handle_type, self_value));
1302#ifdef JAVA_USE_HANDLES
1303 self_value = unhand_expr (self_value);
1304#endif
1305 self_value = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (self_value)),
1306 self_value);
1307 return fold (build (COMPONENT_REF, TREE_TYPE (field_decl),
1308 self_value, field_decl));
1309 }
1310}
1311
1312tree
1313lookup_label (pc)
1314 int pc;
1315{
1316 tree name;
d2e0d40a
AG
1317 char buf[32];
1318 ASM_GENERATE_INTERNAL_LABEL(buf, "LJpc=", pc);
e04a16fb
AG
1319 name = get_identifier (buf);
1320 if (IDENTIFIER_LOCAL_VALUE (name))
1321 return IDENTIFIER_LOCAL_VALUE (name);
1322 else
1323 {
1324 /* The type of the address of a label is return_address_type_node. */
1325 tree decl = create_label_decl (name);
1326 LABEL_PC (decl) = pc;
1327 label_rtx (decl);
1328 return pushdecl (decl);
1329 }
1330}
1331
e4de5a10
PB
1332/* Generate a unique name for the purpose of loops and switches
1333 labels, and try-catch-finally blocks label or temporary variables. */
1334
1335tree
1336generate_name ()
1337{
1338 static int l_number = 0;
d2e0d40a
AG
1339 char buff [32];
1340 ASM_GENERATE_INTERNAL_LABEL(buff, "LJv", l_number);
1341 l_number++;
e4de5a10
PB
1342 return get_identifier (buff);
1343}
1344
e04a16fb
AG
1345tree
1346create_label_decl (name)
1347 tree name;
1348{
1349 tree decl;
1350 push_obstacks (&permanent_obstack, &permanent_obstack);
1351 decl = build_decl (LABEL_DECL, name,
1352 TREE_TYPE (return_address_type_node));
1353 pop_obstacks ();
1354 DECL_CONTEXT (decl) = current_function_decl;
1355 DECL_IGNORED_P (decl) = 1;
1356 return decl;
1357}
1358
1359/* This maps a bytecode offset (PC) to various flags. */
1360char *instruction_bits;
1361
4bcde32e 1362static void
e04a16fb 1363note_label (current_pc, target_pc)
4bcde32e 1364 int current_pc ATTRIBUTE_UNUSED, target_pc;
e04a16fb
AG
1365{
1366 lookup_label (target_pc);
1367 instruction_bits [target_pc] |= BCODE_JUMP_TARGET;
1368}
1369
1370/* Emit code to jump to TARGET_PC if VALUE1 CONDITION VALUE2,
1371 where CONDITION is one of one the compare operators. */
1372
4bcde32e 1373static void
e04a16fb
AG
1374expand_compare (condition, value1, value2, target_pc)
1375 enum tree_code condition;
1376 tree value1, value2;
1377 int target_pc;
1378{
1379 tree target = lookup_label (target_pc);
1380 tree cond = fold (build (condition, boolean_type_node, value1, value2));
1381 expand_start_cond (truthvalue_conversion (cond), 0);
1382 expand_goto (target);
1383 expand_end_cond ();
1384}
1385
1386/* Emit code for a TEST-type opcode. */
1387
4bcde32e 1388static void
e04a16fb
AG
1389expand_test (condition, type, target_pc)
1390 enum tree_code condition;
1391 tree type;
1392 int target_pc;
1393{
1394 tree value1, value2;
1395 flush_quick_stack ();
1396 value1 = pop_value (type);
1397 value2 = (type == ptr_type_node) ? null_pointer_node : integer_zero_node;
1398 expand_compare (condition, value1, value2, target_pc);
1399}
1400
1401/* Emit code for a COND-type opcode. */
1402
4bcde32e 1403static void
e04a16fb
AG
1404expand_cond (condition, type, target_pc)
1405 enum tree_code condition;
1406 tree type;
1407 int target_pc;
1408{
1409 tree value1, value2;
1410 flush_quick_stack ();
1411 /* note: pop values in opposite order */
1412 value2 = pop_value (type);
1413 value1 = pop_value (type);
1414 /* Maybe should check value1 and value2 for type compatibility ??? */
1415 expand_compare (condition, value1, value2, target_pc);
1416}
1417
4bcde32e 1418static void
e04a16fb
AG
1419expand_java_goto (target_pc)
1420 int target_pc;
1421{
1422 tree target_label = lookup_label (target_pc);
1423 flush_quick_stack ();
1424 expand_goto (target_label);
1425}
1426
4bcde32e
KG
1427#if 0
1428static void
e04a16fb
AG
1429expand_java_call (target_pc, return_address)
1430 int target_pc, return_address;
1431{
1432 tree target_label = lookup_label (target_pc);
1433 tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);
1434 push_value (value);
1435 flush_quick_stack ();
1436 expand_goto (target_label);
1437}
1438
4bcde32e 1439static void
e04a16fb 1440expand_java_ret (return_address)
4bcde32e 1441 tree return_address ATTRIBUTE_UNUSED;
e04a16fb
AG
1442{
1443 warning ("ret instruction not implemented");
1444#if 0
1445 tree target_label = lookup_label (target_pc);
1446 flush_quick_stack ();
1447 expand_goto (target_label);
1448#endif
1449}
4bcde32e 1450#endif
e04a16fb
AG
1451
1452/* Recursive helper function to pop argument types during verifiation. */
1453
1454void
1455pop_argument_types (arg_types)
1456 tree arg_types;
1457{
0bd2e6db 1458 if (arg_types == end_params_node)
e04a16fb
AG
1459 return;
1460 if (TREE_CODE (arg_types) == TREE_LIST)
1461 {
1462 pop_argument_types (TREE_CHAIN (arg_types));
1463 pop_type (TREE_VALUE (arg_types));
1464 return;
1465 }
1466 abort ();
1467}
1468
4bcde32e 1469static tree
e04a16fb
AG
1470pop_arguments (arg_types)
1471 tree arg_types;
1472{
0bd2e6db 1473 if (arg_types == end_params_node)
e04a16fb
AG
1474 return NULL_TREE;
1475 if (TREE_CODE (arg_types) == TREE_LIST)
1476 {
1477 tree tail = pop_arguments (TREE_CHAIN (arg_types));
e4de5a10
PB
1478 tree type = TREE_VALUE (arg_types);
1479 tree arg = pop_value (type);
e438e1b7
JJ
1480 if (PROMOTE_PROTOTYPES
1481 && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
e4de5a10
PB
1482 && INTEGRAL_TYPE_P (type))
1483 arg = convert (integer_type_node, arg);
e4de5a10 1484 return tree_cons (NULL_TREE, arg, tail);
e04a16fb
AG
1485 }
1486 abort ();
1487}
1488
1489/* Build an expression to initialize the class CLAS.
1490 if EXPR is non-NULL, returns an expression to first call the initializer
1491 (if it is needed) and then calls EXPR. */
1492
1493tree
1494build_class_init (clas, expr)
1495 tree clas, expr;
1496{
3ff9925c
AG
1497 tree init, call;
1498 struct init_test_hash_entry *ite;
e04a16fb
AG
1499 if (inherits_from_p (current_class, clas))
1500 return expr;
3ff9925c
AG
1501
1502 if (always_initialize_class_p)
1503 {
1504 init = build (CALL_EXPR, void_type_node,
1505 build_address_of (soft_initclass_node),
1506 build_tree_list (NULL_TREE, build_class_ref (clas)),
1507 NULL_TREE);
1508 TREE_SIDE_EFFECTS (init) = 1;
1509 }
1510 else
1511 {
1512 ite = (struct init_test_hash_entry *)
1513 hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
1514 (const hash_table_key) clas,
1515 TRUE, NULL);
1516
1517 if (ite->init_test_decl == 0)
1518 ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
1519 boolean_type_node);
1520 /* Tell the check-init code to ignore this decl. */
1521 DECL_BIT_INDEX(ite->init_test_decl) = -1;
1522
1523 init = build (CALL_EXPR, void_type_node,
1524 build_address_of (soft_initclass_node),
1525 build_tree_list (NULL_TREE, build_class_ref (clas)),
1526 NULL_TREE);
1527 TREE_SIDE_EFFECTS (init) = 1;
1528 call = build (COMPOUND_EXPR, TREE_TYPE (expr), init,
1529 build (MODIFY_EXPR, boolean_type_node,
1530 ite->init_test_decl, boolean_true_node));
1531 TREE_SIDE_EFFECTS (call) = 1;
1532 init = build (COND_EXPR, void_type_node,
1533 build (EQ_EXPR, boolean_type_node,
1534 ite->init_test_decl, boolean_false_node),
1535 call, integer_zero_node);
1536 TREE_SIDE_EFFECTS (init) = 1;
1537 }
1538
e04a16fb
AG
1539 if (expr != NULL_TREE)
1540 {
1541 expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
1542 TREE_SIDE_EFFECTS (expr) = 1;
1543 return expr;
1544 }
1545 return init;
1546}
1547
1548static tree methods_ident = NULL_TREE;
1549static tree ncode_ident = NULL_TREE;
1550tree dtable_ident = NULL_TREE;
1551
1552tree
1553build_known_method_ref (method, method_type, self_type, method_signature, arg_list)
ab3a6dd6
KG
1554 tree method, method_type ATTRIBUTE_UNUSED, self_type,
1555 method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;
e04a16fb
AG
1556{
1557 tree func;
15fdcfe9 1558 if (is_compiled_class (self_type))
e04a16fb
AG
1559 {
1560 make_decl_rtl (method, NULL, 1);
1561 func = build1 (ADDR_EXPR, method_ptr_type_node, method);
1562 }
1563 else
1564 {
1565 /* We don't know whether the method has been (statically) compiled.
1566 Compile this code to get a reference to the method's code:
1567
1568 SELF_TYPE->methods[METHOD_INDEX].ncode
1569
1570 This is guaranteed to work (assuming SELF_TYPE has
1571 been initialized), since if the method is not compiled yet,
1572 its ncode points to a trampoline that forces compilation. */
1573
1574 int method_index = 0;
1575 tree meth;
1576 tree ref = build_class_ref (self_type);
1577 ref = build1 (INDIRECT_REF, class_type_node, ref);
1578 if (ncode_ident == NULL_TREE)
1579 ncode_ident = get_identifier ("ncode");
1580 if (methods_ident == NULL_TREE)
1581 methods_ident = get_identifier ("methods");
1582 ref = build (COMPONENT_REF, method_ptr_type_node, ref,
1583 lookup_field (&class_type_node, methods_ident));
1584 for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));
1585 ; meth = TREE_CHAIN (meth))
1586 {
1587 if (method == meth)
1588 break;
1589 if (meth == NULL_TREE)
1590 fatal ("method '%s' not found in class",
1591 IDENTIFIER_POINTER (DECL_NAME (method)));
1592 method_index++;
1593 }
1594 method_index *= int_size_in_bytes (method_type_node);
1595 ref = fold (build (PLUS_EXPR, method_ptr_type_node,
1596 ref, build_int_2 (method_index, 0)));
1597 ref = build1 (INDIRECT_REF, method_type_node, ref);
1598 func = build (COMPONENT_REF, nativecode_ptr_type_node,
1599 ref,
1600 lookup_field (&method_type_node, ncode_ident));
1601 }
1602 return func;
1603}
1604
1605tree
1606invoke_build_dtable (is_invoke_interface, arg_list)
1607 int is_invoke_interface;
1608 tree arg_list;
1609{
1610 tree dtable, objectref;
1611
1612 TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));
1613
1614 /* If we're dealing with interfaces and if the objectref
1615 argument is an array then get the dispatch table of the class
1616 Object rather than the one from the objectref. */
1617 objectref = (is_invoke_interface
1618 && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?
1619 object_type_node : TREE_VALUE (arg_list));
1620
1621 if (dtable_ident == NULL_TREE)
78857b4e 1622 dtable_ident = get_identifier ("vtable");
e04a16fb
AG
1623 dtable = build1 (INDIRECT_REF, object_type_node, objectref );
1624 dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,
1625 lookup_field (&object_type_node, dtable_ident));
1626
1627 return dtable;
1628}
1629
1630tree
1631build_invokevirtual (dtable, method)
1632 tree dtable, method;
1633{
1634 tree func;
1635 tree nativecode_ptr_ptr_type_node
1636 = build_pointer_type (nativecode_ptr_type_node);
1637 int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));
1638 /* Add one to skip "class" field of dtable, and one to skip unused
1639 vtable entry (for C++ compatibility). */
1640 method_index += 2;
1641 method_index
1642 *= int_size_in_bytes (nativecode_ptr_ptr_type_node);
1643 func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,
1644 dtable, build_int_2 (method_index, 0)));
1645 func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);
1646
1647 return func;
1648}
1649
5e942c50
APB
1650tree
1651build_invokeinterface (dtable, method_name, method_signature)
1652 tree dtable, method_name, method_signature;
1653{
1654 static tree class_ident = NULL_TREE;
1655 tree lookup_arg;
1656
1657 /* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
1658 ensure that the selected method exists, is public and not
1659 abstract nor static. */
1660
1661 if (class_ident == NULL_TREE)
1662 class_ident = get_identifier ("class");
1663
1664 dtable = build1 (INDIRECT_REF, dtable_type, dtable);
1665 dtable = build (COMPONENT_REF, class_ptr_type, dtable,
1666 lookup_field (&dtable_type, class_ident));
7e57923c
AH
1667 lookup_arg = build_tree_list (NULL_TREE,
1668 (build_utf8_ref
1669 (unmangle_classname
1670 (IDENTIFIER_POINTER(method_signature),
1671 IDENTIFIER_LENGTH(method_signature)))));
5e942c50
APB
1672 lookup_arg = tree_cons (NULL_TREE, dtable,
1673 tree_cons (NULL_TREE, build_utf8_ref (method_name),
1674 lookup_arg));
1675 return build (CALL_EXPR, ptr_type_node,
1676 build_address_of (soft_lookupinterfacemethod_node),
1677 lookup_arg, NULL_TREE);
1678}
1679
e04a16fb
AG
1680/* Expand one of the invoke_* opcodes.
1681 OCPODE is the specific opcode.
1682 METHOD_REF_INDEX is an index into the constant pool.
1683 NARGS is the number of arguments, or -1 if not specified. */
1684
4bcde32e 1685static void
e04a16fb
AG
1686expand_invoke (opcode, method_ref_index, nargs)
1687 int opcode;
1688 int method_ref_index;
b4b63e32 1689 int nargs ATTRIBUTE_UNUSED;
e04a16fb
AG
1690{
1691 tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);
1692 tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);
1693 tree self_type = get_class_constant
1694 (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));
49f48c71 1695 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
e04a16fb
AG
1696 tree call, func, method, arg_list, method_type;
1697
e04a16fb
AG
1698 if (! CLASS_LOADED_P (self_type))
1699 {
1700 load_class (self_type, 1);
6bafd8b6 1701 safe_layout_class (self_type);
e04a16fb
AG
1702 if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)
1703 fatal ("failed to find class '%s'", self_name);
1704 }
23a79c61 1705 layout_class_methods (self_type);
e04a16fb
AG
1706
1707 if (method_name == init_identifier_node)
1708 method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),
1709 method_signature);
1710 else
1711 method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),
1712 method_name, method_signature);
1713 if (method == NULL_TREE)
1714 {
1715 error ("Class '%s' has no method named '%s' matching signature '%s'",
1716 self_name,
1717 IDENTIFIER_POINTER (method_name),
1718 IDENTIFIER_POINTER (method_signature));
1719 }
1720 /* Invoke static can't invoke static/abstract method */
1721 else if (opcode == OPCODE_invokestatic)
1722 {
1723 if (!METHOD_STATIC (method))
1724 {
1725 error ("invokestatic on non static method");
1726 method = NULL_TREE;
1727 }
1728 else if (METHOD_ABSTRACT (method))
1729 {
1730 error ("invokestatic on abstract method");
1731 method = NULL_TREE;
1732 }
1733 }
1734 else
1735 {
1736 if (METHOD_STATIC (method))
1737 {
1738 error ("invoke[non-static] on static method");
1739 method = NULL_TREE;
1740 }
1741 }
1742
1743 if (method == NULL_TREE)
1744 {
1745 method_type = get_type_from_signature (method_signature);
1746 pop_arguments (TYPE_ARG_TYPES (method_type));
1747 if (opcode != OPCODE_invokestatic)
1748 pop_type (self_type);
1749 method_type = promote_type (TREE_TYPE (method_type));
1750 push_value (convert (method_type, integer_zero_node));
1751 return;
1752 }
1753
1754 method_type = TREE_TYPE (method);
1755 arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
1756 flush_quick_stack ();
1757
e04a16fb
AG
1758 func = NULL_TREE;
1759 if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial
1760 || (opcode == OPCODE_invokevirtual
0bd2e6db 1761 && (METHOD_PRIVATE (method)
7f1d4866
APB
1762 || METHOD_FINAL (method)
1763 || CLASS_FINAL (TYPE_NAME (self_type)))))
e04a16fb
AG
1764 func = build_known_method_ref (method, method_type, self_type,
1765 method_signature, arg_list);
1766 else
1767 {
1768 tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface,
1769 arg_list);
1770 if (opcode == OPCODE_invokevirtual)
1771 func = build_invokevirtual (dtable, method);
1772 else
5e942c50 1773 func = build_invokeinterface (dtable, method_name, method_signature);
e04a16fb
AG
1774 }
1775 func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
1776 call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
1777 TREE_SIDE_EFFECTS (call) = 1;
1778
e04a16fb
AG
1779 if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)
1780 expand_expr_stmt (call);
1781 else
1782 {
1783 push_value (call);
1784 flush_quick_stack ();
1785 }
1786}
1787
1788
1789/* Expand an operation to extract from or store into a field.
1790 IS_STATIC is 1 iff the field is static.
1791 IS_PUTTING is 1 for putting into a field; 0 for getting from the field.
1792 FIELD_REF_INDEX is an index into the constant pool. */
1793
4bcde32e 1794static void
e04a16fb
AG
1795expand_java_field_op (is_static, is_putting, field_ref_index)
1796 int is_static;
1797 int is_putting;
1798 int field_ref_index;
1799{
7f1d4866
APB
1800 tree self_type =
1801 get_class_constant (current_jcf,
1802 COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool,
1803 field_ref_index));
49f48c71 1804 const char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
e04a16fb 1805 tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);
7f1d4866
APB
1806 tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool,
1807 field_ref_index);
e04a16fb
AG
1808 tree field_type = get_type_from_signature (field_signature);
1809 tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;
1810 tree field_ref;
1811 int is_error = 0;
1812 tree field_decl = lookup_field (&self_type, field_name);
1813 if (field_decl == error_mark_node)
1814 {
1815 is_error = 1;
1816 }
1817 else if (field_decl == NULL_TREE)
1818 {
1819 error ("Missing field '%s' in '%s'",
1820 IDENTIFIER_POINTER (field_name), self_name);
1821 is_error = 1;
1822 }
1823 else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)
1824 {
1825 error ("Mismatching signature for field '%s' in '%s'",
1826 IDENTIFIER_POINTER (field_name), self_name);
1827 is_error = 1;
1828 }
1829 field_ref = is_static ? NULL_TREE : pop_value (self_type);
1830 if (is_error)
1831 {
1832 if (! is_putting)
e4de5a10 1833 push_value (convert (field_type, integer_zero_node));
e04a16fb
AG
1834 flush_quick_stack ();
1835 return;
1836 }
1837
1838 /* Inline references to java.lang.PRIMTYPE.TYPE.
1839 In addition to being a useful (minor) optimization,
1840 this is also needed to avoid circularities in the implementation
1841 of these fields in libjava. */
1842 if (field_name == TYPE_identifier_node && ! is_putting
63a212ed 1843 && ! flag_emit_class_files && field_type == class_ptr_type
e04a16fb
AG
1844 && strncmp (self_name, "java.lang.", 10) == 0)
1845 {
5e942c50
APB
1846 tree typ = build_primtype_type_ref (self_name);
1847 if (typ)
e04a16fb 1848 {
5e942c50 1849 push_value (typ);
e04a16fb
AG
1850 return;
1851 }
1852 }
1853
1854 field_ref = build_field_ref (field_ref, self_type, field_name);
1855 if (is_static)
1856 field_ref = build_class_init (self_type, field_ref);
1857 if (is_putting)
1858 {
1859 flush_quick_stack ();
1860 if (FIELD_FINAL (field_decl))
1861 {
1862 if (DECL_CONTEXT (field_decl) != current_class)
1863 error_with_decl (field_decl,
1864 "assignment to final field `%s' not in field's class");
1865 else if (FIELD_STATIC (field_decl))
1866 {
7f1d4866 1867 if (!IS_CLINIT (current_function_decl))
e04a16fb
AG
1868 error_with_decl (field_decl,
1869 "assignment to final static field `%s' not in class initializer");
1870 }
1871 else
1872 {
6bafd8b6
APB
1873 tree cfndecl_name = DECL_NAME (current_function_decl);
1874 if (! DECL_CONSTRUCTOR_P (current_function_decl)
1875 && (cfndecl_name != finit_identifier_node))
c63b98cd 1876 error_with_decl (field_decl, "assignment to final field `%s' not in constructor");
e04a16fb
AG
1877 }
1878 }
1879 expand_assignment (field_ref, new_value, 0, 0);
1880 }
1881 else
1882 push_value (field_ref);
1883}
1884
5e942c50
APB
1885tree
1886build_primtype_type_ref (self_name)
49f48c71 1887 const char *self_name;
5e942c50 1888{
49f48c71 1889 const char *class_name = self_name+10;
5e942c50
APB
1890 tree typ;
1891 if (strncmp(class_name, "Byte", 4) == 0)
1892 typ = byte_type_node;
1893 else if (strncmp(class_name, "Short", 5) == 0)
1894 typ = short_type_node;
1895 else if (strncmp(class_name, "Integer", 7) == 0)
1896 typ = int_type_node;
1897 else if (strncmp(class_name, "Long", 4) == 0)
1898 typ = long_type_node;
1899 else if (strncmp(class_name, "Float", 5) == 0)
1900 typ = float_type_node;
c877974e
APB
1901 else if (strncmp(class_name, "Double", 6) == 0)
1902 typ = double_type_node;
5e942c50
APB
1903 else if (strncmp(class_name, "Boolean", 7) == 0)
1904 typ = boolean_type_node;
1905 else if (strncmp(class_name, "Char", 4) == 0)
1906 typ = char_type_node;
1907 else if (strncmp(class_name, "Void", 4) == 0)
1908 typ = void_type_node;
1909 else
1910 typ = NULL_TREE;
1911 if (typ != NULL_TREE)
1912 return build_class_ref (typ);
1913 else
1914 return NULL_TREE;
1915}
1916
e04a16fb
AG
1917void
1918load_type_state (label)
1919 tree label;
1920{
1921 int i;
1922 tree vec = LABEL_TYPE_STATE (label);
1923 int cur_length = TREE_VEC_LENGTH (vec);
1924 stack_pointer = cur_length - DECL_MAX_LOCALS(current_function_decl);
1925 for (i = 0; i < cur_length; i++)
1926 type_map [i] = TREE_VEC_ELT (vec, i);
1927}
1928
15fdcfe9
PB
1929/* Do the expansion of a Java switch. With Gcc, switches are front-end
1930 dependant things, but they rely on gcc routines. This function is
1931 placed here because it uses things defined locally in parse.y. */
1932
1933static tree
1934case_identity (t, v)
1935 tree t __attribute__ ((__unused__));
1936 tree v;
1937{
1938 return v;
1939}
1940
e04a16fb
AG
1941struct rtx_def *
1942java_lang_expand_expr (exp, target, tmode, modifier)
1943 register tree exp;
cd531a2e
KG
1944 rtx target ATTRIBUTE_UNUSED;
1945 enum machine_mode tmode ATTRIBUTE_UNUSED;
1946 enum expand_modifier modifier ATTRIBUTE_UNUSED;
e04a16fb 1947{
d4476be2 1948 tree current;
e04a16fb
AG
1949
1950 switch (TREE_CODE (exp))
1951 {
fdec99c6
PB
1952 case NEW_ARRAY_INIT:
1953 {
d4476be2 1954 rtx tmp;
fdec99c6
PB
1955 tree array_type = TREE_TYPE (TREE_TYPE (exp));
1956 tree element_type = TYPE_ARRAY_ELEMENT (array_type);
1957 tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
1958 HOST_WIDE_INT ilength = java_array_type_length (array_type);
1959 tree length = build_int_2 (ilength, 0);
1960 tree init = TREE_OPERAND (exp, 0);
bc3ca41b
PB
1961 tree array_decl;
1962#if 0
1963 /* Enable this once we can set the vtable field statically. FIXME */
ef0fec06 1964 if (TREE_CONSTANT (init) && TREE_STATIC (exp)
bc3ca41b
PB
1965 && JPRIMITIVE_TYPE_P (element_type))
1966 {
1967 tree temp, value, init_decl;
1968 START_RECORD_CONSTRUCTOR (temp, object_type_node);
1969 PUSH_FIELD_VALUE (temp, "vtable",
1970 null_pointer_node /* FIXME */
1971 );
1972 PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
1973 FINISH_RECORD_CONSTRUCTOR (temp);
1974 START_RECORD_CONSTRUCTOR (value, array_type);
1975 PUSH_SUPER_VALUE (value, temp);
1976 PUSH_FIELD_VALUE (value, "length", length);
1977 PUSH_FIELD_VALUE (value, "data", init);
1978 FINISH_RECORD_CONSTRUCTOR (value);
1979
1980 init_decl = build_decl (VAR_DECL, generate_name (), array_type);
1981 pushdecl_top_level (init_decl);
1982 TREE_STATIC (init_decl) = 1;
1983 DECL_INITIAL (init_decl) = value;
1984 DECL_IGNORED_P (init_decl) = 1;
1985 TREE_READONLY (init_decl) = 1;
1986 make_decl_rtl (init_decl, NULL, 1);
1987 init = build1 (ADDR_EXPR, TREE_TYPE (exp), init_decl);
1988 return expand_expr (init, target, tmode, modifier);
1989 }
1990#endif
1991 array_decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp));
fdec99c6
PB
1992 expand_decl (array_decl);
1993 tmp = expand_assignment (array_decl,
1994 build_new_array (element_type, length),
1995 1, 0);
1996 if (TREE_CONSTANT (init)
1997 && ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
1998 {
f626e9fa
AG
1999 tree init_decl;
2000 push_obstacks (&permanent_obstack, &permanent_obstack);
2001 init_decl = build_decl (VAR_DECL, generate_name (),
2002 TREE_TYPE (init));
fdec99c6
PB
2003 pushdecl_top_level (init_decl);
2004 TREE_STATIC (init_decl) = 1;
2005 DECL_INITIAL (init_decl) = init;
2006 DECL_IGNORED_P (init_decl) = 1;
2007 TREE_READONLY (init_decl) = 1;
66e06429 2008 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
fdec99c6 2009 make_decl_rtl (init_decl, NULL, 1);
f626e9fa 2010 pop_obstacks ();
fdec99c6
PB
2011 init = init_decl;
2012 }
2013 expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
2014 build1 (INDIRECT_REF, array_type, array_decl),
2015 data_fld),
2016 init, 0, 0);
2017 return tmp;
2018 }
e04a16fb
AG
2019 case BLOCK:
2020 if (BLOCK_EXPR_BODY (exp))
2021 {
2022 tree local;
15fdcfe9 2023 tree body = BLOCK_EXPR_BODY (exp);
e04a16fb
AG
2024 pushlevel (2); /* 2 and above */
2025 expand_start_bindings (0);
2026 local = BLOCK_EXPR_DECLS (exp);
2027 while (local)
2028 {
2029 tree next = TREE_CHAIN (local);
2030 layout_decl (local, 0);
2031 expand_decl (pushdecl (local));
2032 local = next;
2033 }
15fdcfe9
PB
2034 /* Avoid deep recursion for long block. */
2035 while (TREE_CODE (body) == COMPOUND_EXPR)
2036 {
2037 expand_expr (TREE_OPERAND (body, 0), const0_rtx, VOIDmode, 0);
818347b4 2038 emit_queue ();
15fdcfe9
PB
2039 body = TREE_OPERAND (body, 1);
2040 }
e533f648
AH
2041 expand_expr (body, const0_rtx, VOIDmode, 0);
2042 emit_queue ();
e04a16fb
AG
2043 poplevel (1, 1, 0);
2044 expand_end_bindings (getdecls (), 1, 0);
e533f648 2045 return const0_rtx;
e04a16fb 2046 }
d593dd8c 2047 return const0_rtx;
e04a16fb 2048
15fdcfe9
PB
2049 case CASE_EXPR:
2050 {
2051 tree duplicate;
2052 if (pushcase (TREE_OPERAND (exp, 0), case_identity,
c877974e
APB
2053 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE),
2054 &duplicate) == 2)
15fdcfe9
PB
2055 {
2056 EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (exp);
2057 parse_error_context
2058 (wfl_operator, "Duplicate case label: `%s'",
2059 print_int_node (TREE_OPERAND (exp, 0)));
2060 }
2061 return const0_rtx;
2062 }
2063
2064 case DEFAULT_EXPR:
c877974e
APB
2065 pushcase (NULL_TREE, 0,
2066 build_decl (LABEL_DECL, NULL_TREE, NULL_TREE), NULL);
15fdcfe9
PB
2067 return const0_rtx;
2068
e4de5a10 2069 case SWITCH_EXPR:
15fdcfe9
PB
2070 expand_start_case (0, TREE_OPERAND (exp, 0), int_type_node, "switch");
2071 expand_expr_stmt (TREE_OPERAND (exp, 1));
2072 expand_end_case (TREE_OPERAND (exp, 0));
e4de5a10
PB
2073 return const0_rtx;
2074
2075 case TRY_EXPR:
10b3fbc5 2076 /* We expand a try[-catch] block */
e4de5a10
PB
2077
2078 /* Expand the try block */
6f9c8716 2079 push_obstacks (&permanent_obstack, &permanent_obstack);
e4de5a10 2080 expand_eh_region_start ();
6f9c8716 2081 pop_obstacks ();
e4de5a10 2082 expand_expr_stmt (TREE_OPERAND (exp, 0));
6f9c8716 2083 push_obstacks (&permanent_obstack, &permanent_obstack);
e4de5a10 2084 expand_start_all_catch ();
6f9c8716 2085 pop_obstacks ();
e4de5a10
PB
2086
2087 /* Expand all catch clauses (EH handlers) */
2088 for (current = TREE_OPERAND (exp, 1); current;
2089 current = TREE_CHAIN (current))
2090 {
e4de5a10 2091 tree type;
10b3fbc5
PB
2092 tree catch = TREE_OPERAND (current, 0);
2093 tree decl = BLOCK_EXPR_DECLS (catch);
2094 type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
e4de5a10
PB
2095 start_catch_handler (prepare_eh_table_type (type));
2096 expand_expr_stmt (TREE_OPERAND (current, 0));
2097
1b18747f 2098 expand_resume_after_catch ();
e4de5a10
PB
2099 end_catch_handler ();
2100 }
e4de5a10 2101 expand_end_all_catch ();
d593dd8c 2102 return const0_rtx;
e4de5a10 2103
e04a16fb
AG
2104 default:
2105 fatal ("Can't expand '%s' tree - java_lang_expand_expr",
2106 tree_code_name [TREE_CODE (exp)]);
2107 }
2108}
2109
2110void
2111expand_byte_code (jcf, method)
2112 JCF *jcf;
2113 tree method;
2114{
2115 int PC;
2116 int i;
2117 int saw_index;
49f48c71 2118 const unsigned char *linenumber_pointer;
99fd3aa5 2119 int dead_code_index = -1;
e04a16fb
AG
2120
2121#undef RET /* Defined by config/i386/i386.h */
2122#undef AND /* Causes problems with opcodes for iand and land. */
2123#undef PTR
2124#define BCODE byte_ops
2125#define BYTE_type_node byte_type_node
2126#define SHORT_type_node short_type_node
2127#define INT_type_node int_type_node
2128#define LONG_type_node long_type_node
2129#define CHAR_type_node char_type_node
2130#define PTR_type_node ptr_type_node
2131#define FLOAT_type_node float_type_node
2132#define DOUBLE_type_node double_type_node
2133#define VOID_type_node void_type_node
2134 jint INT_temp;
2135 unsigned char* byte_ops;
2136 long length = DECL_CODE_LENGTH (method);
2137
2138 stack_pointer = 0;
2139 JCF_SEEK (jcf, DECL_CODE_OFFSET (method));
2140 byte_ops = jcf->read_ptr;
2141
2142#define CONST_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2143#define CONST_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2144#define VAR_INDEX_1 (saw_index = 1, IMMEDIATE_u1)
2145#define VAR_INDEX_2 (saw_index = 1, IMMEDIATE_u2)
2146
00abfc00 2147#define CHECK_PC_IN_RANGE(PC) ((void)1) /* Already handled by verifier. */
e04a16fb
AG
2148
2149 instruction_bits = oballoc (length + 1);
2150 bzero (instruction_bits, length + 1);
2151
2152 /* We make an initial pass of the line number table, to note
2153 which instructions have associated line number entries. */
2154 linenumber_pointer = linenumber_table;
2155 for (i = 0; i < linenumber_count; i++)
2156 {
2157 int pc = GET_u2 (linenumber_pointer);
2158 linenumber_pointer += 4;
2159 if (pc >= length)
2160 warning ("invalid PC in line number table");
2161 else
2162 {
2163 if ((instruction_bits[pc] & BCODE_HAS_LINENUMBER) != 0)
2164 instruction_bits[pc] |= BCODE_HAS_MULTI_LINENUMBERS;
2165 instruction_bits[pc] |= BCODE_HAS_LINENUMBER;
2166 }
2167 }
2168
2169 /* Do a preliminary pass.
2170 * This figures out which PC can be the targets of jumps. */
2171 for (PC = 0; PC < length;)
2172 {
2173 int oldpc = PC; /* PC at instruction start. */
2174 instruction_bits [PC] |= BCODE_INSTRUCTION_START;
2175 switch (byte_ops[PC++])
2176 {
2177#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2178 case OPCODE: \
2179 PRE_##OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2180 break;
2181
2182#define NOTE_LABEL(PC) note_label(oldpc, PC)
2183
2184#define PRE_PUSHC(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2185#define PRE_LOAD(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2186#define PRE_STORE(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE);
2187#define PRE_STACK(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2188#define PRE_UNOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2189#define PRE_BINOP(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2190#define PRE_CONVERT(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2191#define PRE_CONVERT2(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2192
2193#define PRE_SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2194 PRE_SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2195#define PRE_SPECIAL_IINC(OPERAND_TYPE) \
2196 ((void) IMMEDIATE_u1, (void) IMMEDIATE_s1)
2197#define PRE_SPECIAL_ENTER(IGNORE) /* nothing */
2198#define PRE_SPECIAL_EXIT(IGNORE) /* nothing */
2199#define PRE_SPECIAL_THROW(IGNORE) /* nothing */
2200#define PRE_SPECIAL_BREAK(IGNORE) /* nothing */
2201
2202/* two forms of wide instructions */
2203#define PRE_SPECIAL_WIDE(IGNORE) \
2204 { \
2205 int modified_opcode = IMMEDIATE_u1; \
2206 if (modified_opcode == OPCODE_iinc) \
2207 { \
2208 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2209 (void) IMMEDIATE_s2; /* constbyte1 and constbyte2 */ \
2210 } \
2211 else \
2212 { \
2213 (void) IMMEDIATE_u2; /* indexbyte1 and indexbyte2 */ \
2214 } \
2215 }
2216
2217/* nothing */ /* XXX JH */
2218
2219#define PRE_IMPL(IGNORE1, IGNORE2) /* nothing */
2220
2221#define PRE_MONITOR(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2222
2223#define PRE_RETURN(OPERAND_TYPE, OPERAND_VALUE) /* nothing */
2224#define PRE_ARRAY(OPERAND_TYPE, SUBOP) \
2225 PRE_ARRAY_##SUBOP(OPERAND_TYPE)
2226#define PRE_ARRAY_LOAD(TYPE) /* nothing */
2227#define PRE_ARRAY_STORE(TYPE) /* nothing */
2228#define PRE_ARRAY_LENGTH(TYPE) /* nothing */
2229#define PRE_ARRAY_NEW(TYPE) PRE_ARRAY_NEW_##TYPE
2230#define PRE_ARRAY_NEW_NUM ((void) IMMEDIATE_u1)
2231#define PRE_ARRAY_NEW_PTR ((void) IMMEDIATE_u2)
2232#define PRE_ARRAY_NEW_MULTI ((void) IMMEDIATE_u2, (void) IMMEDIATE_u1)
2233
2234#define PRE_TEST(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2235#define PRE_COND(OPERAND_TYPE, OPERAND_VALUE) NOTE_LABEL (oldpc+IMMEDIATE_s2)
2236#define PRE_BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2237 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2238 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2239#define PRE_JSR(OPERAND_TYPE, OPERAND_VALUE) \
2240 saw_index = 0; INT_temp = (OPERAND_VALUE); \
2241 if (!saw_index) NOTE_LABEL(oldpc + INT_temp);
2242
2243#define PRE_RET(OPERAND_TYPE, OPERAND_VALUE) (void)(OPERAND_VALUE)
2244
2245#define PRE_SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2246 PC = (PC + 3) / 4 * 4; PRE_##TABLE_OR_LOOKUP##_SWITCH
2247
2248#define PRE_LOOKUP_SWITCH \
2249 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2250 NOTE_LABEL (default_offset+oldpc); \
2251 if (npairs >= 0) \
2252 while (--npairs >= 0) { \
b4b63e32
KG
2253 jint match ATTRIBUTE_UNUSED = IMMEDIATE_s4; \
2254 jint offset = IMMEDIATE_s4; \
e04a16fb
AG
2255 NOTE_LABEL (offset+oldpc); } \
2256 }
2257
2258#define PRE_TABLE_SWITCH \
2259 { jint default_offset = IMMEDIATE_s4; \
2260 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2261 NOTE_LABEL (default_offset+oldpc); \
2262 if (low <= high) \
2263 while (low++ <= high) { \
2264 jint offset = IMMEDIATE_s4; \
2265 NOTE_LABEL (offset+oldpc); } \
2266 }
2267
2268#define PRE_FIELD(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2269#define PRE_OBJECT(MAYBE_STATIC, PUT_OR_GET) (void)(IMMEDIATE_u2);
2270#define PRE_INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2271 (void)(IMMEDIATE_u2); \
2272 PC += 2 * IS_INTERFACE /* for invokeinterface */;
2273
2274#include "javaop.def"
2275#undef JAVAOP
2276 }
2277 } /* for */
2278
2279 if (! verify_jvm_instructions (jcf, byte_ops, length))
2280 return;
2281
2282 /* Translate bytecodes to rtl instructions. */
2283 linenumber_pointer = linenumber_table;
2284 for (PC = 0; PC < length;)
2285 {
2286 if ((instruction_bits [PC] & BCODE_TARGET) != 0 || PC == 0)
2287 {
2288 tree label = lookup_label (PC);
2289 flush_quick_stack ();
2290 if ((instruction_bits [PC] & BCODE_TARGET) != 0)
2291 expand_label (label);
2292 if (LABEL_VERIFIED (label) || PC == 0)
2293 load_type_state (label);
2294 }
2295
2296 if (! (instruction_bits [PC] & BCODE_VERIFIED))
2297 {
99fd3aa5
AG
2298 if (dead_code_index == -1)
2299 {
2300 /* This is the start of a region of unreachable bytecodes.
2301 They still need to be processed in order for EH ranges
2302 to get handled correctly. However, we can simply
2303 replace these bytecodes with nops. */
2304 dead_code_index = PC;
2305 }
2306
2307 /* Turn this bytecode into a nop. */
2308 byte_ops[PC] = 0x0;
2309 }
2310 else
2311 {
2312 if (dead_code_index != -1)
2313 {
2314 /* We've just reached the end of a region of dead code. */
2315 warning ("Unreachable bytecode from %d to before %d.",
2316 dead_code_index, PC);
2317 dead_code_index = -1;
2318 }
e04a16fb
AG
2319 }
2320
e04a16fb
AG
2321 /* Handle possible line number entry for this PC.
2322
2323 This code handles out-of-order and multiple linenumbers per PC,
2324 but is optimized for the case of line numbers increasing
2325 monotonically with PC. */
2326 if ((instruction_bits[PC] & BCODE_HAS_LINENUMBER) != 0)
2327 {
2328 if ((instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS) != 0
2329 || GET_u2 (linenumber_pointer) != PC)
2330 linenumber_pointer = linenumber_table;
2331 while (linenumber_pointer < linenumber_table + linenumber_count * 4)
2332 {
2333 int pc = GET_u2 (linenumber_pointer);
2334 linenumber_pointer += 4;
2335 if (pc == PC)
2336 {
2337 lineno = GET_u2 (linenumber_pointer - 2);
2338 emit_line_note (input_filename, lineno);
2339 if (!(instruction_bits[PC] & BCODE_HAS_MULTI_LINENUMBERS))
2340 break;
2341 }
2342 }
2343 }
e04a16fb 2344 maybe_pushlevels (PC);
e04a16fb 2345 PC = process_jvm_instruction (PC, byte_ops, length);
e04a16fb 2346 maybe_poplevels (PC);
e04a16fb 2347 } /* for */
99fd3aa5
AG
2348
2349 if (dead_code_index != -1)
2350 {
2351 /* We've just reached the end of a region of dead code. */
2352 warning ("Unreachable bytecode from %d to the end of the method.",
2353 dead_code_index);
2354 }
e04a16fb
AG
2355}
2356
4bcde32e 2357static void
e04a16fb
AG
2358java_push_constant_from_pool (jcf, index)
2359 JCF *jcf;
2360 int index;
2361{
2362 tree c;
2363 if (JPOOL_TAG (jcf, index) == CONSTANT_String)
2364 {
2365 tree name;
2366 push_obstacks (&permanent_obstack, &permanent_obstack);
2367 name = get_name_constant (jcf, JPOOL_USHORT1 (jcf, index));
2368 index = alloc_name_constant (CONSTANT_String, name);
2369 c = build_ref_from_constant_pool (index);
2370 TREE_TYPE (c) = promote_type (string_type_node);
2371 pop_obstacks ();
2372 }
2373 else
2374 c = get_constant (jcf, index);
2375 push_value (c);
2376}
2377
2378int
2379process_jvm_instruction (PC, byte_ops, length)
2380 int PC;
c8e7d2e6 2381 const unsigned char* byte_ops;
ab3a6dd6 2382 long length ATTRIBUTE_UNUSED;
e04a16fb 2383{
d4476be2 2384 const char *opname; /* Temporary ??? */
e04a16fb 2385 int oldpc = PC; /* PC at instruction start. */
e4de5a10
PB
2386
2387 /* If the instruction is at the beginning of a exception handler,
2388 replace the top of the stack with the thrown object reference */
2389 if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
2390 {
aabd7048
PB
2391 tree type = pop_type (ptr_type_node);
2392 push_value (build1 (NOP_EXPR, type, soft_exceptioninfo_call_node));
e4de5a10
PB
2393 }
2394
e04a16fb
AG
2395 switch (byte_ops[PC++])
2396 {
2397#define JAVAOP(OPNAME, OPCODE, OPKIND, OPERAND_TYPE, OPERAND_VALUE) \
2398 case OPCODE: \
2399 opname = #OPNAME; \
2400 OPKIND(OPERAND_TYPE, OPERAND_VALUE); \
2401 break;
2402
2403#define RET(OPERAND_TYPE, OPERAND_VALUE) \
2404 { \
2405 int saw_index = 0; \
2406 int index = OPERAND_VALUE; \
2407 build_java_ret (find_local_variable (index, ptr_type_node, oldpc)); \
2408 }
2409
2410#define JSR(OPERAND_TYPE, OPERAND_VALUE) \
2411 { \
2412 tree where = lookup_label (oldpc+OPERAND_VALUE); \
2413 tree ret = lookup_label (PC); \
2414 build_java_jsr (where, ret); \
5a005d9e 2415 load_type_state (ret); \
e04a16fb
AG
2416 }
2417
2418/* Push a constant onto the stack. */
2419#define PUSHC(OPERAND_TYPE, OPERAND_VALUE) \
2420 { int saw_index = 0; int ival = (OPERAND_VALUE); \
2421 if (saw_index) java_push_constant_from_pool (current_jcf, ival); \
2422 else expand_java_pushc (ival, OPERAND_TYPE##_type_node); }
2423
2424/* internal macro added for use by the WIDE case */
2425#define LOAD_INTERNAL(OPTYPE, OPVALUE) \
2426 push_value (find_local_variable (OPVALUE, type_map[OPVALUE], oldpc));
2427
2428/* Push local variable onto the opcode stack. */
2429#define LOAD(OPERAND_TYPE, OPERAND_VALUE) \
2430 { \
2431 /* have to do this since OPERAND_VALUE may have side-effects */ \
2432 int opvalue = OPERAND_VALUE; \
2433 LOAD_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2434 }
2435
2436#define RETURN(OPERAND_TYPE, OPERAND_VALUE) \
2437 expand_java_return (OPERAND_TYPE##_type_node)
2438
2439#define REM_EXPR TRUNC_MOD_EXPR
2440#define BINOP(OPERAND_TYPE, OPERAND_VALUE) \
2441 expand_java_binop (OPERAND_TYPE##_type_node, OPERAND_VALUE##_EXPR)
2442
2443#define FIELD(IS_STATIC, IS_PUT) \
2444 expand_java_field_op (IS_STATIC, IS_PUT, IMMEDIATE_u2)
2445
2446#define TEST(OPERAND_TYPE, CONDITION) \
2447 expand_test (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2448
2449#define COND(OPERAND_TYPE, CONDITION) \
2450 expand_cond (CONDITION##_EXPR, OPERAND_TYPE##_type_node, oldpc+IMMEDIATE_s2)
2451
2452#define BRANCH(OPERAND_TYPE, OPERAND_VALUE) \
2453 BRANCH_##OPERAND_TYPE (OPERAND_VALUE)
2454
2455#define BRANCH_GOTO(OPERAND_VALUE) \
2456 expand_java_goto (oldpc + OPERAND_VALUE)
2457
2458#define BRANCH_CALL(OPERAND_VALUE) \
2459 expand_java_call (oldpc + OPERAND_VALUE, oldpc)
2460
2461#if 0
2462#define BRANCH_RETURN(OPERAND_VALUE) \
2463 { \
2464 tree type = OPERAND_TYPE##_type_node; \
2465 tree value = find_local_variable (OPERAND_VALUE, type, oldpc); \
2466 expand_java_ret (value); \
2467 }
2468#endif
2469
2470#define NOT_IMPL(OPERAND_TYPE, OPERAND_VALUE) \
2471 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2472 fprintf (stderr, "(not implemented)\n")
2473#define NOT_IMPL1(OPERAND_VALUE) \
2474 fprintf (stderr, "%3d: %s ", oldpc, opname); \
2475 fprintf (stderr, "(not implemented)\n")
2476
2477#define BRANCH_RETURN(OPERAND_VALUE) NOT_IMPL1(OPERAND_VALUE)
2478
2479#define STACK(SUBOP, COUNT) STACK_##SUBOP (COUNT)
2480
2481#define STACK_POP(COUNT) java_stack_pop (COUNT)
2482
2483#define STACK_SWAP(COUNT) java_stack_swap()
2484
2485#define STACK_DUP(COUNT) java_stack_dup (COUNT, 0)
2486#define STACK_DUPx1(COUNT) java_stack_dup (COUNT, 1)
2487#define STACK_DUPx2(COUNT) java_stack_dup (COUNT, 2)
2488
2489#define SWITCH(OPERAND_TYPE, TABLE_OR_LOOKUP) \
2490 PC = (PC + 3) / 4 * 4; TABLE_OR_LOOKUP##_SWITCH
2491
2492#define LOOKUP_SWITCH \
2493 { jint default_offset = IMMEDIATE_s4; jint npairs = IMMEDIATE_s4; \
2494 tree selector = pop_value (INT_type_node); \
2495 tree duplicate, label; \
2496 tree type = TREE_TYPE (selector); \
2497 flush_quick_stack (); \
2498 expand_start_case (0, selector, type, "switch statement");\
2499 push_momentary (); \
2500 while (--npairs >= 0) \
2501 { \
2502 jint match = IMMEDIATE_s4; jint offset = IMMEDIATE_s4; \
2503 tree value = build_int_2 (match, match < 0 ? -1 : 0); \
2504 TREE_TYPE (value) = type; \
2505 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2506 pushcase (value, convert, label, &duplicate); \
2507 expand_java_goto (oldpc + offset); \
2508 } \
2509 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2510 pushcase (NULL_TREE, 0, label, &duplicate); \
2511 expand_java_goto (oldpc + default_offset); \
2512 pop_momentary (); \
2513 expand_end_case (selector); \
2514 }
2515
2516#define TABLE_SWITCH \
2517 { jint default_offset = IMMEDIATE_s4; \
2518 jint low = IMMEDIATE_s4; jint high = IMMEDIATE_s4; \
2519 tree selector = pop_value (INT_type_node); \
2520 tree duplicate, label; \
2521 tree type = TREE_TYPE (selector); \
2522 flush_quick_stack (); \
2523 expand_start_case (0, selector, type, "switch statement");\
2524 push_momentary (); \
2525 for (; low <= high; low++) \
2526 { \
2527 jint offset = IMMEDIATE_s4; \
2528 tree value = build_int_2 (low, low < 0 ? -1 : 0); \
2529 TREE_TYPE (value) = type; \
2530 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2531 pushcase (value, convert, label, &duplicate); \
2532 expand_java_goto (oldpc + offset); \
2533 } \
2534 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); \
2535 pushcase (NULL_TREE, 0, label, &duplicate); \
2536 expand_java_goto (oldpc + default_offset); \
2537 pop_momentary (); \
2538 expand_end_case (selector); \
2539 }
2540
2541#define INVOKE(MAYBE_STATIC, IS_INTERFACE) \
2542 { int opcode = byte_ops[PC-1]; \
2543 int method_ref_index = IMMEDIATE_u2; \
2544 int nargs; \
2545 if (IS_INTERFACE) { nargs = IMMEDIATE_u1; (void) IMMEDIATE_u1; } \
2546 else nargs = -1; \
2547 expand_invoke (opcode, method_ref_index, nargs); \
2548 }
2549
2550/* Handle new, checkcast, instanceof */
2551#define OBJECT(TYPE, OP) \
2552 expand_java_##OP (get_class_constant (current_jcf, IMMEDIATE_u2))
2553
2554#define ARRAY(OPERAND_TYPE, SUBOP) ARRAY_##SUBOP(OPERAND_TYPE)
2555
2556#define ARRAY_LOAD(OPERAND_TYPE) \
2557 { \
2558 expand_java_arrayload( OPERAND_TYPE##_type_node ); \
2559 }
2560
2561#define ARRAY_STORE(OPERAND_TYPE) \
2562 { \
2563 expand_java_arraystore( OPERAND_TYPE##_type_node ); \
2564 }
2565
2566#define ARRAY_LENGTH(OPERAND_TYPE) expand_java_array_length();
2567#define ARRAY_NEW(OPERAND_TYPE) ARRAY_NEW_##OPERAND_TYPE()
2568#define ARRAY_NEW_PTR() \
2569 push_value (build_anewarray (get_class_constant (current_jcf, \
2570 IMMEDIATE_u2), \
2571 pop_value (int_type_node)));
2572#define ARRAY_NEW_NUM() \
2573 { \
2574 int atype = IMMEDIATE_u1; \
2575 push_value (build_newarray (atype, pop_value (int_type_node)));\
2576 }
2577#define ARRAY_NEW_MULTI() \
2578 { \
2579 tree class = get_class_constant (current_jcf, IMMEDIATE_u2 ); \
2580 int ndims = IMMEDIATE_u1; \
2581 expand_java_multianewarray( class, ndims ); \
2582 }
2583
2584#define UNOP(OPERAND_TYPE, OPERAND_VALUE) \
2585 push_value (fold (build1 (NEGATE_EXPR, OPERAND_TYPE##_type_node, \
2586 pop_value (OPERAND_TYPE##_type_node))));
2587
2588#define CONVERT2(FROM_TYPE, TO_TYPE) \
2589 { \
2590 push_value (build1 (NOP_EXPR, int_type_node, \
2591 (convert (TO_TYPE##_type_node, \
2592 pop_value (FROM_TYPE##_type_node))))); \
2593 }
2594
2595#define CONVERT(FROM_TYPE, TO_TYPE) \
2596 { \
2597 push_value (convert (TO_TYPE##_type_node, \
2598 pop_value (FROM_TYPE##_type_node))); \
2599 }
2600
2601/* internal macro added for use by the WIDE case
2602 Added TREE_TYPE (decl) assignment, apbianco */
2603#define STORE_INTERNAL(OPTYPE, OPVALUE) \
2604 { \
2605 tree decl, value; \
2606 int var = OPVALUE; \
2607 tree type = OPTYPE; \
2608 value = pop_value (type); \
2609 type = TREE_TYPE (value); \
2610 decl = find_local_variable (var, type, oldpc); \
2611 set_local_type (var, type ); \
2612 expand_assignment (decl, value, 0, 0); \
2613 }
2614
2615#define STORE(OPERAND_TYPE, OPERAND_VALUE) \
2616 { \
2617 /* have to do this since OPERAND_VALUE may have side-effects */ \
2618 int opvalue = OPERAND_VALUE; \
2619 STORE_INTERNAL(OPERAND_TYPE##_type_node, opvalue); \
2620 }
2621
2622#define SPECIAL(OPERAND_TYPE, INSTRUCTION) \
2623 SPECIAL_##INSTRUCTION(OPERAND_TYPE)
2624
2625#define SPECIAL_ENTER(IGNORED) MONITOR_OPERATION (soft_monitorenter_node)
2626#define SPECIAL_EXIT(IGNORED) MONITOR_OPERATION (soft_monitorexit_node)
2627
2628#define MONITOR_OPERATION(call) \
2629 { \
2630 tree o = pop_value (ptr_type_node); \
2631 tree c; \
2632 flush_quick_stack (); \
2633 c = build_java_monitor (call, o); \
2634 TREE_SIDE_EFFECTS (c) = 1; \
2635 expand_expr_stmt (c); \
2636 }
2637
2638#define SPECIAL_IINC(IGNORED) \
2639 { \
2640 unsigned int local_var_index = IMMEDIATE_u1; \
2641 int ival = IMMEDIATE_s1; \
2642 expand_iinc(local_var_index, ival, oldpc); \
2643 }
2644
2645#define SPECIAL_WIDE(IGNORED) \
2646 { \
2647 int modified_opcode = IMMEDIATE_u1; \
2648 unsigned int local_var_index = IMMEDIATE_u2; \
2649 switch (modified_opcode) \
2650 { \
2651 case OPCODE_iinc: \
2652 { \
2653 int ival = IMMEDIATE_s2; \
2654 expand_iinc (local_var_index, ival, oldpc); \
2655 break; \
2656 } \
2657 case OPCODE_iload: \
2658 case OPCODE_lload: \
2659 case OPCODE_fload: \
2660 case OPCODE_dload: \
2661 case OPCODE_aload: \
2662 { \
2663 /* duplicate code from LOAD macro */ \
2664 LOAD_INTERNAL(operand_type[modified_opcode], local_var_index); \
2665 break; \
2666 } \
2667 case OPCODE_istore: \
2668 case OPCODE_lstore: \
2669 case OPCODE_fstore: \
2670 case OPCODE_dstore: \
2671 case OPCODE_astore: \
2672 { \
2673 STORE_INTERNAL(operand_type[modified_opcode], local_var_index); \
2674 break; \
2675 } \
2676 default: \
2677 error ("unrecogized wide sub-instruction"); \
2678 } \
2679 }
2680
2681#define SPECIAL_THROW(IGNORED) \
2682 build_java_athrow (pop_value (throwable_type_node))
2683
2684#define SPECIAL_BREAK NOT_IMPL1
2685#define IMPL NOT_IMPL
2686
2687#include "javaop.def"
2688#undef JAVAOP
2689 default:
2690 fprintf (stderr, "%3d: unknown(%3d)\n", oldpc, byte_ops[PC]);
2691 }
2692 return PC;
2693}
74285560
PB
2694
2695/* Force the (direct) sub-operands of NODE to be evaluated in left-to-right
2696 order, as specified by Java Language Specification.
2697
2698 The problem is that while expand_expr will evaluate its sub-operands in
2699 left-to-right order, for variables it will just return an rtx (i.e.
2700 an lvalue) for the variable (rather than an rvalue). So it is possible
2701 that a later sub-operand will change the register, and when the
2702 actual operation is done, it will use the new value, when it should
2703 have used the original value.
2704
2705 We fix this by using save_expr. This forces the sub-operand to be
2706 copied into a fresh virtual register,
1a6d4fb7
APB
2707
2708 For method invocation, we modify the arguments so that a
2709 left-to-right order evaluation is performed. Saved expressions
2710 will, in CALL_EXPR order, be reused when the call will be expanded.
74285560
PB
2711*/
2712
2713tree
2714force_evaluation_order (node)
2715 tree node;
2716{
2717 if (flag_syntax_only)
2718 return node;
939d7216 2719 if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
74285560
PB
2720 {
2721 if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
2722 TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
2723 }
2724 else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR)
2725 {
1a6d4fb7
APB
2726 tree arg, cmp;
2727
2728 if (!TREE_OPERAND (node, 1))
2729 return node;
2730
2731 /* This reverses the evaluation order. This is a desired effect. */
2732 for (cmp = NULL_TREE, arg = TREE_OPERAND (node, 1);
2733 arg; arg = TREE_CHAIN (arg))
74285560 2734 {
1a6d4fb7
APB
2735 tree saved = save_expr (TREE_VALUE (arg));
2736 cmp = (cmp == NULL_TREE ? saved :
2737 build (COMPOUND_EXPR, void_type_node, cmp, saved));
2738 TREE_VALUE (arg) = saved;
74285560 2739 }
1a6d4fb7
APB
2740
2741 if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
2742 TREE_SIDE_EFFECTS (cmp) = 1;
2743
2744 if (cmp)
74285560 2745 {
1a6d4fb7
APB
2746 cmp = save_expr (build (COMPOUND_EXPR, TREE_TYPE (node), cmp, node));
2747 CAN_COMPLETE_NORMALLY (cmp) = CAN_COMPLETE_NORMALLY (node);
2748 TREE_SIDE_EFFECTS (cmp) = 1;
2749 node = cmp;
74285560
PB
2750 }
2751 }
2752 return node;
2753}
This page took 0.717062 seconds and 5 git commands to generate.