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 5440 2006-09-08 23:59:52Z edwin $
49 #include "mm/memory.h"
50 #include "native/native.h"
51 #include "toolbox/logging.h"
52 #include "vm/global.h"
53 #include "vm/builtin.h"
54 #include "vm/options.h"
55 #include "vm/resolve.h"
56 #include "vm/statistics.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/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 /* stackdata_t ****************************************************************/
113 typedef struct stackdata_t stackdata_t;
125 /* macros for allocating/releasing variable indices */
127 #define GET_NEW_INDEX(sd, new_varindex) \
129 assert((sd).vartop < (sd).varcount); \
130 (new_varindex) = ((sd).vartop)++; \
133 /* not implemented now, can be used to reuse varindices */
134 /* pay attention to not release a localvar once implementing it! */
135 #define RELEASE_INDEX(sd, varindex)
137 #define GET_NEW_VAR(sd, new_varindex, newtype) \
139 GET_NEW_INDEX((sd), (new_varindex)); \
140 (sd).var[new_index].type = (newtype); \
143 /* macros for querying variable properties **************************/
145 #define IS_OUTVAR(sp) \
146 (sd.var[(sp)->varnum].flags & OUTVAR)
148 #define IS_PREALLOC(sp) \
149 (sd.var[(sp)->varnum].flags & PREALLOC)
151 #define IS_TEMPVAR(sp) \
152 ( ((sp)->varnum >= sd.localcount) \
153 && !(sd.var[(sp)->varnum].flags & (OUTVAR | PREALLOC)) )
155 #define IS_LOCALVAR_SD(sd, sp) \
156 ((sp)->varnum < (sd).localcount)
158 #define IS_LOCALVAR(sp) \
159 IS_LOCALVAR_SD(sd, (sp))
162 /* macros for setting variable properties ****************************/
164 #define SET_TEMPVAR(sp) \
166 if (IS_LOCALVAR((sp))) { \
167 GET_NEW_VAR(sd, new_index, (sp)->type); \
168 sd.var[new_index].flags = (sp)->flags; \
169 (sp)->varnum = new_index; \
170 (sp)->varkind = TEMPVAR; \
172 (sp)->creator->dst.varindex = new_index; \
174 sd.var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC); \
177 #define SET_PREALLOC(sp) \
179 assert(!IS_LOCALVAR((sp))); \
180 sd.var[(sp)->varnum].flags |= PREALLOC; \
183 /* macros for source operands ***************************************/
186 (iptr->s1.varindex = -1)
188 #define USE_S1_LOCAL(type1)
190 #define USE_S1(type1) \
193 CHECK_BASIC_TYPE(type1, curstack->type); \
194 iptr->s1.varindex = curstack->varnum; \
200 iptr->s1.varindex = curstack->varnum; \
203 #define USE_S1_S2(type1, type2) \
206 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
207 CHECK_BASIC_TYPE(type2, curstack->type); \
208 iptr->sx.s23.s2.varindex = curstack->varnum; \
209 iptr->s1.varindex = curstack->prev->varnum; \
212 #define USE_S1_S2_ANY_ANY \
215 iptr->sx.s23.s2.varindex = curstack->varnum; \
216 iptr->s1.varindex = curstack->prev->varnum; \
219 #define USE_S1_S2_S3(type1, type2, type3) \
222 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
223 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
224 CHECK_BASIC_TYPE(type3, curstack->type); \
225 iptr->sx.s23.s3.varindex = curstack->varnum; \
226 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
227 iptr->s1.varindex = curstack->prev->prev->varnum; \
230 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
233 if (curstack->varkind == UNDEFVAR) \
234 curstack->varkind = TEMPVAR; \
235 curstack = curstack->prev; \
238 #define POP_S1(type1) \
241 if (curstack->varkind == UNDEFVAR) \
242 curstack->varkind = TEMPVAR; \
243 curstack = curstack->prev; \
249 if (curstack->varkind == UNDEFVAR) \
250 curstack->varkind = TEMPVAR; \
251 curstack = curstack->prev; \
254 #define POP_S1_S2(type1, type2) \
256 USE_S1_S2(type1, type2); \
257 if (curstack->varkind == UNDEFVAR) \
258 curstack->varkind = TEMPVAR; \
259 if (curstack->prev->varkind == UNDEFVAR) \
260 curstack->prev->varkind = TEMPVAR; \
261 curstack = curstack->prev->prev; \
264 #define POP_S1_S2_ANY_ANY \
267 if (curstack->varkind == UNDEFVAR) \
268 curstack->varkind = TEMPVAR; \
269 if (curstack->prev->varkind == UNDEFVAR) \
270 curstack->prev->varkind = TEMPVAR; \
271 curstack = curstack->prev->prev; \
274 #define POP_S1_S2_S3(type1, type2, type3) \
276 USE_S1_S2_S3(type1, type2, type3); \
277 if (curstack->varkind == UNDEFVAR) \
278 curstack->varkind = TEMPVAR; \
279 if (curstack->prev->varkind == UNDEFVAR) \
280 curstack->prev->varkind = TEMPVAR; \
281 if (curstack->prev->prev->varkind == UNDEFVAR) \
282 curstack->prev->prev->varkind = TEMPVAR; \
283 curstack = curstack->prev->prev->prev; \
290 /* macros for setting the destination operand ***********************/
293 (iptr->dst.varindex = -1)
295 #define DST(typed, index) \
297 NEWSTACKn((typed),(index)); \
298 curstack->creator = iptr; \
299 iptr->dst.varindex = (index); \
302 #define DST_LOCALVAR(typed, index) \
304 NEWSTACK((typed), LOCALVAR, (index)); \
305 curstack->creator = iptr; \
306 iptr->dst.varindex = (index); \
310 /* stack modelling macros *******************************************/
312 #define OP0_1(typed) \
315 GET_NEW_VAR(sd, new_index, (typed)); \
316 DST(typed, new_index); \
327 #define OP1_BRANCH(type1) \
333 #define OP1_1(type1, typed) \
336 GET_NEW_VAR(sd, new_index, (typed)); \
337 DST(typed, new_index); \
340 #define OP2_1(type1, type2, typed) \
342 POP_S1_S2(type1, type2); \
343 GET_NEW_VAR(sd, new_index, (typed)); \
344 DST(typed, new_index); \
359 #define OP1_0(type1) \
366 #define OP2_0(type1, type2) \
368 POP_S1_S2(type1, type2); \
373 #define OP2_BRANCH(type1, type2) \
375 POP_S1_S2(type1, type2); \
379 #define OP2_0_ANY_ANY \
386 #define OP3_0(type1, type2, type3) \
388 POP_S1_S2_S3(type1, type2, type3); \
393 #define LOAD(type1, index) \
395 DST_LOCALVAR(type1, index); \
399 #define STORE(type1, index) \
406 /* macros for DUP elimination ***************************************/
408 /* XXX turn off coalescing */
410 #define DUP_SLOT(sp) \
412 if ((sp)->varkind != TEMPVAR) { \
413 GET_NEW_VAR(sd, new_index, (sp)->type); \
414 NEWSTACK((sp)->type, TEMPVAR, new_index); \
417 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
420 #define DUP_SLOT(sp) \
422 GET_NEW_VAR(sd, new_index, (sp)->type); \
423 NEWSTACK((sp)->type, TEMPVAR, new_index); \
427 /* does not check input stackdepth */
428 #define MOVE_UP(sp) \
430 iptr->opc = ICMD_MOVE; \
431 iptr->s1.varindex = (sp)->varnum; \
433 curstack->creator = iptr; \
434 iptr->dst.varindex = curstack->varnum; \
438 /* does not check input stackdepth */
439 #define COPY_UP(sp) \
442 iptr->opc = ICMD_COPY; \
443 iptr->s1.varindex = (sp)->varnum; \
445 curstack->creator = iptr; \
446 iptr->dst.varindex = curstack->varnum; \
450 #define COPY_DOWN(s, d) \
453 iptr->opc = ICMD_COPY; \
454 iptr->s1.varindex = (s)->varnum; \
455 iptr->dst.varindex = (d)->varnum; \
456 (d)->creator = iptr; \
460 /* macros for branching / reaching basic blocks *********************/
462 #if defined(ENABLE_VERIFIER)
463 #define MARKREACHED(b, c) \
465 if (!stack_mark_reached(&sd, (b), curstack, stackdepth)) \
469 #define MARKREACHED(b, c) \
471 (void) stack_mark_reached(&sd, (b), curstack, stackdepth); \
475 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
477 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
478 MARKREACHED(tempbptr, tempsp); \
481 #define BRANCH(tempbptr, tempsp) \
483 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
484 MARKREACHED(tempbptr, tempsp); \
488 /* stack_init ******************************************************************
490 Initialized the stack analysis subsystem (called by jit_init).
492 *******************************************************************************/
494 bool stack_init(void)
500 /* MARKREACHED marks the destination block <b> as reached. If this
501 * block has been reached before we check if stack depth and types
502 * match. Otherwise the destination block receives a copy of the
503 * current stack as its input stack.
505 * b...destination block
509 static bool stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
514 #if defined(ENABLE_VERIFIER)
515 int expectedtype; /* used by CHECK_BASIC_TYPE */
519 b->bitflags |= BBFLAG_REPLACEMENT;
521 if (b->flags < BBREACHED) {
522 /* b is reached for the first time. Create its instack */
523 COPYCURSTACK(*sd, sp);
524 b->flags = BBREACHED;
526 b->indepth = stackdepth;
527 b->invars = DMNEW(s4, stackdepth);
528 for (i = stackdepth; i--; sp = sp->prev) {
529 b->invars[i] = sp->varnum;
530 sd->var[sp->varnum].flags |= OUTVAR;
534 /* b has been reached before. Check that its instack matches */
537 CHECK_STACK_DEPTH(b->indepth, stackdepth);
539 CHECK_BASIC_TYPE(sp->type,tsp->type);
547 #if defined(ENABLE_VERIFIER)
548 throw_stack_depth_error:
549 exceptions_throw_verifyerror(m,"Stack depth mismatch");
552 throw_stack_type_error:
553 exceptions_throw_verifyerror_for_stack(m, expectedtype);
559 /* stack_analyse ***************************************************************
561 Analyse_stack uses the intermediate code created by parse.c to
562 build a model of the JVM operand stack for the current method.
564 The following checks are performed:
565 - check for operand stack underflow (before each instruction)
566 - check for operand stack overflow (after[1] each instruction)
567 - check for matching stack depth at merging points
568 - check for matching basic types[2] at merging points
569 - check basic types for instruction input (except for BUILTIN*
570 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
572 [1]) Checking this after the instruction should be ok. parse.c
573 counts the number of required stack slots in such a way that it is
574 only vital that we don't exceed `maxstack` at basic block
577 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
578 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
579 types are not discerned.
581 *******************************************************************************/
583 bool new_stack_analyse(jitdata *jd)
585 methodinfo *m; /* method being analyzed */
590 int b_count; /* basic block counter */
591 int b_index; /* basic block index */
593 stackptr curstack; /* current stack top */
595 int opcode; /* opcode of current instruction */
598 int len; /* # of instructions after the current one */
599 bool superblockend; /* if true, no fallthrough to next block */
600 bool repeat; /* if true, outermost loop must run again */
601 bool deadcode; /* true if no live code has been reached */
602 instruction *iptr; /* the current instruction */
605 stackptr *last_store_boundary;
606 stackptr coalescing_boundary;
608 stackptr src1, src2, src3, src4, dst1, dst2;
610 branch_target_t *table;
611 lookup_target_t *lookup;
612 #if defined(ENABLE_VERIFIER)
613 int expectedtype; /* used by CHECK_BASIC_TYPE */
615 builtintable_entry *bte;
617 constant_FMIref *fmiref;
618 #if defined(ENABLE_STATISTICS)
619 int iteration_count; /* number of iterations of analysis */
621 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
623 #if defined(STACK_VERBOSE)
624 new_show_method(jd, SHOW_PARSE);
627 /* get required compiler data - initialization */
634 /* initialize the stackdata_t struct */
636 sd.varcount = jd->varcount;
637 sd.vartop = jd->vartop;
638 sd.localcount = jd->localcount;
640 sd.new = jd->new_stack;
642 #if defined(ENABLE_LSRA)
646 #if defined(ENABLE_STATISTICS)
650 /* init jd->interface_map */
652 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
653 for (i = 0; i < m->maxstack * 5; i++)
654 jd->interface_map[i].flags = UNUSED;
656 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
658 /* initialize in-stack of first block */
660 jd->new_basicblocks[0].flags = BBREACHED;
661 jd->new_basicblocks[0].instack = NULL;
662 jd->new_basicblocks[0].invars = NULL;
663 jd->new_basicblocks[0].indepth = 0;
665 /* initialize in-stack of exception handlers */
667 for (i = 0; i < cd->exceptiontablelength; i++) {
668 sd.bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
669 sd.bptr->flags = BBREACHED;
670 sd.bptr->type = BBTYPE_EXH;
671 sd.bptr->instack = sd.new;
672 sd.bptr->indepth = 1;
673 sd.bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
674 curstack = NULL; stackdepth = 0;
675 GET_NEW_VAR(sd, new_index, TYPE_ADR);
676 sd.bptr->invars = DMNEW(s4, 1);
677 sd.bptr->invars[0] = new_index;
678 sd.var[new_index].flags |= OUTVAR;
679 NEWSTACK(TYPE_ADR, STACKVAR, new_index);
680 curstack->creator = NULL;
682 jd->interface_map[0 * 5 + TYPE_ADR].flags = 0;
685 /* stack analysis loop (until fixpoint reached) **************************/
688 #if defined(ENABLE_STATISTICS)
692 /* initialize loop over basic blocks */
694 b_count = jd->new_basicblockcount;
695 sd.bptr = jd->new_basicblocks;
696 superblockend = true;
698 curstack = NULL; stackdepth = 0;
701 /* iterate over basic blocks *****************************************/
703 while (--b_count >= 0) {
704 #if defined(STACK_VERBOSE)
705 printf("----\nANALYZING BLOCK L%03d ", sd.bptr->nr);
706 if (sd.bptr->type == BBTYPE_EXH) printf("EXH\n");
707 else if (sd.bptr->type == BBTYPE_SBR) printf("SBR\n");
708 else printf("STD\n");
712 if (sd.bptr->flags == BBDELETED) {
713 /* This block has been deleted - do nothing. */
715 else if (superblockend && (sd.bptr->flags < BBREACHED)) {
716 /* This block has not been reached so far, and we */
717 /* don't fall into it, so we'll have to iterate again. */
720 else if (sd.bptr->flags <= BBREACHED) {
722 /* We know that sd.bptr->flags == BBREACHED. */
723 /* This block has been reached before. */
724 stackdepth = sd.bptr->indepth;
726 else if (sd.bptr->flags < BBREACHED) {
727 /* This block is reached for the first time now */
728 /* by falling through from the previous block. */
729 /* Create the instack (propagated). */
730 COPYCURSTACK(sd, copy);
731 sd.bptr->instack = copy;
733 sd.bptr->invars = DMNEW(s4, stackdepth);
734 for (i=stackdepth; i--; copy = copy->prev)
735 sd.bptr->invars[i] = copy->varnum;
736 sd.bptr->indepth = stackdepth;
739 /* This block has been reached before. now we are */
740 /* falling into it from the previous block. */
741 /* Check that stack depth is well-defined. */
742 CHECK_STACK_DEPTH(sd.bptr->indepth, stackdepth);
744 /* XXX check stack types? */
747 /* set up local variables for analyzing this block */
749 curstack = sd.bptr->instack;
751 superblockend = false;
752 len = sd.bptr->icount;
753 iptr = sd.bptr->iinstr;
754 b_index = sd.bptr - jd->new_basicblocks;
756 /* mark the block as analysed */
758 sd.bptr->flags = BBFINISHED;
760 /* reset variables for dependency checking */
762 coalescing_boundary = sd.new;
763 for( i = 0; i < cd->maxlocals; i++)
764 last_store_boundary[i] = sd.new;
766 /* XXX store the start of the block's stack representation */
768 sd.bptr->stack = sd.new;
770 #if defined(STACK_VERBOSE)
772 for( copy = sd.bptr->instack; copy; copy = copy->prev ) {
773 printf("%2d(%d", copy->varnum, copy->type);
776 if (IS_PREALLOC(copy))
782 printf("INVARS - indices:\t\n");
783 for (i=0; i<sd.bptr->indepth; ++i) {
784 printf("%d ", sd.bptr->invars[i]);
790 /* iterate over ICMDs ****************************************/
794 #if defined(STACK_VERBOSE)
795 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
796 for( copy = curstack; copy; copy = copy->prev ) {
797 printf("%2d(%d", copy->varnum, copy->type);
800 if (IS_PREALLOC(copy))
807 /* fetch the current opcode */
811 /* automatically replace some ICMDs with builtins */
813 #if defined(USEBUILTINTABLE)
815 bte = builtintable_get_automatic(opcode);
817 if (bte && bte->opcode == opcode) {
818 iptr->opc = ICMD_BUILTIN;
819 iptr->flags.bits = 0;
820 iptr->sx.s23.s3.bte = bte;
821 /* iptr->line is already set */
822 jd->isleafmethod = false;
826 #endif /* defined(USEBUILTINTABLE) */
828 /* main opcode switch *************************************/
841 coalescing_boundary = sd.new;
842 COUNT(count_check_null);
845 CLR_DST; /* XXX live through? */
850 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
852 USE_S1_LOCAL(TYPE_ADR);
856 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
858 superblockend = true;
862 COUNT(count_pcmd_return);
865 superblockend = true;
869 /* pop 0 push 1 const */
871 /************************** ICONST OPTIMIZATIONS **************************/
874 COUNT(count_pcmd_load);
878 switch (iptr[1].opc) {
880 iptr->opc = ICMD_IADDCONST;
884 iptr[1].opc = ICMD_NOP;
885 OP1_1(TYPE_INT, TYPE_INT);
886 COUNT(count_pcmd_op);
890 iptr->opc = ICMD_ISUBCONST;
891 goto icmd_iconst_tail;
892 #if SUPPORT_CONST_MUL
894 iptr->opc = ICMD_IMULCONST;
895 goto icmd_iconst_tail;
896 #else /* SUPPORT_CONST_MUL */
898 if (iptr->sx.val.i == 0x00000002)
900 else if (iptr->sx.val.i == 0x00000004)
902 else if (iptr->sx.val.i == 0x00000008)
904 else if (iptr->sx.val.i == 0x00000010)
906 else if (iptr->sx.val.i == 0x00000020)
908 else if (iptr->sx.val.i == 0x00000040)
910 else if (iptr->sx.val.i == 0x00000080)
912 else if (iptr->sx.val.i == 0x00000100)
914 else if (iptr->sx.val.i == 0x00000200)
916 else if (iptr->sx.val.i == 0x00000400)
918 else if (iptr->sx.val.i == 0x00000800)
920 else if (iptr->sx.val.i == 0x00001000)
922 else if (iptr->sx.val.i == 0x00002000)
924 else if (iptr->sx.val.i == 0x00004000)
926 else if (iptr->sx.val.i == 0x00008000)
928 else if (iptr->sx.val.i == 0x00010000)
930 else if (iptr->sx.val.i == 0x00020000)
932 else if (iptr->sx.val.i == 0x00040000)
934 else if (iptr->sx.val.i == 0x00080000)
936 else if (iptr->sx.val.i == 0x00100000)
938 else if (iptr->sx.val.i == 0x00200000)
940 else if (iptr->sx.val.i == 0x00400000)
942 else if (iptr->sx.val.i == 0x00800000)
944 else if (iptr->sx.val.i == 0x01000000)
946 else if (iptr->sx.val.i == 0x02000000)
948 else if (iptr->sx.val.i == 0x04000000)
950 else if (iptr->sx.val.i == 0x08000000)
952 else if (iptr->sx.val.i == 0x10000000)
954 else if (iptr->sx.val.i == 0x20000000)
956 else if (iptr->sx.val.i == 0x40000000)
958 else if (iptr->sx.val.i == 0x80000000)
963 iptr->opc = ICMD_IMULPOW2;
964 goto icmd_iconst_tail;
965 #endif /* SUPPORT_CONST_MUL */
967 if (iptr->sx.val.i == 0x00000002)
969 else if (iptr->sx.val.i == 0x00000004)
971 else if (iptr->sx.val.i == 0x00000008)
973 else if (iptr->sx.val.i == 0x00000010)
975 else if (iptr->sx.val.i == 0x00000020)
977 else if (iptr->sx.val.i == 0x00000040)
979 else if (iptr->sx.val.i == 0x00000080)
981 else if (iptr->sx.val.i == 0x00000100)
983 else if (iptr->sx.val.i == 0x00000200)
985 else if (iptr->sx.val.i == 0x00000400)
987 else if (iptr->sx.val.i == 0x00000800)
989 else if (iptr->sx.val.i == 0x00001000)
991 else if (iptr->sx.val.i == 0x00002000)
993 else if (iptr->sx.val.i == 0x00004000)
995 else if (iptr->sx.val.i == 0x00008000)
997 else if (iptr->sx.val.i == 0x00010000)
999 else if (iptr->sx.val.i == 0x00020000)
1000 iptr->sx.val.i = 17;
1001 else if (iptr->sx.val.i == 0x00040000)
1002 iptr->sx.val.i = 18;
1003 else if (iptr->sx.val.i == 0x00080000)
1004 iptr->sx.val.i = 19;
1005 else if (iptr->sx.val.i == 0x00100000)
1006 iptr->sx.val.i = 20;
1007 else if (iptr->sx.val.i == 0x00200000)
1008 iptr->sx.val.i = 21;
1009 else if (iptr->sx.val.i == 0x00400000)
1010 iptr->sx.val.i = 22;
1011 else if (iptr->sx.val.i == 0x00800000)
1012 iptr->sx.val.i = 23;
1013 else if (iptr->sx.val.i == 0x01000000)
1014 iptr->sx.val.i = 24;
1015 else if (iptr->sx.val.i == 0x02000000)
1016 iptr->sx.val.i = 25;
1017 else if (iptr->sx.val.i == 0x04000000)
1018 iptr->sx.val.i = 26;
1019 else if (iptr->sx.val.i == 0x08000000)
1020 iptr->sx.val.i = 27;
1021 else if (iptr->sx.val.i == 0x10000000)
1022 iptr->sx.val.i = 28;
1023 else if (iptr->sx.val.i == 0x20000000)
1024 iptr->sx.val.i = 29;
1025 else if (iptr->sx.val.i == 0x40000000)
1026 iptr->sx.val.i = 30;
1027 else if (iptr->sx.val.i == 0x80000000)
1028 iptr->sx.val.i = 31;
1032 iptr->opc = ICMD_IDIVPOW2;
1033 goto icmd_iconst_tail;
1036 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
1037 if ((iptr->sx.val.i == 0x00000002) ||
1038 (iptr->sx.val.i == 0x00000004) ||
1039 (iptr->sx.val.i == 0x00000008) ||
1040 (iptr->sx.val.i == 0x00000010) ||
1041 (iptr->sx.val.i == 0x00000020) ||
1042 (iptr->sx.val.i == 0x00000040) ||
1043 (iptr->sx.val.i == 0x00000080) ||
1044 (iptr->sx.val.i == 0x00000100) ||
1045 (iptr->sx.val.i == 0x00000200) ||
1046 (iptr->sx.val.i == 0x00000400) ||
1047 (iptr->sx.val.i == 0x00000800) ||
1048 (iptr->sx.val.i == 0x00001000) ||
1049 (iptr->sx.val.i == 0x00002000) ||
1050 (iptr->sx.val.i == 0x00004000) ||
1051 (iptr->sx.val.i == 0x00008000) ||
1052 (iptr->sx.val.i == 0x00010000) ||
1053 (iptr->sx.val.i == 0x00020000) ||
1054 (iptr->sx.val.i == 0x00040000) ||
1055 (iptr->sx.val.i == 0x00080000) ||
1056 (iptr->sx.val.i == 0x00100000) ||
1057 (iptr->sx.val.i == 0x00200000) ||
1058 (iptr->sx.val.i == 0x00400000) ||
1059 (iptr->sx.val.i == 0x00800000) ||
1060 (iptr->sx.val.i == 0x01000000) ||
1061 (iptr->sx.val.i == 0x02000000) ||
1062 (iptr->sx.val.i == 0x04000000) ||
1063 (iptr->sx.val.i == 0x08000000) ||
1064 (iptr->sx.val.i == 0x10000000) ||
1065 (iptr->sx.val.i == 0x20000000) ||
1066 (iptr->sx.val.i == 0x40000000) ||
1067 (iptr->sx.val.i == 0x80000000))
1069 iptr->opc = ICMD_IREMPOW2;
1070 iptr->sx.val.i -= 1;
1071 goto icmd_iconst_tail;
1074 #if SUPPORT_CONST_LOGICAL
1076 iptr->opc = ICMD_IANDCONST;
1077 goto icmd_iconst_tail;
1080 iptr->opc = ICMD_IORCONST;
1081 goto icmd_iconst_tail;
1084 iptr->opc = ICMD_IXORCONST;
1085 goto icmd_iconst_tail;
1087 #endif /* SUPPORT_CONST_LOGICAL */
1089 iptr->opc = ICMD_ISHLCONST;
1090 goto icmd_iconst_tail;
1093 iptr->opc = ICMD_ISHRCONST;
1094 goto icmd_iconst_tail;
1097 iptr->opc = ICMD_IUSHRCONST;
1098 goto icmd_iconst_tail;
1099 #if SUPPORT_LONG_SHIFT
1101 iptr->opc = ICMD_LSHLCONST;
1102 goto icmd_lconst_tail;
1105 iptr->opc = ICMD_LSHRCONST;
1106 goto icmd_lconst_tail;
1109 iptr->opc = ICMD_LUSHRCONST;
1110 goto icmd_lconst_tail;
1111 #endif /* SUPPORT_LONG_SHIFT */
1112 case ICMD_IF_ICMPEQ:
1113 iptr[1].opc = ICMD_IFEQ;
1117 /* set the constant for the following icmd */
1118 iptr[1].sx.val.i = iptr->sx.val.i;
1120 /* this instruction becomes a nop */
1121 iptr->opc = ICMD_NOP;
1124 case ICMD_IF_ICMPLT:
1125 iptr[1].opc = ICMD_IFLT;
1126 goto icmd_if_icmp_tail;
1128 case ICMD_IF_ICMPLE:
1129 iptr[1].opc = ICMD_IFLE;
1130 goto icmd_if_icmp_tail;
1132 case ICMD_IF_ICMPNE:
1133 iptr[1].opc = ICMD_IFNE;
1134 goto icmd_if_icmp_tail;
1136 case ICMD_IF_ICMPGT:
1137 iptr[1].opc = ICMD_IFGT;
1138 goto icmd_if_icmp_tail;
1140 case ICMD_IF_ICMPGE:
1141 iptr[1].opc = ICMD_IFGE;
1142 goto icmd_if_icmp_tail;
1144 #if SUPPORT_CONST_STORE
1149 IF_INTRP( goto normal_ICONST; )
1150 # if SUPPORT_CONST_STORE_ZERO_ONLY
1151 if (iptr->sx.val.i != 0)
1154 switch (iptr[1].opc) {
1156 iptr->opc = ICMD_IASTORECONST;
1157 iptr->flags.bits |= INS_FLAG_CHECK;
1160 iptr->opc = ICMD_BASTORECONST;
1161 iptr->flags.bits |= INS_FLAG_CHECK;
1164 iptr->opc = ICMD_CASTORECONST;
1165 iptr->flags.bits |= INS_FLAG_CHECK;
1168 iptr->opc = ICMD_SASTORECONST;
1169 iptr->flags.bits |= INS_FLAG_CHECK;
1173 iptr[1].opc = ICMD_NOP;
1175 /* copy the constant to s3 */
1176 /* XXX constval -> astoreconstval? */
1177 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1178 OP2_0(TYPE_ADR, TYPE_INT);
1179 COUNT(count_pcmd_op);
1182 case ICMD_PUTSTATIC:
1184 IF_INTRP( goto normal_ICONST; )
1185 # if SUPPORT_CONST_STORE_ZERO_ONLY
1186 if (iptr->sx.val.i != 0)
1189 /* XXX check field type? */
1191 /* copy the constant to s2 */
1192 /* XXX constval -> fieldconstval? */
1193 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1196 /* set the field reference (s3) */
1197 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1198 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1199 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1202 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1205 switch (iptr[1].opc) {
1206 case ICMD_PUTSTATIC:
1207 iptr->opc = ICMD_PUTSTATICCONST;
1211 iptr->opc = ICMD_PUTFIELDCONST;
1216 iptr[1].opc = ICMD_NOP;
1217 COUNT(count_pcmd_op);
1219 #endif /* SUPPORT_CONST_STORE */
1225 /* if we get here, the ICONST has been optimized */
1229 /* normal case of an unoptimized ICONST */
1233 /************************** LCONST OPTIMIZATIONS **************************/
1236 COUNT(count_pcmd_load);
1240 /* switch depending on the following instruction */
1242 switch (iptr[1].opc) {
1243 #if SUPPORT_LONG_ADD
1245 iptr->opc = ICMD_LADDCONST;
1249 /* instruction of type LONG -> LONG */
1250 iptr[1].opc = ICMD_NOP;
1251 OP1_1(TYPE_LNG, TYPE_LNG);
1252 COUNT(count_pcmd_op);
1256 iptr->opc = ICMD_LSUBCONST;
1257 goto icmd_lconst_tail;
1259 #endif /* SUPPORT_LONG_ADD */
1260 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1262 iptr->opc = ICMD_LMULCONST;
1263 goto icmd_lconst_tail;
1264 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1265 # if SUPPORT_LONG_SHIFT
1267 if (iptr->sx.val.l == 0x00000002)
1269 else if (iptr->sx.val.l == 0x00000004)
1271 else if (iptr->sx.val.l == 0x00000008)
1273 else if (iptr->sx.val.l == 0x00000010)
1275 else if (iptr->sx.val.l == 0x00000020)
1277 else if (iptr->sx.val.l == 0x00000040)
1279 else if (iptr->sx.val.l == 0x00000080)
1281 else if (iptr->sx.val.l == 0x00000100)
1283 else if (iptr->sx.val.l == 0x00000200)
1285 else if (iptr->sx.val.l == 0x00000400)
1286 iptr->sx.val.i = 10;
1287 else if (iptr->sx.val.l == 0x00000800)
1288 iptr->sx.val.i = 11;
1289 else if (iptr->sx.val.l == 0x00001000)
1290 iptr->sx.val.i = 12;
1291 else if (iptr->sx.val.l == 0x00002000)
1292 iptr->sx.val.i = 13;
1293 else if (iptr->sx.val.l == 0x00004000)
1294 iptr->sx.val.i = 14;
1295 else if (iptr->sx.val.l == 0x00008000)
1296 iptr->sx.val.i = 15;
1297 else if (iptr->sx.val.l == 0x00010000)
1298 iptr->sx.val.i = 16;
1299 else if (iptr->sx.val.l == 0x00020000)
1300 iptr->sx.val.i = 17;
1301 else if (iptr->sx.val.l == 0x00040000)
1302 iptr->sx.val.i = 18;
1303 else if (iptr->sx.val.l == 0x00080000)
1304 iptr->sx.val.i = 19;
1305 else if (iptr->sx.val.l == 0x00100000)
1306 iptr->sx.val.i = 20;
1307 else if (iptr->sx.val.l == 0x00200000)
1308 iptr->sx.val.i = 21;
1309 else if (iptr->sx.val.l == 0x00400000)
1310 iptr->sx.val.i = 22;
1311 else if (iptr->sx.val.l == 0x00800000)
1312 iptr->sx.val.i = 23;
1313 else if (iptr->sx.val.l == 0x01000000)
1314 iptr->sx.val.i = 24;
1315 else if (iptr->sx.val.l == 0x02000000)
1316 iptr->sx.val.i = 25;
1317 else if (iptr->sx.val.l == 0x04000000)
1318 iptr->sx.val.i = 26;
1319 else if (iptr->sx.val.l == 0x08000000)
1320 iptr->sx.val.i = 27;
1321 else if (iptr->sx.val.l == 0x10000000)
1322 iptr->sx.val.i = 28;
1323 else if (iptr->sx.val.l == 0x20000000)
1324 iptr->sx.val.i = 29;
1325 else if (iptr->sx.val.l == 0x40000000)
1326 iptr->sx.val.i = 30;
1327 else if (iptr->sx.val.l == 0x80000000)
1328 iptr->sx.val.i = 31;
1332 iptr->opc = ICMD_LMULPOW2;
1333 goto icmd_lconst_tail;
1334 # endif /* SUPPORT_LONG_SHIFT */
1335 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1336 #if SUPPORT_LONG_DIV_POW2
1338 if (iptr->sx.val.l == 0x00000002)
1340 else if (iptr->sx.val.l == 0x00000004)
1342 else if (iptr->sx.val.l == 0x00000008)
1344 else if (iptr->sx.val.l == 0x00000010)
1346 else if (iptr->sx.val.l == 0x00000020)
1348 else if (iptr->sx.val.l == 0x00000040)
1350 else if (iptr->sx.val.l == 0x00000080)
1352 else if (iptr->sx.val.l == 0x00000100)
1354 else if (iptr->sx.val.l == 0x00000200)
1356 else if (iptr->sx.val.l == 0x00000400)
1357 iptr->sx.val.i = 10;
1358 else if (iptr->sx.val.l == 0x00000800)
1359 iptr->sx.val.i = 11;
1360 else if (iptr->sx.val.l == 0x00001000)
1361 iptr->sx.val.i = 12;
1362 else if (iptr->sx.val.l == 0x00002000)
1363 iptr->sx.val.i = 13;
1364 else if (iptr->sx.val.l == 0x00004000)
1365 iptr->sx.val.i = 14;
1366 else if (iptr->sx.val.l == 0x00008000)
1367 iptr->sx.val.i = 15;
1368 else if (iptr->sx.val.l == 0x00010000)
1369 iptr->sx.val.i = 16;
1370 else if (iptr->sx.val.l == 0x00020000)
1371 iptr->sx.val.i = 17;
1372 else if (iptr->sx.val.l == 0x00040000)
1373 iptr->sx.val.i = 18;
1374 else if (iptr->sx.val.l == 0x00080000)
1375 iptr->sx.val.i = 19;
1376 else if (iptr->sx.val.l == 0x00100000)
1377 iptr->sx.val.i = 20;
1378 else if (iptr->sx.val.l == 0x00200000)
1379 iptr->sx.val.i = 21;
1380 else if (iptr->sx.val.l == 0x00400000)
1381 iptr->sx.val.i = 22;
1382 else if (iptr->sx.val.l == 0x00800000)
1383 iptr->sx.val.i = 23;
1384 else if (iptr->sx.val.l == 0x01000000)
1385 iptr->sx.val.i = 24;
1386 else if (iptr->sx.val.l == 0x02000000)
1387 iptr->sx.val.i = 25;
1388 else if (iptr->sx.val.l == 0x04000000)
1389 iptr->sx.val.i = 26;
1390 else if (iptr->sx.val.l == 0x08000000)
1391 iptr->sx.val.i = 27;
1392 else if (iptr->sx.val.l == 0x10000000)
1393 iptr->sx.val.i = 28;
1394 else if (iptr->sx.val.l == 0x20000000)
1395 iptr->sx.val.i = 29;
1396 else if (iptr->sx.val.l == 0x40000000)
1397 iptr->sx.val.i = 30;
1398 else if (iptr->sx.val.l == 0x80000000)
1399 iptr->sx.val.i = 31;
1403 iptr->opc = ICMD_LDIVPOW2;
1404 goto icmd_lconst_tail;
1405 #endif /* SUPPORT_LONG_DIV_POW2 */
1407 #if SUPPORT_LONG_REM_POW2
1409 if ((iptr->sx.val.l == 0x00000002) ||
1410 (iptr->sx.val.l == 0x00000004) ||
1411 (iptr->sx.val.l == 0x00000008) ||
1412 (iptr->sx.val.l == 0x00000010) ||
1413 (iptr->sx.val.l == 0x00000020) ||
1414 (iptr->sx.val.l == 0x00000040) ||
1415 (iptr->sx.val.l == 0x00000080) ||
1416 (iptr->sx.val.l == 0x00000100) ||
1417 (iptr->sx.val.l == 0x00000200) ||
1418 (iptr->sx.val.l == 0x00000400) ||
1419 (iptr->sx.val.l == 0x00000800) ||
1420 (iptr->sx.val.l == 0x00001000) ||
1421 (iptr->sx.val.l == 0x00002000) ||
1422 (iptr->sx.val.l == 0x00004000) ||
1423 (iptr->sx.val.l == 0x00008000) ||
1424 (iptr->sx.val.l == 0x00010000) ||
1425 (iptr->sx.val.l == 0x00020000) ||
1426 (iptr->sx.val.l == 0x00040000) ||
1427 (iptr->sx.val.l == 0x00080000) ||
1428 (iptr->sx.val.l == 0x00100000) ||
1429 (iptr->sx.val.l == 0x00200000) ||
1430 (iptr->sx.val.l == 0x00400000) ||
1431 (iptr->sx.val.l == 0x00800000) ||
1432 (iptr->sx.val.l == 0x01000000) ||
1433 (iptr->sx.val.l == 0x02000000) ||
1434 (iptr->sx.val.l == 0x04000000) ||
1435 (iptr->sx.val.l == 0x08000000) ||
1436 (iptr->sx.val.l == 0x10000000) ||
1437 (iptr->sx.val.l == 0x20000000) ||
1438 (iptr->sx.val.l == 0x40000000) ||
1439 (iptr->sx.val.l == 0x80000000))
1441 iptr->opc = ICMD_LREMPOW2;
1442 iptr->sx.val.l -= 1;
1443 goto icmd_lconst_tail;
1446 #endif /* SUPPORT_LONG_REM_POW2 */
1448 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1451 iptr->opc = ICMD_LANDCONST;
1452 goto icmd_lconst_tail;
1455 iptr->opc = ICMD_LORCONST;
1456 goto icmd_lconst_tail;
1459 iptr->opc = ICMD_LXORCONST;
1460 goto icmd_lconst_tail;
1461 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1463 #if SUPPORT_LONG_CMP_CONST
1465 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1468 /* switch on the instruction after LCONST - LCMP */
1470 switch (iptr[2].opc) {
1472 iptr->opc = ICMD_IF_LEQ;
1475 icmd_lconst_lcmp_tail:
1476 /* convert LCONST, LCMP, IFXX to IF_LXX */
1477 iptr->dst.insindex = iptr[2].dst.insindex;
1478 iptr[1].opc = ICMD_NOP;
1479 iptr[2].opc = ICMD_NOP;
1481 OP1_BRANCH(TYPE_LNG);
1482 BRANCH(tbptr, copy);
1483 COUNT(count_pcmd_bra);
1484 COUNT(count_pcmd_op);
1488 iptr->opc = ICMD_IF_LNE;
1489 goto icmd_lconst_lcmp_tail;
1492 iptr->opc = ICMD_IF_LLT;
1493 goto icmd_lconst_lcmp_tail;
1496 iptr->opc = ICMD_IF_LGT;
1497 goto icmd_lconst_lcmp_tail;
1500 iptr->opc = ICMD_IF_LLE;
1501 goto icmd_lconst_lcmp_tail;
1504 iptr->opc = ICMD_IF_LGE;
1505 goto icmd_lconst_lcmp_tail;
1509 } /* end switch on opcode after LCONST - LCMP */
1511 #endif /* SUPPORT_LONG_CMP_CONST */
1513 #if SUPPORT_CONST_STORE
1515 IF_INTRP( goto normal_LCONST; )
1516 # if SUPPORT_CONST_STORE_ZERO_ONLY
1517 if (iptr->sx.val.l != 0)
1520 #if SIZEOF_VOID_P == 4
1521 /* the constant must fit into a ptrint */
1522 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1525 /* move the constant to s3 */
1526 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1528 iptr->opc = ICMD_LASTORECONST;
1529 iptr->flags.bits |= INS_FLAG_CHECK;
1530 OP2_0(TYPE_ADR, TYPE_INT);
1532 iptr[1].opc = ICMD_NOP;
1533 COUNT(count_pcmd_op);
1536 case ICMD_PUTSTATIC:
1538 IF_INTRP( goto normal_LCONST; )
1539 # if SUPPORT_CONST_STORE_ZERO_ONLY
1540 if (iptr->sx.val.l != 0)
1543 #if SIZEOF_VOID_P == 4
1544 /* the constant must fit into a ptrint */
1545 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1548 /* XXX check field type? */
1550 /* copy the constant to s2 */
1551 /* XXX constval -> fieldconstval? */
1552 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1556 #endif /* SUPPORT_CONST_STORE */
1560 } /* end switch opcode after LCONST */
1562 /* if we get here, the LCONST has been optimized */
1566 /* the normal case of an unoptimized LCONST */
1570 /************************ END OF LCONST OPTIMIZATIONS *********************/
1573 COUNT(count_pcmd_load);
1578 COUNT(count_pcmd_load);
1582 /************************** ACONST OPTIMIZATIONS **************************/
1585 coalescing_boundary = sd.new;
1586 COUNT(count_pcmd_load);
1587 #if SUPPORT_CONST_STORE
1588 IF_INTRP( goto normal_ACONST; )
1590 /* We can only optimize if the ACONST is resolved
1591 * and there is an instruction after it. */
1593 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1596 switch (iptr[1].opc) {
1598 /* We can only optimize for NULL values
1599 * here because otherwise a checkcast is
1601 if (iptr->sx.val.anyptr != NULL)
1604 /* copy the constant (NULL) to s3 */
1605 iptr->sx.s23.s3.constval = 0;
1606 iptr->opc = ICMD_AASTORECONST;
1607 iptr->flags.bits |= INS_FLAG_CHECK;
1608 OP2_0(TYPE_ADR, TYPE_INT);
1610 iptr[1].opc = ICMD_NOP;
1611 COUNT(count_pcmd_op);
1614 case ICMD_PUTSTATIC:
1616 # if SUPPORT_CONST_STORE_ZERO_ONLY
1617 if (iptr->sx.val.anyptr != NULL)
1620 /* XXX check field type? */
1621 /* copy the constant to s2 */
1622 /* XXX constval -> fieldconstval? */
1623 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1631 /* if we get here the ACONST has been optimized */
1635 #endif /* SUPPORT_CONST_STORE */
1640 /* pop 0 push 1 load */
1647 COUNT(count_load_instruction);
1648 i = opcode - ICMD_ILOAD; /* type */
1651 jd->local_map[iptr->s1.varindex * 5 + i];
1653 LOAD(i, iptr->s1.varindex);
1662 coalescing_boundary = sd.new;
1663 iptr->flags.bits |= INS_FLAG_CHECK;
1664 COUNT(count_check_null);
1665 COUNT(count_check_bound);
1666 COUNT(count_pcmd_mem);
1667 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1674 coalescing_boundary = sd.new;
1675 iptr->flags.bits |= INS_FLAG_CHECK;
1676 COUNT(count_check_null);
1677 COUNT(count_check_bound);
1678 COUNT(count_pcmd_mem);
1679 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1682 /* pop 0 push 0 iinc */
1685 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1687 last_store_boundary[iptr->s1.varindex] = sd.new;
1690 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
1695 if ((copy->varkind == LOCALVAR) &&
1696 (copy->varnum == iptr->s1.varindex))
1698 assert(IS_LOCALVAR(copy));
1705 iptr->dst.varindex = iptr->s1.varindex;
1708 /* pop 1 push 0 store */
1717 i = opcode - ICMD_ISTORE; /* type */
1718 javaindex = iptr->dst.varindex;
1719 j = iptr->dst.varindex =
1720 jd->local_map[javaindex * 5 + i];
1723 #if defined(ENABLE_STATISTICS)
1726 i = sd.new - curstack;
1728 count_store_length[20]++;
1730 count_store_length[i]++;
1733 count_store_depth[10]++;
1735 count_store_depth[i]++;
1738 /* check for conflicts as described in Figure 5.2 */
1740 copy = curstack->prev;
1743 if ((copy->varkind == LOCALVAR) &&
1744 (copy->varnum == j))
1746 copy->varkind = TEMPVAR;
1747 assert(IS_LOCALVAR(copy));
1754 /* if the variable is already coalesced, don't bother */
1756 if (IS_OUTVAR(curstack)
1757 || (curstack->varkind == LOCALVAR
1758 && curstack->varnum != j))
1761 /* there is no STORE Lj while curstack is live */
1763 if (curstack < last_store_boundary[javaindex])
1764 goto assume_conflict;
1766 /* curstack must be after the coalescing boundary */
1768 if (curstack < coalescing_boundary)
1769 goto assume_conflict;
1771 /* there is no DEF LOCALVAR(j) while curstack is live */
1773 copy = sd.new; /* most recent stackslot created + 1 */
1774 while (--copy > curstack) {
1775 if (copy->varkind == LOCALVAR && copy->varnum == j)
1776 goto assume_conflict;
1779 /* coalesce the temporary variable with Lj */
1780 assert( (CURKIND == TEMPVAR) || (CURKIND == UNDEFVAR));
1781 assert(!IS_LOCALVAR(curstack));
1782 assert(!IS_OUTVAR(curstack));
1783 assert(!IS_PREALLOC(curstack));
1785 assert(curstack->creator);
1786 assert(curstack->creator->dst.varindex == curstack->varnum);
1787 RELEASE_INDEX(sd, curstack);
1788 curstack->varkind = LOCALVAR;
1789 curstack->varnum = j;
1790 curstack->creator->dst.varindex = j;
1793 /* revert the coalescing, if it has been done earlier */
1795 if ((curstack->varkind == LOCALVAR)
1796 && (curstack->varnum == j))
1798 assert(IS_LOCALVAR(curstack));
1799 SET_TEMPVAR(curstack);
1802 /* remember the stack boundary at this store */
1804 last_store_boundary[javaindex] = sd.new;
1806 STORE(opcode - ICMD_ISTORE, j);
1812 coalescing_boundary = sd.new;
1813 iptr->flags.bits |= INS_FLAG_CHECK;
1814 COUNT(count_check_null);
1815 COUNT(count_check_bound);
1816 COUNT(count_pcmd_mem);
1818 bte = builtintable_get_internal(BUILTIN_canstore);
1821 if (md->memuse > rd->memuse)
1822 rd->memuse = md->memuse;
1823 if (md->argintreguse > rd->argintreguse)
1824 rd->argintreguse = md->argintreguse;
1825 /* XXX non-leaf method? */
1827 /* make all stack variables saved */
1831 sd.var[copy->varnum].flags |= SAVEDVAR;
1832 /* in case copy->varnum is/will be a LOCALVAR */
1833 /* once and set back to a non LOCALVAR */
1834 /* the correct SAVEDVAR flag has to be */
1835 /* remembered in copy->flags, too */
1836 copy->flags |= SAVEDVAR;
1840 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1847 coalescing_boundary = sd.new;
1848 iptr->flags.bits |= INS_FLAG_CHECK;
1849 COUNT(count_check_null);
1850 COUNT(count_check_bound);
1851 COUNT(count_pcmd_mem);
1852 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1859 coalescing_boundary = sd.new;
1860 iptr->flags.bits |= INS_FLAG_CHECK;
1861 COUNT(count_check_null);
1862 COUNT(count_check_bound);
1863 COUNT(count_pcmd_mem);
1864 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1870 #ifdef ENABLE_VERIFIER
1873 if (IS_2_WORD_TYPE(curstack->type))
1874 goto throw_stack_category_error;
1885 coalescing_boundary = sd.new;
1886 IF_JIT( md_return_alloc(jd, curstack); )
1887 COUNT(count_pcmd_return);
1888 OP1_0(opcode - ICMD_IRETURN);
1889 superblockend = true;
1893 coalescing_boundary = sd.new;
1894 COUNT(count_check_null);
1896 curstack = NULL; stackdepth = 0;
1897 superblockend = true;
1900 case ICMD_PUTSTATIC:
1901 coalescing_boundary = sd.new;
1902 COUNT(count_pcmd_mem);
1903 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1904 OP1_0(fmiref->parseddesc.fd->type);
1907 /* pop 1 push 0 branch */
1910 case ICMD_IFNONNULL:
1911 COUNT(count_pcmd_bra);
1912 OP1_BRANCH(TYPE_ADR);
1913 BRANCH(tbptr, copy);
1922 COUNT(count_pcmd_bra);
1923 /* iptr->sx.val.i is set implicitly in parse by
1924 clearing the memory or from IF_ICMPxx
1927 OP1_BRANCH(TYPE_INT);
1928 /* iptr->sx.val.i = 0; */
1929 BRANCH(tbptr, copy);
1932 /* pop 0 push 0 branch */
1935 COUNT(count_pcmd_bra);
1937 BRANCH(tbptr, copy);
1938 superblockend = true;
1941 /* pop 1 push 0 table branch */
1943 case ICMD_TABLESWITCH:
1944 COUNT(count_pcmd_table);
1945 OP1_BRANCH(TYPE_INT);
1947 table = iptr->dst.table;
1948 BRANCH_TARGET(*table, tbptr, copy);
1951 i = iptr->sx.s23.s3.tablehigh
1952 - iptr->sx.s23.s2.tablelow + 1;
1955 BRANCH_TARGET(*table, tbptr, copy);
1958 superblockend = true;
1961 /* pop 1 push 0 table branch */
1963 case ICMD_LOOKUPSWITCH:
1964 COUNT(count_pcmd_table);
1965 OP1_BRANCH(TYPE_INT);
1967 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
1969 lookup = iptr->dst.lookup;
1971 i = iptr->sx.s23.s2.lookupcount;
1974 BRANCH_TARGET(lookup->target, tbptr, copy);
1977 superblockend = true;
1980 case ICMD_MONITORENTER:
1981 case ICMD_MONITOREXIT:
1982 coalescing_boundary = sd.new;
1983 COUNT(count_check_null);
1987 /* pop 2 push 0 branch */
1989 case ICMD_IF_ICMPEQ:
1990 case ICMD_IF_ICMPNE:
1991 case ICMD_IF_ICMPLT:
1992 case ICMD_IF_ICMPGE:
1993 case ICMD_IF_ICMPGT:
1994 case ICMD_IF_ICMPLE:
1995 COUNT(count_pcmd_bra);
1996 OP2_BRANCH(TYPE_INT, TYPE_INT);
1997 BRANCH(tbptr, copy);
2000 case ICMD_IF_ACMPEQ:
2001 case ICMD_IF_ACMPNE:
2002 COUNT(count_pcmd_bra);
2003 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
2004 BRANCH(tbptr, copy);
2010 coalescing_boundary = sd.new;
2011 COUNT(count_check_null);
2012 COUNT(count_pcmd_mem);
2013 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2014 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
2019 if (!IS_2_WORD_TYPE(curstack->type)) {
2021 #ifdef ENABLE_VERIFIER
2024 if (IS_2_WORD_TYPE(curstack->prev->type))
2025 goto throw_stack_category_error;
2028 OP2_0_ANY_ANY; /* pop two slots */
2031 iptr->opc = ICMD_POP;
2032 OP1_0_ANY; /* pop one (two-word) slot */
2036 /* pop 0 push 1 dup */
2039 #ifdef ENABLE_VERIFIER
2042 if (IS_2_WORD_TYPE(curstack->type))
2043 goto throw_stack_category_error;
2046 COUNT(count_dup_instruction);
2052 coalescing_boundary = sd.new - 1;
2057 if (IS_2_WORD_TYPE(curstack->type)) {
2059 iptr->opc = ICMD_DUP;
2064 /* ..., ????, cat1 */
2065 #ifdef ENABLE_VERIFIER
2067 if (IS_2_WORD_TYPE(curstack->prev->type))
2068 goto throw_stack_category_error;
2071 src1 = curstack->prev;
2074 COPY_UP(src1); iptr++; len--;
2077 coalescing_boundary = sd.new;
2081 /* pop 2 push 3 dup */
2084 #ifdef ENABLE_VERIFIER
2087 if (IS_2_WORD_TYPE(curstack->type) ||
2088 IS_2_WORD_TYPE(curstack->prev->type))
2089 goto throw_stack_category_error;
2094 src1 = curstack->prev;
2099 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2101 MOVE_UP(src1); iptr++; len--;
2102 MOVE_UP(src2); iptr++; len--;
2104 COPY_DOWN(curstack, dst1);
2106 coalescing_boundary = sd.new;
2111 if (IS_2_WORD_TYPE(curstack->type)) {
2112 /* ..., ????, cat2 */
2113 #ifdef ENABLE_VERIFIER
2115 if (IS_2_WORD_TYPE(curstack->prev->type))
2116 goto throw_stack_category_error;
2119 iptr->opc = ICMD_DUP_X1;
2123 /* ..., ????, cat1 */
2124 #ifdef ENABLE_VERIFIER
2127 if (IS_2_WORD_TYPE(curstack->prev->type)
2128 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2129 goto throw_stack_category_error;
2134 src1 = curstack->prev->prev;
2135 src2 = curstack->prev;
2137 POPANY; POPANY; POPANY;
2140 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2141 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
2143 MOVE_UP(src1); iptr++; len--;
2144 MOVE_UP(src2); iptr++; len--;
2145 MOVE_UP(src3); iptr++; len--;
2147 COPY_DOWN(curstack, dst2); iptr++; len--;
2148 COPY_DOWN(curstack->prev, dst1);
2150 coalescing_boundary = sd.new;
2154 /* pop 3 push 4 dup */
2158 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2159 /* ..., cat2, ???? */
2160 #ifdef ENABLE_VERIFIER
2162 if (IS_2_WORD_TYPE(curstack->type))
2163 goto throw_stack_category_error;
2166 iptr->opc = ICMD_DUP_X1;
2170 /* ..., cat1, ???? */
2171 #ifdef ENABLE_VERIFIER
2174 if (IS_2_WORD_TYPE(curstack->type)
2175 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2176 goto throw_stack_category_error;
2180 src1 = curstack->prev->prev;
2181 src2 = curstack->prev;
2183 POPANY; POPANY; POPANY;
2186 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2188 MOVE_UP(src1); iptr++; len--;
2189 MOVE_UP(src2); iptr++; len--;
2190 MOVE_UP(src3); iptr++; len--;
2192 COPY_DOWN(curstack, dst1);
2194 coalescing_boundary = sd.new;
2200 if (IS_2_WORD_TYPE(curstack->type)) {
2201 /* ..., ????, cat2 */
2202 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2203 /* ..., cat2, cat2 */
2204 iptr->opc = ICMD_DUP_X1;
2208 /* ..., cat1, cat2 */
2209 #ifdef ENABLE_VERIFIER
2212 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2213 goto throw_stack_category_error;
2216 iptr->opc = ICMD_DUP_X2;
2222 /* ..., ????, ????, cat1 */
2224 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2225 /* ..., cat2, ????, cat1 */
2226 #ifdef ENABLE_VERIFIER
2228 if (IS_2_WORD_TYPE(curstack->prev->type))
2229 goto throw_stack_category_error;
2232 iptr->opc = ICMD_DUP2_X1;
2236 /* ..., cat1, ????, cat1 */
2237 #ifdef ENABLE_VERIFIER
2240 if (IS_2_WORD_TYPE(curstack->prev->type)
2241 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2242 goto throw_stack_category_error;
2246 src1 = curstack->prev->prev->prev;
2247 src2 = curstack->prev->prev;
2248 src3 = curstack->prev;
2250 POPANY; POPANY; POPANY; POPANY;
2253 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2254 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
2256 MOVE_UP(src1); iptr++; len--;
2257 MOVE_UP(src2); iptr++; len--;
2258 MOVE_UP(src3); iptr++; len--;
2259 MOVE_UP(src4); iptr++; len--;
2261 COPY_DOWN(curstack, dst2); iptr++; len--;
2262 COPY_DOWN(curstack->prev, dst1);
2264 coalescing_boundary = sd.new;
2268 /* pop 2 push 2 swap */
2271 #ifdef ENABLE_VERIFIER
2274 if (IS_2_WORD_TYPE(curstack->type)
2275 || IS_2_WORD_TYPE(curstack->prev->type))
2276 goto throw_stack_category_error;
2280 src1 = curstack->prev;
2285 MOVE_UP(src2); iptr++; len--;
2288 coalescing_boundary = sd.new;
2295 coalescing_boundary = sd.new;
2296 #if !SUPPORT_DIVISION
2297 bte = iptr->sx.s23.s3.bte;
2300 if (md->memuse > rd->memuse)
2301 rd->memuse = md->memuse;
2302 if (md->argintreguse > rd->argintreguse)
2303 rd->argintreguse = md->argintreguse;
2305 /* make all stack variables saved */
2309 sd.var[copy->varnum].flags |= SAVEDVAR;
2310 copy->flags |= SAVEDVAR;
2315 #endif /* !SUPPORT_DIVISION */
2326 COUNT(count_pcmd_op);
2327 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2332 coalescing_boundary = sd.new;
2333 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2334 bte = iptr->sx.s23.s3.bte;
2337 if (md->memuse > rd->memuse)
2338 rd->memuse = md->memuse;
2339 if (md->argintreguse > rd->argintreguse)
2340 rd->argintreguse = md->argintreguse;
2341 /* XXX non-leaf method? */
2343 /* make all stack variables saved */
2347 sd.var[copy->varnum].flags |= SAVEDVAR;
2348 copy->flags |= SAVEDVAR;
2353 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2358 #if SUPPORT_LONG_LOGICAL
2362 #endif /* SUPPORT_LONG_LOGICAL */
2363 COUNT(count_pcmd_op);
2364 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2370 COUNT(count_pcmd_op);
2371 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2379 COUNT(count_pcmd_op);
2380 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2388 COUNT(count_pcmd_op);
2389 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2393 COUNT(count_pcmd_op);
2394 #if SUPPORT_LONG_CMP_CONST
2395 if ((len == 0) || (iptr[1].sx.val.i != 0))
2398 switch (iptr[1].opc) {
2400 iptr->opc = ICMD_IF_LCMPEQ;
2402 iptr->dst.insindex = iptr[1].dst.insindex;
2403 iptr[1].opc = ICMD_NOP;
2405 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2406 BRANCH(tbptr, copy);
2408 COUNT(count_pcmd_bra);
2411 iptr->opc = ICMD_IF_LCMPNE;
2412 goto icmd_lcmp_if_tail;
2414 iptr->opc = ICMD_IF_LCMPLT;
2415 goto icmd_lcmp_if_tail;
2417 iptr->opc = ICMD_IF_LCMPGT;
2418 goto icmd_lcmp_if_tail;
2420 iptr->opc = ICMD_IF_LCMPLE;
2421 goto icmd_lcmp_if_tail;
2423 iptr->opc = ICMD_IF_LCMPGE;
2424 goto icmd_lcmp_if_tail;
2430 #endif /* SUPPORT_LONG_CMP_CONST */
2431 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2434 /* XXX why is this deactivated? */
2437 COUNT(count_pcmd_op);
2438 if ((len == 0) || (iptr[1].sx.val.i != 0))
2441 switch (iptr[1].opc) {
2443 iptr->opc = ICMD_IF_FCMPEQ;
2445 iptr->dst.insindex = iptr[1].dst.insindex;
2446 iptr[1].opc = ICMD_NOP;
2448 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2449 BRANCH(tbptr, copy);
2451 COUNT(count_pcmd_bra);
2454 iptr->opc = ICMD_IF_FCMPNE;
2455 goto icmd_if_fcmpl_tail;
2457 iptr->opc = ICMD_IF_FCMPL_LT;
2458 goto icmd_if_fcmpl_tail;
2460 iptr->opc = ICMD_IF_FCMPL_GT;
2461 goto icmd_if_fcmpl_tail;
2463 iptr->opc = ICMD_IF_FCMPL_LE;
2464 goto icmd_if_fcmpl_tail;
2466 iptr->opc = ICMD_IF_FCMPL_GE;
2467 goto icmd_if_fcmpl_tail;
2474 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2478 COUNT(count_pcmd_op);
2479 if ((len == 0) || (iptr[1].sx.val.i != 0))
2482 switch (iptr[1].opc) {
2484 iptr->opc = ICMD_IF_FCMPEQ;
2486 iptr->dst.insindex = iptr[1].dst.insindex;
2487 iptr[1].opc = ICMD_NOP;
2489 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2490 BRANCH(tbptr, copy);
2492 COUNT(count_pcmd_bra);
2495 iptr->opc = ICMD_IF_FCMPNE;
2496 goto icmd_if_fcmpg_tail;
2498 iptr->opc = ICMD_IF_FCMPG_LT;
2499 goto icmd_if_fcmpg_tail;
2501 iptr->opc = ICMD_IF_FCMPG_GT;
2502 goto icmd_if_fcmpg_tail;
2504 iptr->opc = ICMD_IF_FCMPG_LE;
2505 goto icmd_if_fcmpg_tail;
2507 iptr->opc = ICMD_IF_FCMPG_GE;
2508 goto icmd_if_fcmpg_tail;
2515 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2519 COUNT(count_pcmd_op);
2520 if ((len == 0) || (iptr[1].sx.val.i != 0))
2523 switch (iptr[1].opc) {
2525 iptr->opc = ICMD_IF_DCMPEQ;
2527 iptr->dst.insindex = iptr[1].dst.insindex;
2528 iptr[1].opc = ICMD_NOP;
2530 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2531 BRANCH(tbptr, copy);
2533 COUNT(count_pcmd_bra);
2536 iptr->opc = ICMD_IF_DCMPNE;
2537 goto icmd_if_dcmpl_tail;
2539 iptr->opc = ICMD_IF_DCMPL_LT;
2540 goto icmd_if_dcmpl_tail;
2542 iptr->opc = ICMD_IF_DCMPL_GT;
2543 goto icmd_if_dcmpl_tail;
2545 iptr->opc = ICMD_IF_DCMPL_LE;
2546 goto icmd_if_dcmpl_tail;
2548 iptr->opc = ICMD_IF_DCMPL_GE;
2549 goto icmd_if_dcmpl_tail;
2556 OPTT2_1(TYPE_DBL, TYPE_INT);
2560 COUNT(count_pcmd_op);
2561 if ((len == 0) || (iptr[1].sx.val.i != 0))
2564 switch (iptr[1].opc) {
2566 iptr->opc = ICMD_IF_DCMPEQ;
2568 iptr->dst.insindex = iptr[1].dst.insindex;
2569 iptr[1].opc = ICMD_NOP;
2571 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2572 BRANCH(tbptr, copy);
2574 COUNT(count_pcmd_bra);
2577 iptr->opc = ICMD_IF_DCMPNE;
2578 goto icmd_if_dcmpg_tail;
2580 iptr->opc = ICMD_IF_DCMPG_LT;
2581 goto icmd_if_dcmpg_tail;
2583 iptr->opc = ICMD_IF_DCMPG_GT;
2584 goto icmd_if_dcmpg_tail;
2586 iptr->opc = ICMD_IF_DCMPG_LE;
2587 goto icmd_if_dcmpg_tail;
2589 iptr->opc = ICMD_IF_DCMPG_GE;
2590 goto icmd_if_dcmpg_tail;
2597 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2602 COUNT(count_pcmd_op);
2603 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2608 COUNT(count_pcmd_op);
2609 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2618 case ICMD_INT2SHORT:
2619 COUNT(count_pcmd_op);
2620 OP1_1(TYPE_INT, TYPE_INT);
2623 COUNT(count_pcmd_op);
2624 OP1_1(TYPE_LNG, TYPE_LNG);
2627 COUNT(count_pcmd_op);
2628 OP1_1(TYPE_FLT, TYPE_FLT);
2631 COUNT(count_pcmd_op);
2632 OP1_1(TYPE_DBL, TYPE_DBL);
2636 COUNT(count_pcmd_op);
2637 OP1_1(TYPE_INT, TYPE_LNG);
2640 COUNT(count_pcmd_op);
2641 OP1_1(TYPE_INT, TYPE_FLT);
2644 COUNT(count_pcmd_op);
2645 OP1_1(TYPE_INT, TYPE_DBL);
2648 COUNT(count_pcmd_op);
2649 OP1_1(TYPE_LNG, TYPE_INT);
2652 COUNT(count_pcmd_op);
2653 OP1_1(TYPE_LNG, TYPE_FLT);
2656 COUNT(count_pcmd_op);
2657 OP1_1(TYPE_LNG, TYPE_DBL);
2660 COUNT(count_pcmd_op);
2661 OP1_1(TYPE_FLT, TYPE_INT);
2664 COUNT(count_pcmd_op);
2665 OP1_1(TYPE_FLT, TYPE_LNG);
2668 COUNT(count_pcmd_op);
2669 OP1_1(TYPE_FLT, TYPE_DBL);
2672 COUNT(count_pcmd_op);
2673 OP1_1(TYPE_DBL, TYPE_INT);
2676 COUNT(count_pcmd_op);
2677 OP1_1(TYPE_DBL, TYPE_LNG);
2680 COUNT(count_pcmd_op);
2681 OP1_1(TYPE_DBL, TYPE_FLT);
2684 case ICMD_CHECKCAST:
2685 coalescing_boundary = sd.new;
2686 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2687 /* array type cast-check */
2689 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2692 if (md->memuse > rd->memuse)
2693 rd->memuse = md->memuse;
2694 if (md->argintreguse > rd->argintreguse)
2695 rd->argintreguse = md->argintreguse;
2697 /* make all stack variables saved */
2701 sd.var[copy->varnum].flags |= SAVEDVAR;
2702 copy->flags |= SAVEDVAR;
2706 OP1_1(TYPE_ADR, TYPE_ADR);
2709 case ICMD_INSTANCEOF:
2710 case ICMD_ARRAYLENGTH:
2711 coalescing_boundary = sd.new;
2712 OP1_1(TYPE_ADR, TYPE_INT);
2716 case ICMD_ANEWARRAY:
2717 coalescing_boundary = sd.new;
2718 OP1_1(TYPE_INT, TYPE_ADR);
2722 coalescing_boundary = sd.new;
2723 COUNT(count_check_null);
2724 COUNT(count_pcmd_mem);
2725 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2726 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2731 case ICMD_GETSTATIC:
2732 coalescing_boundary = sd.new;
2733 COUNT(count_pcmd_mem);
2734 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2735 OP0_1(fmiref->parseddesc.fd->type);
2739 coalescing_boundary = sd.new;
2746 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2748 tbptr->type = BBTYPE_SBR;
2750 /* We need to check for overflow right here because
2751 * the pushed value is poped afterwards */
2754 /* calculate stack after return */
2759 /* pop many push any */
2763 bte = iptr->sx.s23.s3.bte;
2767 case ICMD_INVOKESTATIC:
2768 case ICMD_INVOKESPECIAL:
2769 case ICMD_INVOKEVIRTUAL:
2770 case ICMD_INVOKEINTERFACE:
2771 COUNT(count_pcmd_met);
2773 /* Check for functions to replace with builtin
2776 if (builtintable_replace_function(iptr))
2779 INSTRUCTION_GET_METHODDESC(iptr, md);
2780 /* XXX resurrect this COUNT? */
2781 /* if (lm->flags & ACC_STATIC) */
2782 /* {COUNT(count_check_null);} */
2786 coalescing_boundary = sd.new;
2790 if (md->memuse > rd->memuse)
2791 rd->memuse = md->memuse;
2792 if (md->argintreguse > rd->argintreguse)
2793 rd->argintreguse = md->argintreguse;
2794 if (md->argfltreguse > rd->argfltreguse)
2795 rd->argfltreguse = md->argfltreguse;
2799 /* XXX optimize for <= 2 args */
2800 /* XXX not for ICMD_BUILTIN */
2801 iptr->s1.argcount = stackdepth;
2802 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2805 for (i-- ; i >= 0; i--) {
2806 iptr->sx.s23.s2.args[i] = copy->varnum;
2808 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2809 /* -> won't help anyway */
2810 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2812 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2813 /* If we pass float arguments in integer argument registers, we
2814 * are not allowed to precolor them here. Floats have to be moved
2815 * to this regs explicitly in codegen().
2816 * Only arguments that are passed by stack anyway can be precolored
2817 * (michi 2005/07/24) */
2818 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
2819 (!IS_FLT_DBL_TYPE(copy->type)
2820 || md->params[i].inmemory)) {
2822 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
2827 #if defined(ENABLE_INTRP)
2830 if (md->params[i].inmemory) {
2831 sd.var[copy->varnum].regoff =
2832 md->params[i].regoff;
2833 sd.var[copy->varnum].flags |=
2837 if (IS_FLT_DBL_TYPE(copy->type)) {
2838 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2839 assert(0); /* XXX is this assert ok? */
2841 sd.var[copy->varnum].regoff =
2842 rd->argfltregs[md->params[i].regoff];
2843 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2846 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2847 if (IS_2_WORD_TYPE(copy->type))
2848 sd.var[copy->varnum].regoff =
2849 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2850 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2853 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2854 sd.var[copy->varnum].regoff =
2855 rd->argintregs[md->params[i].regoff];
2858 #if defined(ENABLE_INTRP)
2859 } /* end if (!opt_intrp) */
2866 /* deal with live-through stack slots "under" the */
2868 /* XXX not for ICMD_BUILTIN */
2874 iptr->sx.s23.s2.args[i++] = copy->varnum;
2875 sd.var[copy->varnum].flags |= SAVEDVAR;
2879 /* pop the arguments */
2888 /* push the return value */
2890 if (md->returntype.type != TYPE_VOID) {
2891 GET_NEW_VAR(sd, new_index, md->returntype.type);
2892 DST(md->returntype.type, new_index);
2897 case ICMD_INLINE_START:
2898 case ICMD_INLINE_END:
2903 case ICMD_MULTIANEWARRAY:
2904 coalescing_boundary = sd.new;
2905 if (rd->argintreguse < 3)
2906 rd->argintreguse = 3;
2908 i = iptr->s1.argcount;
2912 iptr->sx.s23.s2.args = DMNEW(s4, i);
2914 #if defined(SPECIALMEMUSE)
2915 # if defined(__DARWIN__)
2916 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
2917 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
2919 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
2920 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
2923 # if defined(__I386__)
2924 if (rd->memuse < i + 3)
2925 rd->memuse = i + 3; /* n integer args spilled on stack */
2926 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2927 if (rd->memuse < i + 2)
2928 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2931 rd->memuse = i; /* n integer args spilled on stack */
2932 # endif /* defined(__I386__) */
2936 /* check INT type here? Currently typecheck does this. */
2937 iptr->sx.s23.s2.args[i] = copy->varnum;
2938 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
2939 && (!IS_OUTVAR(copy))
2940 && (!IS_LOCALVAR(copy)) ) {
2941 copy->varkind = ARGVAR;
2942 sd.var[copy->varnum].flags |=
2943 INMEMORY & PREALLOC;
2944 #if defined(SPECIALMEMUSE)
2945 # if defined(__DARWIN__)
2946 sd.var[copy->varnum].regoff = i +
2947 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
2949 sd.var[copy->varnum].regoff = i +
2950 LA_SIZE_IN_POINTERS + 3;
2953 # if defined(__I386__)
2954 sd.var[copy->varnum].regoff = i + 3;
2955 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2956 sd.var[copy->varnum].regoff = i + 2;
2958 sd.var[copy->varnum].regoff = i;
2959 # endif /* defined(__I386__) */
2960 #endif /* defined(SPECIALMEMUSE) */
2965 sd.var[copy->varnum].flags |= SAVEDVAR;
2969 i = iptr->s1.argcount;
2974 GET_NEW_VAR(sd, new_index, TYPE_ADR);
2975 DST(TYPE_ADR, new_index);
2981 new_internalerror("Unknown ICMD %d", opcode);
2987 } /* while instructions */
2989 /* stack slots at basic block end become interfaces */
2991 sd.bptr->outstack = curstack;
2992 sd.bptr->outdepth = stackdepth;
2993 sd.bptr->outvars = DMNEW(s4, stackdepth);
2996 for (copy = curstack; copy; i--, copy = copy->prev) {
2999 /* with the new vars rd->interfaces will be removed */
3000 /* and all in and outvars have to be STACKVARS! */
3001 /* in the moment i.e. SWAP with in and out vars can */
3002 /* create an unresolvable conflict */
3006 v = sd.var + copy->varnum;
3009 if (jd->interface_map[i*5 + copy->type].flags == UNUSED) {
3010 /* no interface var until now for this depth and */
3012 jd->interface_map[i*5 + copy->type].flags = v->flags;
3015 jd->interface_map[i*5 + copy->type].flags |= v->flags;
3018 sd.bptr->outvars[i] = copy->varnum;
3021 /* check if interface slots at basic block begin must be saved */
3023 for (i=0; i<sd.bptr->indepth; ++i) {
3024 varinfo *v = sd.var + sd.bptr->invars[i];
3026 if (jd->interface_map[i*5 + v->type].flags == UNUSED) {
3027 /* no interface var until now for this depth and */
3029 jd->interface_map[i*5 + v->type].flags = v->flags;
3032 jd->interface_map[i*5 + v->type].flags |= v->flags;
3037 #if defined(STACK_VERBOSE)
3038 printf("OUTVARS\n");
3039 for( copy = sd.bptr->outstack; copy; copy = copy->prev ) {
3040 printf("%2d(%d", copy->varnum, copy->type);
3041 if (IS_OUTVAR(copy))
3043 if (IS_PREALLOC(copy))
3051 superblockend = true;
3054 } /* while blocks */
3055 } while (repeat && !deadcode);
3057 /* gather statistics *****************************************************/
3059 #if defined(ENABLE_STATISTICS)
3061 if (jd->new_basicblockcount > count_max_basic_blocks)
3062 count_max_basic_blocks = jd->new_basicblockcount;
3063 count_basic_blocks += jd->new_basicblockcount;
3064 if (jd->new_instructioncount > count_max_javainstr)
3065 count_max_javainstr = jd->new_instructioncount;
3066 count_javainstr += jd->new_instructioncount;
3067 if (jd->new_stackcount > count_upper_bound_new_stack)
3068 count_upper_bound_new_stack = jd->new_stackcount;
3069 if ((sd.new - jd->new_stack) > count_max_new_stack)
3070 count_max_new_stack = (sd.new - jd->new_stack);
3072 b_count = jd->new_basicblockcount;
3073 sd.bptr = jd->new_basicblocks;
3074 while (--b_count >= 0) {
3075 if (sd.bptr->flags > BBREACHED) {
3076 if (sd.bptr->indepth >= 10)
3077 count_block_stack[10]++;
3079 count_block_stack[sd.bptr->indepth]++;
3080 len = sd.bptr->icount;
3082 count_block_size_distribution[len]++;
3084 count_block_size_distribution[10]++;
3086 count_block_size_distribution[11]++;
3088 count_block_size_distribution[12]++;
3090 count_block_size_distribution[13]++;
3092 count_block_size_distribution[14]++;
3094 count_block_size_distribution[15]++;
3096 count_block_size_distribution[16]++;
3098 count_block_size_distribution[17]++;
3103 if (iteration_count == 1)
3104 count_analyse_iterations[0]++;
3105 else if (iteration_count == 2)
3106 count_analyse_iterations[1]++;
3107 else if (iteration_count == 3)
3108 count_analyse_iterations[2]++;
3109 else if (iteration_count == 4)
3110 count_analyse_iterations[3]++;
3112 count_analyse_iterations[4]++;
3114 if (jd->new_basicblockcount <= 5)
3115 count_method_bb_distribution[0]++;
3116 else if (jd->new_basicblockcount <= 10)
3117 count_method_bb_distribution[1]++;
3118 else if (jd->new_basicblockcount <= 15)
3119 count_method_bb_distribution[2]++;
3120 else if (jd->new_basicblockcount <= 20)
3121 count_method_bb_distribution[3]++;
3122 else if (jd->new_basicblockcount <= 30)
3123 count_method_bb_distribution[4]++;
3124 else if (jd->new_basicblockcount <= 40)
3125 count_method_bb_distribution[5]++;
3126 else if (jd->new_basicblockcount <= 50)
3127 count_method_bb_distribution[6]++;
3128 else if (jd->new_basicblockcount <= 75)
3129 count_method_bb_distribution[7]++;
3131 count_method_bb_distribution[8]++;
3133 #endif /* defined(ENABLE_STATISTICS) */
3135 /* everything's ok *******************************************************/
3139 /* goto labels for throwing verifier exceptions **************************/
3141 #if defined(ENABLE_VERIFIER)
3143 throw_stack_underflow:
3144 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3147 throw_stack_overflow:
3148 exceptions_throw_verifyerror(m, "Stack size too large");
3151 throw_stack_depth_error:
3152 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3155 throw_stack_type_error:
3156 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3159 throw_stack_category_error:
3160 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3168 * These are local overrides for various environment variables in Emacs.
3169 * Please do not remove this and leave it at the end of the file, where
3170 * Emacs will automagically detect them.
3171 * ---------------------------------------------------------------------
3174 * indent-tabs-mode: t
3178 * vim:noexpandtab:sw=4:ts=4: