1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
33 $Id: stack.c 4682 2006-03-23 00:08:28Z edwin $
49 #include "mm/memory.h"
50 #include "native/native.h"
51 #include "toolbox/logging.h"
52 #include "vm/global.h"
53 #include "vm/builtin.h"
54 #include "vm/options.h"
55 #include "vm/resolve.h"
56 #include "vm/statistics.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/disass.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/stack.h"
63 #include "vm/jit/allocator/lsra.h"
66 /* global variables ***********************************************************/
68 #if defined(USE_THREADS)
69 static java_objectheader *lock_show_icmd;
72 /* macro for saving #ifdefs ***************************************************/
74 #if defined(ENABLE_INTRP)
75 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
77 #define IF_NO_INTRP(x) { x }
80 /* stack_init ******************************************************************
82 Initialized the stack analysis subsystem (called by jit_init).
84 *******************************************************************************/
88 #if defined(USE_THREADS)
89 /* initialize the show lock */
91 lock_show_icmd = NEW(java_objectheader);
93 # if defined(NATIVE_THREADS)
94 initObjectLock(lock_show_icmd);
104 /**********************************************************************/
106 /**********************************************************************/
108 /* analyse_stack uses the intermediate code created by parse.c to
109 * build a model of the JVM operand stack for the current method.
111 * The following checks are performed:
112 * - check for operand stack underflow (before each instruction)
113 * - check for operand stack overflow (after[1] each instruction)
114 * - check for matching stack depth at merging points
115 * - check for matching basic types[2] at merging points
116 * - check basic types for instruction input (except for BUILTIN*
117 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
119 * [1]) Checking this after the instruction should be ok. parse.c
120 * counts the number of required stack slots in such a way that it is
121 * only vital that we don't exceed `maxstack` at basic block
124 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
125 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
126 * types are not discerned.
129 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
137 int opcode, i, j, len, loops;
138 int superblockend, repeat, deadcode;
144 s4 *last_store;/* instruction index of last XSTORE */
145 /* [ local_index * 5 + type ] */
146 s4 last_pei; /* instruction index of last possible exception */
147 /* used for conflict resolution for copy */
148 /* elimination (XLOAD, IINC, XSTORE) */
150 #if defined(ENABLE_VERIFIER)
151 int expectedtype; /* used by CHECK_BASIC_TYPE */
154 builtintable_entry *bte;
155 unresolved_method *um;
158 #if defined(ENABLE_LSRA)
162 last_store = DMNEW(s4 , cd->maxlocals * 5);
166 m->basicblocks[0].flags = BBREACHED;
167 m->basicblocks[0].instack = 0;
168 m->basicblocks[0].indepth = 0;
170 for (i = 0; i < cd->exceptiontablelength; i++) {
171 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
172 bptr->flags = BBREACHED;
173 bptr->type = BBTYPE_EXH;
176 bptr->pre_count = 10000;
181 #if CONDITIONAL_LOADCONST
182 b_count = m->basicblockcount;
183 bptr = m->basicblocks;
184 while (--b_count >= 0) {
185 if (bptr->icount != 0) {
186 iptr = bptr->iinstr + bptr->icount - 1;
219 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
222 case ICMD_TABLESWITCH:
224 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
225 i = *s4ptr++; /* low */
226 i = *s4ptr++ - i + 1; /* high */
228 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
232 case ICMD_LOOKUPSWITCH:
234 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
235 i = *s4ptr++; /* count */
237 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
248 #endif /* CONDITIONAL_LOADCONST */
253 b_count = m->basicblockcount;
254 bptr = m->basicblocks;
255 superblockend = true;
260 while (--b_count >= 0) {
261 if (bptr->flags == BBDELETED) {
264 } else if (superblockend && (bptr->flags < BBREACHED)) {
267 } else if (bptr->flags <= BBREACHED) {
269 stackdepth = bptr->indepth;
271 } else if (bptr->flags < BBREACHED) {
273 bptr->instack = copy;
274 bptr->indepth = stackdepth;
276 } else if (bptr->indepth != stackdepth) {
277 /*show_icmd_method(m, cd, rd);
278 printf("Block: %d, required depth: %d, current depth: %d\n",
279 bptr->debug_nr, bptr->indepth, stackdepth);*/
280 *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
284 curstack = bptr->instack;
286 superblockend = false;
287 bptr->flags = BBFINISHED;
290 b_index = bptr - m->basicblocks;
294 for( i = 0; i < cd->maxlocals; i++)
295 for( j = 0; j < 5; j++)
296 last_store[5 * i + j] = -1;
303 #if defined(USEBUILTINTABLE)
304 # if defined(ENABLE_INTRP)
307 bte = builtintable_get_automatic(opcode);
309 if (bte && bte->opcode == opcode) {
310 iptr->opc = ICMD_BUILTIN;
311 iptr->op1 = false; /* don't check for exception */
313 m->isleafmethod = false;
316 # if defined(ENABLE_INTRP)
319 #endif /* defined(USEBUILTINTABLE) */
326 COUNT(count_check_null);
329 case ICMD_IFEQ_ICONST:
330 case ICMD_IFNE_ICONST:
331 case ICMD_IFLT_ICONST:
332 case ICMD_IFGE_ICONST:
333 case ICMD_IFGT_ICONST:
334 case ICMD_IFLE_ICONST:
335 case ICMD_ELSE_ICONST:
340 #if defined(ENABLE_INTRP)
343 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
345 COUNT(count_pcmd_return);
347 superblockend = true;
350 /* pop 0 push 1 const */
353 COUNT(count_pcmd_load);
355 switch (iptr[1].opc) {
357 iptr[0].opc = ICMD_IADDCONST;
359 iptr[1].opc = ICMD_NOP;
360 OP1_1(TYPE_INT, TYPE_INT);
361 COUNT(count_pcmd_op);
364 iptr[0].opc = ICMD_ISUBCONST;
365 goto icmd_iconst_tail;
366 #if SUPPORT_CONST_MUL
368 iptr[0].opc = ICMD_IMULCONST;
369 goto icmd_iconst_tail;
370 #else /* SUPPORT_CONST_MUL */
372 if (iptr[0].val.i == 0x00000002)
374 else if (iptr[0].val.i == 0x00000004)
376 else if (iptr[0].val.i == 0x00000008)
378 else if (iptr[0].val.i == 0x00000010)
380 else if (iptr[0].val.i == 0x00000020)
382 else if (iptr[0].val.i == 0x00000040)
384 else if (iptr[0].val.i == 0x00000080)
386 else if (iptr[0].val.i == 0x00000100)
388 else if (iptr[0].val.i == 0x00000200)
390 else if (iptr[0].val.i == 0x00000400)
392 else if (iptr[0].val.i == 0x00000800)
394 else if (iptr[0].val.i == 0x00001000)
396 else if (iptr[0].val.i == 0x00002000)
398 else if (iptr[0].val.i == 0x00004000)
400 else if (iptr[0].val.i == 0x00008000)
402 else if (iptr[0].val.i == 0x00010000)
404 else if (iptr[0].val.i == 0x00020000)
406 else if (iptr[0].val.i == 0x00040000)
408 else if (iptr[0].val.i == 0x00080000)
410 else if (iptr[0].val.i == 0x00100000)
412 else if (iptr[0].val.i == 0x00200000)
414 else if (iptr[0].val.i == 0x00400000)
416 else if (iptr[0].val.i == 0x00800000)
418 else if (iptr[0].val.i == 0x01000000)
420 else if (iptr[0].val.i == 0x02000000)
422 else if (iptr[0].val.i == 0x04000000)
424 else if (iptr[0].val.i == 0x08000000)
426 else if (iptr[0].val.i == 0x10000000)
428 else if (iptr[0].val.i == 0x20000000)
430 else if (iptr[0].val.i == 0x40000000)
432 else if (iptr[0].val.i == 0x80000000)
438 iptr[0].opc = ICMD_IMULPOW2;
439 goto icmd_iconst_tail;
440 #endif /* SUPPORT_CONST_MUL */
442 if (iptr[0].val.i == 0x00000002)
444 else if (iptr[0].val.i == 0x00000004)
446 else if (iptr[0].val.i == 0x00000008)
448 else if (iptr[0].val.i == 0x00000010)
450 else if (iptr[0].val.i == 0x00000020)
452 else if (iptr[0].val.i == 0x00000040)
454 else if (iptr[0].val.i == 0x00000080)
456 else if (iptr[0].val.i == 0x00000100)
458 else if (iptr[0].val.i == 0x00000200)
460 else if (iptr[0].val.i == 0x00000400)
462 else if (iptr[0].val.i == 0x00000800)
464 else if (iptr[0].val.i == 0x00001000)
466 else if (iptr[0].val.i == 0x00002000)
468 else if (iptr[0].val.i == 0x00004000)
470 else if (iptr[0].val.i == 0x00008000)
472 else if (iptr[0].val.i == 0x00010000)
474 else if (iptr[0].val.i == 0x00020000)
476 else if (iptr[0].val.i == 0x00040000)
478 else if (iptr[0].val.i == 0x00080000)
480 else if (iptr[0].val.i == 0x00100000)
482 else if (iptr[0].val.i == 0x00200000)
484 else if (iptr[0].val.i == 0x00400000)
486 else if (iptr[0].val.i == 0x00800000)
488 else if (iptr[0].val.i == 0x01000000)
490 else if (iptr[0].val.i == 0x02000000)
492 else if (iptr[0].val.i == 0x04000000)
494 else if (iptr[0].val.i == 0x08000000)
496 else if (iptr[0].val.i == 0x10000000)
498 else if (iptr[0].val.i == 0x20000000)
500 else if (iptr[0].val.i == 0x40000000)
502 else if (iptr[0].val.i == 0x80000000)
508 iptr[0].opc = ICMD_IDIVPOW2;
509 goto icmd_iconst_tail;
511 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
512 if ((iptr[0].val.i == 0x00000002) ||
513 (iptr[0].val.i == 0x00000004) ||
514 (iptr[0].val.i == 0x00000008) ||
515 (iptr[0].val.i == 0x00000010) ||
516 (iptr[0].val.i == 0x00000020) ||
517 (iptr[0].val.i == 0x00000040) ||
518 (iptr[0].val.i == 0x00000080) ||
519 (iptr[0].val.i == 0x00000100) ||
520 (iptr[0].val.i == 0x00000200) ||
521 (iptr[0].val.i == 0x00000400) ||
522 (iptr[0].val.i == 0x00000800) ||
523 (iptr[0].val.i == 0x00001000) ||
524 (iptr[0].val.i == 0x00002000) ||
525 (iptr[0].val.i == 0x00004000) ||
526 (iptr[0].val.i == 0x00008000) ||
527 (iptr[0].val.i == 0x00010000) ||
528 (iptr[0].val.i == 0x00020000) ||
529 (iptr[0].val.i == 0x00040000) ||
530 (iptr[0].val.i == 0x00080000) ||
531 (iptr[0].val.i == 0x00100000) ||
532 (iptr[0].val.i == 0x00200000) ||
533 (iptr[0].val.i == 0x00400000) ||
534 (iptr[0].val.i == 0x00800000) ||
535 (iptr[0].val.i == 0x01000000) ||
536 (iptr[0].val.i == 0x02000000) ||
537 (iptr[0].val.i == 0x04000000) ||
538 (iptr[0].val.i == 0x08000000) ||
539 (iptr[0].val.i == 0x10000000) ||
540 (iptr[0].val.i == 0x20000000) ||
541 (iptr[0].val.i == 0x40000000) ||
542 (iptr[0].val.i == 0x80000000)) {
543 iptr[0].opc = ICMD_IREMPOW2;
545 goto icmd_iconst_tail;
549 #if SUPPORT_CONST_LOGICAL
551 iptr[0].opc = ICMD_IANDCONST;
552 goto icmd_iconst_tail;
554 iptr[0].opc = ICMD_IORCONST;
555 goto icmd_iconst_tail;
557 iptr[0].opc = ICMD_IXORCONST;
558 goto icmd_iconst_tail;
559 #endif /* SUPPORT_CONST_LOGICAL */
561 iptr[0].opc = ICMD_ISHLCONST;
562 goto icmd_iconst_tail;
564 iptr[0].opc = ICMD_ISHRCONST;
565 goto icmd_iconst_tail;
567 iptr[0].opc = ICMD_IUSHRCONST;
568 goto icmd_iconst_tail;
569 #if SUPPORT_LONG_SHIFT
571 iptr[0].opc = ICMD_LSHLCONST;
572 goto icmd_lconst_tail;
574 iptr[0].opc = ICMD_LSHRCONST;
575 goto icmd_lconst_tail;
577 iptr[0].opc = ICMD_LUSHRCONST;
578 goto icmd_lconst_tail;
579 #endif /* SUPPORT_LONG_SHIFT */
581 iptr[0].opc = ICMD_IFEQ;
583 iptr[0].op1 = iptr[1].op1;
584 /* IF_ICMPxx is the last instruction in the */
585 /* basic block, just remove it */
586 /* iptr[1].opc = ICMD_NOP; */
591 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
593 iptr[0].target = (void *) tbptr;
595 MARKREACHED(tbptr, copy);
596 COUNT(count_pcmd_bra);
599 iptr[0].opc = ICMD_IFLT;
600 goto icmd_if_icmp_tail;
602 iptr[0].opc = ICMD_IFLE;
603 goto icmd_if_icmp_tail;
605 iptr[0].opc = ICMD_IFNE;
606 goto icmd_if_icmp_tail;
608 iptr[0].opc = ICMD_IFGT;
609 goto icmd_if_icmp_tail;
611 iptr[0].opc = ICMD_IFGE;
612 goto icmd_if_icmp_tail;
614 #if SUPPORT_CONST_STORE
619 # if defined(ENABLE_INTRP)
622 # if SUPPORT_CONST_STORE_ZERO_ONLY
623 if (iptr[0].val.i == 0) {
624 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
625 switch (iptr[1].opc) {
627 iptr[0].opc = ICMD_IASTORECONST;
630 iptr[0].opc = ICMD_BASTORECONST;
633 iptr[0].opc = ICMD_CASTORECONST;
636 iptr[0].opc = ICMD_SASTORECONST;
640 iptr[1].opc = ICMD_NOP;
641 OPTT2_0(TYPE_INT, TYPE_ADR);
642 COUNT(count_pcmd_op);
643 # if SUPPORT_CONST_STORE_ZERO_ONLY
646 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
647 # if defined(ENABLE_INTRP)
655 # if defined(ENABLE_INTRP)
658 # if SUPPORT_CONST_STORE_ZERO_ONLY
659 if (iptr[0].val.i == 0) {
660 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
661 switch (iptr[1].opc) {
663 iptr[0].opc = ICMD_PUTSTATICCONST;
667 iptr[0].opc = ICMD_PUTFIELDCONST;
672 iptr[1].opc = ICMD_NOP;
673 iptr[0].op1 = TYPE_INT;
674 COUNT(count_pcmd_op);
675 # if SUPPORT_CONST_STORE_ZERO_ONLY
678 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
679 # if defined(ENABLE_INTRP)
684 #endif /* SUPPORT_CONST_STORE */
694 COUNT(count_pcmd_load);
696 switch (iptr[1].opc) {
699 iptr[0].opc = ICMD_LADDCONST;
701 iptr[1].opc = ICMD_NOP;
702 OP1_1(TYPE_LNG,TYPE_LNG);
703 COUNT(count_pcmd_op);
706 iptr[0].opc = ICMD_LSUBCONST;
707 goto icmd_lconst_tail;
708 #endif /* SUPPORT_LONG_ADD */
709 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
711 iptr[0].opc = ICMD_LMULCONST;
712 goto icmd_lconst_tail;
713 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
714 # if SUPPORT_LONG_SHIFT
716 if (iptr[0].val.l == 0x00000002)
718 else if (iptr[0].val.l == 0x00000004)
720 else if (iptr[0].val.l == 0x00000008)
722 else if (iptr[0].val.l == 0x00000010)
724 else if (iptr[0].val.l == 0x00000020)
726 else if (iptr[0].val.l == 0x00000040)
728 else if (iptr[0].val.l == 0x00000080)
730 else if (iptr[0].val.l == 0x00000100)
732 else if (iptr[0].val.l == 0x00000200)
734 else if (iptr[0].val.l == 0x00000400)
736 else if (iptr[0].val.l == 0x00000800)
738 else if (iptr[0].val.l == 0x00001000)
740 else if (iptr[0].val.l == 0x00002000)
742 else if (iptr[0].val.l == 0x00004000)
744 else if (iptr[0].val.l == 0x00008000)
746 else if (iptr[0].val.l == 0x00010000)
748 else if (iptr[0].val.l == 0x00020000)
750 else if (iptr[0].val.l == 0x00040000)
752 else if (iptr[0].val.l == 0x00080000)
754 else if (iptr[0].val.l == 0x00100000)
756 else if (iptr[0].val.l == 0x00200000)
758 else if (iptr[0].val.l == 0x00400000)
760 else if (iptr[0].val.l == 0x00800000)
762 else if (iptr[0].val.l == 0x01000000)
764 else if (iptr[0].val.l == 0x02000000)
766 else if (iptr[0].val.l == 0x04000000)
768 else if (iptr[0].val.l == 0x08000000)
770 else if (iptr[0].val.l == 0x10000000)
772 else if (iptr[0].val.l == 0x20000000)
774 else if (iptr[0].val.l == 0x40000000)
776 else if (iptr[0].val.l == 0x80000000)
782 iptr[0].opc = ICMD_LMULPOW2;
783 goto icmd_lconst_tail;
784 # endif /* SUPPORT_LONG_SHIFT */
785 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
788 if (iptr[0].val.l == 0x00000002)
790 else if (iptr[0].val.l == 0x00000004)
792 else if (iptr[0].val.l == 0x00000008)
794 else if (iptr[0].val.l == 0x00000010)
796 else if (iptr[0].val.l == 0x00000020)
798 else if (iptr[0].val.l == 0x00000040)
800 else if (iptr[0].val.l == 0x00000080)
802 else if (iptr[0].val.l == 0x00000100)
804 else if (iptr[0].val.l == 0x00000200)
806 else if (iptr[0].val.l == 0x00000400)
808 else if (iptr[0].val.l == 0x00000800)
810 else if (iptr[0].val.l == 0x00001000)
812 else if (iptr[0].val.l == 0x00002000)
814 else if (iptr[0].val.l == 0x00004000)
816 else if (iptr[0].val.l == 0x00008000)
818 else if (iptr[0].val.l == 0x00010000)
820 else if (iptr[0].val.l == 0x00020000)
822 else if (iptr[0].val.l == 0x00040000)
824 else if (iptr[0].val.l == 0x00080000)
826 else if (iptr[0].val.l == 0x00100000)
828 else if (iptr[0].val.l == 0x00200000)
830 else if (iptr[0].val.l == 0x00400000)
832 else if (iptr[0].val.l == 0x00800000)
834 else if (iptr[0].val.l == 0x01000000)
836 else if (iptr[0].val.l == 0x02000000)
838 else if (iptr[0].val.l == 0x04000000)
840 else if (iptr[0].val.l == 0x08000000)
842 else if (iptr[0].val.l == 0x10000000)
844 else if (iptr[0].val.l == 0x20000000)
846 else if (iptr[0].val.l == 0x40000000)
848 else if (iptr[0].val.l == 0x80000000)
854 iptr[0].opc = ICMD_LDIVPOW2;
855 goto icmd_lconst_tail;
857 if ((iptr[0].val.l == 0x00000002) ||
858 (iptr[0].val.l == 0x00000004) ||
859 (iptr[0].val.l == 0x00000008) ||
860 (iptr[0].val.l == 0x00000010) ||
861 (iptr[0].val.l == 0x00000020) ||
862 (iptr[0].val.l == 0x00000040) ||
863 (iptr[0].val.l == 0x00000080) ||
864 (iptr[0].val.l == 0x00000100) ||
865 (iptr[0].val.l == 0x00000200) ||
866 (iptr[0].val.l == 0x00000400) ||
867 (iptr[0].val.l == 0x00000800) ||
868 (iptr[0].val.l == 0x00001000) ||
869 (iptr[0].val.l == 0x00002000) ||
870 (iptr[0].val.l == 0x00004000) ||
871 (iptr[0].val.l == 0x00008000) ||
872 (iptr[0].val.l == 0x00010000) ||
873 (iptr[0].val.l == 0x00020000) ||
874 (iptr[0].val.l == 0x00040000) ||
875 (iptr[0].val.l == 0x00080000) ||
876 (iptr[0].val.l == 0x00100000) ||
877 (iptr[0].val.l == 0x00200000) ||
878 (iptr[0].val.l == 0x00400000) ||
879 (iptr[0].val.l == 0x00800000) ||
880 (iptr[0].val.l == 0x01000000) ||
881 (iptr[0].val.l == 0x02000000) ||
882 (iptr[0].val.l == 0x04000000) ||
883 (iptr[0].val.l == 0x08000000) ||
884 (iptr[0].val.l == 0x10000000) ||
885 (iptr[0].val.l == 0x20000000) ||
886 (iptr[0].val.l == 0x40000000) ||
887 (iptr[0].val.l == 0x80000000)) {
888 iptr[0].opc = ICMD_LREMPOW2;
890 goto icmd_lconst_tail;
894 #endif /* SUPPORT_LONG_DIV */
895 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
898 iptr[0].opc = ICMD_LANDCONST;
899 goto icmd_lconst_tail;
901 iptr[0].opc = ICMD_LORCONST;
902 goto icmd_lconst_tail;
904 iptr[0].opc = ICMD_LXORCONST;
905 goto icmd_lconst_tail;
906 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
908 #if SUPPORT_LONG_CMP_CONST
910 if ((len > 1) && (iptr[2].val.i == 0)) {
911 switch (iptr[2].opc) {
913 iptr[0].opc = ICMD_IF_LEQ;
914 icmd_lconst_lcmp_tail:
915 iptr[0].op1 = iptr[2].op1;
918 /* iptr[1].opc = ICMD_NOP;
919 iptr[2].opc = ICMD_NOP; */
921 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
923 iptr[0].target = (void *) tbptr;
925 MARKREACHED(tbptr, copy);
926 COUNT(count_pcmd_bra);
927 COUNT(count_pcmd_op);
930 iptr[0].opc = ICMD_IF_LNE;
931 goto icmd_lconst_lcmp_tail;
933 iptr[0].opc = ICMD_IF_LLT;
934 goto icmd_lconst_lcmp_tail;
936 iptr[0].opc = ICMD_IF_LGT;
937 goto icmd_lconst_lcmp_tail;
939 iptr[0].opc = ICMD_IF_LLE;
940 goto icmd_lconst_lcmp_tail;
942 iptr[0].opc = ICMD_IF_LGE;
943 goto icmd_lconst_lcmp_tail;
946 } /* switch (iptr[2].opc) */
947 } /* if (iptr[2].val.i == 0) */
951 #endif /* SUPPORT_LONG_CMP_CONST */
953 #if SUPPORT_CONST_STORE
955 # if defined(ENABLE_INTRP)
958 # if SUPPORT_CONST_STORE_ZERO_ONLY
959 if (iptr[0].val.l == 0) {
960 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
961 iptr[0].opc = ICMD_LASTORECONST;
962 iptr[1].opc = ICMD_NOP;
963 OPTT2_0(TYPE_INT, TYPE_ADR);
964 COUNT(count_pcmd_op);
965 # if SUPPORT_CONST_STORE_ZERO_ONLY
968 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
969 # if defined(ENABLE_INTRP)
977 # if defined(ENABLE_INTRP)
980 # if SUPPORT_CONST_STORE_ZERO_ONLY
981 if (iptr[0].val.l == 0) {
982 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
983 switch (iptr[1].opc) {
985 iptr[0].opc = ICMD_PUTSTATICCONST;
989 iptr[0].opc = ICMD_PUTFIELDCONST;
994 iptr[1].opc = ICMD_NOP;
995 iptr[0].op1 = TYPE_LNG;
996 COUNT(count_pcmd_op);
997 # if SUPPORT_CONST_STORE_ZERO_ONLY
1000 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
1001 # if defined(ENABLE_INTRP)
1003 PUSHCONST(TYPE_LNG);
1006 #endif /* SUPPORT_CONST_STORE */
1008 PUSHCONST(TYPE_LNG);
1012 PUSHCONST(TYPE_LNG);
1016 COUNT(count_pcmd_load);
1017 PUSHCONST(TYPE_FLT);
1021 COUNT(count_pcmd_load);
1022 PUSHCONST(TYPE_DBL);
1026 COUNT(count_pcmd_load);
1027 #if SUPPORT_CONST_STORE
1028 # if defined(ENABLE_INTRP)
1031 if ((len > 0) && (iptr->val.a == 0)) {
1032 switch (iptr[1].opc) {
1034 case ICMD_PUTSTATIC:
1036 switch (iptr[1].opc) {
1038 iptr[0].opc = ICMD_AASTORECONST;
1039 OPTT2_0(TYPE_INT, TYPE_ADR);
1041 case ICMD_PUTSTATIC:
1042 iptr[0].opc = ICMD_PUTSTATICCONST;
1043 iptr[0].op1 = TYPE_ADR;
1047 iptr[0].opc = ICMD_PUTFIELDCONST;
1048 iptr[0].op1 = TYPE_ADR;
1053 iptr[1].opc = ICMD_NOP;
1054 COUNT(count_pcmd_op);
1058 PUSHCONST(TYPE_ADR);
1062 PUSHCONST(TYPE_ADR);
1063 # if defined(ENABLE_INTRP)
1065 PUSHCONST(TYPE_ADR);
1067 #else /* SUPPORT_CONST_STORE */
1068 PUSHCONST(TYPE_ADR);
1069 #endif /* SUPPORT_CONST_STORE */
1072 /* pop 0 push 1 load */
1079 COUNT(count_load_instruction);
1080 i = opcode - ICMD_ILOAD;
1081 #if defined(ENABLE_INTRP)
1084 rd->locals[iptr->op1][i].type = i;
1085 LOAD(i, LOCALVAR, iptr->op1);
1095 COUNT(count_check_null);
1096 COUNT(count_check_bound);
1097 COUNT(count_pcmd_mem);
1098 OP2IAT_1(opcode - ICMD_IALOAD);
1104 COUNT(count_check_null);
1105 COUNT(count_check_bound);
1106 COUNT(count_pcmd_mem);
1110 /* pop 0 push 0 iinc */
1113 #if defined(ENABLE_STATISTICS)
1117 count_store_depth[10]++;
1119 count_store_depth[i]++;
1122 last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
1127 if ((copy->varkind == LOCALVAR) &&
1128 (copy->varnum == iptr->op1)) {
1129 copy->varkind = TEMPVAR;
1139 /* pop 1 push 0 store */
1148 i = opcode - ICMD_ISTORE;
1149 #if defined(ENABLE_INTRP)
1152 rd->locals[iptr->op1][i].type = i;
1153 #if defined(ENABLE_STATISTICS)
1158 count_store_length[20]++;
1160 count_store_length[i]++;
1163 count_store_depth[10]++;
1165 count_store_depth[i]++;
1168 /* check for conflicts as described in Figure 5.2 */
1169 copy = curstack->prev;
1172 if ((copy->varkind == LOCALVAR) &&
1173 (copy->varnum == iptr->op1)) {
1174 copy->varkind = TEMPVAR;
1181 /* do not change instack Stackslots */
1182 /* it won't improve performance if we copy the interface */
1183 /* at the BB begin or here, and lsra relies that no */
1184 /* instack stackslot is marked LOCALVAR */
1185 if (curstack->varkind == STACKVAR)
1186 goto _possible_conflict;
1188 /* check for a DUPX,SWAP while the lifetime of curstack */
1189 /* and as creator curstack */
1190 if (last_dupx != -1) {
1191 /* we have to look at the dst stack of DUPX */
1192 /* == src Stack of PEI */
1193 copy = bptr->iinstr[last_dupx].dst;
1196 copy = bptr->instack;
1198 copy = bptr->iinstr[last_pei-1].dst;
1200 if ((copy != NULL) && (curstack <= copy)) {
1201 /* curstack alive at or created by DUPX */
1204 /* now look, if there is a LOCALVAR at anyone of */
1205 /* the src stacklots used by DUPX */
1207 goto _possible_conflict;
1211 /* check for a PEI while the lifetime of curstack */
1212 if (last_pei != -1) {
1213 /* && there are exception handler in this method */
1214 /* when this is checked prevent ARGVAR from */
1215 /* overwriting LOCALVAR!!! */
1217 /* we have to look at the stack _before_ the PEI! */
1218 /* == src Stack of PEI */
1220 copy = bptr->instack;
1222 copy = bptr->iinstr[last_pei-1].dst;
1223 if ((copy != NULL) && (curstack <= copy)) {
1224 /* curstack alive at PEI */
1225 goto _possible_conflict;
1229 /* check if there is a possible conflicting XSTORE */
1230 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) {
1231 /* we have to look at the stack _before_ the XSTORE! */
1232 /* == src Stack of XSTORE */
1233 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0)
1234 copy = bptr->instack;
1236 copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst;
1237 if ((copy != NULL) && (curstack <= copy)) {
1238 /* curstack alive at Last Store */
1239 goto _possible_conflict;
1243 /* check if there is a conflict with a XLOAD */
1244 /* this is done indirectly by looking if a Stackslot is */
1245 /* marked LOCALVAR and is live while curstack is live */
1246 /* see figure 5.3 */
1248 /* First check "above" stackslots of the instack */
1249 copy = curstack + 1;
1250 for(;(copy <= bptr->instack); copy++)
1251 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1252 goto _possible_conflict;
1255 /* "intra" Basic Block Stackslots are allocated above */
1256 /* bptr->stack (see doc/stack.txt), so if curstack + 1 */
1257 /* is an instack, copy could point now to the stackslots */
1258 /* of an inbetween analysed Basic Block */
1259 if (copy < bptr->stack)
1261 while (copy < new) {
1262 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1263 goto _possible_conflict;
1267 /* If Stackslot is already marked as LOCALVAR, do not */
1268 /* change it! Conflict resolution works only, if xLOAD */
1270 if (curstack->varkind == LOCALVAR)
1271 goto _possible_conflict;
1272 /* no conflict - mark the Stackslot as LOCALVAR */
1273 curstack->varkind = LOCALVAR;
1274 curstack->varnum = iptr->op1;
1278 if ((curstack->varkind == LOCALVAR)
1279 && (curstack->varnum == iptr->op1)) {
1280 curstack->varkind = TEMPVAR;
1281 curstack->varnum = stackdepth-1;
1284 last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1;
1286 STORE(opcode - ICMD_ISTORE);
1292 COUNT(count_check_null);
1293 COUNT(count_check_bound);
1294 COUNT(count_pcmd_mem);
1296 bte = builtintable_get_internal(BUILTIN_canstore);
1299 if (md->memuse > rd->memuse)
1300 rd->memuse = md->memuse;
1301 if (md->argintreguse > rd->argintreguse)
1302 rd->argintreguse = md->argintreguse;
1304 /* make all stack variables saved */
1308 copy->flags |= SAVEDVAR;
1319 COUNT(count_check_null);
1320 COUNT(count_check_bound);
1321 COUNT(count_pcmd_mem);
1322 OP3TIA_0(opcode - ICMD_IASTORE);
1328 COUNT(count_check_null);
1329 COUNT(count_check_bound);
1330 COUNT(count_pcmd_mem);
1337 #ifdef ENABLE_VERIFIER
1340 if (IS_2_WORD_TYPE(curstack->type))
1341 goto throw_stack_category_error;
1352 #if defined(ENABLE_JIT)
1353 # if defined(ENABLE_INTRP)
1356 md_return_alloc(m, rd, opcode - ICMD_IRETURN,
1359 COUNT(count_pcmd_return);
1360 OP1_0(opcode - ICMD_IRETURN);
1361 superblockend = true;
1365 COUNT(count_check_null);
1369 superblockend = true;
1372 case ICMD_PUTSTATIC:
1373 COUNT(count_pcmd_mem);
1377 /* pop 1 push 0 branch */
1380 case ICMD_IFNONNULL:
1381 COUNT(count_pcmd_bra);
1383 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1385 iptr[0].target = (void *) tbptr;
1387 MARKREACHED(tbptr, copy);
1396 COUNT(count_pcmd_bra);
1397 #if CONDITIONAL_LOADCONST
1398 # if defined(ENABLE_INTRP)
1401 tbptr = m->basicblocks + b_index;
1402 if ((b_count >= 3) &&
1403 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1404 (tbptr[1].pre_count == 1) &&
1405 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1406 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1407 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1408 (tbptr[2].pre_count == 1) &&
1409 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1410 (tbptr[2].icount==1)) {
1411 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1412 OP1_1(TYPE_INT, TYPE_INT);
1413 switch (iptr[0].opc) {
1415 iptr[0].opc = ICMD_IFNE_ICONST;
1418 iptr[0].opc = ICMD_IFEQ_ICONST;
1421 iptr[0].opc = ICMD_IFGE_ICONST;
1424 iptr[0].opc = ICMD_IFLT_ICONST;
1427 iptr[0].opc = ICMD_IFLE_ICONST;
1430 iptr[0].opc = ICMD_IFGT_ICONST;
1434 iptr[0].val.i = iptr[1].val.i;
1435 iptr[1].opc = ICMD_ELSE_ICONST;
1436 iptr[1].val.i = iptr[3].val.i;
1437 iptr[2].opc = ICMD_NOP;
1438 iptr[3].opc = ICMD_NOP;
1440 /* HACK: save compare value in iptr[1].op1 */
1441 iptr[1].op1 = iptr[0].val.i;
1442 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1443 iptr[1].opc = ICMD_ELSE_ICONST;
1444 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1445 tbptr[1].iinstr[0].opc = ICMD_NOP;
1446 tbptr[1].iinstr[1].opc = ICMD_NOP;
1447 tbptr[2].iinstr[0].opc = ICMD_NOP;
1449 tbptr[1].flags = BBDELETED;
1450 tbptr[2].flags = BBDELETED;
1451 tbptr[1].icount = 0;
1452 tbptr[2].icount = 0;
1453 if (tbptr[3].pre_count == 2) {
1454 len += tbptr[3].icount + 3;
1455 bptr->icount += tbptr[3].icount + 3;
1456 tbptr[3].flags = BBDELETED;
1457 tbptr[3].icount = 0;
1467 # if defined(ENABLE_INTRP)
1471 #endif /* CONDITIONAL_LOADCONST */
1475 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1477 iptr[0].target = (void *) tbptr;
1479 MARKREACHED(tbptr, copy);
1482 /* pop 0 push 0 branch */
1485 COUNT(count_pcmd_bra);
1486 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1488 iptr[0].target = (void *) tbptr;
1490 MARKREACHED(tbptr, copy);
1492 superblockend = true;
1495 /* pop 1 push 0 table branch */
1497 case ICMD_TABLESWITCH:
1498 COUNT(count_pcmd_table);
1500 s4ptr = iptr->val.a;
1501 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1502 MARKREACHED(tbptr, copy);
1503 i = *s4ptr++; /* low */
1504 i = *s4ptr++ - i + 1; /* high */
1506 tptr = DMNEW(void*, i+1);
1507 iptr->target = (void *) tptr;
1509 tptr[0] = (void *) tbptr;
1513 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1515 tptr[0] = (void *) tbptr;
1518 MARKREACHED(tbptr, copy);
1521 superblockend = true;
1524 /* pop 1 push 0 table branch */
1526 case ICMD_LOOKUPSWITCH:
1527 COUNT(count_pcmd_table);
1529 s4ptr = iptr->val.a;
1530 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1531 MARKREACHED(tbptr, copy);
1532 i = *s4ptr++; /* count */
1534 tptr = DMNEW(void*, i+1);
1535 iptr->target = (void *) tptr;
1537 tptr[0] = (void *) tbptr;
1541 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1543 tptr[0] = (void *) tbptr;
1546 MARKREACHED(tbptr, copy);
1550 superblockend = true;
1553 case ICMD_MONITORENTER:
1554 COUNT(count_check_null);
1555 case ICMD_MONITOREXIT:
1559 /* pop 2 push 0 branch */
1561 case ICMD_IF_ICMPEQ:
1562 case ICMD_IF_ICMPNE:
1563 case ICMD_IF_ICMPLT:
1564 case ICMD_IF_ICMPGE:
1565 case ICMD_IF_ICMPGT:
1566 case ICMD_IF_ICMPLE:
1567 COUNT(count_pcmd_bra);
1569 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1571 iptr[0].target = (void *) tbptr;
1573 MARKREACHED(tbptr, copy);
1576 case ICMD_IF_ACMPEQ:
1577 case ICMD_IF_ACMPNE:
1578 COUNT(count_pcmd_bra);
1580 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1582 iptr[0].target = (void *) tbptr;
1584 MARKREACHED(tbptr, copy);
1590 COUNT(count_check_null);
1591 COUNT(count_pcmd_mem);
1592 OPTT2_0(iptr->op1,TYPE_ADR);
1597 if (!IS_2_WORD_TYPE(curstack->type)) {
1599 #ifdef ENABLE_VERIFIER
1602 if (IS_2_WORD_TYPE(curstack->prev->type))
1603 goto throw_stack_category_error;
1606 OP1_0ANY; /* second pop */
1609 iptr->opc = ICMD_POP;
1613 /* pop 0 push 1 dup */
1616 #ifdef ENABLE_VERIFIER
1619 if (IS_2_WORD_TYPE(curstack->type))
1620 goto throw_stack_category_error;
1623 last_dupx = bptr->icount - len - 1;
1624 COUNT(count_dup_instruction);
1629 last_dupx = bptr->icount - len - 1;
1631 if (IS_2_WORD_TYPE(curstack->type)) {
1633 iptr->opc = ICMD_DUP;
1638 /* ..., ????, cat1 */
1639 #ifdef ENABLE_VERIFIER
1641 if (IS_2_WORD_TYPE(curstack->prev->type))
1642 goto throw_stack_category_error;
1646 NEWSTACK(copy->prev->type, copy->prev->varkind,
1647 copy->prev->varnum);
1648 NEWSTACK(copy->type, copy->varkind,
1655 /* pop 2 push 3 dup */
1658 #ifdef ENABLE_VERIFIER
1661 if (IS_2_WORD_TYPE(curstack->type) ||
1662 IS_2_WORD_TYPE(curstack->prev->type))
1663 goto throw_stack_category_error;
1666 last_dupx = bptr->icount - len - 1;
1671 last_dupx = bptr->icount - len - 1;
1673 if (IS_2_WORD_TYPE(curstack->type)) {
1674 /* ..., ????, cat2 */
1675 #ifdef ENABLE_VERIFIER
1677 if (IS_2_WORD_TYPE(curstack->prev->type))
1678 goto throw_stack_category_error;
1681 iptr->opc = ICMD_DUP_X1;
1685 /* ..., ????, cat1 */
1686 #ifdef ENABLE_VERIFIER
1689 if (IS_2_WORD_TYPE(curstack->prev->type)
1690 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1691 goto throw_stack_category_error;
1698 /* pop 3 push 4 dup */
1701 last_dupx = bptr->icount - len - 1;
1703 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1704 /* ..., cat2, ???? */
1705 #ifdef ENABLE_VERIFIER
1707 if (IS_2_WORD_TYPE(curstack->type))
1708 goto throw_stack_category_error;
1711 iptr->opc = ICMD_DUP_X1;
1715 /* ..., cat1, ???? */
1716 #ifdef ENABLE_VERIFIER
1719 if (IS_2_WORD_TYPE(curstack->type)
1720 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1721 goto throw_stack_category_error;
1729 last_dupx = bptr->icount - len - 1;
1731 if (IS_2_WORD_TYPE(curstack->type)) {
1732 /* ..., ????, cat2 */
1733 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1734 /* ..., cat2, cat2 */
1735 iptr->opc = ICMD_DUP_X1;
1739 /* ..., cat1, cat2 */
1740 #ifdef ENABLE_VERIFIER
1743 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
1744 goto throw_stack_category_error;
1747 iptr->opc = ICMD_DUP_X2;
1753 /* ..., ????, ????, cat1 */
1754 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1755 /* ..., cat2, ????, cat1 */
1756 #ifdef ENABLE_VERIFIER
1758 if (IS_2_WORD_TYPE(curstack->prev->type))
1759 goto throw_stack_category_error;
1762 iptr->opc = ICMD_DUP2_X1;
1766 /* ..., cat1, ????, cat1 */
1767 #ifdef ENABLE_VERIFIER
1770 if (IS_2_WORD_TYPE(curstack->prev->type)
1771 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
1772 goto throw_stack_category_error;
1780 /* pop 2 push 2 swap */
1783 last_dupx = bptr->icount - len - 1;
1784 #ifdef ENABLE_VERIFIER
1787 if (IS_2_WORD_TYPE(curstack->type)
1788 || IS_2_WORD_TYPE(curstack->prev->type))
1789 goto throw_stack_category_error;
1799 #if !SUPPORT_DIVISION
1800 bte = (builtintable_entry *) iptr->val.a;
1804 if (md->memuse > rd->memuse)
1805 rd->memuse = md->memuse;
1806 if (md->argintreguse > rd->argintreguse)
1807 rd->argintreguse = md->argintreguse;
1809 /* make all stack variables saved */
1813 copy->flags |= SAVEDVAR;
1818 #endif /* !SUPPORT_DIVISION */
1829 COUNT(count_pcmd_op);
1835 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1836 bte = (builtintable_entry *) iptr->val.a;
1840 if (md->memuse > rd->memuse)
1841 rd->memuse = md->memuse;
1842 if (md->argintreguse > rd->argintreguse)
1843 rd->argintreguse = md->argintreguse;
1845 /* make all stack variables saved */
1849 copy->flags |= SAVEDVAR;
1854 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
1859 #if SUPPORT_LONG_LOGICAL
1863 #endif /* SUPPORT_LONG_LOGICAL */
1864 COUNT(count_pcmd_op);
1871 COUNT(count_pcmd_op);
1880 COUNT(count_pcmd_op);
1889 COUNT(count_pcmd_op);
1894 COUNT(count_pcmd_op);
1895 #if SUPPORT_LONG_CMP_CONST
1896 if ((len > 0) && (iptr[1].val.i == 0)) {
1897 switch (iptr[1].opc) {
1899 iptr[0].opc = ICMD_IF_LCMPEQ;
1901 iptr[0].op1 = iptr[1].op1;
1904 /* iptr[1].opc = ICMD_NOP; */
1906 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1908 iptr[0].target = (void *) tbptr;
1910 MARKREACHED(tbptr, copy);
1911 COUNT(count_pcmd_bra);
1914 iptr[0].opc = ICMD_IF_LCMPNE;
1915 goto icmd_lcmp_if_tail;
1917 iptr[0].opc = ICMD_IF_LCMPLT;
1918 goto icmd_lcmp_if_tail;
1920 iptr[0].opc = ICMD_IF_LCMPGT;
1921 goto icmd_lcmp_if_tail;
1923 iptr[0].opc = ICMD_IF_LCMPLE;
1924 goto icmd_lcmp_if_tail;
1926 iptr[0].opc = ICMD_IF_LCMPGE;
1927 goto icmd_lcmp_if_tail;
1929 OPTT2_1(TYPE_LNG, TYPE_INT);
1933 #endif /* SUPPORT_LONG_CMP_CONST */
1934 OPTT2_1(TYPE_LNG, TYPE_INT);
1938 COUNT(count_pcmd_op);
1939 OPTT2_1(TYPE_FLT, TYPE_INT);
1943 COUNT(count_pcmd_op);
1944 OPTT2_1(TYPE_DBL, TYPE_INT);
1952 case ICMD_INT2SHORT:
1953 COUNT(count_pcmd_op);
1954 OP1_1(TYPE_INT, TYPE_INT);
1957 COUNT(count_pcmd_op);
1958 OP1_1(TYPE_LNG, TYPE_LNG);
1961 COUNT(count_pcmd_op);
1962 OP1_1(TYPE_FLT, TYPE_FLT);
1965 COUNT(count_pcmd_op);
1966 OP1_1(TYPE_DBL, TYPE_DBL);
1970 COUNT(count_pcmd_op);
1971 OP1_1(TYPE_INT, TYPE_LNG);
1974 COUNT(count_pcmd_op);
1975 OP1_1(TYPE_INT, TYPE_FLT);
1978 COUNT(count_pcmd_op);
1979 OP1_1(TYPE_INT, TYPE_DBL);
1982 COUNT(count_pcmd_op);
1983 OP1_1(TYPE_LNG, TYPE_INT);
1986 COUNT(count_pcmd_op);
1987 OP1_1(TYPE_LNG, TYPE_FLT);
1990 COUNT(count_pcmd_op);
1991 OP1_1(TYPE_LNG, TYPE_DBL);
1994 COUNT(count_pcmd_op);
1995 OP1_1(TYPE_FLT, TYPE_INT);
1998 COUNT(count_pcmd_op);
1999 OP1_1(TYPE_FLT, TYPE_LNG);
2002 COUNT(count_pcmd_op);
2003 OP1_1(TYPE_FLT, TYPE_DBL);
2006 COUNT(count_pcmd_op);
2007 OP1_1(TYPE_DBL, TYPE_INT);
2010 COUNT(count_pcmd_op);
2011 OP1_1(TYPE_DBL, TYPE_LNG);
2014 COUNT(count_pcmd_op);
2015 OP1_1(TYPE_DBL, TYPE_FLT);
2018 case ICMD_CHECKCAST:
2019 if (iptr->op1 == 0) {
2020 /* array type cast-check */
2022 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2025 if (md->memuse > rd->memuse)
2026 rd->memuse = md->memuse;
2027 if (md->argintreguse > rd->argintreguse)
2028 rd->argintreguse = md->argintreguse;
2030 /* make all stack variables saved */
2034 copy->flags |= SAVEDVAR;
2038 OP1_1(TYPE_ADR, TYPE_ADR);
2041 case ICMD_INSTANCEOF:
2042 case ICMD_ARRAYLENGTH:
2043 OP1_1(TYPE_ADR, TYPE_INT);
2047 case ICMD_ANEWARRAY:
2048 OP1_1(TYPE_INT, TYPE_ADR);
2052 COUNT(count_check_null);
2053 COUNT(count_pcmd_mem);
2054 OP1_1(TYPE_ADR, iptr->op1);
2059 case ICMD_GETSTATIC:
2060 COUNT(count_pcmd_mem);
2070 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
2072 iptr[0].target = (void *) tbptr;
2074 /* This is a dirty hack. The typechecker
2075 * needs it because the OP1_0ANY below
2076 * overwrites iptr->dst.
2078 iptr->val.a = (void *) iptr->dst;
2080 tbptr->type = BBTYPE_SBR;
2082 /* We need to check for overflow right here because
2083 * the pushed value is poped after MARKREACHED. */
2085 MARKREACHED(tbptr, copy);
2089 /* pop many push any */
2092 #if defined(USEBUILTINTABLE)
2095 bte = (builtintable_entry *) iptr->val.a;
2099 case ICMD_INVOKESTATIC:
2100 case ICMD_INVOKESPECIAL:
2101 case ICMD_INVOKEVIRTUAL:
2102 case ICMD_INVOKEINTERFACE:
2103 COUNT(count_pcmd_met);
2105 md = um->methodref->parseddesc.md;
2106 /* if (lm->flags & ACC_STATIC) */
2107 /* {COUNT(count_check_null);} */
2111 last_pei = bptr->icount - len - 1;
2115 if (md->memuse > rd->memuse)
2116 rd->memuse = md->memuse;
2117 if (md->argintreguse > rd->argintreguse)
2118 rd->argintreguse = md->argintreguse;
2119 if (md->argfltreguse > rd->argfltreguse)
2120 rd->argfltreguse = md->argfltreguse;
2125 for (i-- ; i >= 0; i--) {
2126 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2127 /* If we pass float arguments in integer argument registers, we
2128 * are not allowed to precolor them here. Floats have to be moved
2129 * to this regs explicitly in codegen().
2130 * Only arguments that are passed by stack anyway can be precolored
2131 * (michi 2005/07/24) */
2132 if (!(copy->flags & SAVEDVAR) &&
2133 (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
2135 if (!(copy->flags & SAVEDVAR)) {
2137 copy->varkind = ARGVAR;
2140 #if defined(ENABLE_INTRP)
2143 if (md->params[i].inmemory) {
2144 copy->flags = INMEMORY;
2145 copy->regoff = md->params[i].regoff;
2148 if (IS_FLT_DBL_TYPE(copy->type))
2149 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2150 assert(0); /* XXX is this assert ok? */
2153 rd->argfltregs[md->params[i].regoff];
2156 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2157 if (IS_2_WORD_TYPE(copy->type))
2158 copy->regoff = PACK_REGS(
2159 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2160 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2164 rd->argintregs[md->params[i].regoff];
2167 #if defined(ENABLE_INTRP)
2175 copy->flags |= SAVEDVAR;
2181 if (md->returntype.type != TYPE_VOID)
2182 OP0_1(md->returntype.type);
2185 case ICMD_INLINE_START:
2186 case ICMD_INLINE_END:
2190 case ICMD_MULTIANEWARRAY:
2191 if (rd->argintreguse < 3)
2192 rd->argintreguse = 3;
2197 #if defined(SPECIALMEMUSE)
2198 # if defined(__DARWIN__)
2199 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
2200 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
2202 if (rd->memuse < (i + LA_WORD_SIZE + 3))
2203 rd->memuse = i + LA_WORD_SIZE + 3;
2206 # if defined(__I386__)
2207 if (rd->memuse < i + 3)
2208 rd->memuse = i + 3; /* n integer args spilled on stack */
2209 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2210 if (rd->memuse < i + 2)
2211 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2214 rd->memuse = i; /* n integer args spilled on stack */
2215 # endif /* defined(__I386__) */
2219 /* check INT type here? Currently typecheck does this. */
2220 if (!(copy->flags & SAVEDVAR)) {
2221 copy->varkind = ARGVAR;
2222 copy->varnum = i + INT_ARG_CNT;
2223 copy->flags |= INMEMORY;
2224 #if defined(SPECIALMEMUSE)
2225 # if defined(__DARWIN__)
2226 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
2228 copy->regoff = i + LA_WORD_SIZE + 3;
2231 # if defined(__I386__)
2232 copy->regoff = i + 3;
2233 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2234 copy->regoff = i + 2;
2237 # endif /* defined(__I386__) */
2238 #endif /* defined(SPECIALMEMUSE) */
2243 copy->flags |= SAVEDVAR;
2253 new_internalerror("Unknown ICMD %d", opcode);
2259 } /* while instructions */
2261 /* set out-stack of block */
2263 bptr->outstack = curstack;
2264 bptr->outdepth = stackdepth;
2266 /* stack slots at basic block end become interfaces */
2269 for (copy = curstack; copy; i--, copy = copy->prev) {
2270 if ((copy->varkind == STACKVAR) && (copy->varnum > i))
2271 copy->varkind = TEMPVAR;
2273 copy->varkind = STACKVAR;
2277 rd->interfaces[i][copy->type].type = copy->type;
2278 rd->interfaces[i][copy->type].flags |= copy->flags;
2282 /* check if interface slots at basic block begin must be saved */
2285 i = bptr->indepth - 1;
2286 for (copy = bptr->instack; copy; i--, copy = copy->prev) {
2287 rd->interfaces[i][copy->type].type = copy->type;
2288 if (copy->varkind == STACKVAR) {
2289 if (copy->flags & SAVEDVAR)
2290 rd->interfaces[i][copy->type].flags |= SAVEDVAR;
2297 superblockend = true;
2299 } /* while blocks */
2300 } while (repeat && !deadcode);
2302 #if defined(ENABLE_STATISTICS)
2304 if (m->basicblockcount > count_max_basic_blocks)
2305 count_max_basic_blocks = m->basicblockcount;
2306 count_basic_blocks += m->basicblockcount;
2307 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2308 count_javainstr += m->instructioncount;
2309 if (m->stackcount > count_upper_bound_new_stack)
2310 count_upper_bound_new_stack = m->stackcount;
2311 if ((new - m->stack) > count_max_new_stack)
2312 count_max_new_stack = (new - m->stack);
2314 b_count = m->basicblockcount;
2315 bptr = m->basicblocks;
2316 while (--b_count >= 0) {
2317 if (bptr->flags > BBREACHED) {
2318 if (bptr->indepth >= 10)
2319 count_block_stack[10]++;
2321 count_block_stack[bptr->indepth]++;
2324 count_block_size_distribution[len]++;
2326 count_block_size_distribution[10]++;
2328 count_block_size_distribution[11]++;
2330 count_block_size_distribution[12]++;
2332 count_block_size_distribution[13]++;
2334 count_block_size_distribution[14]++;
2336 count_block_size_distribution[15]++;
2338 count_block_size_distribution[16]++;
2340 count_block_size_distribution[17]++;
2346 count_analyse_iterations[0]++;
2347 else if (loops == 2)
2348 count_analyse_iterations[1]++;
2349 else if (loops == 3)
2350 count_analyse_iterations[2]++;
2351 else if (loops == 4)
2352 count_analyse_iterations[3]++;
2354 count_analyse_iterations[4]++;
2356 if (m->basicblockcount <= 5)
2357 count_method_bb_distribution[0]++;
2358 else if (m->basicblockcount <= 10)
2359 count_method_bb_distribution[1]++;
2360 else if (m->basicblockcount <= 15)
2361 count_method_bb_distribution[2]++;
2362 else if (m->basicblockcount <= 20)
2363 count_method_bb_distribution[3]++;
2364 else if (m->basicblockcount <= 30)
2365 count_method_bb_distribution[4]++;
2366 else if (m->basicblockcount <= 40)
2367 count_method_bb_distribution[5]++;
2368 else if (m->basicblockcount <= 50)
2369 count_method_bb_distribution[6]++;
2370 else if (m->basicblockcount <= 75)
2371 count_method_bb_distribution[7]++;
2373 count_method_bb_distribution[8]++;
2375 #endif /* defined(ENABLE_STATISTICS) */
2377 /* just return methodinfo* to signal everything was ok */
2381 #if defined(ENABLE_VERIFIER)
2382 throw_stack_underflow:
2384 new_verifyerror(m, "Unable to pop operand off an empty stack");
2387 throw_stack_overflow:
2388 *exceptionptr = new_verifyerror(m, "Stack size too large");
2391 throw_stack_type_error:
2392 exceptions_throw_verifyerror_for_stack(m, expectedtype);
2395 throw_stack_category_error:
2396 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
2402 /* debugging helpers **********************************************************/
2404 /* stack_print *****************************************************************
2406 Print the stack representation starting with the given top stackptr.
2408 NOTE: Currently this function may only be called after register allocation!
2410 *******************************************************************************/
2412 void stack_print(codegendata *cd, stackptr s)
2424 j = cd->maxstack - i;
2430 if (s->flags & SAVEDVAR)
2431 switch (s->varkind) {
2433 if (s->flags & INMEMORY)
2434 printf(" M%02d", s->regoff);
2435 #ifdef HAS_ADDRESS_REGISTER_FILE
2436 else if (s->type == TYPE_ADR)
2437 printf(" R%02d", s->regoff);
2439 else if (IS_FLT_DBL_TYPE(s->type))
2440 printf(" F%02d", s->regoff);
2442 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2443 if (IS_2_WORD_TYPE(s->type)) {
2444 # if defined(ENABLE_JIT)
2445 # if defined(ENABLE_INTRP)
2447 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2448 GET_HIGH_REG(s->regoff));
2451 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2452 regs[GET_HIGH_REG(s->regoff)]);
2454 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2455 GET_HIGH_REG(s->regoff));
2458 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
2460 #if defined(ENABLE_JIT)
2461 # if defined(ENABLE_INTRP)
2463 printf(" %3d", s->regoff);
2466 printf(" %3s", regs[s->regoff]);
2468 printf(" %3d", s->regoff);
2474 printf(" I%02d", s->varnum);
2477 printf(" L%02d", s->varnum);
2480 if (s->varnum == -1) {
2482 /* varkind ARGVAR "misused for this special case */
2484 } else /* "normal" Argvar */
2485 printf(" A%02d", s->varnum);
2488 printf(" !%02d", j);
2491 switch (s->varkind) {
2493 if (s->flags & INMEMORY)
2494 printf(" m%02d", s->regoff);
2495 #ifdef HAS_ADDRESS_REGISTER_FILE
2496 else if (s->type == TYPE_ADR)
2497 printf(" r%02d", s->regoff);
2499 else if (IS_FLT_DBL_TYPE(s->type))
2500 printf(" f%02d", s->regoff);
2502 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2503 if (IS_2_WORD_TYPE(s->type)) {
2504 # if defined(ENABLE_JIT)
2505 # if defined(ENABLE_INTRP)
2507 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2508 GET_HIGH_REG(s->regoff));
2511 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2512 regs[GET_HIGH_REG(s->regoff)]);
2514 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2515 GET_HIGH_REG(s->regoff));
2518 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
2520 #if defined(ENABLE_JIT)
2521 # if defined(ENABLE_INTRP)
2523 printf(" %3d", s->regoff);
2526 printf(" %3s", regs[s->regoff]);
2528 printf(" %3d", s->regoff);
2534 printf(" i%02d", s->varnum);
2537 printf(" l%02d", s->varnum);
2540 if (s->varnum == -1) {
2542 /* varkind ARGVAR "misused for this special case */
2544 } else /* "normal" Argvar */
2545 printf(" a%02d", s->varnum);
2548 printf(" ?%02d", j);
2556 static void print_reg(stackptr s) {
2558 if (s->flags & SAVEDVAR)
2559 switch (s->varkind) {
2561 if (s->flags & INMEMORY)
2562 printf(" tm%02d", s->regoff);
2564 printf(" tr%02d", s->regoff);
2567 printf(" s %02d", s->varnum);
2570 printf(" l %02d", s->varnum);
2573 printf(" a %02d", s->varnum);
2576 printf(" ! %02d", s->varnum);
2579 switch (s->varkind) {
2581 if (s->flags & INMEMORY)
2582 printf(" Tm%02d", s->regoff);
2584 printf(" Tr%02d", s->regoff);
2587 printf(" S %02d", s->varnum);
2590 printf(" L %02d", s->varnum);
2593 printf(" A %02d", s->varnum);
2596 printf(" ? %02d", s->varnum);
2606 #if !defined(NDEBUG)
2607 static char *jit_type[] = {
2617 /* show_icmd_method ************************************************************
2619 Print the intermediate representation of a method.
2621 NOTE: Currently this function may only be called after register allocation!
2623 *******************************************************************************/
2625 #if !defined(NDEBUG)
2626 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2634 #if defined(USE_THREADS)
2635 /* We need to enter a lock here, since the binutils disassembler
2636 is not reentrant-able and we could not read functions printed
2637 at the same time. */
2639 builtin_monitorenter(lock_show_icmd);
2648 printf("\nBasic blocks: %d\n", m->basicblockcount);
2649 printf("Max locals: %d\n", cd->maxlocals);
2650 printf("Max stack: %d\n", cd->maxstack);
2651 printf("Line number table length: %d\n", m->linenumbercount);
2653 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2654 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2655 printf(" L%03d ... ", ex->start->debug_nr );
2656 printf("L%03d = ", ex->end->debug_nr);
2657 printf("L%03d", ex->handler->debug_nr);
2658 printf(" (catchtype: ");
2659 if (ex->catchtype.any)
2660 if (IS_CLASSREF(ex->catchtype))
2661 utf_display_classname(ex->catchtype.ref->name);
2663 utf_display_classname(ex->catchtype.cls->name);
2669 printf("Local Table:\n");
2670 for (i = 0; i < cd->maxlocals; i++) {
2671 printf(" %3d: ", i);
2673 #if defined(ENABLE_JIT)
2674 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
2675 # if defined(ENABLE_INTRP)
2678 if (rd->locals[i][j].type >= 0) {
2679 printf(" (%s) ", jit_type[j]);
2680 if (rd->locals[i][j].flags & INMEMORY)
2681 printf("m%2d", rd->locals[i][j].regoff);
2682 # ifdef HAS_ADDRESS_REGISTER_FILE
2683 else if (j == TYPE_ADR)
2684 printf("r%02d", rd->locals[i][j].regoff);
2686 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2687 printf("f%02d", rd->locals[i][j].regoff);
2689 # if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2690 if (IS_2_WORD_TYPE(j))
2692 regs[GET_LOW_REG(rd->locals[i][j].regoff)],
2693 regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
2696 printf("%3s", regs[rd->locals[i][j].regoff]);
2699 # if defined(ENABLE_INTRP)
2703 #endif /* defined(ENABLE_JIT) */
2709 #if defined(ENABLE_LSRA)
2712 #if defined(ENABLE_INTRP)
2715 printf("Interface Table:\n");
2716 for (i = 0; i < cd->maxstack; i++) {
2717 if ((rd->interfaces[i][0].type >= 0) ||
2718 (rd->interfaces[i][1].type >= 0) ||
2719 (rd->interfaces[i][2].type >= 0) ||
2720 (rd->interfaces[i][3].type >= 0) ||
2721 (rd->interfaces[i][4].type >= 0)) {
2722 printf(" %3d: ", i);
2724 #if defined(ENABLE_JIT)
2725 # if defined(ENABLE_INTRP)
2728 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
2729 if (rd->interfaces[i][j].type >= 0) {
2730 printf(" (%s) ", jit_type[j]);
2731 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2732 if (rd->interfaces[i][j].flags & INMEMORY)
2733 printf("M%2d", rd->interfaces[i][j].regoff);
2734 #ifdef HAS_ADDRESS_REGISTER_FILE
2735 else if (j == TYPE_ADR)
2736 printf("R%02d", rd->interfaces[i][j].regoff);
2738 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2739 printf("F%02d", rd->interfaces[i][j].regoff);
2741 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2742 if (IS_2_WORD_TYPE(j))
2744 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2745 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2748 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2752 if (rd->interfaces[i][j].flags & INMEMORY)
2753 printf("m%2d", rd->interfaces[i][j].regoff);
2754 #ifdef HAS_ADDRESS_REGISTER_FILE
2755 else if (j == TYPE_ADR)
2756 printf("r%02d", rd->interfaces[i][j].regoff);
2758 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2759 printf("f%02d", rd->interfaces[i][j].regoff);
2761 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2762 if (IS_2_WORD_TYPE(j))
2764 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2765 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2768 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2774 # if defined(ENABLE_INTRP)
2777 #endif /* defined(ENABLE_JIT) */
2783 #if defined(ENABLE_INTRP)
2786 #if defined(ENABLE_LSRA)
2790 if (code->rplpoints) {
2791 printf("Replacement Points:\n");
2792 replace_show_replacement_points(code);
2796 /* show code before first basic block */
2798 if (opt_showdisassemble) {
2799 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
2801 for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + m->basicblocks[0].mpc);)
2807 /* show code of all basic blocks */
2809 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2810 show_icmd_block(m, cd, bptr);
2813 /* show stubs code */
2815 if (opt_showdisassemble && opt_showexceptionstubs) {
2816 printf("\nException stubs code:\n");
2817 printf("Length: %d\n\n", (s4) (code->mcodelength -
2818 ((ptrint) cd->dseglen +
2819 m->basicblocks[m->basicblockcount].mpc)));
2821 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen +
2822 m->basicblocks[m->basicblockcount].mpc);
2824 for (; (ptrint) u1ptr < ((ptrint) code->mcode + code->mcodelength);)
2830 #if defined(USE_THREADS)
2831 builtin_monitorexit(lock_show_icmd);
2834 #endif /* !defined(NDEBUG) */
2837 /* show_icmd_block *************************************************************
2839 Print the intermediate representation of a basic block.
2841 NOTE: Currently this function may only be called after register allocation!
2843 *******************************************************************************/
2845 #if !defined(NDEBUG)
2846 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2853 if (bptr->flags != BBDELETED) {
2854 deadcode = bptr->flags <= BBREACHED;
2859 for (j = cd->maxstack; j > 0; j--)
2862 stack_print(cd, bptr->instack);
2864 printf("] %sL%03d(flags: %d, bitflags: %01x, next: %d, type: ",
2865 (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : "",
2866 bptr->debug_nr, bptr->flags, bptr->bitflags,
2867 (bptr->next) ? (bptr->next->debug_nr) : -1);
2869 switch (bptr->type) {
2881 printf(", instruction count: %d, predecessors: %d):\n",
2882 bptr->icount, bptr->pre_count);
2884 iptr = bptr->iinstr;
2886 for (i = 0; i < bptr->icount; i++, iptr++) {
2890 for (j = cd->maxstack; j > 0; j--)
2893 stack_print(cd, iptr->dst);
2895 printf("] %5d (line: %5d) ", i, iptr->line);
2897 show_icmd(iptr, deadcode);
2901 if (opt_showdisassemble && (!deadcode)) {
2903 u1ptr = (u1 *) ((ptrint) cd->code->mcode + cd->dseglen + bptr->mpc);
2905 if (bptr->next != NULL) {
2906 for (; u1ptr < (u1 *) ((ptrint) cd->code->mcode + cd->dseglen + bptr->next->mpc);)
2910 for (; u1ptr < (u1 *) ((ptrint) cd->code->mcode + cd->code->mcodelength);)
2917 #endif /* !defined(NDEBUG) */
2920 /* show_icmd *******************************************************************
2922 Print the intermediate representation of an instruction.
2924 NOTE: Currently this function may only be called after register allocation!
2926 *******************************************************************************/
2928 #if !defined(NDEBUG)
2929 void show_icmd(instruction *iptr, bool deadcode)
2935 printf("%s", icmd_names[iptr->opc]);
2937 switch (iptr->opc) {
2938 case ICMD_IADDCONST:
2939 case ICMD_ISUBCONST:
2940 case ICMD_IMULCONST:
2944 case ICMD_IANDCONST:
2946 case ICMD_IXORCONST:
2947 case ICMD_ISHLCONST:
2948 case ICMD_ISHRCONST:
2949 case ICMD_IUSHRCONST:
2950 case ICMD_LSHLCONST:
2951 case ICMD_LSHRCONST:
2952 case ICMD_LUSHRCONST:
2954 case ICMD_IASTORECONST:
2955 case ICMD_BASTORECONST:
2956 case ICMD_CASTORECONST:
2957 case ICMD_SASTORECONST:
2958 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2961 case ICMD_IFEQ_ICONST:
2962 case ICMD_IFNE_ICONST:
2963 case ICMD_IFLT_ICONST:
2964 case ICMD_IFGE_ICONST:
2965 case ICMD_IFGT_ICONST:
2966 case ICMD_IFLE_ICONST:
2967 printf(" %d, %d (0x%08x)", iptr[1].op1, iptr->val.i, iptr->val.i);
2970 case ICMD_ELSE_ICONST:
2971 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2974 case ICMD_LADDCONST:
2975 case ICMD_LSUBCONST:
2976 case ICMD_LMULCONST:
2980 case ICMD_LANDCONST:
2982 case ICMD_LXORCONST:
2984 case ICMD_LASTORECONST:
2985 #if SIZEOF_VOID_P == 4
2986 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
2988 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
2993 printf(" %f (0x%08x)", iptr->val.f, iptr->val.i);
2997 #if SIZEOF_VOID_P == 4
2998 printf(" %g (0x%016llx)", iptr->val.d, iptr->val.l);
3000 printf(" %g (0x%016lx)", iptr->val.d, iptr->val.l);
3005 case ICMD_AASTORECONST:
3006 /* check if this is a constant string or a class reference */
3010 printf(" %p", iptr->val.a);
3012 printf(" (NOT RESOLVED)");
3014 printf(", Class = \"");
3015 utf_display(((constant_classref *) iptr->target)->name);
3019 printf(" %p", iptr->val.a);
3021 printf(", String = \"");
3022 utf_display(javastring_toutf(iptr->val.a, false));
3031 printf(" %d, ", ((fieldinfo *) iptr->val.a)->offset);
3033 printf(" (NOT RESOLVED), ");
3034 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
3036 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
3038 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
3042 case ICMD_PUTSTATIC:
3043 case ICMD_GETSTATIC:
3045 if (!CLASS_IS_OR_ALMOST_INITIALIZED(((fieldinfo *) iptr->val.a)->class))
3046 printf(" (NOT INITIALIZED) ");
3050 printf(" (NOT RESOLVED) ");
3051 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
3053 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
3055 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
3059 case ICMD_PUTSTATICCONST:
3060 case ICMD_PUTFIELDCONST:
3061 switch (iptr[1].op1) {
3063 printf(" %d (0x%08x),", iptr->val.i, iptr->val.i);
3066 #if SIZEOF_VOID_P == 4
3067 printf(" %lld (0x%016llx),", iptr->val.l, iptr->val.l);
3069 printf(" %ld (0x%016lx),", iptr->val.l, iptr->val.l);
3073 printf(" %p,", iptr->val.a);
3076 printf(" %g (0x%08x),", iptr->val.f, iptr->val.i);
3079 #if SIZEOF_VOID_P == 4
3080 printf(" %g (0x%016llx),", iptr->val.d, iptr->val.l);
3082 printf(" %g (0x%016lx),", iptr->val.d, iptr->val.l);
3086 if (iptr->opc == ICMD_PUTFIELDCONST) {
3088 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
3090 printf(" (NOT RESOLVED),");
3093 utf_display_classname(((unresolved_field *) iptr[1].target)->fieldref->classref->name);
3095 utf_display(((unresolved_field *) iptr[1].target)->fieldref->name);
3097 utf_display(((unresolved_field *) iptr[1].target)->fieldref->descriptor);
3102 printf(" %d + %d", iptr->op1, iptr->val.i);
3137 printf(" %d", iptr->op1);
3142 utf_display_classname(((classinfo *) iptr->val.a)->name);
3146 switch (iptr->op1) {
3174 case ICMD_ANEWARRAY:
3177 utf_display_classname(((classinfo *) iptr->val.a)->name);
3181 case ICMD_MULTIANEWARRAY:
3182 if (iptr->val.a == NULL) {
3183 printf(" (NOT RESOLVED) %d ", iptr->op1);
3184 utf_display(((constant_classref *) iptr->target)->name);
3186 printf(" %d ",iptr->op1);
3187 utf_display_classname(((classinfo *) iptr->val.a)->name);
3191 case ICMD_CHECKCAST:
3192 case ICMD_INSTANCEOF:
3194 classinfo *c = iptr->val.a;
3196 if (c->flags & ACC_INTERFACE)
3197 printf(" (INTERFACE) ");
3199 printf(" (CLASS,%3d) ", c->vftbl->diffval);
3201 printf(" (NOT RESOLVED) ");
3203 utf_display_classname(((constant_classref *) iptr->target)->name);
3207 case ICMD_INLINE_START:
3208 case ICMD_INLINE_END:
3210 utf_display_classname(iptr->method->class->name);
3212 utf_display_classname(iptr->method->name);
3213 utf_display_classname(iptr->method->descriptor);
3217 printf(" %s", ((builtintable_entry *) iptr->val.a)->name);
3220 case ICMD_INVOKEVIRTUAL:
3221 case ICMD_INVOKESPECIAL:
3222 case ICMD_INVOKESTATIC:
3223 case ICMD_INVOKEINTERFACE:
3225 printf(" (NOT RESOLVED) ");
3228 utf_display_classname(((unresolved_method *) iptr->target)->methodref->classref->name);
3230 utf_display(((unresolved_method *) iptr->target)->methodref->name);
3231 utf_display(((unresolved_method *) iptr->target)->methodref->descriptor);
3240 if (deadcode || !iptr->target)
3241 printf(" %d (0x%08x) op1=%d", iptr->val.i, iptr->val.i, iptr->op1);
3243 printf(" %d (0x%08x) L%03d (%p)", iptr->val.i, iptr->val.i, ((basicblock *) iptr->target)->debug_nr,iptr->target);
3252 if (deadcode || !iptr->target)
3253 #if SIZEOF_VOID_P == 4
3254 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
3256 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
3259 #if SIZEOF_VOID_P == 4
3260 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
3262 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
3269 case ICMD_IFNONNULL:
3270 case ICMD_IF_ICMPEQ:
3271 case ICMD_IF_ICMPNE:
3272 case ICMD_IF_ICMPLT:
3273 case ICMD_IF_ICMPGE:
3274 case ICMD_IF_ICMPGT:
3275 case ICMD_IF_ICMPLE:
3276 case ICMD_IF_LCMPEQ:
3277 case ICMD_IF_LCMPNE:
3278 case ICMD_IF_LCMPLT:
3279 case ICMD_IF_LCMPGE:
3280 case ICMD_IF_LCMPGT:
3281 case ICMD_IF_LCMPLE:
3282 case ICMD_IF_ACMPEQ:
3283 case ICMD_IF_ACMPNE:
3284 case ICMD_INLINE_GOTO:
3285 if (deadcode || !iptr->target)
3286 printf(" op1=%d", iptr->op1);
3288 printf(" L%03d (%p)", ((basicblock *) iptr->target)->debug_nr,iptr->target);
3291 case ICMD_TABLESWITCH:
3292 s4ptr = (s4*)iptr->val.a;
3294 if (deadcode || !iptr->target) {
3295 printf(" %d;", *s4ptr);
3298 tptr = (void **) iptr->target;
3299 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
3303 s4ptr++; /* skip default */
3304 j = *s4ptr++; /* low */
3305 j = *s4ptr++ - j; /* high */
3307 if (deadcode || !*tptr)
3308 printf(" %d", *s4ptr++);
3310 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
3317 case ICMD_LOOKUPSWITCH:
3318 s4ptr = (s4*)iptr->val.a;
3320 if (deadcode || !iptr->target) {
3321 printf(" %d;", *s4ptr);
3324 tptr = (void **) iptr->target;
3325 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
3328 s4ptr++; /* default */
3329 j = *s4ptr++; /* count */
3332 if (deadcode || !*tptr) {
3333 s4ptr++; /* skip value */
3334 printf(" %d",*s4ptr++);
3337 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
3345 printf(" (NOT RESOLVED), Class = \"");
3346 utf_display(((unresolved_class *) iptr->val.a)->classref->name);
3351 #endif /* !defined(NDEBUG) */
3355 * These are local overrides for various environment variables in Emacs.
3356 * Please do not remove this and leave it at the end of the file, where
3357 * Emacs will automagically detect them.
3358 * ---------------------------------------------------------------------
3361 * indent-tabs-mode: t
3365 * vim:noexpandtab:sw=4:ts=4: