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 5447 2006-09-09 21:33:48Z 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. */
814 else if (sd.bptr->flags <= BBREACHED) {
816 /* We know that sd.bptr->flags == BBREACHED. */
817 /* This block has been reached before. */
818 stackdepth = sd.bptr->indepth;
819 curstack = stack_create_instack(&sd);
821 else if (sd.bptr->flags < BBREACHED) {
822 /* This block is reached for the first time now */
823 /* by falling through from the previous block. */
824 /* Create the instack (propagated). */
826 stack_create_invars(&sd, sd.bptr, curstack, stackdepth);
828 curstack = stack_create_instack(&sd);
831 /* This block has been reached before. now we are */
832 /* falling into it from the previous block. */
833 /* Check that stack depth is well-defined. */
835 if (!stack_check_invars(&sd, sd.bptr, curstack, stackdepth))
838 curstack = stack_create_instack(&sd);
841 /* set up local variables for analyzing this block */
844 superblockend = false;
845 len = sd.bptr->icount;
846 iptr = sd.bptr->iinstr;
847 b_index = sd.bptr - jd->new_basicblocks;
849 /* mark the block as analysed */
851 sd.bptr->flags = BBFINISHED;
853 /* reset variables for dependency checking */
855 coalescing_boundary = sd.new;
856 for( i = 0; i < cd->maxlocals; i++)
857 last_store_boundary[i] = sd.new;
859 /* remember the start of this block's variables */
861 sd.bptr->varstart = sd.vartop;
863 #if defined(STACK_VERBOSE)
864 printf("INVARS - indices:\t\n");
865 for (i=0; i<sd.bptr->indepth; ++i) {
866 printf("%d ", sd.bptr->invars[i]);
871 /* iterate over ICMDs ****************************************/
875 #if defined(STACK_VERBOSE)
876 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
877 for( copy = curstack; copy; copy = copy->prev ) {
878 printf("%2d(%d", copy->varnum, copy->type);
881 if (IS_PREALLOC(copy))
888 /* fetch the current opcode */
892 /* automatically replace some ICMDs with builtins */
894 #if defined(USEBUILTINTABLE)
896 bte = builtintable_get_automatic(opcode);
898 if (bte && bte->opcode == opcode) {
899 iptr->opc = ICMD_BUILTIN;
900 iptr->flags.bits = 0;
901 iptr->sx.s23.s3.bte = bte;
902 /* iptr->line is already set */
903 jd->isleafmethod = false;
907 #endif /* defined(USEBUILTINTABLE) */
909 /* main opcode switch *************************************/
922 coalescing_boundary = sd.new;
923 COUNT(count_check_null);
926 CLR_DST; /* XXX live through? */
931 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
933 USE_S1_LOCAL(TYPE_ADR);
937 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
939 superblockend = true;
943 COUNT(count_pcmd_return);
946 superblockend = true;
950 /* pop 0 push 1 const */
952 /************************** ICONST OPTIMIZATIONS **************************/
955 COUNT(count_pcmd_load);
959 switch (iptr[1].opc) {
961 iptr->opc = ICMD_IADDCONST;
965 iptr[1].opc = ICMD_NOP;
966 OP1_1(TYPE_INT, TYPE_INT);
967 COUNT(count_pcmd_op);
971 iptr->opc = ICMD_ISUBCONST;
972 goto icmd_iconst_tail;
973 #if SUPPORT_CONST_MUL
975 iptr->opc = ICMD_IMULCONST;
976 goto icmd_iconst_tail;
977 #else /* SUPPORT_CONST_MUL */
979 if (iptr->sx.val.i == 0x00000002)
981 else if (iptr->sx.val.i == 0x00000004)
983 else if (iptr->sx.val.i == 0x00000008)
985 else if (iptr->sx.val.i == 0x00000010)
987 else if (iptr->sx.val.i == 0x00000020)
989 else if (iptr->sx.val.i == 0x00000040)
991 else if (iptr->sx.val.i == 0x00000080)
993 else if (iptr->sx.val.i == 0x00000100)
995 else if (iptr->sx.val.i == 0x00000200)
997 else if (iptr->sx.val.i == 0x00000400)
999 else if (iptr->sx.val.i == 0x00000800)
1000 iptr->sx.val.i = 11;
1001 else if (iptr->sx.val.i == 0x00001000)
1002 iptr->sx.val.i = 12;
1003 else if (iptr->sx.val.i == 0x00002000)
1004 iptr->sx.val.i = 13;
1005 else if (iptr->sx.val.i == 0x00004000)
1006 iptr->sx.val.i = 14;
1007 else if (iptr->sx.val.i == 0x00008000)
1008 iptr->sx.val.i = 15;
1009 else if (iptr->sx.val.i == 0x00010000)
1010 iptr->sx.val.i = 16;
1011 else if (iptr->sx.val.i == 0x00020000)
1012 iptr->sx.val.i = 17;
1013 else if (iptr->sx.val.i == 0x00040000)
1014 iptr->sx.val.i = 18;
1015 else if (iptr->sx.val.i == 0x00080000)
1016 iptr->sx.val.i = 19;
1017 else if (iptr->sx.val.i == 0x00100000)
1018 iptr->sx.val.i = 20;
1019 else if (iptr->sx.val.i == 0x00200000)
1020 iptr->sx.val.i = 21;
1021 else if (iptr->sx.val.i == 0x00400000)
1022 iptr->sx.val.i = 22;
1023 else if (iptr->sx.val.i == 0x00800000)
1024 iptr->sx.val.i = 23;
1025 else if (iptr->sx.val.i == 0x01000000)
1026 iptr->sx.val.i = 24;
1027 else if (iptr->sx.val.i == 0x02000000)
1028 iptr->sx.val.i = 25;
1029 else if (iptr->sx.val.i == 0x04000000)
1030 iptr->sx.val.i = 26;
1031 else if (iptr->sx.val.i == 0x08000000)
1032 iptr->sx.val.i = 27;
1033 else if (iptr->sx.val.i == 0x10000000)
1034 iptr->sx.val.i = 28;
1035 else if (iptr->sx.val.i == 0x20000000)
1036 iptr->sx.val.i = 29;
1037 else if (iptr->sx.val.i == 0x40000000)
1038 iptr->sx.val.i = 30;
1039 else if (iptr->sx.val.i == 0x80000000)
1040 iptr->sx.val.i = 31;
1044 iptr->opc = ICMD_IMULPOW2;
1045 goto icmd_iconst_tail;
1046 #endif /* SUPPORT_CONST_MUL */
1048 if (iptr->sx.val.i == 0x00000002)
1050 else if (iptr->sx.val.i == 0x00000004)
1052 else if (iptr->sx.val.i == 0x00000008)
1054 else if (iptr->sx.val.i == 0x00000010)
1056 else if (iptr->sx.val.i == 0x00000020)
1058 else if (iptr->sx.val.i == 0x00000040)
1060 else if (iptr->sx.val.i == 0x00000080)
1062 else if (iptr->sx.val.i == 0x00000100)
1064 else if (iptr->sx.val.i == 0x00000200)
1066 else if (iptr->sx.val.i == 0x00000400)
1067 iptr->sx.val.i = 10;
1068 else if (iptr->sx.val.i == 0x00000800)
1069 iptr->sx.val.i = 11;
1070 else if (iptr->sx.val.i == 0x00001000)
1071 iptr->sx.val.i = 12;
1072 else if (iptr->sx.val.i == 0x00002000)
1073 iptr->sx.val.i = 13;
1074 else if (iptr->sx.val.i == 0x00004000)
1075 iptr->sx.val.i = 14;
1076 else if (iptr->sx.val.i == 0x00008000)
1077 iptr->sx.val.i = 15;
1078 else if (iptr->sx.val.i == 0x00010000)
1079 iptr->sx.val.i = 16;
1080 else if (iptr->sx.val.i == 0x00020000)
1081 iptr->sx.val.i = 17;
1082 else if (iptr->sx.val.i == 0x00040000)
1083 iptr->sx.val.i = 18;
1084 else if (iptr->sx.val.i == 0x00080000)
1085 iptr->sx.val.i = 19;
1086 else if (iptr->sx.val.i == 0x00100000)
1087 iptr->sx.val.i = 20;
1088 else if (iptr->sx.val.i == 0x00200000)
1089 iptr->sx.val.i = 21;
1090 else if (iptr->sx.val.i == 0x00400000)
1091 iptr->sx.val.i = 22;
1092 else if (iptr->sx.val.i == 0x00800000)
1093 iptr->sx.val.i = 23;
1094 else if (iptr->sx.val.i == 0x01000000)
1095 iptr->sx.val.i = 24;
1096 else if (iptr->sx.val.i == 0x02000000)
1097 iptr->sx.val.i = 25;
1098 else if (iptr->sx.val.i == 0x04000000)
1099 iptr->sx.val.i = 26;
1100 else if (iptr->sx.val.i == 0x08000000)
1101 iptr->sx.val.i = 27;
1102 else if (iptr->sx.val.i == 0x10000000)
1103 iptr->sx.val.i = 28;
1104 else if (iptr->sx.val.i == 0x20000000)
1105 iptr->sx.val.i = 29;
1106 else if (iptr->sx.val.i == 0x40000000)
1107 iptr->sx.val.i = 30;
1108 else if (iptr->sx.val.i == 0x80000000)
1109 iptr->sx.val.i = 31;
1113 iptr->opc = ICMD_IDIVPOW2;
1114 goto icmd_iconst_tail;
1117 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
1118 if ((iptr->sx.val.i == 0x00000002) ||
1119 (iptr->sx.val.i == 0x00000004) ||
1120 (iptr->sx.val.i == 0x00000008) ||
1121 (iptr->sx.val.i == 0x00000010) ||
1122 (iptr->sx.val.i == 0x00000020) ||
1123 (iptr->sx.val.i == 0x00000040) ||
1124 (iptr->sx.val.i == 0x00000080) ||
1125 (iptr->sx.val.i == 0x00000100) ||
1126 (iptr->sx.val.i == 0x00000200) ||
1127 (iptr->sx.val.i == 0x00000400) ||
1128 (iptr->sx.val.i == 0x00000800) ||
1129 (iptr->sx.val.i == 0x00001000) ||
1130 (iptr->sx.val.i == 0x00002000) ||
1131 (iptr->sx.val.i == 0x00004000) ||
1132 (iptr->sx.val.i == 0x00008000) ||
1133 (iptr->sx.val.i == 0x00010000) ||
1134 (iptr->sx.val.i == 0x00020000) ||
1135 (iptr->sx.val.i == 0x00040000) ||
1136 (iptr->sx.val.i == 0x00080000) ||
1137 (iptr->sx.val.i == 0x00100000) ||
1138 (iptr->sx.val.i == 0x00200000) ||
1139 (iptr->sx.val.i == 0x00400000) ||
1140 (iptr->sx.val.i == 0x00800000) ||
1141 (iptr->sx.val.i == 0x01000000) ||
1142 (iptr->sx.val.i == 0x02000000) ||
1143 (iptr->sx.val.i == 0x04000000) ||
1144 (iptr->sx.val.i == 0x08000000) ||
1145 (iptr->sx.val.i == 0x10000000) ||
1146 (iptr->sx.val.i == 0x20000000) ||
1147 (iptr->sx.val.i == 0x40000000) ||
1148 (iptr->sx.val.i == 0x80000000))
1150 iptr->opc = ICMD_IREMPOW2;
1151 iptr->sx.val.i -= 1;
1152 goto icmd_iconst_tail;
1155 #if SUPPORT_CONST_LOGICAL
1157 iptr->opc = ICMD_IANDCONST;
1158 goto icmd_iconst_tail;
1161 iptr->opc = ICMD_IORCONST;
1162 goto icmd_iconst_tail;
1165 iptr->opc = ICMD_IXORCONST;
1166 goto icmd_iconst_tail;
1168 #endif /* SUPPORT_CONST_LOGICAL */
1170 iptr->opc = ICMD_ISHLCONST;
1171 goto icmd_iconst_tail;
1174 iptr->opc = ICMD_ISHRCONST;
1175 goto icmd_iconst_tail;
1178 iptr->opc = ICMD_IUSHRCONST;
1179 goto icmd_iconst_tail;
1180 #if SUPPORT_LONG_SHIFT
1182 iptr->opc = ICMD_LSHLCONST;
1183 goto icmd_lconst_tail;
1186 iptr->opc = ICMD_LSHRCONST;
1187 goto icmd_lconst_tail;
1190 iptr->opc = ICMD_LUSHRCONST;
1191 goto icmd_lconst_tail;
1192 #endif /* SUPPORT_LONG_SHIFT */
1193 case ICMD_IF_ICMPEQ:
1194 iptr[1].opc = ICMD_IFEQ;
1198 /* set the constant for the following icmd */
1199 iptr[1].sx.val.i = iptr->sx.val.i;
1201 /* this instruction becomes a nop */
1202 iptr->opc = ICMD_NOP;
1205 case ICMD_IF_ICMPLT:
1206 iptr[1].opc = ICMD_IFLT;
1207 goto icmd_if_icmp_tail;
1209 case ICMD_IF_ICMPLE:
1210 iptr[1].opc = ICMD_IFLE;
1211 goto icmd_if_icmp_tail;
1213 case ICMD_IF_ICMPNE:
1214 iptr[1].opc = ICMD_IFNE;
1215 goto icmd_if_icmp_tail;
1217 case ICMD_IF_ICMPGT:
1218 iptr[1].opc = ICMD_IFGT;
1219 goto icmd_if_icmp_tail;
1221 case ICMD_IF_ICMPGE:
1222 iptr[1].opc = ICMD_IFGE;
1223 goto icmd_if_icmp_tail;
1225 #if SUPPORT_CONST_STORE
1230 IF_INTRP( goto normal_ICONST; )
1231 # if SUPPORT_CONST_STORE_ZERO_ONLY
1232 if (iptr->sx.val.i != 0)
1235 switch (iptr[1].opc) {
1237 iptr->opc = ICMD_IASTORECONST;
1238 iptr->flags.bits |= INS_FLAG_CHECK;
1241 iptr->opc = ICMD_BASTORECONST;
1242 iptr->flags.bits |= INS_FLAG_CHECK;
1245 iptr->opc = ICMD_CASTORECONST;
1246 iptr->flags.bits |= INS_FLAG_CHECK;
1249 iptr->opc = ICMD_SASTORECONST;
1250 iptr->flags.bits |= INS_FLAG_CHECK;
1254 iptr[1].opc = ICMD_NOP;
1256 /* copy the constant to s3 */
1257 /* XXX constval -> astoreconstval? */
1258 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1259 OP2_0(TYPE_ADR, TYPE_INT);
1260 COUNT(count_pcmd_op);
1263 case ICMD_PUTSTATIC:
1265 IF_INTRP( goto normal_ICONST; )
1266 # if SUPPORT_CONST_STORE_ZERO_ONLY
1267 if (iptr->sx.val.i != 0)
1270 /* XXX check field type? */
1272 /* copy the constant to s2 */
1273 /* XXX constval -> fieldconstval? */
1274 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1277 /* set the field reference (s3) */
1278 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1279 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1280 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1283 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1286 switch (iptr[1].opc) {
1287 case ICMD_PUTSTATIC:
1288 iptr->opc = ICMD_PUTSTATICCONST;
1292 iptr->opc = ICMD_PUTFIELDCONST;
1297 iptr[1].opc = ICMD_NOP;
1298 COUNT(count_pcmd_op);
1300 #endif /* SUPPORT_CONST_STORE */
1306 /* if we get here, the ICONST has been optimized */
1310 /* normal case of an unoptimized ICONST */
1314 /************************** LCONST OPTIMIZATIONS **************************/
1317 COUNT(count_pcmd_load);
1321 /* switch depending on the following instruction */
1323 switch (iptr[1].opc) {
1324 #if SUPPORT_LONG_ADD
1326 iptr->opc = ICMD_LADDCONST;
1330 /* instruction of type LONG -> LONG */
1331 iptr[1].opc = ICMD_NOP;
1332 OP1_1(TYPE_LNG, TYPE_LNG);
1333 COUNT(count_pcmd_op);
1337 iptr->opc = ICMD_LSUBCONST;
1338 goto icmd_lconst_tail;
1340 #endif /* SUPPORT_LONG_ADD */
1341 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1343 iptr->opc = ICMD_LMULCONST;
1344 goto icmd_lconst_tail;
1345 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1346 # if SUPPORT_LONG_SHIFT
1348 if (iptr->sx.val.l == 0x00000002)
1350 else if (iptr->sx.val.l == 0x00000004)
1352 else if (iptr->sx.val.l == 0x00000008)
1354 else if (iptr->sx.val.l == 0x00000010)
1356 else if (iptr->sx.val.l == 0x00000020)
1358 else if (iptr->sx.val.l == 0x00000040)
1360 else if (iptr->sx.val.l == 0x00000080)
1362 else if (iptr->sx.val.l == 0x00000100)
1364 else if (iptr->sx.val.l == 0x00000200)
1366 else if (iptr->sx.val.l == 0x00000400)
1367 iptr->sx.val.i = 10;
1368 else if (iptr->sx.val.l == 0x00000800)
1369 iptr->sx.val.i = 11;
1370 else if (iptr->sx.val.l == 0x00001000)
1371 iptr->sx.val.i = 12;
1372 else if (iptr->sx.val.l == 0x00002000)
1373 iptr->sx.val.i = 13;
1374 else if (iptr->sx.val.l == 0x00004000)
1375 iptr->sx.val.i = 14;
1376 else if (iptr->sx.val.l == 0x00008000)
1377 iptr->sx.val.i = 15;
1378 else if (iptr->sx.val.l == 0x00010000)
1379 iptr->sx.val.i = 16;
1380 else if (iptr->sx.val.l == 0x00020000)
1381 iptr->sx.val.i = 17;
1382 else if (iptr->sx.val.l == 0x00040000)
1383 iptr->sx.val.i = 18;
1384 else if (iptr->sx.val.l == 0x00080000)
1385 iptr->sx.val.i = 19;
1386 else if (iptr->sx.val.l == 0x00100000)
1387 iptr->sx.val.i = 20;
1388 else if (iptr->sx.val.l == 0x00200000)
1389 iptr->sx.val.i = 21;
1390 else if (iptr->sx.val.l == 0x00400000)
1391 iptr->sx.val.i = 22;
1392 else if (iptr->sx.val.l == 0x00800000)
1393 iptr->sx.val.i = 23;
1394 else if (iptr->sx.val.l == 0x01000000)
1395 iptr->sx.val.i = 24;
1396 else if (iptr->sx.val.l == 0x02000000)
1397 iptr->sx.val.i = 25;
1398 else if (iptr->sx.val.l == 0x04000000)
1399 iptr->sx.val.i = 26;
1400 else if (iptr->sx.val.l == 0x08000000)
1401 iptr->sx.val.i = 27;
1402 else if (iptr->sx.val.l == 0x10000000)
1403 iptr->sx.val.i = 28;
1404 else if (iptr->sx.val.l == 0x20000000)
1405 iptr->sx.val.i = 29;
1406 else if (iptr->sx.val.l == 0x40000000)
1407 iptr->sx.val.i = 30;
1408 else if (iptr->sx.val.l == 0x80000000)
1409 iptr->sx.val.i = 31;
1413 iptr->opc = ICMD_LMULPOW2;
1414 goto icmd_lconst_tail;
1415 # endif /* SUPPORT_LONG_SHIFT */
1416 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1417 #if SUPPORT_LONG_DIV_POW2
1419 if (iptr->sx.val.l == 0x00000002)
1421 else if (iptr->sx.val.l == 0x00000004)
1423 else if (iptr->sx.val.l == 0x00000008)
1425 else if (iptr->sx.val.l == 0x00000010)
1427 else if (iptr->sx.val.l == 0x00000020)
1429 else if (iptr->sx.val.l == 0x00000040)
1431 else if (iptr->sx.val.l == 0x00000080)
1433 else if (iptr->sx.val.l == 0x00000100)
1435 else if (iptr->sx.val.l == 0x00000200)
1437 else if (iptr->sx.val.l == 0x00000400)
1438 iptr->sx.val.i = 10;
1439 else if (iptr->sx.val.l == 0x00000800)
1440 iptr->sx.val.i = 11;
1441 else if (iptr->sx.val.l == 0x00001000)
1442 iptr->sx.val.i = 12;
1443 else if (iptr->sx.val.l == 0x00002000)
1444 iptr->sx.val.i = 13;
1445 else if (iptr->sx.val.l == 0x00004000)
1446 iptr->sx.val.i = 14;
1447 else if (iptr->sx.val.l == 0x00008000)
1448 iptr->sx.val.i = 15;
1449 else if (iptr->sx.val.l == 0x00010000)
1450 iptr->sx.val.i = 16;
1451 else if (iptr->sx.val.l == 0x00020000)
1452 iptr->sx.val.i = 17;
1453 else if (iptr->sx.val.l == 0x00040000)
1454 iptr->sx.val.i = 18;
1455 else if (iptr->sx.val.l == 0x00080000)
1456 iptr->sx.val.i = 19;
1457 else if (iptr->sx.val.l == 0x00100000)
1458 iptr->sx.val.i = 20;
1459 else if (iptr->sx.val.l == 0x00200000)
1460 iptr->sx.val.i = 21;
1461 else if (iptr->sx.val.l == 0x00400000)
1462 iptr->sx.val.i = 22;
1463 else if (iptr->sx.val.l == 0x00800000)
1464 iptr->sx.val.i = 23;
1465 else if (iptr->sx.val.l == 0x01000000)
1466 iptr->sx.val.i = 24;
1467 else if (iptr->sx.val.l == 0x02000000)
1468 iptr->sx.val.i = 25;
1469 else if (iptr->sx.val.l == 0x04000000)
1470 iptr->sx.val.i = 26;
1471 else if (iptr->sx.val.l == 0x08000000)
1472 iptr->sx.val.i = 27;
1473 else if (iptr->sx.val.l == 0x10000000)
1474 iptr->sx.val.i = 28;
1475 else if (iptr->sx.val.l == 0x20000000)
1476 iptr->sx.val.i = 29;
1477 else if (iptr->sx.val.l == 0x40000000)
1478 iptr->sx.val.i = 30;
1479 else if (iptr->sx.val.l == 0x80000000)
1480 iptr->sx.val.i = 31;
1484 iptr->opc = ICMD_LDIVPOW2;
1485 goto icmd_lconst_tail;
1486 #endif /* SUPPORT_LONG_DIV_POW2 */
1488 #if SUPPORT_LONG_REM_POW2
1490 if ((iptr->sx.val.l == 0x00000002) ||
1491 (iptr->sx.val.l == 0x00000004) ||
1492 (iptr->sx.val.l == 0x00000008) ||
1493 (iptr->sx.val.l == 0x00000010) ||
1494 (iptr->sx.val.l == 0x00000020) ||
1495 (iptr->sx.val.l == 0x00000040) ||
1496 (iptr->sx.val.l == 0x00000080) ||
1497 (iptr->sx.val.l == 0x00000100) ||
1498 (iptr->sx.val.l == 0x00000200) ||
1499 (iptr->sx.val.l == 0x00000400) ||
1500 (iptr->sx.val.l == 0x00000800) ||
1501 (iptr->sx.val.l == 0x00001000) ||
1502 (iptr->sx.val.l == 0x00002000) ||
1503 (iptr->sx.val.l == 0x00004000) ||
1504 (iptr->sx.val.l == 0x00008000) ||
1505 (iptr->sx.val.l == 0x00010000) ||
1506 (iptr->sx.val.l == 0x00020000) ||
1507 (iptr->sx.val.l == 0x00040000) ||
1508 (iptr->sx.val.l == 0x00080000) ||
1509 (iptr->sx.val.l == 0x00100000) ||
1510 (iptr->sx.val.l == 0x00200000) ||
1511 (iptr->sx.val.l == 0x00400000) ||
1512 (iptr->sx.val.l == 0x00800000) ||
1513 (iptr->sx.val.l == 0x01000000) ||
1514 (iptr->sx.val.l == 0x02000000) ||
1515 (iptr->sx.val.l == 0x04000000) ||
1516 (iptr->sx.val.l == 0x08000000) ||
1517 (iptr->sx.val.l == 0x10000000) ||
1518 (iptr->sx.val.l == 0x20000000) ||
1519 (iptr->sx.val.l == 0x40000000) ||
1520 (iptr->sx.val.l == 0x80000000))
1522 iptr->opc = ICMD_LREMPOW2;
1523 iptr->sx.val.l -= 1;
1524 goto icmd_lconst_tail;
1527 #endif /* SUPPORT_LONG_REM_POW2 */
1529 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1532 iptr->opc = ICMD_LANDCONST;
1533 goto icmd_lconst_tail;
1536 iptr->opc = ICMD_LORCONST;
1537 goto icmd_lconst_tail;
1540 iptr->opc = ICMD_LXORCONST;
1541 goto icmd_lconst_tail;
1542 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1544 #if SUPPORT_LONG_CMP_CONST
1546 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1549 /* switch on the instruction after LCONST - LCMP */
1551 switch (iptr[2].opc) {
1553 iptr->opc = ICMD_IF_LEQ;
1556 icmd_lconst_lcmp_tail:
1557 /* convert LCONST, LCMP, IFXX to IF_LXX */
1558 iptr->dst.insindex = iptr[2].dst.insindex;
1559 iptr[1].opc = ICMD_NOP;
1560 iptr[2].opc = ICMD_NOP;
1562 OP1_BRANCH(TYPE_LNG);
1563 BRANCH(tbptr, copy);
1564 COUNT(count_pcmd_bra);
1565 COUNT(count_pcmd_op);
1569 iptr->opc = ICMD_IF_LNE;
1570 goto icmd_lconst_lcmp_tail;
1573 iptr->opc = ICMD_IF_LLT;
1574 goto icmd_lconst_lcmp_tail;
1577 iptr->opc = ICMD_IF_LGT;
1578 goto icmd_lconst_lcmp_tail;
1581 iptr->opc = ICMD_IF_LLE;
1582 goto icmd_lconst_lcmp_tail;
1585 iptr->opc = ICMD_IF_LGE;
1586 goto icmd_lconst_lcmp_tail;
1590 } /* end switch on opcode after LCONST - LCMP */
1592 #endif /* SUPPORT_LONG_CMP_CONST */
1594 #if SUPPORT_CONST_STORE
1596 IF_INTRP( goto normal_LCONST; )
1597 # if SUPPORT_CONST_STORE_ZERO_ONLY
1598 if (iptr->sx.val.l != 0)
1601 #if SIZEOF_VOID_P == 4
1602 /* the constant must fit into a ptrint */
1603 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1606 /* move the constant to s3 */
1607 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1609 iptr->opc = ICMD_LASTORECONST;
1610 iptr->flags.bits |= INS_FLAG_CHECK;
1611 OP2_0(TYPE_ADR, TYPE_INT);
1613 iptr[1].opc = ICMD_NOP;
1614 COUNT(count_pcmd_op);
1617 case ICMD_PUTSTATIC:
1619 IF_INTRP( goto normal_LCONST; )
1620 # if SUPPORT_CONST_STORE_ZERO_ONLY
1621 if (iptr->sx.val.l != 0)
1624 #if SIZEOF_VOID_P == 4
1625 /* the constant must fit into a ptrint */
1626 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1629 /* XXX check field type? */
1631 /* copy the constant to s2 */
1632 /* XXX constval -> fieldconstval? */
1633 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1637 #endif /* SUPPORT_CONST_STORE */
1641 } /* end switch opcode after LCONST */
1643 /* if we get here, the LCONST has been optimized */
1647 /* the normal case of an unoptimized LCONST */
1651 /************************ END OF LCONST OPTIMIZATIONS *********************/
1654 COUNT(count_pcmd_load);
1659 COUNT(count_pcmd_load);
1663 /************************** ACONST OPTIMIZATIONS **************************/
1666 coalescing_boundary = sd.new;
1667 COUNT(count_pcmd_load);
1668 #if SUPPORT_CONST_STORE
1669 IF_INTRP( goto normal_ACONST; )
1671 /* We can only optimize if the ACONST is resolved
1672 * and there is an instruction after it. */
1674 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1677 switch (iptr[1].opc) {
1679 /* We can only optimize for NULL values
1680 * here because otherwise a checkcast is
1682 if (iptr->sx.val.anyptr != NULL)
1685 /* copy the constant (NULL) to s3 */
1686 iptr->sx.s23.s3.constval = 0;
1687 iptr->opc = ICMD_AASTORECONST;
1688 iptr->flags.bits |= INS_FLAG_CHECK;
1689 OP2_0(TYPE_ADR, TYPE_INT);
1691 iptr[1].opc = ICMD_NOP;
1692 COUNT(count_pcmd_op);
1695 case ICMD_PUTSTATIC:
1697 # if SUPPORT_CONST_STORE_ZERO_ONLY
1698 if (iptr->sx.val.anyptr != NULL)
1701 /* XXX check field type? */
1702 /* copy the constant to s2 */
1703 /* XXX constval -> fieldconstval? */
1704 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1712 /* if we get here the ACONST has been optimized */
1716 #endif /* SUPPORT_CONST_STORE */
1721 /* pop 0 push 1 load */
1728 COUNT(count_load_instruction);
1729 i = opcode - ICMD_ILOAD; /* type */
1732 jd->local_map[iptr->s1.varindex * 5 + i];
1734 LOAD(i, iptr->s1.varindex);
1743 coalescing_boundary = sd.new;
1744 iptr->flags.bits |= INS_FLAG_CHECK;
1745 COUNT(count_check_null);
1746 COUNT(count_check_bound);
1747 COUNT(count_pcmd_mem);
1748 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1755 coalescing_boundary = sd.new;
1756 iptr->flags.bits |= INS_FLAG_CHECK;
1757 COUNT(count_check_null);
1758 COUNT(count_check_bound);
1759 COUNT(count_pcmd_mem);
1760 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1763 /* pop 0 push 0 iinc */
1766 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1768 last_store_boundary[iptr->s1.varindex] = sd.new;
1771 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
1776 if ((copy->varkind == LOCALVAR) &&
1777 (copy->varnum == iptr->s1.varindex))
1779 assert(IS_LOCALVAR(copy));
1786 iptr->dst.varindex = iptr->s1.varindex;
1789 /* pop 1 push 0 store */
1798 i = opcode - ICMD_ISTORE; /* type */
1799 javaindex = iptr->dst.varindex;
1800 j = iptr->dst.varindex =
1801 jd->local_map[javaindex * 5 + i];
1804 #if defined(ENABLE_STATISTICS)
1807 i = sd.new - curstack;
1809 count_store_length[20]++;
1811 count_store_length[i]++;
1814 count_store_depth[10]++;
1816 count_store_depth[i]++;
1819 /* check for conflicts as described in Figure 5.2 */
1821 copy = curstack->prev;
1824 if ((copy->varkind == LOCALVAR) &&
1825 (copy->varnum == j))
1827 copy->varkind = TEMPVAR;
1828 assert(IS_LOCALVAR(copy));
1835 /* if the variable is already coalesced, don't bother */
1837 if (IS_OUTVAR(curstack)
1838 || (curstack->varkind == LOCALVAR
1839 && curstack->varnum != j))
1842 /* there is no STORE Lj while curstack is live */
1844 if (curstack < last_store_boundary[javaindex])
1845 goto assume_conflict;
1847 /* curstack must be after the coalescing boundary */
1849 if (curstack < coalescing_boundary)
1850 goto assume_conflict;
1852 /* there is no DEF LOCALVAR(j) while curstack is live */
1854 copy = sd.new; /* most recent stackslot created + 1 */
1855 while (--copy > curstack) {
1856 if (copy->varkind == LOCALVAR && copy->varnum == j)
1857 goto assume_conflict;
1860 /* coalesce the temporary variable with Lj */
1861 assert((curstack->varkind == TEMPVAR)
1862 || (curstack->varkind == UNDEFVAR));
1863 assert(!IS_LOCALVAR(curstack));
1864 assert(!IS_OUTVAR(curstack));
1865 assert(!IS_PREALLOC(curstack));
1867 assert(curstack->creator);
1868 assert(curstack->creator->dst.varindex == curstack->varnum);
1869 RELEASE_INDEX(sd, curstack);
1870 curstack->varkind = LOCALVAR;
1871 curstack->varnum = j;
1872 curstack->creator->dst.varindex = j;
1875 /* revert the coalescing, if it has been done earlier */
1877 if ((curstack->varkind == LOCALVAR)
1878 && (curstack->varnum == j))
1880 assert(IS_LOCALVAR(curstack));
1881 SET_TEMPVAR(curstack);
1884 /* remember the stack boundary at this store */
1886 last_store_boundary[javaindex] = sd.new;
1888 STORE(opcode - ICMD_ISTORE, j);
1894 coalescing_boundary = sd.new;
1895 iptr->flags.bits |= INS_FLAG_CHECK;
1896 COUNT(count_check_null);
1897 COUNT(count_check_bound);
1898 COUNT(count_pcmd_mem);
1900 bte = builtintable_get_internal(BUILTIN_canstore);
1903 if (md->memuse > rd->memuse)
1904 rd->memuse = md->memuse;
1905 if (md->argintreguse > rd->argintreguse)
1906 rd->argintreguse = md->argintreguse;
1907 /* XXX non-leaf method? */
1909 /* make all stack variables saved */
1913 sd.var[copy->varnum].flags |= SAVEDVAR;
1914 /* in case copy->varnum is/will be a LOCALVAR */
1915 /* once and set back to a non LOCALVAR */
1916 /* the correct SAVEDVAR flag has to be */
1917 /* remembered in copy->flags, too */
1918 copy->flags |= SAVEDVAR;
1922 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1929 coalescing_boundary = sd.new;
1930 iptr->flags.bits |= INS_FLAG_CHECK;
1931 COUNT(count_check_null);
1932 COUNT(count_check_bound);
1933 COUNT(count_pcmd_mem);
1934 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1941 coalescing_boundary = sd.new;
1942 iptr->flags.bits |= INS_FLAG_CHECK;
1943 COUNT(count_check_null);
1944 COUNT(count_check_bound);
1945 COUNT(count_pcmd_mem);
1946 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1952 #ifdef ENABLE_VERIFIER
1955 if (IS_2_WORD_TYPE(curstack->type))
1956 goto throw_stack_category_error;
1967 coalescing_boundary = sd.new;
1968 IF_JIT( md_return_alloc(jd, curstack); )
1969 COUNT(count_pcmd_return);
1970 OP1_0(opcode - ICMD_IRETURN);
1971 superblockend = true;
1975 coalescing_boundary = sd.new;
1976 COUNT(count_check_null);
1978 curstack = NULL; stackdepth = 0;
1979 superblockend = true;
1982 case ICMD_PUTSTATIC:
1983 coalescing_boundary = sd.new;
1984 COUNT(count_pcmd_mem);
1985 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1986 OP1_0(fmiref->parseddesc.fd->type);
1989 /* pop 1 push 0 branch */
1992 case ICMD_IFNONNULL:
1993 COUNT(count_pcmd_bra);
1994 OP1_BRANCH(TYPE_ADR);
1995 BRANCH(tbptr, copy);
2004 COUNT(count_pcmd_bra);
2005 /* iptr->sx.val.i is set implicitly in parse by
2006 clearing the memory or from IF_ICMPxx
2009 OP1_BRANCH(TYPE_INT);
2010 /* iptr->sx.val.i = 0; */
2011 BRANCH(tbptr, copy);
2014 /* pop 0 push 0 branch */
2017 COUNT(count_pcmd_bra);
2019 BRANCH(tbptr, copy);
2020 superblockend = true;
2023 /* pop 1 push 0 table branch */
2025 case ICMD_TABLESWITCH:
2026 COUNT(count_pcmd_table);
2027 OP1_BRANCH(TYPE_INT);
2029 table = iptr->dst.table;
2030 BRANCH_TARGET(*table, tbptr, copy);
2033 i = iptr->sx.s23.s3.tablehigh
2034 - iptr->sx.s23.s2.tablelow + 1;
2037 BRANCH_TARGET(*table, tbptr, copy);
2040 superblockend = true;
2043 /* pop 1 push 0 table branch */
2045 case ICMD_LOOKUPSWITCH:
2046 COUNT(count_pcmd_table);
2047 OP1_BRANCH(TYPE_INT);
2049 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
2051 lookup = iptr->dst.lookup;
2053 i = iptr->sx.s23.s2.lookupcount;
2056 BRANCH_TARGET(lookup->target, tbptr, copy);
2059 superblockend = true;
2062 case ICMD_MONITORENTER:
2063 case ICMD_MONITOREXIT:
2064 coalescing_boundary = sd.new;
2065 COUNT(count_check_null);
2069 /* pop 2 push 0 branch */
2071 case ICMD_IF_ICMPEQ:
2072 case ICMD_IF_ICMPNE:
2073 case ICMD_IF_ICMPLT:
2074 case ICMD_IF_ICMPGE:
2075 case ICMD_IF_ICMPGT:
2076 case ICMD_IF_ICMPLE:
2077 COUNT(count_pcmd_bra);
2078 OP2_BRANCH(TYPE_INT, TYPE_INT);
2079 BRANCH(tbptr, copy);
2082 case ICMD_IF_ACMPEQ:
2083 case ICMD_IF_ACMPNE:
2084 COUNT(count_pcmd_bra);
2085 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
2086 BRANCH(tbptr, copy);
2092 coalescing_boundary = sd.new;
2093 COUNT(count_check_null);
2094 COUNT(count_pcmd_mem);
2095 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2096 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
2101 if (!IS_2_WORD_TYPE(curstack->type)) {
2103 #ifdef ENABLE_VERIFIER
2106 if (IS_2_WORD_TYPE(curstack->prev->type))
2107 goto throw_stack_category_error;
2110 OP2_0_ANY_ANY; /* pop two slots */
2113 iptr->opc = ICMD_POP;
2114 OP1_0_ANY; /* pop one (two-word) slot */
2118 /* pop 0 push 1 dup */
2121 #ifdef ENABLE_VERIFIER
2124 if (IS_2_WORD_TYPE(curstack->type))
2125 goto throw_stack_category_error;
2128 COUNT(count_dup_instruction);
2134 coalescing_boundary = sd.new - 1;
2139 if (IS_2_WORD_TYPE(curstack->type)) {
2141 iptr->opc = ICMD_DUP;
2146 /* ..., ????, cat1 */
2147 #ifdef ENABLE_VERIFIER
2149 if (IS_2_WORD_TYPE(curstack->prev->type))
2150 goto throw_stack_category_error;
2153 src1 = curstack->prev;
2156 COPY_UP(src1); iptr++; len--;
2159 coalescing_boundary = sd.new;
2163 /* pop 2 push 3 dup */
2166 #ifdef ENABLE_VERIFIER
2169 if (IS_2_WORD_TYPE(curstack->type) ||
2170 IS_2_WORD_TYPE(curstack->prev->type))
2171 goto throw_stack_category_error;
2176 src1 = curstack->prev;
2181 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2183 MOVE_UP(src1); iptr++; len--;
2184 MOVE_UP(src2); iptr++; len--;
2186 COPY_DOWN(curstack, dst1);
2188 coalescing_boundary = sd.new;
2193 if (IS_2_WORD_TYPE(curstack->type)) {
2194 /* ..., ????, cat2 */
2195 #ifdef ENABLE_VERIFIER
2197 if (IS_2_WORD_TYPE(curstack->prev->type))
2198 goto throw_stack_category_error;
2201 iptr->opc = ICMD_DUP_X1;
2205 /* ..., ????, cat1 */
2206 #ifdef ENABLE_VERIFIER
2209 if (IS_2_WORD_TYPE(curstack->prev->type)
2210 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2211 goto throw_stack_category_error;
2216 src1 = curstack->prev->prev;
2217 src2 = curstack->prev;
2219 POPANY; POPANY; POPANY;
2222 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2223 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
2225 MOVE_UP(src1); iptr++; len--;
2226 MOVE_UP(src2); iptr++; len--;
2227 MOVE_UP(src3); iptr++; len--;
2229 COPY_DOWN(curstack, dst2); iptr++; len--;
2230 COPY_DOWN(curstack->prev, dst1);
2232 coalescing_boundary = sd.new;
2236 /* pop 3 push 4 dup */
2240 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2241 /* ..., cat2, ???? */
2242 #ifdef ENABLE_VERIFIER
2244 if (IS_2_WORD_TYPE(curstack->type))
2245 goto throw_stack_category_error;
2248 iptr->opc = ICMD_DUP_X1;
2252 /* ..., cat1, ???? */
2253 #ifdef ENABLE_VERIFIER
2256 if (IS_2_WORD_TYPE(curstack->type)
2257 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2258 goto throw_stack_category_error;
2262 src1 = curstack->prev->prev;
2263 src2 = curstack->prev;
2265 POPANY; POPANY; POPANY;
2268 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2270 MOVE_UP(src1); iptr++; len--;
2271 MOVE_UP(src2); iptr++; len--;
2272 MOVE_UP(src3); iptr++; len--;
2274 COPY_DOWN(curstack, dst1);
2276 coalescing_boundary = sd.new;
2282 if (IS_2_WORD_TYPE(curstack->type)) {
2283 /* ..., ????, cat2 */
2284 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2285 /* ..., cat2, cat2 */
2286 iptr->opc = ICMD_DUP_X1;
2290 /* ..., cat1, cat2 */
2291 #ifdef ENABLE_VERIFIER
2294 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2295 goto throw_stack_category_error;
2298 iptr->opc = ICMD_DUP_X2;
2304 /* ..., ????, ????, cat1 */
2306 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2307 /* ..., cat2, ????, cat1 */
2308 #ifdef ENABLE_VERIFIER
2310 if (IS_2_WORD_TYPE(curstack->prev->type))
2311 goto throw_stack_category_error;
2314 iptr->opc = ICMD_DUP2_X1;
2318 /* ..., cat1, ????, cat1 */
2319 #ifdef ENABLE_VERIFIER
2322 if (IS_2_WORD_TYPE(curstack->prev->type)
2323 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2324 goto throw_stack_category_error;
2328 src1 = curstack->prev->prev->prev;
2329 src2 = curstack->prev->prev;
2330 src3 = curstack->prev;
2332 POPANY; POPANY; POPANY; POPANY;
2335 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2336 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
2338 MOVE_UP(src1); iptr++; len--;
2339 MOVE_UP(src2); iptr++; len--;
2340 MOVE_UP(src3); iptr++; len--;
2341 MOVE_UP(src4); iptr++; len--;
2343 COPY_DOWN(curstack, dst2); iptr++; len--;
2344 COPY_DOWN(curstack->prev, dst1);
2346 coalescing_boundary = sd.new;
2350 /* pop 2 push 2 swap */
2353 #ifdef ENABLE_VERIFIER
2356 if (IS_2_WORD_TYPE(curstack->type)
2357 || IS_2_WORD_TYPE(curstack->prev->type))
2358 goto throw_stack_category_error;
2362 src1 = curstack->prev;
2367 MOVE_UP(src2); iptr++; len--;
2370 coalescing_boundary = sd.new;
2377 coalescing_boundary = sd.new;
2378 #if !SUPPORT_DIVISION
2379 bte = iptr->sx.s23.s3.bte;
2382 if (md->memuse > rd->memuse)
2383 rd->memuse = md->memuse;
2384 if (md->argintreguse > rd->argintreguse)
2385 rd->argintreguse = md->argintreguse;
2387 /* make all stack variables saved */
2391 sd.var[copy->varnum].flags |= SAVEDVAR;
2392 copy->flags |= SAVEDVAR;
2397 #endif /* !SUPPORT_DIVISION */
2408 COUNT(count_pcmd_op);
2409 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2414 coalescing_boundary = sd.new;
2415 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2416 bte = iptr->sx.s23.s3.bte;
2419 if (md->memuse > rd->memuse)
2420 rd->memuse = md->memuse;
2421 if (md->argintreguse > rd->argintreguse)
2422 rd->argintreguse = md->argintreguse;
2423 /* XXX non-leaf method? */
2425 /* make all stack variables saved */
2429 sd.var[copy->varnum].flags |= SAVEDVAR;
2430 copy->flags |= SAVEDVAR;
2435 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2440 #if SUPPORT_LONG_LOGICAL
2444 #endif /* SUPPORT_LONG_LOGICAL */
2445 COUNT(count_pcmd_op);
2446 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2452 COUNT(count_pcmd_op);
2453 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2461 COUNT(count_pcmd_op);
2462 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2470 COUNT(count_pcmd_op);
2471 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2475 COUNT(count_pcmd_op);
2476 #if SUPPORT_LONG_CMP_CONST
2477 if ((len == 0) || (iptr[1].sx.val.i != 0))
2480 switch (iptr[1].opc) {
2482 iptr->opc = ICMD_IF_LCMPEQ;
2484 iptr->dst.insindex = iptr[1].dst.insindex;
2485 iptr[1].opc = ICMD_NOP;
2487 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2488 BRANCH(tbptr, copy);
2490 COUNT(count_pcmd_bra);
2493 iptr->opc = ICMD_IF_LCMPNE;
2494 goto icmd_lcmp_if_tail;
2496 iptr->opc = ICMD_IF_LCMPLT;
2497 goto icmd_lcmp_if_tail;
2499 iptr->opc = ICMD_IF_LCMPGT;
2500 goto icmd_lcmp_if_tail;
2502 iptr->opc = ICMD_IF_LCMPLE;
2503 goto icmd_lcmp_if_tail;
2505 iptr->opc = ICMD_IF_LCMPGE;
2506 goto icmd_lcmp_if_tail;
2512 #endif /* SUPPORT_LONG_CMP_CONST */
2513 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2516 /* XXX why is this deactivated? */
2519 COUNT(count_pcmd_op);
2520 if ((len == 0) || (iptr[1].sx.val.i != 0))
2523 switch (iptr[1].opc) {
2525 iptr->opc = ICMD_IF_FCMPEQ;
2527 iptr->dst.insindex = iptr[1].dst.insindex;
2528 iptr[1].opc = ICMD_NOP;
2530 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2531 BRANCH(tbptr, copy);
2533 COUNT(count_pcmd_bra);
2536 iptr->opc = ICMD_IF_FCMPNE;
2537 goto icmd_if_fcmpl_tail;
2539 iptr->opc = ICMD_IF_FCMPL_LT;
2540 goto icmd_if_fcmpl_tail;
2542 iptr->opc = ICMD_IF_FCMPL_GT;
2543 goto icmd_if_fcmpl_tail;
2545 iptr->opc = ICMD_IF_FCMPL_LE;
2546 goto icmd_if_fcmpl_tail;
2548 iptr->opc = ICMD_IF_FCMPL_GE;
2549 goto icmd_if_fcmpl_tail;
2556 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2560 COUNT(count_pcmd_op);
2561 if ((len == 0) || (iptr[1].sx.val.i != 0))
2564 switch (iptr[1].opc) {
2566 iptr->opc = ICMD_IF_FCMPEQ;
2568 iptr->dst.insindex = iptr[1].dst.insindex;
2569 iptr[1].opc = ICMD_NOP;
2571 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2572 BRANCH(tbptr, copy);
2574 COUNT(count_pcmd_bra);
2577 iptr->opc = ICMD_IF_FCMPNE;
2578 goto icmd_if_fcmpg_tail;
2580 iptr->opc = ICMD_IF_FCMPG_LT;
2581 goto icmd_if_fcmpg_tail;
2583 iptr->opc = ICMD_IF_FCMPG_GT;
2584 goto icmd_if_fcmpg_tail;
2586 iptr->opc = ICMD_IF_FCMPG_LE;
2587 goto icmd_if_fcmpg_tail;
2589 iptr->opc = ICMD_IF_FCMPG_GE;
2590 goto icmd_if_fcmpg_tail;
2597 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2601 COUNT(count_pcmd_op);
2602 if ((len == 0) || (iptr[1].sx.val.i != 0))
2605 switch (iptr[1].opc) {
2607 iptr->opc = ICMD_IF_DCMPEQ;
2609 iptr->dst.insindex = iptr[1].dst.insindex;
2610 iptr[1].opc = ICMD_NOP;
2612 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2613 BRANCH(tbptr, copy);
2615 COUNT(count_pcmd_bra);
2618 iptr->opc = ICMD_IF_DCMPNE;
2619 goto icmd_if_dcmpl_tail;
2621 iptr->opc = ICMD_IF_DCMPL_LT;
2622 goto icmd_if_dcmpl_tail;
2624 iptr->opc = ICMD_IF_DCMPL_GT;
2625 goto icmd_if_dcmpl_tail;
2627 iptr->opc = ICMD_IF_DCMPL_LE;
2628 goto icmd_if_dcmpl_tail;
2630 iptr->opc = ICMD_IF_DCMPL_GE;
2631 goto icmd_if_dcmpl_tail;
2638 OPTT2_1(TYPE_DBL, TYPE_INT);
2642 COUNT(count_pcmd_op);
2643 if ((len == 0) || (iptr[1].sx.val.i != 0))
2646 switch (iptr[1].opc) {
2648 iptr->opc = ICMD_IF_DCMPEQ;
2650 iptr->dst.insindex = iptr[1].dst.insindex;
2651 iptr[1].opc = ICMD_NOP;
2653 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2654 BRANCH(tbptr, copy);
2656 COUNT(count_pcmd_bra);
2659 iptr->opc = ICMD_IF_DCMPNE;
2660 goto icmd_if_dcmpg_tail;
2662 iptr->opc = ICMD_IF_DCMPG_LT;
2663 goto icmd_if_dcmpg_tail;
2665 iptr->opc = ICMD_IF_DCMPG_GT;
2666 goto icmd_if_dcmpg_tail;
2668 iptr->opc = ICMD_IF_DCMPG_LE;
2669 goto icmd_if_dcmpg_tail;
2671 iptr->opc = ICMD_IF_DCMPG_GE;
2672 goto icmd_if_dcmpg_tail;
2679 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2684 COUNT(count_pcmd_op);
2685 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2690 COUNT(count_pcmd_op);
2691 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2700 case ICMD_INT2SHORT:
2701 COUNT(count_pcmd_op);
2702 OP1_1(TYPE_INT, TYPE_INT);
2705 COUNT(count_pcmd_op);
2706 OP1_1(TYPE_LNG, TYPE_LNG);
2709 COUNT(count_pcmd_op);
2710 OP1_1(TYPE_FLT, TYPE_FLT);
2713 COUNT(count_pcmd_op);
2714 OP1_1(TYPE_DBL, TYPE_DBL);
2718 COUNT(count_pcmd_op);
2719 OP1_1(TYPE_INT, TYPE_LNG);
2722 COUNT(count_pcmd_op);
2723 OP1_1(TYPE_INT, TYPE_FLT);
2726 COUNT(count_pcmd_op);
2727 OP1_1(TYPE_INT, TYPE_DBL);
2730 COUNT(count_pcmd_op);
2731 OP1_1(TYPE_LNG, TYPE_INT);
2734 COUNT(count_pcmd_op);
2735 OP1_1(TYPE_LNG, TYPE_FLT);
2738 COUNT(count_pcmd_op);
2739 OP1_1(TYPE_LNG, TYPE_DBL);
2742 COUNT(count_pcmd_op);
2743 OP1_1(TYPE_FLT, TYPE_INT);
2746 COUNT(count_pcmd_op);
2747 OP1_1(TYPE_FLT, TYPE_LNG);
2750 COUNT(count_pcmd_op);
2751 OP1_1(TYPE_FLT, TYPE_DBL);
2754 COUNT(count_pcmd_op);
2755 OP1_1(TYPE_DBL, TYPE_INT);
2758 COUNT(count_pcmd_op);
2759 OP1_1(TYPE_DBL, TYPE_LNG);
2762 COUNT(count_pcmd_op);
2763 OP1_1(TYPE_DBL, TYPE_FLT);
2766 case ICMD_CHECKCAST:
2767 coalescing_boundary = sd.new;
2768 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2769 /* array type cast-check */
2771 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2774 if (md->memuse > rd->memuse)
2775 rd->memuse = md->memuse;
2776 if (md->argintreguse > rd->argintreguse)
2777 rd->argintreguse = md->argintreguse;
2779 /* make all stack variables saved */
2783 sd.var[copy->varnum].flags |= SAVEDVAR;
2784 copy->flags |= SAVEDVAR;
2788 OP1_1(TYPE_ADR, TYPE_ADR);
2791 case ICMD_INSTANCEOF:
2792 case ICMD_ARRAYLENGTH:
2793 coalescing_boundary = sd.new;
2794 OP1_1(TYPE_ADR, TYPE_INT);
2798 case ICMD_ANEWARRAY:
2799 coalescing_boundary = sd.new;
2800 OP1_1(TYPE_INT, TYPE_ADR);
2804 coalescing_boundary = sd.new;
2805 COUNT(count_check_null);
2806 COUNT(count_pcmd_mem);
2807 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2808 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2813 case ICMD_GETSTATIC:
2814 coalescing_boundary = sd.new;
2815 COUNT(count_pcmd_mem);
2816 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2817 OP0_1(fmiref->parseddesc.fd->type);
2821 coalescing_boundary = sd.new;
2828 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2830 tbptr->type = BBTYPE_SBR;
2832 /* We need to check for overflow right here because
2833 * the pushed value is poped afterwards */
2836 /* calculate stack after return */
2841 /* pop many push any */
2845 bte = iptr->sx.s23.s3.bte;
2849 case ICMD_INVOKESTATIC:
2850 case ICMD_INVOKESPECIAL:
2851 case ICMD_INVOKEVIRTUAL:
2852 case ICMD_INVOKEINTERFACE:
2853 COUNT(count_pcmd_met);
2855 /* Check for functions to replace with builtin
2858 if (builtintable_replace_function(iptr))
2861 INSTRUCTION_GET_METHODDESC(iptr, md);
2862 /* XXX resurrect this COUNT? */
2863 /* if (lm->flags & ACC_STATIC) */
2864 /* {COUNT(count_check_null);} */
2868 coalescing_boundary = sd.new;
2872 if (md->memuse > rd->memuse)
2873 rd->memuse = md->memuse;
2874 if (md->argintreguse > rd->argintreguse)
2875 rd->argintreguse = md->argintreguse;
2876 if (md->argfltreguse > rd->argfltreguse)
2877 rd->argfltreguse = md->argfltreguse;
2881 /* XXX optimize for <= 2 args */
2882 /* XXX not for ICMD_BUILTIN */
2883 iptr->s1.argcount = stackdepth;
2884 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2887 for (i-- ; i >= 0; i--) {
2888 iptr->sx.s23.s2.args[i] = copy->varnum;
2890 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2891 /* -> won't help anyway */
2892 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2894 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2895 /* If we pass float arguments in integer argument registers, we
2896 * are not allowed to precolor them here. Floats have to be moved
2897 * to this regs explicitly in codegen().
2898 * Only arguments that are passed by stack anyway can be precolored
2899 * (michi 2005/07/24) */
2900 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
2901 (!IS_FLT_DBL_TYPE(copy->type)
2902 || md->params[i].inmemory)) {
2904 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
2909 #if defined(ENABLE_INTRP)
2912 if (md->params[i].inmemory) {
2913 sd.var[copy->varnum].regoff =
2914 md->params[i].regoff;
2915 sd.var[copy->varnum].flags |=
2919 if (IS_FLT_DBL_TYPE(copy->type)) {
2920 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2921 assert(0); /* XXX is this assert ok? */
2923 sd.var[copy->varnum].regoff =
2924 rd->argfltregs[md->params[i].regoff];
2925 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2928 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2929 if (IS_2_WORD_TYPE(copy->type))
2930 sd.var[copy->varnum].regoff =
2931 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2932 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2935 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2936 sd.var[copy->varnum].regoff =
2937 rd->argintregs[md->params[i].regoff];
2940 #if defined(ENABLE_INTRP)
2941 } /* end if (!opt_intrp) */
2948 /* deal with live-through stack slots "under" the */
2950 /* XXX not for ICMD_BUILTIN */
2956 iptr->sx.s23.s2.args[i++] = copy->varnum;
2957 sd.var[copy->varnum].flags |= SAVEDVAR;
2961 /* pop the arguments */
2970 /* push the return value */
2972 if (md->returntype.type != TYPE_VOID) {
2973 GET_NEW_VAR(sd, new_index, md->returntype.type);
2974 DST(md->returntype.type, new_index);
2979 case ICMD_INLINE_START:
2980 case ICMD_INLINE_END:
2985 case ICMD_MULTIANEWARRAY:
2986 coalescing_boundary = sd.new;
2987 if (rd->argintreguse < 3)
2988 rd->argintreguse = 3;
2990 i = iptr->s1.argcount;
2994 iptr->sx.s23.s2.args = DMNEW(s4, i);
2996 #if defined(SPECIALMEMUSE)
2997 # if defined(__DARWIN__)
2998 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
2999 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3001 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
3002 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
3005 # if defined(__I386__)
3006 if (rd->memuse < i + 3)
3007 rd->memuse = i + 3; /* n integer args spilled on stack */
3008 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3009 if (rd->memuse < i + 2)
3010 rd->memuse = i + 2; /* 4*4 bytes callee save space */
3013 rd->memuse = i; /* n integer args spilled on stack */
3014 # endif /* defined(__I386__) */
3018 /* check INT type here? Currently typecheck does this. */
3019 iptr->sx.s23.s2.args[i] = copy->varnum;
3020 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
3021 && (!IS_OUTVAR(copy))
3022 && (!IS_LOCALVAR(copy)) ) {
3023 copy->varkind = ARGVAR;
3024 sd.var[copy->varnum].flags |=
3025 INMEMORY & PREALLOC;
3026 #if defined(SPECIALMEMUSE)
3027 # if defined(__DARWIN__)
3028 sd.var[copy->varnum].regoff = i +
3029 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
3031 sd.var[copy->varnum].regoff = i +
3032 LA_SIZE_IN_POINTERS + 3;
3035 # if defined(__I386__)
3036 sd.var[copy->varnum].regoff = i + 3;
3037 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
3038 sd.var[copy->varnum].regoff = i + 2;
3040 sd.var[copy->varnum].regoff = i;
3041 # endif /* defined(__I386__) */
3042 #endif /* defined(SPECIALMEMUSE) */
3047 sd.var[copy->varnum].flags |= SAVEDVAR;
3051 i = iptr->s1.argcount;
3056 GET_NEW_VAR(sd, new_index, TYPE_ADR);
3057 DST(TYPE_ADR, new_index);
3063 new_internalerror("Unknown ICMD %d", opcode);
3069 } /* while instructions */
3071 /* stack slots at basic block end become interfaces */
3073 sd.bptr->outdepth = stackdepth;
3074 sd.bptr->outvars = DMNEW(s4, stackdepth);
3077 for (copy = curstack; copy; i--, copy = copy->prev) {
3080 /* with the new vars rd->interfaces will be removed */
3081 /* and all in and outvars have to be STACKVARS! */
3082 /* in the moment i.e. SWAP with in and out vars can */
3083 /* create an unresolvable conflict */
3087 v = sd.var + copy->varnum;
3090 if (jd->interface_map[i*5 + copy->type].flags == UNUSED) {
3091 /* no interface var until now for this depth and */
3093 jd->interface_map[i*5 + copy->type].flags = v->flags;
3096 jd->interface_map[i*5 + copy->type].flags |= v->flags;
3099 sd.bptr->outvars[i] = copy->varnum;
3102 /* check if interface slots at basic block begin must be saved */
3104 for (i=0; i<sd.bptr->indepth; ++i) {
3105 varinfo *v = sd.var + sd.bptr->invars[i];
3107 if (jd->interface_map[i*5 + v->type].flags == UNUSED) {
3108 /* no interface var until now for this depth and */
3110 jd->interface_map[i*5 + v->type].flags = v->flags;
3113 jd->interface_map[i*5 + v->type].flags |= v->flags;
3118 /* store the number of this block's variables */
3120 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
3122 #if defined(STACK_VERBOSE)
3123 printf("OUTVARS\n");
3124 /* XXX print something useful here */
3129 superblockend = true;
3132 } /* while blocks */
3133 } while (repeat && !deadcode);
3135 /* gather statistics *****************************************************/
3137 #if defined(ENABLE_STATISTICS)
3139 if (jd->new_basicblockcount > count_max_basic_blocks)
3140 count_max_basic_blocks = jd->new_basicblockcount;
3141 count_basic_blocks += jd->new_basicblockcount;
3142 if (jd->new_instructioncount > count_max_javainstr)
3143 count_max_javainstr = jd->new_instructioncount;
3144 count_javainstr += jd->new_instructioncount;
3145 if (jd->new_stackcount > count_upper_bound_new_stack)
3146 count_upper_bound_new_stack = jd->new_stackcount;
3147 if ((sd.new - jd->new_stack) > count_max_new_stack)
3148 count_max_new_stack = (sd.new - jd->new_stack);
3150 b_count = jd->new_basicblockcount;
3151 sd.bptr = jd->new_basicblocks;
3152 while (--b_count >= 0) {
3153 if (sd.bptr->flags > BBREACHED) {
3154 if (sd.bptr->indepth >= 10)
3155 count_block_stack[10]++;
3157 count_block_stack[sd.bptr->indepth]++;
3158 len = sd.bptr->icount;
3160 count_block_size_distribution[len]++;
3162 count_block_size_distribution[10]++;
3164 count_block_size_distribution[11]++;
3166 count_block_size_distribution[12]++;
3168 count_block_size_distribution[13]++;
3170 count_block_size_distribution[14]++;
3172 count_block_size_distribution[15]++;
3174 count_block_size_distribution[16]++;
3176 count_block_size_distribution[17]++;
3181 if (iteration_count == 1)
3182 count_analyse_iterations[0]++;
3183 else if (iteration_count == 2)
3184 count_analyse_iterations[1]++;
3185 else if (iteration_count == 3)
3186 count_analyse_iterations[2]++;
3187 else if (iteration_count == 4)
3188 count_analyse_iterations[3]++;
3190 count_analyse_iterations[4]++;
3192 if (jd->new_basicblockcount <= 5)
3193 count_method_bb_distribution[0]++;
3194 else if (jd->new_basicblockcount <= 10)
3195 count_method_bb_distribution[1]++;
3196 else if (jd->new_basicblockcount <= 15)
3197 count_method_bb_distribution[2]++;
3198 else if (jd->new_basicblockcount <= 20)
3199 count_method_bb_distribution[3]++;
3200 else if (jd->new_basicblockcount <= 30)
3201 count_method_bb_distribution[4]++;
3202 else if (jd->new_basicblockcount <= 40)
3203 count_method_bb_distribution[5]++;
3204 else if (jd->new_basicblockcount <= 50)
3205 count_method_bb_distribution[6]++;
3206 else if (jd->new_basicblockcount <= 75)
3207 count_method_bb_distribution[7]++;
3209 count_method_bb_distribution[8]++;
3211 #endif /* defined(ENABLE_STATISTICS) */
3213 /* everything's ok *******************************************************/
3217 /* goto labels for throwing verifier exceptions **************************/
3219 #if defined(ENABLE_VERIFIER)
3221 throw_stack_underflow:
3222 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3225 throw_stack_overflow:
3226 exceptions_throw_verifyerror(m, "Stack size too large");
3229 throw_stack_depth_error:
3230 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3233 throw_stack_type_error:
3234 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3237 throw_stack_category_error:
3238 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3246 * These are local overrides for various environment variables in Emacs.
3247 * Please do not remove this and leave it at the end of the file, where
3248 * Emacs will automagically detect them.
3249 * ---------------------------------------------------------------------
3252 * indent-tabs-mode: t
3256 * vim:noexpandtab:sw=4:ts=4: