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 5017 2006-06-06 18:05:16Z twisti $
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/abi.h"
61 #if defined(ENABLE_DISASSEMBLER)
62 # include "vm/jit/disass.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/stack.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
73 /* macro for saving #ifdefs ***************************************************/
75 #if defined(ENABLE_INTRP)
76 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
78 #define IF_NO_INTRP(x) { x }
81 /* stack_init ******************************************************************
83 Initialized the stack analysis subsystem (called by jit_init).
85 *******************************************************************************/
93 /* stack_analyse ***************************************************************
95 Analyse_stack uses the intermediate code created by parse.c to
96 build a model of the JVM operand stack for the current method.
98 The following checks are performed:
99 - check for operand stack underflow (before each instruction)
100 - check for operand stack overflow (after[1] each instruction)
101 - check for matching stack depth at merging points
102 - check for matching basic types[2] at merging points
103 - check basic types for instruction input (except for BUILTIN*
104 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
106 [1]) Checking this after the instruction should be ok. parse.c
107 counts the number of required stack slots in such a way that it is
108 only vital that we don't exceed `maxstack` at basic block
111 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
112 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
113 types are not discerned.
115 *******************************************************************************/
117 bool stack_analyse(jitdata *jd)
128 int opcode, i, j, len, loops;
129 int superblockend, repeat, deadcode;
135 s4 *last_store;/* instruction index of last XSTORE */
136 /* [ local_index * 5 + type ] */
137 s4 last_pei; /* instruction index of last possible exception */
138 /* used for conflict resolution for copy */
139 /* elimination (XLOAD, IINC, XSTORE) */
141 #if defined(ENABLE_VERIFIER)
142 int expectedtype; /* used by CHECK_BASIC_TYPE */
145 builtintable_entry *bte;
148 /* get required compiler data */
154 #if defined(ENABLE_LSRA)
158 last_store = DMNEW(s4 , cd->maxlocals * 5);
162 m->basicblocks[0].flags = BBREACHED;
163 m->basicblocks[0].instack = 0;
164 m->basicblocks[0].indepth = 0;
166 for (i = 0; i < cd->exceptiontablelength; i++) {
167 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
168 bptr->flags = BBREACHED;
169 bptr->type = BBTYPE_EXH;
172 bptr->pre_count = 10000;
177 #if CONDITIONAL_LOADCONST
178 b_count = m->basicblockcount;
179 bptr = m->basicblocks;
180 while (--b_count >= 0) {
181 if (bptr->icount != 0) {
182 iptr = bptr->iinstr + bptr->icount - 1;
215 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
218 case ICMD_TABLESWITCH:
220 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
221 i = *s4ptr++; /* low */
222 i = *s4ptr++ - i + 1; /* high */
224 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
228 case ICMD_LOOKUPSWITCH:
230 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
231 i = *s4ptr++; /* count */
233 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
244 #endif /* CONDITIONAL_LOADCONST */
249 b_count = m->basicblockcount;
250 bptr = m->basicblocks;
251 superblockend = true;
256 while (--b_count >= 0) {
257 if (bptr->flags == BBDELETED) {
260 else if (superblockend && (bptr->flags < BBREACHED)) {
263 else if (bptr->flags <= BBREACHED) {
265 stackdepth = bptr->indepth;
267 else if (bptr->flags < BBREACHED) {
269 bptr->instack = copy;
270 bptr->indepth = stackdepth;
273 CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
276 curstack = bptr->instack;
278 superblockend = false;
279 bptr->flags = BBFINISHED;
282 b_index = bptr - m->basicblocks;
286 for( i = 0; i < cd->maxlocals; i++)
287 for( j = 0; j < 5; j++)
288 last_store[5 * i + j] = -1;
295 #if defined(USEBUILTINTABLE)
296 # if defined(ENABLE_INTRP)
299 bte = builtintable_get_automatic(opcode);
301 if (bte && bte->opcode == opcode) {
302 iptr->opc = ICMD_BUILTIN;
303 iptr->op1 = false; /* don't check for exception */
305 m->isleafmethod = false;
308 # if defined(ENABLE_INTRP)
311 #endif /* defined(USEBUILTINTABLE) */
313 /* this is the main switch */
320 COUNT(count_check_null);
323 case ICMD_IFEQ_ICONST:
324 case ICMD_IFNE_ICONST:
325 case ICMD_IFLT_ICONST:
326 case ICMD_IFGE_ICONST:
327 case ICMD_IFGT_ICONST:
328 case ICMD_IFLE_ICONST:
329 case ICMD_ELSE_ICONST:
334 #if defined(ENABLE_INTRP)
337 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
339 COUNT(count_pcmd_return);
341 superblockend = true;
344 /* pop 0 push 1 const */
347 COUNT(count_pcmd_load);
349 switch (iptr[1].opc) {
351 iptr[0].opc = ICMD_IADDCONST;
353 iptr[1].opc = ICMD_NOP;
354 OP1_1(TYPE_INT, TYPE_INT);
355 COUNT(count_pcmd_op);
358 iptr[0].opc = ICMD_ISUBCONST;
359 goto icmd_iconst_tail;
360 #if SUPPORT_CONST_MUL
362 iptr[0].opc = ICMD_IMULCONST;
363 goto icmd_iconst_tail;
364 #else /* SUPPORT_CONST_MUL */
366 if (iptr[0].val.i == 0x00000002)
368 else if (iptr[0].val.i == 0x00000004)
370 else if (iptr[0].val.i == 0x00000008)
372 else if (iptr[0].val.i == 0x00000010)
374 else if (iptr[0].val.i == 0x00000020)
376 else if (iptr[0].val.i == 0x00000040)
378 else if (iptr[0].val.i == 0x00000080)
380 else if (iptr[0].val.i == 0x00000100)
382 else if (iptr[0].val.i == 0x00000200)
384 else if (iptr[0].val.i == 0x00000400)
386 else if (iptr[0].val.i == 0x00000800)
388 else if (iptr[0].val.i == 0x00001000)
390 else if (iptr[0].val.i == 0x00002000)
392 else if (iptr[0].val.i == 0x00004000)
394 else if (iptr[0].val.i == 0x00008000)
396 else if (iptr[0].val.i == 0x00010000)
398 else if (iptr[0].val.i == 0x00020000)
400 else if (iptr[0].val.i == 0x00040000)
402 else if (iptr[0].val.i == 0x00080000)
404 else if (iptr[0].val.i == 0x00100000)
406 else if (iptr[0].val.i == 0x00200000)
408 else if (iptr[0].val.i == 0x00400000)
410 else if (iptr[0].val.i == 0x00800000)
412 else if (iptr[0].val.i == 0x01000000)
414 else if (iptr[0].val.i == 0x02000000)
416 else if (iptr[0].val.i == 0x04000000)
418 else if (iptr[0].val.i == 0x08000000)
420 else if (iptr[0].val.i == 0x10000000)
422 else if (iptr[0].val.i == 0x20000000)
424 else if (iptr[0].val.i == 0x40000000)
426 else if (iptr[0].val.i == 0x80000000)
432 iptr[0].opc = ICMD_IMULPOW2;
433 goto icmd_iconst_tail;
434 #endif /* SUPPORT_CONST_MUL */
436 if (iptr[0].val.i == 0x00000002)
438 else if (iptr[0].val.i == 0x00000004)
440 else if (iptr[0].val.i == 0x00000008)
442 else if (iptr[0].val.i == 0x00000010)
444 else if (iptr[0].val.i == 0x00000020)
446 else if (iptr[0].val.i == 0x00000040)
448 else if (iptr[0].val.i == 0x00000080)
450 else if (iptr[0].val.i == 0x00000100)
452 else if (iptr[0].val.i == 0x00000200)
454 else if (iptr[0].val.i == 0x00000400)
456 else if (iptr[0].val.i == 0x00000800)
458 else if (iptr[0].val.i == 0x00001000)
460 else if (iptr[0].val.i == 0x00002000)
462 else if (iptr[0].val.i == 0x00004000)
464 else if (iptr[0].val.i == 0x00008000)
466 else if (iptr[0].val.i == 0x00010000)
468 else if (iptr[0].val.i == 0x00020000)
470 else if (iptr[0].val.i == 0x00040000)
472 else if (iptr[0].val.i == 0x00080000)
474 else if (iptr[0].val.i == 0x00100000)
476 else if (iptr[0].val.i == 0x00200000)
478 else if (iptr[0].val.i == 0x00400000)
480 else if (iptr[0].val.i == 0x00800000)
482 else if (iptr[0].val.i == 0x01000000)
484 else if (iptr[0].val.i == 0x02000000)
486 else if (iptr[0].val.i == 0x04000000)
488 else if (iptr[0].val.i == 0x08000000)
490 else if (iptr[0].val.i == 0x10000000)
492 else if (iptr[0].val.i == 0x20000000)
494 else if (iptr[0].val.i == 0x40000000)
496 else if (iptr[0].val.i == 0x80000000)
502 iptr[0].opc = ICMD_IDIVPOW2;
503 goto icmd_iconst_tail;
505 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
506 if ((iptr[0].val.i == 0x00000002) ||
507 (iptr[0].val.i == 0x00000004) ||
508 (iptr[0].val.i == 0x00000008) ||
509 (iptr[0].val.i == 0x00000010) ||
510 (iptr[0].val.i == 0x00000020) ||
511 (iptr[0].val.i == 0x00000040) ||
512 (iptr[0].val.i == 0x00000080) ||
513 (iptr[0].val.i == 0x00000100) ||
514 (iptr[0].val.i == 0x00000200) ||
515 (iptr[0].val.i == 0x00000400) ||
516 (iptr[0].val.i == 0x00000800) ||
517 (iptr[0].val.i == 0x00001000) ||
518 (iptr[0].val.i == 0x00002000) ||
519 (iptr[0].val.i == 0x00004000) ||
520 (iptr[0].val.i == 0x00008000) ||
521 (iptr[0].val.i == 0x00010000) ||
522 (iptr[0].val.i == 0x00020000) ||
523 (iptr[0].val.i == 0x00040000) ||
524 (iptr[0].val.i == 0x00080000) ||
525 (iptr[0].val.i == 0x00100000) ||
526 (iptr[0].val.i == 0x00200000) ||
527 (iptr[0].val.i == 0x00400000) ||
528 (iptr[0].val.i == 0x00800000) ||
529 (iptr[0].val.i == 0x01000000) ||
530 (iptr[0].val.i == 0x02000000) ||
531 (iptr[0].val.i == 0x04000000) ||
532 (iptr[0].val.i == 0x08000000) ||
533 (iptr[0].val.i == 0x10000000) ||
534 (iptr[0].val.i == 0x20000000) ||
535 (iptr[0].val.i == 0x40000000) ||
536 (iptr[0].val.i == 0x80000000)) {
537 iptr[0].opc = ICMD_IREMPOW2;
539 goto icmd_iconst_tail;
543 #if SUPPORT_CONST_LOGICAL
545 iptr[0].opc = ICMD_IANDCONST;
546 goto icmd_iconst_tail;
548 iptr[0].opc = ICMD_IORCONST;
549 goto icmd_iconst_tail;
551 iptr[0].opc = ICMD_IXORCONST;
552 goto icmd_iconst_tail;
553 #endif /* SUPPORT_CONST_LOGICAL */
555 iptr[0].opc = ICMD_ISHLCONST;
556 goto icmd_iconst_tail;
558 iptr[0].opc = ICMD_ISHRCONST;
559 goto icmd_iconst_tail;
561 iptr[0].opc = ICMD_IUSHRCONST;
562 goto icmd_iconst_tail;
563 #if SUPPORT_LONG_SHIFT
565 iptr[0].opc = ICMD_LSHLCONST;
566 goto icmd_lconst_tail;
568 iptr[0].opc = ICMD_LSHRCONST;
569 goto icmd_lconst_tail;
571 iptr[0].opc = ICMD_LUSHRCONST;
572 goto icmd_lconst_tail;
573 #endif /* SUPPORT_LONG_SHIFT */
575 iptr[1].opc = ICMD_IFEQ;
577 /* iptr[0].op1 = iptr[1].op1; */
578 /* IF_ICMPxx is the last instruction in the
579 basic block, just remove it. */
580 iptr[0].opc = ICMD_NOP;
581 iptr[1].val.i = iptr[0].val.i;
583 /* bptr->icount--; */
587 tbptr = m->basicblocks +
588 m->basicblockindex[iptr[1].op1];
590 iptr[1].target = (void *) tbptr;
592 MARKREACHED(tbptr, copy);
593 COUNT(count_pcmd_bra);
597 iptr[1].opc = ICMD_IFLT;
598 goto icmd_if_icmp_tail;
600 iptr[1].opc = ICMD_IFLE;
601 goto icmd_if_icmp_tail;
603 iptr[1].opc = ICMD_IFNE;
604 goto icmd_if_icmp_tail;
606 iptr[1].opc = ICMD_IFGT;
607 goto icmd_if_icmp_tail;
609 iptr[1].opc = ICMD_IFGE;
610 goto icmd_if_icmp_tail;
612 #if SUPPORT_CONST_STORE
617 # if defined(ENABLE_INTRP)
620 # if SUPPORT_CONST_STORE_ZERO_ONLY
621 if (iptr[0].val.i == 0) {
623 switch (iptr[1].opc) {
625 iptr[0].opc = ICMD_IASTORECONST;
628 iptr[0].opc = ICMD_BASTORECONST;
631 iptr[0].opc = ICMD_CASTORECONST;
634 iptr[0].opc = ICMD_SASTORECONST;
638 iptr[1].opc = ICMD_NOP;
639 OPTT2_0(TYPE_INT, TYPE_ADR);
640 COUNT(count_pcmd_op);
641 # if SUPPORT_CONST_STORE_ZERO_ONLY
646 # if defined(ENABLE_INTRP)
655 # if defined(ENABLE_INTRP)
658 # if SUPPORT_CONST_STORE_ZERO_ONLY
659 if (iptr[0].val.i == 0) {
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
680 # if defined(ENABLE_INTRP)
686 #endif /* SUPPORT_CONST_STORE */
696 COUNT(count_pcmd_load);
698 switch (iptr[1].opc) {
701 iptr[0].opc = ICMD_LADDCONST;
703 iptr[1].opc = ICMD_NOP;
704 OP1_1(TYPE_LNG,TYPE_LNG);
705 COUNT(count_pcmd_op);
708 iptr[0].opc = ICMD_LSUBCONST;
709 goto icmd_lconst_tail;
710 #endif /* SUPPORT_LONG_ADD */
711 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
713 iptr[0].opc = ICMD_LMULCONST;
714 goto icmd_lconst_tail;
715 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
716 # if SUPPORT_LONG_SHIFT
718 if (iptr[0].val.l == 0x00000002)
720 else if (iptr[0].val.l == 0x00000004)
722 else if (iptr[0].val.l == 0x00000008)
724 else if (iptr[0].val.l == 0x00000010)
726 else if (iptr[0].val.l == 0x00000020)
728 else if (iptr[0].val.l == 0x00000040)
730 else if (iptr[0].val.l == 0x00000080)
732 else if (iptr[0].val.l == 0x00000100)
734 else if (iptr[0].val.l == 0x00000200)
736 else if (iptr[0].val.l == 0x00000400)
738 else if (iptr[0].val.l == 0x00000800)
740 else if (iptr[0].val.l == 0x00001000)
742 else if (iptr[0].val.l == 0x00002000)
744 else if (iptr[0].val.l == 0x00004000)
746 else if (iptr[0].val.l == 0x00008000)
748 else if (iptr[0].val.l == 0x00010000)
750 else if (iptr[0].val.l == 0x00020000)
752 else if (iptr[0].val.l == 0x00040000)
754 else if (iptr[0].val.l == 0x00080000)
756 else if (iptr[0].val.l == 0x00100000)
758 else if (iptr[0].val.l == 0x00200000)
760 else if (iptr[0].val.l == 0x00400000)
762 else if (iptr[0].val.l == 0x00800000)
764 else if (iptr[0].val.l == 0x01000000)
766 else if (iptr[0].val.l == 0x02000000)
768 else if (iptr[0].val.l == 0x04000000)
770 else if (iptr[0].val.l == 0x08000000)
772 else if (iptr[0].val.l == 0x10000000)
774 else if (iptr[0].val.l == 0x20000000)
776 else if (iptr[0].val.l == 0x40000000)
778 else if (iptr[0].val.l == 0x80000000)
784 iptr[0].opc = ICMD_LMULPOW2;
785 goto icmd_lconst_tail;
786 # endif /* SUPPORT_LONG_SHIFT */
787 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
789 #if SUPPORT_LONG_DIV_POW2
791 if (iptr[0].val.l == 0x00000002)
793 else if (iptr[0].val.l == 0x00000004)
795 else if (iptr[0].val.l == 0x00000008)
797 else if (iptr[0].val.l == 0x00000010)
799 else if (iptr[0].val.l == 0x00000020)
801 else if (iptr[0].val.l == 0x00000040)
803 else if (iptr[0].val.l == 0x00000080)
805 else if (iptr[0].val.l == 0x00000100)
807 else if (iptr[0].val.l == 0x00000200)
809 else if (iptr[0].val.l == 0x00000400)
811 else if (iptr[0].val.l == 0x00000800)
813 else if (iptr[0].val.l == 0x00001000)
815 else if (iptr[0].val.l == 0x00002000)
817 else if (iptr[0].val.l == 0x00004000)
819 else if (iptr[0].val.l == 0x00008000)
821 else if (iptr[0].val.l == 0x00010000)
823 else if (iptr[0].val.l == 0x00020000)
825 else if (iptr[0].val.l == 0x00040000)
827 else if (iptr[0].val.l == 0x00080000)
829 else if (iptr[0].val.l == 0x00100000)
831 else if (iptr[0].val.l == 0x00200000)
833 else if (iptr[0].val.l == 0x00400000)
835 else if (iptr[0].val.l == 0x00800000)
837 else if (iptr[0].val.l == 0x01000000)
839 else if (iptr[0].val.l == 0x02000000)
841 else if (iptr[0].val.l == 0x04000000)
843 else if (iptr[0].val.l == 0x08000000)
845 else if (iptr[0].val.l == 0x10000000)
847 else if (iptr[0].val.l == 0x20000000)
849 else if (iptr[0].val.l == 0x40000000)
851 else if (iptr[0].val.l == 0x80000000)
857 iptr[0].opc = ICMD_LDIVPOW2;
858 goto icmd_lconst_tail;
859 #endif /* SUPPORT_LONG_DIV_POW2 */
861 #if SUPPORT_LONG_REM_POW2
863 if ((iptr[0].val.l == 0x00000002) ||
864 (iptr[0].val.l == 0x00000004) ||
865 (iptr[0].val.l == 0x00000008) ||
866 (iptr[0].val.l == 0x00000010) ||
867 (iptr[0].val.l == 0x00000020) ||
868 (iptr[0].val.l == 0x00000040) ||
869 (iptr[0].val.l == 0x00000080) ||
870 (iptr[0].val.l == 0x00000100) ||
871 (iptr[0].val.l == 0x00000200) ||
872 (iptr[0].val.l == 0x00000400) ||
873 (iptr[0].val.l == 0x00000800) ||
874 (iptr[0].val.l == 0x00001000) ||
875 (iptr[0].val.l == 0x00002000) ||
876 (iptr[0].val.l == 0x00004000) ||
877 (iptr[0].val.l == 0x00008000) ||
878 (iptr[0].val.l == 0x00010000) ||
879 (iptr[0].val.l == 0x00020000) ||
880 (iptr[0].val.l == 0x00040000) ||
881 (iptr[0].val.l == 0x00080000) ||
882 (iptr[0].val.l == 0x00100000) ||
883 (iptr[0].val.l == 0x00200000) ||
884 (iptr[0].val.l == 0x00400000) ||
885 (iptr[0].val.l == 0x00800000) ||
886 (iptr[0].val.l == 0x01000000) ||
887 (iptr[0].val.l == 0x02000000) ||
888 (iptr[0].val.l == 0x04000000) ||
889 (iptr[0].val.l == 0x08000000) ||
890 (iptr[0].val.l == 0x10000000) ||
891 (iptr[0].val.l == 0x20000000) ||
892 (iptr[0].val.l == 0x40000000) ||
893 (iptr[0].val.l == 0x80000000)) {
894 iptr[0].opc = ICMD_LREMPOW2;
896 goto icmd_lconst_tail;
900 #endif /* SUPPORT_LONG_REM_POW2 */
902 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
905 iptr[0].opc = ICMD_LANDCONST;
906 goto icmd_lconst_tail;
908 iptr[0].opc = ICMD_LORCONST;
909 goto icmd_lconst_tail;
911 iptr[0].opc = ICMD_LXORCONST;
912 goto icmd_lconst_tail;
913 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
915 #if SUPPORT_LONG_CMP_CONST
917 if ((len > 1) && (iptr[2].val.i == 0)) {
918 switch (iptr[2].opc) {
920 iptr[0].opc = ICMD_IF_LEQ;
921 icmd_lconst_lcmp_tail:
922 iptr[0].op1 = iptr[2].op1;
923 iptr[1].opc = ICMD_NOP;
924 iptr[2].opc = ICMD_NOP;
926 /* bptr->icount -= 2; */
930 tbptr = m->basicblocks +
931 m->basicblockindex[iptr[0].op1];
933 iptr[0].target = (void *) tbptr;
935 MARKREACHED(tbptr, copy);
936 COUNT(count_pcmd_bra);
937 COUNT(count_pcmd_op);
940 iptr[0].opc = ICMD_IF_LNE;
941 goto icmd_lconst_lcmp_tail;
943 iptr[0].opc = ICMD_IF_LLT;
944 goto icmd_lconst_lcmp_tail;
946 iptr[0].opc = ICMD_IF_LGT;
947 goto icmd_lconst_lcmp_tail;
949 iptr[0].opc = ICMD_IF_LLE;
950 goto icmd_lconst_lcmp_tail;
952 iptr[0].opc = ICMD_IF_LGE;
953 goto icmd_lconst_lcmp_tail;
956 } /* switch (iptr[2].opc) */
957 } /* if (iptr[2].val.i == 0) */
961 #endif /* SUPPORT_LONG_CMP_CONST */
963 #if SUPPORT_CONST_STORE
965 # if defined(ENABLE_INTRP)
968 # if SUPPORT_CONST_STORE_ZERO_ONLY
969 if (iptr[0].val.l == 0) {
971 iptr[0].opc = ICMD_LASTORECONST;
972 iptr[1].opc = ICMD_NOP;
973 OPTT2_0(TYPE_INT, TYPE_ADR);
974 COUNT(count_pcmd_op);
975 # if SUPPORT_CONST_STORE_ZERO_ONLY
980 # if defined(ENABLE_INTRP)
989 # if defined(ENABLE_INTRP)
992 # if SUPPORT_CONST_STORE_ZERO_ONLY
993 if (iptr[0].val.l == 0) {
995 switch (iptr[1].opc) {
997 iptr[0].opc = ICMD_PUTSTATICCONST;
1001 iptr[0].opc = ICMD_PUTFIELDCONST;
1006 iptr[1].opc = ICMD_NOP;
1007 iptr[0].op1 = TYPE_LNG;
1008 COUNT(count_pcmd_op);
1009 # if SUPPORT_CONST_STORE_ZERO_ONLY
1012 PUSHCONST(TYPE_LNG);
1014 # if defined(ENABLE_INTRP)
1017 PUSHCONST(TYPE_LNG);
1020 #endif /* SUPPORT_CONST_STORE */
1022 PUSHCONST(TYPE_LNG);
1026 PUSHCONST(TYPE_LNG);
1030 COUNT(count_pcmd_load);
1031 PUSHCONST(TYPE_FLT);
1035 COUNT(count_pcmd_load);
1036 PUSHCONST(TYPE_DBL);
1040 COUNT(count_pcmd_load);
1041 #if SUPPORT_CONST_STORE
1042 # if defined(ENABLE_INTRP)
1045 /* We can only optimize if the ACONST is resolved
1046 * and there is an instruction after it. */
1048 if ((len > 0) && INSTRUCTION_IS_RESOLVED(iptr))
1050 switch (iptr[1].opc) {
1052 /* We can only optimize for NULL values
1053 * here because otherwise a checkcast is
1055 if (iptr->val.a != NULL)
1056 goto aconst_no_transform;
1058 iptr[0].opc = ICMD_AASTORECONST;
1059 OPTT2_0(TYPE_INT, TYPE_ADR);
1061 iptr[1].opc = ICMD_NOP;
1062 COUNT(count_pcmd_op);
1065 case ICMD_PUTSTATIC:
1067 # if SUPPORT_CONST_STORE_ZERO_ONLY
1068 if (iptr->val.a == 0) {
1071 switch (iptr[1].opc) {
1072 case ICMD_PUTSTATIC:
1073 iptr[0].opc = ICMD_PUTSTATICCONST;
1074 iptr[0].op1 = TYPE_ADR;
1078 iptr[0].opc = ICMD_PUTFIELDCONST;
1079 iptr[0].op1 = TYPE_ADR;
1084 iptr[1].opc = ICMD_NOP;
1085 COUNT(count_pcmd_op);
1087 # if SUPPORT_CONST_STORE_ZERO_ONLY
1090 /* no transformation */
1091 PUSHCONST(TYPE_ADR);
1096 aconst_no_transform:
1097 /* no transformation */
1098 PUSHCONST(TYPE_ADR);
1102 /* no transformation */
1103 PUSHCONST(TYPE_ADR);
1105 # if defined(ENABLE_INTRP)
1108 PUSHCONST(TYPE_ADR);
1110 #else /* SUPPORT_CONST_STORE */
1111 PUSHCONST(TYPE_ADR);
1112 #endif /* SUPPORT_CONST_STORE */
1115 /* pop 0 push 1 load */
1122 COUNT(count_load_instruction);
1123 i = opcode - ICMD_ILOAD;
1124 #if defined(ENABLE_INTRP)
1127 rd->locals[iptr->op1][i].type = i;
1128 LOAD(i, LOCALVAR, iptr->op1);
1138 COUNT(count_check_null);
1139 COUNT(count_check_bound);
1140 COUNT(count_pcmd_mem);
1141 OP2IAT_1(opcode - ICMD_IALOAD);
1147 COUNT(count_check_null);
1148 COUNT(count_check_bound);
1149 COUNT(count_pcmd_mem);
1153 /* pop 0 push 0 iinc */
1156 #if defined(ENABLE_STATISTICS)
1160 count_store_depth[10]++;
1162 count_store_depth[i]++;
1165 last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
1170 if ((copy->varkind == LOCALVAR) &&
1171 (copy->varnum == iptr->op1)) {
1172 copy->varkind = TEMPVAR;
1182 /* pop 1 push 0 store */
1191 i = opcode - ICMD_ISTORE;
1192 #if defined(ENABLE_INTRP)
1195 rd->locals[iptr->op1][i].type = i;
1196 #if defined(ENABLE_STATISTICS)
1201 count_store_length[20]++;
1203 count_store_length[i]++;
1206 count_store_depth[10]++;
1208 count_store_depth[i]++;
1211 /* check for conflicts as described in Figure 5.2 */
1212 copy = curstack->prev;
1215 if ((copy->varkind == LOCALVAR) &&
1216 (copy->varnum == iptr->op1)) {
1217 copy->varkind = TEMPVAR;
1224 /* do not change instack Stackslots */
1225 /* it won't improve performance if we copy the interface */
1226 /* at the BB begin or here, and lsra relies that no */
1227 /* instack stackslot is marked LOCALVAR */
1228 if (curstack->varkind == STACKVAR)
1229 goto _possible_conflict;
1231 /* check for a DUPX,SWAP while the lifetime of curstack */
1232 /* and as creator curstack */
1233 if (last_dupx != -1) {
1234 /* we have to look at the dst stack of DUPX */
1235 /* == src Stack of PEI */
1236 copy = bptr->iinstr[last_dupx].dst;
1239 copy = bptr->instack;
1241 copy = bptr->iinstr[last_pei-1].dst;
1243 if ((copy != NULL) && (curstack <= copy)) {
1244 /* curstack alive at or created by DUPX */
1247 /* now look, if there is a LOCALVAR at anyone of */
1248 /* the src stacklots used by DUPX */
1250 goto _possible_conflict;
1254 /* check for a PEI while the lifetime of curstack */
1255 if (last_pei != -1) {
1256 /* && there are exception handler in this method */
1257 /* when this is checked prevent ARGVAR from */
1258 /* overwriting LOCALVAR!!! */
1260 /* we have to look at the stack _before_ the PEI! */
1261 /* == src Stack of PEI */
1263 copy = bptr->instack;
1265 copy = bptr->iinstr[last_pei-1].dst;
1266 if ((copy != NULL) && (curstack <= copy)) {
1267 /* curstack alive at PEI */
1268 goto _possible_conflict;
1272 /* check if there is a possible conflicting XSTORE */
1273 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) {
1274 /* we have to look at the stack _before_ the XSTORE! */
1275 /* == src Stack of XSTORE */
1276 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0)
1277 copy = bptr->instack;
1279 copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst;
1280 if ((copy != NULL) && (curstack <= copy)) {
1281 /* curstack alive at Last Store */
1282 goto _possible_conflict;
1286 /* check if there is a conflict with a XLOAD */
1287 /* this is done indirectly by looking if a Stackslot is */
1288 /* marked LOCALVAR and is live while curstack is live */
1289 /* see figure 5.3 */
1291 /* First check "above" stackslots of the instack */
1292 copy = curstack + 1;
1293 for(;(copy <= bptr->instack); copy++)
1294 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1295 goto _possible_conflict;
1298 /* "intra" Basic Block Stackslots are allocated above */
1299 /* bptr->stack (see doc/stack.txt), so if curstack + 1 */
1300 /* is an instack, copy could point now to the stackslots */
1301 /* of an inbetween analysed Basic Block */
1302 if (copy < bptr->stack)
1304 while (copy < new) {
1305 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1306 goto _possible_conflict;
1310 /* If Stackslot is already marked as LOCALVAR, do not */
1311 /* change it! Conflict resolution works only, if xLOAD */
1313 if (curstack->varkind == LOCALVAR)
1314 goto _possible_conflict;
1315 /* no conflict - mark the Stackslot as LOCALVAR */
1316 curstack->varkind = LOCALVAR;
1317 curstack->varnum = iptr->op1;
1321 if ((curstack->varkind == LOCALVAR)
1322 && (curstack->varnum == iptr->op1)) {
1323 curstack->varkind = TEMPVAR;
1324 curstack->varnum = stackdepth-1;
1327 last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1;
1329 STORE(opcode - ICMD_ISTORE);
1335 COUNT(count_check_null);
1336 COUNT(count_check_bound);
1337 COUNT(count_pcmd_mem);
1339 bte = builtintable_get_internal(BUILTIN_canstore);
1342 if (md->memuse > rd->memuse)
1343 rd->memuse = md->memuse;
1344 if (md->argintreguse > rd->argintreguse)
1345 rd->argintreguse = md->argintreguse;
1347 /* make all stack variables saved */
1351 copy->flags |= SAVEDVAR;
1362 COUNT(count_check_null);
1363 COUNT(count_check_bound);
1364 COUNT(count_pcmd_mem);
1365 OP3TIA_0(opcode - ICMD_IASTORE);
1371 COUNT(count_check_null);
1372 COUNT(count_check_bound);
1373 COUNT(count_pcmd_mem);
1380 #ifdef ENABLE_VERIFIER
1383 if (IS_2_WORD_TYPE(curstack->type))
1384 goto throw_stack_category_error;
1395 #if defined(ENABLE_JIT)
1396 # if defined(ENABLE_INTRP)
1399 md_return_alloc(m, rd, opcode - ICMD_IRETURN,
1402 COUNT(count_pcmd_return);
1403 OP1_0(opcode - ICMD_IRETURN);
1404 superblockend = true;
1408 COUNT(count_check_null);
1412 superblockend = true;
1415 case ICMD_PUTSTATIC:
1416 COUNT(count_pcmd_mem);
1420 /* pop 1 push 0 branch */
1423 case ICMD_IFNONNULL:
1424 COUNT(count_pcmd_bra);
1426 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1428 iptr[0].target = (void *) tbptr;
1430 MARKREACHED(tbptr, copy);
1439 COUNT(count_pcmd_bra);
1440 #if CONDITIONAL_LOADCONST && 0
1441 # if defined(ENABLE_INTRP)
1444 tbptr = m->basicblocks + b_index;
1446 if ((b_count >= 3) &&
1447 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1448 (tbptr[1].pre_count == 1) &&
1449 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1450 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1451 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1452 (tbptr[2].pre_count == 1) &&
1453 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1454 (tbptr[2].icount==1)) {
1455 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1456 OP1_1(TYPE_INT, TYPE_INT);
1457 switch (iptr[0].opc) {
1459 iptr[0].opc = ICMD_IFNE_ICONST;
1462 iptr[0].opc = ICMD_IFEQ_ICONST;
1465 iptr[0].opc = ICMD_IFGE_ICONST;
1468 iptr[0].opc = ICMD_IFLT_ICONST;
1471 iptr[0].opc = ICMD_IFLE_ICONST;
1474 iptr[0].opc = ICMD_IFGT_ICONST;
1478 iptr[0].val.i = iptr[1].val.i;
1479 iptr[1].opc = ICMD_ELSE_ICONST;
1480 iptr[1].val.i = iptr[3].val.i;
1481 iptr[2].opc = ICMD_NOP;
1482 iptr[3].opc = ICMD_NOP;
1484 /* HACK: save compare value in iptr[1].op1 */
1485 iptr[1].op1 = iptr[0].val.i;
1486 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1487 iptr[1].opc = ICMD_ELSE_ICONST;
1488 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1489 tbptr[1].iinstr[0].opc = ICMD_NOP;
1490 tbptr[1].iinstr[1].opc = ICMD_NOP;
1491 tbptr[2].iinstr[0].opc = ICMD_NOP;
1493 tbptr[1].flags = BBDELETED;
1494 tbptr[2].flags = BBDELETED;
1495 tbptr[1].icount = 0;
1496 tbptr[2].icount = 0;
1497 if (tbptr[3].pre_count == 2) {
1498 len += tbptr[3].icount + 3;
1499 bptr->icount += tbptr[3].icount + 3;
1500 tbptr[3].flags = BBDELETED;
1501 tbptr[3].icount = 0;
1511 # if defined(ENABLE_INTRP)
1515 #endif /* CONDITIONAL_LOADCONST */
1517 /* iptr->val.i is set implicitly in parse by
1518 clearing the memory or from IF_ICMPxx
1522 /* iptr->val.i = 0; */
1523 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1525 iptr[0].target = (void *) tbptr;
1527 MARKREACHED(tbptr, copy);
1530 /* pop 0 push 0 branch */
1533 COUNT(count_pcmd_bra);
1534 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1536 iptr[0].target = (void *) tbptr;
1538 MARKREACHED(tbptr, copy);
1540 superblockend = true;
1543 /* pop 1 push 0 table branch */
1545 case ICMD_TABLESWITCH:
1546 COUNT(count_pcmd_table);
1548 s4ptr = iptr->val.a;
1549 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1550 MARKREACHED(tbptr, copy);
1551 i = *s4ptr++; /* low */
1552 i = *s4ptr++ - i + 1; /* high */
1554 tptr = DMNEW(void*, i+1);
1555 iptr->target = (void *) tptr;
1557 tptr[0] = (void *) tbptr;
1561 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1563 tptr[0] = (void *) tbptr;
1566 MARKREACHED(tbptr, copy);
1569 superblockend = true;
1572 /* pop 1 push 0 table branch */
1574 case ICMD_LOOKUPSWITCH:
1575 COUNT(count_pcmd_table);
1577 s4ptr = iptr->val.a;
1578 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1579 MARKREACHED(tbptr, copy);
1580 i = *s4ptr++; /* count */
1582 tptr = DMNEW(void*, i+1);
1583 iptr->target = (void *) tptr;
1585 tptr[0] = (void *) tbptr;
1589 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1591 tptr[0] = (void *) tbptr;
1594 MARKREACHED(tbptr, copy);
1598 superblockend = true;
1601 case ICMD_MONITORENTER:
1602 COUNT(count_check_null);
1603 case ICMD_MONITOREXIT:
1607 /* pop 2 push 0 branch */
1609 case ICMD_IF_ICMPEQ:
1610 case ICMD_IF_ICMPNE:
1611 case ICMD_IF_ICMPLT:
1612 case ICMD_IF_ICMPGE:
1613 case ICMD_IF_ICMPGT:
1614 case ICMD_IF_ICMPLE:
1615 COUNT(count_pcmd_bra);
1617 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1619 iptr[0].target = (void *) tbptr;
1621 MARKREACHED(tbptr, copy);
1624 case ICMD_IF_ACMPEQ:
1625 case ICMD_IF_ACMPNE:
1626 COUNT(count_pcmd_bra);
1628 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1630 iptr[0].target = (void *) tbptr;
1632 MARKREACHED(tbptr, copy);
1638 COUNT(count_check_null);
1639 COUNT(count_pcmd_mem);
1640 OPTT2_0(iptr->op1,TYPE_ADR);
1645 if (!IS_2_WORD_TYPE(curstack->type)) {
1647 #ifdef ENABLE_VERIFIER
1650 if (IS_2_WORD_TYPE(curstack->prev->type))
1651 goto throw_stack_category_error;
1654 OP1_0ANY; /* second pop */
1657 iptr->opc = ICMD_POP;
1661 /* pop 0 push 1 dup */
1664 #ifdef ENABLE_VERIFIER
1667 if (IS_2_WORD_TYPE(curstack->type))
1668 goto throw_stack_category_error;
1671 last_dupx = bptr->icount - len - 1;
1672 COUNT(count_dup_instruction);
1677 last_dupx = bptr->icount - len - 1;
1679 if (IS_2_WORD_TYPE(curstack->type)) {
1681 iptr->opc = ICMD_DUP;
1686 /* ..., ????, cat1 */
1687 #ifdef ENABLE_VERIFIER
1689 if (IS_2_WORD_TYPE(curstack->prev->type))
1690 goto throw_stack_category_error;
1694 NEWSTACK(copy->prev->type, copy->prev->varkind,
1695 copy->prev->varnum);
1696 NEWSTACK(copy->type, copy->varkind,
1703 /* pop 2 push 3 dup */
1706 #ifdef ENABLE_VERIFIER
1709 if (IS_2_WORD_TYPE(curstack->type) ||
1710 IS_2_WORD_TYPE(curstack->prev->type))
1711 goto throw_stack_category_error;
1714 last_dupx = bptr->icount - len - 1;
1719 last_dupx = bptr->icount - len - 1;
1721 if (IS_2_WORD_TYPE(curstack->type)) {
1722 /* ..., ????, cat2 */
1723 #ifdef ENABLE_VERIFIER
1725 if (IS_2_WORD_TYPE(curstack->prev->type))
1726 goto throw_stack_category_error;
1729 iptr->opc = ICMD_DUP_X1;
1733 /* ..., ????, cat1 */
1734 #ifdef ENABLE_VERIFIER
1737 if (IS_2_WORD_TYPE(curstack->prev->type)
1738 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1739 goto throw_stack_category_error;
1746 /* pop 3 push 4 dup */
1749 last_dupx = bptr->icount - len - 1;
1751 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1752 /* ..., cat2, ???? */
1753 #ifdef ENABLE_VERIFIER
1755 if (IS_2_WORD_TYPE(curstack->type))
1756 goto throw_stack_category_error;
1759 iptr->opc = ICMD_DUP_X1;
1763 /* ..., cat1, ???? */
1764 #ifdef ENABLE_VERIFIER
1767 if (IS_2_WORD_TYPE(curstack->type)
1768 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1769 goto throw_stack_category_error;
1777 last_dupx = bptr->icount - len - 1;
1779 if (IS_2_WORD_TYPE(curstack->type)) {
1780 /* ..., ????, cat2 */
1781 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1782 /* ..., cat2, cat2 */
1783 iptr->opc = ICMD_DUP_X1;
1787 /* ..., cat1, cat2 */
1788 #ifdef ENABLE_VERIFIER
1791 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
1792 goto throw_stack_category_error;
1795 iptr->opc = ICMD_DUP_X2;
1801 /* ..., ????, ????, cat1 */
1802 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1803 /* ..., cat2, ????, cat1 */
1804 #ifdef ENABLE_VERIFIER
1806 if (IS_2_WORD_TYPE(curstack->prev->type))
1807 goto throw_stack_category_error;
1810 iptr->opc = ICMD_DUP2_X1;
1814 /* ..., cat1, ????, cat1 */
1815 #ifdef ENABLE_VERIFIER
1818 if (IS_2_WORD_TYPE(curstack->prev->type)
1819 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
1820 goto throw_stack_category_error;
1828 /* pop 2 push 2 swap */
1831 last_dupx = bptr->icount - len - 1;
1832 #ifdef ENABLE_VERIFIER
1835 if (IS_2_WORD_TYPE(curstack->type)
1836 || IS_2_WORD_TYPE(curstack->prev->type))
1837 goto throw_stack_category_error;
1847 #if !SUPPORT_DIVISION
1848 bte = (builtintable_entry *) iptr->val.a;
1852 if (md->memuse > rd->memuse)
1853 rd->memuse = md->memuse;
1854 if (md->argintreguse > rd->argintreguse)
1855 rd->argintreguse = md->argintreguse;
1857 /* make all stack variables saved */
1861 copy->flags |= SAVEDVAR;
1866 #endif /* !SUPPORT_DIVISION */
1877 COUNT(count_pcmd_op);
1883 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1884 bte = (builtintable_entry *) iptr->val.a;
1888 if (md->memuse > rd->memuse)
1889 rd->memuse = md->memuse;
1890 if (md->argintreguse > rd->argintreguse)
1891 rd->argintreguse = md->argintreguse;
1893 /* make all stack variables saved */
1897 copy->flags |= SAVEDVAR;
1902 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
1907 #if SUPPORT_LONG_LOGICAL
1911 #endif /* SUPPORT_LONG_LOGICAL */
1912 COUNT(count_pcmd_op);
1919 COUNT(count_pcmd_op);
1928 COUNT(count_pcmd_op);
1937 COUNT(count_pcmd_op);
1942 COUNT(count_pcmd_op);
1943 #if SUPPORT_LONG_CMP_CONST
1944 if ((len > 0) && (iptr[1].val.i == 0)) {
1945 switch (iptr[1].opc) {
1947 iptr[0].opc = ICMD_IF_LCMPEQ;
1949 iptr[0].op1 = iptr[1].op1;
1950 iptr[1].opc = ICMD_NOP;
1952 /* bptr->icount--; */
1955 tbptr = m->basicblocks +
1956 m->basicblockindex[iptr[0].op1];
1958 iptr[0].target = (void *) tbptr;
1960 MARKREACHED(tbptr, copy);
1961 COUNT(count_pcmd_bra);
1964 iptr[0].opc = ICMD_IF_LCMPNE;
1965 goto icmd_lcmp_if_tail;
1967 iptr[0].opc = ICMD_IF_LCMPLT;
1968 goto icmd_lcmp_if_tail;
1970 iptr[0].opc = ICMD_IF_LCMPGT;
1971 goto icmd_lcmp_if_tail;
1973 iptr[0].opc = ICMD_IF_LCMPLE;
1974 goto icmd_lcmp_if_tail;
1976 iptr[0].opc = ICMD_IF_LCMPGE;
1977 goto icmd_lcmp_if_tail;
1979 OPTT2_1(TYPE_LNG, TYPE_INT);
1983 #endif /* SUPPORT_LONG_CMP_CONST */
1984 OPTT2_1(TYPE_LNG, TYPE_INT);
1989 COUNT(count_pcmd_op);
1990 if ((len > 0) && (iptr[1].val.i == 0)) {
1991 switch (iptr[1].opc) {
1993 iptr[0].opc = ICMD_IF_FCMPEQ;
1995 iptr[0].op1 = iptr[1].op1;
1996 iptr[1].opc = ICMD_NOP;
1999 tbptr = m->basicblocks +
2000 m->basicblockindex[iptr[0].op1];
2002 iptr[0].target = (void *) tbptr;
2004 MARKREACHED(tbptr, copy);
2005 COUNT(count_pcmd_bra);
2008 iptr[0].opc = ICMD_IF_FCMPNE;
2009 goto icmd_if_fcmpl_tail;
2011 iptr[0].opc = ICMD_IF_FCMPL_LT;
2012 goto icmd_if_fcmpl_tail;
2014 iptr[0].opc = ICMD_IF_FCMPL_GT;
2015 goto icmd_if_fcmpl_tail;
2017 iptr[0].opc = ICMD_IF_FCMPL_LE;
2018 goto icmd_if_fcmpl_tail;
2020 iptr[0].opc = ICMD_IF_FCMPL_GE;
2021 goto icmd_if_fcmpl_tail;
2023 OPTT2_1(TYPE_FLT, TYPE_INT);
2027 OPTT2_1(TYPE_FLT, TYPE_INT);
2031 COUNT(count_pcmd_op);
2032 if ((len > 0) && (iptr[1].val.i == 0)) {
2033 switch (iptr[1].opc) {
2035 iptr[0].opc = ICMD_IF_FCMPEQ;
2037 iptr[0].op1 = iptr[1].op1;
2038 iptr[1].opc = ICMD_NOP;
2041 tbptr = m->basicblocks +
2042 m->basicblockindex[iptr[0].op1];
2044 iptr[0].target = (void *) tbptr;
2046 MARKREACHED(tbptr, copy);
2047 COUNT(count_pcmd_bra);
2050 iptr[0].opc = ICMD_IF_FCMPNE;
2051 goto icmd_if_fcmpg_tail;
2053 iptr[0].opc = ICMD_IF_FCMPG_LT;
2054 goto icmd_if_fcmpg_tail;
2056 iptr[0].opc = ICMD_IF_FCMPG_GT;
2057 goto icmd_if_fcmpg_tail;
2059 iptr[0].opc = ICMD_IF_FCMPG_LE;
2060 goto icmd_if_fcmpg_tail;
2062 iptr[0].opc = ICMD_IF_FCMPG_GE;
2063 goto icmd_if_fcmpg_tail;
2065 OPTT2_1(TYPE_FLT, TYPE_INT);
2069 OPTT2_1(TYPE_FLT, TYPE_INT);
2073 COUNT(count_pcmd_op);
2074 if ((len > 0) && (iptr[1].val.i == 0)) {
2075 switch (iptr[1].opc) {
2077 iptr[0].opc = ICMD_IF_DCMPEQ;
2079 iptr[0].op1 = iptr[1].op1;
2080 iptr[1].opc = ICMD_NOP;
2083 tbptr = m->basicblocks +
2084 m->basicblockindex[iptr[0].op1];
2086 iptr[0].target = (void *) tbptr;
2088 MARKREACHED(tbptr, copy);
2089 COUNT(count_pcmd_bra);
2092 iptr[0].opc = ICMD_IF_DCMPNE;
2093 goto icmd_if_dcmpl_tail;
2095 iptr[0].opc = ICMD_IF_DCMPL_LT;
2096 goto icmd_if_dcmpl_tail;
2098 iptr[0].opc = ICMD_IF_DCMPL_GT;
2099 goto icmd_if_dcmpl_tail;
2101 iptr[0].opc = ICMD_IF_DCMPL_LE;
2102 goto icmd_if_dcmpl_tail;
2104 iptr[0].opc = ICMD_IF_DCMPL_GE;
2105 goto icmd_if_dcmpl_tail;
2107 OPTT2_1(TYPE_DBL, TYPE_INT);
2111 OPTT2_1(TYPE_DBL, TYPE_INT);
2115 COUNT(count_pcmd_op);
2116 if ((len > 0) && (iptr[1].val.i == 0)) {
2117 switch (iptr[1].opc) {
2119 iptr[0].opc = ICMD_IF_DCMPEQ;
2121 iptr[0].op1 = iptr[1].op1;
2122 iptr[1].opc = ICMD_NOP;
2125 tbptr = m->basicblocks +
2126 m->basicblockindex[iptr[0].op1];
2128 iptr[0].target = (void *) tbptr;
2130 MARKREACHED(tbptr, copy);
2131 COUNT(count_pcmd_bra);
2134 iptr[0].opc = ICMD_IF_DCMPNE;
2135 goto icmd_if_dcmpg_tail;
2137 iptr[0].opc = ICMD_IF_DCMPG_LT;
2138 goto icmd_if_dcmpg_tail;
2140 iptr[0].opc = ICMD_IF_DCMPG_GT;
2141 goto icmd_if_dcmpg_tail;
2143 iptr[0].opc = ICMD_IF_DCMPG_LE;
2144 goto icmd_if_dcmpg_tail;
2146 iptr[0].opc = ICMD_IF_DCMPG_GE;
2147 goto icmd_if_dcmpg_tail;
2149 OPTT2_1(TYPE_DBL, TYPE_INT);
2153 OPTT2_1(TYPE_DBL, TYPE_INT);
2158 COUNT(count_pcmd_op);
2159 OPTT2_1(TYPE_FLT, TYPE_INT);
2164 COUNT(count_pcmd_op);
2165 OPTT2_1(TYPE_DBL, TYPE_INT);
2174 case ICMD_INT2SHORT:
2175 COUNT(count_pcmd_op);
2176 OP1_1(TYPE_INT, TYPE_INT);
2179 COUNT(count_pcmd_op);
2180 OP1_1(TYPE_LNG, TYPE_LNG);
2183 COUNT(count_pcmd_op);
2184 OP1_1(TYPE_FLT, TYPE_FLT);
2187 COUNT(count_pcmd_op);
2188 OP1_1(TYPE_DBL, TYPE_DBL);
2192 COUNT(count_pcmd_op);
2193 OP1_1(TYPE_INT, TYPE_LNG);
2196 COUNT(count_pcmd_op);
2197 OP1_1(TYPE_INT, TYPE_FLT);
2200 COUNT(count_pcmd_op);
2201 OP1_1(TYPE_INT, TYPE_DBL);
2204 COUNT(count_pcmd_op);
2205 OP1_1(TYPE_LNG, TYPE_INT);
2208 COUNT(count_pcmd_op);
2209 OP1_1(TYPE_LNG, TYPE_FLT);
2212 COUNT(count_pcmd_op);
2213 OP1_1(TYPE_LNG, TYPE_DBL);
2216 COUNT(count_pcmd_op);
2217 OP1_1(TYPE_FLT, TYPE_INT);
2220 COUNT(count_pcmd_op);
2221 OP1_1(TYPE_FLT, TYPE_LNG);
2224 COUNT(count_pcmd_op);
2225 OP1_1(TYPE_FLT, TYPE_DBL);
2228 COUNT(count_pcmd_op);
2229 OP1_1(TYPE_DBL, TYPE_INT);
2232 COUNT(count_pcmd_op);
2233 OP1_1(TYPE_DBL, TYPE_LNG);
2236 COUNT(count_pcmd_op);
2237 OP1_1(TYPE_DBL, TYPE_FLT);
2240 case ICMD_CHECKCAST:
2241 if (iptr->op1 == 0) {
2242 /* array type cast-check */
2244 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2247 if (md->memuse > rd->memuse)
2248 rd->memuse = md->memuse;
2249 if (md->argintreguse > rd->argintreguse)
2250 rd->argintreguse = md->argintreguse;
2252 /* make all stack variables saved */
2256 copy->flags |= SAVEDVAR;
2260 OP1_1(TYPE_ADR, TYPE_ADR);
2263 case ICMD_INSTANCEOF:
2264 case ICMD_ARRAYLENGTH:
2265 OP1_1(TYPE_ADR, TYPE_INT);
2269 case ICMD_ANEWARRAY:
2270 OP1_1(TYPE_INT, TYPE_ADR);
2274 COUNT(count_check_null);
2275 COUNT(count_pcmd_mem);
2276 OP1_1(TYPE_ADR, iptr->op1);
2281 case ICMD_GETSTATIC:
2282 COUNT(count_pcmd_mem);
2292 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
2294 iptr[0].target = (void *) tbptr;
2296 /* This is a dirty hack. The typechecker
2297 * needs it because the OP1_0ANY below
2298 * overwrites iptr->dst.
2300 iptr->val.a = (void *) iptr->dst;
2302 tbptr->type = BBTYPE_SBR;
2304 /* We need to check for overflow right here because
2305 * the pushed value is poped after MARKREACHED. */
2307 MARKREACHED(tbptr, copy);
2311 /* pop many push any */
2314 #if defined(USEBUILTINTABLE)
2317 bte = (builtintable_entry *) iptr->val.a;
2321 case ICMD_INVOKESTATIC:
2322 case ICMD_INVOKESPECIAL:
2323 case ICMD_INVOKEVIRTUAL:
2324 case ICMD_INVOKEINTERFACE:
2325 COUNT(count_pcmd_met);
2326 INSTRUCTION_GET_METHODDESC(iptr,md);
2327 /* if (lm->flags & ACC_STATIC) */
2328 /* {COUNT(count_check_null);} */
2332 last_pei = bptr->icount - len - 1;
2336 if (md->memuse > rd->memuse)
2337 rd->memuse = md->memuse;
2338 if (md->argintreguse > rd->argintreguse)
2339 rd->argintreguse = md->argintreguse;
2340 if (md->argfltreguse > rd->argfltreguse)
2341 rd->argfltreguse = md->argfltreguse;
2346 for (i-- ; i >= 0; i--) {
2347 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2348 /* If we pass float arguments in integer argument registers, we
2349 * are not allowed to precolor them here. Floats have to be moved
2350 * to this regs explicitly in codegen().
2351 * Only arguments that are passed by stack anyway can be precolored
2352 * (michi 2005/07/24) */
2353 if (!(copy->flags & SAVEDVAR) &&
2354 (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
2356 if (!(copy->flags & SAVEDVAR)) {
2358 copy->varkind = ARGVAR;
2361 #if defined(ENABLE_INTRP)
2364 if (md->params[i].inmemory) {
2365 copy->flags = INMEMORY;
2366 copy->regoff = md->params[i].regoff;
2370 if (IS_FLT_DBL_TYPE(copy->type))
2371 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2372 assert(0); /* XXX is this assert ok? */
2375 rd->argfltregs[md->params[i].regoff];
2378 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2379 if (IS_2_WORD_TYPE(copy->type))
2380 copy->regoff = PACK_REGS(
2381 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2382 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2386 rd->argintregs[md->params[i].regoff];
2389 #if defined(ENABLE_INTRP)
2397 copy->flags |= SAVEDVAR;
2403 if (md->returntype.type != TYPE_VOID)
2404 OP0_1(md->returntype.type);
2407 case ICMD_INLINE_START:
2408 case ICMD_INLINE_END:
2412 case ICMD_MULTIANEWARRAY:
2413 if (rd->argintreguse < 3)
2414 rd->argintreguse = 3;
2419 #if defined(SPECIALMEMUSE)
2420 # if defined(__DARWIN__)
2421 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
2422 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
2424 if (rd->memuse < (i + LA_WORD_SIZE + 3))
2425 rd->memuse = i + LA_WORD_SIZE + 3;
2428 # if defined(__I386__)
2429 if (rd->memuse < i + 3)
2430 rd->memuse = i + 3; /* n integer args spilled on stack */
2431 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2432 if (rd->memuse < i + 2)
2433 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2436 rd->memuse = i; /* n integer args spilled on stack */
2437 # endif /* defined(__I386__) */
2441 /* check INT type here? Currently typecheck does this. */
2442 if (!(copy->flags & SAVEDVAR)) {
2443 copy->varkind = ARGVAR;
2444 copy->varnum = i + INT_ARG_CNT;
2445 copy->flags |= INMEMORY;
2446 #if defined(SPECIALMEMUSE)
2447 # if defined(__DARWIN__)
2448 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
2450 copy->regoff = i + LA_WORD_SIZE + 3;
2453 # if defined(__I386__)
2454 copy->regoff = i + 3;
2455 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2456 copy->regoff = i + 2;
2459 # endif /* defined(__I386__) */
2460 #endif /* defined(SPECIALMEMUSE) */
2465 copy->flags |= SAVEDVAR;
2475 new_internalerror("Unknown ICMD %d", opcode);
2481 } /* while instructions */
2483 /* set out-stack of block */
2485 bptr->outstack = curstack;
2486 bptr->outdepth = stackdepth;
2488 /* stack slots at basic block end become interfaces */
2491 for (copy = curstack; copy; i--, copy = copy->prev) {
2492 if ((copy->varkind == STACKVAR) && (copy->varnum > i))
2493 copy->varkind = TEMPVAR;
2495 copy->varkind = STACKVAR;
2499 rd->interfaces[i][copy->type].type = copy->type;
2500 rd->interfaces[i][copy->type].flags |= copy->flags;
2504 /* check if interface slots at basic block begin must be saved */
2507 i = bptr->indepth - 1;
2508 for (copy = bptr->instack; copy; i--, copy = copy->prev) {
2509 rd->interfaces[i][copy->type].type = copy->type;
2510 if (copy->varkind == STACKVAR) {
2511 if (copy->flags & SAVEDVAR)
2512 rd->interfaces[i][copy->type].flags |= SAVEDVAR;
2519 superblockend = true;
2522 } /* while blocks */
2523 } while (repeat && !deadcode);
2525 #if defined(ENABLE_STATISTICS)
2527 if (m->basicblockcount > count_max_basic_blocks)
2528 count_max_basic_blocks = m->basicblockcount;
2529 count_basic_blocks += m->basicblockcount;
2530 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2531 count_javainstr += m->instructioncount;
2532 if (m->stackcount > count_upper_bound_new_stack)
2533 count_upper_bound_new_stack = m->stackcount;
2534 if ((new - m->stack) > count_max_new_stack)
2535 count_max_new_stack = (new - m->stack);
2537 b_count = m->basicblockcount;
2538 bptr = m->basicblocks;
2539 while (--b_count >= 0) {
2540 if (bptr->flags > BBREACHED) {
2541 if (bptr->indepth >= 10)
2542 count_block_stack[10]++;
2544 count_block_stack[bptr->indepth]++;
2547 count_block_size_distribution[len]++;
2549 count_block_size_distribution[10]++;
2551 count_block_size_distribution[11]++;
2553 count_block_size_distribution[12]++;
2555 count_block_size_distribution[13]++;
2557 count_block_size_distribution[14]++;
2559 count_block_size_distribution[15]++;
2561 count_block_size_distribution[16]++;
2563 count_block_size_distribution[17]++;
2569 count_analyse_iterations[0]++;
2570 else if (loops == 2)
2571 count_analyse_iterations[1]++;
2572 else if (loops == 3)
2573 count_analyse_iterations[2]++;
2574 else if (loops == 4)
2575 count_analyse_iterations[3]++;
2577 count_analyse_iterations[4]++;
2579 if (m->basicblockcount <= 5)
2580 count_method_bb_distribution[0]++;
2581 else if (m->basicblockcount <= 10)
2582 count_method_bb_distribution[1]++;
2583 else if (m->basicblockcount <= 15)
2584 count_method_bb_distribution[2]++;
2585 else if (m->basicblockcount <= 20)
2586 count_method_bb_distribution[3]++;
2587 else if (m->basicblockcount <= 30)
2588 count_method_bb_distribution[4]++;
2589 else if (m->basicblockcount <= 40)
2590 count_method_bb_distribution[5]++;
2591 else if (m->basicblockcount <= 50)
2592 count_method_bb_distribution[6]++;
2593 else if (m->basicblockcount <= 75)
2594 count_method_bb_distribution[7]++;
2596 count_method_bb_distribution[8]++;
2598 #endif /* defined(ENABLE_STATISTICS) */
2600 /* everything's ok */
2604 #if defined(ENABLE_VERIFIER)
2606 throw_stack_underflow:
2608 new_verifyerror(m, "Unable to pop operand off an empty stack");
2611 throw_stack_overflow:
2612 *exceptionptr = new_verifyerror(m, "Stack size too large");
2615 throw_stack_depth_error:
2616 *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
2619 throw_stack_type_error:
2620 exceptions_throw_verifyerror_for_stack(m, expectedtype);
2623 throw_stack_category_error:
2625 new_verifyerror(m, "Attempt to split long or double on the stack");
2634 * These are local overrides for various environment variables in Emacs.
2635 * Please do not remove this and leave it at the end of the file, where
2636 * Emacs will automagically detect them.
2637 * ---------------------------------------------------------------------
2640 * indent-tabs-mode: t
2644 * vim:noexpandtab:sw=4:ts=4: