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 5097 2006-07-10 14:11:07Z 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"
60 #include "vm/jit/show.h"
62 #if defined(ENABLE_DISASSEMBLER)
63 # include "vm/jit/disass.h"
66 #include "vm/jit/jit.h"
67 #include "vm/jit/stack.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 /*#define STACK_VERBOSE*/
76 /* macro for saving #ifdefs ***************************************************/
78 #if defined(ENABLE_INTRP)
79 #define IF_INTRP(x) if (opt_intrp) { x }
80 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
83 #define IF_NO_INTRP(x) { x }
86 #if defined(ENABLE_INTRP)
87 #if defined(ENABLE_JIT)
88 #define IF_JIT(x) if (!opt_intrp) { x }
92 #else /* !defined(ENABLE_INTRP) */
93 #define IF_JIT(x) { x }
94 #endif /* defined(ENABLE_INTRP) */
96 #if defined(ENABLE_STATISTICS)
97 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
100 if (stackdepth >= 10) \
101 count_store_depth[10]++; \
103 count_store_depth[stackdepth]++; \
106 #else /* !defined(ENABLE_STATISTICS) */
107 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
110 /* stack_init ******************************************************************
112 Initialized the stack analysis subsystem (called by jit_init).
114 *******************************************************************************/
116 bool stack_init(void)
122 /* stack_analyse ***************************************************************
124 Analyse_stack uses the intermediate code created by parse.c to
125 build a model of the JVM operand stack for the current method.
127 The following checks are performed:
128 - check for operand stack underflow (before each instruction)
129 - check for operand stack overflow (after[1] each instruction)
130 - check for matching stack depth at merging points
131 - check for matching basic types[2] at merging points
132 - check basic types for instruction input (except for BUILTIN*
133 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
135 [1]) Checking this after the instruction should be ok. parse.c
136 counts the number of required stack slots in such a way that it is
137 only vital that we don't exceed `maxstack` at basic block
140 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
141 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
142 types are not discerned.
144 *******************************************************************************/
146 #define BLOCK_OF(index) \
147 (jd->new_basicblocks + jd->new_basicblockindex[index])
150 (iptr->s1.var = NULL)
152 #define USE_S1_LOCAL(type1)
154 #define USE_S1(type1) \
157 CHECK_BASIC_TYPE(type1, curstack->type); \
158 iptr->s1.var = curstack; \
164 iptr->s1.var = curstack; \
167 #define USE_S1_S2(type1, type2) \
170 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
171 CHECK_BASIC_TYPE(type2, curstack->type); \
172 iptr->sx.s23.s2.var = curstack; \
173 iptr->s1.var = curstack->prev; \
176 #define USE_S1_S2_ANY_ANY \
179 iptr->sx.s23.s2.var = curstack; \
180 iptr->s1.var = curstack->prev; \
183 #define USE_S1_S2_S3(type1, type2, type3) \
186 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
187 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
188 CHECK_BASIC_TYPE(type3, curstack->type); \
189 iptr->sx.s23.s3.var = curstack; \
190 iptr->sx.s23.s2.var = curstack->prev; \
191 iptr->s1.var = curstack->prev->prev; \
194 #define POP_S1(type1) \
197 if (curstack->varkind == UNDEFVAR) \
198 curstack->varkind = TEMPVAR; \
199 curstack = curstack->prev; \
205 if (curstack->varkind == UNDEFVAR) \
206 curstack->varkind = TEMPVAR; \
207 curstack = curstack->prev; \
210 #define POP_S1_S2(type1, type2) \
212 USE_S1_S2(type1, type2); \
213 if (curstack->varkind == UNDEFVAR) \
214 curstack->varkind = TEMPVAR; \
215 if (curstack->prev->varkind == UNDEFVAR) \
216 curstack->prev->varkind = TEMPVAR; \
217 curstack = curstack->prev->prev; \
220 #define POP_S1_S2_ANY_ANY \
223 if (curstack->varkind == UNDEFVAR) \
224 curstack->varkind = TEMPVAR; \
225 if (curstack->prev->varkind == UNDEFVAR) \
226 curstack->prev->varkind = TEMPVAR; \
227 curstack = curstack->prev->prev; \
230 #define POP_S1_S2_S3(type1, type2, type3) \
232 USE_S1_S2_S3(type1, type2, type3); \
233 if (curstack->varkind == UNDEFVAR) \
234 curstack->varkind = TEMPVAR; \
235 if (curstack->prev->varkind == UNDEFVAR) \
236 curstack->prev->varkind = TEMPVAR; \
237 if (curstack->prev->prev->varkind == UNDEFVAR) \
238 curstack->prev->prev->varkind = TEMPVAR; \
239 curstack = curstack->prev->prev->prev; \
246 (iptr->dst.var = NULL)
248 #define NEW_DST(typed, depth) \
250 NEWSTACKn(typed, (depth)); \
251 iptr->dst.var = curstack; \
254 #define NEW_DST_LOCALVAR(typed, index) \
256 NEWSTACK(typed, LOCALVAR, (index)); \
257 iptr->dst.var = curstack; \
266 #define NEW_OP0_BRANCH \
271 #define NEW_OP0_1(typed) \
274 NEW_DST(typed, stackdepth); \
278 #define NEW_OP1_0(type1) \
285 #define NEW_OP1_0_ANY \
292 #define NEW_OP1_BRANCH(type1) \
298 #define NEW_OP1_1(type1, typed) \
301 NEW_DST(typed, stackdepth - 1); \
304 #define NEW_OP2_0(type1, type2) \
306 POP_S1_S2(type1, type2); \
311 #define NEW_OP2_BRANCH(type1, type2) \
313 POP_S1_S2(type1, type2); \
317 #define NEW_OP2_0_ANY_ANY \
324 #define NEW_OP2_1(type1, type2, typed) \
326 POP_S1_S2(type1, type2); \
327 NEW_DST(typed, stackdepth - 2); \
331 #define NEW_OP3_0(type1, type2, type3) \
333 POP_S1_S2_S3(type1, type2, type3); \
338 #define NEW_LOAD(type1, index) \
340 NEW_DST_LOCALVAR(type1, index); \
344 #define NEW_STORE(type1, index) \
350 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
352 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
353 MARKREACHED(tempbptr, tempsp); \
356 #define BRANCH(tempbptr, tempsp) \
358 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
359 MARKREACHED(tempbptr, tempsp); \
362 #define DUP_SLOT(sp) \
364 if ((sp)->varkind == STACKVAR) \
365 NEWSTACK((sp)->type, TEMPVAR, stackdepth); \
367 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
370 bool new_stack_analyse(jitdata *jd)
372 methodinfo *m; /* method being analyzed */
376 int b_count; /* basic block counter */
377 int b_index; /* basic block index */
379 stackptr curstack; /* current stack top */
382 int opcode; /* opcode of current instruction */
384 int len; /* # of instructions after the current one */
385 bool superblockend; /* if true, no fallthrough to next block */
386 bool repeat; /* if true, outermost loop must run again */
387 bool deadcode; /* true if no live code has been reached */
388 new_instruction *iptr; /* the current instruction */
389 basicblock *bptr; /* the current basic block */
391 s4 *last_store; /* instruction index of last XSTORE */
392 /* [ local_index * 5 + type ] */
393 s4 last_pei; /* ins. index of last possible exception */
394 /* used for conflict resolution for copy */
395 /* elimination (XLOAD, IINC, XSTORE) */
397 branch_target_t *table;
398 lookup_target_t *lookup;
399 #if defined(ENABLE_VERIFIER)
400 int expectedtype; /* used by CHECK_BASIC_TYPE */
402 builtintable_entry *bte;
404 constant_FMIref *fmiref;
405 #if defined(ENABLE_STATISTICS)
406 int iteration_count; /* number of iterations of analysis */
409 #if defined(STACK_VERBOSE)
410 new_show_method(jd, SHOW_PARSE);
413 /* get required compiler data - initialization */
420 #if defined(ENABLE_LSRA)
424 #if defined(ENABLE_STATISTICS)
428 last_store = DMNEW(s4 , cd->maxlocals * 5);
430 /* initialize in-stack of first block */
433 jd->new_basicblocks[0].flags = BBREACHED;
434 jd->new_basicblocks[0].instack = 0;
435 jd->new_basicblocks[0].indepth = 0;
437 /* initialize in-stack of exception handlers */
439 for (i = 0; i < cd->exceptiontablelength; i++) {
440 bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
441 bptr->flags = BBREACHED;
442 bptr->type = BBTYPE_EXH;
445 bptr->pre_count = 10000;
450 /* count predecessors of each block **************************************/
452 #if CONDITIONAL_LOADCONST
453 /* XXX move this to a separate function */
455 b_count = jd->new_basicblockcount;
456 bptr = jd->new_basicblocks;
457 for (; --b_count >= 0; bptr++) {
458 if (bptr->icount == 0)
461 /* get the last instruction of the block */
463 iptr = /* XXX */ (new_instruction *) bptr->iinstr + (bptr->icount - 1);
466 /* instruction stopping control flow */
477 /* conditional branches */
494 /* XXX add missing conditional branches */
498 /* unconditional branch */
500 BLOCK_OF(iptr->dst.insindex)->pre_count++;
504 case ICMD_TABLESWITCH:
505 table = iptr->dst.table;
506 BLOCK_OF((table++)->insindex)->pre_count++;
507 i = iptr->sx.s23.s3.tablehigh
508 - iptr->sx.s23.s2.tablelow + 1;
510 BLOCK_OF((table++)->insindex)->pre_count++;
514 case ICMD_LOOKUPSWITCH:
515 lookup = iptr->dst.lookup;
516 BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->pre_count++;
517 i = iptr->sx.s23.s2.lookupcount;
519 BLOCK_OF((lookup++)->target.insindex)->pre_count++;
523 /* default - fall into next block */
528 } /* end basic block loop */
530 #endif /* CONDITIONAL_LOADCONST */
532 /* stack analysis loop (until fixpoint reached) **************************/
535 #if defined(ENABLE_STATISTICS)
539 /* initialize loop over basic blocks */
541 b_count = jd->new_basicblockcount;
542 bptr = jd->new_basicblocks;
543 superblockend = true;
548 /* iterate over basic blocks *****************************************/
550 while (--b_count >= 0) {
551 #if defined(STACK_VERBOSE)
552 printf("ANALYZING BLOCK L%03d\n", bptr->debug_nr);
555 if (bptr->flags == BBDELETED) {
556 /* This block has been deleted - do nothing. */
558 else if (superblockend && (bptr->flags < BBREACHED)) {
559 /* This block has not been reached so far, and we */
560 /* don't fall into it, so we'll have to iterate again. */
563 else if (bptr->flags <= BBREACHED) {
565 /* We know that bptr->flags == BBREACHED. */
566 /* This block has been reached before. */
567 stackdepth = bptr->indepth;
569 else if (bptr->flags < BBREACHED) {
570 /* This block is reached for the first time now */
571 /* by falling through from the previous block. */
573 bptr->instack = copy;
574 bptr->indepth = stackdepth;
577 /* This block has been reached before. now we are */
578 /* falling into it from the previous block. */
579 /* Check that stack depth is well-defined. */
580 CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
583 /* set up local variables for analyzing this block */
585 curstack = bptr->instack;
587 superblockend = false;
588 bptr->flags = BBFINISHED;
590 iptr = /* XXX */ (new_instruction *) bptr->iinstr;
591 b_index = bptr - jd->new_basicblocks;
593 /* reset variables for dependency checking */
597 for( i = 0; i < cd->maxlocals; i++)
598 for( j = 0; j < 5; j++)
599 last_store[5 * i + j] = -1;
601 /* XXX store the start of the block's stack representation */
605 /* iterate over ICMDs ****************************************/
608 #if defined(STACK_VERBOSE)
609 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
610 for( copy = curstack; copy; copy = copy->prev ) {
611 printf("%d ", copy->type);
616 /* fetch the current opcode */
620 /* automatically replace some ICMDs with builtins */
622 #if defined(USEBUILTINTABLE)
624 bte = builtintable_get_automatic(opcode);
626 if (bte && bte->opcode == opcode) {
627 iptr->opc = ICMD_BUILTIN;
628 iptr->flags.bits = INS_FLAG_NOCHECK;
629 iptr->sx.s23.s3.bte = bte;
630 /* iptr->line is already set */
631 jd->isleafmethod = false;
635 #endif /* defined(USEBUILTINTABLE) */
637 /* main opcode switch *************************************/
650 COUNT(count_check_null);
653 CLR_DST; /* XXX live through? */
656 case ICMD_IFEQ_ICONST:
657 case ICMD_IFNE_ICONST:
658 case ICMD_IFLT_ICONST:
659 case ICMD_IFGE_ICONST:
660 case ICMD_IFGT_ICONST:
661 case ICMD_IFLE_ICONST:
662 case ICMD_ELSE_ICONST:
665 CLR_DST; /* XXX live through? */
669 USE_S1_LOCAL(TYPE_ADR);
672 IF_NO_INTRP( rd->locals[iptr->s1.localindex][TYPE_ADR].type = TYPE_ADR; );
673 superblockend = true;
677 COUNT(count_pcmd_return);
680 superblockend = true;
684 /* pop 0 push 1 const */
686 /************************** ICONST OPTIMIZATIONS **************************/
689 COUNT(count_pcmd_load);
693 switch (iptr[1].opc) {
695 iptr->opc = ICMD_IADDCONST;
699 iptr[1].opc = ICMD_NOP;
700 NEW_OP1_1(TYPE_INT, TYPE_INT);
701 COUNT(count_pcmd_op);
705 iptr->opc = ICMD_ISUBCONST;
706 goto icmd_iconst_tail;
707 #if SUPPORT_CONST_MUL
709 iptr->opc = ICMD_IMULCONST;
710 goto icmd_iconst_tail;
711 #else /* SUPPORT_CONST_MUL */
713 if (iptr->sx.val.i == 0x00000002)
715 else if (iptr->sx.val.i == 0x00000004)
717 else if (iptr->sx.val.i == 0x00000008)
719 else if (iptr->sx.val.i == 0x00000010)
721 else if (iptr->sx.val.i == 0x00000020)
723 else if (iptr->sx.val.i == 0x00000040)
725 else if (iptr->sx.val.i == 0x00000080)
727 else if (iptr->sx.val.i == 0x00000100)
729 else if (iptr->sx.val.i == 0x00000200)
731 else if (iptr->sx.val.i == 0x00000400)
733 else if (iptr->sx.val.i == 0x00000800)
735 else if (iptr->sx.val.i == 0x00001000)
737 else if (iptr->sx.val.i == 0x00002000)
739 else if (iptr->sx.val.i == 0x00004000)
741 else if (iptr->sx.val.i == 0x00008000)
743 else if (iptr->sx.val.i == 0x00010000)
745 else if (iptr->sx.val.i == 0x00020000)
747 else if (iptr->sx.val.i == 0x00040000)
749 else if (iptr->sx.val.i == 0x00080000)
751 else if (iptr->sx.val.i == 0x00100000)
753 else if (iptr->sx.val.i == 0x00200000)
755 else if (iptr->sx.val.i == 0x00400000)
757 else if (iptr->sx.val.i == 0x00800000)
759 else if (iptr->sx.val.i == 0x01000000)
761 else if (iptr->sx.val.i == 0x02000000)
763 else if (iptr->sx.val.i == 0x04000000)
765 else if (iptr->sx.val.i == 0x08000000)
767 else if (iptr->sx.val.i == 0x10000000)
769 else if (iptr->sx.val.i == 0x20000000)
771 else if (iptr->sx.val.i == 0x40000000)
773 else if (iptr->sx.val.i == 0x80000000)
778 iptr->opc = ICMD_IMULPOW2;
779 goto icmd_iconst_tail;
780 #endif /* SUPPORT_CONST_MUL */
782 if (iptr->sx.val.i == 0x00000002)
784 else if (iptr->sx.val.i == 0x00000004)
786 else if (iptr->sx.val.i == 0x00000008)
788 else if (iptr->sx.val.i == 0x00000010)
790 else if (iptr->sx.val.i == 0x00000020)
792 else if (iptr->sx.val.i == 0x00000040)
794 else if (iptr->sx.val.i == 0x00000080)
796 else if (iptr->sx.val.i == 0x00000100)
798 else if (iptr->sx.val.i == 0x00000200)
800 else if (iptr->sx.val.i == 0x00000400)
802 else if (iptr->sx.val.i == 0x00000800)
804 else if (iptr->sx.val.i == 0x00001000)
806 else if (iptr->sx.val.i == 0x00002000)
808 else if (iptr->sx.val.i == 0x00004000)
810 else if (iptr->sx.val.i == 0x00008000)
812 else if (iptr->sx.val.i == 0x00010000)
814 else if (iptr->sx.val.i == 0x00020000)
816 else if (iptr->sx.val.i == 0x00040000)
818 else if (iptr->sx.val.i == 0x00080000)
820 else if (iptr->sx.val.i == 0x00100000)
822 else if (iptr->sx.val.i == 0x00200000)
824 else if (iptr->sx.val.i == 0x00400000)
826 else if (iptr->sx.val.i == 0x00800000)
828 else if (iptr->sx.val.i == 0x01000000)
830 else if (iptr->sx.val.i == 0x02000000)
832 else if (iptr->sx.val.i == 0x04000000)
834 else if (iptr->sx.val.i == 0x08000000)
836 else if (iptr->sx.val.i == 0x10000000)
838 else if (iptr->sx.val.i == 0x20000000)
840 else if (iptr->sx.val.i == 0x40000000)
842 else if (iptr->sx.val.i == 0x80000000)
847 iptr->opc = ICMD_IDIVPOW2;
848 goto icmd_iconst_tail;
851 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
852 if ((iptr->sx.val.i == 0x00000002) ||
853 (iptr->sx.val.i == 0x00000004) ||
854 (iptr->sx.val.i == 0x00000008) ||
855 (iptr->sx.val.i == 0x00000010) ||
856 (iptr->sx.val.i == 0x00000020) ||
857 (iptr->sx.val.i == 0x00000040) ||
858 (iptr->sx.val.i == 0x00000080) ||
859 (iptr->sx.val.i == 0x00000100) ||
860 (iptr->sx.val.i == 0x00000200) ||
861 (iptr->sx.val.i == 0x00000400) ||
862 (iptr->sx.val.i == 0x00000800) ||
863 (iptr->sx.val.i == 0x00001000) ||
864 (iptr->sx.val.i == 0x00002000) ||
865 (iptr->sx.val.i == 0x00004000) ||
866 (iptr->sx.val.i == 0x00008000) ||
867 (iptr->sx.val.i == 0x00010000) ||
868 (iptr->sx.val.i == 0x00020000) ||
869 (iptr->sx.val.i == 0x00040000) ||
870 (iptr->sx.val.i == 0x00080000) ||
871 (iptr->sx.val.i == 0x00100000) ||
872 (iptr->sx.val.i == 0x00200000) ||
873 (iptr->sx.val.i == 0x00400000) ||
874 (iptr->sx.val.i == 0x00800000) ||
875 (iptr->sx.val.i == 0x01000000) ||
876 (iptr->sx.val.i == 0x02000000) ||
877 (iptr->sx.val.i == 0x04000000) ||
878 (iptr->sx.val.i == 0x08000000) ||
879 (iptr->sx.val.i == 0x10000000) ||
880 (iptr->sx.val.i == 0x20000000) ||
881 (iptr->sx.val.i == 0x40000000) ||
882 (iptr->sx.val.i == 0x80000000))
884 iptr->opc = ICMD_IREMPOW2;
886 goto icmd_iconst_tail;
889 #if SUPPORT_CONST_LOGICAL
891 iptr->opc = ICMD_IANDCONST;
892 goto icmd_iconst_tail;
895 iptr->opc = ICMD_IORCONST;
896 goto icmd_iconst_tail;
899 iptr->opc = ICMD_IXORCONST;
900 goto icmd_iconst_tail;
902 #endif /* SUPPORT_CONST_LOGICAL */
904 iptr->opc = ICMD_ISHLCONST;
905 goto icmd_iconst_tail;
908 iptr->opc = ICMD_ISHRCONST;
909 goto icmd_iconst_tail;
912 iptr->opc = ICMD_IUSHRCONST;
913 goto icmd_iconst_tail;
914 #if SUPPORT_LONG_SHIFT
916 iptr->opc = ICMD_LSHLCONST;
917 goto icmd_lconst_tail;
920 iptr->opc = ICMD_LSHRCONST;
921 goto icmd_lconst_tail;
924 iptr->opc = ICMD_LUSHRCONST;
925 goto icmd_lconst_tail;
926 #endif /* SUPPORT_LONG_SHIFT */
928 iptr[1].opc = ICMD_IFEQ;
932 /* set the constant for the following icmd */
933 iptr[1].sx.val.i = iptr->sx.val.i;
935 /* this instruction becomes a nop */
936 iptr->opc = ICMD_NOP;
940 iptr[1].opc = ICMD_IFLT;
941 goto icmd_if_icmp_tail;
944 iptr[1].opc = ICMD_IFLE;
945 goto icmd_if_icmp_tail;
948 iptr[1].opc = ICMD_IFNE;
949 goto icmd_if_icmp_tail;
952 iptr[1].opc = ICMD_IFGT;
953 goto icmd_if_icmp_tail;
956 iptr[1].opc = ICMD_IFGE;
957 goto icmd_if_icmp_tail;
959 #if SUPPORT_CONST_STORE
964 IF_INTRP( goto normal_ICONST; )
965 # if SUPPORT_CONST_STORE_ZERO_ONLY
966 if (iptr->sx.val.i != 0)
969 switch (iptr[1].opc) {
971 iptr->opc = ICMD_IASTORECONST;
974 iptr->opc = ICMD_BASTORECONST;
977 iptr->opc = ICMD_CASTORECONST;
980 iptr->opc = ICMD_SASTORECONST;
984 iptr[1].opc = ICMD_NOP;
986 /* copy the constant to s3 */
987 /* XXX constval -> astoreconstval? */
988 iptr->sx.s23.s3.constval = iptr->sx.val.i;
989 NEW_OP2_0(TYPE_ADR, TYPE_INT);
990 COUNT(count_pcmd_op);
995 IF_INTRP( goto normal_ICONST; )
996 # if SUPPORT_CONST_STORE_ZERO_ONLY
997 if (iptr->sx.val.i != 0)
1000 /* XXX check field type? */
1002 /* copy the constant to s2 */
1003 /* XXX constval -> fieldconstval? */
1004 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1007 /* set the field reference (s3) */
1008 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED)
1009 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1011 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1013 switch (iptr[1].opc) {
1014 case ICMD_PUTSTATIC:
1015 iptr->opc = ICMD_PUTSTATICCONST;
1019 iptr->opc = ICMD_PUTFIELDCONST;
1020 NEW_OP1_0(TYPE_ADR);
1024 iptr[1].opc = ICMD_NOP;
1025 COUNT(count_pcmd_op);
1027 #endif /* SUPPORT_CONST_STORE */
1033 /* if we get here, the ICONST has been optimized */
1037 /* normal case of an unoptimized ICONST */
1038 NEW_OP0_1(TYPE_INT);
1041 /************************** LCONST OPTIMIZATIONS **************************/
1044 COUNT(count_pcmd_load);
1048 /* switch depending on the following instruction */
1050 switch (iptr[1].opc) {
1051 #if SUPPORT_LONG_ADD
1053 iptr->opc = ICMD_LADDCONST;
1057 /* instruction of type LONG -> LONG */
1058 iptr[1].opc = ICMD_NOP;
1059 NEW_OP1_1(TYPE_LNG, TYPE_LNG);
1060 COUNT(count_pcmd_op);
1064 iptr->opc = ICMD_LSUBCONST;
1065 goto icmd_lconst_tail;
1067 #endif /* SUPPORT_LONG_ADD */
1068 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1070 iptr->opc = ICMD_LMULCONST;
1071 goto icmd_lconst_tail;
1072 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1073 # if SUPPORT_LONG_SHIFT
1075 if (iptr->sx.val.l == 0x00000002)
1077 else if (iptr->sx.val.l == 0x00000004)
1079 else if (iptr->sx.val.l == 0x00000008)
1081 else if (iptr->sx.val.l == 0x00000010)
1083 else if (iptr->sx.val.l == 0x00000020)
1085 else if (iptr->sx.val.l == 0x00000040)
1087 else if (iptr->sx.val.l == 0x00000080)
1089 else if (iptr->sx.val.l == 0x00000100)
1091 else if (iptr->sx.val.l == 0x00000200)
1093 else if (iptr->sx.val.l == 0x00000400)
1094 iptr->sx.val.i = 10;
1095 else if (iptr->sx.val.l == 0x00000800)
1096 iptr->sx.val.i = 11;
1097 else if (iptr->sx.val.l == 0x00001000)
1098 iptr->sx.val.i = 12;
1099 else if (iptr->sx.val.l == 0x00002000)
1100 iptr->sx.val.i = 13;
1101 else if (iptr->sx.val.l == 0x00004000)
1102 iptr->sx.val.i = 14;
1103 else if (iptr->sx.val.l == 0x00008000)
1104 iptr->sx.val.i = 15;
1105 else if (iptr->sx.val.l == 0x00010000)
1106 iptr->sx.val.i = 16;
1107 else if (iptr->sx.val.l == 0x00020000)
1108 iptr->sx.val.i = 17;
1109 else if (iptr->sx.val.l == 0x00040000)
1110 iptr->sx.val.i = 18;
1111 else if (iptr->sx.val.l == 0x00080000)
1112 iptr->sx.val.i = 19;
1113 else if (iptr->sx.val.l == 0x00100000)
1114 iptr->sx.val.i = 20;
1115 else if (iptr->sx.val.l == 0x00200000)
1116 iptr->sx.val.i = 21;
1117 else if (iptr->sx.val.l == 0x00400000)
1118 iptr->sx.val.i = 22;
1119 else if (iptr->sx.val.l == 0x00800000)
1120 iptr->sx.val.i = 23;
1121 else if (iptr->sx.val.l == 0x01000000)
1122 iptr->sx.val.i = 24;
1123 else if (iptr->sx.val.l == 0x02000000)
1124 iptr->sx.val.i = 25;
1125 else if (iptr->sx.val.l == 0x04000000)
1126 iptr->sx.val.i = 26;
1127 else if (iptr->sx.val.l == 0x08000000)
1128 iptr->sx.val.i = 27;
1129 else if (iptr->sx.val.l == 0x10000000)
1130 iptr->sx.val.i = 28;
1131 else if (iptr->sx.val.l == 0x20000000)
1132 iptr->sx.val.i = 29;
1133 else if (iptr->sx.val.l == 0x40000000)
1134 iptr->sx.val.i = 30;
1135 else if (iptr->sx.val.l == 0x80000000)
1136 iptr->sx.val.i = 31;
1140 iptr->opc = ICMD_LMULPOW2;
1141 goto icmd_lconst_tail;
1142 # endif /* SUPPORT_LONG_SHIFT */
1143 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1144 #if SUPPORT_LONG_DIV_POW2
1146 if (iptr->sx.val.l == 0x00000002)
1148 else if (iptr->sx.val.l == 0x00000004)
1150 else if (iptr->sx.val.l == 0x00000008)
1152 else if (iptr->sx.val.l == 0x00000010)
1154 else if (iptr->sx.val.l == 0x00000020)
1156 else if (iptr->sx.val.l == 0x00000040)
1158 else if (iptr->sx.val.l == 0x00000080)
1160 else if (iptr->sx.val.l == 0x00000100)
1162 else if (iptr->sx.val.l == 0x00000200)
1164 else if (iptr->sx.val.l == 0x00000400)
1165 iptr->sx.val.i = 10;
1166 else if (iptr->sx.val.l == 0x00000800)
1167 iptr->sx.val.i = 11;
1168 else if (iptr->sx.val.l == 0x00001000)
1169 iptr->sx.val.i = 12;
1170 else if (iptr->sx.val.l == 0x00002000)
1171 iptr->sx.val.i = 13;
1172 else if (iptr->sx.val.l == 0x00004000)
1173 iptr->sx.val.i = 14;
1174 else if (iptr->sx.val.l == 0x00008000)
1175 iptr->sx.val.i = 15;
1176 else if (iptr->sx.val.l == 0x00010000)
1177 iptr->sx.val.i = 16;
1178 else if (iptr->sx.val.l == 0x00020000)
1179 iptr->sx.val.i = 17;
1180 else if (iptr->sx.val.l == 0x00040000)
1181 iptr->sx.val.i = 18;
1182 else if (iptr->sx.val.l == 0x00080000)
1183 iptr->sx.val.i = 19;
1184 else if (iptr->sx.val.l == 0x00100000)
1185 iptr->sx.val.i = 20;
1186 else if (iptr->sx.val.l == 0x00200000)
1187 iptr->sx.val.i = 21;
1188 else if (iptr->sx.val.l == 0x00400000)
1189 iptr->sx.val.i = 22;
1190 else if (iptr->sx.val.l == 0x00800000)
1191 iptr->sx.val.i = 23;
1192 else if (iptr->sx.val.l == 0x01000000)
1193 iptr->sx.val.i = 24;
1194 else if (iptr->sx.val.l == 0x02000000)
1195 iptr->sx.val.i = 25;
1196 else if (iptr->sx.val.l == 0x04000000)
1197 iptr->sx.val.i = 26;
1198 else if (iptr->sx.val.l == 0x08000000)
1199 iptr->sx.val.i = 27;
1200 else if (iptr->sx.val.l == 0x10000000)
1201 iptr->sx.val.i = 28;
1202 else if (iptr->sx.val.l == 0x20000000)
1203 iptr->sx.val.i = 29;
1204 else if (iptr->sx.val.l == 0x40000000)
1205 iptr->sx.val.i = 30;
1206 else if (iptr->sx.val.l == 0x80000000)
1207 iptr->sx.val.i = 31;
1211 iptr->opc = ICMD_LDIVPOW2;
1212 goto icmd_lconst_tail;
1213 #endif /* SUPPORT_LONG_DIV_POW2 */
1215 #if SUPPORT_LONG_REM_POW2
1217 if ((iptr->sx.val.l == 0x00000002) ||
1218 (iptr->sx.val.l == 0x00000004) ||
1219 (iptr->sx.val.l == 0x00000008) ||
1220 (iptr->sx.val.l == 0x00000010) ||
1221 (iptr->sx.val.l == 0x00000020) ||
1222 (iptr->sx.val.l == 0x00000040) ||
1223 (iptr->sx.val.l == 0x00000080) ||
1224 (iptr->sx.val.l == 0x00000100) ||
1225 (iptr->sx.val.l == 0x00000200) ||
1226 (iptr->sx.val.l == 0x00000400) ||
1227 (iptr->sx.val.l == 0x00000800) ||
1228 (iptr->sx.val.l == 0x00001000) ||
1229 (iptr->sx.val.l == 0x00002000) ||
1230 (iptr->sx.val.l == 0x00004000) ||
1231 (iptr->sx.val.l == 0x00008000) ||
1232 (iptr->sx.val.l == 0x00010000) ||
1233 (iptr->sx.val.l == 0x00020000) ||
1234 (iptr->sx.val.l == 0x00040000) ||
1235 (iptr->sx.val.l == 0x00080000) ||
1236 (iptr->sx.val.l == 0x00100000) ||
1237 (iptr->sx.val.l == 0x00200000) ||
1238 (iptr->sx.val.l == 0x00400000) ||
1239 (iptr->sx.val.l == 0x00800000) ||
1240 (iptr->sx.val.l == 0x01000000) ||
1241 (iptr->sx.val.l == 0x02000000) ||
1242 (iptr->sx.val.l == 0x04000000) ||
1243 (iptr->sx.val.l == 0x08000000) ||
1244 (iptr->sx.val.l == 0x10000000) ||
1245 (iptr->sx.val.l == 0x20000000) ||
1246 (iptr->sx.val.l == 0x40000000) ||
1247 (iptr->sx.val.l == 0x80000000))
1249 iptr->opc = ICMD_LREMPOW2;
1250 iptr->sx.val.l -= 1;
1251 goto icmd_lconst_tail;
1254 #endif /* SUPPORT_LONG_REM_POW2 */
1256 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1259 iptr->opc = ICMD_LANDCONST;
1260 goto icmd_lconst_tail;
1263 iptr->opc = ICMD_LORCONST;
1264 goto icmd_lconst_tail;
1267 iptr->opc = ICMD_LXORCONST;
1268 goto icmd_lconst_tail;
1269 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1271 #if SUPPORT_LONG_CMP_CONST
1273 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1276 /* switch on the instruction after LCONST - LCMP */
1278 switch (iptr[2].opc) {
1280 iptr->opc = ICMD_IF_LEQ;
1283 icmd_lconst_lcmp_tail:
1284 /* convert LCONST, LCMP, IFXX to IF_LXX */
1285 iptr->dst.insindex = iptr[2].dst.insindex;
1286 iptr[1].opc = ICMD_NOP;
1287 iptr[2].opc = ICMD_NOP;
1289 NEW_OP1_BRANCH(TYPE_LNG);
1290 BRANCH(tbptr, copy);
1291 COUNT(count_pcmd_bra);
1292 COUNT(count_pcmd_op);
1296 iptr->opc = ICMD_IF_LNE;
1297 goto icmd_lconst_lcmp_tail;
1300 iptr->opc = ICMD_IF_LLT;
1301 goto icmd_lconst_lcmp_tail;
1304 iptr->opc = ICMD_IF_LGT;
1305 goto icmd_lconst_lcmp_tail;
1308 iptr->opc = ICMD_IF_LLE;
1309 goto icmd_lconst_lcmp_tail;
1312 iptr->opc = ICMD_IF_LGE;
1313 goto icmd_lconst_lcmp_tail;
1317 } /* end switch on opcode after LCONST - LCMP */
1319 #endif /* SUPPORT_LONG_CMP_CONST */
1321 #if SUPPORT_CONST_STORE
1323 IF_INTRP( goto normal_LCONST; )
1324 # if SUPPORT_CONST_STORE_ZERO_ONLY
1325 if (iptr->sx.val.l != 0)
1328 #if SIZEOF_VOID_P == 4
1329 /* the constant must fit into a ptrint */
1330 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1333 /* move the constant to s3 */
1334 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1336 iptr->opc = ICMD_LASTORECONST;
1337 NEW_OP2_0(TYPE_ADR, TYPE_INT);
1339 iptr[1].opc = ICMD_NOP;
1340 COUNT(count_pcmd_op);
1343 case ICMD_PUTSTATIC:
1345 IF_INTRP( goto normal_LCONST; )
1346 # if SUPPORT_CONST_STORE_ZERO_ONLY
1347 if (iptr->sx.val.l != 0)
1350 #if SIZEOF_VOID_P == 4
1351 /* the constant must fit into a ptrint */
1352 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1355 /* XXX check field type? */
1357 /* copy the constant to s2 */
1358 /* XXX constval -> fieldconstval? */
1359 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1363 #endif /* SUPPORT_CONST_STORE */
1367 } /* end switch opcode after LCONST */
1369 /* if we get here, the LCONST has been optimized */
1373 /* the normal case of an unoptimized LCONST */
1374 NEW_OP0_1(TYPE_LNG);
1377 /************************ END OF LCONST OPTIMIZATIONS *********************/
1380 COUNT(count_pcmd_load);
1381 NEW_OP0_1(TYPE_FLT);
1385 COUNT(count_pcmd_load);
1386 NEW_OP0_1(TYPE_DBL);
1389 /************************** ACONST OPTIMIZATIONS **************************/
1392 COUNT(count_pcmd_load);
1393 #if SUPPORT_CONST_STORE
1394 IF_INTRP( goto normal_ACONST; )
1396 /* We can only optimize if the ACONST is resolved
1397 * and there is an instruction after it. */
1399 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1402 switch (iptr[1].opc) {
1404 /* We can only optimize for NULL values
1405 * here because otherwise a checkcast is
1407 if (iptr->sx.val.anyptr != NULL)
1410 /* copy the constant (NULL) to s3 */
1411 iptr->sx.s23.s3.constval = 0;
1412 iptr->opc = ICMD_AASTORECONST;
1413 NEW_OP2_0(TYPE_ADR, TYPE_INT);
1415 iptr[1].opc = ICMD_NOP;
1416 COUNT(count_pcmd_op);
1419 case ICMD_PUTSTATIC:
1421 # if SUPPORT_CONST_STORE_ZERO_ONLY
1422 if (iptr->sx.val.anyptr != NULL)
1425 /* XXX check field type? */
1426 /* copy the constant to s2 */
1427 /* XXX constval -> fieldconstval? */
1428 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1436 /* if we get here the ACONST has been optimized */
1440 #endif /* SUPPORT_CONST_STORE */
1441 NEW_OP0_1(TYPE_ADR);
1445 /* pop 0 push 1 load */
1452 COUNT(count_load_instruction);
1453 i = opcode - ICMD_ILOAD;
1454 IF_NO_INTRP( rd->locals[iptr->s1.localindex][i].type = i; )
1455 NEW_LOAD(i, iptr->s1.localindex);
1464 COUNT(count_check_null);
1465 COUNT(count_check_bound);
1466 COUNT(count_pcmd_mem);
1467 NEW_OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1474 COUNT(count_check_null);
1475 COUNT(count_check_bound);
1476 COUNT(count_pcmd_mem);
1477 NEW_OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1480 /* pop 0 push 0 iinc */
1483 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1485 last_store[5 * iptr->s1.localindex + TYPE_INT] = bptr->icount - len - 1;
1490 if ((copy->varkind == LOCALVAR) &&
1491 (copy->varnum == iptr->s1.localindex))
1493 copy->varkind = TEMPVAR;
1500 iptr->dst.localindex = iptr->s1.localindex;
1503 /* pop 1 push 0 store */
1512 i = opcode - ICMD_ISTORE; /* type */
1513 IF_NO_INTRP( rd->locals[iptr->dst.localindex][i].type = i; )
1515 #if defined(ENABLE_STATISTICS)
1520 count_store_length[20]++;
1522 count_store_length[i]++;
1525 count_store_depth[10]++;
1527 count_store_depth[i]++;
1530 /* check for conflicts as described in Figure 5.2 */
1531 copy = curstack->prev;
1534 if ((copy->varkind == LOCALVAR) &&
1535 (copy->varnum == iptr->dst.localindex))
1537 copy->varkind = TEMPVAR;
1544 if ((curstack->varkind == LOCALVAR)
1545 && (curstack->varnum == iptr->dst.localindex))
1547 curstack->varkind = TEMPVAR;
1548 curstack->varnum = stackdepth-1;
1551 last_store[5 * iptr->dst.localindex + (opcode - ICMD_ISTORE)] = bptr->icount - len - 1;
1553 NEW_STORE(opcode - ICMD_ISTORE, iptr->dst.localindex);
1559 COUNT(count_check_null);
1560 COUNT(count_check_bound);
1561 COUNT(count_pcmd_mem);
1563 bte = builtintable_get_internal(BUILTIN_canstore);
1566 if (md->memuse > rd->memuse)
1567 rd->memuse = md->memuse;
1568 if (md->argintreguse > rd->argintreguse)
1569 rd->argintreguse = md->argintreguse;
1570 /* XXX non-leaf method? */
1572 /* make all stack variables saved */
1576 copy->flags |= SAVEDVAR;
1580 NEW_OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1587 COUNT(count_check_null);
1588 COUNT(count_check_bound);
1589 COUNT(count_pcmd_mem);
1590 NEW_OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1597 COUNT(count_check_null);
1598 COUNT(count_check_bound);
1599 COUNT(count_pcmd_mem);
1600 NEW_OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1606 #ifdef ENABLE_VERIFIER
1609 if (IS_2_WORD_TYPE(curstack->type))
1610 goto throw_stack_category_error;
1621 IF_JIT( md_return_alloc(jd, curstack); )
1622 COUNT(count_pcmd_return);
1623 NEW_OP1_0(opcode - ICMD_IRETURN);
1624 superblockend = true;
1628 COUNT(count_check_null);
1629 NEW_OP1_0(TYPE_ADR);
1631 superblockend = true;
1634 case ICMD_PUTSTATIC:
1635 COUNT(count_pcmd_mem);
1636 NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1637 NEW_OP1_0(fmiref->parseddesc.fd->type);
1640 /* pop 1 push 0 branch */
1643 case ICMD_IFNONNULL:
1644 COUNT(count_pcmd_bra);
1645 NEW_OP1_BRANCH(TYPE_ADR);
1646 BRANCH(tbptr, copy);
1655 COUNT(count_pcmd_bra);
1656 /* iptr->sx.val.i is set implicitly in parse by
1657 clearing the memory or from IF_ICMPxx
1660 NEW_OP1_BRANCH(TYPE_INT);
1661 /* iptr->sx.val.i = 0; */
1662 BRANCH(tbptr, copy);
1665 /* pop 0 push 0 branch */
1668 COUNT(count_pcmd_bra);
1670 BRANCH(tbptr, copy);
1671 superblockend = true;
1674 /* pop 1 push 0 table branch */
1676 case ICMD_TABLESWITCH:
1677 COUNT(count_pcmd_table);
1678 NEW_OP1_BRANCH(TYPE_INT);
1680 table = iptr->dst.table;
1681 BRANCH_TARGET(*table, tbptr, copy);
1684 i = iptr->sx.s23.s3.tablehigh
1685 - iptr->sx.s23.s2.tablelow + 1;
1688 BRANCH_TARGET(*table, tbptr, copy);
1691 superblockend = true;
1694 /* pop 1 push 0 table branch */
1696 case ICMD_LOOKUPSWITCH:
1697 COUNT(count_pcmd_table);
1698 NEW_OP1_BRANCH(TYPE_INT);
1700 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
1702 lookup = iptr->dst.lookup;
1704 i = iptr->sx.s23.s2.lookupcount;
1707 BRANCH_TARGET(lookup->target, tbptr, copy);
1710 superblockend = true;
1713 case ICMD_MONITORENTER:
1714 case ICMD_MONITOREXIT:
1715 COUNT(count_check_null);
1716 NEW_OP1_0(TYPE_ADR);
1719 /* pop 2 push 0 branch */
1721 case ICMD_IF_ICMPEQ:
1722 case ICMD_IF_ICMPNE:
1723 case ICMD_IF_ICMPLT:
1724 case ICMD_IF_ICMPGE:
1725 case ICMD_IF_ICMPGT:
1726 case ICMD_IF_ICMPLE:
1727 COUNT(count_pcmd_bra);
1728 NEW_OP2_BRANCH(TYPE_INT, TYPE_INT);
1729 BRANCH(tbptr, copy);
1732 case ICMD_IF_ACMPEQ:
1733 case ICMD_IF_ACMPNE:
1734 COUNT(count_pcmd_bra);
1735 NEW_OP2_BRANCH(TYPE_ADR, TYPE_ADR);
1736 BRANCH(tbptr, copy);
1742 COUNT(count_check_null);
1743 COUNT(count_pcmd_mem);
1744 NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1745 NEW_OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
1750 if (!IS_2_WORD_TYPE(curstack->type)) {
1752 #ifdef ENABLE_VERIFIER
1755 if (IS_2_WORD_TYPE(curstack->prev->type))
1756 goto throw_stack_category_error;
1759 NEW_OP2_0_ANY_ANY; /* pop two slots */
1762 iptr->opc = ICMD_POP;
1763 NEW_OP1_0_ANY; /* pop one (two-word) slot */
1767 /* pop 0 push 1 dup */
1770 #ifdef ENABLE_VERIFIER
1773 if (IS_2_WORD_TYPE(curstack->type))
1774 goto throw_stack_category_error;
1777 last_dupx = bptr->icount - len - 1;
1778 COUNT(count_dup_instruction);
1781 USE_S1_ANY; /* XXX live through */
1782 DUP_SLOT(iptr->s1.var);
1783 iptr->dst.var = curstack;
1788 last_dupx = bptr->icount - len - 1;
1790 if (IS_2_WORD_TYPE(curstack->type)) {
1792 iptr->opc = ICMD_DUP;
1797 /* ..., ????, cat1 */
1798 #ifdef ENABLE_VERIFIER
1800 if (IS_2_WORD_TYPE(curstack->prev->type))
1801 goto throw_stack_category_error;
1804 iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
1805 iptr->dst.dupslots[0] = curstack->prev; /* XXX live through */
1806 iptr->dst.dupslots[1] = curstack; /* XXX live through */
1808 DUP_SLOT(iptr->dst.dupslots[0]);
1809 iptr->dst.dupslots[2+0] = curstack;
1810 DUP_SLOT(iptr->dst.dupslots[1]);
1811 iptr->dst.dupslots[2+1] = curstack;
1816 /* pop 2 push 3 dup */
1819 #ifdef ENABLE_VERIFIER
1822 if (IS_2_WORD_TYPE(curstack->type) ||
1823 IS_2_WORD_TYPE(curstack->prev->type))
1824 goto throw_stack_category_error;
1827 last_dupx = bptr->icount - len - 1;
1830 iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
1831 iptr->dst.dupslots[0] = curstack->prev;
1832 iptr->dst.dupslots[1] = curstack;
1833 curstack = curstack->prev->prev;
1835 DUP_SLOT(iptr->dst.dupslots[1]);
1836 iptr->dst.dupslots[2+0] = curstack;
1837 DUP_SLOT(iptr->dst.dupslots[0]);
1838 iptr->dst.dupslots[2+1] = curstack;
1839 DUP_SLOT(iptr->dst.dupslots[1]);
1840 iptr->dst.dupslots[2+2] = curstack;
1845 last_dupx = bptr->icount - len - 1;
1847 if (IS_2_WORD_TYPE(curstack->type)) {
1848 /* ..., ????, cat2 */
1849 #ifdef ENABLE_VERIFIER
1851 if (IS_2_WORD_TYPE(curstack->prev->type))
1852 goto throw_stack_category_error;
1855 iptr->opc = ICMD_DUP_X1;
1859 /* ..., ????, cat1 */
1860 #ifdef ENABLE_VERIFIER
1863 if (IS_2_WORD_TYPE(curstack->prev->type)
1864 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1865 goto throw_stack_category_error;
1870 iptr->dst.dupslots = DMNEW(stackptr, 3 + 5);
1871 iptr->dst.dupslots[0] = curstack->prev->prev;
1872 iptr->dst.dupslots[1] = curstack->prev;
1873 iptr->dst.dupslots[2] = curstack;
1874 curstack = curstack->prev->prev->prev;
1876 DUP_SLOT(iptr->dst.dupslots[1]);
1877 iptr->dst.dupslots[3+0] = curstack;
1878 DUP_SLOT(iptr->dst.dupslots[2]);
1879 iptr->dst.dupslots[3+1] = curstack;
1880 DUP_SLOT(iptr->dst.dupslots[0]);
1881 iptr->dst.dupslots[3+2] = curstack;
1882 DUP_SLOT(iptr->dst.dupslots[1]);
1883 iptr->dst.dupslots[3+3] = curstack;
1884 DUP_SLOT(iptr->dst.dupslots[2]);
1885 iptr->dst.dupslots[3+4] = curstack;
1890 /* pop 3 push 4 dup */
1893 last_dupx = bptr->icount - len - 1;
1895 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1896 /* ..., cat2, ???? */
1897 #ifdef ENABLE_VERIFIER
1899 if (IS_2_WORD_TYPE(curstack->type))
1900 goto throw_stack_category_error;
1903 iptr->opc = ICMD_DUP_X1;
1907 /* ..., cat1, ???? */
1908 #ifdef ENABLE_VERIFIER
1911 if (IS_2_WORD_TYPE(curstack->type)
1912 || IS_2_WORD_TYPE(curstack->prev->prev->type))
1913 goto throw_stack_category_error;
1917 iptr->dst.dupslots = DMNEW(stackptr, 3 + 4);
1918 iptr->dst.dupslots[0] = curstack->prev->prev;
1919 iptr->dst.dupslots[1] = curstack->prev;
1920 iptr->dst.dupslots[2] = curstack;
1921 curstack = curstack->prev->prev->prev;
1923 DUP_SLOT(iptr->dst.dupslots[2]);
1924 iptr->dst.dupslots[3+0] = curstack;
1925 DUP_SLOT(iptr->dst.dupslots[0]);
1926 iptr->dst.dupslots[3+1] = curstack;
1927 DUP_SLOT(iptr->dst.dupslots[1]);
1928 iptr->dst.dupslots[3+2] = curstack;
1929 DUP_SLOT(iptr->dst.dupslots[2]);
1930 iptr->dst.dupslots[3+3] = curstack;
1936 last_dupx = bptr->icount - len - 1;
1938 if (IS_2_WORD_TYPE(curstack->type)) {
1939 /* ..., ????, cat2 */
1940 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1941 /* ..., cat2, cat2 */
1942 iptr->opc = ICMD_DUP_X1;
1946 /* ..., cat1, cat2 */
1947 #ifdef ENABLE_VERIFIER
1950 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
1951 goto throw_stack_category_error;
1954 iptr->opc = ICMD_DUP_X2;
1960 /* ..., ????, ????, cat1 */
1962 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1963 /* ..., cat2, ????, cat1 */
1964 #ifdef ENABLE_VERIFIER
1966 if (IS_2_WORD_TYPE(curstack->prev->type))
1967 goto throw_stack_category_error;
1970 iptr->opc = ICMD_DUP2_X1;
1974 /* ..., cat1, ????, cat1 */
1975 #ifdef ENABLE_VERIFIER
1978 if (IS_2_WORD_TYPE(curstack->prev->type)
1979 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
1980 goto throw_stack_category_error;
1983 iptr->dst.dupslots = DMNEW(stackptr, 4 + 6);
1984 iptr->dst.dupslots[0] = curstack->prev->prev->prev;
1985 iptr->dst.dupslots[1] = curstack->prev->prev;
1986 iptr->dst.dupslots[2] = curstack->prev;
1987 iptr->dst.dupslots[3] = curstack;
1988 curstack = curstack->prev->prev->prev->prev;
1990 DUP_SLOT(iptr->dst.dupslots[2]);
1991 iptr->dst.dupslots[4+0] = curstack;
1992 DUP_SLOT(iptr->dst.dupslots[3]);
1993 iptr->dst.dupslots[4+1] = curstack;
1994 DUP_SLOT(iptr->dst.dupslots[0]);
1995 iptr->dst.dupslots[4+2] = curstack;
1996 DUP_SLOT(iptr->dst.dupslots[1]);
1997 iptr->dst.dupslots[4+3] = curstack;
1998 DUP_SLOT(iptr->dst.dupslots[2]);
1999 iptr->dst.dupslots[4+4] = curstack;
2000 DUP_SLOT(iptr->dst.dupslots[3]);
2001 iptr->dst.dupslots[4+5] = curstack;
2006 /* pop 2 push 2 swap */
2009 last_dupx = bptr->icount - len - 1;
2010 #ifdef ENABLE_VERIFIER
2013 if (IS_2_WORD_TYPE(curstack->type)
2014 || IS_2_WORD_TYPE(curstack->prev->type))
2015 goto throw_stack_category_error;
2018 iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
2019 iptr->dst.dupslots[0] = curstack->prev;
2020 iptr->dst.dupslots[1] = curstack;
2021 curstack = curstack->prev->prev;
2023 DUP_SLOT(iptr->dst.dupslots[1]);
2024 iptr->dst.dupslots[2+0] = curstack;
2025 DUP_SLOT(iptr->dst.dupslots[0]);
2026 iptr->dst.dupslots[2+1] = curstack;
2033 #if !SUPPORT_DIVISION
2034 bte = iptr->sx.s23.s3.bte;
2037 if (md->memuse > rd->memuse)
2038 rd->memuse = md->memuse;
2039 if (md->argintreguse > rd->argintreguse)
2040 rd->argintreguse = md->argintreguse;
2042 /* make all stack variables saved */
2046 copy->flags |= SAVEDVAR;
2051 #endif /* !SUPPORT_DIVISION */
2062 COUNT(count_pcmd_op);
2063 NEW_OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2068 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2069 bte = iptr->sx.s23.s3.bte;
2072 if (md->memuse > rd->memuse)
2073 rd->memuse = md->memuse;
2074 if (md->argintreguse > rd->argintreguse)
2075 rd->argintreguse = md->argintreguse;
2076 /* XXX non-leaf method? */
2078 /* make all stack variables saved */
2082 copy->flags |= SAVEDVAR;
2087 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2092 #if SUPPORT_LONG_LOGICAL
2096 #endif /* SUPPORT_LONG_LOGICAL */
2097 COUNT(count_pcmd_op);
2098 NEW_OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2104 COUNT(count_pcmd_op);
2105 NEW_OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2113 COUNT(count_pcmd_op);
2114 NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2122 COUNT(count_pcmd_op);
2123 NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2127 COUNT(count_pcmd_op);
2128 #if SUPPORT_LONG_CMP_CONST
2129 if ((len == 0) || (iptr[1].sx.val.i != 0))
2132 switch (iptr[1].opc) {
2134 iptr->opc = ICMD_IF_LCMPEQ;
2136 iptr->dst.insindex = iptr[1].dst.insindex;
2137 iptr[1].opc = ICMD_NOP;
2139 NEW_OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2140 BRANCH(tbptr, copy);
2142 COUNT(count_pcmd_bra);
2145 iptr->opc = ICMD_IF_LCMPNE;
2146 goto icmd_lcmp_if_tail;
2148 iptr->opc = ICMD_IF_LCMPLT;
2149 goto icmd_lcmp_if_tail;
2151 iptr->opc = ICMD_IF_LCMPGT;
2152 goto icmd_lcmp_if_tail;
2154 iptr->opc = ICMD_IF_LCMPLE;
2155 goto icmd_lcmp_if_tail;
2157 iptr->opc = ICMD_IF_LCMPGE;
2158 goto icmd_lcmp_if_tail;
2164 #endif /* SUPPORT_LONG_CMP_CONST */
2165 NEW_OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2168 /* XXX why is this deactivated? */
2171 COUNT(count_pcmd_op);
2172 if ((len == 0) || (iptr[1].sx.val.i != 0))
2175 switch (iptr[1].opc) {
2177 iptr->opc = ICMD_IF_FCMPEQ;
2179 iptr->dst.insindex = iptr[1].dst.insindex;
2180 iptr[1].opc = ICMD_NOP;
2182 NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2183 BRANCH(tbptr, copy);
2185 COUNT(count_pcmd_bra);
2188 iptr->opc = ICMD_IF_FCMPNE;
2189 goto icmd_if_fcmpl_tail;
2191 iptr->opc = ICMD_IF_FCMPL_LT;
2192 goto icmd_if_fcmpl_tail;
2194 iptr->opc = ICMD_IF_FCMPL_GT;
2195 goto icmd_if_fcmpl_tail;
2197 iptr->opc = ICMD_IF_FCMPL_LE;
2198 goto icmd_if_fcmpl_tail;
2200 iptr->opc = ICMD_IF_FCMPL_GE;
2201 goto icmd_if_fcmpl_tail;
2208 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2212 COUNT(count_pcmd_op);
2213 if ((len == 0) || (iptr[1].sx.val.i != 0))
2216 switch (iptr[1].opc) {
2218 iptr->opc = ICMD_IF_FCMPEQ;
2220 iptr->dst.insindex = iptr[1].dst.insindex;
2221 iptr[1].opc = ICMD_NOP;
2223 NEW_OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2224 BRANCH(tbptr, copy);
2226 COUNT(count_pcmd_bra);
2229 iptr->opc = ICMD_IF_FCMPNE;
2230 goto icmd_if_fcmpg_tail;
2232 iptr->opc = ICMD_IF_FCMPG_LT;
2233 goto icmd_if_fcmpg_tail;
2235 iptr->opc = ICMD_IF_FCMPG_GT;
2236 goto icmd_if_fcmpg_tail;
2238 iptr->opc = ICMD_IF_FCMPG_LE;
2239 goto icmd_if_fcmpg_tail;
2241 iptr->opc = ICMD_IF_FCMPG_GE;
2242 goto icmd_if_fcmpg_tail;
2249 NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2253 COUNT(count_pcmd_op);
2254 if ((len == 0) || (iptr[1].sx.val.i != 0))
2257 switch (iptr[1].opc) {
2259 iptr->opc = ICMD_IF_DCMPEQ;
2261 iptr->dst.insindex = iptr[1].dst.insindex;
2262 iptr[1].opc = ICMD_NOP;
2264 NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2265 BRANCH(tbptr, copy);
2267 COUNT(count_pcmd_bra);
2270 iptr->opc = ICMD_IF_DCMPNE;
2271 goto icmd_if_dcmpl_tail;
2273 iptr->opc = ICMD_IF_DCMPL_LT;
2274 goto icmd_if_dcmpl_tail;
2276 iptr->opc = ICMD_IF_DCMPL_GT;
2277 goto icmd_if_dcmpl_tail;
2279 iptr->opc = ICMD_IF_DCMPL_LE;
2280 goto icmd_if_dcmpl_tail;
2282 iptr->opc = ICMD_IF_DCMPL_GE;
2283 goto icmd_if_dcmpl_tail;
2290 OPTT2_1(TYPE_DBL, TYPE_INT);
2294 COUNT(count_pcmd_op);
2295 if ((len == 0) || (iptr[1].sx.val.i != 0))
2298 switch (iptr[1].opc) {
2300 iptr->opc = ICMD_IF_DCMPEQ;
2302 iptr->dst.insindex = iptr[1].dst.insindex;
2303 iptr[1].opc = ICMD_NOP;
2305 NEW_OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2306 BRANCH(tbptr, copy);
2308 COUNT(count_pcmd_bra);
2311 iptr->opc = ICMD_IF_DCMPNE;
2312 goto icmd_if_dcmpg_tail;
2314 iptr->opc = ICMD_IF_DCMPG_LT;
2315 goto icmd_if_dcmpg_tail;
2317 iptr->opc = ICMD_IF_DCMPG_GT;
2318 goto icmd_if_dcmpg_tail;
2320 iptr->opc = ICMD_IF_DCMPG_LE;
2321 goto icmd_if_dcmpg_tail;
2323 iptr->opc = ICMD_IF_DCMPG_GE;
2324 goto icmd_if_dcmpg_tail;
2331 NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2336 COUNT(count_pcmd_op);
2337 NEW_OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2342 COUNT(count_pcmd_op);
2343 NEW_OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2352 case ICMD_INT2SHORT:
2353 COUNT(count_pcmd_op);
2354 NEW_OP1_1(TYPE_INT, TYPE_INT);
2357 COUNT(count_pcmd_op);
2358 NEW_OP1_1(TYPE_LNG, TYPE_LNG);
2361 COUNT(count_pcmd_op);
2362 NEW_OP1_1(TYPE_FLT, TYPE_FLT);
2365 COUNT(count_pcmd_op);
2366 NEW_OP1_1(TYPE_DBL, TYPE_DBL);
2370 COUNT(count_pcmd_op);
2371 NEW_OP1_1(TYPE_INT, TYPE_LNG);
2374 COUNT(count_pcmd_op);
2375 NEW_OP1_1(TYPE_INT, TYPE_FLT);
2378 COUNT(count_pcmd_op);
2379 NEW_OP1_1(TYPE_INT, TYPE_DBL);
2382 COUNT(count_pcmd_op);
2383 NEW_OP1_1(TYPE_LNG, TYPE_INT);
2386 COUNT(count_pcmd_op);
2387 NEW_OP1_1(TYPE_LNG, TYPE_FLT);
2390 COUNT(count_pcmd_op);
2391 NEW_OP1_1(TYPE_LNG, TYPE_DBL);
2394 COUNT(count_pcmd_op);
2395 NEW_OP1_1(TYPE_FLT, TYPE_INT);
2398 COUNT(count_pcmd_op);
2399 NEW_OP1_1(TYPE_FLT, TYPE_LNG);
2402 COUNT(count_pcmd_op);
2403 NEW_OP1_1(TYPE_FLT, TYPE_DBL);
2406 COUNT(count_pcmd_op);
2407 NEW_OP1_1(TYPE_DBL, TYPE_INT);
2410 COUNT(count_pcmd_op);
2411 NEW_OP1_1(TYPE_DBL, TYPE_LNG);
2414 COUNT(count_pcmd_op);
2415 NEW_OP1_1(TYPE_DBL, TYPE_FLT);
2418 case ICMD_CHECKCAST:
2419 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2420 /* array type cast-check */
2422 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2425 if (md->memuse > rd->memuse)
2426 rd->memuse = md->memuse;
2427 if (md->argintreguse > rd->argintreguse)
2428 rd->argintreguse = md->argintreguse;
2430 /* make all stack variables saved */
2434 copy->flags |= SAVEDVAR;
2438 NEW_OP1_1(TYPE_ADR, TYPE_ADR);
2441 case ICMD_INSTANCEOF:
2442 case ICMD_ARRAYLENGTH:
2443 NEW_OP1_1(TYPE_ADR, TYPE_INT);
2447 case ICMD_ANEWARRAY:
2448 NEW_OP1_1(TYPE_INT, TYPE_ADR);
2452 COUNT(count_check_null);
2453 COUNT(count_pcmd_mem);
2454 NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2455 NEW_OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2460 case ICMD_GETSTATIC:
2461 COUNT(count_pcmd_mem);
2462 NEW_INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2463 NEW_OP0_1(fmiref->parseddesc.fd->type);
2467 NEW_OP0_1(TYPE_ADR);
2471 NEW_OP0_1(TYPE_ADR);
2473 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2475 tbptr->type = BBTYPE_SBR;
2477 /* We need to check for overflow right here because
2478 * the pushed value is poped afterwards */
2481 /* calculate stack after return */
2486 /* pop many push any */
2489 #if defined(USEBUILTINTABLE)
2492 bte = iptr->sx.s23.s3.bte;
2496 case ICMD_INVOKESTATIC:
2497 case ICMD_INVOKESPECIAL:
2498 case ICMD_INVOKEVIRTUAL:
2499 case ICMD_INVOKEINTERFACE:
2500 COUNT(count_pcmd_met);
2501 NEW_INSTRUCTION_GET_METHODDESC(iptr, md);
2502 /* XXX resurrect this COUNT? */
2503 /* if (lm->flags & ACC_STATIC) */
2504 /* {COUNT(count_check_null);} */
2508 last_pei = bptr->icount - len - 1;
2512 if (md->memuse > rd->memuse)
2513 rd->memuse = md->memuse;
2514 if (md->argintreguse > rd->argintreguse)
2515 rd->argintreguse = md->argintreguse;
2516 if (md->argfltreguse > rd->argfltreguse)
2517 rd->argfltreguse = md->argfltreguse;
2521 /* XXX optimize for <= 2 args */
2522 iptr->s1.argcount = i;
2523 iptr->sx.s23.s2.args = DMNEW(stackptr, i);
2526 for (i-- ; i >= 0; i--) {
2527 iptr->sx.s23.s2.args[i] = copy;
2529 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2530 /* If we pass float arguments in integer argument registers, we
2531 * are not allowed to precolor them here. Floats have to be moved
2532 * to this regs explicitly in codegen().
2533 * Only arguments that are passed by stack anyway can be precolored
2534 * (michi 2005/07/24) */
2535 if (!(copy->flags & SAVEDVAR) &&
2536 (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
2538 if (!(copy->flags & SAVEDVAR)) {
2540 copy->varkind = ARGVAR;
2543 #if defined(ENABLE_INTRP)
2546 if (md->params[i].inmemory) {
2547 copy->flags = INMEMORY;
2548 copy->regoff = md->params[i].regoff;
2552 if (IS_FLT_DBL_TYPE(copy->type)) {
2553 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2554 assert(0); /* XXX is this assert ok? */
2557 rd->argfltregs[md->params[i].regoff];
2558 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2561 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2562 if (IS_2_WORD_TYPE(copy->type))
2563 copy->regoff = PACK_REGS(
2564 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2565 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2567 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2569 rd->argintregs[md->params[i].regoff];
2572 #if defined(ENABLE_INTRP)
2573 } /* end if (!opt_intrp) */
2580 copy->flags |= SAVEDVAR;
2591 if (md->returntype.type != TYPE_VOID) {
2592 NEW_DST(md->returntype.type, stackdepth);
2597 case ICMD_INLINE_START:
2598 case ICMD_INLINE_END:
2603 case ICMD_MULTIANEWARRAY:
2604 if (rd->argintreguse < 3)
2605 rd->argintreguse = 3;
2607 i = iptr->s1.argcount;
2611 iptr->sx.s23.s2.args = DMNEW(stackptr, i);
2613 #if defined(SPECIALMEMUSE)
2614 # if defined(__DARWIN__)
2615 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
2616 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
2618 if (rd->memuse < (i + LA_WORD_SIZE + 3))
2619 rd->memuse = i + LA_WORD_SIZE + 3;
2622 # if defined(__I386__)
2623 if (rd->memuse < i + 3)
2624 rd->memuse = i + 3; /* n integer args spilled on stack */
2625 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2626 if (rd->memuse < i + 2)
2627 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2630 rd->memuse = i; /* n integer args spilled on stack */
2631 # endif /* defined(__I386__) */
2635 /* check INT type here? Currently typecheck does this. */
2636 iptr->sx.s23.s2.args[i] = copy;
2637 if (!(copy->flags & SAVEDVAR)) {
2638 copy->varkind = ARGVAR;
2639 copy->varnum = i + INT_ARG_CNT;
2640 copy->flags |= INMEMORY;
2641 #if defined(SPECIALMEMUSE)
2642 # if defined(__DARWIN__)
2643 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
2645 copy->regoff = i + LA_WORD_SIZE + 3;
2648 # if defined(__I386__)
2649 copy->regoff = i + 3;
2650 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2651 copy->regoff = i + 2;
2654 # endif /* defined(__I386__) */
2655 #endif /* defined(SPECIALMEMUSE) */
2660 copy->flags |= SAVEDVAR;
2664 i = iptr->s1.argcount;
2669 NEW_DST(TYPE_ADR, stackdepth);
2675 new_internalerror("Unknown ICMD %d", opcode);
2681 } /* while instructions */
2683 /* set out-stack of block */
2685 bptr->outstack = curstack;
2686 bptr->outdepth = stackdepth;
2688 /* stack slots at basic block end become interfaces */
2691 for (copy = curstack; copy; i--, copy = copy->prev) {
2692 if ((copy->varkind == STACKVAR) && (copy->varnum > i))
2693 copy->varkind = TEMPVAR;
2695 copy->varkind = STACKVAR;
2699 rd->interfaces[i][copy->type].type = copy->type;
2700 rd->interfaces[i][copy->type].flags |= copy->flags;
2704 /* check if interface slots at basic block begin must be saved */
2707 i = bptr->indepth - 1;
2708 for (copy = bptr->instack; copy; i--, copy = copy->prev) {
2709 rd->interfaces[i][copy->type].type = copy->type;
2710 if (copy->varkind == STACKVAR) {
2711 if (copy->flags & SAVEDVAR)
2712 rd->interfaces[i][copy->type].flags |= SAVEDVAR;
2719 superblockend = true;
2722 } /* while blocks */
2723 } while (repeat && !deadcode);
2725 /* gather statistics *****************************************************/
2727 #if defined(ENABLE_STATISTICS)
2729 if (jd->new_basicblockcount > count_max_basic_blocks)
2730 count_max_basic_blocks = jd->new_basicblockcount;
2731 count_basic_blocks += jd->new_basicblockcount;
2732 if (jd->new_instructioncount > count_max_javainstr)
2733 count_max_javainstr = jd->new_instructioncount;
2734 count_javainstr += jd->new_instructioncount;
2735 if (jd->new_stackcount > count_upper_bound_new_stack)
2736 count_upper_bound_new_stack = jd->new_stackcount;
2737 if ((new - jd->new_stack) > count_max_new_stack)
2738 count_max_new_stack = (new - jd->new_stack);
2740 b_count = jd->new_basicblockcount;
2741 bptr = jd->new_basicblocks;
2742 while (--b_count >= 0) {
2743 if (bptr->flags > BBREACHED) {
2744 if (bptr->indepth >= 10)
2745 count_block_stack[10]++;
2747 count_block_stack[bptr->indepth]++;
2750 count_block_size_distribution[len]++;
2752 count_block_size_distribution[10]++;
2754 count_block_size_distribution[11]++;
2756 count_block_size_distribution[12]++;
2758 count_block_size_distribution[13]++;
2760 count_block_size_distribution[14]++;
2762 count_block_size_distribution[15]++;
2764 count_block_size_distribution[16]++;
2766 count_block_size_distribution[17]++;
2771 if (iteration_count == 1)
2772 count_analyse_iterations[0]++;
2773 else if (iteration_count == 2)
2774 count_analyse_iterations[1]++;
2775 else if (iteration_count == 3)
2776 count_analyse_iterations[2]++;
2777 else if (iteration_count == 4)
2778 count_analyse_iterations[3]++;
2780 count_analyse_iterations[4]++;
2782 if (jd->new_basicblockcount <= 5)
2783 count_method_bb_distribution[0]++;
2784 else if (jd->new_basicblockcount <= 10)
2785 count_method_bb_distribution[1]++;
2786 else if (jd->new_basicblockcount <= 15)
2787 count_method_bb_distribution[2]++;
2788 else if (jd->new_basicblockcount <= 20)
2789 count_method_bb_distribution[3]++;
2790 else if (jd->new_basicblockcount <= 30)
2791 count_method_bb_distribution[4]++;
2792 else if (jd->new_basicblockcount <= 40)
2793 count_method_bb_distribution[5]++;
2794 else if (jd->new_basicblockcount <= 50)
2795 count_method_bb_distribution[6]++;
2796 else if (jd->new_basicblockcount <= 75)
2797 count_method_bb_distribution[7]++;
2799 count_method_bb_distribution[8]++;
2801 #endif /* defined(ENABLE_STATISTICS) */
2803 /* everything's ok *******************************************************/
2807 /* goto labels for throwing verifier exceptions **************************/
2809 #if defined(ENABLE_VERIFIER)
2811 throw_stack_underflow:
2813 new_verifyerror(m, "Unable to pop operand off an empty stack");
2816 throw_stack_overflow:
2817 *exceptionptr = new_verifyerror(m, "Stack size too large");
2820 throw_stack_depth_error:
2821 *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
2824 throw_stack_type_error:
2825 exceptions_throw_verifyerror_for_stack(m, expectedtype);
2828 throw_stack_category_error:
2830 new_verifyerror(m, "Attempt to split long or double on the stack");
2836 bool stack_analyse(jitdata *jd)
2848 int opcode, i, j, len, loops;
2849 int superblockend, repeat, deadcode;
2855 s4 *last_store;/* instruction index of last XSTORE */
2856 /* [ local_index * 5 + type ] */
2857 s4 last_pei; /* instruction index of last possible exception */
2858 /* used for conflict resolution for copy */
2859 /* elimination (XLOAD, IINC, XSTORE) */
2861 #if defined(ENABLE_VERIFIER)
2862 int expectedtype; /* used by CHECK_BASIC_TYPE */
2865 builtintable_entry *bte;
2868 /* get required compiler data */
2875 #if defined(ENABLE_LSRA)
2876 m->maxlifetimes = 0;
2879 last_store = DMNEW(s4 , cd->maxlocals * 5);
2883 m->basicblocks[0].flags = BBREACHED;
2884 m->basicblocks[0].instack = 0;
2885 m->basicblocks[0].indepth = 0;
2887 for (i = 0; i < cd->exceptiontablelength; i++) {
2888 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
2889 bptr->flags = BBREACHED;
2890 bptr->type = BBTYPE_EXH;
2891 bptr->instack = new;
2893 bptr->pre_count = 10000;
2898 #if CONDITIONAL_LOADCONST
2899 b_count = m->basicblockcount;
2900 bptr = m->basicblocks;
2901 while (--b_count >= 0) {
2902 if (bptr->icount != 0) {
2903 iptr = bptr->iinstr + bptr->icount - 1;
2904 switch (iptr->opc) {
2923 case ICMD_IFNONNULL:
2925 case ICMD_IF_ICMPEQ:
2926 case ICMD_IF_ICMPNE:
2927 case ICMD_IF_ICMPLT:
2928 case ICMD_IF_ICMPGE:
2929 case ICMD_IF_ICMPGT:
2930 case ICMD_IF_ICMPLE:
2932 case ICMD_IF_ACMPEQ:
2933 case ICMD_IF_ACMPNE:
2934 bptr[1].pre_count++;
2936 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
2939 case ICMD_TABLESWITCH:
2940 s4ptr = iptr->val.a;
2941 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
2942 i = *s4ptr++; /* low */
2943 i = *s4ptr++ - i + 1; /* high */
2945 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
2949 case ICMD_LOOKUPSWITCH:
2950 s4ptr = iptr->val.a;
2951 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
2952 i = *s4ptr++; /* count */
2954 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
2959 bptr[1].pre_count++;
2965 #endif /* CONDITIONAL_LOADCONST */
2970 b_count = m->basicblockcount;
2971 bptr = m->basicblocks;
2972 superblockend = true;
2977 while (--b_count >= 0) {
2978 if (bptr->flags == BBDELETED) {
2981 else if (superblockend && (bptr->flags < BBREACHED)) {
2984 else if (bptr->flags <= BBREACHED) {
2985 if (superblockend) {
2986 stackdepth = bptr->indepth;
2988 else if (bptr->flags < BBREACHED) {
2990 bptr->instack = copy;
2991 bptr->indepth = stackdepth;
2994 CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
2997 curstack = bptr->instack;
2999 superblockend = false;
3000 bptr->flags = BBFINISHED;
3002 iptr = bptr->iinstr;
3003 b_index = bptr - m->basicblocks;
3007 for( i = 0; i < cd->maxlocals; i++)
3008 for( j = 0; j < 5; j++)
3009 last_store[5 * i + j] = -1;
3013 while (--len >= 0) {
3016 #if defined(USEBUILTINTABLE)
3017 # if defined(ENABLE_INTRP)
3020 bte = builtintable_get_automatic(opcode);
3022 if (bte && bte->opcode == opcode) {
3023 iptr->opc = ICMD_BUILTIN;
3024 iptr->op1 = false; /* don't check for exception */
3026 jd->isleafmethod = false;
3029 # if defined(ENABLE_INTRP)
3032 #endif /* defined(USEBUILTINTABLE) */
3034 /* this is the main switch */
3040 case ICMD_CHECKNULL:
3041 COUNT(count_check_null);
3044 case ICMD_IFEQ_ICONST:
3045 case ICMD_IFNE_ICONST:
3046 case ICMD_IFLT_ICONST:
3047 case ICMD_IFGE_ICONST:
3048 case ICMD_IFGT_ICONST:
3049 case ICMD_IFLE_ICONST:
3050 case ICMD_ELSE_ICONST:
3055 #if defined(ENABLE_INTRP)
3058 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
3060 COUNT(count_pcmd_return);
3062 superblockend = true;
3065 /* pop 0 push 1 const */
3068 COUNT(count_pcmd_load);
3070 switch (iptr[1].opc) {
3072 iptr[0].opc = ICMD_IADDCONST;
3074 iptr[1].opc = ICMD_NOP;
3075 OP1_1(TYPE_INT, TYPE_INT);
3076 COUNT(count_pcmd_op);
3079 iptr[0].opc = ICMD_ISUBCONST;
3080 goto icmd_iconst_tail;
3081 #if SUPPORT_CONST_MUL
3083 iptr[0].opc = ICMD_IMULCONST;
3084 goto icmd_iconst_tail;
3085 #else /* SUPPORT_CONST_MUL */
3087 if (iptr[0].val.i == 0x00000002)
3089 else if (iptr[0].val.i == 0x00000004)
3091 else if (iptr[0].val.i == 0x00000008)
3093 else if (iptr[0].val.i == 0x00000010)
3095 else if (iptr[0].val.i == 0x00000020)
3097 else if (iptr[0].val.i == 0x00000040)
3099 else if (iptr[0].val.i == 0x00000080)
3101 else if (iptr[0].val.i == 0x00000100)
3103 else if (iptr[0].val.i == 0x00000200)
3105 else if (iptr[0].val.i == 0x00000400)
3107 else if (iptr[0].val.i == 0x00000800)
3109 else if (iptr[0].val.i == 0x00001000)
3111 else if (iptr[0].val.i == 0x00002000)
3113 else if (iptr[0].val.i == 0x00004000)
3115 else if (iptr[0].val.i == 0x00008000)
3117 else if (iptr[0].val.i == 0x00010000)
3119 else if (iptr[0].val.i == 0x00020000)
3121 else if (iptr[0].val.i == 0x00040000)
3123 else if (iptr[0].val.i == 0x00080000)
3125 else if (iptr[0].val.i == 0x00100000)
3127 else if (iptr[0].val.i == 0x00200000)
3129 else if (iptr[0].val.i == 0x00400000)
3131 else if (iptr[0].val.i == 0x00800000)
3133 else if (iptr[0].val.i == 0x01000000)
3135 else if (iptr[0].val.i == 0x02000000)
3137 else if (iptr[0].val.i == 0x04000000)
3139 else if (iptr[0].val.i == 0x08000000)
3141 else if (iptr[0].val.i == 0x10000000)
3143 else if (iptr[0].val.i == 0x20000000)
3145 else if (iptr[0].val.i == 0x40000000)
3147 else if (iptr[0].val.i == 0x80000000)
3150 PUSHCONST(TYPE_INT);
3153 iptr[0].opc = ICMD_IMULPOW2;
3154 goto icmd_iconst_tail;
3155 #endif /* SUPPORT_CONST_MUL */
3157 if (iptr[0].val.i == 0x00000002)
3159 else if (iptr[0].val.i == 0x00000004)
3161 else if (iptr[0].val.i == 0x00000008)
3163 else if (iptr[0].val.i == 0x00000010)
3165 else if (iptr[0].val.i == 0x00000020)
3167 else if (iptr[0].val.i == 0x00000040)
3169 else if (iptr[0].val.i == 0x00000080)
3171 else if (iptr[0].val.i == 0x00000100)
3173 else if (iptr[0].val.i == 0x00000200)
3175 else if (iptr[0].val.i == 0x00000400)
3177 else if (iptr[0].val.i == 0x00000800)
3179 else if (iptr[0].val.i == 0x00001000)
3181 else if (iptr[0].val.i == 0x00002000)
3183 else if (iptr[0].val.i == 0x00004000)
3185 else if (iptr[0].val.i == 0x00008000)
3187 else if (iptr[0].val.i == 0x00010000)
3189 else if (iptr[0].val.i == 0x00020000)
3191 else if (iptr[0].val.i == 0x00040000)
3193 else if (iptr[0].val.i == 0x00080000)
3195 else if (iptr[0].val.i == 0x00100000)
3197 else if (iptr[0].val.i == 0x00200000)
3199 else if (iptr[0].val.i == 0x00400000)
3201 else if (iptr[0].val.i == 0x00800000)
3203 else if (iptr[0].val.i == 0x01000000)
3205 else if (iptr[0].val.i == 0x02000000)
3207 else if (iptr[0].val.i == 0x04000000)
3209 else if (iptr[0].val.i == 0x08000000)
3211 else if (iptr[0].val.i == 0x10000000)
3213 else if (iptr[0].val.i == 0x20000000)
3215 else if (iptr[0].val.i == 0x40000000)
3217 else if (iptr[0].val.i == 0x80000000)
3220 PUSHCONST(TYPE_INT);
3223 iptr[0].opc = ICMD_IDIVPOW2;
3224 goto icmd_iconst_tail;
3226 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
3227 if ((iptr[0].val.i == 0x00000002) ||
3228 (iptr[0].val.i == 0x00000004) ||
3229 (iptr[0].val.i == 0x00000008) ||
3230 (iptr[0].val.i == 0x00000010) ||
3231 (iptr[0].val.i == 0x00000020) ||
3232 (iptr[0].val.i == 0x00000040) ||
3233 (iptr[0].val.i == 0x00000080) ||
3234 (iptr[0].val.i == 0x00000100) ||
3235 (iptr[0].val.i == 0x00000200) ||
3236 (iptr[0].val.i == 0x00000400) ||
3237 (iptr[0].val.i == 0x00000800) ||
3238 (iptr[0].val.i == 0x00001000) ||
3239 (iptr[0].val.i == 0x00002000) ||
3240 (iptr[0].val.i == 0x00004000) ||
3241 (iptr[0].val.i == 0x00008000) ||
3242 (iptr[0].val.i == 0x00010000) ||
3243 (iptr[0].val.i == 0x00020000) ||
3244 (iptr[0].val.i == 0x00040000) ||
3245 (iptr[0].val.i == 0x00080000) ||
3246 (iptr[0].val.i == 0x00100000) ||
3247 (iptr[0].val.i == 0x00200000) ||
3248 (iptr[0].val.i == 0x00400000) ||
3249 (iptr[0].val.i == 0x00800000) ||
3250 (iptr[0].val.i == 0x01000000) ||
3251 (iptr[0].val.i == 0x02000000) ||
3252 (iptr[0].val.i == 0x04000000) ||
3253 (iptr[0].val.i == 0x08000000) ||
3254 (iptr[0].val.i == 0x10000000) ||
3255 (iptr[0].val.i == 0x20000000) ||
3256 (iptr[0].val.i == 0x40000000) ||
3257 (iptr[0].val.i == 0x80000000)) {
3258 iptr[0].opc = ICMD_IREMPOW2;
3260 goto icmd_iconst_tail;
3262 PUSHCONST(TYPE_INT);
3264 #if SUPPORT_CONST_LOGICAL
3266 iptr[0].opc = ICMD_IANDCONST;
3267 goto icmd_iconst_tail;
3269 iptr[0].opc = ICMD_IORCONST;
3270 goto icmd_iconst_tail;
3272 iptr[0].opc = ICMD_IXORCONST;
3273 goto icmd_iconst_tail;
3274 #endif /* SUPPORT_CONST_LOGICAL */
3276 iptr[0].opc = ICMD_ISHLCONST;
3277 goto icmd_iconst_tail;
3279 iptr[0].opc = ICMD_ISHRCONST;
3280 goto icmd_iconst_tail;
3282 iptr[0].opc = ICMD_IUSHRCONST;
3283 goto icmd_iconst_tail;
3284 #if SUPPORT_LONG_SHIFT
3286 iptr[0].opc = ICMD_LSHLCONST;
3287 goto icmd_lconst_tail;
3289 iptr[0].opc = ICMD_LSHRCONST;
3290 goto icmd_lconst_tail;
3292 iptr[0].opc = ICMD_LUSHRCONST;
3293 goto icmd_lconst_tail;
3294 #endif /* SUPPORT_LONG_SHIFT */
3295 case ICMD_IF_ICMPEQ:
3296 iptr[1].opc = ICMD_IFEQ;
3298 /* iptr[0].op1 = iptr[1].op1; */
3299 /* IF_ICMPxx is the last instruction in the
3300 basic block, just remove it. */
3301 iptr[0].opc = ICMD_NOP;
3302 iptr[1].val.i = iptr[0].val.i;
3304 /* bptr->icount--; */
3308 tbptr = m->basicblocks +
3309 m->basicblockindex[iptr[1].op1];
3311 iptr[1].target = (void *) tbptr;
3313 MARKREACHED(tbptr, copy);
3314 COUNT(count_pcmd_bra);
3317 case ICMD_IF_ICMPLT:
3318 iptr[1].opc = ICMD_IFLT;
3319 goto icmd_if_icmp_tail;
3320 case ICMD_IF_ICMPLE:
3321 iptr[1].opc = ICMD_IFLE;
3322 goto icmd_if_icmp_tail;
3323 case ICMD_IF_ICMPNE:
3324 iptr[1].opc = ICMD_IFNE;
3325 goto icmd_if_icmp_tail;
3326 case ICMD_IF_ICMPGT:
3327 iptr[1].opc = ICMD_IFGT;
3328 goto icmd_if_icmp_tail;
3329 case ICMD_IF_ICMPGE:
3330 iptr[1].opc = ICMD_IFGE;
3331 goto icmd_if_icmp_tail;
3333 #if SUPPORT_CONST_STORE
3338 # if defined(ENABLE_INTRP)
3341 # if SUPPORT_CONST_STORE_ZERO_ONLY
3342 if (iptr[0].val.i == 0) {
3344 switch (iptr[1].opc) {
3346 iptr[0].opc = ICMD_IASTORECONST;
3349 iptr[0].opc = ICMD_BASTORECONST;
3352 iptr[0].opc = ICMD_CASTORECONST;
3355 iptr[0].opc = ICMD_SASTORECONST;
3359 iptr[1].opc = ICMD_NOP;
3360 OPTT2_0(TYPE_INT, TYPE_ADR);
3361 COUNT(count_pcmd_op);
3362 # if SUPPORT_CONST_STORE_ZERO_ONLY
3365 PUSHCONST(TYPE_INT);
3367 # if defined(ENABLE_INTRP)
3370 PUSHCONST(TYPE_INT);
3374 case ICMD_PUTSTATIC:
3376 # if defined(ENABLE_INTRP)
3379 # if SUPPORT_CONST_STORE_ZERO_ONLY
3380 if (iptr[0].val.i == 0) {
3382 switch (iptr[1].opc) {
3383 case ICMD_PUTSTATIC:
3384 iptr[0].opc = ICMD_PUTSTATICCONST;
3388 iptr[0].opc = ICMD_PUTFIELDCONST;
3393 iptr[1].opc = ICMD_NOP;
3394 iptr[0].op1 = TYPE_INT;
3395 COUNT(count_pcmd_op);
3396 # if SUPPORT_CONST_STORE_ZERO_ONLY
3399 PUSHCONST(TYPE_INT);
3401 # if defined(ENABLE_INTRP)
3404 PUSHCONST(TYPE_INT);
3407 #endif /* SUPPORT_CONST_STORE */
3409 PUSHCONST(TYPE_INT);
3413 PUSHCONST(TYPE_INT);
3417 COUNT(count_pcmd_load);
3419 switch (iptr[1].opc) {
3420 #if SUPPORT_LONG_ADD
3422 iptr[0].opc = ICMD_LADDCONST;
3424 iptr[1].opc = ICMD_NOP;
3425 OP1_1(TYPE_LNG,TYPE_LNG);
3426 COUNT(count_pcmd_op);
3429 iptr[0].opc = ICMD_LSUBCONST;
3430 goto icmd_lconst_tail;
3431 #endif /* SUPPORT_LONG_ADD */
3432 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
3434 iptr[0].opc = ICMD_LMULCONST;
3435 goto icmd_lconst_tail;
3436 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
3437 # if SUPPORT_LONG_SHIFT
3439 if (iptr[0].val.l == 0x00000002)
3441 else if (iptr[0].val.l == 0x00000004)
3443 else if (iptr[0].val.l == 0x00000008)
3445 else if (iptr[0].val.l == 0x00000010)
3447 else if (iptr[0].val.l == 0x00000020)
3449 else if (iptr[0].val.l == 0x00000040)
3451 else if (iptr[0].val.l == 0x00000080)
3453 else if (iptr[0].val.l == 0x00000100)
3455 else if (iptr[0].val.l == 0x00000200)
3457 else if (iptr[0].val.l == 0x00000400)
3459 else if (iptr[0].val.l == 0x00000800)
3461 else if (iptr[0].val.l == 0x00001000)
3463 else if (iptr[0].val.l == 0x00002000)
3465 else if (iptr[0].val.l == 0x00004000)
3467 else if (iptr[0].val.l == 0x00008000)
3469 else if (iptr[0].val.l == 0x00010000)
3471 else if (iptr[0].val.l == 0x00020000)
3473 else if (iptr[0].val.l == 0x00040000)
3475 else if (iptr[0].val.l == 0x00080000)
3477 else if (iptr[0].val.l == 0x00100000)
3479 else if (iptr[0].val.l == 0x00200000)
3481 else if (iptr[0].val.l == 0x00400000)
3483 else if (iptr[0].val.l == 0x00800000)
3485 else if (iptr[0].val.l == 0x01000000)
3487 else if (iptr[0].val.l == 0x02000000)
3489 else if (iptr[0].val.l == 0x04000000)
3491 else if (iptr[0].val.l == 0x08000000)
3493 else if (iptr[0].val.l == 0x10000000)
3495 else if (iptr[0].val.l == 0x20000000)
3497 else if (iptr[0].val.l == 0x40000000)
3499 else if (iptr[0].val.l == 0x80000000)
3502 PUSHCONST(TYPE_LNG);
3505 iptr[0].opc = ICMD_LMULPOW2;
3506 goto icmd_lconst_tail;
3507 # endif /* SUPPORT_LONG_SHIFT */
3508 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
3510 #if SUPPORT_LONG_DIV_POW2
3512 if (iptr[0].val.l == 0x00000002)
3514 else if (iptr[0].val.l == 0x00000004)
3516 else if (iptr[0].val.l == 0x00000008)
3518 else if (iptr[0].val.l == 0x00000010)
3520 else if (iptr[0].val.l == 0x00000020)
3522 else if (iptr[0].val.l == 0x00000040)
3524 else if (iptr[0].val.l == 0x00000080)
3526 else if (iptr[0].val.l == 0x00000100)
3528 else if (iptr[0].val.l == 0x00000200)
3530 else if (iptr[0].val.l == 0x00000400)
3532 else if (iptr[0].val.l == 0x00000800)
3534 else if (iptr[0].val.l == 0x00001000)
3536 else if (iptr[0].val.l == 0x00002000)
3538 else if (iptr[0].val.l == 0x00004000)
3540 else if (iptr[0].val.l == 0x00008000)
3542 else if (iptr[0].val.l == 0x00010000)
3544 else if (iptr[0].val.l == 0x00020000)
3546 else if (iptr[0].val.l == 0x00040000)
3548 else if (iptr[0].val.l == 0x00080000)
3550 else if (iptr[0].val.l == 0x00100000)
3552 else if (iptr[0].val.l == 0x00200000)
3554 else if (iptr[0].val.l == 0x00400000)
3556 else if (iptr[0].val.l == 0x00800000)
3558 else if (iptr[0].val.l == 0x01000000)
3560 else if (iptr[0].val.l == 0x02000000)
3562 else if (iptr[0].val.l == 0x04000000)
3564 else if (iptr[0].val.l == 0x08000000)
3566 else if (iptr[0].val.l == 0x10000000)
3568 else if (iptr[0].val.l == 0x20000000)
3570 else if (iptr[0].val.l == 0x40000000)
3572 else if (iptr[0].val.l == 0x80000000)
3575 PUSHCONST(TYPE_LNG);
3578 iptr[0].opc = ICMD_LDIVPOW2;
3579 goto icmd_lconst_tail;
3580 #endif /* SUPPORT_LONG_DIV_POW2 */
3582 #if SUPPORT_LONG_REM_POW2
3584 if ((iptr[0].val.l == 0x00000002) ||
3585 (iptr[0].val.l == 0x00000004) ||
3586 (iptr[0].val.l == 0x00000008) ||
3587 (iptr[0].val.l == 0x00000010) ||
3588 (iptr[0].val.l == 0x00000020) ||
3589 (iptr[0].val.l == 0x00000040) ||
3590 (iptr[0].val.l == 0x00000080) ||
3591 (iptr[0].val.l == 0x00000100) ||
3592 (iptr[0].val.l == 0x00000200) ||
3593 (iptr[0].val.l == 0x00000400) ||
3594 (iptr[0].val.l == 0x00000800) ||
3595 (iptr[0].val.l == 0x00001000) ||
3596 (iptr[0].val.l == 0x00002000) ||
3597 (iptr[0].val.l == 0x00004000) ||
3598 (iptr[0].val.l == 0x00008000) ||
3599 (iptr[0].val.l == 0x00010000) ||
3600 (iptr[0].val.l == 0x00020000) ||
3601 (iptr[0].val.l == 0x00040000) ||
3602 (iptr[0].val.l == 0x00080000) ||
3603 (iptr[0].val.l == 0x00100000) ||
3604 (iptr[0].val.l == 0x00200000) ||
3605 (iptr[0].val.l == 0x00400000) ||
3606 (iptr[0].val.l == 0x00800000) ||
3607 (iptr[0].val.l == 0x01000000) ||
3608 (iptr[0].val.l == 0x02000000) ||
3609 (iptr[0].val.l == 0x04000000) ||
3610 (iptr[0].val.l == 0x08000000) ||
3611 (iptr[0].val.l == 0x10000000) ||
3612 (iptr[0].val.l == 0x20000000) ||
3613 (iptr[0].val.l == 0x40000000) ||
3614 (iptr[0].val.l == 0x80000000)) {
3615 iptr[0].opc = ICMD_LREMPOW2;
3617 goto icmd_lconst_tail;
3619 PUSHCONST(TYPE_LNG);
3621 #endif /* SUPPORT_LONG_REM_POW2 */
3623 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
3626 iptr[0].opc = ICMD_LANDCONST;
3627 goto icmd_lconst_tail;
3629 iptr[0].opc = ICMD_LORCONST;
3630 goto icmd_lconst_tail;
3632 iptr[0].opc = ICMD_LXORCONST;
3633 goto icmd_lconst_tail;
3634 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
3636 #if SUPPORT_LONG_CMP_CONST
3638 if ((len > 1) && (iptr[2].val.i == 0)) {
3639 switch (iptr[2].opc) {
3641 iptr[0].opc = ICMD_IF_LEQ;
3642 icmd_lconst_lcmp_tail:
3643 iptr[0].op1 = iptr[2].op1;
3644 iptr[1].opc = ICMD_NOP;
3645 iptr[2].opc = ICMD_NOP;
3647 /* bptr->icount -= 2; */
3651 tbptr = m->basicblocks +
3652 m->basicblockindex[iptr[0].op1];
3654 iptr[0].target = (void *) tbptr;
3656 MARKREACHED(tbptr, copy);
3657 COUNT(count_pcmd_bra);
3658 COUNT(count_pcmd_op);
3661 iptr[0].opc = ICMD_IF_LNE;
3662 goto icmd_lconst_lcmp_tail;
3664 iptr[0].opc = ICMD_IF_LLT;
3665 goto icmd_lconst_lcmp_tail;
3667 iptr[0].opc = ICMD_IF_LGT;
3668 goto icmd_lconst_lcmp_tail;
3670 iptr[0].opc = ICMD_IF_LLE;
3671 goto icmd_lconst_lcmp_tail;
3673 iptr[0].opc = ICMD_IF_LGE;
3674 goto icmd_lconst_lcmp_tail;
3676 PUSHCONST(TYPE_LNG);
3677 } /* switch (iptr[2].opc) */
3678 } /* if (iptr[2].val.i == 0) */
3680 PUSHCONST(TYPE_LNG);
3682 #endif /* SUPPORT_LONG_CMP_CONST */
3684 #if SUPPORT_CONST_STORE
3686 # if defined(ENABLE_INTRP)
3689 # if SUPPORT_CONST_STORE_ZERO_ONLY
3690 if (iptr[0].val.l == 0) {
3692 iptr[0].opc = ICMD_LASTORECONST;
3693 iptr[1].opc = ICMD_NOP;
3694 OPTT2_0(TYPE_INT, TYPE_ADR);
3695 COUNT(count_pcmd_op);
3696 # if SUPPORT_CONST_STORE_ZERO_ONLY
3699 PUSHCONST(TYPE_LNG);
3701 # if defined(ENABLE_INTRP)
3704 PUSHCONST(TYPE_LNG);
3708 case ICMD_PUTSTATIC:
3710 # if defined(ENABLE_INTRP)
3713 # if SUPPORT_CONST_STORE_ZERO_ONLY
3714 if (iptr[0].val.l == 0) {
3716 switch (iptr[1].opc) {
3717 case ICMD_PUTSTATIC:
3718 iptr[0].opc = ICMD_PUTSTATICCONST;
3722 iptr[0].opc = ICMD_PUTFIELDCONST;
3727 iptr[1].opc = ICMD_NOP;
3728 iptr[0].op1 = TYPE_LNG;
3729 COUNT(count_pcmd_op);
3730 # if SUPPORT_CONST_STORE_ZERO_ONLY
3733 PUSHCONST(TYPE_LNG);
3735 # if defined(ENABLE_INTRP)
3738 PUSHCONST(TYPE_LNG);
3741 #endif /* SUPPORT_CONST_STORE */
3743 PUSHCONST(TYPE_LNG);
3747 PUSHCONST(TYPE_LNG);
3751 COUNT(count_pcmd_load);
3752 PUSHCONST(TYPE_FLT);
3756 COUNT(count_pcmd_load);
3757 PUSHCONST(TYPE_DBL);
3761 COUNT(count_pcmd_load);
3762 #if SUPPORT_CONST_STORE
3763 # if defined(ENABLE_INTRP)
3766 /* We can only optimize if the ACONST is resolved
3767 * and there is an instruction after it. */
3769 if ((len > 0) && INSTRUCTION_IS_RESOLVED(iptr))
3771 switch (iptr[1].opc) {
3773 /* We can only optimize for NULL values
3774 * here because otherwise a checkcast is
3776 if (iptr->val.a != NULL)
3777 goto aconst_no_transform;
3779 iptr[0].opc = ICMD_AASTORECONST;
3780 OPTT2_0(TYPE_INT, TYPE_ADR);
3782 iptr[1].opc = ICMD_NOP;
3783 COUNT(count_pcmd_op);
3786 case ICMD_PUTSTATIC:
3788 # if SUPPORT_CONST_STORE_ZERO_ONLY
3789 if (iptr->val.a == 0) {
3792 switch (iptr[1].opc) {
3793 case ICMD_PUTSTATIC:
3794 iptr[0].opc = ICMD_PUTSTATICCONST;
3795 iptr[0].op1 = TYPE_ADR;
3799 iptr[0].opc = ICMD_PUTFIELDCONST;
3800 iptr[0].op1 = TYPE_ADR;
3805 iptr[1].opc = ICMD_NOP;
3806 COUNT(count_pcmd_op);
3808 # if SUPPORT_CONST_STORE_ZERO_ONLY
3811 /* no transformation */
3812 PUSHCONST(TYPE_ADR);
3817 aconst_no_transform:
3818 /* no transformation */
3819 PUSHCONST(TYPE_ADR);
3823 /* no transformation */
3824 PUSHCONST(TYPE_ADR);
3826 # if defined(ENABLE_INTRP)
3829 PUSHCONST(TYPE_ADR);
3831 #else /* SUPPORT_CONST_STORE */
3832 PUSHCONST(TYPE_ADR);
3833 #endif /* SUPPORT_CONST_STORE */
3836 /* pop 0 push 1 load */
3843 COUNT(count_load_instruction);
3844 i = opcode - ICMD_ILOAD;
3845 #if defined(ENABLE_INTRP)
3848 rd->locals[iptr->op1][i].type = i;
3849 LOAD(i, LOCALVAR, iptr->op1);
3859 COUNT(count_check_null);
3860 COUNT(count_check_bound);
3861 COUNT(count_pcmd_mem);
3862 OP2IAT_1(opcode - ICMD_IALOAD);
3868 COUNT(count_check_null);
3869 COUNT(count_check_bound);
3870 COUNT(count_pcmd_mem);
3874 /* pop 0 push 0 iinc */
3877 #if defined(ENABLE_STATISTICS)
3881 count_store_depth[10]++;
3883 count_store_depth[i]++;
3886 last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
3891 if ((copy->varkind == LOCALVAR) &&
3892 (copy->varnum == iptr->op1)) {
3893 copy->varkind = TEMPVAR;
3903 /* pop 1 push 0 store */
3912 i = opcode - ICMD_ISTORE;
3913 #if defined(ENABLE_INTRP)
3916 rd->locals[iptr->op1][i].type = i;
3917 #if defined(ENABLE_STATISTICS)
3922 count_store_length[20]++;
3924 count_store_length[i]++;
3927 count_store_depth[10]++;
3929 count_store_depth[i]++;
3932 /* check for conflicts as described in Figure 5.2 */
3933 copy = curstack->prev;
3936 if ((copy->varkind == LOCALVAR) &&
3937 (copy->varnum == iptr->op1)) {
3938 copy->varkind = TEMPVAR;
3945 /* do not change instack Stackslots */
3946 /* it won't improve performance if we copy the interface */
3947 /* at the BB begin or here, and lsra relies that no */
3948 /* instack stackslot is marked LOCALVAR */
3949 if (curstack->varkind == STACKVAR)
3950 goto _possible_conflict;
3952 /* check for a DUPX,SWAP while the lifetime of curstack */
3953 /* and as creator curstack */
3954 if (last_dupx != -1) {
3955 /* we have to look at the dst stack of DUPX */
3956 /* == src Stack of PEI */
3957 copy = bptr->iinstr[last_dupx].dst;
3960 copy = bptr->instack;
3962 copy = bptr->iinstr[last_pei-1].dst;
3964 if ((copy != NULL) && (curstack <= copy)) {
3965 /* curstack alive at or created by DUPX */
3968 /* now look, if there is a LOCALVAR at anyone of */
3969 /* the src stacklots used by DUPX */
3971 goto _possible_conflict;
3975 /* check for a PEI while the lifetime of curstack */
3976 if (last_pei != -1) {
3977 /* && there are exception handler in this method */
3978 /* when this is checked prevent ARGVAR from */
3979 /* overwriting LOCALVAR!!! */
3981 /* we have to look at the stack _before_ the PEI! */
3982 /* == src Stack of PEI */
3984 copy = bptr->instack;
3986 copy = bptr->iinstr[last_pei-1].dst;
3987 if ((copy != NULL) && (curstack <= copy)) {
3988 /* curstack alive at PEI */
3989 goto _possible_conflict;
3993 /* check if there is a possible conflicting XSTORE */
3994 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) {
3995 /* we have to look at the stack _before_ the XSTORE! */
3996 /* == src Stack of XSTORE */
3997 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0)
3998 copy = bptr->instack;
4000 copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst;
4001 if ((copy != NULL) && (curstack <= copy)) {
4002 /* curstack alive at Last Store */
4003 goto _possible_conflict;
4007 /* check if there is a conflict with a XLOAD */
4008 /* this is done indirectly by looking if a Stackslot is */
4009 /* marked LOCALVAR and is live while curstack is live */
4010 /* see figure 5.3 */
4012 /* First check "above" stackslots of the instack */
4013 copy = curstack + 1;
4014 for(;(copy <= bptr->instack); copy++)
4015 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
4016 goto _possible_conflict;
4019 /* "intra" Basic Block Stackslots are allocated above */
4020 /* bptr->stack (see doc/stack.txt), so if curstack + 1 */
4021 /* is an instack, copy could point now to the stackslots */
4022 /* of an inbetween analysed Basic Block */
4023 if (copy < bptr->stack)
4025 while (copy < new) {
4026 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
4027 goto _possible_conflict;
4031 /* If Stackslot is already marked as LOCALVAR, do not */
4032 /* change it! Conflict resolution works only, if xLOAD */
4034 if (curstack->varkind == LOCALVAR)
4035 goto _possible_conflict;
4036 /* no conflict - mark the Stackslot as LOCALVAR */
4037 curstack->varkind = LOCALVAR;
4038 curstack->varnum = iptr->op1;
4042 if ((curstack->varkind == LOCALVAR)
4043 && (curstack->varnum == iptr->op1)) {
4044 curstack->varkind = TEMPVAR;
4045 curstack->varnum = stackdepth-1;
4048 last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1;
4050 STORE(opcode - ICMD_ISTORE);
4056 COUNT(count_check_null);
4057 COUNT(count_check_bound);
4058 COUNT(count_pcmd_mem);
4060 bte = builtintable_get_internal(BUILTIN_canstore);
4063 if (md->memuse > rd->memuse)
4064 rd->memuse = md->memuse;
4065 if (md->argintreguse > rd->argintreguse)
4066 rd->argintreguse = md->argintreguse;
4068 /* make all stack variables saved */
4072 copy->flags |= SAVEDVAR;
4083 COUNT(count_check_null);
4084 COUNT(count_check_bound);
4085 COUNT(count_pcmd_mem);
4086 OP3TIA_0(opcode - ICMD_IASTORE);
4092 COUNT(count_check_null);
4093 COUNT(count_check_bound);
4094 COUNT(count_pcmd_mem);
4101 #ifdef ENABLE_VERIFIER
4104 if (IS_2_WORD_TYPE(curstack->type))
4105 goto throw_stack_category_error;
4116 #if defined(ENABLE_JIT)
4117 # if defined(ENABLE_INTRP)
4120 md_return_alloc(jd, curstack);
4122 COUNT(count_pcmd_return);
4123 OP1_0(opcode - ICMD_IRETURN);
4124 superblockend = true;
4128 COUNT(count_check_null);
4132 superblockend = true;
4135 case ICMD_PUTSTATIC:
4136 COUNT(count_pcmd_mem);
4140 /* pop 1 push 0 branch */
4143 case ICMD_IFNONNULL:
4144 COUNT(count_pcmd_bra);
4146 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
4148 iptr[0].target = (void *) tbptr;
4150 MARKREACHED(tbptr, copy);
4159 COUNT(count_pcmd_bra);
4160 #if CONDITIONAL_LOADCONST && 0
4161 # if defined(ENABLE_INTRP)
4164 tbptr = m->basicblocks + b_index;
4166 if ((b_count >= 3) &&
4167 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
4168 (tbptr[1].pre_count == 1) &&
4169 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
4170 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
4171 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
4172 (tbptr[2].pre_count == 1) &&
4173 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
4174 (tbptr[2].icount==1)) {
4175 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
4176 OP1_1(TYPE_INT, TYPE_INT);
4177 switch (iptr[0].opc) {
4179 iptr[0].opc = ICMD_IFNE_ICONST;
4182 iptr[0].opc = ICMD_IFEQ_ICONST;
4185 iptr[0].opc = ICMD_IFGE_ICONST;
4188 iptr[0].opc = ICMD_IFLT_ICONST;
4191 iptr[0].opc = ICMD_IFLE_ICONST;
4194 iptr[0].opc = ICMD_IFGT_ICONST;
4198 iptr[0].val.i = iptr[1].val.i;
4199 iptr[1].opc = ICMD_ELSE_ICONST;
4200 iptr[1].val.i = iptr[3].val.i;
4201 iptr[2].opc = ICMD_NOP;
4202 iptr[3].opc = ICMD_NOP;
4204 /* HACK: save compare value in iptr[1].op1 */
4205 iptr[1].op1 = iptr[0].val.i;
4206 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
4207 iptr[1].opc = ICMD_ELSE_ICONST;
4208 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
4209 tbptr[1].iinstr[0].opc = ICMD_NOP;
4210 tbptr[1].iinstr[1].opc = ICMD_NOP;
4211 tbptr[2].iinstr[0].opc = ICMD_NOP;
4213 tbptr[1].flags = BBDELETED;
4214 tbptr[2].flags = BBDELETED;
4215 tbptr[1].icount = 0;
4216 tbptr[2].icount = 0;
4217 if (tbptr[3].pre_count == 2) {
4218 len += tbptr[3].icount + 3;
4219 bptr->icount += tbptr[3].icount + 3;
4220 tbptr[3].flags = BBDELETED;
4221 tbptr[3].icount = 0;
4231 # if defined(ENABLE_INTRP)
4235 #endif /* CONDITIONAL_LOADCONST */
4237 /* iptr->val.i is set implicitly in parse by
4238 clearing the memory or from IF_ICMPxx
4242 /* iptr->val.i = 0; */
4243 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
4245 iptr[0].target = (void *) tbptr;
4247 MARKREACHED(tbptr, copy);
4250 /* pop 0 push 0 branch */
4253 COUNT(count_pcmd_bra);
4254 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
4256 iptr[0].target = (void *) tbptr;
4258 MARKREACHED(tbptr, copy);
4260 superblockend = true;
4263 /* pop 1 push 0 table branch */
4265 case ICMD_TABLESWITCH:
4266 COUNT(count_pcmd_table);
4268 s4ptr = iptr->val.a;
4269 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
4270 MARKREACHED(tbptr, copy);
4271 i = *s4ptr++; /* low */
4272 i = *s4ptr++ - i + 1; /* high */
4274 tptr = DMNEW(void*, i+1);
4275 iptr->target = (void *) tptr;
4277 tptr[0] = (void *) tbptr;
4281 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
4283 tptr[0] = (void *) tbptr;
4286 MARKREACHED(tbptr, copy);
4289 superblockend = true;
4292 /* pop 1 push 0 table branch */
4294 case ICMD_LOOKUPSWITCH:
4295 COUNT(count_pcmd_table);
4297 s4ptr = iptr->val.a;
4298 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
4299 MARKREACHED(tbptr, copy);
4300 i = *s4ptr++; /* count */
4302 tptr = DMNEW(void*, i+1);
4303 iptr->target = (void *) tptr;
4305 tptr[0] = (void *) tbptr;
4309 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
4311 tptr[0] = (void *) tbptr;
4314 MARKREACHED(tbptr, copy);
4318 superblockend = true;
4321 case ICMD_MONITORENTER:
4322 COUNT(count_check_null);
4323 case ICMD_MONITOREXIT:
4327 /* pop 2 push 0 branch */
4329 case ICMD_IF_ICMPEQ:
4330 case ICMD_IF_ICMPNE:
4331 case ICMD_IF_ICMPLT:
4332 case ICMD_IF_ICMPGE:
4333 case ICMD_IF_ICMPGT:
4334 case ICMD_IF_ICMPLE:
4335 COUNT(count_pcmd_bra);
4337 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
4339 iptr[0].target = (void *) tbptr;
4341 MARKREACHED(tbptr, copy);
4344 case ICMD_IF_ACMPEQ:
4345 case ICMD_IF_ACMPNE:
4346 COUNT(count_pcmd_bra);
4348 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
4350 iptr[0].target = (void *) tbptr;
4352 MARKREACHED(tbptr, copy);
4358 COUNT(count_check_null);
4359 COUNT(count_pcmd_mem);
4360 OPTT2_0(iptr->op1,TYPE_ADR);
4365 if (!IS_2_WORD_TYPE(curstack->type)) {
4367 #ifdef ENABLE_VERIFIER
4370 if (IS_2_WORD_TYPE(curstack->prev->type))
4371 goto throw_stack_category_error;
4374 OP1_0ANY; /* second pop */
4377 iptr->opc = ICMD_POP;
4381 /* pop 0 push 1 dup */
4384 #ifdef ENABLE_VERIFIER
4387 if (IS_2_WORD_TYPE(curstack->type))
4388 goto throw_stack_category_error;
4391 last_dupx = bptr->icount - len - 1;
4392 COUNT(count_dup_instruction);
4397 last_dupx = bptr->icount - len - 1;
4399 if (IS_2_WORD_TYPE(curstack->type)) {
4401 iptr->opc = ICMD_DUP;
4406 /* ..., ????, cat1 */
4407 #ifdef ENABLE_VERIFIER
4409 if (IS_2_WORD_TYPE(curstack->prev->type))
4410 goto throw_stack_category_error;
4414 NEWSTACK(copy->prev->type, copy->prev->varkind,
4415 copy->prev->varnum);
4416 NEWSTACK(copy->type, copy->varkind,
4423 /* pop 2 push 3 dup */
4426 #ifdef ENABLE_VERIFIER
4429 if (IS_2_WORD_TYPE(curstack->type) ||
4430 IS_2_WORD_TYPE(curstack->prev->type))
4431 goto throw_stack_category_error;
4434 last_dupx = bptr->icount - len - 1;
4439 last_dupx = bptr->icount - len - 1;
4441 if (IS_2_WORD_TYPE(curstack->type)) {
4442 /* ..., ????, cat2 */
4443 #ifdef ENABLE_VERIFIER
4445 if (IS_2_WORD_TYPE(curstack->prev->type))
4446 goto throw_stack_category_error;
4449 iptr->opc = ICMD_DUP_X1;
4453 /* ..., ????, cat1 */
4454 #ifdef ENABLE_VERIFIER
4457 if (IS_2_WORD_TYPE(curstack->prev->type)
4458 || IS_2_WORD_TYPE(curstack->prev->prev->type))
4459 goto throw_stack_category_error;
4466 /* pop 3 push 4 dup */
4469 last_dupx = bptr->icount - len - 1;
4471 if (IS_2_WORD_TYPE(curstack->prev->type)) {
4472 /* ..., cat2, ???? */
4473 #ifdef ENABLE_VERIFIER
4475 if (IS_2_WORD_TYPE(curstack->type))
4476 goto throw_stack_category_error;
4479 iptr->opc = ICMD_DUP_X1;
4483 /* ..., cat1, ???? */
4484 #ifdef ENABLE_VERIFIER
4487 if (IS_2_WORD_TYPE(curstack->type)
4488 || IS_2_WORD_TYPE(curstack->prev->prev->type))
4489 goto throw_stack_category_error;
4497 last_dupx = bptr->icount - len - 1;
4499 if (IS_2_WORD_TYPE(curstack->type)) {
4500 /* ..., ????, cat2 */
4501 if (IS_2_WORD_TYPE(curstack->prev->type)) {
4502 /* ..., cat2, cat2 */
4503 iptr->opc = ICMD_DUP_X1;
4507 /* ..., cat1, cat2 */
4508 #ifdef ENABLE_VERIFIER
4511 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
4512 goto throw_stack_category_error;
4515 iptr->opc = ICMD_DUP_X2;
4521 /* ..., ????, ????, cat1 */
4522 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
4523 /* ..., cat2, ????, cat1 */
4524 #ifdef ENABLE_VERIFIER
4526 if (IS_2_WORD_TYPE(curstack->prev->type))
4527 goto throw_stack_category_error;
4530 iptr->opc = ICMD_DUP2_X1;
4534 /* ..., cat1, ????, cat1 */
4535 #ifdef ENABLE_VERIFIER
4538 if (IS_2_WORD_TYPE(curstack->prev->type)
4539 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
4540 goto throw_stack_category_error;
4548 /* pop 2 push 2 swap */
4551 last_dupx = bptr->icount - len - 1;
4552 #ifdef ENABLE_VERIFIER
4555 if (IS_2_WORD_TYPE(curstack->type)
4556 || IS_2_WORD_TYPE(curstack->prev->type))
4557 goto throw_stack_category_error;
4567 #if !SUPPORT_DIVISION
4568 bte = (builtintable_entry *) iptr->val.a;
4572 if (md->memuse > rd->memuse)
4573 rd->memuse = md->memuse;
4574 if (md->argintreguse > rd->argintreguse)
4575 rd->argintreguse = md->argintreguse;
4577 /* make all stack variables saved */
4581 copy->flags |= SAVEDVAR;
4586 #endif /* !SUPPORT_DIVISION */
4597 COUNT(count_pcmd_op);
4603 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
4604 bte = (builtintable_entry *) iptr->val.a;
4608 if (md->memuse > rd->memuse)
4609 rd->memuse = md->memuse;
4610 if (md->argintreguse > rd->argintreguse)
4611 rd->argintreguse = md->argintreguse;
4613 /* make all stack variables saved */
4617 copy->flags |= SAVEDVAR;
4622 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
4627 #if SUPPORT_LONG_LOGICAL
4631 #endif /* SUPPORT_LONG_LOGICAL */
4632 COUNT(count_pcmd_op);
4639 COUNT(count_pcmd_op);
4648 COUNT(count_pcmd_op);
4657 COUNT(count_pcmd_op);
4662 COUNT(count_pcmd_op);
4663 #if SUPPORT_LONG_CMP_CONST
4664 if ((len > 0) && (iptr[1].val.i == 0)) {
4665 switch (iptr[1].opc) {
4667 iptr[0].opc = ICMD_IF_LCMPEQ;
4669 iptr[0].op1 = iptr[1].op1;
4670 iptr[1].opc = ICMD_NOP;
4672 /* bptr->icount--; */
4675 tbptr = m->basicblocks +
4676 m->basicblockindex[iptr[0].op1];
4678 iptr[0].target = (void *) tbptr;
4680 MARKREACHED(tbptr, copy);
4681 COUNT(count_pcmd_bra);
4684 iptr[0].opc = ICMD_IF_LCMPNE;
4685 goto icmd_lcmp_if_tail;
4687 iptr[0].opc = ICMD_IF_LCMPLT;
4688 goto icmd_lcmp_if_tail;
4690 iptr[0].opc = ICMD_IF_LCMPGT;
4691 goto icmd_lcmp_if_tail;
4693 iptr[0].opc = ICMD_IF_LCMPLE;
4694 goto icmd_lcmp_if_tail;
4696 iptr[0].opc = ICMD_IF_LCMPGE;
4697 goto icmd_lcmp_if_tail;
4699 OPTT2_1(TYPE_LNG, TYPE_INT);
4703 #endif /* SUPPORT_LONG_CMP_CONST */
4704 OPTT2_1(TYPE_LNG, TYPE_INT);
4709 COUNT(count_pcmd_op);
4710 if ((len > 0) && (iptr[1].val.i == 0)) {
4711 switch (iptr[1].opc) {
4713 iptr[0].opc = ICMD_IF_FCMPEQ;
4715 iptr[0].op1 = iptr[1].op1;
4716 iptr[1].opc = ICMD_NOP;
4719 tbptr = m->basicblocks +
4720 m->basicblockindex[iptr[0].op1];
4722 iptr[0].target = (void *) tbptr;
4724 MARKREACHED(tbptr, copy);
4725 COUNT(count_pcmd_bra);
4728 iptr[0].opc = ICMD_IF_FCMPNE;
4729 goto icmd_if_fcmpl_tail;
4731 iptr[0].opc = ICMD_IF_FCMPL_LT;
4732 goto icmd_if_fcmpl_tail;
4734 iptr[0].opc = ICMD_IF_FCMPL_GT;
4735 goto icmd_if_fcmpl_tail;
4737 iptr[0].opc = ICMD_IF_FCMPL_LE;
4738 goto icmd_if_fcmpl_tail;
4740 iptr[0].opc = ICMD_IF_FCMPL_GE;
4741 goto icmd_if_fcmpl_tail;
4743 OPTT2_1(TYPE_FLT, TYPE_INT);
4747 OPTT2_1(TYPE_FLT, TYPE_INT);
4751 COUNT(count_pcmd_op);
4752 if ((len > 0) && (iptr[1].val.i == 0)) {
4753 switch (iptr[1].opc) {
4755 iptr[0].opc = ICMD_IF_FCMPEQ;
4757 iptr[0].op1 = iptr[1].op1;
4758 iptr[1].opc = ICMD_NOP;
4761 tbptr = m->basicblocks +
4762 m->basicblockindex[iptr[0].op1];
4764 iptr[0].target = (void *) tbptr;
4766 MARKREACHED(tbptr, copy);
4767 COUNT(count_pcmd_bra);
4770 iptr[0].opc = ICMD_IF_FCMPNE;
4771 goto icmd_if_fcmpg_tail;
4773 iptr[0].opc = ICMD_IF_FCMPG_LT;
4774 goto icmd_if_fcmpg_tail;
4776 iptr[0].opc = ICMD_IF_FCMPG_GT;
4777 goto icmd_if_fcmpg_tail;
4779 iptr[0].opc = ICMD_IF_FCMPG_LE;
4780 goto icmd_if_fcmpg_tail;
4782 iptr[0].opc = ICMD_IF_FCMPG_GE;
4783 goto icmd_if_fcmpg_tail;
4785 OPTT2_1(TYPE_FLT, TYPE_INT);
4789 OPTT2_1(TYPE_FLT, TYPE_INT);
4793 COUNT(count_pcmd_op);
4794 if ((len > 0) && (iptr[1].val.i == 0)) {
4795 switch (iptr[1].opc) {
4797 iptr[0].opc = ICMD_IF_DCMPEQ;
4799 iptr[0].op1 = iptr[1].op1;
4800 iptr[1].opc = ICMD_NOP;
4803 tbptr = m->basicblocks +
4804 m->basicblockindex[iptr[0].op1];
4806 iptr[0].target = (void *) tbptr;
4808 MARKREACHED(tbptr, copy);
4809 COUNT(count_pcmd_bra);
4812 iptr[0].opc = ICMD_IF_DCMPNE;
4813 goto icmd_if_dcmpl_tail;
4815 iptr[0].opc = ICMD_IF_DCMPL_LT;
4816 goto icmd_if_dcmpl_tail;
4818 iptr[0].opc = ICMD_IF_DCMPL_GT;
4819 goto icmd_if_dcmpl_tail;
4821 iptr[0].opc = ICMD_IF_DCMPL_LE;
4822 goto icmd_if_dcmpl_tail;
4824 iptr[0].opc = ICMD_IF_DCMPL_GE;
4825 goto icmd_if_dcmpl_tail;
4827 OPTT2_1(TYPE_DBL, TYPE_INT);
4831 OPTT2_1(TYPE_DBL, TYPE_INT);
4835 COUNT(count_pcmd_op);
4836 if ((len > 0) && (iptr[1].val.i == 0)) {
4837 switch (iptr[1].opc) {
4839 iptr[0].opc = ICMD_IF_DCMPEQ;
4841 iptr[0].op1 = iptr[1].op1;
4842 iptr[1].opc = ICMD_NOP;
4845 tbptr = m->basicblocks +
4846 m->basicblockindex[iptr[0].op1];
4848 iptr[0].target = (void *) tbptr;
4850 MARKREACHED(tbptr, copy);
4851 COUNT(count_pcmd_bra);
4854 iptr[0].opc = ICMD_IF_DCMPNE;
4855 goto icmd_if_dcmpg_tail;
4857 iptr[0].opc = ICMD_IF_DCMPG_LT;
4858 goto icmd_if_dcmpg_tail;
4860 iptr[0].opc = ICMD_IF_DCMPG_GT;
4861 goto icmd_if_dcmpg_tail;
4863 iptr[0].opc = ICMD_IF_DCMPG_LE;
4864 goto icmd_if_dcmpg_tail;
4866 iptr[0].opc = ICMD_IF_DCMPG_GE;
4867 goto icmd_if_dcmpg_tail;
4869 OPTT2_1(TYPE_DBL, TYPE_INT);
4873 OPTT2_1(TYPE_DBL, TYPE_INT);
4878 COUNT(count_pcmd_op);
4879 OPTT2_1(TYPE_FLT, TYPE_INT);
4884 COUNT(count_pcmd_op);
4885 OPTT2_1(TYPE_DBL, TYPE_INT);
4894 case ICMD_INT2SHORT:
4895 COUNT(count_pcmd_op);
4896 OP1_1(TYPE_INT, TYPE_INT);
4899 COUNT(count_pcmd_op);
4900 OP1_1(TYPE_LNG, TYPE_LNG);
4903 COUNT(count_pcmd_op);
4904 OP1_1(TYPE_FLT, TYPE_FLT);
4907 COUNT(count_pcmd_op);
4908 OP1_1(TYPE_DBL, TYPE_DBL);
4912 COUNT(count_pcmd_op);
4913 OP1_1(TYPE_INT, TYPE_LNG);
4916 COUNT(count_pcmd_op);
4917 OP1_1(TYPE_INT, TYPE_FLT);
4920 COUNT(count_pcmd_op);
4921 OP1_1(TYPE_INT, TYPE_DBL);
4924 COUNT(count_pcmd_op);
4925 OP1_1(TYPE_LNG, TYPE_INT);
4928 COUNT(count_pcmd_op);
4929 OP1_1(TYPE_LNG, TYPE_FLT);
4932 COUNT(count_pcmd_op);
4933 OP1_1(TYPE_LNG, TYPE_DBL);
4936 COUNT(count_pcmd_op);
4937 OP1_1(TYPE_FLT, TYPE_INT);
4940 COUNT(count_pcmd_op);
4941 OP1_1(TYPE_FLT, TYPE_LNG);
4944 COUNT(count_pcmd_op);
4945 OP1_1(TYPE_FLT, TYPE_DBL);
4948 COUNT(count_pcmd_op);
4949 OP1_1(TYPE_DBL, TYPE_INT);
4952 COUNT(count_pcmd_op);
4953 OP1_1(TYPE_DBL, TYPE_LNG);
4956 COUNT(count_pcmd_op);
4957 OP1_1(TYPE_DBL, TYPE_FLT);
4960 case ICMD_CHECKCAST:
4961 if (iptr->op1 == 0) {
4962 /* array type cast-check */
4964 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4967 if (md->memuse > rd->memuse)
4968 rd->memuse = md->memuse;
4969 if (md->argintreguse > rd->argintreguse)
4970 rd->argintreguse = md->argintreguse;
4972 /* make all stack variables saved */
4976 copy->flags |= SAVEDVAR;
4980 OP1_1(TYPE_ADR, TYPE_ADR);
4983 case ICMD_INSTANCEOF:
4984 case ICMD_ARRAYLENGTH:
4985 OP1_1(TYPE_ADR, TYPE_INT);
4989 case ICMD_ANEWARRAY:
4990 OP1_1(TYPE_INT, TYPE_ADR);
4994 COUNT(count_check_null);
4995 COUNT(count_pcmd_mem);
4996 OP1_1(TYPE_ADR, iptr->op1);
5001 case ICMD_GETSTATIC:
5002 COUNT(count_pcmd_mem);
5012 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
5014 iptr[0].target = (void *) tbptr;
5016 /* This is a dirty hack. The typechecker
5017 * needs it because the OP1_0ANY below
5018 * overwrites iptr->dst.
5020 iptr->val.a = (void *) iptr->dst;
5022 tbptr->type = BBTYPE_SBR;
5024 /* We need to check for overflow right here because
5025 * the pushed value is poped after MARKREACHED. */
5027 MARKREACHED(tbptr, copy);
5031 /* pop many push any */
5034 #if defined(USEBUILTINTABLE)
5037 bte = (builtintable_entry *) iptr->val.a;
5041 case ICMD_INVOKESTATIC:
5042 case ICMD_INVOKESPECIAL:
5043 case ICMD_INVOKEVIRTUAL:
5044 case ICMD_INVOKEINTERFACE:
5045 COUNT(count_pcmd_met);
5046 INSTRUCTION_GET_METHODDESC(iptr,md);
5047 /* if (lm->flags & ACC_STATIC) */
5048 /* {COUNT(count_check_null);} */
5052 last_pei = bptr->icount - len - 1;
5056 if (md->memuse > rd->memuse)
5057 rd->memuse = md->memuse;
5058 if (md->argintreguse > rd->argintreguse)
5059 rd->argintreguse = md->argintreguse;
5060 if (md->argfltreguse > rd->argfltreguse)
5061 rd->argfltreguse = md->argfltreguse;
5066 for (i-- ; i >= 0; i--) {
5067 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
5068 /* If we pass float arguments in integer argument registers, we
5069 * are not allowed to precolor them here. Floats have to be moved
5070 * to this regs explicitly in codegen().
5071 * Only arguments that are passed by stack anyway can be precolored
5072 * (michi 2005/07/24) */
5073 if (!(copy->flags & SAVEDVAR) &&
5074 (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
5076 if (!(copy->flags & SAVEDVAR)) {
5078 copy->varkind = ARGVAR;
5081 #if defined(ENABLE_INTRP)
5084 if (md->params[i].inmemory) {
5085 copy->flags = INMEMORY;
5086 copy->regoff = md->params[i].regoff;
5090 if (IS_FLT_DBL_TYPE(copy->type))
5091 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
5092 assert(0); /* XXX is this assert ok? */
5095 rd->argfltregs[md->params[i].regoff];
5098 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
5099 if (IS_2_WORD_TYPE(copy->type))
5100 copy->regoff = PACK_REGS(
5101 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
5102 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
5106 rd->argintregs[md->params[i].regoff];
5109 #if defined(ENABLE_INTRP)
5117 copy->flags |= SAVEDVAR;
5123 if (md->returntype.type != TYPE_VOID)
5124 OP0_1(md->returntype.type);
5127 case ICMD_INLINE_START:
5128 case ICMD_INLINE_END:
5132 case ICMD_MULTIANEWARRAY:
5133 if (rd->argintreguse < 3)
5134 rd->argintreguse = 3;
5139 #if defined(SPECIALMEMUSE)
5140 # if defined(__DARWIN__)
5141 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
5142 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
5144 if (rd->memuse < (i + LA_WORD_SIZE + 3))
5145 rd->memuse = i + LA_WORD_SIZE + 3;
5148 # if defined(__I386__)
5149 if (rd->memuse < i + 3)
5150 rd->memuse = i + 3; /* n integer args spilled on stack */
5151 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
5152 if (rd->memuse < i + 2)
5153 rd->memuse = i + 2; /* 4*4 bytes callee save space */
5156 rd->memuse = i; /* n integer args spilled on stack */
5157 # endif /* defined(__I386__) */
5161 /* check INT type here? Currently typecheck does this. */
5162 if (!(copy->flags & SAVEDVAR)) {
5163 copy->varkind = ARGVAR;
5164 copy->varnum = i + INT_ARG_CNT;
5165 copy->flags |= INMEMORY;
5166 #if defined(SPECIALMEMUSE)
5167 # if defined(__DARWIN__)
5168 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
5170 copy->regoff = i + LA_WORD_SIZE + 3;
5173 # if defined(__I386__)
5174 copy->regoff = i + 3;
5175 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
5176 copy->regoff = i + 2;
5179 # endif /* defined(__I386__) */
5180 #endif /* defined(SPECIALMEMUSE) */
5185 copy->flags |= SAVEDVAR;
5195 new_internalerror("Unknown ICMD %d", opcode);
5201 } /* while instructions */
5203 /* set out-stack of block */
5205 bptr->outstack = curstack;
5206 bptr->outdepth = stackdepth;
5208 /* stack slots at basic block end become interfaces */
5211 for (copy = curstack; copy; i--, copy = copy->prev) {
5212 if ((copy->varkind == STACKVAR) && (copy->varnum > i))
5213 copy->varkind = TEMPVAR;
5215 copy->varkind = STACKVAR;
5219 rd->interfaces[i][copy->type].type = copy->type;
5220 rd->interfaces[i][copy->type].flags |= copy->flags;
5224 /* check if interface slots at basic block begin must be saved */
5227 i = bptr->indepth - 1;
5228 for (copy = bptr->instack; copy; i--, copy = copy->prev) {
5229 rd->interfaces[i][copy->type].type = copy->type;
5230 if (copy->varkind == STACKVAR) {
5231 if (copy->flags & SAVEDVAR)
5232 rd->interfaces[i][copy->type].flags |= SAVEDVAR;
5239 superblockend = true;
5242 } /* while blocks */
5243 } while (repeat && !deadcode);
5245 #if defined(ENABLE_STATISTICS)
5247 if (m->basicblockcount > count_max_basic_blocks)
5248 count_max_basic_blocks = m->basicblockcount;
5249 count_basic_blocks += m->basicblockcount;
5250 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
5251 count_javainstr += m->instructioncount;
5252 if (m->stackcount > count_upper_bound_new_stack)
5253 count_upper_bound_new_stack = m->stackcount;
5254 if ((new - m->stack) > count_max_new_stack)
5255 count_max_new_stack = (new - m->stack);
5257 b_count = m->basicblockcount;
5258 bptr = m->basicblocks;
5259 while (--b_count >= 0) {
5260 if (bptr->flags > BBREACHED) {
5261 if (bptr->indepth >= 10)
5262 count_block_stack[10]++;
5264 count_block_stack[bptr->indepth]++;
5267 count_block_size_distribution[len]++;
5269 count_block_size_distribution[10]++;
5271 count_block_size_distribution[11]++;
5273 count_block_size_distribution[12]++;
5275 count_block_size_distribution[13]++;
5277 count_block_size_distribution[14]++;
5279 count_block_size_distribution[15]++;
5281 count_block_size_distribution[16]++;
5283 count_block_size_distribution[17]++;
5289 count_analyse_iterations[0]++;
5290 else if (loops == 2)
5291 count_analyse_iterations[1]++;
5292 else if (loops == 3)
5293 count_analyse_iterations[2]++;
5294 else if (loops == 4)
5295 count_analyse_iterations[3]++;
5297 count_analyse_iterations[4]++;
5299 if (m->basicblockcount <= 5)
5300 count_method_bb_distribution[0]++;
5301 else if (m->basicblockcount <= 10)
5302 count_method_bb_distribution[1]++;
5303 else if (m->basicblockcount <= 15)
5304 count_method_bb_distribution[2]++;
5305 else if (m->basicblockcount <= 20)
5306 count_method_bb_distribution[3]++;
5307 else if (m->basicblockcount <= 30)
5308 count_method_bb_distribution[4]++;
5309 else if (m->basicblockcount <= 40)
5310 count_method_bb_distribution[5]++;
5311 else if (m->basicblockcount <= 50)
5312 count_method_bb_distribution[6]++;
5313 else if (m->basicblockcount <= 75)
5314 count_method_bb_distribution[7]++;
5316 count_method_bb_distribution[8]++;
5318 #endif /* defined(ENABLE_STATISTICS) */
5320 /* everything's ok */
5324 #if defined(ENABLE_VERIFIER)
5326 throw_stack_underflow:
5328 new_verifyerror(m, "Unable to pop operand off an empty stack");
5331 throw_stack_overflow:
5332 *exceptionptr = new_verifyerror(m, "Stack size too large");
5335 throw_stack_depth_error:
5336 *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
5339 throw_stack_type_error:
5340 exceptions_throw_verifyerror_for_stack(m, expectedtype);
5343 throw_stack_category_error:
5345 new_verifyerror(m, "Attempt to split long or double on the stack");
5354 * These are local overrides for various environment variables in Emacs.
5355 * Please do not remove this and leave it at the end of the file, where
5356 * Emacs will automagically detect them.
5357 * ---------------------------------------------------------------------
5360 * indent-tabs-mode: t
5364 * vim:noexpandtab:sw=4:ts=4: