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