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 5404 2006-09-07 13:29:05Z christian $
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/cfg.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/abi.h"
61 #include "vm/jit/show.h"
63 #if defined(ENABLE_DISASSEMBLER)
64 # include "vm/jit/disass.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/stack.h"
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 /*#define STACK_VERBOSE*/
77 /* macro for saving #ifdefs ***************************************************/
79 #if defined(ENABLE_INTRP)
80 #define IF_INTRP(x) if (opt_intrp) { x }
81 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
84 #define IF_NO_INTRP(x) { x }
87 #if defined(ENABLE_INTRP)
88 #if defined(ENABLE_JIT)
89 #define IF_JIT(x) if (!opt_intrp) { x }
93 #else /* !defined(ENABLE_INTRP) */
94 #define IF_JIT(x) { x }
95 #endif /* defined(ENABLE_INTRP) */
97 #if defined(ENABLE_STATISTICS)
98 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
101 if (stackdepth >= 10) \
102 count_store_depth[10]++; \
104 count_store_depth[stackdepth]++; \
107 #else /* !defined(ENABLE_STATISTICS) */
108 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
111 /* stack_init ******************************************************************
113 Initialized the stack analysis subsystem (called by jit_init).
115 *******************************************************************************/
117 bool stack_init(void)
123 /* stack_analyse ***************************************************************
125 Analyse_stack uses the intermediate code created by parse.c to
126 build a model of the JVM operand stack for the current method.
128 The following checks are performed:
129 - check for operand stack underflow (before each instruction)
130 - check for operand stack overflow (after[1] each instruction)
131 - check for matching stack depth at merging points
132 - check for matching basic types[2] at merging points
133 - check basic types for instruction input (except for BUILTIN*
134 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
136 [1]) Checking this after the instruction should be ok. parse.c
137 counts the number of required stack slots in such a way that it is
138 only vital that we don't exceed `maxstack` at basic block
141 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
142 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
143 types are not discerned.
145 *******************************************************************************/
147 #define GET_NEW_INDEX(new_varindex) \
149 assert(jd->vartop < jd->varcount); \
150 (new_varindex) = (jd->vartop)++; \
153 /* not implemented now, can be used to reuse varindices */
154 /* pay attention to not release a localvar once implementing it! */
155 #define RELEASE_INDEX(varindex)
157 /* with the new vars setting an OUTVAR is not as trivial as changing */
158 /* the varkind before. If varindex was a localvar, a new TEMPVAR has */
159 /* to be created for the slot and the OUTVAR flag set */
160 #define SET_OUTVAR(sp) \
162 if (IS_LOCALVAR((sp))) { \
163 GET_NEW_INDEX(new_index); \
164 sp->varnum = new_index; \
167 SET_OUTVAR_BY_INDEX((sp)->varnum); \
170 #define SET_OUTVAR_BY_INDEX(index) \
172 assert(index >= jd->localcount); \
173 jd->var[(index)].flags |=OUTVAR; \
177 #define SET_TEMPVAR(sp) \
179 if ( IS_LOCALVAR( (sp) ) ) { \
180 GET_NEW_INDEX(new_index); \
181 (sp)->varnum = new_index; \
182 jd->var[(sp)->varnum].flags = copy->flags; \
184 jd->var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC); \
187 #define SET_PREALLOC(sp) \
189 assert(!IS_LOCALVAR((sp))); \
190 jd->var[(sp)->varnum].flags |= PREALLOC; \
193 #define IS_OUTVAR(sp) \
194 (jd->var[(sp)->varnum].flags & OUTVAR)
196 #define IS_PREALLOC(sp) \
197 (jd->var[(sp)->varnum].flags & PREALLOC)
199 #define IS_TEMPVAR(sp) \
200 ( (jd->var[(sp)->varnum].flags & (OUTVAR | PREALLOC) \
201 && (((sp)->varnum < jd->localcount)) == 0) )
203 #define IS_LOCALVAR(sp) \
204 ((sp)->varnum < jd->localcount)
207 (iptr->s1.varindex = -1)
209 #define USE_S1_LOCAL(type1)
211 #define USE_S1(type1) \
214 CHECK_BASIC_TYPE(type1, curstack->type); \
215 iptr->s1.varindex = curstack->varnum; \
221 iptr->s1.varindex = curstack->varnum; \
224 #define USE_S1_S2(type1, type2) \
227 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
228 CHECK_BASIC_TYPE(type2, curstack->type); \
229 iptr->sx.s23.s2.varindex = curstack->varnum; \
230 iptr->s1.varindex = curstack->prev->varnum; \
233 #define USE_S1_S2_ANY_ANY \
236 iptr->sx.s23.s2.varindex = curstack->varnum; \
237 iptr->s1.varindex = curstack->prev->varnum; \
240 #define USE_S1_S2_S3(type1, type2, type3) \
243 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
244 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
245 CHECK_BASIC_TYPE(type3, curstack->type); \
246 iptr->sx.s23.s3.varindex = curstack->varnum; \
247 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
248 iptr->s1.varindex = curstack->prev->prev->varnum; \
252 (iptr->dst.varindex = -1)
254 #define DST(typed, index) \
256 NEWSTACKn((typed),(index)); \
257 iptr->dst.varindex = (index); \
260 #define DST_LOCALVAR(typed, index) \
262 NEWSTACK(typed, LOCALVAR, (index)); \
263 iptr->dst.varindex = (index); \
266 #define OP0_1(typed) \
269 GET_NEW_INDEX(new_index); \
270 DST(typed, new_index); \
281 #define OP1_BRANCH(type1) \
287 #define OP1_1(type1, typed) \
290 GET_NEW_INDEX(new_index); \
291 DST(typed, new_index); \
294 #define OP2_1(type1, type2, typed) \
296 POP_S1_S2(type1, type2); \
297 GET_NEW_INDEX(new_index); \
298 DST(typed, new_index); \
302 #define DUP_SLOT(sp) \
304 if ((sp)->varkind != TEMPVAR) { \
305 GET_NEW_INDEX(new_index); \
306 NEWSTACK((sp)->type, TEMPVAR, new_index); \
309 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
312 #else /* defined(NEW_VAR) */
315 (iptr->s1.var = NULL)
317 #define USE_S1_LOCAL(type1)
319 #define USE_S1(type1) \
322 CHECK_BASIC_TYPE(type1, curstack->type); \
323 iptr->s1.var = curstack; \
329 iptr->s1.var = curstack; \
332 #define USE_S1_S2(type1, type2) \
335 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
336 CHECK_BASIC_TYPE(type2, curstack->type); \
337 iptr->sx.s23.s2.var = curstack; \
338 iptr->s1.var = curstack->prev; \
341 #define USE_S1_S2_ANY_ANY \
344 iptr->sx.s23.s2.var = curstack; \
345 iptr->s1.var = curstack->prev; \
348 #define USE_S1_S2_S3(type1, type2, type3) \
351 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
352 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
353 CHECK_BASIC_TYPE(type3, curstack->type); \
354 iptr->sx.s23.s3.var = curstack; \
355 iptr->sx.s23.s2.var = curstack->prev; \
356 iptr->s1.var = curstack->prev->prev; \
360 (iptr->dst.var = NULL)
362 #define DST(typed, depth) \
364 NEWSTACKn(typed, (depth)); \
365 iptr->dst.var = curstack; \
368 #define DST_LOCALVAR(typed, index) \
370 NEWSTACK(typed, LOCALVAR, (index)); \
371 iptr->dst.var = curstack; \
374 #define OP0_1(typed) \
377 DST(typed, stackdepth); \
388 #define OP1_BRANCH(type1) \
394 #define OP1_1(type1, typed) \
397 DST(typed, stackdepth - 1); \
400 #define OP2_1(type1, type2, typed) \
402 POP_S1_S2(type1, type2); \
403 DST(typed, stackdepth - 2); \
407 #define DUP_SLOT(sp) \
409 if ((sp)->varkind != TEMPVAR) \
410 NEWSTACK((sp)->type, TEMPVAR, stackdepth); \
412 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
415 #endif /* defined(NEW_VAR) */
418 #define POP_S1(type1) \
421 if (curstack->varkind == UNDEFVAR) \
422 curstack->varkind = TEMPVAR; \
423 curstack = curstack->prev; \
429 if (curstack->varkind == UNDEFVAR) \
430 curstack->varkind = TEMPVAR; \
431 curstack = curstack->prev; \
434 #define POP_S1_S2(type1, type2) \
436 USE_S1_S2(type1, type2); \
437 if (curstack->varkind == UNDEFVAR) \
438 curstack->varkind = TEMPVAR; \
439 if (curstack->prev->varkind == UNDEFVAR) \
440 curstack->prev->varkind = TEMPVAR; \
441 curstack = curstack->prev->prev; \
444 #define POP_S1_S2_ANY_ANY \
447 if (curstack->varkind == UNDEFVAR) \
448 curstack->varkind = TEMPVAR; \
449 if (curstack->prev->varkind == UNDEFVAR) \
450 curstack->prev->varkind = TEMPVAR; \
451 curstack = curstack->prev->prev; \
454 #define POP_S1_S2_S3(type1, type2, type3) \
456 USE_S1_S2_S3(type1, type2, type3); \
457 if (curstack->varkind == UNDEFVAR) \
458 curstack->varkind = TEMPVAR; \
459 if (curstack->prev->varkind == UNDEFVAR) \
460 curstack->prev->varkind = TEMPVAR; \
461 if (curstack->prev->prev->varkind == UNDEFVAR) \
462 curstack->prev->prev->varkind = TEMPVAR; \
463 curstack = curstack->prev->prev->prev; \
480 #define OP1_0(type1) \
487 #define OP2_0(type1, type2) \
489 POP_S1_S2(type1, type2); \
494 #define OP2_BRANCH(type1, type2) \
496 POP_S1_S2(type1, type2); \
500 #define OP2_0_ANY_ANY \
507 #define OP3_0(type1, type2, type3) \
509 POP_S1_S2_S3(type1, type2, type3); \
514 #define LOAD(type1, index) \
516 DST_LOCALVAR(type1, index); \
520 #define STORE(type1, index) \
526 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
528 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
529 MARKREACHED(tempbptr, tempsp); \
532 #define BRANCH(tempbptr, tempsp) \
534 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
535 MARKREACHED(tempbptr, tempsp); \
538 bool new_stack_analyse(jitdata *jd)
540 methodinfo *m; /* method being analyzed */
544 int b_count; /* basic block counter */
545 int b_index; /* basic block index */
547 stackptr curstack; /* current stack top */
550 int opcode; /* opcode of current instruction */
552 int len; /* # of instructions after the current one */
553 bool superblockend; /* if true, no fallthrough to next block */
554 bool repeat; /* if true, outermost loop must run again */
555 bool deadcode; /* true if no live code has been reached */
556 instruction *iptr; /* the current instruction */
557 basicblock *bptr; /* the current basic block */
560 stackptr *last_store_boundary;
561 stackptr last_pei_boundary;
562 stackptr last_dup_boundary;
564 branch_target_t *table;
565 lookup_target_t *lookup;
566 #if defined(ENABLE_VERIFIER)
567 int expectedtype; /* used by CHECK_BASIC_TYPE */
569 builtintable_entry *bte;
571 constant_FMIref *fmiref;
572 #if defined(ENABLE_STATISTICS)
573 int iteration_count; /* number of iterations of analysis */
576 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
578 #if defined(STACK_VERBOSE)
579 new_show_method(jd, SHOW_PARSE);
582 /* get required compiler data - initialization */
589 #if defined(ENABLE_LSRA)
593 #if defined(ENABLE_STATISTICS)
598 /* init jd->interface_map */
600 jd->interface_map = DMNEW(s4, m->maxstack * 5);
601 for (i = 0; i < m->maxstack * 5; i++)
602 jd->interface_map[i] = UNUSED;
604 last_store_boundary = DMNEW(stackptr, jd->localcount);
606 last_store_boundary = DMNEW(stackptr , cd->maxlocals);
609 /* initialize in-stack of first block */
612 jd->new_basicblocks[0].flags = BBREACHED;
613 jd->new_basicblocks[0].instack = NULL;
614 jd->new_basicblocks[0].invars = NULL;
615 jd->new_basicblocks[0].indepth = 0;
617 /* initialize in-stack of exception handlers */
619 for (i = 0; i < cd->exceptiontablelength; i++) {
620 bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
621 bptr->flags = BBREACHED;
622 bptr->type = BBTYPE_EXH;
625 bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
628 GET_NEW_INDEX(new_index);
629 bptr->invars = DMNEW(s4, 1);
630 bptr->invars[0] = new_index;
631 NEWSTACK(TYPE_ADR, STACKVAR, new_index);
633 jd->interface_map[0 * 5 + TYPE_ADR] = new_index;
634 SET_OUTVAR_BY_INDEX(new_index);
636 bptr->invars = DMNEW(stackptr, 1);
637 bptr->invars[0] = new;
642 /* stack analysis loop (until fixpoint reached) **************************/
645 #if defined(ENABLE_STATISTICS)
649 /* initialize loop over basic blocks */
651 b_count = jd->new_basicblockcount;
652 bptr = jd->new_basicblocks;
653 superblockend = true;
658 /* iterate over basic blocks *****************************************/
660 while (--b_count >= 0) {
661 #if defined(STACK_VERBOSE)
662 printf("----\nANALYZING BLOCK L%03d ", bptr->nr);
663 if (bptr->type == BBTYPE_EXH) printf("EXH\n");
664 else if (bptr->type == BBTYPE_SBR) printf("SBR\n");
665 else printf("STD\n");
669 if (bptr->flags == BBDELETED) {
670 /* This block has been deleted - do nothing. */
672 else if (superblockend && (bptr->flags < BBREACHED)) {
673 /* This block has not been reached so far, and we */
674 /* don't fall into it, so we'll have to iterate again. */
677 else if (bptr->flags <= BBREACHED) {
679 /* We know that bptr->flags == BBREACHED. */
680 /* This block has been reached before. */
681 stackdepth = bptr->indepth;
683 else if (bptr->flags < BBREACHED) {
684 /* This block is reached for the first time now */
685 /* by falling through from the previous block. */
687 bptr->instack = copy;
690 bptr->invars = DMNEW(s4, stackdepth);
691 for (i=stackdepth; i--; copy = copy->prev)
692 bptr->invars[i] = copy->varnum;
694 bptr->invars = DMNEW(stackptr, stackdepth);
695 for (i=stackdepth; i--; copy = copy->prev)
696 bptr->invars[i] = copy;
698 bptr->indepth = stackdepth;
701 /* This block has been reached before. now we are */
702 /* falling into it from the previous block. */
703 /* Check that stack depth is well-defined. */
704 CHECK_STACK_DEPTH(bptr->indepth, stackdepth);
707 /* set up local variables for analyzing this block */
709 curstack = bptr->instack;
711 superblockend = false;
712 bptr->flags = BBFINISHED;
715 b_index = bptr - jd->new_basicblocks;
717 /* reset variables for dependency checking */
719 last_pei_boundary = new;
720 last_dup_boundary = new;
721 for( i = 0; i < cd->maxlocals; i++)
722 last_store_boundary[i] = new;
724 /* XXX store the start of the block's stack representation */
727 #if defined(STACK_VERBOSE)
729 for( copy = bptr->instack; copy; copy = copy->prev ) {
730 printf("%2d(%d", copy->varnum, copy->type);
733 if (IS_PREALLOC(copy))
740 /* iterate over ICMDs ****************************************/
743 #if defined(STACK_VERBOSE)
744 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
745 for( copy = curstack; copy; copy = copy->prev ) {
746 printf("%2d(%d", copy->varnum, copy->type);
749 if (IS_PREALLOC(copy))
756 /* fetch the current opcode */
760 /* automatically replace some ICMDs with builtins */
762 #if defined(USEBUILTINTABLE)
764 bte = builtintable_get_automatic(opcode);
766 if (bte && bte->opcode == opcode) {
767 iptr->opc = ICMD_BUILTIN;
768 iptr->flags.bits = 0;
769 iptr->sx.s23.s3.bte = bte;
770 /* iptr->line is already set */
771 jd->isleafmethod = false;
775 #endif /* defined(USEBUILTINTABLE) */
777 /* main opcode switch *************************************/
790 last_pei_boundary = new;
791 COUNT(count_check_null);
794 CLR_DST; /* XXX live through? */
798 USE_S1_LOCAL(TYPE_ADR);
801 #if !defined(NEW_VAR)
802 IF_NO_INTRP( rd->locals[iptr->s1.localindex][TYPE_ADR].type = TYPE_ADR; );
804 superblockend = true;
808 COUNT(count_pcmd_return);
811 superblockend = true;
815 /* pop 0 push 1 const */
817 /************************** ICONST OPTIMIZATIONS **************************/
820 COUNT(count_pcmd_load);
824 switch (iptr[1].opc) {
826 iptr->opc = ICMD_IADDCONST;
830 iptr[1].opc = ICMD_NOP;
831 OP1_1(TYPE_INT, TYPE_INT);
832 COUNT(count_pcmd_op);
836 iptr->opc = ICMD_ISUBCONST;
837 goto icmd_iconst_tail;
838 #if SUPPORT_CONST_MUL
840 iptr->opc = ICMD_IMULCONST;
841 goto icmd_iconst_tail;
842 #else /* SUPPORT_CONST_MUL */
844 if (iptr->sx.val.i == 0x00000002)
846 else if (iptr->sx.val.i == 0x00000004)
848 else if (iptr->sx.val.i == 0x00000008)
850 else if (iptr->sx.val.i == 0x00000010)
852 else if (iptr->sx.val.i == 0x00000020)
854 else if (iptr->sx.val.i == 0x00000040)
856 else if (iptr->sx.val.i == 0x00000080)
858 else if (iptr->sx.val.i == 0x00000100)
860 else if (iptr->sx.val.i == 0x00000200)
862 else if (iptr->sx.val.i == 0x00000400)
864 else if (iptr->sx.val.i == 0x00000800)
866 else if (iptr->sx.val.i == 0x00001000)
868 else if (iptr->sx.val.i == 0x00002000)
870 else if (iptr->sx.val.i == 0x00004000)
872 else if (iptr->sx.val.i == 0x00008000)
874 else if (iptr->sx.val.i == 0x00010000)
876 else if (iptr->sx.val.i == 0x00020000)
878 else if (iptr->sx.val.i == 0x00040000)
880 else if (iptr->sx.val.i == 0x00080000)
882 else if (iptr->sx.val.i == 0x00100000)
884 else if (iptr->sx.val.i == 0x00200000)
886 else if (iptr->sx.val.i == 0x00400000)
888 else if (iptr->sx.val.i == 0x00800000)
890 else if (iptr->sx.val.i == 0x01000000)
892 else if (iptr->sx.val.i == 0x02000000)
894 else if (iptr->sx.val.i == 0x04000000)
896 else if (iptr->sx.val.i == 0x08000000)
898 else if (iptr->sx.val.i == 0x10000000)
900 else if (iptr->sx.val.i == 0x20000000)
902 else if (iptr->sx.val.i == 0x40000000)
904 else if (iptr->sx.val.i == 0x80000000)
909 iptr->opc = ICMD_IMULPOW2;
910 goto icmd_iconst_tail;
911 #endif /* SUPPORT_CONST_MUL */
913 if (iptr->sx.val.i == 0x00000002)
915 else if (iptr->sx.val.i == 0x00000004)
917 else if (iptr->sx.val.i == 0x00000008)
919 else if (iptr->sx.val.i == 0x00000010)
921 else if (iptr->sx.val.i == 0x00000020)
923 else if (iptr->sx.val.i == 0x00000040)
925 else if (iptr->sx.val.i == 0x00000080)
927 else if (iptr->sx.val.i == 0x00000100)
929 else if (iptr->sx.val.i == 0x00000200)
931 else if (iptr->sx.val.i == 0x00000400)
933 else if (iptr->sx.val.i == 0x00000800)
935 else if (iptr->sx.val.i == 0x00001000)
937 else if (iptr->sx.val.i == 0x00002000)
939 else if (iptr->sx.val.i == 0x00004000)
941 else if (iptr->sx.val.i == 0x00008000)
943 else if (iptr->sx.val.i == 0x00010000)
945 else if (iptr->sx.val.i == 0x00020000)
947 else if (iptr->sx.val.i == 0x00040000)
949 else if (iptr->sx.val.i == 0x00080000)
951 else if (iptr->sx.val.i == 0x00100000)
953 else if (iptr->sx.val.i == 0x00200000)
955 else if (iptr->sx.val.i == 0x00400000)
957 else if (iptr->sx.val.i == 0x00800000)
959 else if (iptr->sx.val.i == 0x01000000)
961 else if (iptr->sx.val.i == 0x02000000)
963 else if (iptr->sx.val.i == 0x04000000)
965 else if (iptr->sx.val.i == 0x08000000)
967 else if (iptr->sx.val.i == 0x10000000)
969 else if (iptr->sx.val.i == 0x20000000)
971 else if (iptr->sx.val.i == 0x40000000)
973 else if (iptr->sx.val.i == 0x80000000)
978 iptr->opc = ICMD_IDIVPOW2;
979 goto icmd_iconst_tail;
982 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
983 if ((iptr->sx.val.i == 0x00000002) ||
984 (iptr->sx.val.i == 0x00000004) ||
985 (iptr->sx.val.i == 0x00000008) ||
986 (iptr->sx.val.i == 0x00000010) ||
987 (iptr->sx.val.i == 0x00000020) ||
988 (iptr->sx.val.i == 0x00000040) ||
989 (iptr->sx.val.i == 0x00000080) ||
990 (iptr->sx.val.i == 0x00000100) ||
991 (iptr->sx.val.i == 0x00000200) ||
992 (iptr->sx.val.i == 0x00000400) ||
993 (iptr->sx.val.i == 0x00000800) ||
994 (iptr->sx.val.i == 0x00001000) ||
995 (iptr->sx.val.i == 0x00002000) ||
996 (iptr->sx.val.i == 0x00004000) ||
997 (iptr->sx.val.i == 0x00008000) ||
998 (iptr->sx.val.i == 0x00010000) ||
999 (iptr->sx.val.i == 0x00020000) ||
1000 (iptr->sx.val.i == 0x00040000) ||
1001 (iptr->sx.val.i == 0x00080000) ||
1002 (iptr->sx.val.i == 0x00100000) ||
1003 (iptr->sx.val.i == 0x00200000) ||
1004 (iptr->sx.val.i == 0x00400000) ||
1005 (iptr->sx.val.i == 0x00800000) ||
1006 (iptr->sx.val.i == 0x01000000) ||
1007 (iptr->sx.val.i == 0x02000000) ||
1008 (iptr->sx.val.i == 0x04000000) ||
1009 (iptr->sx.val.i == 0x08000000) ||
1010 (iptr->sx.val.i == 0x10000000) ||
1011 (iptr->sx.val.i == 0x20000000) ||
1012 (iptr->sx.val.i == 0x40000000) ||
1013 (iptr->sx.val.i == 0x80000000))
1015 iptr->opc = ICMD_IREMPOW2;
1016 iptr->sx.val.i -= 1;
1017 goto icmd_iconst_tail;
1020 #if SUPPORT_CONST_LOGICAL
1022 iptr->opc = ICMD_IANDCONST;
1023 goto icmd_iconst_tail;
1026 iptr->opc = ICMD_IORCONST;
1027 goto icmd_iconst_tail;
1030 iptr->opc = ICMD_IXORCONST;
1031 goto icmd_iconst_tail;
1033 #endif /* SUPPORT_CONST_LOGICAL */
1035 iptr->opc = ICMD_ISHLCONST;
1036 goto icmd_iconst_tail;
1039 iptr->opc = ICMD_ISHRCONST;
1040 goto icmd_iconst_tail;
1043 iptr->opc = ICMD_IUSHRCONST;
1044 goto icmd_iconst_tail;
1045 #if SUPPORT_LONG_SHIFT
1047 iptr->opc = ICMD_LSHLCONST;
1048 goto icmd_lconst_tail;
1051 iptr->opc = ICMD_LSHRCONST;
1052 goto icmd_lconst_tail;
1055 iptr->opc = ICMD_LUSHRCONST;
1056 goto icmd_lconst_tail;
1057 #endif /* SUPPORT_LONG_SHIFT */
1058 case ICMD_IF_ICMPEQ:
1059 iptr[1].opc = ICMD_IFEQ;
1063 /* set the constant for the following icmd */
1064 iptr[1].sx.val.i = iptr->sx.val.i;
1066 /* this instruction becomes a nop */
1067 iptr->opc = ICMD_NOP;
1070 case ICMD_IF_ICMPLT:
1071 iptr[1].opc = ICMD_IFLT;
1072 goto icmd_if_icmp_tail;
1074 case ICMD_IF_ICMPLE:
1075 iptr[1].opc = ICMD_IFLE;
1076 goto icmd_if_icmp_tail;
1078 case ICMD_IF_ICMPNE:
1079 iptr[1].opc = ICMD_IFNE;
1080 goto icmd_if_icmp_tail;
1082 case ICMD_IF_ICMPGT:
1083 iptr[1].opc = ICMD_IFGT;
1084 goto icmd_if_icmp_tail;
1086 case ICMD_IF_ICMPGE:
1087 iptr[1].opc = ICMD_IFGE;
1088 goto icmd_if_icmp_tail;
1090 #if SUPPORT_CONST_STORE
1095 IF_INTRP( goto normal_ICONST; )
1096 # if SUPPORT_CONST_STORE_ZERO_ONLY
1097 if (iptr->sx.val.i != 0)
1100 switch (iptr[1].opc) {
1102 iptr->opc = ICMD_IASTORECONST;
1103 iptr->flags.bits |= INS_FLAG_CHECK;
1106 iptr->opc = ICMD_BASTORECONST;
1107 iptr->flags.bits |= INS_FLAG_CHECK;
1110 iptr->opc = ICMD_CASTORECONST;
1111 iptr->flags.bits |= INS_FLAG_CHECK;
1114 iptr->opc = ICMD_SASTORECONST;
1115 iptr->flags.bits |= INS_FLAG_CHECK;
1119 iptr[1].opc = ICMD_NOP;
1121 /* copy the constant to s3 */
1122 /* XXX constval -> astoreconstval? */
1123 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1124 OP2_0(TYPE_ADR, TYPE_INT);
1125 COUNT(count_pcmd_op);
1128 case ICMD_PUTSTATIC:
1130 IF_INTRP( goto normal_ICONST; )
1131 # if SUPPORT_CONST_STORE_ZERO_ONLY
1132 if (iptr->sx.val.i != 0)
1135 /* XXX check field type? */
1137 /* copy the constant to s2 */
1138 /* XXX constval -> fieldconstval? */
1139 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1142 /* set the field reference (s3) */
1143 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1144 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1145 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1148 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1151 switch (iptr[1].opc) {
1152 case ICMD_PUTSTATIC:
1153 iptr->opc = ICMD_PUTSTATICCONST;
1157 iptr->opc = ICMD_PUTFIELDCONST;
1162 iptr[1].opc = ICMD_NOP;
1163 COUNT(count_pcmd_op);
1165 #endif /* SUPPORT_CONST_STORE */
1171 /* if we get here, the ICONST has been optimized */
1175 /* normal case of an unoptimized ICONST */
1179 /************************** LCONST OPTIMIZATIONS **************************/
1182 COUNT(count_pcmd_load);
1186 /* switch depending on the following instruction */
1188 switch (iptr[1].opc) {
1189 #if SUPPORT_LONG_ADD
1191 iptr->opc = ICMD_LADDCONST;
1195 /* instruction of type LONG -> LONG */
1196 iptr[1].opc = ICMD_NOP;
1197 OP1_1(TYPE_LNG, TYPE_LNG);
1198 COUNT(count_pcmd_op);
1202 iptr->opc = ICMD_LSUBCONST;
1203 goto icmd_lconst_tail;
1205 #endif /* SUPPORT_LONG_ADD */
1206 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1208 iptr->opc = ICMD_LMULCONST;
1209 goto icmd_lconst_tail;
1210 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1211 # if SUPPORT_LONG_SHIFT
1213 if (iptr->sx.val.l == 0x00000002)
1215 else if (iptr->sx.val.l == 0x00000004)
1217 else if (iptr->sx.val.l == 0x00000008)
1219 else if (iptr->sx.val.l == 0x00000010)
1221 else if (iptr->sx.val.l == 0x00000020)
1223 else if (iptr->sx.val.l == 0x00000040)
1225 else if (iptr->sx.val.l == 0x00000080)
1227 else if (iptr->sx.val.l == 0x00000100)
1229 else if (iptr->sx.val.l == 0x00000200)
1231 else if (iptr->sx.val.l == 0x00000400)
1232 iptr->sx.val.i = 10;
1233 else if (iptr->sx.val.l == 0x00000800)
1234 iptr->sx.val.i = 11;
1235 else if (iptr->sx.val.l == 0x00001000)
1236 iptr->sx.val.i = 12;
1237 else if (iptr->sx.val.l == 0x00002000)
1238 iptr->sx.val.i = 13;
1239 else if (iptr->sx.val.l == 0x00004000)
1240 iptr->sx.val.i = 14;
1241 else if (iptr->sx.val.l == 0x00008000)
1242 iptr->sx.val.i = 15;
1243 else if (iptr->sx.val.l == 0x00010000)
1244 iptr->sx.val.i = 16;
1245 else if (iptr->sx.val.l == 0x00020000)
1246 iptr->sx.val.i = 17;
1247 else if (iptr->sx.val.l == 0x00040000)
1248 iptr->sx.val.i = 18;
1249 else if (iptr->sx.val.l == 0x00080000)
1250 iptr->sx.val.i = 19;
1251 else if (iptr->sx.val.l == 0x00100000)
1252 iptr->sx.val.i = 20;
1253 else if (iptr->sx.val.l == 0x00200000)
1254 iptr->sx.val.i = 21;
1255 else if (iptr->sx.val.l == 0x00400000)
1256 iptr->sx.val.i = 22;
1257 else if (iptr->sx.val.l == 0x00800000)
1258 iptr->sx.val.i = 23;
1259 else if (iptr->sx.val.l == 0x01000000)
1260 iptr->sx.val.i = 24;
1261 else if (iptr->sx.val.l == 0x02000000)
1262 iptr->sx.val.i = 25;
1263 else if (iptr->sx.val.l == 0x04000000)
1264 iptr->sx.val.i = 26;
1265 else if (iptr->sx.val.l == 0x08000000)
1266 iptr->sx.val.i = 27;
1267 else if (iptr->sx.val.l == 0x10000000)
1268 iptr->sx.val.i = 28;
1269 else if (iptr->sx.val.l == 0x20000000)
1270 iptr->sx.val.i = 29;
1271 else if (iptr->sx.val.l == 0x40000000)
1272 iptr->sx.val.i = 30;
1273 else if (iptr->sx.val.l == 0x80000000)
1274 iptr->sx.val.i = 31;
1278 iptr->opc = ICMD_LMULPOW2;
1279 goto icmd_lconst_tail;
1280 # endif /* SUPPORT_LONG_SHIFT */
1281 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1282 #if SUPPORT_LONG_DIV_POW2
1284 if (iptr->sx.val.l == 0x00000002)
1286 else if (iptr->sx.val.l == 0x00000004)
1288 else if (iptr->sx.val.l == 0x00000008)
1290 else if (iptr->sx.val.l == 0x00000010)
1292 else if (iptr->sx.val.l == 0x00000020)
1294 else if (iptr->sx.val.l == 0x00000040)
1296 else if (iptr->sx.val.l == 0x00000080)
1298 else if (iptr->sx.val.l == 0x00000100)
1300 else if (iptr->sx.val.l == 0x00000200)
1302 else if (iptr->sx.val.l == 0x00000400)
1303 iptr->sx.val.i = 10;
1304 else if (iptr->sx.val.l == 0x00000800)
1305 iptr->sx.val.i = 11;
1306 else if (iptr->sx.val.l == 0x00001000)
1307 iptr->sx.val.i = 12;
1308 else if (iptr->sx.val.l == 0x00002000)
1309 iptr->sx.val.i = 13;
1310 else if (iptr->sx.val.l == 0x00004000)
1311 iptr->sx.val.i = 14;
1312 else if (iptr->sx.val.l == 0x00008000)
1313 iptr->sx.val.i = 15;
1314 else if (iptr->sx.val.l == 0x00010000)
1315 iptr->sx.val.i = 16;
1316 else if (iptr->sx.val.l == 0x00020000)
1317 iptr->sx.val.i = 17;
1318 else if (iptr->sx.val.l == 0x00040000)
1319 iptr->sx.val.i = 18;
1320 else if (iptr->sx.val.l == 0x00080000)
1321 iptr->sx.val.i = 19;
1322 else if (iptr->sx.val.l == 0x00100000)
1323 iptr->sx.val.i = 20;
1324 else if (iptr->sx.val.l == 0x00200000)
1325 iptr->sx.val.i = 21;
1326 else if (iptr->sx.val.l == 0x00400000)
1327 iptr->sx.val.i = 22;
1328 else if (iptr->sx.val.l == 0x00800000)
1329 iptr->sx.val.i = 23;
1330 else if (iptr->sx.val.l == 0x01000000)
1331 iptr->sx.val.i = 24;
1332 else if (iptr->sx.val.l == 0x02000000)
1333 iptr->sx.val.i = 25;
1334 else if (iptr->sx.val.l == 0x04000000)
1335 iptr->sx.val.i = 26;
1336 else if (iptr->sx.val.l == 0x08000000)
1337 iptr->sx.val.i = 27;
1338 else if (iptr->sx.val.l == 0x10000000)
1339 iptr->sx.val.i = 28;
1340 else if (iptr->sx.val.l == 0x20000000)
1341 iptr->sx.val.i = 29;
1342 else if (iptr->sx.val.l == 0x40000000)
1343 iptr->sx.val.i = 30;
1344 else if (iptr->sx.val.l == 0x80000000)
1345 iptr->sx.val.i = 31;
1349 iptr->opc = ICMD_LDIVPOW2;
1350 goto icmd_lconst_tail;
1351 #endif /* SUPPORT_LONG_DIV_POW2 */
1353 #if SUPPORT_LONG_REM_POW2
1355 if ((iptr->sx.val.l == 0x00000002) ||
1356 (iptr->sx.val.l == 0x00000004) ||
1357 (iptr->sx.val.l == 0x00000008) ||
1358 (iptr->sx.val.l == 0x00000010) ||
1359 (iptr->sx.val.l == 0x00000020) ||
1360 (iptr->sx.val.l == 0x00000040) ||
1361 (iptr->sx.val.l == 0x00000080) ||
1362 (iptr->sx.val.l == 0x00000100) ||
1363 (iptr->sx.val.l == 0x00000200) ||
1364 (iptr->sx.val.l == 0x00000400) ||
1365 (iptr->sx.val.l == 0x00000800) ||
1366 (iptr->sx.val.l == 0x00001000) ||
1367 (iptr->sx.val.l == 0x00002000) ||
1368 (iptr->sx.val.l == 0x00004000) ||
1369 (iptr->sx.val.l == 0x00008000) ||
1370 (iptr->sx.val.l == 0x00010000) ||
1371 (iptr->sx.val.l == 0x00020000) ||
1372 (iptr->sx.val.l == 0x00040000) ||
1373 (iptr->sx.val.l == 0x00080000) ||
1374 (iptr->sx.val.l == 0x00100000) ||
1375 (iptr->sx.val.l == 0x00200000) ||
1376 (iptr->sx.val.l == 0x00400000) ||
1377 (iptr->sx.val.l == 0x00800000) ||
1378 (iptr->sx.val.l == 0x01000000) ||
1379 (iptr->sx.val.l == 0x02000000) ||
1380 (iptr->sx.val.l == 0x04000000) ||
1381 (iptr->sx.val.l == 0x08000000) ||
1382 (iptr->sx.val.l == 0x10000000) ||
1383 (iptr->sx.val.l == 0x20000000) ||
1384 (iptr->sx.val.l == 0x40000000) ||
1385 (iptr->sx.val.l == 0x80000000))
1387 iptr->opc = ICMD_LREMPOW2;
1388 iptr->sx.val.l -= 1;
1389 goto icmd_lconst_tail;
1392 #endif /* SUPPORT_LONG_REM_POW2 */
1394 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1397 iptr->opc = ICMD_LANDCONST;
1398 goto icmd_lconst_tail;
1401 iptr->opc = ICMD_LORCONST;
1402 goto icmd_lconst_tail;
1405 iptr->opc = ICMD_LXORCONST;
1406 goto icmd_lconst_tail;
1407 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1409 #if SUPPORT_LONG_CMP_CONST
1411 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1414 /* switch on the instruction after LCONST - LCMP */
1416 switch (iptr[2].opc) {
1418 iptr->opc = ICMD_IF_LEQ;
1421 icmd_lconst_lcmp_tail:
1422 /* convert LCONST, LCMP, IFXX to IF_LXX */
1423 iptr->dst.insindex = iptr[2].dst.insindex;
1424 iptr[1].opc = ICMD_NOP;
1425 iptr[2].opc = ICMD_NOP;
1427 OP1_BRANCH(TYPE_LNG);
1428 BRANCH(tbptr, copy);
1429 COUNT(count_pcmd_bra);
1430 COUNT(count_pcmd_op);
1434 iptr->opc = ICMD_IF_LNE;
1435 goto icmd_lconst_lcmp_tail;
1438 iptr->opc = ICMD_IF_LLT;
1439 goto icmd_lconst_lcmp_tail;
1442 iptr->opc = ICMD_IF_LGT;
1443 goto icmd_lconst_lcmp_tail;
1446 iptr->opc = ICMD_IF_LLE;
1447 goto icmd_lconst_lcmp_tail;
1450 iptr->opc = ICMD_IF_LGE;
1451 goto icmd_lconst_lcmp_tail;
1455 } /* end switch on opcode after LCONST - LCMP */
1457 #endif /* SUPPORT_LONG_CMP_CONST */
1459 #if SUPPORT_CONST_STORE
1461 IF_INTRP( goto normal_LCONST; )
1462 # if SUPPORT_CONST_STORE_ZERO_ONLY
1463 if (iptr->sx.val.l != 0)
1466 #if SIZEOF_VOID_P == 4
1467 /* the constant must fit into a ptrint */
1468 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1471 /* move the constant to s3 */
1472 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1474 iptr->opc = ICMD_LASTORECONST;
1475 iptr->flags.bits |= INS_FLAG_CHECK;
1476 OP2_0(TYPE_ADR, TYPE_INT);
1478 iptr[1].opc = ICMD_NOP;
1479 COUNT(count_pcmd_op);
1482 case ICMD_PUTSTATIC:
1484 IF_INTRP( goto normal_LCONST; )
1485 # if SUPPORT_CONST_STORE_ZERO_ONLY
1486 if (iptr->sx.val.l != 0)
1489 #if SIZEOF_VOID_P == 4
1490 /* the constant must fit into a ptrint */
1491 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1494 /* XXX check field type? */
1496 /* copy the constant to s2 */
1497 /* XXX constval -> fieldconstval? */
1498 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1502 #endif /* SUPPORT_CONST_STORE */
1506 } /* end switch opcode after LCONST */
1508 /* if we get here, the LCONST has been optimized */
1512 /* the normal case of an unoptimized LCONST */
1516 /************************ END OF LCONST OPTIMIZATIONS *********************/
1519 COUNT(count_pcmd_load);
1524 COUNT(count_pcmd_load);
1528 /************************** ACONST OPTIMIZATIONS **************************/
1531 last_pei_boundary = new;
1532 COUNT(count_pcmd_load);
1533 #if SUPPORT_CONST_STORE
1534 IF_INTRP( goto normal_ACONST; )
1536 /* We can only optimize if the ACONST is resolved
1537 * and there is an instruction after it. */
1539 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1542 switch (iptr[1].opc) {
1544 /* We can only optimize for NULL values
1545 * here because otherwise a checkcast is
1547 if (iptr->sx.val.anyptr != NULL)
1550 /* copy the constant (NULL) to s3 */
1551 iptr->sx.s23.s3.constval = 0;
1552 iptr->opc = ICMD_AASTORECONST;
1553 iptr->flags.bits |= INS_FLAG_CHECK;
1554 OP2_0(TYPE_ADR, TYPE_INT);
1556 iptr[1].opc = ICMD_NOP;
1557 COUNT(count_pcmd_op);
1560 case ICMD_PUTSTATIC:
1562 # if SUPPORT_CONST_STORE_ZERO_ONLY
1563 if (iptr->sx.val.anyptr != NULL)
1566 /* XXX check field type? */
1567 /* copy the constant to s2 */
1568 /* XXX constval -> fieldconstval? */
1569 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1577 /* if we get here the ACONST has been optimized */
1581 #endif /* SUPPORT_CONST_STORE */
1586 /* pop 0 push 1 load */
1593 COUNT(count_load_instruction);
1594 i = opcode - ICMD_ILOAD;
1595 #if defined(NEW_VAR)
1597 jd->local_map[iptr->s1.varindex * 5 + i];
1599 LOAD(i, iptr->s1.varindex);
1602 IF_NO_INTRP( rd->locals[iptr->s1.localindex][i].type =
1604 LOAD(i, iptr->s1.localindex);
1614 last_pei_boundary = new;
1615 iptr->flags.bits |= INS_FLAG_CHECK;
1616 COUNT(count_check_null);
1617 COUNT(count_check_bound);
1618 COUNT(count_pcmd_mem);
1619 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1626 last_pei_boundary = new;
1627 iptr->flags.bits |= INS_FLAG_CHECK;
1628 COUNT(count_check_null);
1629 COUNT(count_check_bound);
1630 COUNT(count_pcmd_mem);
1631 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1634 /* pop 0 push 0 iinc */
1637 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1639 #if defined(NEW_VAR)
1641 jd->local_map[iptr->s1.varindex * 5 + i];
1643 last_store_boundary[iptr->s1.varindex] = new;
1645 last_store_boundary[iptr->s1.localindex] = new;
1651 if ((copy->varkind == LOCALVAR) &&
1652 (copy->varnum == iptr->s1.varindex))
1654 copy->varkind = TEMPVAR;
1655 #if defined(NEW_VAR)
1656 assert(IS_LOCALVAR(copy));
1666 #if defined(NEW_VAR)
1667 iptr->dst.varindex = iptr->s1.varindex;
1669 iptr->dst.localindex = iptr->s1.localindex;
1673 /* pop 1 push 0 store */
1682 i = opcode - ICMD_ISTORE; /* type */
1683 #if defined(NEW_VAR)
1684 j = iptr->dst.varindex =
1685 jd->local_map[iptr->dst.varindex * 5 + i];
1688 j = iptr->dst.localindex; /* index */
1690 IF_NO_INTRP( rd->locals[j][i].type = i; )
1693 #if defined(ENABLE_STATISTICS)
1698 count_store_length[20]++;
1700 count_store_length[i]++;
1703 count_store_depth[10]++;
1705 count_store_depth[i]++;
1708 /* check for conflicts as described in Figure 5.2 */
1710 copy = curstack->prev;
1713 if ((copy->varkind == LOCALVAR) &&
1714 (copy->varnum == j))
1716 copy->varkind = TEMPVAR;
1717 #if defined(NEW_VAR)
1718 assert(IS_LOCALVAR(copy));
1728 /* if the variable is already coalesced, don't bother */
1730 if (IS_OUTVAR(curstack)
1731 || (curstack->varkind == LOCALVAR
1732 && curstack->varnum != j))
1735 /* there is no STORE Lj while curstack is live */
1737 if (curstack < last_store_boundary[j])
1738 goto assume_conflict;
1740 /* there is no PEI while curstack is live */
1742 if (curstack < last_pei_boundary)
1743 goto assume_conflict;
1745 /*there is no non-consuming USE while curstack is live*/
1747 if (curstack < last_dup_boundary)
1748 goto assume_conflict;
1750 /* there is no DEF LOCALVAR(j) while curstack is live */
1752 copy = new; /* most recent stackslot created + 1 */
1753 while (--copy > curstack) {
1754 if (copy->varkind == LOCALVAR && copy->varnum == j)
1755 goto assume_conflict;
1758 /* coalesce the temporary variable with Lj */
1759 #if defined(NEW_VAR)
1760 assert( (CURKIND == TEMPVAR) || (CURKIND == UNDEFVAR));
1761 assert(!IS_LOCALVAR(curstack));
1762 assert(!IS_OUTVAR(curstack));
1763 assert(!IS_PREALLOC(curstack));
1765 RELEASE_INDEX(curstack);
1767 curstack->varkind = LOCALVAR;
1768 curstack->varnum = j;
1771 /* revert the coalescing, if it has been done earlier */
1773 if ((curstack->varkind == LOCALVAR)
1774 && (curstack->varnum == j))
1776 curstack->varkind = TEMPVAR;
1777 #if defined(NEW_VAR)
1778 assert(IS_LOCALVAR(curstack));
1779 SET_TEMPVAR(curstack);
1781 curstack->varnum = stackdepth-1;
1785 /* remember the stack boundary at this store */
1787 last_store_boundary[j] = new;
1789 STORE(opcode - ICMD_ISTORE, j);
1795 last_pei_boundary = new;
1796 iptr->flags.bits |= INS_FLAG_CHECK;
1797 COUNT(count_check_null);
1798 COUNT(count_check_bound);
1799 COUNT(count_pcmd_mem);
1801 bte = builtintable_get_internal(BUILTIN_canstore);
1804 if (md->memuse > rd->memuse)
1805 rd->memuse = md->memuse;
1806 if (md->argintreguse > rd->argintreguse)
1807 rd->argintreguse = md->argintreguse;
1808 /* XXX non-leaf method? */
1810 /* make all stack variables saved */
1814 #if defined(NEW_VAR)
1815 jd->var[copy->varnum].flags |= SAVEDVAR;
1816 /* in case copy->varnum is/will be a LOCALVAR */
1817 /* once and set back to a non LOCALVAR */
1818 /* the correct SAVEDVAR flag has to be */
1819 /* remembered in copy->flags, too */
1821 copy->flags |= SAVEDVAR;
1825 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1832 last_pei_boundary = new;
1833 iptr->flags.bits |= INS_FLAG_CHECK;
1834 COUNT(count_check_null);
1835 COUNT(count_check_bound);
1836 COUNT(count_pcmd_mem);
1837 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1844 last_pei_boundary = new;
1845 iptr->flags.bits |= INS_FLAG_CHECK;
1846 COUNT(count_check_null);
1847 COUNT(count_check_bound);
1848 COUNT(count_pcmd_mem);
1849 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1855 #ifdef ENABLE_VERIFIER
1858 if (IS_2_WORD_TYPE(curstack->type))
1859 goto throw_stack_category_error;
1870 last_pei_boundary = new;
1871 IF_JIT( md_return_alloc(jd, curstack); )
1872 COUNT(count_pcmd_return);
1873 OP1_0(opcode - ICMD_IRETURN);
1874 superblockend = true;
1878 last_pei_boundary = new;
1879 COUNT(count_check_null);
1882 superblockend = true;
1885 case ICMD_PUTSTATIC:
1886 last_pei_boundary = new;
1887 COUNT(count_pcmd_mem);
1888 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1889 OP1_0(fmiref->parseddesc.fd->type);
1892 /* pop 1 push 0 branch */
1895 case ICMD_IFNONNULL:
1896 COUNT(count_pcmd_bra);
1897 OP1_BRANCH(TYPE_ADR);
1898 BRANCH(tbptr, copy);
1907 COUNT(count_pcmd_bra);
1908 /* iptr->sx.val.i is set implicitly in parse by
1909 clearing the memory or from IF_ICMPxx
1912 OP1_BRANCH(TYPE_INT);
1913 /* iptr->sx.val.i = 0; */
1914 BRANCH(tbptr, copy);
1917 /* pop 0 push 0 branch */
1920 COUNT(count_pcmd_bra);
1922 BRANCH(tbptr, copy);
1923 superblockend = true;
1926 /* pop 1 push 0 table branch */
1928 case ICMD_TABLESWITCH:
1929 COUNT(count_pcmd_table);
1930 OP1_BRANCH(TYPE_INT);
1932 table = iptr->dst.table;
1933 BRANCH_TARGET(*table, tbptr, copy);
1936 i = iptr->sx.s23.s3.tablehigh
1937 - iptr->sx.s23.s2.tablelow + 1;
1940 BRANCH_TARGET(*table, tbptr, copy);
1943 superblockend = true;
1946 /* pop 1 push 0 table branch */
1948 case ICMD_LOOKUPSWITCH:
1949 COUNT(count_pcmd_table);
1950 OP1_BRANCH(TYPE_INT);
1952 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
1954 lookup = iptr->dst.lookup;
1956 i = iptr->sx.s23.s2.lookupcount;
1959 BRANCH_TARGET(lookup->target, tbptr, copy);
1962 superblockend = true;
1965 case ICMD_MONITORENTER:
1966 case ICMD_MONITOREXIT:
1967 last_pei_boundary = new;
1968 COUNT(count_check_null);
1972 /* pop 2 push 0 branch */
1974 case ICMD_IF_ICMPEQ:
1975 case ICMD_IF_ICMPNE:
1976 case ICMD_IF_ICMPLT:
1977 case ICMD_IF_ICMPGE:
1978 case ICMD_IF_ICMPGT:
1979 case ICMD_IF_ICMPLE:
1980 COUNT(count_pcmd_bra);
1981 OP2_BRANCH(TYPE_INT, TYPE_INT);
1982 BRANCH(tbptr, copy);
1985 case ICMD_IF_ACMPEQ:
1986 case ICMD_IF_ACMPNE:
1987 COUNT(count_pcmd_bra);
1988 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
1989 BRANCH(tbptr, copy);
1995 last_pei_boundary = new;
1996 COUNT(count_check_null);
1997 COUNT(count_pcmd_mem);
1998 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1999 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
2004 if (!IS_2_WORD_TYPE(curstack->type)) {
2006 #ifdef ENABLE_VERIFIER
2009 if (IS_2_WORD_TYPE(curstack->prev->type))
2010 goto throw_stack_category_error;
2013 OP2_0_ANY_ANY; /* pop two slots */
2016 iptr->opc = ICMD_POP;
2017 OP1_0_ANY; /* pop one (two-word) slot */
2021 /* pop 0 push 1 dup */
2024 #ifdef ENABLE_VERIFIER
2027 if (IS_2_WORD_TYPE(curstack->type))
2028 goto throw_stack_category_error;
2031 COUNT(count_dup_instruction);
2034 USE_S1_ANY; /* XXX live through */
2035 /* DUP_SLOT(iptr->s1.var); */
2037 last_dup_boundary = new - 1;
2038 #if defined(NEW_VAR)
2039 iptr->dst.varindex = curstack->varnum;
2041 iptr->dst.var = curstack;
2048 if (IS_2_WORD_TYPE(curstack->type)) {
2050 iptr->opc = ICMD_DUP;
2055 /* ..., ????, cat1 */
2056 #ifdef ENABLE_VERIFIER
2058 if (IS_2_WORD_TYPE(curstack->prev->type))
2059 goto throw_stack_category_error;
2062 #if defined(NEW_VAR)
2063 iptr->dst.dupslots = DMNEW(s4, 2 + 2);
2064 /* XXX live through */
2065 iptr->dst.dupslots[0] = curstack->prev->varnum;
2066 /* XXX live through */
2067 iptr->dst.dupslots[1] = curstack->varnum;
2070 DUP_SLOT(copy->prev);
2071 iptr->dst.dupslots[2+0] = curstack->varnum;
2073 iptr->dst.dupslots[2+1] = curstack->varnum;
2075 iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
2076 iptr->dst.dupslots[0] = curstack->prev; /* XXX live through */
2077 iptr->dst.dupslots[1] = curstack; /* XXX live through */
2079 DUP_SLOT(iptr->dst.dupslots[0]);
2080 iptr->dst.dupslots[2+0] = curstack;
2081 DUP_SLOT(iptr->dst.dupslots[1]);
2082 iptr->dst.dupslots[2+1] = curstack;
2084 last_dup_boundary = new;
2089 /* pop 2 push 3 dup */
2092 #ifdef ENABLE_VERIFIER
2095 if (IS_2_WORD_TYPE(curstack->type) ||
2096 IS_2_WORD_TYPE(curstack->prev->type))
2097 goto throw_stack_category_error;
2102 #if defined(NEW_VAR)
2103 iptr->dst.dupslots = DMNEW(int, 2 + 3);
2104 iptr->dst.dupslots[0] = curstack->prev->varnum;
2105 iptr->dst.dupslots[1] = curstack->varnum;
2110 iptr->dst.dupslots[2+0] = curstack->varnum;
2111 DUP_SLOT(copy->prev);
2112 iptr->dst.dupslots[2+1] = curstack->varnum;
2114 iptr->dst.dupslots[2+2] = curstack->varnum;
2116 iptr->dst.dupslots = DMNEW(stackptr, 2 + 3);
2117 iptr->dst.dupslots[0] = curstack->prev;
2118 iptr->dst.dupslots[1] = curstack;
2121 DUP_SLOT(iptr->dst.dupslots[1]);
2122 iptr->dst.dupslots[2+0] = curstack;
2123 DUP_SLOT(iptr->dst.dupslots[0]);
2124 iptr->dst.dupslots[2+1] = curstack;
2125 DUP_SLOT(iptr->dst.dupslots[1]);
2126 iptr->dst.dupslots[2+2] = curstack;
2128 last_dup_boundary = new;
2134 if (IS_2_WORD_TYPE(curstack->type)) {
2135 /* ..., ????, cat2 */
2136 #ifdef ENABLE_VERIFIER
2138 if (IS_2_WORD_TYPE(curstack->prev->type))
2139 goto throw_stack_category_error;
2142 iptr->opc = ICMD_DUP_X1;
2146 /* ..., ????, cat1 */
2147 #ifdef ENABLE_VERIFIER
2150 if (IS_2_WORD_TYPE(curstack->prev->type)
2151 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2152 goto throw_stack_category_error;
2157 #if defined(NEW_VAR)
2158 iptr->dst.dupslots = DMNEW(s4, 3 + 5);
2159 iptr->dst.dupslots[0] =curstack->prev->prev->varnum;
2160 iptr->dst.dupslots[1] = curstack->prev->varnum;
2161 iptr->dst.dupslots[2] = curstack->varnum;
2163 POPANY; POPANY; POPANY;
2165 DUP_SLOT(copy->prev);
2166 iptr->dst.dupslots[3+0] = curstack->varnum;
2168 iptr->dst.dupslots[3+1] = curstack->varnum;
2169 DUP_SLOT(copy->prev->prev);
2170 iptr->dst.dupslots[3+2] = curstack->varnum;
2171 DUP_SLOT(copy->prev);
2172 iptr->dst.dupslots[3+3] = curstack->varnum;
2174 iptr->dst.dupslots[3+4] = curstack->varnum;
2176 iptr->dst.dupslots = DMNEW(stackptr, 3 + 5);
2177 iptr->dst.dupslots[0] = curstack->prev->prev;
2178 iptr->dst.dupslots[1] = curstack->prev;
2179 iptr->dst.dupslots[2] = curstack;
2180 POPANY; POPANY; POPANY;
2182 DUP_SLOT(iptr->dst.dupslots[1]);
2183 iptr->dst.dupslots[3+0] = curstack;
2184 DUP_SLOT(iptr->dst.dupslots[2]);
2185 iptr->dst.dupslots[3+1] = curstack;
2186 DUP_SLOT(iptr->dst.dupslots[0]);
2187 iptr->dst.dupslots[3+2] = curstack;
2188 DUP_SLOT(iptr->dst.dupslots[1]);
2189 iptr->dst.dupslots[3+3] = curstack;
2190 DUP_SLOT(iptr->dst.dupslots[2]);
2191 iptr->dst.dupslots[3+4] = curstack;
2193 last_dup_boundary = new;
2198 /* pop 3 push 4 dup */
2202 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2203 /* ..., cat2, ???? */
2204 #ifdef ENABLE_VERIFIER
2206 if (IS_2_WORD_TYPE(curstack->type))
2207 goto throw_stack_category_error;
2210 iptr->opc = ICMD_DUP_X1;
2214 /* ..., cat1, ???? */
2215 #ifdef ENABLE_VERIFIER
2218 if (IS_2_WORD_TYPE(curstack->type)
2219 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2220 goto throw_stack_category_error;
2224 #if defined(NEW_VAR)
2225 iptr->dst.dupslots = DMNEW(s4, 3 + 4);
2226 iptr->dst.dupslots[0] =curstack->prev->prev->varnum;
2227 iptr->dst.dupslots[1] = curstack->prev->varnum;
2228 iptr->dst.dupslots[2] = curstack->varnum;
2230 POPANY; POPANY; POPANY;
2233 iptr->dst.dupslots[3+0] = curstack->varnum;
2234 DUP_SLOT(copy->prev->prev);
2235 iptr->dst.dupslots[3+1] = curstack->varnum;
2236 DUP_SLOT(copy->prev);
2237 iptr->dst.dupslots[3+2] = curstack->varnum;
2239 iptr->dst.dupslots[3+3] = curstack->varnum;
2241 iptr->dst.dupslots = DMNEW(stackptr, 3 + 4);
2242 iptr->dst.dupslots[0] = curstack->prev->prev;
2243 iptr->dst.dupslots[1] = curstack->prev;
2244 iptr->dst.dupslots[2] = curstack;
2245 POPANY; POPANY; POPANY;
2247 DUP_SLOT(iptr->dst.dupslots[2]);
2248 iptr->dst.dupslots[3+0] = curstack;
2249 DUP_SLOT(iptr->dst.dupslots[0]);
2250 iptr->dst.dupslots[3+1] = curstack;
2251 DUP_SLOT(iptr->dst.dupslots[1]);
2252 iptr->dst.dupslots[3+2] = curstack;
2253 DUP_SLOT(iptr->dst.dupslots[2]);
2254 iptr->dst.dupslots[3+3] = curstack;
2256 last_dup_boundary = new;
2263 if (IS_2_WORD_TYPE(curstack->type)) {
2264 /* ..., ????, cat2 */
2265 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2266 /* ..., cat2, cat2 */
2267 iptr->opc = ICMD_DUP_X1;
2271 /* ..., cat1, cat2 */
2272 #ifdef ENABLE_VERIFIER
2275 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2276 goto throw_stack_category_error;
2279 iptr->opc = ICMD_DUP_X2;
2285 /* ..., ????, ????, cat1 */
2287 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2288 /* ..., cat2, ????, cat1 */
2289 #ifdef ENABLE_VERIFIER
2291 if (IS_2_WORD_TYPE(curstack->prev->type))
2292 goto throw_stack_category_error;
2295 iptr->opc = ICMD_DUP2_X1;
2299 /* ..., cat1, ????, cat1 */
2300 #ifdef ENABLE_VERIFIER
2303 if (IS_2_WORD_TYPE(curstack->prev->type)
2304 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2305 goto throw_stack_category_error;
2309 #if defined(NEW_VAR)
2310 iptr->dst.dupslots = DMNEW(s4, 4 + 6);
2311 iptr->dst.dupslots[0] =
2312 curstack->prev->prev->prev->varnum;
2313 iptr->dst.dupslots[1] =
2314 curstack->prev->prev->varnum;
2315 iptr->dst.dupslots[2] = curstack->prev->varnum;
2316 iptr->dst.dupslots[3] = curstack->varnum;
2318 POPANY; POPANY; POPANY; POPANY;
2320 DUP_SLOT(copy->prev);
2321 iptr->dst.dupslots[4+0] = curstack->varnum;
2323 iptr->dst.dupslots[4+1] = curstack->varnum;
2324 DUP_SLOT(copy->prev->prev->prev);
2325 iptr->dst.dupslots[4+2] = curstack->varnum;
2326 DUP_SLOT(copy->prev->prev);
2327 iptr->dst.dupslots[4+3] = curstack->varnum;
2328 DUP_SLOT(copy->prev);
2329 iptr->dst.dupslots[4+4] = curstack->varnum;
2331 iptr->dst.dupslots[4+5] = curstack->varnum;
2333 iptr->dst.dupslots = DMNEW(stackptr, 4 + 6);
2334 iptr->dst.dupslots[0] = curstack->prev->prev->prev;
2335 iptr->dst.dupslots[1] = curstack->prev->prev;
2336 iptr->dst.dupslots[2] = curstack->prev;
2337 iptr->dst.dupslots[3] = curstack;
2338 POPANY; POPANY; POPANY; POPANY;
2340 DUP_SLOT(iptr->dst.dupslots[2]);
2341 iptr->dst.dupslots[4+0] = curstack;
2342 DUP_SLOT(iptr->dst.dupslots[3]);
2343 iptr->dst.dupslots[4+1] = curstack;
2344 DUP_SLOT(iptr->dst.dupslots[0]);
2345 iptr->dst.dupslots[4+2] = curstack;
2346 DUP_SLOT(iptr->dst.dupslots[1]);
2347 iptr->dst.dupslots[4+3] = curstack;
2348 DUP_SLOT(iptr->dst.dupslots[2]);
2349 iptr->dst.dupslots[4+4] = curstack;
2350 DUP_SLOT(iptr->dst.dupslots[3]);
2351 iptr->dst.dupslots[4+5] = curstack;
2353 last_dup_boundary = new;
2358 /* pop 2 push 2 swap */
2361 #ifdef ENABLE_VERIFIER
2364 if (IS_2_WORD_TYPE(curstack->type)
2365 || IS_2_WORD_TYPE(curstack->prev->type))
2366 goto throw_stack_category_error;
2370 #if defined(NEW_VAR)
2371 iptr->dst.dupslots = DMNEW(s4, 2 + 2);
2372 iptr->dst.dupslots[0] = curstack->prev->varnum;
2373 iptr->dst.dupslots[1] = curstack->varnum;
2378 iptr->dst.dupslots[2+0] = curstack->varnum;
2379 DUP_SLOT(copy->prev);
2380 iptr->dst.dupslots[2+1] = curstack->varnum;
2382 iptr->dst.dupslots = DMNEW(stackptr, 2 + 2);
2383 iptr->dst.dupslots[0] = curstack->prev;
2384 iptr->dst.dupslots[1] = curstack;
2387 DUP_SLOT(iptr->dst.dupslots[1]);
2388 iptr->dst.dupslots[2+0] = curstack;
2389 DUP_SLOT(iptr->dst.dupslots[0]);
2390 iptr->dst.dupslots[2+1] = curstack;
2392 last_dup_boundary = new;
2399 last_pei_boundary = new;
2400 #if !SUPPORT_DIVISION
2401 bte = iptr->sx.s23.s3.bte;
2404 if (md->memuse > rd->memuse)
2405 rd->memuse = md->memuse;
2406 if (md->argintreguse > rd->argintreguse)
2407 rd->argintreguse = md->argintreguse;
2409 /* make all stack variables saved */
2413 #if defined(NEW_VAR)
2414 jd->var[copy->varnum].flags |= SAVEDVAR;
2416 copy->flags |= SAVEDVAR;
2421 #endif /* !SUPPORT_DIVISION */
2432 COUNT(count_pcmd_op);
2433 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2438 last_pei_boundary = new;
2439 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2440 bte = iptr->sx.s23.s3.bte;
2443 if (md->memuse > rd->memuse)
2444 rd->memuse = md->memuse;
2445 if (md->argintreguse > rd->argintreguse)
2446 rd->argintreguse = md->argintreguse;
2447 /* XXX non-leaf method? */
2449 /* make all stack variables saved */
2453 #if defined(NEW_VAR)
2454 jd->var[copy->varnum].flags |= SAVEDVAR;
2456 copy->flags |= SAVEDVAR;
2461 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2466 #if SUPPORT_LONG_LOGICAL
2470 #endif /* SUPPORT_LONG_LOGICAL */
2471 COUNT(count_pcmd_op);
2472 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2478 COUNT(count_pcmd_op);
2479 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2487 COUNT(count_pcmd_op);
2488 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2496 COUNT(count_pcmd_op);
2497 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2501 COUNT(count_pcmd_op);
2502 #if SUPPORT_LONG_CMP_CONST
2503 if ((len == 0) || (iptr[1].sx.val.i != 0))
2506 switch (iptr[1].opc) {
2508 iptr->opc = ICMD_IF_LCMPEQ;
2510 iptr->dst.insindex = iptr[1].dst.insindex;
2511 iptr[1].opc = ICMD_NOP;
2513 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2514 BRANCH(tbptr, copy);
2516 COUNT(count_pcmd_bra);
2519 iptr->opc = ICMD_IF_LCMPNE;
2520 goto icmd_lcmp_if_tail;
2522 iptr->opc = ICMD_IF_LCMPLT;
2523 goto icmd_lcmp_if_tail;
2525 iptr->opc = ICMD_IF_LCMPGT;
2526 goto icmd_lcmp_if_tail;
2528 iptr->opc = ICMD_IF_LCMPLE;
2529 goto icmd_lcmp_if_tail;
2531 iptr->opc = ICMD_IF_LCMPGE;
2532 goto icmd_lcmp_if_tail;
2538 #endif /* SUPPORT_LONG_CMP_CONST */
2539 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2542 /* XXX why is this deactivated? */
2545 COUNT(count_pcmd_op);
2546 if ((len == 0) || (iptr[1].sx.val.i != 0))
2549 switch (iptr[1].opc) {
2551 iptr->opc = ICMD_IF_FCMPEQ;
2553 iptr->dst.insindex = iptr[1].dst.insindex;
2554 iptr[1].opc = ICMD_NOP;
2556 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2557 BRANCH(tbptr, copy);
2559 COUNT(count_pcmd_bra);
2562 iptr->opc = ICMD_IF_FCMPNE;
2563 goto icmd_if_fcmpl_tail;
2565 iptr->opc = ICMD_IF_FCMPL_LT;
2566 goto icmd_if_fcmpl_tail;
2568 iptr->opc = ICMD_IF_FCMPL_GT;
2569 goto icmd_if_fcmpl_tail;
2571 iptr->opc = ICMD_IF_FCMPL_LE;
2572 goto icmd_if_fcmpl_tail;
2574 iptr->opc = ICMD_IF_FCMPL_GE;
2575 goto icmd_if_fcmpl_tail;
2582 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2586 COUNT(count_pcmd_op);
2587 if ((len == 0) || (iptr[1].sx.val.i != 0))
2590 switch (iptr[1].opc) {
2592 iptr->opc = ICMD_IF_FCMPEQ;
2594 iptr->dst.insindex = iptr[1].dst.insindex;
2595 iptr[1].opc = ICMD_NOP;
2597 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2598 BRANCH(tbptr, copy);
2600 COUNT(count_pcmd_bra);
2603 iptr->opc = ICMD_IF_FCMPNE;
2604 goto icmd_if_fcmpg_tail;
2606 iptr->opc = ICMD_IF_FCMPG_LT;
2607 goto icmd_if_fcmpg_tail;
2609 iptr->opc = ICMD_IF_FCMPG_GT;
2610 goto icmd_if_fcmpg_tail;
2612 iptr->opc = ICMD_IF_FCMPG_LE;
2613 goto icmd_if_fcmpg_tail;
2615 iptr->opc = ICMD_IF_FCMPG_GE;
2616 goto icmd_if_fcmpg_tail;
2623 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2627 COUNT(count_pcmd_op);
2628 if ((len == 0) || (iptr[1].sx.val.i != 0))
2631 switch (iptr[1].opc) {
2633 iptr->opc = ICMD_IF_DCMPEQ;
2635 iptr->dst.insindex = iptr[1].dst.insindex;
2636 iptr[1].opc = ICMD_NOP;
2638 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2639 BRANCH(tbptr, copy);
2641 COUNT(count_pcmd_bra);
2644 iptr->opc = ICMD_IF_DCMPNE;
2645 goto icmd_if_dcmpl_tail;
2647 iptr->opc = ICMD_IF_DCMPL_LT;
2648 goto icmd_if_dcmpl_tail;
2650 iptr->opc = ICMD_IF_DCMPL_GT;
2651 goto icmd_if_dcmpl_tail;
2653 iptr->opc = ICMD_IF_DCMPL_LE;
2654 goto icmd_if_dcmpl_tail;
2656 iptr->opc = ICMD_IF_DCMPL_GE;
2657 goto icmd_if_dcmpl_tail;
2664 OPTT2_1(TYPE_DBL, TYPE_INT);
2668 COUNT(count_pcmd_op);
2669 if ((len == 0) || (iptr[1].sx.val.i != 0))
2672 switch (iptr[1].opc) {
2674 iptr->opc = ICMD_IF_DCMPEQ;
2676 iptr->dst.insindex = iptr[1].dst.insindex;
2677 iptr[1].opc = ICMD_NOP;
2679 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2680 BRANCH(tbptr, copy);
2682 COUNT(count_pcmd_bra);
2685 iptr->opc = ICMD_IF_DCMPNE;
2686 goto icmd_if_dcmpg_tail;
2688 iptr->opc = ICMD_IF_DCMPG_LT;
2689 goto icmd_if_dcmpg_tail;
2691 iptr->opc = ICMD_IF_DCMPG_GT;
2692 goto icmd_if_dcmpg_tail;
2694 iptr->opc = ICMD_IF_DCMPG_LE;
2695 goto icmd_if_dcmpg_tail;
2697 iptr->opc = ICMD_IF_DCMPG_GE;
2698 goto icmd_if_dcmpg_tail;
2705 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2710 COUNT(count_pcmd_op);
2711 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2716 COUNT(count_pcmd_op);
2717 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2726 case ICMD_INT2SHORT:
2727 COUNT(count_pcmd_op);
2728 OP1_1(TYPE_INT, TYPE_INT);
2731 COUNT(count_pcmd_op);
2732 OP1_1(TYPE_LNG, TYPE_LNG);
2735 COUNT(count_pcmd_op);
2736 OP1_1(TYPE_FLT, TYPE_FLT);
2739 COUNT(count_pcmd_op);
2740 OP1_1(TYPE_DBL, TYPE_DBL);
2744 COUNT(count_pcmd_op);
2745 OP1_1(TYPE_INT, TYPE_LNG);
2748 COUNT(count_pcmd_op);
2749 OP1_1(TYPE_INT, TYPE_FLT);
2752 COUNT(count_pcmd_op);
2753 OP1_1(TYPE_INT, TYPE_DBL);
2756 COUNT(count_pcmd_op);
2757 OP1_1(TYPE_LNG, TYPE_INT);
2760 COUNT(count_pcmd_op);
2761 OP1_1(TYPE_LNG, TYPE_FLT);
2764 COUNT(count_pcmd_op);
2765 OP1_1(TYPE_LNG, TYPE_DBL);
2768 COUNT(count_pcmd_op);
2769 OP1_1(TYPE_FLT, TYPE_INT);
2772 COUNT(count_pcmd_op);
2773 OP1_1(TYPE_FLT, TYPE_LNG);
2776 COUNT(count_pcmd_op);
2777 OP1_1(TYPE_FLT, TYPE_DBL);
2780 COUNT(count_pcmd_op);
2781 OP1_1(TYPE_DBL, TYPE_INT);
2784 COUNT(count_pcmd_op);
2785 OP1_1(TYPE_DBL, TYPE_LNG);
2788 COUNT(count_pcmd_op);
2789 OP1_1(TYPE_DBL, TYPE_FLT);
2792 case ICMD_CHECKCAST:
2793 last_pei_boundary = new;
2794 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2795 /* array type cast-check */
2797 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2800 if (md->memuse > rd->memuse)
2801 rd->memuse = md->memuse;
2802 if (md->argintreguse > rd->argintreguse)
2803 rd->argintreguse = md->argintreguse;
2805 /* make all stack variables saved */
2809 #if defined(NEW_VAR)
2810 jd->var[copy->varnum].flags |= SAVEDVAR;
2812 copy->flags |= SAVEDVAR;
2816 OP1_1(TYPE_ADR, TYPE_ADR);
2819 case ICMD_INSTANCEOF:
2820 case ICMD_ARRAYLENGTH:
2821 last_pei_boundary = new;
2822 OP1_1(TYPE_ADR, TYPE_INT);
2826 case ICMD_ANEWARRAY:
2827 last_pei_boundary = new;
2828 OP1_1(TYPE_INT, TYPE_ADR);
2832 last_pei_boundary = new;
2833 COUNT(count_check_null);
2834 COUNT(count_pcmd_mem);
2835 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2836 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2841 case ICMD_GETSTATIC:
2842 last_pei_boundary = new;
2843 COUNT(count_pcmd_mem);
2844 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2845 OP0_1(fmiref->parseddesc.fd->type);
2849 last_pei_boundary = new;
2856 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2858 tbptr->type = BBTYPE_SBR;
2860 /* We need to check for overflow right here because
2861 * the pushed value is poped afterwards */
2864 /* calculate stack after return */
2869 /* pop many push any */
2873 bte = iptr->sx.s23.s3.bte;
2877 case ICMD_INVOKESTATIC:
2878 case ICMD_INVOKESPECIAL:
2879 case ICMD_INVOKEVIRTUAL:
2880 case ICMD_INVOKEINTERFACE:
2881 COUNT(count_pcmd_met);
2883 /* Check for functions to replace with builtin
2886 if (builtintable_replace_function(iptr))
2889 INSTRUCTION_GET_METHODDESC(iptr, md);
2890 /* XXX resurrect this COUNT? */
2891 /* if (lm->flags & ACC_STATIC) */
2892 /* {COUNT(count_check_null);} */
2896 last_pei_boundary = new;
2900 if (md->memuse > rd->memuse)
2901 rd->memuse = md->memuse;
2902 if (md->argintreguse > rd->argintreguse)
2903 rd->argintreguse = md->argintreguse;
2904 if (md->argfltreguse > rd->argfltreguse)
2905 rd->argfltreguse = md->argfltreguse;
2909 /* XXX optimize for <= 2 args */
2910 /* XXX not for ICMD_BUILTIN */
2911 iptr->s1.argcount = stackdepth;
2912 #if defined(NEW_VAR)
2913 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2915 iptr->sx.s23.s2.args = DMNEW(stackptr, stackdepth);
2919 for (i-- ; i >= 0; i--) {
2920 #if defined(NEW_VAR)
2921 iptr->sx.s23.s2.args[i] = copy->varnum;
2923 iptr->sx.s23.s2.args[i] = copy;
2926 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2927 /* -> won't help anyway */
2928 #if defined(NEW_VAR)
2929 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2931 if (copy->varkind != STACKVAR) {
2934 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2935 /* If we pass float arguments in integer argument registers, we
2936 * are not allowed to precolor them here. Floats have to be moved
2937 * to this regs explicitly in codegen().
2938 * Only arguments that are passed by stack anyway can be precolored
2939 * (michi 2005/07/24) */
2940 # if defined(NEW_VAR)
2941 if (!(jd->var[copy->varnum].flags & SAVEDVAR) &&
2942 (!IS_FLT_DBL_TYPE(copy->type)
2943 || md->params[i].inmemory)) {
2944 # else /* defined(NEW_VAR) */
2945 if (!(copy->flags & SAVEDVAR) &&
2946 (!IS_FLT_DBL_TYPE(copy->type)
2947 || md->params[i].inmemory)) {
2948 # endif /* defined(NEW_VAR) */
2950 # if defined(NEW_VAR)
2951 if (!(jd->var[copy->varnum].flags & SAVEDVAR)) {
2953 if (!(copy->flags & SAVEDVAR)) {
2957 #if defined(NEW_VAR)
2960 copy->varkind = ARGVAR;
2964 #if defined(ENABLE_INTRP)
2967 if (md->params[i].inmemory) {
2968 #if defined(NEW_VAR)
2969 jd->var[copy->varnum].regoff =
2970 md->params[i].regoff;
2971 jd->var[copy->varnum].flags |=
2974 copy->flags = INMEMORY;
2975 copy->regoff = md->params[i].regoff;
2979 #if !defined(NEW_VAR)
2982 if (IS_FLT_DBL_TYPE(copy->type)) {
2983 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2984 assert(0); /* XXX is this assert ok? */
2986 #if defined(NEW_VAR)
2987 jd->var[copy->varnum].regoff =
2988 rd->argfltregs[md->params[i].regoff];
2991 rd->argfltregs[md->params[i].regoff];
2993 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2996 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2997 if (IS_2_WORD_TYPE(copy->type))
2998 #if defined(NEW_VAR)
2999 jd->var[copy->varnum].regoff =
3000 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3001 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3004 copy->regoff = PACK_REGS(
3005 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3006 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3009 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
3010 #if defined(NEW_VAR)
3011 jd->var[copy->varnum].regoff =
3012 rd->argintregs[md->params[i].regoff];
3015 rd->argintregs[md->params[i].regoff];
3019 #if defined(ENABLE_INTRP)
3020 } /* end if (!opt_intrp) */
3027 /* deal with live-through stack slots "under" the */
3029 /* XXX not for ICMD_BUILTIN */
3034 #if defined(NEW_VAR)
3035 iptr->sx.s23.s2.args[i++] = copy->varnum;
3036 jd->var[copy->varnum].flags |= SAVEDVAR;
3038 iptr->sx.s23.s2.args[i++] = copy;
3039 copy->flags |= SAVEDVAR;
3044 /* pop the arguments */
3053 /* push the return value */
3055 if (md->returntype.type != TYPE_VOID) {
3056 #if defined(NEW_VAR)
3057 GET_NEW_INDEX(new_index);
3058 DST(md->returntype.type, new_index);
3060 DST(md->returntype.type, stackdepth);
3066 case ICMD_INLINE_START:
3067 case ICMD_INLINE_END:
3072 case ICMD_MULTIANEWARRAY:
3073 last_pei_boundary = new;
3074 if (rd->argintreguse < 3)
3075 rd->argintreguse = 3;
3077 i = iptr->s1.argcount;
3081 #if defined(NEW_VAR)
3082 iptr->sx.s23.s2.args = DMNEW(s4, i);
3084 iptr->sx.s23.s2.args = DMNEW(stackptr, i);
3087 #if defined(SPECIALMEMUSE)
3088 # if defined(__DARWIN__)
3089 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
3090 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3092 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
3093 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
3096 # if defined(__I386__)
3097 if (rd->memuse < i + 3)
3098 rd->memuse = i + 3; /* n integer args spilled on stack */
3099 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3100 if (rd->memuse < i + 2)
3101 rd->memuse = i + 2; /* 4*4 bytes callee save space */
3104 rd->memuse = i; /* n integer args spilled on stack */
3105 # endif /* defined(__I386__) */
3109 /* check INT type here? Currently typecheck does this. */
3110 #if defined(NEW_VAR)
3111 iptr->sx.s23.s2.args[i] = copy->varnum;
3112 if (!(jd->var[copy->varnum].flags & SAVEDVAR)
3113 && (!IS_OUTVAR(copy))
3114 && (!IS_LOCALVAR(copy)) ) {
3116 iptr->sx.s23.s2.args[i] = copy;
3117 if (!(copy->flags & SAVEDVAR)
3118 && (copy->varkind != STACKVAR)) {
3120 copy->varkind = ARGVAR;
3121 #if defined(NEW_VAR)
3122 jd->var[copy->varnum].flags |=
3123 INMEMORY & PREALLOC;
3124 #if defined(SPECIALMEMUSE)
3125 # if defined(__DARWIN__)
3126 jd->var[copy->varnum].regoff = i +
3127 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3129 jd->var[copy->varnum].regoff = i +
3130 LA_SIZE_IN_POINTERS + 3;
3133 # if defined(__I386__)
3134 jd->var[copy->varnum].regoff = i + 3;
3135 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3136 jd->var[copy->varnum].regoff = i + 2;
3138 jd->var[copy->varnum].regoff = i;
3139 # endif /* defined(__I386__) */
3140 #endif /* defined(SPECIALMEMUSE) */
3141 #else /* defined(NEW_VAR) */
3142 copy->varnum = i + INT_ARG_CNT;
3143 copy->flags |= INMEMORY;
3144 #if defined(SPECIALMEMUSE)
3145 # if defined(__DARWIN__)
3146 copy->regoff = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3148 copy->regoff = i + LA_SIZE_IN_POINTERS + 3;
3151 # if defined(__I386__)
3152 copy->regoff = i + 3;
3153 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3154 copy->regoff = i + 2;
3157 # endif /* defined(__I386__) */
3158 #endif /* defined(SPECIALMEMUSE) */
3160 #endif /* defined(NEW_VAR) */
3165 #if defined(NEW_VAR)
3166 jd->var[copy->varnum].flags |= SAVEDVAR;
3168 copy->flags |= SAVEDVAR;
3173 i = iptr->s1.argcount;
3178 #if defined(NEW_VAR)
3179 GET_NEW_INDEX(new_index);
3180 DST(TYPE_ADR, new_index);
3182 DST(TYPE_ADR, stackdepth);
3189 new_internalerror("Unknown ICMD %d", opcode);
3195 } /* while instructions */
3197 /* set out-stack of block */
3199 bptr->outstack = curstack;
3200 bptr->outdepth = stackdepth;
3201 #if defined(NEW_VAR)
3202 bptr->outvars = DMNEW(s4, stackdepth);
3203 for (i = stackdepth, copy = curstack; i--; copy = copy->prev)
3204 bptr->outvars[i] = copy->varnum;
3206 bptr->outvars = DMNEW(stackptr, stackdepth);
3207 for (i = stackdepth, copy = curstack; i--; copy = copy->prev)
3208 bptr->outvars[i] = copy;
3211 /* stack slots at basic block end become interfaces */
3214 for (copy = curstack; copy; i--, copy = copy->prev) {
3215 #if defined(NEW_VAR)
3216 /* with the new vars rd->interfaces will be removed */
3217 /* and all in and outvars have to be STACKVARS! */
3218 /* in the moment i.e. SWAP with in and out vars can */
3219 /* create an unresolvable conflict */
3221 j = jd->interface_map[i * 5 + copy->type];
3223 /* no interface var until now for this depth and */
3228 if (! IS_LOCALVAR(copy) )
3229 jd->var[j].flags |= jd->var[copy->varnum].flags;
3230 jd->interface_map[i*5 + copy->type] = copy->varnum;
3232 else if (j != copy->varnum) {
3233 /* release copy->varnum and take already existing */
3235 RELEASE_INDEX(copy);
3237 if (! IS_LOCALVAR(copy) )
3238 jd->var[j].flags |= jd->var[copy->varnum].flags;
3239 copy->varnum = jd->interface_map[i*5 + copy->type];
3240 } /* else <-> if (j == copy->varnum) --> nothing todo! */
3242 if ((copy->varkind == STACKVAR) && (copy->varnum > i)) {
3243 copy->varkind = TEMPVAR;
3245 copy->varkind = STACKVAR;
3249 rd->interfaces[i][copy->type].type = copy->type;
3250 rd->interfaces[i][copy->type].flags |= copy->flags;
3255 /* check if interface slots at basic block begin must be saved */
3256 #if !defined(NEW_VAR)
3258 i = bptr->indepth - 1;
3259 for (copy = bptr->instack; copy; i--, copy = copy->prev) {
3260 rd->interfaces[i][copy->type].type = copy->type;
3261 if (copy->varkind == STACKVAR) {
3262 if (copy->flags & SAVEDVAR)
3263 rd->interfaces[i][copy->type].flags |= SAVEDVAR;
3269 #if defined(STACK_VERBOSE)
3270 printf("OUTVARS\n");
3271 for( copy = bptr->outstack; copy; copy = copy->prev ) {
3272 printf("%2d(%d", copy->varnum, copy->type);
3273 if (IS_OUTVAR(copy))
3275 if (IS_PREALLOC(copy))
3283 superblockend = true;
3286 } /* while blocks */
3287 } while (repeat && !deadcode);
3289 /* gather statistics *****************************************************/
3291 #if defined(ENABLE_STATISTICS)
3293 if (jd->new_basicblockcount > count_max_basic_blocks)
3294 count_max_basic_blocks = jd->new_basicblockcount;
3295 count_basic_blocks += jd->new_basicblockcount;
3296 if (jd->new_instructioncount > count_max_javainstr)
3297 count_max_javainstr = jd->new_instructioncount;
3298 count_javainstr += jd->new_instructioncount;
3299 if (jd->new_stackcount > count_upper_bound_new_stack)
3300 count_upper_bound_new_stack = jd->new_stackcount;
3301 if ((new - jd->new_stack) > count_max_new_stack)
3302 count_max_new_stack = (new - jd->new_stack);
3304 b_count = jd->new_basicblockcount;
3305 bptr = jd->new_basicblocks;
3306 while (--b_count >= 0) {
3307 if (bptr->flags > BBREACHED) {
3308 if (bptr->indepth >= 10)
3309 count_block_stack[10]++;
3311 count_block_stack[bptr->indepth]++;
3314 count_block_size_distribution[len]++;
3316 count_block_size_distribution[10]++;
3318 count_block_size_distribution[11]++;
3320 count_block_size_distribution[12]++;
3322 count_block_size_distribution[13]++;
3324 count_block_size_distribution[14]++;
3326 count_block_size_distribution[15]++;
3328 count_block_size_distribution[16]++;
3330 count_block_size_distribution[17]++;
3335 if (iteration_count == 1)
3336 count_analyse_iterations[0]++;
3337 else if (iteration_count == 2)
3338 count_analyse_iterations[1]++;
3339 else if (iteration_count == 3)
3340 count_analyse_iterations[2]++;
3341 else if (iteration_count == 4)
3342 count_analyse_iterations[3]++;
3344 count_analyse_iterations[4]++;
3346 if (jd->new_basicblockcount <= 5)
3347 count_method_bb_distribution[0]++;
3348 else if (jd->new_basicblockcount <= 10)
3349 count_method_bb_distribution[1]++;
3350 else if (jd->new_basicblockcount <= 15)
3351 count_method_bb_distribution[2]++;
3352 else if (jd->new_basicblockcount <= 20)
3353 count_method_bb_distribution[3]++;
3354 else if (jd->new_basicblockcount <= 30)
3355 count_method_bb_distribution[4]++;
3356 else if (jd->new_basicblockcount <= 40)
3357 count_method_bb_distribution[5]++;
3358 else if (jd->new_basicblockcount <= 50)
3359 count_method_bb_distribution[6]++;
3360 else if (jd->new_basicblockcount <= 75)
3361 count_method_bb_distribution[7]++;
3363 count_method_bb_distribution[8]++;
3365 #endif /* defined(ENABLE_STATISTICS) */
3367 /* everything's ok *******************************************************/
3371 /* goto labels for throwing verifier exceptions **************************/
3373 #if defined(ENABLE_VERIFIER)
3375 throw_stack_underflow:
3376 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3379 throw_stack_overflow:
3380 exceptions_throw_verifyerror(m, "Stack size too large");
3383 throw_stack_depth_error:
3384 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3387 throw_stack_type_error:
3388 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3391 throw_stack_category_error:
3392 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3400 * These are local overrides for various environment variables in Emacs.
3401 * Please do not remove this and leave it at the end of the file, where
3402 * Emacs will automagically detect them.
3403 * ---------------------------------------------------------------------
3406 * indent-tabs-mode: t
3410 * vim:noexpandtab:sw=4:ts=4: