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 5463 2006-09-11 14:37:06Z 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;
126 /* macros for allocating/releasing variable indices */
128 #define GET_NEW_INDEX(sd, new_varindex) \
130 assert((sd).vartop < (sd).varcount); \
131 (new_varindex) = ((sd).vartop)++; \
134 /* not implemented now, can be used to reuse varindices */
135 /* pay attention to not release a localvar once implementing it! */
136 #define RELEASE_INDEX(sd, varindex)
138 #define GET_NEW_VAR(sd, new_varindex, newtype) \
140 GET_NEW_INDEX((sd), (new_varindex)); \
141 (sd).var[new_index].type = (newtype); \
144 /* macros for querying variable properties **************************/
146 #define IS_OUTVAR(sp) \
147 (sd.var[(sp)->varnum].flags & OUTVAR)
149 #define IS_PREALLOC(sp) \
150 (sd.var[(sp)->varnum].flags & PREALLOC)
152 #define IS_TEMPVAR(sp) \
153 ( ((sp)->varnum >= sd.localcount) \
154 && !(sd.var[(sp)->varnum].flags & (OUTVAR | PREALLOC)) )
156 #define IS_LOCALVAR_SD(sd, sp) \
157 ((sp)->varnum < (sd).localcount)
159 #define IS_LOCALVAR(sp) \
160 IS_LOCALVAR_SD(sd, (sp))
163 /* macros for setting variable properties ****************************/
165 #define SET_TEMPVAR(sp) \
167 if (IS_LOCALVAR((sp))) { \
168 GET_NEW_VAR(sd, new_index, (sp)->type); \
169 sd.var[new_index].flags = (sp)->flags; \
170 (sp)->varnum = new_index; \
171 (sp)->varkind = TEMPVAR; \
173 (sp)->creator->dst.varindex = new_index; \
175 sd.var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC); \
178 #define SET_PREALLOC(sp) \
180 assert(!IS_LOCALVAR((sp))); \
181 sd.var[(sp)->varnum].flags |= PREALLOC; \
184 /* macros for source operands ***************************************/
187 (iptr->s1.varindex = -1)
189 #define USE_S1_LOCAL(type1)
191 #define USE_S1(type1) \
194 CHECK_BASIC_TYPE(type1, curstack->type); \
195 iptr->s1.varindex = curstack->varnum; \
201 iptr->s1.varindex = curstack->varnum; \
204 #define USE_S1_S2(type1, type2) \
207 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
208 CHECK_BASIC_TYPE(type2, curstack->type); \
209 iptr->sx.s23.s2.varindex = curstack->varnum; \
210 iptr->s1.varindex = curstack->prev->varnum; \
213 #define USE_S1_S2_ANY_ANY \
216 iptr->sx.s23.s2.varindex = curstack->varnum; \
217 iptr->s1.varindex = curstack->prev->varnum; \
220 #define USE_S1_S2_S3(type1, type2, type3) \
223 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
224 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
225 CHECK_BASIC_TYPE(type3, curstack->type); \
226 iptr->sx.s23.s3.varindex = curstack->varnum; \
227 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
228 iptr->s1.varindex = curstack->prev->prev->varnum; \
231 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
234 if (curstack->varkind == UNDEFVAR) \
235 curstack->varkind = TEMPVAR; \
236 curstack = curstack->prev; \
239 #define POP_S1(type1) \
242 if (curstack->varkind == UNDEFVAR) \
243 curstack->varkind = TEMPVAR; \
244 curstack = curstack->prev; \
250 if (curstack->varkind == UNDEFVAR) \
251 curstack->varkind = TEMPVAR; \
252 curstack = curstack->prev; \
255 #define POP_S1_S2(type1, type2) \
257 USE_S1_S2(type1, type2); \
258 if (curstack->varkind == UNDEFVAR) \
259 curstack->varkind = TEMPVAR; \
260 if (curstack->prev->varkind == UNDEFVAR) \
261 curstack->prev->varkind = TEMPVAR; \
262 curstack = curstack->prev->prev; \
265 #define POP_S1_S2_ANY_ANY \
268 if (curstack->varkind == UNDEFVAR) \
269 curstack->varkind = TEMPVAR; \
270 if (curstack->prev->varkind == UNDEFVAR) \
271 curstack->prev->varkind = TEMPVAR; \
272 curstack = curstack->prev->prev; \
275 #define POP_S1_S2_S3(type1, type2, type3) \
277 USE_S1_S2_S3(type1, type2, type3); \
278 if (curstack->varkind == UNDEFVAR) \
279 curstack->varkind = TEMPVAR; \
280 if (curstack->prev->varkind == UNDEFVAR) \
281 curstack->prev->varkind = TEMPVAR; \
282 if (curstack->prev->prev->varkind == UNDEFVAR) \
283 curstack->prev->prev->varkind = TEMPVAR; \
284 curstack = curstack->prev->prev->prev; \
291 /* macros for setting the destination operand ***********************/
294 (iptr->dst.varindex = -1)
296 #define DST(typed, index) \
298 NEWSTACKn((typed),(index)); \
299 curstack->creator = iptr; \
300 iptr->dst.varindex = (index); \
303 #define DST_LOCALVAR(typed, index) \
305 NEWSTACK((typed), LOCALVAR, (index)); \
306 curstack->creator = iptr; \
307 iptr->dst.varindex = (index); \
311 /* stack modelling macros *******************************************/
313 #define OP0_1(typed) \
316 GET_NEW_VAR(sd, new_index, (typed)); \
317 DST(typed, new_index); \
328 #define OP1_BRANCH(type1) \
334 #define OP1_1(type1, typed) \
337 GET_NEW_VAR(sd, new_index, (typed)); \
338 DST(typed, new_index); \
341 #define OP2_1(type1, type2, typed) \
343 POP_S1_S2(type1, type2); \
344 GET_NEW_VAR(sd, new_index, (typed)); \
345 DST(typed, new_index); \
360 #define OP1_0(type1) \
367 #define OP2_0(type1, type2) \
369 POP_S1_S2(type1, type2); \
374 #define OP2_BRANCH(type1, type2) \
376 POP_S1_S2(type1, type2); \
380 #define OP2_0_ANY_ANY \
387 #define OP3_0(type1, type2, type3) \
389 POP_S1_S2_S3(type1, type2, type3); \
394 #define LOAD(type1, index) \
396 DST_LOCALVAR(type1, index); \
400 #define STORE(type1, index) \
407 /* macros for DUP elimination ***************************************/
409 #define DUP_SLOT(sp) \
411 GET_NEW_VAR(sd, new_index, (sp)->type); \
412 NEWSTACK((sp)->type, TEMPVAR, new_index); \
415 /* does not check input stackdepth */
416 #define MOVE_UP(sp) \
418 iptr->opc = ICMD_MOVE; \
419 iptr->s1.varindex = (sp)->varnum; \
421 curstack->creator = iptr; \
422 iptr->dst.varindex = curstack->varnum; \
426 /* does not check input stackdepth */
427 #define COPY_UP(sp) \
430 iptr->opc = ICMD_COPY; \
431 iptr->s1.varindex = (sp)->varnum; \
433 curstack->creator = iptr; \
434 iptr->dst.varindex = curstack->varnum; \
438 #define COPY_DOWN(s, d) \
441 iptr->opc = ICMD_COPY; \
442 iptr->s1.varindex = (s)->varnum; \
443 iptr->dst.varindex = (d)->varnum; \
444 (d)->creator = iptr; \
448 /* macros for branching / reaching basic blocks *********************/
450 #if defined(ENABLE_VERIFIER)
451 #define MARKREACHED(b, c) \
453 if (!stack_mark_reached(&sd, (b), curstack, stackdepth)) \
457 #define MARKREACHED(b, c) \
459 (void) stack_mark_reached(&sd, (b), curstack, stackdepth); \
463 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
465 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
466 MARKREACHED(tempbptr, tempsp); \
469 #define BRANCH(tempbptr, tempsp) \
471 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
472 MARKREACHED(tempbptr, tempsp); \
476 /* stack_init ******************************************************************
478 Initialized the stack analysis subsystem (called by jit_init).
480 *******************************************************************************/
482 bool stack_init(void)
488 /* stack_create_invars *********************************************************
490 Create the invars for the given basic block.
493 sd...........stack analysis data
494 b............block to create the invars for
495 curstack.....current stack top
496 stackdepth...current stack depth
498 This function creates STACKDEPTH invars and sets their types to the
499 types to the types of the corresponding slot in the current stack.
501 *******************************************************************************/
503 static void stack_create_invars(stackdata_t *sd, basicblock *b,
504 stackptr curstack, int stackdepth)
511 assert(sd->vartop + stackdepth <= sd->varcount);
513 b->indepth = stackdepth;
514 b->invars = DMNEW(s4, stackdepth);
516 /* allocate the variable indices */
517 index = (sd->vartop += stackdepth);
520 for (sp = curstack; i--; sp = sp->prev) {
521 b->invars[i] = --index;
529 /* stack_check_invars **********************************************************
531 Check the current stack against the invars of the given basic block.
532 Depth and types must match.
535 sd...........stack analysis data
536 b............block which invars to check against
537 curstack.....current stack top
538 stackdepth...current stack depth
541 true.........everything ok
542 false........a VerifyError has been thrown
544 *******************************************************************************/
546 /* XXX only if ENABLE_VERIFIER */
547 static bool stack_check_invars(stackdata_t *sd, basicblock *b,
548 stackptr curstack, int stackdepth)
554 if (depth != stackdepth) {
555 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
560 if (sd->var[b->invars[depth]].type != curstack->type) {
561 exceptions_throw_verifyerror_for_stack(sd->m,
562 sd->var[b->invars[depth]].type);
565 curstack = curstack->prev;
572 /* stack_create_instack ********************************************************
574 Create the instack of the current basic block.
577 sd...........stack analysis data
580 the current stack top at the start of the basic block.
582 *******************************************************************************/
584 static stackptr stack_create_instack(stackdata_t *sd)
590 if ((depth = sd->bptr->indepth) == 0)
593 sp = (sd->new += depth);
597 index = sd->bptr->invars[depth];
599 sp->type = sd->var[index].type;
603 sp->varkind = STACKVAR;
607 /* return the top of the created stack */
612 /* MARKREACHED marks the destination block <b> as reached. If this
613 * block has been reached before we check if stack depth and types
614 * match. Otherwise the destination block receives a copy of the
615 * current stack as its input stack.
617 * b...destination block
621 static bool stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
623 /* mark targets of backward branches */
625 b->bitflags |= BBFLAG_REPLACEMENT;
627 if (b->flags < BBREACHED) {
628 /* b is reached for the first time. Create its instack */
629 stack_create_invars(sd, b, curstack, stackdepth);
631 b->flags = BBREACHED;
634 /* b has been reached before. Check that its instack matches */
635 if (!stack_check_invars(sd, b, curstack, stackdepth))
643 /* stack_analyse ***************************************************************
645 Analyse_stack uses the intermediate code created by parse.c to
646 build a model of the JVM operand stack for the current method.
648 The following checks are performed:
649 - check for operand stack underflow (before each instruction)
650 - check for operand stack overflow (after[1] each instruction)
651 - check for matching stack depth at merging points
652 - check for matching basic types[2] at merging points
653 - check basic types for instruction input (except for BUILTIN*
654 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
656 [1]) Checking this after the instruction should be ok. parse.c
657 counts the number of required stack slots in such a way that it is
658 only vital that we don't exceed `maxstack` at basic block
661 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
662 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
663 types are not discerned.
665 *******************************************************************************/
667 bool new_stack_analyse(jitdata *jd)
669 methodinfo *m; /* method being analyzed */
674 int b_count; /* basic block counter */
675 int b_index; /* basic block index */
677 stackptr curstack; /* current stack top */
679 int opcode; /* opcode of current instruction */
682 int len; /* # of instructions after the current one */
683 bool superblockend; /* if true, no fallthrough to next block */
684 bool repeat; /* if true, outermost loop must run again */
685 bool deadcode; /* true if no live code has been reached */
686 instruction *iptr; /* the current instruction */
689 stackptr *last_store_boundary;
690 stackptr coalescing_boundary;
692 stackptr src1, src2, src3, src4, dst1, dst2;
694 branch_target_t *table;
695 lookup_target_t *lookup;
696 #if defined(ENABLE_VERIFIER)
697 int expectedtype; /* used by CHECK_BASIC_TYPE */
699 builtintable_entry *bte;
701 constant_FMIref *fmiref;
702 #if defined(ENABLE_STATISTICS)
703 int iteration_count; /* number of iterations of analysis */
705 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
707 #if defined(STACK_VERBOSE)
708 new_show_method(jd, SHOW_PARSE);
711 /* get required compiler data - initialization */
718 /* initialize the stackdata_t struct */
721 sd.varcount = jd->varcount;
722 sd.vartop = jd->vartop;
723 sd.localcount = jd->localcount;
726 #if defined(ENABLE_LSRA)
730 #if defined(ENABLE_STATISTICS)
734 /* init jd->interface_map */
736 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
737 for (i = 0; i < m->maxstack * 5; i++)
738 jd->interface_map[i].flags = UNUSED;
740 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
742 /* initialize flags and invars (none) of first block */
744 jd->new_basicblocks[0].flags = BBREACHED;
745 jd->new_basicblocks[0].invars = NULL;
746 jd->new_basicblocks[0].indepth = 0;
748 /* initialize invars of exception handlers */
750 for (i = 0; i < cd->exceptiontablelength; i++) {
751 sd.bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
752 sd.bptr->flags = BBREACHED;
753 sd.bptr->type = BBTYPE_EXH;
754 sd.bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
756 GET_NEW_VAR(sd, new_index, TYPE_ADR);
757 sd.bptr->invars = DMNEW(s4, 1);
758 sd.bptr->invars[0] = new_index;
759 sd.bptr->indepth = 1;
760 sd.var[new_index].flags |= OUTVAR;
762 /* mark this interface variable used */
763 jd->interface_map[0 * 5 + TYPE_ADR].flags = 0;
766 /* stack analysis loop (until fixpoint reached) **************************/
769 #if defined(ENABLE_STATISTICS)
773 /* initialize loop over basic blocks */
775 b_count = jd->new_basicblockcount;
776 sd.bptr = jd->new_basicblocks;
777 superblockend = true;
779 curstack = NULL; stackdepth = 0;
782 /* iterate over basic blocks *****************************************/
784 for (; --b_count >= 0; ++sd.bptr) {
786 #if defined(STACK_VERBOSE)
787 printf("----\nANALYZING BLOCK L%03d ", sd.bptr->nr);
788 if (sd.bptr->type == BBTYPE_EXH) printf("EXH\n");
789 else if (sd.bptr->type == BBTYPE_SBR) printf("SBR\n");
790 else printf("STD\n");
793 if (sd.bptr->flags == BBDELETED) {
794 /* This block has been deleted - do nothing. */
799 if (superblockend && (sd.bptr->flags < BBREACHED)) {
800 /* This block has not been reached so far, and we */
801 /* don't fall into it, so we'll have to iterate again. */
807 if (sd.bptr->flags > BBREACHED) {
808 /* This block is already finished. */
810 superblockend = true;
814 /* This block has to be analysed now. */
816 /* XXX The rest of this block is still indented one level too */
817 /* much in order to avoid a giant diff by changing that. */
820 /* We know that sd.bptr->flags == BBREACHED. */
821 /* This block has been reached before. */
823 stackdepth = sd.bptr->indepth;
825 else if (sd.bptr->flags < BBREACHED) {
826 /* This block is reached for the first time now */
827 /* by falling through from the previous block. */
828 /* Create the instack (propagated). */
830 stack_create_invars(&sd, sd.bptr, curstack, stackdepth);
833 /* This block has been reached before. now we are */
834 /* falling into it from the previous block. */
835 /* Check that stack depth is well-defined. */
837 if (!stack_check_invars(&sd, sd.bptr, curstack, stackdepth))
841 /* reset the new pointer for allocating stackslots */
843 sd.new = jd->new_stack;
845 /* create the instack of this block */
847 curstack = stack_create_instack(&sd);
849 /* set up local variables for analyzing this block */
852 superblockend = false;
853 len = sd.bptr->icount;
854 iptr = sd.bptr->iinstr;
855 b_index = sd.bptr - jd->new_basicblocks;
857 /* mark the block as analysed */
859 sd.bptr->flags = BBFINISHED;
861 /* reset variables for dependency checking */
863 coalescing_boundary = sd.new;
864 for( i = 0; i < cd->maxlocals; i++)
865 last_store_boundary[i] = sd.new;
867 /* remember the start of this block's variables */
869 sd.bptr->varstart = sd.vartop;
871 #if defined(STACK_VERBOSE)
872 printf("INVARS - indices:\t\n");
873 for (i=0; i<sd.bptr->indepth; ++i) {
874 printf("%d ", sd.bptr->invars[i]);
879 /* iterate over ICMDs ****************************************/
883 #if defined(STACK_VERBOSE)
884 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
885 for( copy = curstack; copy; copy = copy->prev ) {
886 printf("%2d(%d", copy->varnum, copy->type);
889 if (IS_PREALLOC(copy))
896 /* fetch the current opcode */
900 /* automatically replace some ICMDs with builtins */
902 #if defined(USEBUILTINTABLE)
904 bte = builtintable_get_automatic(opcode);
906 if (bte && bte->opcode == opcode) {
907 iptr->opc = ICMD_BUILTIN;
908 iptr->flags.bits = 0;
909 iptr->sx.s23.s3.bte = bte;
910 /* iptr->line is already set */
911 jd->isleafmethod = false;
915 #endif /* defined(USEBUILTINTABLE) */
917 /* main opcode switch *************************************/
930 coalescing_boundary = sd.new;
931 COUNT(count_check_null);
934 CLR_DST; /* XXX live through? */
939 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
941 USE_S1_LOCAL(TYPE_ADR);
945 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
947 superblockend = true;
951 COUNT(count_pcmd_return);
954 superblockend = true;
958 /* pop 0 push 1 const */
960 /************************** ICONST OPTIMIZATIONS **************************/
963 COUNT(count_pcmd_load);
967 switch (iptr[1].opc) {
969 iptr->opc = ICMD_IADDCONST;
973 iptr[1].opc = ICMD_NOP;
974 OP1_1(TYPE_INT, TYPE_INT);
975 COUNT(count_pcmd_op);
979 iptr->opc = ICMD_ISUBCONST;
980 goto icmd_iconst_tail;
981 #if SUPPORT_CONST_MUL
983 iptr->opc = ICMD_IMULCONST;
984 goto icmd_iconst_tail;
985 #else /* SUPPORT_CONST_MUL */
987 if (iptr->sx.val.i == 0x00000002)
989 else if (iptr->sx.val.i == 0x00000004)
991 else if (iptr->sx.val.i == 0x00000008)
993 else if (iptr->sx.val.i == 0x00000010)
995 else if (iptr->sx.val.i == 0x00000020)
997 else if (iptr->sx.val.i == 0x00000040)
999 else if (iptr->sx.val.i == 0x00000080)
1001 else if (iptr->sx.val.i == 0x00000100)
1003 else if (iptr->sx.val.i == 0x00000200)
1005 else if (iptr->sx.val.i == 0x00000400)
1006 iptr->sx.val.i = 10;
1007 else if (iptr->sx.val.i == 0x00000800)
1008 iptr->sx.val.i = 11;
1009 else if (iptr->sx.val.i == 0x00001000)
1010 iptr->sx.val.i = 12;
1011 else if (iptr->sx.val.i == 0x00002000)
1012 iptr->sx.val.i = 13;
1013 else if (iptr->sx.val.i == 0x00004000)
1014 iptr->sx.val.i = 14;
1015 else if (iptr->sx.val.i == 0x00008000)
1016 iptr->sx.val.i = 15;
1017 else if (iptr->sx.val.i == 0x00010000)
1018 iptr->sx.val.i = 16;
1019 else if (iptr->sx.val.i == 0x00020000)
1020 iptr->sx.val.i = 17;
1021 else if (iptr->sx.val.i == 0x00040000)
1022 iptr->sx.val.i = 18;
1023 else if (iptr->sx.val.i == 0x00080000)
1024 iptr->sx.val.i = 19;
1025 else if (iptr->sx.val.i == 0x00100000)
1026 iptr->sx.val.i = 20;
1027 else if (iptr->sx.val.i == 0x00200000)
1028 iptr->sx.val.i = 21;
1029 else if (iptr->sx.val.i == 0x00400000)
1030 iptr->sx.val.i = 22;
1031 else if (iptr->sx.val.i == 0x00800000)
1032 iptr->sx.val.i = 23;
1033 else if (iptr->sx.val.i == 0x01000000)
1034 iptr->sx.val.i = 24;
1035 else if (iptr->sx.val.i == 0x02000000)
1036 iptr->sx.val.i = 25;
1037 else if (iptr->sx.val.i == 0x04000000)
1038 iptr->sx.val.i = 26;
1039 else if (iptr->sx.val.i == 0x08000000)
1040 iptr->sx.val.i = 27;
1041 else if (iptr->sx.val.i == 0x10000000)
1042 iptr->sx.val.i = 28;
1043 else if (iptr->sx.val.i == 0x20000000)
1044 iptr->sx.val.i = 29;
1045 else if (iptr->sx.val.i == 0x40000000)
1046 iptr->sx.val.i = 30;
1047 else if (iptr->sx.val.i == 0x80000000)
1048 iptr->sx.val.i = 31;
1052 iptr->opc = ICMD_IMULPOW2;
1053 goto icmd_iconst_tail;
1054 #endif /* SUPPORT_CONST_MUL */
1056 if (iptr->sx.val.i == 0x00000002)
1058 else if (iptr->sx.val.i == 0x00000004)
1060 else if (iptr->sx.val.i == 0x00000008)
1062 else if (iptr->sx.val.i == 0x00000010)
1064 else if (iptr->sx.val.i == 0x00000020)
1066 else if (iptr->sx.val.i == 0x00000040)
1068 else if (iptr->sx.val.i == 0x00000080)
1070 else if (iptr->sx.val.i == 0x00000100)
1072 else if (iptr->sx.val.i == 0x00000200)
1074 else if (iptr->sx.val.i == 0x00000400)
1075 iptr->sx.val.i = 10;
1076 else if (iptr->sx.val.i == 0x00000800)
1077 iptr->sx.val.i = 11;
1078 else if (iptr->sx.val.i == 0x00001000)
1079 iptr->sx.val.i = 12;
1080 else if (iptr->sx.val.i == 0x00002000)
1081 iptr->sx.val.i = 13;
1082 else if (iptr->sx.val.i == 0x00004000)
1083 iptr->sx.val.i = 14;
1084 else if (iptr->sx.val.i == 0x00008000)
1085 iptr->sx.val.i = 15;
1086 else if (iptr->sx.val.i == 0x00010000)
1087 iptr->sx.val.i = 16;
1088 else if (iptr->sx.val.i == 0x00020000)
1089 iptr->sx.val.i = 17;
1090 else if (iptr->sx.val.i == 0x00040000)
1091 iptr->sx.val.i = 18;
1092 else if (iptr->sx.val.i == 0x00080000)
1093 iptr->sx.val.i = 19;
1094 else if (iptr->sx.val.i == 0x00100000)
1095 iptr->sx.val.i = 20;
1096 else if (iptr->sx.val.i == 0x00200000)
1097 iptr->sx.val.i = 21;
1098 else if (iptr->sx.val.i == 0x00400000)
1099 iptr->sx.val.i = 22;
1100 else if (iptr->sx.val.i == 0x00800000)
1101 iptr->sx.val.i = 23;
1102 else if (iptr->sx.val.i == 0x01000000)
1103 iptr->sx.val.i = 24;
1104 else if (iptr->sx.val.i == 0x02000000)
1105 iptr->sx.val.i = 25;
1106 else if (iptr->sx.val.i == 0x04000000)
1107 iptr->sx.val.i = 26;
1108 else if (iptr->sx.val.i == 0x08000000)
1109 iptr->sx.val.i = 27;
1110 else if (iptr->sx.val.i == 0x10000000)
1111 iptr->sx.val.i = 28;
1112 else if (iptr->sx.val.i == 0x20000000)
1113 iptr->sx.val.i = 29;
1114 else if (iptr->sx.val.i == 0x40000000)
1115 iptr->sx.val.i = 30;
1116 else if (iptr->sx.val.i == 0x80000000)
1117 iptr->sx.val.i = 31;
1121 iptr->opc = ICMD_IDIVPOW2;
1122 goto icmd_iconst_tail;
1125 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
1126 if ((iptr->sx.val.i == 0x00000002) ||
1127 (iptr->sx.val.i == 0x00000004) ||
1128 (iptr->sx.val.i == 0x00000008) ||
1129 (iptr->sx.val.i == 0x00000010) ||
1130 (iptr->sx.val.i == 0x00000020) ||
1131 (iptr->sx.val.i == 0x00000040) ||
1132 (iptr->sx.val.i == 0x00000080) ||
1133 (iptr->sx.val.i == 0x00000100) ||
1134 (iptr->sx.val.i == 0x00000200) ||
1135 (iptr->sx.val.i == 0x00000400) ||
1136 (iptr->sx.val.i == 0x00000800) ||
1137 (iptr->sx.val.i == 0x00001000) ||
1138 (iptr->sx.val.i == 0x00002000) ||
1139 (iptr->sx.val.i == 0x00004000) ||
1140 (iptr->sx.val.i == 0x00008000) ||
1141 (iptr->sx.val.i == 0x00010000) ||
1142 (iptr->sx.val.i == 0x00020000) ||
1143 (iptr->sx.val.i == 0x00040000) ||
1144 (iptr->sx.val.i == 0x00080000) ||
1145 (iptr->sx.val.i == 0x00100000) ||
1146 (iptr->sx.val.i == 0x00200000) ||
1147 (iptr->sx.val.i == 0x00400000) ||
1148 (iptr->sx.val.i == 0x00800000) ||
1149 (iptr->sx.val.i == 0x01000000) ||
1150 (iptr->sx.val.i == 0x02000000) ||
1151 (iptr->sx.val.i == 0x04000000) ||
1152 (iptr->sx.val.i == 0x08000000) ||
1153 (iptr->sx.val.i == 0x10000000) ||
1154 (iptr->sx.val.i == 0x20000000) ||
1155 (iptr->sx.val.i == 0x40000000) ||
1156 (iptr->sx.val.i == 0x80000000))
1158 iptr->opc = ICMD_IREMPOW2;
1159 iptr->sx.val.i -= 1;
1160 goto icmd_iconst_tail;
1163 #if SUPPORT_CONST_LOGICAL
1165 iptr->opc = ICMD_IANDCONST;
1166 goto icmd_iconst_tail;
1169 iptr->opc = ICMD_IORCONST;
1170 goto icmd_iconst_tail;
1173 iptr->opc = ICMD_IXORCONST;
1174 goto icmd_iconst_tail;
1176 #endif /* SUPPORT_CONST_LOGICAL */
1178 iptr->opc = ICMD_ISHLCONST;
1179 goto icmd_iconst_tail;
1182 iptr->opc = ICMD_ISHRCONST;
1183 goto icmd_iconst_tail;
1186 iptr->opc = ICMD_IUSHRCONST;
1187 goto icmd_iconst_tail;
1188 #if SUPPORT_LONG_SHIFT
1190 iptr->opc = ICMD_LSHLCONST;
1191 goto icmd_lconst_tail;
1194 iptr->opc = ICMD_LSHRCONST;
1195 goto icmd_lconst_tail;
1198 iptr->opc = ICMD_LUSHRCONST;
1199 goto icmd_lconst_tail;
1200 #endif /* SUPPORT_LONG_SHIFT */
1201 case ICMD_IF_ICMPEQ:
1202 iptr[1].opc = ICMD_IFEQ;
1206 /* set the constant for the following icmd */
1207 iptr[1].sx.val.i = iptr->sx.val.i;
1209 /* this instruction becomes a nop */
1210 iptr->opc = ICMD_NOP;
1213 case ICMD_IF_ICMPLT:
1214 iptr[1].opc = ICMD_IFLT;
1215 goto icmd_if_icmp_tail;
1217 case ICMD_IF_ICMPLE:
1218 iptr[1].opc = ICMD_IFLE;
1219 goto icmd_if_icmp_tail;
1221 case ICMD_IF_ICMPNE:
1222 iptr[1].opc = ICMD_IFNE;
1223 goto icmd_if_icmp_tail;
1225 case ICMD_IF_ICMPGT:
1226 iptr[1].opc = ICMD_IFGT;
1227 goto icmd_if_icmp_tail;
1229 case ICMD_IF_ICMPGE:
1230 iptr[1].opc = ICMD_IFGE;
1231 goto icmd_if_icmp_tail;
1233 #if SUPPORT_CONST_STORE
1238 IF_INTRP( goto normal_ICONST; )
1239 # if SUPPORT_CONST_STORE_ZERO_ONLY
1240 if (iptr->sx.val.i != 0)
1243 switch (iptr[1].opc) {
1245 iptr->opc = ICMD_IASTORECONST;
1246 iptr->flags.bits |= INS_FLAG_CHECK;
1249 iptr->opc = ICMD_BASTORECONST;
1250 iptr->flags.bits |= INS_FLAG_CHECK;
1253 iptr->opc = ICMD_CASTORECONST;
1254 iptr->flags.bits |= INS_FLAG_CHECK;
1257 iptr->opc = ICMD_SASTORECONST;
1258 iptr->flags.bits |= INS_FLAG_CHECK;
1262 iptr[1].opc = ICMD_NOP;
1264 /* copy the constant to s3 */
1265 /* XXX constval -> astoreconstval? */
1266 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1267 OP2_0(TYPE_ADR, TYPE_INT);
1268 COUNT(count_pcmd_op);
1271 case ICMD_PUTSTATIC:
1273 IF_INTRP( goto normal_ICONST; )
1274 # if SUPPORT_CONST_STORE_ZERO_ONLY
1275 if (iptr->sx.val.i != 0)
1278 /* XXX check field type? */
1280 /* copy the constant to s2 */
1281 /* XXX constval -> fieldconstval? */
1282 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1285 /* set the field reference (s3) */
1286 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1287 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1288 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1291 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1294 switch (iptr[1].opc) {
1295 case ICMD_PUTSTATIC:
1296 iptr->opc = ICMD_PUTSTATICCONST;
1300 iptr->opc = ICMD_PUTFIELDCONST;
1305 iptr[1].opc = ICMD_NOP;
1306 COUNT(count_pcmd_op);
1308 #endif /* SUPPORT_CONST_STORE */
1314 /* if we get here, the ICONST has been optimized */
1318 /* normal case of an unoptimized ICONST */
1322 /************************** LCONST OPTIMIZATIONS **************************/
1325 COUNT(count_pcmd_load);
1329 /* switch depending on the following instruction */
1331 switch (iptr[1].opc) {
1332 #if SUPPORT_LONG_ADD
1334 iptr->opc = ICMD_LADDCONST;
1338 /* instruction of type LONG -> LONG */
1339 iptr[1].opc = ICMD_NOP;
1340 OP1_1(TYPE_LNG, TYPE_LNG);
1341 COUNT(count_pcmd_op);
1345 iptr->opc = ICMD_LSUBCONST;
1346 goto icmd_lconst_tail;
1348 #endif /* SUPPORT_LONG_ADD */
1349 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1351 iptr->opc = ICMD_LMULCONST;
1352 goto icmd_lconst_tail;
1353 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1354 # if SUPPORT_LONG_SHIFT
1356 if (iptr->sx.val.l == 0x00000002)
1358 else if (iptr->sx.val.l == 0x00000004)
1360 else if (iptr->sx.val.l == 0x00000008)
1362 else if (iptr->sx.val.l == 0x00000010)
1364 else if (iptr->sx.val.l == 0x00000020)
1366 else if (iptr->sx.val.l == 0x00000040)
1368 else if (iptr->sx.val.l == 0x00000080)
1370 else if (iptr->sx.val.l == 0x00000100)
1372 else if (iptr->sx.val.l == 0x00000200)
1374 else if (iptr->sx.val.l == 0x00000400)
1375 iptr->sx.val.i = 10;
1376 else if (iptr->sx.val.l == 0x00000800)
1377 iptr->sx.val.i = 11;
1378 else if (iptr->sx.val.l == 0x00001000)
1379 iptr->sx.val.i = 12;
1380 else if (iptr->sx.val.l == 0x00002000)
1381 iptr->sx.val.i = 13;
1382 else if (iptr->sx.val.l == 0x00004000)
1383 iptr->sx.val.i = 14;
1384 else if (iptr->sx.val.l == 0x00008000)
1385 iptr->sx.val.i = 15;
1386 else if (iptr->sx.val.l == 0x00010000)
1387 iptr->sx.val.i = 16;
1388 else if (iptr->sx.val.l == 0x00020000)
1389 iptr->sx.val.i = 17;
1390 else if (iptr->sx.val.l == 0x00040000)
1391 iptr->sx.val.i = 18;
1392 else if (iptr->sx.val.l == 0x00080000)
1393 iptr->sx.val.i = 19;
1394 else if (iptr->sx.val.l == 0x00100000)
1395 iptr->sx.val.i = 20;
1396 else if (iptr->sx.val.l == 0x00200000)
1397 iptr->sx.val.i = 21;
1398 else if (iptr->sx.val.l == 0x00400000)
1399 iptr->sx.val.i = 22;
1400 else if (iptr->sx.val.l == 0x00800000)
1401 iptr->sx.val.i = 23;
1402 else if (iptr->sx.val.l == 0x01000000)
1403 iptr->sx.val.i = 24;
1404 else if (iptr->sx.val.l == 0x02000000)
1405 iptr->sx.val.i = 25;
1406 else if (iptr->sx.val.l == 0x04000000)
1407 iptr->sx.val.i = 26;
1408 else if (iptr->sx.val.l == 0x08000000)
1409 iptr->sx.val.i = 27;
1410 else if (iptr->sx.val.l == 0x10000000)
1411 iptr->sx.val.i = 28;
1412 else if (iptr->sx.val.l == 0x20000000)
1413 iptr->sx.val.i = 29;
1414 else if (iptr->sx.val.l == 0x40000000)
1415 iptr->sx.val.i = 30;
1416 else if (iptr->sx.val.l == 0x80000000)
1417 iptr->sx.val.i = 31;
1421 iptr->opc = ICMD_LMULPOW2;
1422 goto icmd_lconst_tail;
1423 # endif /* SUPPORT_LONG_SHIFT */
1424 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1425 #if SUPPORT_LONG_DIV_POW2
1427 if (iptr->sx.val.l == 0x00000002)
1429 else if (iptr->sx.val.l == 0x00000004)
1431 else if (iptr->sx.val.l == 0x00000008)
1433 else if (iptr->sx.val.l == 0x00000010)
1435 else if (iptr->sx.val.l == 0x00000020)
1437 else if (iptr->sx.val.l == 0x00000040)
1439 else if (iptr->sx.val.l == 0x00000080)
1441 else if (iptr->sx.val.l == 0x00000100)
1443 else if (iptr->sx.val.l == 0x00000200)
1445 else if (iptr->sx.val.l == 0x00000400)
1446 iptr->sx.val.i = 10;
1447 else if (iptr->sx.val.l == 0x00000800)
1448 iptr->sx.val.i = 11;
1449 else if (iptr->sx.val.l == 0x00001000)
1450 iptr->sx.val.i = 12;
1451 else if (iptr->sx.val.l == 0x00002000)
1452 iptr->sx.val.i = 13;
1453 else if (iptr->sx.val.l == 0x00004000)
1454 iptr->sx.val.i = 14;
1455 else if (iptr->sx.val.l == 0x00008000)
1456 iptr->sx.val.i = 15;
1457 else if (iptr->sx.val.l == 0x00010000)
1458 iptr->sx.val.i = 16;
1459 else if (iptr->sx.val.l == 0x00020000)
1460 iptr->sx.val.i = 17;
1461 else if (iptr->sx.val.l == 0x00040000)
1462 iptr->sx.val.i = 18;
1463 else if (iptr->sx.val.l == 0x00080000)
1464 iptr->sx.val.i = 19;
1465 else if (iptr->sx.val.l == 0x00100000)
1466 iptr->sx.val.i = 20;
1467 else if (iptr->sx.val.l == 0x00200000)
1468 iptr->sx.val.i = 21;
1469 else if (iptr->sx.val.l == 0x00400000)
1470 iptr->sx.val.i = 22;
1471 else if (iptr->sx.val.l == 0x00800000)
1472 iptr->sx.val.i = 23;
1473 else if (iptr->sx.val.l == 0x01000000)
1474 iptr->sx.val.i = 24;
1475 else if (iptr->sx.val.l == 0x02000000)
1476 iptr->sx.val.i = 25;
1477 else if (iptr->sx.val.l == 0x04000000)
1478 iptr->sx.val.i = 26;
1479 else if (iptr->sx.val.l == 0x08000000)
1480 iptr->sx.val.i = 27;
1481 else if (iptr->sx.val.l == 0x10000000)
1482 iptr->sx.val.i = 28;
1483 else if (iptr->sx.val.l == 0x20000000)
1484 iptr->sx.val.i = 29;
1485 else if (iptr->sx.val.l == 0x40000000)
1486 iptr->sx.val.i = 30;
1487 else if (iptr->sx.val.l == 0x80000000)
1488 iptr->sx.val.i = 31;
1492 iptr->opc = ICMD_LDIVPOW2;
1493 goto icmd_lconst_tail;
1494 #endif /* SUPPORT_LONG_DIV_POW2 */
1496 #if SUPPORT_LONG_REM_POW2
1498 if ((iptr->sx.val.l == 0x00000002) ||
1499 (iptr->sx.val.l == 0x00000004) ||
1500 (iptr->sx.val.l == 0x00000008) ||
1501 (iptr->sx.val.l == 0x00000010) ||
1502 (iptr->sx.val.l == 0x00000020) ||
1503 (iptr->sx.val.l == 0x00000040) ||
1504 (iptr->sx.val.l == 0x00000080) ||
1505 (iptr->sx.val.l == 0x00000100) ||
1506 (iptr->sx.val.l == 0x00000200) ||
1507 (iptr->sx.val.l == 0x00000400) ||
1508 (iptr->sx.val.l == 0x00000800) ||
1509 (iptr->sx.val.l == 0x00001000) ||
1510 (iptr->sx.val.l == 0x00002000) ||
1511 (iptr->sx.val.l == 0x00004000) ||
1512 (iptr->sx.val.l == 0x00008000) ||
1513 (iptr->sx.val.l == 0x00010000) ||
1514 (iptr->sx.val.l == 0x00020000) ||
1515 (iptr->sx.val.l == 0x00040000) ||
1516 (iptr->sx.val.l == 0x00080000) ||
1517 (iptr->sx.val.l == 0x00100000) ||
1518 (iptr->sx.val.l == 0x00200000) ||
1519 (iptr->sx.val.l == 0x00400000) ||
1520 (iptr->sx.val.l == 0x00800000) ||
1521 (iptr->sx.val.l == 0x01000000) ||
1522 (iptr->sx.val.l == 0x02000000) ||
1523 (iptr->sx.val.l == 0x04000000) ||
1524 (iptr->sx.val.l == 0x08000000) ||
1525 (iptr->sx.val.l == 0x10000000) ||
1526 (iptr->sx.val.l == 0x20000000) ||
1527 (iptr->sx.val.l == 0x40000000) ||
1528 (iptr->sx.val.l == 0x80000000))
1530 iptr->opc = ICMD_LREMPOW2;
1531 iptr->sx.val.l -= 1;
1532 goto icmd_lconst_tail;
1535 #endif /* SUPPORT_LONG_REM_POW2 */
1537 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1540 iptr->opc = ICMD_LANDCONST;
1541 goto icmd_lconst_tail;
1544 iptr->opc = ICMD_LORCONST;
1545 goto icmd_lconst_tail;
1548 iptr->opc = ICMD_LXORCONST;
1549 goto icmd_lconst_tail;
1550 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1552 #if SUPPORT_LONG_CMP_CONST
1554 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1557 /* switch on the instruction after LCONST - LCMP */
1559 switch (iptr[2].opc) {
1561 iptr->opc = ICMD_IF_LEQ;
1564 icmd_lconst_lcmp_tail:
1565 /* convert LCONST, LCMP, IFXX to IF_LXX */
1566 iptr->dst.insindex = iptr[2].dst.insindex;
1567 iptr[1].opc = ICMD_NOP;
1568 iptr[2].opc = ICMD_NOP;
1570 OP1_BRANCH(TYPE_LNG);
1571 BRANCH(tbptr, copy);
1572 COUNT(count_pcmd_bra);
1573 COUNT(count_pcmd_op);
1577 iptr->opc = ICMD_IF_LNE;
1578 goto icmd_lconst_lcmp_tail;
1581 iptr->opc = ICMD_IF_LLT;
1582 goto icmd_lconst_lcmp_tail;
1585 iptr->opc = ICMD_IF_LGT;
1586 goto icmd_lconst_lcmp_tail;
1589 iptr->opc = ICMD_IF_LLE;
1590 goto icmd_lconst_lcmp_tail;
1593 iptr->opc = ICMD_IF_LGE;
1594 goto icmd_lconst_lcmp_tail;
1598 } /* end switch on opcode after LCONST - LCMP */
1600 #endif /* SUPPORT_LONG_CMP_CONST */
1602 #if SUPPORT_CONST_STORE
1604 IF_INTRP( goto normal_LCONST; )
1605 # if SUPPORT_CONST_STORE_ZERO_ONLY
1606 if (iptr->sx.val.l != 0)
1609 #if SIZEOF_VOID_P == 4
1610 /* the constant must fit into a ptrint */
1611 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1614 /* move the constant to s3 */
1615 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1617 iptr->opc = ICMD_LASTORECONST;
1618 iptr->flags.bits |= INS_FLAG_CHECK;
1619 OP2_0(TYPE_ADR, TYPE_INT);
1621 iptr[1].opc = ICMD_NOP;
1622 COUNT(count_pcmd_op);
1625 case ICMD_PUTSTATIC:
1627 IF_INTRP( goto normal_LCONST; )
1628 # if SUPPORT_CONST_STORE_ZERO_ONLY
1629 if (iptr->sx.val.l != 0)
1632 #if SIZEOF_VOID_P == 4
1633 /* the constant must fit into a ptrint */
1634 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1637 /* XXX check field type? */
1639 /* copy the constant to s2 */
1640 /* XXX constval -> fieldconstval? */
1641 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1645 #endif /* SUPPORT_CONST_STORE */
1649 } /* end switch opcode after LCONST */
1651 /* if we get here, the LCONST has been optimized */
1655 /* the normal case of an unoptimized LCONST */
1659 /************************ END OF LCONST OPTIMIZATIONS *********************/
1662 COUNT(count_pcmd_load);
1667 COUNT(count_pcmd_load);
1671 /************************** ACONST OPTIMIZATIONS **************************/
1674 coalescing_boundary = sd.new;
1675 COUNT(count_pcmd_load);
1676 #if SUPPORT_CONST_STORE
1677 IF_INTRP( goto normal_ACONST; )
1679 /* We can only optimize if the ACONST is resolved
1680 * and there is an instruction after it. */
1682 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1685 switch (iptr[1].opc) {
1687 /* We can only optimize for NULL values
1688 * here because otherwise a checkcast is
1690 if (iptr->sx.val.anyptr != NULL)
1693 /* copy the constant (NULL) to s3 */
1694 iptr->sx.s23.s3.constval = 0;
1695 iptr->opc = ICMD_AASTORECONST;
1696 iptr->flags.bits |= INS_FLAG_CHECK;
1697 OP2_0(TYPE_ADR, TYPE_INT);
1699 iptr[1].opc = ICMD_NOP;
1700 COUNT(count_pcmd_op);
1703 case ICMD_PUTSTATIC:
1705 # if SUPPORT_CONST_STORE_ZERO_ONLY
1706 if (iptr->sx.val.anyptr != NULL)
1709 /* XXX check field type? */
1710 /* copy the constant to s2 */
1711 /* XXX constval -> fieldconstval? */
1712 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1720 /* if we get here the ACONST has been optimized */
1724 #endif /* SUPPORT_CONST_STORE */
1729 /* pop 0 push 1 load */
1736 COUNT(count_load_instruction);
1737 i = opcode - ICMD_ILOAD; /* type */
1740 jd->local_map[iptr->s1.varindex * 5 + i];
1742 LOAD(i, iptr->s1.varindex);
1751 coalescing_boundary = sd.new;
1752 iptr->flags.bits |= INS_FLAG_CHECK;
1753 COUNT(count_check_null);
1754 COUNT(count_check_bound);
1755 COUNT(count_pcmd_mem);
1756 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1763 coalescing_boundary = sd.new;
1764 iptr->flags.bits |= INS_FLAG_CHECK;
1765 COUNT(count_check_null);
1766 COUNT(count_check_bound);
1767 COUNT(count_pcmd_mem);
1768 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1771 /* pop 0 push 0 iinc */
1774 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1776 last_store_boundary[iptr->s1.varindex] = sd.new;
1779 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
1784 if ((copy->varkind == LOCALVAR) &&
1785 (copy->varnum == iptr->s1.varindex))
1787 assert(IS_LOCALVAR(copy));
1794 iptr->dst.varindex = iptr->s1.varindex;
1797 /* pop 1 push 0 store */
1806 i = opcode - ICMD_ISTORE; /* type */
1807 javaindex = iptr->dst.varindex;
1808 j = iptr->dst.varindex =
1809 jd->local_map[javaindex * 5 + i];
1812 #if defined(ENABLE_STATISTICS)
1815 i = sd.new - curstack;
1817 count_store_length[20]++;
1819 count_store_length[i]++;
1822 count_store_depth[10]++;
1824 count_store_depth[i]++;
1827 /* check for conflicts as described in Figure 5.2 */
1829 copy = curstack->prev;
1832 if ((copy->varkind == LOCALVAR) &&
1833 (copy->varnum == j))
1835 copy->varkind = TEMPVAR;
1836 assert(IS_LOCALVAR(copy));
1843 /* if the variable is already coalesced, don't bother */
1845 if (IS_OUTVAR(curstack)
1846 || (curstack->varkind == LOCALVAR
1847 && curstack->varnum != j))
1850 /* there is no STORE Lj while curstack is live */
1852 if (curstack < last_store_boundary[javaindex])
1853 goto assume_conflict;
1855 /* curstack must be after the coalescing boundary */
1857 if (curstack < coalescing_boundary)
1858 goto assume_conflict;
1860 /* there is no DEF LOCALVAR(j) while curstack is live */
1862 copy = sd.new; /* most recent stackslot created + 1 */
1863 while (--copy > curstack) {
1864 if (copy->varkind == LOCALVAR && copy->varnum == j)
1865 goto assume_conflict;
1868 /* coalesce the temporary variable with Lj */
1869 assert((curstack->varkind == TEMPVAR)
1870 || (curstack->varkind == UNDEFVAR));
1871 assert(!IS_LOCALVAR(curstack));
1872 assert(!IS_OUTVAR(curstack));
1873 assert(!IS_PREALLOC(curstack));
1875 assert(curstack->creator);
1876 assert(curstack->creator->dst.varindex == curstack->varnum);
1877 RELEASE_INDEX(sd, curstack);
1878 curstack->varkind = LOCALVAR;
1879 curstack->varnum = j;
1880 curstack->creator->dst.varindex = j;
1883 /* revert the coalescing, if it has been done earlier */
1885 if ((curstack->varkind == LOCALVAR)
1886 && (curstack->varnum == j))
1888 assert(IS_LOCALVAR(curstack));
1889 SET_TEMPVAR(curstack);
1892 /* remember the stack boundary at this store */
1894 last_store_boundary[javaindex] = sd.new;
1896 STORE(opcode - ICMD_ISTORE, j);
1902 coalescing_boundary = sd.new;
1903 iptr->flags.bits |= INS_FLAG_CHECK;
1904 COUNT(count_check_null);
1905 COUNT(count_check_bound);
1906 COUNT(count_pcmd_mem);
1908 bte = builtintable_get_internal(BUILTIN_canstore);
1911 if (md->memuse > rd->memuse)
1912 rd->memuse = md->memuse;
1913 if (md->argintreguse > rd->argintreguse)
1914 rd->argintreguse = md->argintreguse;
1915 /* XXX non-leaf method? */
1917 /* make all stack variables saved */
1921 sd.var[copy->varnum].flags |= SAVEDVAR;
1922 /* in case copy->varnum is/will be a LOCALVAR */
1923 /* once and set back to a non LOCALVAR */
1924 /* the correct SAVEDVAR flag has to be */
1925 /* remembered in copy->flags, too */
1926 copy->flags |= SAVEDVAR;
1930 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1937 coalescing_boundary = sd.new;
1938 iptr->flags.bits |= INS_FLAG_CHECK;
1939 COUNT(count_check_null);
1940 COUNT(count_check_bound);
1941 COUNT(count_pcmd_mem);
1942 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1949 coalescing_boundary = sd.new;
1950 iptr->flags.bits |= INS_FLAG_CHECK;
1951 COUNT(count_check_null);
1952 COUNT(count_check_bound);
1953 COUNT(count_pcmd_mem);
1954 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1960 #ifdef ENABLE_VERIFIER
1963 if (IS_2_WORD_TYPE(curstack->type))
1964 goto throw_stack_category_error;
1975 coalescing_boundary = sd.new;
1976 IF_JIT( md_return_alloc(jd, curstack); )
1977 COUNT(count_pcmd_return);
1978 OP1_0(opcode - ICMD_IRETURN);
1979 superblockend = true;
1983 coalescing_boundary = sd.new;
1984 COUNT(count_check_null);
1986 curstack = NULL; stackdepth = 0;
1987 superblockend = true;
1990 case ICMD_PUTSTATIC:
1991 coalescing_boundary = sd.new;
1992 COUNT(count_pcmd_mem);
1993 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1994 OP1_0(fmiref->parseddesc.fd->type);
1997 /* pop 1 push 0 branch */
2000 case ICMD_IFNONNULL:
2001 COUNT(count_pcmd_bra);
2002 OP1_BRANCH(TYPE_ADR);
2003 BRANCH(tbptr, copy);
2012 COUNT(count_pcmd_bra);
2013 /* iptr->sx.val.i is set implicitly in parse by
2014 clearing the memory or from IF_ICMPxx
2017 OP1_BRANCH(TYPE_INT);
2018 /* iptr->sx.val.i = 0; */
2019 BRANCH(tbptr, copy);
2022 /* pop 0 push 0 branch */
2025 COUNT(count_pcmd_bra);
2027 BRANCH(tbptr, copy);
2028 superblockend = true;
2031 /* pop 1 push 0 table branch */
2033 case ICMD_TABLESWITCH:
2034 COUNT(count_pcmd_table);
2035 OP1_BRANCH(TYPE_INT);
2037 table = iptr->dst.table;
2038 BRANCH_TARGET(*table, tbptr, copy);
2041 i = iptr->sx.s23.s3.tablehigh
2042 - iptr->sx.s23.s2.tablelow + 1;
2045 BRANCH_TARGET(*table, tbptr, copy);
2048 superblockend = true;
2051 /* pop 1 push 0 table branch */
2053 case ICMD_LOOKUPSWITCH:
2054 COUNT(count_pcmd_table);
2055 OP1_BRANCH(TYPE_INT);
2057 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
2059 lookup = iptr->dst.lookup;
2061 i = iptr->sx.s23.s2.lookupcount;
2064 BRANCH_TARGET(lookup->target, tbptr, copy);
2067 superblockend = true;
2070 case ICMD_MONITORENTER:
2071 case ICMD_MONITOREXIT:
2072 coalescing_boundary = sd.new;
2073 COUNT(count_check_null);
2077 /* pop 2 push 0 branch */
2079 case ICMD_IF_ICMPEQ:
2080 case ICMD_IF_ICMPNE:
2081 case ICMD_IF_ICMPLT:
2082 case ICMD_IF_ICMPGE:
2083 case ICMD_IF_ICMPGT:
2084 case ICMD_IF_ICMPLE:
2085 COUNT(count_pcmd_bra);
2086 OP2_BRANCH(TYPE_INT, TYPE_INT);
2087 BRANCH(tbptr, copy);
2090 case ICMD_IF_ACMPEQ:
2091 case ICMD_IF_ACMPNE:
2092 COUNT(count_pcmd_bra);
2093 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
2094 BRANCH(tbptr, copy);
2100 coalescing_boundary = sd.new;
2101 COUNT(count_check_null);
2102 COUNT(count_pcmd_mem);
2103 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2104 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
2109 if (!IS_2_WORD_TYPE(curstack->type)) {
2111 #ifdef ENABLE_VERIFIER
2114 if (IS_2_WORD_TYPE(curstack->prev->type))
2115 goto throw_stack_category_error;
2118 OP2_0_ANY_ANY; /* pop two slots */
2121 iptr->opc = ICMD_POP;
2122 OP1_0_ANY; /* pop one (two-word) slot */
2126 /* pop 0 push 1 dup */
2129 #ifdef ENABLE_VERIFIER
2132 if (IS_2_WORD_TYPE(curstack->type))
2133 goto throw_stack_category_error;
2136 COUNT(count_dup_instruction);
2142 coalescing_boundary = sd.new - 1;
2147 if (IS_2_WORD_TYPE(curstack->type)) {
2149 iptr->opc = ICMD_DUP;
2154 /* ..., ????, cat1 */
2155 #ifdef ENABLE_VERIFIER
2157 if (IS_2_WORD_TYPE(curstack->prev->type))
2158 goto throw_stack_category_error;
2161 src1 = curstack->prev;
2164 COPY_UP(src1); iptr++; len--;
2167 coalescing_boundary = sd.new;
2171 /* pop 2 push 3 dup */
2174 #ifdef ENABLE_VERIFIER
2177 if (IS_2_WORD_TYPE(curstack->type) ||
2178 IS_2_WORD_TYPE(curstack->prev->type))
2179 goto throw_stack_category_error;
2184 src1 = curstack->prev;
2189 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2191 MOVE_UP(src1); iptr++; len--;
2192 MOVE_UP(src2); iptr++; len--;
2194 COPY_DOWN(curstack, dst1);
2196 coalescing_boundary = sd.new;
2201 if (IS_2_WORD_TYPE(curstack->type)) {
2202 /* ..., ????, cat2 */
2203 #ifdef ENABLE_VERIFIER
2205 if (IS_2_WORD_TYPE(curstack->prev->type))
2206 goto throw_stack_category_error;
2209 iptr->opc = ICMD_DUP_X1;
2213 /* ..., ????, cat1 */
2214 #ifdef ENABLE_VERIFIER
2217 if (IS_2_WORD_TYPE(curstack->prev->type)
2218 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2219 goto throw_stack_category_error;
2224 src1 = curstack->prev->prev;
2225 src2 = curstack->prev;
2227 POPANY; POPANY; POPANY;
2230 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2231 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
2233 MOVE_UP(src1); iptr++; len--;
2234 MOVE_UP(src2); iptr++; len--;
2235 MOVE_UP(src3); iptr++; len--;
2237 COPY_DOWN(curstack, dst2); iptr++; len--;
2238 COPY_DOWN(curstack->prev, dst1);
2240 coalescing_boundary = sd.new;
2244 /* pop 3 push 4 dup */
2248 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2249 /* ..., cat2, ???? */
2250 #ifdef ENABLE_VERIFIER
2252 if (IS_2_WORD_TYPE(curstack->type))
2253 goto throw_stack_category_error;
2256 iptr->opc = ICMD_DUP_X1;
2260 /* ..., cat1, ???? */
2261 #ifdef ENABLE_VERIFIER
2264 if (IS_2_WORD_TYPE(curstack->type)
2265 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2266 goto throw_stack_category_error;
2270 src1 = curstack->prev->prev;
2271 src2 = curstack->prev;
2273 POPANY; POPANY; POPANY;
2276 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2278 MOVE_UP(src1); iptr++; len--;
2279 MOVE_UP(src2); iptr++; len--;
2280 MOVE_UP(src3); iptr++; len--;
2282 COPY_DOWN(curstack, dst1);
2284 coalescing_boundary = sd.new;
2290 if (IS_2_WORD_TYPE(curstack->type)) {
2291 /* ..., ????, cat2 */
2292 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2293 /* ..., cat2, cat2 */
2294 iptr->opc = ICMD_DUP_X1;
2298 /* ..., cat1, cat2 */
2299 #ifdef ENABLE_VERIFIER
2302 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2303 goto throw_stack_category_error;
2306 iptr->opc = ICMD_DUP_X2;
2312 /* ..., ????, ????, cat1 */
2314 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2315 /* ..., cat2, ????, cat1 */
2316 #ifdef ENABLE_VERIFIER
2318 if (IS_2_WORD_TYPE(curstack->prev->type))
2319 goto throw_stack_category_error;
2322 iptr->opc = ICMD_DUP2_X1;
2326 /* ..., cat1, ????, cat1 */
2327 #ifdef ENABLE_VERIFIER
2330 if (IS_2_WORD_TYPE(curstack->prev->type)
2331 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2332 goto throw_stack_category_error;
2336 src1 = curstack->prev->prev->prev;
2337 src2 = curstack->prev->prev;
2338 src3 = curstack->prev;
2340 POPANY; POPANY; POPANY; POPANY;
2343 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2344 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
2346 MOVE_UP(src1); iptr++; len--;
2347 MOVE_UP(src2); iptr++; len--;
2348 MOVE_UP(src3); iptr++; len--;
2349 MOVE_UP(src4); iptr++; len--;
2351 COPY_DOWN(curstack, dst2); iptr++; len--;
2352 COPY_DOWN(curstack->prev, dst1);
2354 coalescing_boundary = sd.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 src1 = curstack->prev;
2375 MOVE_UP(src2); iptr++; len--;
2378 coalescing_boundary = sd.new;
2385 coalescing_boundary = sd.new;
2386 #if !SUPPORT_DIVISION
2387 bte = iptr->sx.s23.s3.bte;
2390 if (md->memuse > rd->memuse)
2391 rd->memuse = md->memuse;
2392 if (md->argintreguse > rd->argintreguse)
2393 rd->argintreguse = md->argintreguse;
2395 /* make all stack variables saved */
2399 sd.var[copy->varnum].flags |= SAVEDVAR;
2400 copy->flags |= SAVEDVAR;
2405 #endif /* !SUPPORT_DIVISION */
2416 COUNT(count_pcmd_op);
2417 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2422 coalescing_boundary = sd.new;
2423 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2424 bte = iptr->sx.s23.s3.bte;
2427 if (md->memuse > rd->memuse)
2428 rd->memuse = md->memuse;
2429 if (md->argintreguse > rd->argintreguse)
2430 rd->argintreguse = md->argintreguse;
2431 /* XXX non-leaf method? */
2433 /* make all stack variables saved */
2437 sd.var[copy->varnum].flags |= SAVEDVAR;
2438 copy->flags |= SAVEDVAR;
2443 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2448 #if SUPPORT_LONG_LOGICAL
2452 #endif /* SUPPORT_LONG_LOGICAL */
2453 COUNT(count_pcmd_op);
2454 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2460 COUNT(count_pcmd_op);
2461 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2469 COUNT(count_pcmd_op);
2470 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2478 COUNT(count_pcmd_op);
2479 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2483 COUNT(count_pcmd_op);
2484 #if SUPPORT_LONG_CMP_CONST
2485 if ((len == 0) || (iptr[1].sx.val.i != 0))
2488 switch (iptr[1].opc) {
2490 iptr->opc = ICMD_IF_LCMPEQ;
2492 iptr->dst.insindex = iptr[1].dst.insindex;
2493 iptr[1].opc = ICMD_NOP;
2495 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2496 BRANCH(tbptr, copy);
2498 COUNT(count_pcmd_bra);
2501 iptr->opc = ICMD_IF_LCMPNE;
2502 goto icmd_lcmp_if_tail;
2504 iptr->opc = ICMD_IF_LCMPLT;
2505 goto icmd_lcmp_if_tail;
2507 iptr->opc = ICMD_IF_LCMPGT;
2508 goto icmd_lcmp_if_tail;
2510 iptr->opc = ICMD_IF_LCMPLE;
2511 goto icmd_lcmp_if_tail;
2513 iptr->opc = ICMD_IF_LCMPGE;
2514 goto icmd_lcmp_if_tail;
2520 #endif /* SUPPORT_LONG_CMP_CONST */
2521 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2524 /* XXX why is this deactivated? */
2527 COUNT(count_pcmd_op);
2528 if ((len == 0) || (iptr[1].sx.val.i != 0))
2531 switch (iptr[1].opc) {
2533 iptr->opc = ICMD_IF_FCMPEQ;
2535 iptr->dst.insindex = iptr[1].dst.insindex;
2536 iptr[1].opc = ICMD_NOP;
2538 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2539 BRANCH(tbptr, copy);
2541 COUNT(count_pcmd_bra);
2544 iptr->opc = ICMD_IF_FCMPNE;
2545 goto icmd_if_fcmpl_tail;
2547 iptr->opc = ICMD_IF_FCMPL_LT;
2548 goto icmd_if_fcmpl_tail;
2550 iptr->opc = ICMD_IF_FCMPL_GT;
2551 goto icmd_if_fcmpl_tail;
2553 iptr->opc = ICMD_IF_FCMPL_LE;
2554 goto icmd_if_fcmpl_tail;
2556 iptr->opc = ICMD_IF_FCMPL_GE;
2557 goto icmd_if_fcmpl_tail;
2564 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2568 COUNT(count_pcmd_op);
2569 if ((len == 0) || (iptr[1].sx.val.i != 0))
2572 switch (iptr[1].opc) {
2574 iptr->opc = ICMD_IF_FCMPEQ;
2576 iptr->dst.insindex = iptr[1].dst.insindex;
2577 iptr[1].opc = ICMD_NOP;
2579 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2580 BRANCH(tbptr, copy);
2582 COUNT(count_pcmd_bra);
2585 iptr->opc = ICMD_IF_FCMPNE;
2586 goto icmd_if_fcmpg_tail;
2588 iptr->opc = ICMD_IF_FCMPG_LT;
2589 goto icmd_if_fcmpg_tail;
2591 iptr->opc = ICMD_IF_FCMPG_GT;
2592 goto icmd_if_fcmpg_tail;
2594 iptr->opc = ICMD_IF_FCMPG_LE;
2595 goto icmd_if_fcmpg_tail;
2597 iptr->opc = ICMD_IF_FCMPG_GE;
2598 goto icmd_if_fcmpg_tail;
2605 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2609 COUNT(count_pcmd_op);
2610 if ((len == 0) || (iptr[1].sx.val.i != 0))
2613 switch (iptr[1].opc) {
2615 iptr->opc = ICMD_IF_DCMPEQ;
2617 iptr->dst.insindex = iptr[1].dst.insindex;
2618 iptr[1].opc = ICMD_NOP;
2620 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2621 BRANCH(tbptr, copy);
2623 COUNT(count_pcmd_bra);
2626 iptr->opc = ICMD_IF_DCMPNE;
2627 goto icmd_if_dcmpl_tail;
2629 iptr->opc = ICMD_IF_DCMPL_LT;
2630 goto icmd_if_dcmpl_tail;
2632 iptr->opc = ICMD_IF_DCMPL_GT;
2633 goto icmd_if_dcmpl_tail;
2635 iptr->opc = ICMD_IF_DCMPL_LE;
2636 goto icmd_if_dcmpl_tail;
2638 iptr->opc = ICMD_IF_DCMPL_GE;
2639 goto icmd_if_dcmpl_tail;
2646 OPTT2_1(TYPE_DBL, TYPE_INT);
2650 COUNT(count_pcmd_op);
2651 if ((len == 0) || (iptr[1].sx.val.i != 0))
2654 switch (iptr[1].opc) {
2656 iptr->opc = ICMD_IF_DCMPEQ;
2658 iptr->dst.insindex = iptr[1].dst.insindex;
2659 iptr[1].opc = ICMD_NOP;
2661 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2662 BRANCH(tbptr, copy);
2664 COUNT(count_pcmd_bra);
2667 iptr->opc = ICMD_IF_DCMPNE;
2668 goto icmd_if_dcmpg_tail;
2670 iptr->opc = ICMD_IF_DCMPG_LT;
2671 goto icmd_if_dcmpg_tail;
2673 iptr->opc = ICMD_IF_DCMPG_GT;
2674 goto icmd_if_dcmpg_tail;
2676 iptr->opc = ICMD_IF_DCMPG_LE;
2677 goto icmd_if_dcmpg_tail;
2679 iptr->opc = ICMD_IF_DCMPG_GE;
2680 goto icmd_if_dcmpg_tail;
2687 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2692 COUNT(count_pcmd_op);
2693 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2698 COUNT(count_pcmd_op);
2699 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2708 case ICMD_INT2SHORT:
2709 COUNT(count_pcmd_op);
2710 OP1_1(TYPE_INT, TYPE_INT);
2713 COUNT(count_pcmd_op);
2714 OP1_1(TYPE_LNG, TYPE_LNG);
2717 COUNT(count_pcmd_op);
2718 OP1_1(TYPE_FLT, TYPE_FLT);
2721 COUNT(count_pcmd_op);
2722 OP1_1(TYPE_DBL, TYPE_DBL);
2726 COUNT(count_pcmd_op);
2727 OP1_1(TYPE_INT, TYPE_LNG);
2730 COUNT(count_pcmd_op);
2731 OP1_1(TYPE_INT, TYPE_FLT);
2734 COUNT(count_pcmd_op);
2735 OP1_1(TYPE_INT, TYPE_DBL);
2738 COUNT(count_pcmd_op);
2739 OP1_1(TYPE_LNG, TYPE_INT);
2742 COUNT(count_pcmd_op);
2743 OP1_1(TYPE_LNG, TYPE_FLT);
2746 COUNT(count_pcmd_op);
2747 OP1_1(TYPE_LNG, TYPE_DBL);
2750 COUNT(count_pcmd_op);
2751 OP1_1(TYPE_FLT, TYPE_INT);
2754 COUNT(count_pcmd_op);
2755 OP1_1(TYPE_FLT, TYPE_LNG);
2758 COUNT(count_pcmd_op);
2759 OP1_1(TYPE_FLT, TYPE_DBL);
2762 COUNT(count_pcmd_op);
2763 OP1_1(TYPE_DBL, TYPE_INT);
2766 COUNT(count_pcmd_op);
2767 OP1_1(TYPE_DBL, TYPE_LNG);
2770 COUNT(count_pcmd_op);
2771 OP1_1(TYPE_DBL, TYPE_FLT);
2774 case ICMD_CHECKCAST:
2775 coalescing_boundary = sd.new;
2776 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2777 /* array type cast-check */
2779 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2782 if (md->memuse > rd->memuse)
2783 rd->memuse = md->memuse;
2784 if (md->argintreguse > rd->argintreguse)
2785 rd->argintreguse = md->argintreguse;
2787 /* make all stack variables saved */
2791 sd.var[copy->varnum].flags |= SAVEDVAR;
2792 copy->flags |= SAVEDVAR;
2796 OP1_1(TYPE_ADR, TYPE_ADR);
2799 case ICMD_INSTANCEOF:
2800 case ICMD_ARRAYLENGTH:
2801 coalescing_boundary = sd.new;
2802 OP1_1(TYPE_ADR, TYPE_INT);
2806 case ICMD_ANEWARRAY:
2807 coalescing_boundary = sd.new;
2808 OP1_1(TYPE_INT, TYPE_ADR);
2812 coalescing_boundary = sd.new;
2813 COUNT(count_check_null);
2814 COUNT(count_pcmd_mem);
2815 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2816 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2821 case ICMD_GETSTATIC:
2822 coalescing_boundary = sd.new;
2823 COUNT(count_pcmd_mem);
2824 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2825 OP0_1(fmiref->parseddesc.fd->type);
2829 coalescing_boundary = sd.new;
2836 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2838 tbptr->type = BBTYPE_SBR;
2840 /* We need to check for overflow right here because
2841 * the pushed value is poped afterwards */
2844 /* calculate stack after return */
2849 /* pop many push any */
2853 bte = iptr->sx.s23.s3.bte;
2857 case ICMD_INVOKESTATIC:
2858 case ICMD_INVOKESPECIAL:
2859 case ICMD_INVOKEVIRTUAL:
2860 case ICMD_INVOKEINTERFACE:
2861 COUNT(count_pcmd_met);
2863 /* Check for functions to replace with builtin
2866 if (builtintable_replace_function(iptr))
2869 INSTRUCTION_GET_METHODDESC(iptr, md);
2870 /* XXX resurrect this COUNT? */
2871 /* if (lm->flags & ACC_STATIC) */
2872 /* {COUNT(count_check_null);} */
2876 coalescing_boundary = sd.new;
2880 if (md->memuse > rd->memuse)
2881 rd->memuse = md->memuse;
2882 if (md->argintreguse > rd->argintreguse)
2883 rd->argintreguse = md->argintreguse;
2884 if (md->argfltreguse > rd->argfltreguse)
2885 rd->argfltreguse = md->argfltreguse;
2889 /* XXX optimize for <= 2 args */
2890 /* XXX not for ICMD_BUILTIN */
2891 iptr->s1.argcount = stackdepth;
2892 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2895 for (i-- ; i >= 0; i--) {
2896 iptr->sx.s23.s2.args[i] = copy->varnum;
2898 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2899 /* -> won't help anyway */
2900 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2902 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2903 /* If we pass float arguments in integer argument registers, we
2904 * are not allowed to precolor them here. Floats have to be moved
2905 * to this regs explicitly in codegen().
2906 * Only arguments that are passed by stack anyway can be precolored
2907 * (michi 2005/07/24) */
2908 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
2909 (!IS_FLT_DBL_TYPE(copy->type)
2910 || md->params[i].inmemory)) {
2912 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
2917 #if defined(ENABLE_INTRP)
2920 if (md->params[i].inmemory) {
2921 sd.var[copy->varnum].vv.regoff =
2922 md->params[i].regoff;
2923 sd.var[copy->varnum].flags |=
2927 if (IS_FLT_DBL_TYPE(copy->type)) {
2928 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2929 assert(0); /* XXX is this assert ok? */
2931 sd.var[copy->varnum].vv.regoff =
2932 rd->argfltregs[md->params[i].regoff];
2933 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2936 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2937 if (IS_2_WORD_TYPE(copy->type))
2938 sd.var[copy->varnum].vv.regoff =
2939 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2940 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2943 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2944 sd.var[copy->varnum].vv.regoff =
2945 rd->argintregs[md->params[i].regoff];
2948 #if defined(ENABLE_INTRP)
2949 } /* end if (!opt_intrp) */
2956 /* deal with live-through stack slots "under" the */
2958 /* XXX not for ICMD_BUILTIN */
2964 iptr->sx.s23.s2.args[i++] = copy->varnum;
2965 sd.var[copy->varnum].flags |= SAVEDVAR;
2969 /* pop the arguments */
2978 /* push the return value */
2980 if (md->returntype.type != TYPE_VOID) {
2981 GET_NEW_VAR(sd, new_index, md->returntype.type);
2982 DST(md->returntype.type, new_index);
2987 case ICMD_INLINE_START:
2988 case ICMD_INLINE_END:
2993 case ICMD_MULTIANEWARRAY:
2994 coalescing_boundary = sd.new;
2995 if (rd->argintreguse < 3)
2996 rd->argintreguse = 3;
2998 i = iptr->s1.argcount;
3002 iptr->sx.s23.s2.args = DMNEW(s4, i);
3004 #if defined(SPECIALMEMUSE)
3005 # if defined(__DARWIN__)
3006 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
3007 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3009 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
3010 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
3013 # if defined(__I386__)
3014 if (rd->memuse < i + 3)
3015 rd->memuse = i + 3; /* n integer args spilled on stack */
3016 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3017 if (rd->memuse < i + 2)
3018 rd->memuse = i + 2; /* 4*4 bytes callee save space */
3021 rd->memuse = i; /* n integer args spilled on stack */
3022 # endif /* defined(__I386__) */
3026 /* check INT type here? Currently typecheck does this. */
3027 iptr->sx.s23.s2.args[i] = copy->varnum;
3028 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
3029 && (!IS_OUTVAR(copy))
3030 && (!IS_LOCALVAR(copy)) ) {
3031 copy->varkind = ARGVAR;
3032 sd.var[copy->varnum].flags |=
3033 INMEMORY & PREALLOC;
3034 #if defined(SPECIALMEMUSE)
3035 # if defined(__DARWIN__)
3036 sd.var[copy->varnum].vv.regoff = i +
3037 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3039 sd.var[copy->varnum].vv.regoff = i +
3040 LA_SIZE_IN_POINTERS + 3;
3043 # if defined(__I386__)
3044 sd.var[copy->varnum].vv.regoff = i + 3;
3045 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3046 sd.var[copy->varnum].vv.regoff = i + 2;
3048 sd.var[copy->varnum].vv.regoff = i;
3049 # endif /* defined(__I386__) */
3050 #endif /* defined(SPECIALMEMUSE) */
3055 sd.var[copy->varnum].flags |= SAVEDVAR;
3059 i = iptr->s1.argcount;
3064 GET_NEW_VAR(sd, new_index, TYPE_ADR);
3065 DST(TYPE_ADR, new_index);
3071 new_internalerror("Unknown ICMD %d", opcode);
3077 } /* while instructions */
3079 /* stack slots at basic block end become interfaces */
3081 sd.bptr->outdepth = stackdepth;
3082 sd.bptr->outvars = DMNEW(s4, stackdepth);
3085 for (copy = curstack; copy; i--, copy = copy->prev) {
3088 /* with the new vars rd->interfaces will be removed */
3089 /* and all in and outvars have to be STACKVARS! */
3090 /* in the moment i.e. SWAP with in and out vars can */
3091 /* create an unresolvable conflict */
3095 v = sd.var + copy->varnum;
3098 if (jd->interface_map[i*5 + copy->type].flags == UNUSED) {
3099 /* no interface var until now for this depth and */
3101 jd->interface_map[i*5 + copy->type].flags = v->flags;
3104 jd->interface_map[i*5 + copy->type].flags |= v->flags;
3107 sd.bptr->outvars[i] = copy->varnum;
3110 /* check if interface slots at basic block begin must be saved */
3112 for (i=0; i<sd.bptr->indepth; ++i) {
3113 varinfo *v = sd.var + sd.bptr->invars[i];
3115 if (jd->interface_map[i*5 + v->type].flags == UNUSED) {
3116 /* no interface var until now for this depth and */
3118 jd->interface_map[i*5 + v->type].flags = v->flags;
3121 jd->interface_map[i*5 + v->type].flags |= v->flags;
3126 /* store the number of this block's variables */
3128 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
3130 #if defined(STACK_VERBOSE)
3131 printf("OUTVARS\n");
3132 /* XXX print something useful here */
3138 } while (repeat && !deadcode);
3140 /* gather statistics *****************************************************/
3142 #if defined(ENABLE_STATISTICS)
3144 if (jd->new_basicblockcount > count_max_basic_blocks)
3145 count_max_basic_blocks = jd->new_basicblockcount;
3146 count_basic_blocks += jd->new_basicblockcount;
3147 if (jd->new_instructioncount > count_max_javainstr)
3148 count_max_javainstr = jd->new_instructioncount;
3149 count_javainstr += jd->new_instructioncount;
3150 if (jd->new_stackcount > count_upper_bound_new_stack)
3151 count_upper_bound_new_stack = jd->new_stackcount;
3152 if ((sd.new - jd->new_stack) > count_max_new_stack)
3153 count_max_new_stack = (sd.new - jd->new_stack);
3155 b_count = jd->new_basicblockcount;
3156 sd.bptr = jd->new_basicblocks;
3157 while (--b_count >= 0) {
3158 if (sd.bptr->flags > BBREACHED) {
3159 if (sd.bptr->indepth >= 10)
3160 count_block_stack[10]++;
3162 count_block_stack[sd.bptr->indepth]++;
3163 len = sd.bptr->icount;
3165 count_block_size_distribution[len]++;
3167 count_block_size_distribution[10]++;
3169 count_block_size_distribution[11]++;
3171 count_block_size_distribution[12]++;
3173 count_block_size_distribution[13]++;
3175 count_block_size_distribution[14]++;
3177 count_block_size_distribution[15]++;
3179 count_block_size_distribution[16]++;
3181 count_block_size_distribution[17]++;
3186 if (iteration_count == 1)
3187 count_analyse_iterations[0]++;
3188 else if (iteration_count == 2)
3189 count_analyse_iterations[1]++;
3190 else if (iteration_count == 3)
3191 count_analyse_iterations[2]++;
3192 else if (iteration_count == 4)
3193 count_analyse_iterations[3]++;
3195 count_analyse_iterations[4]++;
3197 if (jd->new_basicblockcount <= 5)
3198 count_method_bb_distribution[0]++;
3199 else if (jd->new_basicblockcount <= 10)
3200 count_method_bb_distribution[1]++;
3201 else if (jd->new_basicblockcount <= 15)
3202 count_method_bb_distribution[2]++;
3203 else if (jd->new_basicblockcount <= 20)
3204 count_method_bb_distribution[3]++;
3205 else if (jd->new_basicblockcount <= 30)
3206 count_method_bb_distribution[4]++;
3207 else if (jd->new_basicblockcount <= 40)
3208 count_method_bb_distribution[5]++;
3209 else if (jd->new_basicblockcount <= 50)
3210 count_method_bb_distribution[6]++;
3211 else if (jd->new_basicblockcount <= 75)
3212 count_method_bb_distribution[7]++;
3214 count_method_bb_distribution[8]++;
3216 #endif /* defined(ENABLE_STATISTICS) */
3218 /* everything's ok *******************************************************/
3222 /* goto labels for throwing verifier exceptions **************************/
3224 #if defined(ENABLE_VERIFIER)
3226 throw_stack_underflow:
3227 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3230 throw_stack_overflow:
3231 exceptions_throw_verifyerror(m, "Stack size too large");
3234 throw_stack_depth_error:
3235 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3238 throw_stack_type_error:
3239 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3242 throw_stack_category_error:
3243 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3251 * These are local overrides for various environment variables in Emacs.
3252 * Please do not remove this and leave it at the end of the file, where
3253 * Emacs will automagically detect them.
3254 * ---------------------------------------------------------------------
3257 * indent-tabs-mode: t
3261 * vim:noexpandtab:sw=4:ts=4: