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 5448 2006-09-09 21:41:45Z 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 /* XXX turn off coalescing */
411 #define DUP_SLOT(sp) \
413 if ((sp)->varkind != TEMPVAR) { \
414 GET_NEW_VAR(sd, new_index, (sp)->type); \
415 NEWSTACK((sp)->type, TEMPVAR, new_index); \
418 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
421 #define DUP_SLOT(sp) \
423 GET_NEW_VAR(sd, new_index, (sp)->type); \
424 NEWSTACK((sp)->type, TEMPVAR, new_index); \
428 /* does not check input stackdepth */
429 #define MOVE_UP(sp) \
431 iptr->opc = ICMD_MOVE; \
432 iptr->s1.varindex = (sp)->varnum; \
434 curstack->creator = iptr; \
435 iptr->dst.varindex = curstack->varnum; \
439 /* does not check input stackdepth */
440 #define COPY_UP(sp) \
443 iptr->opc = ICMD_COPY; \
444 iptr->s1.varindex = (sp)->varnum; \
446 curstack->creator = iptr; \
447 iptr->dst.varindex = curstack->varnum; \
451 #define COPY_DOWN(s, d) \
454 iptr->opc = ICMD_COPY; \
455 iptr->s1.varindex = (s)->varnum; \
456 iptr->dst.varindex = (d)->varnum; \
457 (d)->creator = iptr; \
461 /* macros for branching / reaching basic blocks *********************/
463 #if defined(ENABLE_VERIFIER)
464 #define MARKREACHED(b, c) \
466 if (!stack_mark_reached(&sd, (b), curstack, stackdepth)) \
470 #define MARKREACHED(b, c) \
472 (void) stack_mark_reached(&sd, (b), curstack, stackdepth); \
476 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
478 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
479 MARKREACHED(tempbptr, tempsp); \
482 #define BRANCH(tempbptr, tempsp) \
484 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
485 MARKREACHED(tempbptr, tempsp); \
489 /* stack_init ******************************************************************
491 Initialized the stack analysis subsystem (called by jit_init).
493 *******************************************************************************/
495 bool stack_init(void)
501 /* stack_create_invars *********************************************************
503 Create the invars for the given basic block.
506 sd...........stack analysis data
507 b............block to create the invars for
508 curstack.....current stack top
509 stackdepth...current stack depth
511 This function creates STACKDEPTH invars and sets their types to the
512 types to the types of the corresponding slot in the current stack.
514 *******************************************************************************/
516 static void stack_create_invars(stackdata_t *sd, basicblock *b,
517 stackptr curstack, int stackdepth)
524 assert(sd->vartop + stackdepth <= sd->varcount);
526 b->indepth = stackdepth;
527 b->invars = DMNEW(s4, stackdepth);
529 /* allocate the variable indices */
530 index = (sd->vartop += stackdepth);
533 for (sp = curstack; i--; sp = sp->prev) {
534 b->invars[i] = --index;
542 /* stack_check_invars **********************************************************
544 Check the current stack against the invars of the given basic block.
545 Depth and types must match.
548 sd...........stack analysis data
549 b............block which invars to check against
550 curstack.....current stack top
551 stackdepth...current stack depth
554 true.........everything ok
555 false........a VerifyError has been thrown
557 *******************************************************************************/
559 /* XXX only if ENABLE_VERIFIER */
560 static bool stack_check_invars(stackdata_t *sd, basicblock *b,
561 stackptr curstack, int stackdepth)
567 if (depth != stackdepth) {
568 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
573 if (sd->var[b->invars[depth]].type != curstack->type) {
574 exceptions_throw_verifyerror_for_stack(sd->m,
575 sd->var[b->invars[depth]].type);
578 curstack = curstack->prev;
585 /* stack_create_instack ********************************************************
587 Create the instack of the current basic block.
590 sd...........stack analysis data
593 the current stack top at the start of the basic block.
595 *******************************************************************************/
597 static stackptr stack_create_instack(stackdata_t *sd)
603 if ((depth = sd->bptr->indepth) == 0)
606 sp = (sd->new += depth);
610 index = sd->bptr->invars[depth];
612 sp->type = sd->var[index].type;
616 sp->varkind = STACKVAR;
620 /* return the top of the created stack */
625 /* MARKREACHED marks the destination block <b> as reached. If this
626 * block has been reached before we check if stack depth and types
627 * match. Otherwise the destination block receives a copy of the
628 * current stack as its input stack.
630 * b...destination block
634 static bool stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
636 /* mark targets of backward branches */
638 b->bitflags |= BBFLAG_REPLACEMENT;
640 if (b->flags < BBREACHED) {
641 /* b is reached for the first time. Create its instack */
642 stack_create_invars(sd, b, curstack, stackdepth);
644 b->flags = BBREACHED;
647 /* b has been reached before. Check that its instack matches */
648 if (!stack_check_invars(sd, b, curstack, stackdepth))
656 /* stack_analyse ***************************************************************
658 Analyse_stack uses the intermediate code created by parse.c to
659 build a model of the JVM operand stack for the current method.
661 The following checks are performed:
662 - check for operand stack underflow (before each instruction)
663 - check for operand stack overflow (after[1] each instruction)
664 - check for matching stack depth at merging points
665 - check for matching basic types[2] at merging points
666 - check basic types for instruction input (except for BUILTIN*
667 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
669 [1]) Checking this after the instruction should be ok. parse.c
670 counts the number of required stack slots in such a way that it is
671 only vital that we don't exceed `maxstack` at basic block
674 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
675 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
676 types are not discerned.
678 *******************************************************************************/
680 bool new_stack_analyse(jitdata *jd)
682 methodinfo *m; /* method being analyzed */
687 int b_count; /* basic block counter */
688 int b_index; /* basic block index */
690 stackptr curstack; /* current stack top */
692 int opcode; /* opcode of current instruction */
695 int len; /* # of instructions after the current one */
696 bool superblockend; /* if true, no fallthrough to next block */
697 bool repeat; /* if true, outermost loop must run again */
698 bool deadcode; /* true if no live code has been reached */
699 instruction *iptr; /* the current instruction */
702 stackptr *last_store_boundary;
703 stackptr coalescing_boundary;
705 stackptr src1, src2, src3, src4, dst1, dst2;
707 branch_target_t *table;
708 lookup_target_t *lookup;
709 #if defined(ENABLE_VERIFIER)
710 int expectedtype; /* used by CHECK_BASIC_TYPE */
712 builtintable_entry *bte;
714 constant_FMIref *fmiref;
715 #if defined(ENABLE_STATISTICS)
716 int iteration_count; /* number of iterations of analysis */
718 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
720 #if defined(STACK_VERBOSE)
721 new_show_method(jd, SHOW_PARSE);
724 /* get required compiler data - initialization */
731 /* initialize the stackdata_t struct */
734 sd.varcount = jd->varcount;
735 sd.vartop = jd->vartop;
736 sd.localcount = jd->localcount;
738 sd.new = jd->new_stack;
740 #if defined(ENABLE_LSRA)
744 #if defined(ENABLE_STATISTICS)
748 /* init jd->interface_map */
750 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
751 for (i = 0; i < m->maxstack * 5; i++)
752 jd->interface_map[i].flags = UNUSED;
754 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
756 /* initialize in-stack of first block */
758 jd->new_basicblocks[0].flags = BBREACHED;
759 jd->new_basicblocks[0].invars = NULL;
760 jd->new_basicblocks[0].indepth = 0;
762 /* initialize in-stack of exception handlers */
764 for (i = 0; i < cd->exceptiontablelength; i++) {
765 sd.bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
766 sd.bptr->flags = BBREACHED;
767 sd.bptr->type = BBTYPE_EXH;
768 sd.bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
770 GET_NEW_VAR(sd, new_index, TYPE_ADR);
771 sd.bptr->invars = DMNEW(s4, 1);
772 sd.bptr->invars[0] = new_index;
773 sd.bptr->indepth = 1;
774 sd.var[new_index].flags |= OUTVAR;
776 jd->interface_map[0 * 5 + TYPE_ADR].flags = 0;
779 /* stack analysis loop (until fixpoint reached) **************************/
782 #if defined(ENABLE_STATISTICS)
786 /* initialize loop over basic blocks */
788 b_count = jd->new_basicblockcount;
789 sd.bptr = jd->new_basicblocks;
790 superblockend = true;
792 curstack = NULL; stackdepth = 0;
795 /* iterate over basic blocks *****************************************/
797 while (--b_count >= 0) {
798 #if defined(STACK_VERBOSE)
799 printf("----\nANALYZING BLOCK L%03d ", sd.bptr->nr);
800 if (sd.bptr->type == BBTYPE_EXH) printf("EXH\n");
801 else if (sd.bptr->type == BBTYPE_SBR) printf("SBR\n");
802 else printf("STD\n");
806 if (sd.bptr->flags == BBDELETED) {
807 /* This block has been deleted - do nothing. */
809 else if (superblockend && (sd.bptr->flags < BBREACHED)) {
810 /* This block has not been reached so far, and we */
811 /* don't fall into it, so we'll have to iterate again. */
815 else if (sd.bptr->flags <= BBREACHED) {
817 /* We know that sd.bptr->flags == BBREACHED. */
818 /* This block has been reached before. */
820 stackdepth = sd.bptr->indepth;
822 else if (sd.bptr->flags < BBREACHED) {
823 /* This block is reached for the first time now */
824 /* by falling through from the previous block. */
825 /* Create the instack (propagated). */
827 stack_create_invars(&sd, sd.bptr, curstack, stackdepth);
830 /* This block has been reached before. now we are */
831 /* falling into it from the previous block. */
832 /* Check that stack depth is well-defined. */
834 if (!stack_check_invars(&sd, sd.bptr, curstack, stackdepth))
838 /* create the instack of this block */
840 curstack = stack_create_instack(&sd);
842 /* set up local variables for analyzing this block */
845 superblockend = false;
846 len = sd.bptr->icount;
847 iptr = sd.bptr->iinstr;
848 b_index = sd.bptr - jd->new_basicblocks;
850 /* mark the block as analysed */
852 sd.bptr->flags = BBFINISHED;
854 /* reset variables for dependency checking */
856 coalescing_boundary = sd.new;
857 for( i = 0; i < cd->maxlocals; i++)
858 last_store_boundary[i] = sd.new;
860 /* remember the start of this block's variables */
862 sd.bptr->varstart = sd.vartop;
864 #if defined(STACK_VERBOSE)
865 printf("INVARS - indices:\t\n");
866 for (i=0; i<sd.bptr->indepth; ++i) {
867 printf("%d ", sd.bptr->invars[i]);
872 /* iterate over ICMDs ****************************************/
876 #if defined(STACK_VERBOSE)
877 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
878 for( copy = curstack; copy; copy = copy->prev ) {
879 printf("%2d(%d", copy->varnum, copy->type);
882 if (IS_PREALLOC(copy))
889 /* fetch the current opcode */
893 /* automatically replace some ICMDs with builtins */
895 #if defined(USEBUILTINTABLE)
897 bte = builtintable_get_automatic(opcode);
899 if (bte && bte->opcode == opcode) {
900 iptr->opc = ICMD_BUILTIN;
901 iptr->flags.bits = 0;
902 iptr->sx.s23.s3.bte = bte;
903 /* iptr->line is already set */
904 jd->isleafmethod = false;
908 #endif /* defined(USEBUILTINTABLE) */
910 /* main opcode switch *************************************/
923 coalescing_boundary = sd.new;
924 COUNT(count_check_null);
927 CLR_DST; /* XXX live through? */
932 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
934 USE_S1_LOCAL(TYPE_ADR);
938 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
940 superblockend = true;
944 COUNT(count_pcmd_return);
947 superblockend = true;
951 /* pop 0 push 1 const */
953 /************************** ICONST OPTIMIZATIONS **************************/
956 COUNT(count_pcmd_load);
960 switch (iptr[1].opc) {
962 iptr->opc = ICMD_IADDCONST;
966 iptr[1].opc = ICMD_NOP;
967 OP1_1(TYPE_INT, TYPE_INT);
968 COUNT(count_pcmd_op);
972 iptr->opc = ICMD_ISUBCONST;
973 goto icmd_iconst_tail;
974 #if SUPPORT_CONST_MUL
976 iptr->opc = ICMD_IMULCONST;
977 goto icmd_iconst_tail;
978 #else /* SUPPORT_CONST_MUL */
980 if (iptr->sx.val.i == 0x00000002)
982 else if (iptr->sx.val.i == 0x00000004)
984 else if (iptr->sx.val.i == 0x00000008)
986 else if (iptr->sx.val.i == 0x00000010)
988 else if (iptr->sx.val.i == 0x00000020)
990 else if (iptr->sx.val.i == 0x00000040)
992 else if (iptr->sx.val.i == 0x00000080)
994 else if (iptr->sx.val.i == 0x00000100)
996 else if (iptr->sx.val.i == 0x00000200)
998 else if (iptr->sx.val.i == 0x00000400)
1000 else if (iptr->sx.val.i == 0x00000800)
1001 iptr->sx.val.i = 11;
1002 else if (iptr->sx.val.i == 0x00001000)
1003 iptr->sx.val.i = 12;
1004 else if (iptr->sx.val.i == 0x00002000)
1005 iptr->sx.val.i = 13;
1006 else if (iptr->sx.val.i == 0x00004000)
1007 iptr->sx.val.i = 14;
1008 else if (iptr->sx.val.i == 0x00008000)
1009 iptr->sx.val.i = 15;
1010 else if (iptr->sx.val.i == 0x00010000)
1011 iptr->sx.val.i = 16;
1012 else if (iptr->sx.val.i == 0x00020000)
1013 iptr->sx.val.i = 17;
1014 else if (iptr->sx.val.i == 0x00040000)
1015 iptr->sx.val.i = 18;
1016 else if (iptr->sx.val.i == 0x00080000)
1017 iptr->sx.val.i = 19;
1018 else if (iptr->sx.val.i == 0x00100000)
1019 iptr->sx.val.i = 20;
1020 else if (iptr->sx.val.i == 0x00200000)
1021 iptr->sx.val.i = 21;
1022 else if (iptr->sx.val.i == 0x00400000)
1023 iptr->sx.val.i = 22;
1024 else if (iptr->sx.val.i == 0x00800000)
1025 iptr->sx.val.i = 23;
1026 else if (iptr->sx.val.i == 0x01000000)
1027 iptr->sx.val.i = 24;
1028 else if (iptr->sx.val.i == 0x02000000)
1029 iptr->sx.val.i = 25;
1030 else if (iptr->sx.val.i == 0x04000000)
1031 iptr->sx.val.i = 26;
1032 else if (iptr->sx.val.i == 0x08000000)
1033 iptr->sx.val.i = 27;
1034 else if (iptr->sx.val.i == 0x10000000)
1035 iptr->sx.val.i = 28;
1036 else if (iptr->sx.val.i == 0x20000000)
1037 iptr->sx.val.i = 29;
1038 else if (iptr->sx.val.i == 0x40000000)
1039 iptr->sx.val.i = 30;
1040 else if (iptr->sx.val.i == 0x80000000)
1041 iptr->sx.val.i = 31;
1045 iptr->opc = ICMD_IMULPOW2;
1046 goto icmd_iconst_tail;
1047 #endif /* SUPPORT_CONST_MUL */
1049 if (iptr->sx.val.i == 0x00000002)
1051 else if (iptr->sx.val.i == 0x00000004)
1053 else if (iptr->sx.val.i == 0x00000008)
1055 else if (iptr->sx.val.i == 0x00000010)
1057 else if (iptr->sx.val.i == 0x00000020)
1059 else if (iptr->sx.val.i == 0x00000040)
1061 else if (iptr->sx.val.i == 0x00000080)
1063 else if (iptr->sx.val.i == 0x00000100)
1065 else if (iptr->sx.val.i == 0x00000200)
1067 else if (iptr->sx.val.i == 0x00000400)
1068 iptr->sx.val.i = 10;
1069 else if (iptr->sx.val.i == 0x00000800)
1070 iptr->sx.val.i = 11;
1071 else if (iptr->sx.val.i == 0x00001000)
1072 iptr->sx.val.i = 12;
1073 else if (iptr->sx.val.i == 0x00002000)
1074 iptr->sx.val.i = 13;
1075 else if (iptr->sx.val.i == 0x00004000)
1076 iptr->sx.val.i = 14;
1077 else if (iptr->sx.val.i == 0x00008000)
1078 iptr->sx.val.i = 15;
1079 else if (iptr->sx.val.i == 0x00010000)
1080 iptr->sx.val.i = 16;
1081 else if (iptr->sx.val.i == 0x00020000)
1082 iptr->sx.val.i = 17;
1083 else if (iptr->sx.val.i == 0x00040000)
1084 iptr->sx.val.i = 18;
1085 else if (iptr->sx.val.i == 0x00080000)
1086 iptr->sx.val.i = 19;
1087 else if (iptr->sx.val.i == 0x00100000)
1088 iptr->sx.val.i = 20;
1089 else if (iptr->sx.val.i == 0x00200000)
1090 iptr->sx.val.i = 21;
1091 else if (iptr->sx.val.i == 0x00400000)
1092 iptr->sx.val.i = 22;
1093 else if (iptr->sx.val.i == 0x00800000)
1094 iptr->sx.val.i = 23;
1095 else if (iptr->sx.val.i == 0x01000000)
1096 iptr->sx.val.i = 24;
1097 else if (iptr->sx.val.i == 0x02000000)
1098 iptr->sx.val.i = 25;
1099 else if (iptr->sx.val.i == 0x04000000)
1100 iptr->sx.val.i = 26;
1101 else if (iptr->sx.val.i == 0x08000000)
1102 iptr->sx.val.i = 27;
1103 else if (iptr->sx.val.i == 0x10000000)
1104 iptr->sx.val.i = 28;
1105 else if (iptr->sx.val.i == 0x20000000)
1106 iptr->sx.val.i = 29;
1107 else if (iptr->sx.val.i == 0x40000000)
1108 iptr->sx.val.i = 30;
1109 else if (iptr->sx.val.i == 0x80000000)
1110 iptr->sx.val.i = 31;
1114 iptr->opc = ICMD_IDIVPOW2;
1115 goto icmd_iconst_tail;
1118 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
1119 if ((iptr->sx.val.i == 0x00000002) ||
1120 (iptr->sx.val.i == 0x00000004) ||
1121 (iptr->sx.val.i == 0x00000008) ||
1122 (iptr->sx.val.i == 0x00000010) ||
1123 (iptr->sx.val.i == 0x00000020) ||
1124 (iptr->sx.val.i == 0x00000040) ||
1125 (iptr->sx.val.i == 0x00000080) ||
1126 (iptr->sx.val.i == 0x00000100) ||
1127 (iptr->sx.val.i == 0x00000200) ||
1128 (iptr->sx.val.i == 0x00000400) ||
1129 (iptr->sx.val.i == 0x00000800) ||
1130 (iptr->sx.val.i == 0x00001000) ||
1131 (iptr->sx.val.i == 0x00002000) ||
1132 (iptr->sx.val.i == 0x00004000) ||
1133 (iptr->sx.val.i == 0x00008000) ||
1134 (iptr->sx.val.i == 0x00010000) ||
1135 (iptr->sx.val.i == 0x00020000) ||
1136 (iptr->sx.val.i == 0x00040000) ||
1137 (iptr->sx.val.i == 0x00080000) ||
1138 (iptr->sx.val.i == 0x00100000) ||
1139 (iptr->sx.val.i == 0x00200000) ||
1140 (iptr->sx.val.i == 0x00400000) ||
1141 (iptr->sx.val.i == 0x00800000) ||
1142 (iptr->sx.val.i == 0x01000000) ||
1143 (iptr->sx.val.i == 0x02000000) ||
1144 (iptr->sx.val.i == 0x04000000) ||
1145 (iptr->sx.val.i == 0x08000000) ||
1146 (iptr->sx.val.i == 0x10000000) ||
1147 (iptr->sx.val.i == 0x20000000) ||
1148 (iptr->sx.val.i == 0x40000000) ||
1149 (iptr->sx.val.i == 0x80000000))
1151 iptr->opc = ICMD_IREMPOW2;
1152 iptr->sx.val.i -= 1;
1153 goto icmd_iconst_tail;
1156 #if SUPPORT_CONST_LOGICAL
1158 iptr->opc = ICMD_IANDCONST;
1159 goto icmd_iconst_tail;
1162 iptr->opc = ICMD_IORCONST;
1163 goto icmd_iconst_tail;
1166 iptr->opc = ICMD_IXORCONST;
1167 goto icmd_iconst_tail;
1169 #endif /* SUPPORT_CONST_LOGICAL */
1171 iptr->opc = ICMD_ISHLCONST;
1172 goto icmd_iconst_tail;
1175 iptr->opc = ICMD_ISHRCONST;
1176 goto icmd_iconst_tail;
1179 iptr->opc = ICMD_IUSHRCONST;
1180 goto icmd_iconst_tail;
1181 #if SUPPORT_LONG_SHIFT
1183 iptr->opc = ICMD_LSHLCONST;
1184 goto icmd_lconst_tail;
1187 iptr->opc = ICMD_LSHRCONST;
1188 goto icmd_lconst_tail;
1191 iptr->opc = ICMD_LUSHRCONST;
1192 goto icmd_lconst_tail;
1193 #endif /* SUPPORT_LONG_SHIFT */
1194 case ICMD_IF_ICMPEQ:
1195 iptr[1].opc = ICMD_IFEQ;
1199 /* set the constant for the following icmd */
1200 iptr[1].sx.val.i = iptr->sx.val.i;
1202 /* this instruction becomes a nop */
1203 iptr->opc = ICMD_NOP;
1206 case ICMD_IF_ICMPLT:
1207 iptr[1].opc = ICMD_IFLT;
1208 goto icmd_if_icmp_tail;
1210 case ICMD_IF_ICMPLE:
1211 iptr[1].opc = ICMD_IFLE;
1212 goto icmd_if_icmp_tail;
1214 case ICMD_IF_ICMPNE:
1215 iptr[1].opc = ICMD_IFNE;
1216 goto icmd_if_icmp_tail;
1218 case ICMD_IF_ICMPGT:
1219 iptr[1].opc = ICMD_IFGT;
1220 goto icmd_if_icmp_tail;
1222 case ICMD_IF_ICMPGE:
1223 iptr[1].opc = ICMD_IFGE;
1224 goto icmd_if_icmp_tail;
1226 #if SUPPORT_CONST_STORE
1231 IF_INTRP( goto normal_ICONST; )
1232 # if SUPPORT_CONST_STORE_ZERO_ONLY
1233 if (iptr->sx.val.i != 0)
1236 switch (iptr[1].opc) {
1238 iptr->opc = ICMD_IASTORECONST;
1239 iptr->flags.bits |= INS_FLAG_CHECK;
1242 iptr->opc = ICMD_BASTORECONST;
1243 iptr->flags.bits |= INS_FLAG_CHECK;
1246 iptr->opc = ICMD_CASTORECONST;
1247 iptr->flags.bits |= INS_FLAG_CHECK;
1250 iptr->opc = ICMD_SASTORECONST;
1251 iptr->flags.bits |= INS_FLAG_CHECK;
1255 iptr[1].opc = ICMD_NOP;
1257 /* copy the constant to s3 */
1258 /* XXX constval -> astoreconstval? */
1259 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1260 OP2_0(TYPE_ADR, TYPE_INT);
1261 COUNT(count_pcmd_op);
1264 case ICMD_PUTSTATIC:
1266 IF_INTRP( goto normal_ICONST; )
1267 # if SUPPORT_CONST_STORE_ZERO_ONLY
1268 if (iptr->sx.val.i != 0)
1271 /* XXX check field type? */
1273 /* copy the constant to s2 */
1274 /* XXX constval -> fieldconstval? */
1275 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1278 /* set the field reference (s3) */
1279 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1280 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1281 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1284 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1287 switch (iptr[1].opc) {
1288 case ICMD_PUTSTATIC:
1289 iptr->opc = ICMD_PUTSTATICCONST;
1293 iptr->opc = ICMD_PUTFIELDCONST;
1298 iptr[1].opc = ICMD_NOP;
1299 COUNT(count_pcmd_op);
1301 #endif /* SUPPORT_CONST_STORE */
1307 /* if we get here, the ICONST has been optimized */
1311 /* normal case of an unoptimized ICONST */
1315 /************************** LCONST OPTIMIZATIONS **************************/
1318 COUNT(count_pcmd_load);
1322 /* switch depending on the following instruction */
1324 switch (iptr[1].opc) {
1325 #if SUPPORT_LONG_ADD
1327 iptr->opc = ICMD_LADDCONST;
1331 /* instruction of type LONG -> LONG */
1332 iptr[1].opc = ICMD_NOP;
1333 OP1_1(TYPE_LNG, TYPE_LNG);
1334 COUNT(count_pcmd_op);
1338 iptr->opc = ICMD_LSUBCONST;
1339 goto icmd_lconst_tail;
1341 #endif /* SUPPORT_LONG_ADD */
1342 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1344 iptr->opc = ICMD_LMULCONST;
1345 goto icmd_lconst_tail;
1346 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1347 # if SUPPORT_LONG_SHIFT
1349 if (iptr->sx.val.l == 0x00000002)
1351 else if (iptr->sx.val.l == 0x00000004)
1353 else if (iptr->sx.val.l == 0x00000008)
1355 else if (iptr->sx.val.l == 0x00000010)
1357 else if (iptr->sx.val.l == 0x00000020)
1359 else if (iptr->sx.val.l == 0x00000040)
1361 else if (iptr->sx.val.l == 0x00000080)
1363 else if (iptr->sx.val.l == 0x00000100)
1365 else if (iptr->sx.val.l == 0x00000200)
1367 else if (iptr->sx.val.l == 0x00000400)
1368 iptr->sx.val.i = 10;
1369 else if (iptr->sx.val.l == 0x00000800)
1370 iptr->sx.val.i = 11;
1371 else if (iptr->sx.val.l == 0x00001000)
1372 iptr->sx.val.i = 12;
1373 else if (iptr->sx.val.l == 0x00002000)
1374 iptr->sx.val.i = 13;
1375 else if (iptr->sx.val.l == 0x00004000)
1376 iptr->sx.val.i = 14;
1377 else if (iptr->sx.val.l == 0x00008000)
1378 iptr->sx.val.i = 15;
1379 else if (iptr->sx.val.l == 0x00010000)
1380 iptr->sx.val.i = 16;
1381 else if (iptr->sx.val.l == 0x00020000)
1382 iptr->sx.val.i = 17;
1383 else if (iptr->sx.val.l == 0x00040000)
1384 iptr->sx.val.i = 18;
1385 else if (iptr->sx.val.l == 0x00080000)
1386 iptr->sx.val.i = 19;
1387 else if (iptr->sx.val.l == 0x00100000)
1388 iptr->sx.val.i = 20;
1389 else if (iptr->sx.val.l == 0x00200000)
1390 iptr->sx.val.i = 21;
1391 else if (iptr->sx.val.l == 0x00400000)
1392 iptr->sx.val.i = 22;
1393 else if (iptr->sx.val.l == 0x00800000)
1394 iptr->sx.val.i = 23;
1395 else if (iptr->sx.val.l == 0x01000000)
1396 iptr->sx.val.i = 24;
1397 else if (iptr->sx.val.l == 0x02000000)
1398 iptr->sx.val.i = 25;
1399 else if (iptr->sx.val.l == 0x04000000)
1400 iptr->sx.val.i = 26;
1401 else if (iptr->sx.val.l == 0x08000000)
1402 iptr->sx.val.i = 27;
1403 else if (iptr->sx.val.l == 0x10000000)
1404 iptr->sx.val.i = 28;
1405 else if (iptr->sx.val.l == 0x20000000)
1406 iptr->sx.val.i = 29;
1407 else if (iptr->sx.val.l == 0x40000000)
1408 iptr->sx.val.i = 30;
1409 else if (iptr->sx.val.l == 0x80000000)
1410 iptr->sx.val.i = 31;
1414 iptr->opc = ICMD_LMULPOW2;
1415 goto icmd_lconst_tail;
1416 # endif /* SUPPORT_LONG_SHIFT */
1417 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1418 #if SUPPORT_LONG_DIV_POW2
1420 if (iptr->sx.val.l == 0x00000002)
1422 else if (iptr->sx.val.l == 0x00000004)
1424 else if (iptr->sx.val.l == 0x00000008)
1426 else if (iptr->sx.val.l == 0x00000010)
1428 else if (iptr->sx.val.l == 0x00000020)
1430 else if (iptr->sx.val.l == 0x00000040)
1432 else if (iptr->sx.val.l == 0x00000080)
1434 else if (iptr->sx.val.l == 0x00000100)
1436 else if (iptr->sx.val.l == 0x00000200)
1438 else if (iptr->sx.val.l == 0x00000400)
1439 iptr->sx.val.i = 10;
1440 else if (iptr->sx.val.l == 0x00000800)
1441 iptr->sx.val.i = 11;
1442 else if (iptr->sx.val.l == 0x00001000)
1443 iptr->sx.val.i = 12;
1444 else if (iptr->sx.val.l == 0x00002000)
1445 iptr->sx.val.i = 13;
1446 else if (iptr->sx.val.l == 0x00004000)
1447 iptr->sx.val.i = 14;
1448 else if (iptr->sx.val.l == 0x00008000)
1449 iptr->sx.val.i = 15;
1450 else if (iptr->sx.val.l == 0x00010000)
1451 iptr->sx.val.i = 16;
1452 else if (iptr->sx.val.l == 0x00020000)
1453 iptr->sx.val.i = 17;
1454 else if (iptr->sx.val.l == 0x00040000)
1455 iptr->sx.val.i = 18;
1456 else if (iptr->sx.val.l == 0x00080000)
1457 iptr->sx.val.i = 19;
1458 else if (iptr->sx.val.l == 0x00100000)
1459 iptr->sx.val.i = 20;
1460 else if (iptr->sx.val.l == 0x00200000)
1461 iptr->sx.val.i = 21;
1462 else if (iptr->sx.val.l == 0x00400000)
1463 iptr->sx.val.i = 22;
1464 else if (iptr->sx.val.l == 0x00800000)
1465 iptr->sx.val.i = 23;
1466 else if (iptr->sx.val.l == 0x01000000)
1467 iptr->sx.val.i = 24;
1468 else if (iptr->sx.val.l == 0x02000000)
1469 iptr->sx.val.i = 25;
1470 else if (iptr->sx.val.l == 0x04000000)
1471 iptr->sx.val.i = 26;
1472 else if (iptr->sx.val.l == 0x08000000)
1473 iptr->sx.val.i = 27;
1474 else if (iptr->sx.val.l == 0x10000000)
1475 iptr->sx.val.i = 28;
1476 else if (iptr->sx.val.l == 0x20000000)
1477 iptr->sx.val.i = 29;
1478 else if (iptr->sx.val.l == 0x40000000)
1479 iptr->sx.val.i = 30;
1480 else if (iptr->sx.val.l == 0x80000000)
1481 iptr->sx.val.i = 31;
1485 iptr->opc = ICMD_LDIVPOW2;
1486 goto icmd_lconst_tail;
1487 #endif /* SUPPORT_LONG_DIV_POW2 */
1489 #if SUPPORT_LONG_REM_POW2
1491 if ((iptr->sx.val.l == 0x00000002) ||
1492 (iptr->sx.val.l == 0x00000004) ||
1493 (iptr->sx.val.l == 0x00000008) ||
1494 (iptr->sx.val.l == 0x00000010) ||
1495 (iptr->sx.val.l == 0x00000020) ||
1496 (iptr->sx.val.l == 0x00000040) ||
1497 (iptr->sx.val.l == 0x00000080) ||
1498 (iptr->sx.val.l == 0x00000100) ||
1499 (iptr->sx.val.l == 0x00000200) ||
1500 (iptr->sx.val.l == 0x00000400) ||
1501 (iptr->sx.val.l == 0x00000800) ||
1502 (iptr->sx.val.l == 0x00001000) ||
1503 (iptr->sx.val.l == 0x00002000) ||
1504 (iptr->sx.val.l == 0x00004000) ||
1505 (iptr->sx.val.l == 0x00008000) ||
1506 (iptr->sx.val.l == 0x00010000) ||
1507 (iptr->sx.val.l == 0x00020000) ||
1508 (iptr->sx.val.l == 0x00040000) ||
1509 (iptr->sx.val.l == 0x00080000) ||
1510 (iptr->sx.val.l == 0x00100000) ||
1511 (iptr->sx.val.l == 0x00200000) ||
1512 (iptr->sx.val.l == 0x00400000) ||
1513 (iptr->sx.val.l == 0x00800000) ||
1514 (iptr->sx.val.l == 0x01000000) ||
1515 (iptr->sx.val.l == 0x02000000) ||
1516 (iptr->sx.val.l == 0x04000000) ||
1517 (iptr->sx.val.l == 0x08000000) ||
1518 (iptr->sx.val.l == 0x10000000) ||
1519 (iptr->sx.val.l == 0x20000000) ||
1520 (iptr->sx.val.l == 0x40000000) ||
1521 (iptr->sx.val.l == 0x80000000))
1523 iptr->opc = ICMD_LREMPOW2;
1524 iptr->sx.val.l -= 1;
1525 goto icmd_lconst_tail;
1528 #endif /* SUPPORT_LONG_REM_POW2 */
1530 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1533 iptr->opc = ICMD_LANDCONST;
1534 goto icmd_lconst_tail;
1537 iptr->opc = ICMD_LORCONST;
1538 goto icmd_lconst_tail;
1541 iptr->opc = ICMD_LXORCONST;
1542 goto icmd_lconst_tail;
1543 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1545 #if SUPPORT_LONG_CMP_CONST
1547 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1550 /* switch on the instruction after LCONST - LCMP */
1552 switch (iptr[2].opc) {
1554 iptr->opc = ICMD_IF_LEQ;
1557 icmd_lconst_lcmp_tail:
1558 /* convert LCONST, LCMP, IFXX to IF_LXX */
1559 iptr->dst.insindex = iptr[2].dst.insindex;
1560 iptr[1].opc = ICMD_NOP;
1561 iptr[2].opc = ICMD_NOP;
1563 OP1_BRANCH(TYPE_LNG);
1564 BRANCH(tbptr, copy);
1565 COUNT(count_pcmd_bra);
1566 COUNT(count_pcmd_op);
1570 iptr->opc = ICMD_IF_LNE;
1571 goto icmd_lconst_lcmp_tail;
1574 iptr->opc = ICMD_IF_LLT;
1575 goto icmd_lconst_lcmp_tail;
1578 iptr->opc = ICMD_IF_LGT;
1579 goto icmd_lconst_lcmp_tail;
1582 iptr->opc = ICMD_IF_LLE;
1583 goto icmd_lconst_lcmp_tail;
1586 iptr->opc = ICMD_IF_LGE;
1587 goto icmd_lconst_lcmp_tail;
1591 } /* end switch on opcode after LCONST - LCMP */
1593 #endif /* SUPPORT_LONG_CMP_CONST */
1595 #if SUPPORT_CONST_STORE
1597 IF_INTRP( goto normal_LCONST; )
1598 # if SUPPORT_CONST_STORE_ZERO_ONLY
1599 if (iptr->sx.val.l != 0)
1602 #if SIZEOF_VOID_P == 4
1603 /* the constant must fit into a ptrint */
1604 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1607 /* move the constant to s3 */
1608 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1610 iptr->opc = ICMD_LASTORECONST;
1611 iptr->flags.bits |= INS_FLAG_CHECK;
1612 OP2_0(TYPE_ADR, TYPE_INT);
1614 iptr[1].opc = ICMD_NOP;
1615 COUNT(count_pcmd_op);
1618 case ICMD_PUTSTATIC:
1620 IF_INTRP( goto normal_LCONST; )
1621 # if SUPPORT_CONST_STORE_ZERO_ONLY
1622 if (iptr->sx.val.l != 0)
1625 #if SIZEOF_VOID_P == 4
1626 /* the constant must fit into a ptrint */
1627 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1630 /* XXX check field type? */
1632 /* copy the constant to s2 */
1633 /* XXX constval -> fieldconstval? */
1634 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1638 #endif /* SUPPORT_CONST_STORE */
1642 } /* end switch opcode after LCONST */
1644 /* if we get here, the LCONST has been optimized */
1648 /* the normal case of an unoptimized LCONST */
1652 /************************ END OF LCONST OPTIMIZATIONS *********************/
1655 COUNT(count_pcmd_load);
1660 COUNT(count_pcmd_load);
1664 /************************** ACONST OPTIMIZATIONS **************************/
1667 coalescing_boundary = sd.new;
1668 COUNT(count_pcmd_load);
1669 #if SUPPORT_CONST_STORE
1670 IF_INTRP( goto normal_ACONST; )
1672 /* We can only optimize if the ACONST is resolved
1673 * and there is an instruction after it. */
1675 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1678 switch (iptr[1].opc) {
1680 /* We can only optimize for NULL values
1681 * here because otherwise a checkcast is
1683 if (iptr->sx.val.anyptr != NULL)
1686 /* copy the constant (NULL) to s3 */
1687 iptr->sx.s23.s3.constval = 0;
1688 iptr->opc = ICMD_AASTORECONST;
1689 iptr->flags.bits |= INS_FLAG_CHECK;
1690 OP2_0(TYPE_ADR, TYPE_INT);
1692 iptr[1].opc = ICMD_NOP;
1693 COUNT(count_pcmd_op);
1696 case ICMD_PUTSTATIC:
1698 # if SUPPORT_CONST_STORE_ZERO_ONLY
1699 if (iptr->sx.val.anyptr != NULL)
1702 /* XXX check field type? */
1703 /* copy the constant to s2 */
1704 /* XXX constval -> fieldconstval? */
1705 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1713 /* if we get here the ACONST has been optimized */
1717 #endif /* SUPPORT_CONST_STORE */
1722 /* pop 0 push 1 load */
1729 COUNT(count_load_instruction);
1730 i = opcode - ICMD_ILOAD; /* type */
1733 jd->local_map[iptr->s1.varindex * 5 + i];
1735 LOAD(i, iptr->s1.varindex);
1744 coalescing_boundary = sd.new;
1745 iptr->flags.bits |= INS_FLAG_CHECK;
1746 COUNT(count_check_null);
1747 COUNT(count_check_bound);
1748 COUNT(count_pcmd_mem);
1749 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1756 coalescing_boundary = sd.new;
1757 iptr->flags.bits |= INS_FLAG_CHECK;
1758 COUNT(count_check_null);
1759 COUNT(count_check_bound);
1760 COUNT(count_pcmd_mem);
1761 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1764 /* pop 0 push 0 iinc */
1767 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1769 last_store_boundary[iptr->s1.varindex] = sd.new;
1772 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
1777 if ((copy->varkind == LOCALVAR) &&
1778 (copy->varnum == iptr->s1.varindex))
1780 assert(IS_LOCALVAR(copy));
1787 iptr->dst.varindex = iptr->s1.varindex;
1790 /* pop 1 push 0 store */
1799 i = opcode - ICMD_ISTORE; /* type */
1800 javaindex = iptr->dst.varindex;
1801 j = iptr->dst.varindex =
1802 jd->local_map[javaindex * 5 + i];
1805 #if defined(ENABLE_STATISTICS)
1808 i = sd.new - curstack;
1810 count_store_length[20]++;
1812 count_store_length[i]++;
1815 count_store_depth[10]++;
1817 count_store_depth[i]++;
1820 /* check for conflicts as described in Figure 5.2 */
1822 copy = curstack->prev;
1825 if ((copy->varkind == LOCALVAR) &&
1826 (copy->varnum == j))
1828 copy->varkind = TEMPVAR;
1829 assert(IS_LOCALVAR(copy));
1836 /* if the variable is already coalesced, don't bother */
1838 if (IS_OUTVAR(curstack)
1839 || (curstack->varkind == LOCALVAR
1840 && curstack->varnum != j))
1843 /* there is no STORE Lj while curstack is live */
1845 if (curstack < last_store_boundary[javaindex])
1846 goto assume_conflict;
1848 /* curstack must be after the coalescing boundary */
1850 if (curstack < coalescing_boundary)
1851 goto assume_conflict;
1853 /* there is no DEF LOCALVAR(j) while curstack is live */
1855 copy = sd.new; /* most recent stackslot created + 1 */
1856 while (--copy > curstack) {
1857 if (copy->varkind == LOCALVAR && copy->varnum == j)
1858 goto assume_conflict;
1861 /* coalesce the temporary variable with Lj */
1862 assert((curstack->varkind == TEMPVAR)
1863 || (curstack->varkind == UNDEFVAR));
1864 assert(!IS_LOCALVAR(curstack));
1865 assert(!IS_OUTVAR(curstack));
1866 assert(!IS_PREALLOC(curstack));
1868 assert(curstack->creator);
1869 assert(curstack->creator->dst.varindex == curstack->varnum);
1870 RELEASE_INDEX(sd, curstack);
1871 curstack->varkind = LOCALVAR;
1872 curstack->varnum = j;
1873 curstack->creator->dst.varindex = j;
1876 /* revert the coalescing, if it has been done earlier */
1878 if ((curstack->varkind == LOCALVAR)
1879 && (curstack->varnum == j))
1881 assert(IS_LOCALVAR(curstack));
1882 SET_TEMPVAR(curstack);
1885 /* remember the stack boundary at this store */
1887 last_store_boundary[javaindex] = sd.new;
1889 STORE(opcode - ICMD_ISTORE, j);
1895 coalescing_boundary = sd.new;
1896 iptr->flags.bits |= INS_FLAG_CHECK;
1897 COUNT(count_check_null);
1898 COUNT(count_check_bound);
1899 COUNT(count_pcmd_mem);
1901 bte = builtintable_get_internal(BUILTIN_canstore);
1904 if (md->memuse > rd->memuse)
1905 rd->memuse = md->memuse;
1906 if (md->argintreguse > rd->argintreguse)
1907 rd->argintreguse = md->argintreguse;
1908 /* XXX non-leaf method? */
1910 /* make all stack variables saved */
1914 sd.var[copy->varnum].flags |= SAVEDVAR;
1915 /* in case copy->varnum is/will be a LOCALVAR */
1916 /* once and set back to a non LOCALVAR */
1917 /* the correct SAVEDVAR flag has to be */
1918 /* remembered in copy->flags, too */
1919 copy->flags |= SAVEDVAR;
1923 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1930 coalescing_boundary = sd.new;
1931 iptr->flags.bits |= INS_FLAG_CHECK;
1932 COUNT(count_check_null);
1933 COUNT(count_check_bound);
1934 COUNT(count_pcmd_mem);
1935 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1942 coalescing_boundary = sd.new;
1943 iptr->flags.bits |= INS_FLAG_CHECK;
1944 COUNT(count_check_null);
1945 COUNT(count_check_bound);
1946 COUNT(count_pcmd_mem);
1947 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1953 #ifdef ENABLE_VERIFIER
1956 if (IS_2_WORD_TYPE(curstack->type))
1957 goto throw_stack_category_error;
1968 coalescing_boundary = sd.new;
1969 IF_JIT( md_return_alloc(jd, curstack); )
1970 COUNT(count_pcmd_return);
1971 OP1_0(opcode - ICMD_IRETURN);
1972 superblockend = true;
1976 coalescing_boundary = sd.new;
1977 COUNT(count_check_null);
1979 curstack = NULL; stackdepth = 0;
1980 superblockend = true;
1983 case ICMD_PUTSTATIC:
1984 coalescing_boundary = sd.new;
1985 COUNT(count_pcmd_mem);
1986 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1987 OP1_0(fmiref->parseddesc.fd->type);
1990 /* pop 1 push 0 branch */
1993 case ICMD_IFNONNULL:
1994 COUNT(count_pcmd_bra);
1995 OP1_BRANCH(TYPE_ADR);
1996 BRANCH(tbptr, copy);
2005 COUNT(count_pcmd_bra);
2006 /* iptr->sx.val.i is set implicitly in parse by
2007 clearing the memory or from IF_ICMPxx
2010 OP1_BRANCH(TYPE_INT);
2011 /* iptr->sx.val.i = 0; */
2012 BRANCH(tbptr, copy);
2015 /* pop 0 push 0 branch */
2018 COUNT(count_pcmd_bra);
2020 BRANCH(tbptr, copy);
2021 superblockend = true;
2024 /* pop 1 push 0 table branch */
2026 case ICMD_TABLESWITCH:
2027 COUNT(count_pcmd_table);
2028 OP1_BRANCH(TYPE_INT);
2030 table = iptr->dst.table;
2031 BRANCH_TARGET(*table, tbptr, copy);
2034 i = iptr->sx.s23.s3.tablehigh
2035 - iptr->sx.s23.s2.tablelow + 1;
2038 BRANCH_TARGET(*table, tbptr, copy);
2041 superblockend = true;
2044 /* pop 1 push 0 table branch */
2046 case ICMD_LOOKUPSWITCH:
2047 COUNT(count_pcmd_table);
2048 OP1_BRANCH(TYPE_INT);
2050 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
2052 lookup = iptr->dst.lookup;
2054 i = iptr->sx.s23.s2.lookupcount;
2057 BRANCH_TARGET(lookup->target, tbptr, copy);
2060 superblockend = true;
2063 case ICMD_MONITORENTER:
2064 case ICMD_MONITOREXIT:
2065 coalescing_boundary = sd.new;
2066 COUNT(count_check_null);
2070 /* pop 2 push 0 branch */
2072 case ICMD_IF_ICMPEQ:
2073 case ICMD_IF_ICMPNE:
2074 case ICMD_IF_ICMPLT:
2075 case ICMD_IF_ICMPGE:
2076 case ICMD_IF_ICMPGT:
2077 case ICMD_IF_ICMPLE:
2078 COUNT(count_pcmd_bra);
2079 OP2_BRANCH(TYPE_INT, TYPE_INT);
2080 BRANCH(tbptr, copy);
2083 case ICMD_IF_ACMPEQ:
2084 case ICMD_IF_ACMPNE:
2085 COUNT(count_pcmd_bra);
2086 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
2087 BRANCH(tbptr, copy);
2093 coalescing_boundary = sd.new;
2094 COUNT(count_check_null);
2095 COUNT(count_pcmd_mem);
2096 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2097 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
2102 if (!IS_2_WORD_TYPE(curstack->type)) {
2104 #ifdef ENABLE_VERIFIER
2107 if (IS_2_WORD_TYPE(curstack->prev->type))
2108 goto throw_stack_category_error;
2111 OP2_0_ANY_ANY; /* pop two slots */
2114 iptr->opc = ICMD_POP;
2115 OP1_0_ANY; /* pop one (two-word) slot */
2119 /* pop 0 push 1 dup */
2122 #ifdef ENABLE_VERIFIER
2125 if (IS_2_WORD_TYPE(curstack->type))
2126 goto throw_stack_category_error;
2129 COUNT(count_dup_instruction);
2135 coalescing_boundary = sd.new - 1;
2140 if (IS_2_WORD_TYPE(curstack->type)) {
2142 iptr->opc = ICMD_DUP;
2147 /* ..., ????, cat1 */
2148 #ifdef ENABLE_VERIFIER
2150 if (IS_2_WORD_TYPE(curstack->prev->type))
2151 goto throw_stack_category_error;
2154 src1 = curstack->prev;
2157 COPY_UP(src1); iptr++; len--;
2160 coalescing_boundary = sd.new;
2164 /* pop 2 push 3 dup */
2167 #ifdef ENABLE_VERIFIER
2170 if (IS_2_WORD_TYPE(curstack->type) ||
2171 IS_2_WORD_TYPE(curstack->prev->type))
2172 goto throw_stack_category_error;
2177 src1 = curstack->prev;
2182 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2184 MOVE_UP(src1); iptr++; len--;
2185 MOVE_UP(src2); iptr++; len--;
2187 COPY_DOWN(curstack, dst1);
2189 coalescing_boundary = sd.new;
2194 if (IS_2_WORD_TYPE(curstack->type)) {
2195 /* ..., ????, cat2 */
2196 #ifdef ENABLE_VERIFIER
2198 if (IS_2_WORD_TYPE(curstack->prev->type))
2199 goto throw_stack_category_error;
2202 iptr->opc = ICMD_DUP_X1;
2206 /* ..., ????, cat1 */
2207 #ifdef ENABLE_VERIFIER
2210 if (IS_2_WORD_TYPE(curstack->prev->type)
2211 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2212 goto throw_stack_category_error;
2217 src1 = curstack->prev->prev;
2218 src2 = curstack->prev;
2220 POPANY; POPANY; POPANY;
2223 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2224 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
2226 MOVE_UP(src1); iptr++; len--;
2227 MOVE_UP(src2); iptr++; len--;
2228 MOVE_UP(src3); iptr++; len--;
2230 COPY_DOWN(curstack, dst2); iptr++; len--;
2231 COPY_DOWN(curstack->prev, dst1);
2233 coalescing_boundary = sd.new;
2237 /* pop 3 push 4 dup */
2241 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2242 /* ..., cat2, ???? */
2243 #ifdef ENABLE_VERIFIER
2245 if (IS_2_WORD_TYPE(curstack->type))
2246 goto throw_stack_category_error;
2249 iptr->opc = ICMD_DUP_X1;
2253 /* ..., cat1, ???? */
2254 #ifdef ENABLE_VERIFIER
2257 if (IS_2_WORD_TYPE(curstack->type)
2258 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2259 goto throw_stack_category_error;
2263 src1 = curstack->prev->prev;
2264 src2 = curstack->prev;
2266 POPANY; POPANY; POPANY;
2269 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2271 MOVE_UP(src1); iptr++; len--;
2272 MOVE_UP(src2); iptr++; len--;
2273 MOVE_UP(src3); iptr++; len--;
2275 COPY_DOWN(curstack, dst1);
2277 coalescing_boundary = sd.new;
2283 if (IS_2_WORD_TYPE(curstack->type)) {
2284 /* ..., ????, cat2 */
2285 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2286 /* ..., cat2, cat2 */
2287 iptr->opc = ICMD_DUP_X1;
2291 /* ..., cat1, cat2 */
2292 #ifdef ENABLE_VERIFIER
2295 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2296 goto throw_stack_category_error;
2299 iptr->opc = ICMD_DUP_X2;
2305 /* ..., ????, ????, cat1 */
2307 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2308 /* ..., cat2, ????, cat1 */
2309 #ifdef ENABLE_VERIFIER
2311 if (IS_2_WORD_TYPE(curstack->prev->type))
2312 goto throw_stack_category_error;
2315 iptr->opc = ICMD_DUP2_X1;
2319 /* ..., cat1, ????, cat1 */
2320 #ifdef ENABLE_VERIFIER
2323 if (IS_2_WORD_TYPE(curstack->prev->type)
2324 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2325 goto throw_stack_category_error;
2329 src1 = curstack->prev->prev->prev;
2330 src2 = curstack->prev->prev;
2331 src3 = curstack->prev;
2333 POPANY; POPANY; POPANY; POPANY;
2336 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2337 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
2339 MOVE_UP(src1); iptr++; len--;
2340 MOVE_UP(src2); iptr++; len--;
2341 MOVE_UP(src3); iptr++; len--;
2342 MOVE_UP(src4); iptr++; len--;
2344 COPY_DOWN(curstack, dst2); iptr++; len--;
2345 COPY_DOWN(curstack->prev, dst1);
2347 coalescing_boundary = sd.new;
2351 /* pop 2 push 2 swap */
2354 #ifdef ENABLE_VERIFIER
2357 if (IS_2_WORD_TYPE(curstack->type)
2358 || IS_2_WORD_TYPE(curstack->prev->type))
2359 goto throw_stack_category_error;
2363 src1 = curstack->prev;
2368 MOVE_UP(src2); iptr++; len--;
2371 coalescing_boundary = sd.new;
2378 coalescing_boundary = sd.new;
2379 #if !SUPPORT_DIVISION
2380 bte = iptr->sx.s23.s3.bte;
2383 if (md->memuse > rd->memuse)
2384 rd->memuse = md->memuse;
2385 if (md->argintreguse > rd->argintreguse)
2386 rd->argintreguse = md->argintreguse;
2388 /* make all stack variables saved */
2392 sd.var[copy->varnum].flags |= SAVEDVAR;
2393 copy->flags |= SAVEDVAR;
2398 #endif /* !SUPPORT_DIVISION */
2409 COUNT(count_pcmd_op);
2410 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2415 coalescing_boundary = sd.new;
2416 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2417 bte = iptr->sx.s23.s3.bte;
2420 if (md->memuse > rd->memuse)
2421 rd->memuse = md->memuse;
2422 if (md->argintreguse > rd->argintreguse)
2423 rd->argintreguse = md->argintreguse;
2424 /* XXX non-leaf method? */
2426 /* make all stack variables saved */
2430 sd.var[copy->varnum].flags |= SAVEDVAR;
2431 copy->flags |= SAVEDVAR;
2436 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2441 #if SUPPORT_LONG_LOGICAL
2445 #endif /* SUPPORT_LONG_LOGICAL */
2446 COUNT(count_pcmd_op);
2447 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2453 COUNT(count_pcmd_op);
2454 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2462 COUNT(count_pcmd_op);
2463 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2471 COUNT(count_pcmd_op);
2472 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2476 COUNT(count_pcmd_op);
2477 #if SUPPORT_LONG_CMP_CONST
2478 if ((len == 0) || (iptr[1].sx.val.i != 0))
2481 switch (iptr[1].opc) {
2483 iptr->opc = ICMD_IF_LCMPEQ;
2485 iptr->dst.insindex = iptr[1].dst.insindex;
2486 iptr[1].opc = ICMD_NOP;
2488 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2489 BRANCH(tbptr, copy);
2491 COUNT(count_pcmd_bra);
2494 iptr->opc = ICMD_IF_LCMPNE;
2495 goto icmd_lcmp_if_tail;
2497 iptr->opc = ICMD_IF_LCMPLT;
2498 goto icmd_lcmp_if_tail;
2500 iptr->opc = ICMD_IF_LCMPGT;
2501 goto icmd_lcmp_if_tail;
2503 iptr->opc = ICMD_IF_LCMPLE;
2504 goto icmd_lcmp_if_tail;
2506 iptr->opc = ICMD_IF_LCMPGE;
2507 goto icmd_lcmp_if_tail;
2513 #endif /* SUPPORT_LONG_CMP_CONST */
2514 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2517 /* XXX why is this deactivated? */
2520 COUNT(count_pcmd_op);
2521 if ((len == 0) || (iptr[1].sx.val.i != 0))
2524 switch (iptr[1].opc) {
2526 iptr->opc = ICMD_IF_FCMPEQ;
2528 iptr->dst.insindex = iptr[1].dst.insindex;
2529 iptr[1].opc = ICMD_NOP;
2531 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2532 BRANCH(tbptr, copy);
2534 COUNT(count_pcmd_bra);
2537 iptr->opc = ICMD_IF_FCMPNE;
2538 goto icmd_if_fcmpl_tail;
2540 iptr->opc = ICMD_IF_FCMPL_LT;
2541 goto icmd_if_fcmpl_tail;
2543 iptr->opc = ICMD_IF_FCMPL_GT;
2544 goto icmd_if_fcmpl_tail;
2546 iptr->opc = ICMD_IF_FCMPL_LE;
2547 goto icmd_if_fcmpl_tail;
2549 iptr->opc = ICMD_IF_FCMPL_GE;
2550 goto icmd_if_fcmpl_tail;
2557 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2561 COUNT(count_pcmd_op);
2562 if ((len == 0) || (iptr[1].sx.val.i != 0))
2565 switch (iptr[1].opc) {
2567 iptr->opc = ICMD_IF_FCMPEQ;
2569 iptr->dst.insindex = iptr[1].dst.insindex;
2570 iptr[1].opc = ICMD_NOP;
2572 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2573 BRANCH(tbptr, copy);
2575 COUNT(count_pcmd_bra);
2578 iptr->opc = ICMD_IF_FCMPNE;
2579 goto icmd_if_fcmpg_tail;
2581 iptr->opc = ICMD_IF_FCMPG_LT;
2582 goto icmd_if_fcmpg_tail;
2584 iptr->opc = ICMD_IF_FCMPG_GT;
2585 goto icmd_if_fcmpg_tail;
2587 iptr->opc = ICMD_IF_FCMPG_LE;
2588 goto icmd_if_fcmpg_tail;
2590 iptr->opc = ICMD_IF_FCMPG_GE;
2591 goto icmd_if_fcmpg_tail;
2598 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2602 COUNT(count_pcmd_op);
2603 if ((len == 0) || (iptr[1].sx.val.i != 0))
2606 switch (iptr[1].opc) {
2608 iptr->opc = ICMD_IF_DCMPEQ;
2610 iptr->dst.insindex = iptr[1].dst.insindex;
2611 iptr[1].opc = ICMD_NOP;
2613 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2614 BRANCH(tbptr, copy);
2616 COUNT(count_pcmd_bra);
2619 iptr->opc = ICMD_IF_DCMPNE;
2620 goto icmd_if_dcmpl_tail;
2622 iptr->opc = ICMD_IF_DCMPL_LT;
2623 goto icmd_if_dcmpl_tail;
2625 iptr->opc = ICMD_IF_DCMPL_GT;
2626 goto icmd_if_dcmpl_tail;
2628 iptr->opc = ICMD_IF_DCMPL_LE;
2629 goto icmd_if_dcmpl_tail;
2631 iptr->opc = ICMD_IF_DCMPL_GE;
2632 goto icmd_if_dcmpl_tail;
2639 OPTT2_1(TYPE_DBL, TYPE_INT);
2643 COUNT(count_pcmd_op);
2644 if ((len == 0) || (iptr[1].sx.val.i != 0))
2647 switch (iptr[1].opc) {
2649 iptr->opc = ICMD_IF_DCMPEQ;
2651 iptr->dst.insindex = iptr[1].dst.insindex;
2652 iptr[1].opc = ICMD_NOP;
2654 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2655 BRANCH(tbptr, copy);
2657 COUNT(count_pcmd_bra);
2660 iptr->opc = ICMD_IF_DCMPNE;
2661 goto icmd_if_dcmpg_tail;
2663 iptr->opc = ICMD_IF_DCMPG_LT;
2664 goto icmd_if_dcmpg_tail;
2666 iptr->opc = ICMD_IF_DCMPG_GT;
2667 goto icmd_if_dcmpg_tail;
2669 iptr->opc = ICMD_IF_DCMPG_LE;
2670 goto icmd_if_dcmpg_tail;
2672 iptr->opc = ICMD_IF_DCMPG_GE;
2673 goto icmd_if_dcmpg_tail;
2680 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2685 COUNT(count_pcmd_op);
2686 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2691 COUNT(count_pcmd_op);
2692 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2701 case ICMD_INT2SHORT:
2702 COUNT(count_pcmd_op);
2703 OP1_1(TYPE_INT, TYPE_INT);
2706 COUNT(count_pcmd_op);
2707 OP1_1(TYPE_LNG, TYPE_LNG);
2710 COUNT(count_pcmd_op);
2711 OP1_1(TYPE_FLT, TYPE_FLT);
2714 COUNT(count_pcmd_op);
2715 OP1_1(TYPE_DBL, TYPE_DBL);
2719 COUNT(count_pcmd_op);
2720 OP1_1(TYPE_INT, TYPE_LNG);
2723 COUNT(count_pcmd_op);
2724 OP1_1(TYPE_INT, TYPE_FLT);
2727 COUNT(count_pcmd_op);
2728 OP1_1(TYPE_INT, TYPE_DBL);
2731 COUNT(count_pcmd_op);
2732 OP1_1(TYPE_LNG, TYPE_INT);
2735 COUNT(count_pcmd_op);
2736 OP1_1(TYPE_LNG, TYPE_FLT);
2739 COUNT(count_pcmd_op);
2740 OP1_1(TYPE_LNG, TYPE_DBL);
2743 COUNT(count_pcmd_op);
2744 OP1_1(TYPE_FLT, TYPE_INT);
2747 COUNT(count_pcmd_op);
2748 OP1_1(TYPE_FLT, TYPE_LNG);
2751 COUNT(count_pcmd_op);
2752 OP1_1(TYPE_FLT, TYPE_DBL);
2755 COUNT(count_pcmd_op);
2756 OP1_1(TYPE_DBL, TYPE_INT);
2759 COUNT(count_pcmd_op);
2760 OP1_1(TYPE_DBL, TYPE_LNG);
2763 COUNT(count_pcmd_op);
2764 OP1_1(TYPE_DBL, TYPE_FLT);
2767 case ICMD_CHECKCAST:
2768 coalescing_boundary = sd.new;
2769 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2770 /* array type cast-check */
2772 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2775 if (md->memuse > rd->memuse)
2776 rd->memuse = md->memuse;
2777 if (md->argintreguse > rd->argintreguse)
2778 rd->argintreguse = md->argintreguse;
2780 /* make all stack variables saved */
2784 sd.var[copy->varnum].flags |= SAVEDVAR;
2785 copy->flags |= SAVEDVAR;
2789 OP1_1(TYPE_ADR, TYPE_ADR);
2792 case ICMD_INSTANCEOF:
2793 case ICMD_ARRAYLENGTH:
2794 coalescing_boundary = sd.new;
2795 OP1_1(TYPE_ADR, TYPE_INT);
2799 case ICMD_ANEWARRAY:
2800 coalescing_boundary = sd.new;
2801 OP1_1(TYPE_INT, TYPE_ADR);
2805 coalescing_boundary = sd.new;
2806 COUNT(count_check_null);
2807 COUNT(count_pcmd_mem);
2808 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2809 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2814 case ICMD_GETSTATIC:
2815 coalescing_boundary = sd.new;
2816 COUNT(count_pcmd_mem);
2817 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2818 OP0_1(fmiref->parseddesc.fd->type);
2822 coalescing_boundary = sd.new;
2829 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2831 tbptr->type = BBTYPE_SBR;
2833 /* We need to check for overflow right here because
2834 * the pushed value is poped afterwards */
2837 /* calculate stack after return */
2842 /* pop many push any */
2846 bte = iptr->sx.s23.s3.bte;
2850 case ICMD_INVOKESTATIC:
2851 case ICMD_INVOKESPECIAL:
2852 case ICMD_INVOKEVIRTUAL:
2853 case ICMD_INVOKEINTERFACE:
2854 COUNT(count_pcmd_met);
2856 /* Check for functions to replace with builtin
2859 if (builtintable_replace_function(iptr))
2862 INSTRUCTION_GET_METHODDESC(iptr, md);
2863 /* XXX resurrect this COUNT? */
2864 /* if (lm->flags & ACC_STATIC) */
2865 /* {COUNT(count_check_null);} */
2869 coalescing_boundary = sd.new;
2873 if (md->memuse > rd->memuse)
2874 rd->memuse = md->memuse;
2875 if (md->argintreguse > rd->argintreguse)
2876 rd->argintreguse = md->argintreguse;
2877 if (md->argfltreguse > rd->argfltreguse)
2878 rd->argfltreguse = md->argfltreguse;
2882 /* XXX optimize for <= 2 args */
2883 /* XXX not for ICMD_BUILTIN */
2884 iptr->s1.argcount = stackdepth;
2885 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2888 for (i-- ; i >= 0; i--) {
2889 iptr->sx.s23.s2.args[i] = copy->varnum;
2891 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2892 /* -> won't help anyway */
2893 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2895 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2896 /* If we pass float arguments in integer argument registers, we
2897 * are not allowed to precolor them here. Floats have to be moved
2898 * to this regs explicitly in codegen().
2899 * Only arguments that are passed by stack anyway can be precolored
2900 * (michi 2005/07/24) */
2901 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
2902 (!IS_FLT_DBL_TYPE(copy->type)
2903 || md->params[i].inmemory)) {
2905 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
2910 #if defined(ENABLE_INTRP)
2913 if (md->params[i].inmemory) {
2914 sd.var[copy->varnum].regoff =
2915 md->params[i].regoff;
2916 sd.var[copy->varnum].flags |=
2920 if (IS_FLT_DBL_TYPE(copy->type)) {
2921 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2922 assert(0); /* XXX is this assert ok? */
2924 sd.var[copy->varnum].regoff =
2925 rd->argfltregs[md->params[i].regoff];
2926 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2929 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2930 if (IS_2_WORD_TYPE(copy->type))
2931 sd.var[copy->varnum].regoff =
2932 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2933 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2936 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2937 sd.var[copy->varnum].regoff =
2938 rd->argintregs[md->params[i].regoff];
2941 #if defined(ENABLE_INTRP)
2942 } /* end if (!opt_intrp) */
2949 /* deal with live-through stack slots "under" the */
2951 /* XXX not for ICMD_BUILTIN */
2957 iptr->sx.s23.s2.args[i++] = copy->varnum;
2958 sd.var[copy->varnum].flags |= SAVEDVAR;
2962 /* pop the arguments */
2971 /* push the return value */
2973 if (md->returntype.type != TYPE_VOID) {
2974 GET_NEW_VAR(sd, new_index, md->returntype.type);
2975 DST(md->returntype.type, new_index);
2980 case ICMD_INLINE_START:
2981 case ICMD_INLINE_END:
2986 case ICMD_MULTIANEWARRAY:
2987 coalescing_boundary = sd.new;
2988 if (rd->argintreguse < 3)
2989 rd->argintreguse = 3;
2991 i = iptr->s1.argcount;
2995 iptr->sx.s23.s2.args = DMNEW(s4, i);
2997 #if defined(SPECIALMEMUSE)
2998 # if defined(__DARWIN__)
2999 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
3000 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3002 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
3003 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
3006 # if defined(__I386__)
3007 if (rd->memuse < i + 3)
3008 rd->memuse = i + 3; /* n integer args spilled on stack */
3009 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3010 if (rd->memuse < i + 2)
3011 rd->memuse = i + 2; /* 4*4 bytes callee save space */
3014 rd->memuse = i; /* n integer args spilled on stack */
3015 # endif /* defined(__I386__) */
3019 /* check INT type here? Currently typecheck does this. */
3020 iptr->sx.s23.s2.args[i] = copy->varnum;
3021 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
3022 && (!IS_OUTVAR(copy))
3023 && (!IS_LOCALVAR(copy)) ) {
3024 copy->varkind = ARGVAR;
3025 sd.var[copy->varnum].flags |=
3026 INMEMORY & PREALLOC;
3027 #if defined(SPECIALMEMUSE)
3028 # if defined(__DARWIN__)
3029 sd.var[copy->varnum].regoff = i +
3030 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3032 sd.var[copy->varnum].regoff = i +
3033 LA_SIZE_IN_POINTERS + 3;
3036 # if defined(__I386__)
3037 sd.var[copy->varnum].regoff = i + 3;
3038 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3039 sd.var[copy->varnum].regoff = i + 2;
3041 sd.var[copy->varnum].regoff = i;
3042 # endif /* defined(__I386__) */
3043 #endif /* defined(SPECIALMEMUSE) */
3048 sd.var[copy->varnum].flags |= SAVEDVAR;
3052 i = iptr->s1.argcount;
3057 GET_NEW_VAR(sd, new_index, TYPE_ADR);
3058 DST(TYPE_ADR, new_index);
3064 new_internalerror("Unknown ICMD %d", opcode);
3070 } /* while instructions */
3072 /* stack slots at basic block end become interfaces */
3074 sd.bptr->outdepth = stackdepth;
3075 sd.bptr->outvars = DMNEW(s4, stackdepth);
3078 for (copy = curstack; copy; i--, copy = copy->prev) {
3081 /* with the new vars rd->interfaces will be removed */
3082 /* and all in and outvars have to be STACKVARS! */
3083 /* in the moment i.e. SWAP with in and out vars can */
3084 /* create an unresolvable conflict */
3088 v = sd.var + copy->varnum;
3091 if (jd->interface_map[i*5 + copy->type].flags == UNUSED) {
3092 /* no interface var until now for this depth and */
3094 jd->interface_map[i*5 + copy->type].flags = v->flags;
3097 jd->interface_map[i*5 + copy->type].flags |= v->flags;
3100 sd.bptr->outvars[i] = copy->varnum;
3103 /* check if interface slots at basic block begin must be saved */
3105 for (i=0; i<sd.bptr->indepth; ++i) {
3106 varinfo *v = sd.var + sd.bptr->invars[i];
3108 if (jd->interface_map[i*5 + v->type].flags == UNUSED) {
3109 /* no interface var until now for this depth and */
3111 jd->interface_map[i*5 + v->type].flags = v->flags;
3114 jd->interface_map[i*5 + v->type].flags |= v->flags;
3119 /* store the number of this block's variables */
3121 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
3123 #if defined(STACK_VERBOSE)
3124 printf("OUTVARS\n");
3125 /* XXX print something useful here */
3130 superblockend = true;
3133 } /* while blocks */
3134 } while (repeat && !deadcode);
3136 /* gather statistics *****************************************************/
3138 #if defined(ENABLE_STATISTICS)
3140 if (jd->new_basicblockcount > count_max_basic_blocks)
3141 count_max_basic_blocks = jd->new_basicblockcount;
3142 count_basic_blocks += jd->new_basicblockcount;
3143 if (jd->new_instructioncount > count_max_javainstr)
3144 count_max_javainstr = jd->new_instructioncount;
3145 count_javainstr += jd->new_instructioncount;
3146 if (jd->new_stackcount > count_upper_bound_new_stack)
3147 count_upper_bound_new_stack = jd->new_stackcount;
3148 if ((sd.new - jd->new_stack) > count_max_new_stack)
3149 count_max_new_stack = (sd.new - jd->new_stack);
3151 b_count = jd->new_basicblockcount;
3152 sd.bptr = jd->new_basicblocks;
3153 while (--b_count >= 0) {
3154 if (sd.bptr->flags > BBREACHED) {
3155 if (sd.bptr->indepth >= 10)
3156 count_block_stack[10]++;
3158 count_block_stack[sd.bptr->indepth]++;
3159 len = sd.bptr->icount;
3161 count_block_size_distribution[len]++;
3163 count_block_size_distribution[10]++;
3165 count_block_size_distribution[11]++;
3167 count_block_size_distribution[12]++;
3169 count_block_size_distribution[13]++;
3171 count_block_size_distribution[14]++;
3173 count_block_size_distribution[15]++;
3175 count_block_size_distribution[16]++;
3177 count_block_size_distribution[17]++;
3182 if (iteration_count == 1)
3183 count_analyse_iterations[0]++;
3184 else if (iteration_count == 2)
3185 count_analyse_iterations[1]++;
3186 else if (iteration_count == 3)
3187 count_analyse_iterations[2]++;
3188 else if (iteration_count == 4)
3189 count_analyse_iterations[3]++;
3191 count_analyse_iterations[4]++;
3193 if (jd->new_basicblockcount <= 5)
3194 count_method_bb_distribution[0]++;
3195 else if (jd->new_basicblockcount <= 10)
3196 count_method_bb_distribution[1]++;
3197 else if (jd->new_basicblockcount <= 15)
3198 count_method_bb_distribution[2]++;
3199 else if (jd->new_basicblockcount <= 20)
3200 count_method_bb_distribution[3]++;
3201 else if (jd->new_basicblockcount <= 30)
3202 count_method_bb_distribution[4]++;
3203 else if (jd->new_basicblockcount <= 40)
3204 count_method_bb_distribution[5]++;
3205 else if (jd->new_basicblockcount <= 50)
3206 count_method_bb_distribution[6]++;
3207 else if (jd->new_basicblockcount <= 75)
3208 count_method_bb_distribution[7]++;
3210 count_method_bb_distribution[8]++;
3212 #endif /* defined(ENABLE_STATISTICS) */
3214 /* everything's ok *******************************************************/
3218 /* goto labels for throwing verifier exceptions **************************/
3220 #if defined(ENABLE_VERIFIER)
3222 throw_stack_underflow:
3223 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3226 throw_stack_overflow:
3227 exceptions_throw_verifyerror(m, "Stack size too large");
3230 throw_stack_depth_error:
3231 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3234 throw_stack_type_error:
3235 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3238 throw_stack_category_error:
3239 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3247 * These are local overrides for various environment variables in Emacs.
3248 * Please do not remove this and leave it at the end of the file, where
3249 * Emacs will automagically detect them.
3250 * ---------------------------------------------------------------------
3253 * indent-tabs-mode: t
3257 * vim:noexpandtab:sw=4:ts=4: