1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
32 $Id: stack.c 2406 2005-04-28 12:19:06Z jowenn $
43 #include "mm/memory.h"
44 #include "native/native.h"
45 #include "toolbox/logging.h"
46 #include "vm/global.h"
47 #include "vm/builtin.h"
48 #include "vm/options.h"
49 #include "vm/resolve.h"
50 #include "vm/statistics.h"
51 #include "vm/tables.h"
52 #include "vm/jit/codegen.inc.h"
53 #include "vm/jit/jit.h"
54 #include "vm/jit/reg.h"
55 #include "vm/jit/stack.h"
56 #include "vm/jit/lsra.h"
59 /**********************************************************************/
61 /**********************************************************************/
63 /* analyse_stack uses the intermediate code created by parse.c to
64 * build a model of the JVM operand stack for the current method.
66 * The following checks are performed:
67 * - check for operand stack underflow (before each instruction)
68 * - check for operand stack overflow (after[1] each instruction)
69 * - check for matching stack depth at merging points
70 * - check for matching basic types[2] at merging points
71 * - check basic types for instruction input (except for BUILTIN*
72 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
74 * [1]) Checking this after the instruction should be ok. parse.c
75 * counts the number of required stack slots in such a way that it is
76 * only vital that we don't exceed `maxstack` at basic block
79 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
80 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
81 * types are not discerned.
84 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
92 int opcode, i, len, loops;
93 int superblockend, repeat, deadcode;
108 argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */
109 for (i = 0; i < cd->maxlocals; i++)
112 rd->arguments_num = 0;
115 m->basicblocks[0].flags = BBREACHED;
116 m->basicblocks[0].instack = 0;
117 m->basicblocks[0].indepth = 0;
119 for (i = 0; i < cd->exceptiontablelength; i++) {
120 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
121 bptr->flags = BBREACHED;
122 bptr->type = BBTYPE_EXH;
125 bptr->pre_count = 10000;
130 #if CONDITIONAL_LOADCONST
131 b_count = m->basicblockcount;
132 bptr = m->basicblocks;
133 while (--b_count >= 0) {
134 if (bptr->icount != 0) {
135 iptr = bptr->iinstr + bptr->icount - 1;
168 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
171 case ICMD_TABLESWITCH:
173 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
174 i = *s4ptr++; /* low */
175 i = *s4ptr++ - i + 1; /* high */
177 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
181 case ICMD_LOOKUPSWITCH:
183 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
184 i = *s4ptr++; /* count */
186 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
197 #endif /* CONDITIONAL_LOADCONST */
202 b_count = m->basicblockcount;
203 bptr = m->basicblocks;
204 superblockend = true;
208 /*printf("Block count :%d\n",b_count);*/
209 while (--b_count >= 0) {
210 if (bptr->flags == BBDELETED) {
212 /*log_text("BBDELETED");*/
214 else if (superblockend && (bptr->flags < BBREACHED))
216 else if (bptr->flags <= BBREACHED) {
218 stackdepth = bptr->indepth;
219 else if (bptr->flags < BBREACHED) {
221 bptr->instack = copy;
222 bptr->indepth = stackdepth;
224 else if (bptr->indepth != stackdepth) {
225 show_icmd_method(m, cd, rd);
226 printf("Block: %d, required depth: %d, current depth: %d\n", bptr->debug_nr, bptr->indepth, stackdepth);
227 panic("Stack depth mismatch");
230 curstack = bptr->instack;
232 superblockend = false;
233 bptr->flags = BBFINISHED;
236 b_index = bptr - m->basicblocks;
239 /* XXX TWISTI: why is this set to NULL here? */
240 /* iptr->target = NULL; */
242 /* dolog("p: %04d op: %s stack: %p", iptr - instr, icmd_names[opcode], curstack); */
244 #if defined(USEBUILTINTABLE)
247 stdopdescriptor *breplace;
248 breplace = find_builtin(opcode);
250 if (breplace && opcode == breplace->opcode) {
251 iptr[0].opc = breplace->icmd;
252 iptr[0].op1 = breplace->type_d;
253 iptr[0].val.fp = breplace->builtin;
254 m->isleafmethod = false;
255 switch (breplace->icmd) {
263 builtin_descriptor *breplace;
264 breplace = find_builtin(opcode);
266 if (breplace && opcode == breplace->opcode) {
267 iptr[0].opc = breplace->icmd;
268 iptr[0].op1 = breplace->type_d;
269 iptr[0].val.fp = breplace->builtin;
270 m->isleafmethod = false;
271 switch (breplace->icmd) {
279 #endif /* defined(USEBUILTINTABLE) */
286 COUNT(count_check_null);
288 case ICMD_CHECKASIZE:
289 case ICMD_CHECKEXCEPTION:
291 case ICMD_IFEQ_ICONST:
292 case ICMD_IFNE_ICONST:
293 case ICMD_IFLT_ICONST:
294 case ICMD_IFGE_ICONST:
295 case ICMD_IFGT_ICONST:
296 case ICMD_IFLE_ICONST:
297 case ICMD_ELSE_ICONST:
302 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
304 COUNT(count_pcmd_return);
306 superblockend = true;
309 /* pop 0 push 1 const */
312 COUNT(count_pcmd_load);
314 switch (iptr[1].opc) {
316 iptr[0].opc = ICMD_IADDCONST;
318 iptr[1].opc = ICMD_NOP;
319 OP1_1(TYPE_INT, TYPE_INT);
320 COUNT(count_pcmd_op);
323 iptr[0].opc = ICMD_ISUBCONST;
324 goto icmd_iconst_tail;
325 #if SUPPORT_CONST_MUL
327 iptr[0].opc = ICMD_IMULCONST;
328 goto icmd_iconst_tail;
329 #else /* SUPPORT_CONST_MUL */
331 if (iptr[0].val.i == 0x00000002)
333 else if (iptr[0].val.i == 0x00000004)
335 else if (iptr[0].val.i == 0x00000008)
337 else if (iptr[0].val.i == 0x00000010)
339 else if (iptr[0].val.i == 0x00000020)
341 else if (iptr[0].val.i == 0x00000040)
343 else if (iptr[0].val.i == 0x00000080)
345 else if (iptr[0].val.i == 0x00000100)
347 else if (iptr[0].val.i == 0x00000200)
349 else if (iptr[0].val.i == 0x00000400)
351 else if (iptr[0].val.i == 0x00000800)
353 else if (iptr[0].val.i == 0x00001000)
355 else if (iptr[0].val.i == 0x00002000)
357 else if (iptr[0].val.i == 0x00004000)
359 else if (iptr[0].val.i == 0x00008000)
361 else if (iptr[0].val.i == 0x00010000)
363 else if (iptr[0].val.i == 0x00020000)
365 else if (iptr[0].val.i == 0x00040000)
367 else if (iptr[0].val.i == 0x00080000)
369 else if (iptr[0].val.i == 0x00100000)
371 else if (iptr[0].val.i == 0x00200000)
373 else if (iptr[0].val.i == 0x00400000)
375 else if (iptr[0].val.i == 0x00800000)
377 else if (iptr[0].val.i == 0x01000000)
379 else if (iptr[0].val.i == 0x02000000)
381 else if (iptr[0].val.i == 0x04000000)
383 else if (iptr[0].val.i == 0x08000000)
385 else if (iptr[0].val.i == 0x10000000)
387 else if (iptr[0].val.i == 0x20000000)
389 else if (iptr[0].val.i == 0x40000000)
391 else if (iptr[0].val.i == 0x80000000)
397 iptr[0].opc = ICMD_IMULPOW2;
398 goto icmd_iconst_tail;
399 #endif /* SUPPORT_CONST_MUL */
401 if (iptr[0].val.i == 0x00000002)
403 else if (iptr[0].val.i == 0x00000004)
405 else if (iptr[0].val.i == 0x00000008)
407 else if (iptr[0].val.i == 0x00000010)
409 else if (iptr[0].val.i == 0x00000020)
411 else if (iptr[0].val.i == 0x00000040)
413 else if (iptr[0].val.i == 0x00000080)
415 else if (iptr[0].val.i == 0x00000100)
417 else if (iptr[0].val.i == 0x00000200)
419 else if (iptr[0].val.i == 0x00000400)
421 else if (iptr[0].val.i == 0x00000800)
423 else if (iptr[0].val.i == 0x00001000)
425 else if (iptr[0].val.i == 0x00002000)
427 else if (iptr[0].val.i == 0x00004000)
429 else if (iptr[0].val.i == 0x00008000)
431 else if (iptr[0].val.i == 0x00010000)
433 else if (iptr[0].val.i == 0x00020000)
435 else if (iptr[0].val.i == 0x00040000)
437 else if (iptr[0].val.i == 0x00080000)
439 else if (iptr[0].val.i == 0x00100000)
441 else if (iptr[0].val.i == 0x00200000)
443 else if (iptr[0].val.i == 0x00400000)
445 else if (iptr[0].val.i == 0x00800000)
447 else if (iptr[0].val.i == 0x01000000)
449 else if (iptr[0].val.i == 0x02000000)
451 else if (iptr[0].val.i == 0x04000000)
453 else if (iptr[0].val.i == 0x08000000)
455 else if (iptr[0].val.i == 0x10000000)
457 else if (iptr[0].val.i == 0x20000000)
459 else if (iptr[0].val.i == 0x40000000)
461 else if (iptr[0].val.i == 0x80000000)
467 iptr[0].opc = ICMD_IDIVPOW2;
468 goto icmd_iconst_tail;
470 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
471 if ((iptr[0].val.i == 0x00000002) ||
472 (iptr[0].val.i == 0x00000004) ||
473 (iptr[0].val.i == 0x00000008) ||
474 (iptr[0].val.i == 0x00000010) ||
475 (iptr[0].val.i == 0x00000020) ||
476 (iptr[0].val.i == 0x00000040) ||
477 (iptr[0].val.i == 0x00000080) ||
478 (iptr[0].val.i == 0x00000100) ||
479 (iptr[0].val.i == 0x00000200) ||
480 (iptr[0].val.i == 0x00000400) ||
481 (iptr[0].val.i == 0x00000800) ||
482 (iptr[0].val.i == 0x00001000) ||
483 (iptr[0].val.i == 0x00002000) ||
484 (iptr[0].val.i == 0x00004000) ||
485 (iptr[0].val.i == 0x00008000) ||
486 (iptr[0].val.i == 0x00010000) ||
487 (iptr[0].val.i == 0x00020000) ||
488 (iptr[0].val.i == 0x00040000) ||
489 (iptr[0].val.i == 0x00080000) ||
490 (iptr[0].val.i == 0x00100000) ||
491 (iptr[0].val.i == 0x00200000) ||
492 (iptr[0].val.i == 0x00400000) ||
493 (iptr[0].val.i == 0x00800000) ||
494 (iptr[0].val.i == 0x01000000) ||
495 (iptr[0].val.i == 0x02000000) ||
496 (iptr[0].val.i == 0x04000000) ||
497 (iptr[0].val.i == 0x08000000) ||
498 (iptr[0].val.i == 0x10000000) ||
499 (iptr[0].val.i == 0x20000000) ||
500 (iptr[0].val.i == 0x40000000) ||
501 (iptr[0].val.i == 0x80000000)) {
502 iptr[0].opc = ICMD_IREMPOW2;
504 goto icmd_iconst_tail;
508 #if SUPPORT_CONST_LOGICAL
510 iptr[0].opc = ICMD_IANDCONST;
511 goto icmd_iconst_tail;
513 iptr[0].opc = ICMD_IORCONST;
514 goto icmd_iconst_tail;
516 iptr[0].opc = ICMD_IXORCONST;
517 goto icmd_iconst_tail;
518 #endif /* SUPPORT_CONST_LOGICAL */
520 iptr[0].opc = ICMD_ISHLCONST;
521 goto icmd_iconst_tail;
523 iptr[0].opc = ICMD_ISHRCONST;
524 goto icmd_iconst_tail;
526 iptr[0].opc = ICMD_IUSHRCONST;
527 goto icmd_iconst_tail;
528 #if SUPPORT_LONG_SHIFT
530 iptr[0].opc = ICMD_LSHLCONST;
531 goto icmd_lconst_tail;
533 iptr[0].opc = ICMD_LSHRCONST;
534 goto icmd_lconst_tail;
536 iptr[0].opc = ICMD_LUSHRCONST;
537 goto icmd_lconst_tail;
538 #endif /* SUPPORT_LONG_SHIFT */
540 iptr[0].opc = ICMD_IFEQ;
542 iptr[0].op1 = iptr[1].op1;
546 /* iptr[1].opc = ICMD_NOP; */
548 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
550 iptr[0].target = (void *) tbptr;
552 MARKREACHED(tbptr, copy);
553 COUNT(count_pcmd_bra);
559 iptr[0].opc = ICMD_IFLT;
560 goto icmd_if_icmp_tail;
562 iptr[0].opc = ICMD_IFLE;
563 goto icmd_if_icmp_tail;
565 iptr[0].opc = ICMD_IFNE;
566 goto icmd_if_icmp_tail;
568 iptr[0].opc = ICMD_IFGT;
569 goto icmd_if_icmp_tail;
571 iptr[0].opc = ICMD_IFGE;
572 goto icmd_if_icmp_tail;
574 #if SUPPORT_CONST_STORE
579 #if SUPPORT_CONST_STORE_ZERO_ONLY
580 if (iptr[0].val.i == 0) {
581 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
582 switch (iptr[1].opc) {
584 iptr[0].opc = ICMD_IASTORECONST;
587 iptr[0].opc = ICMD_BASTORECONST;
590 iptr[0].opc = ICMD_CASTORECONST;
593 iptr[0].opc = ICMD_SASTORECONST;
597 iptr[1].opc = ICMD_NOP;
598 OPTT2_0(TYPE_INT, TYPE_ADR);
599 COUNT(count_pcmd_op);
600 #if SUPPORT_CONST_STORE_ZERO_ONLY
603 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
608 #if SUPPORT_CONST_STORE_ZERO_ONLY
609 if (iptr[0].val.i == 0) {
610 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
611 switch (iptr[1].opc) {
613 iptr[0].opc = ICMD_PUTSTATICCONST;
617 iptr[0].opc = ICMD_PUTFIELDCONST;
622 iptr[1].opc = ICMD_NOP;
623 iptr[0].op1 = TYPE_INT;
624 COUNT(count_pcmd_op);
625 #if SUPPORT_CONST_STORE_ZERO_ONLY
628 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
630 #endif /* SUPPORT_CONST_STORE */
640 COUNT(count_pcmd_load);
642 switch (iptr[1].opc) {
645 iptr[0].opc = ICMD_LADDCONST;
647 iptr[1].opc = ICMD_NOP;
648 OP1_1(TYPE_LNG,TYPE_LNG);
649 COUNT(count_pcmd_op);
652 iptr[0].opc = ICMD_LSUBCONST;
653 goto icmd_lconst_tail;
654 #endif /* SUPPORT_LONG_ADD */
655 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
657 iptr[0].opc = ICMD_LMULCONST;
658 goto icmd_lconst_tail;
659 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
660 # if SUPPORT_LONG_SHIFT
662 if (iptr[0].val.l == 0x00000002)
664 else if (iptr[0].val.l == 0x00000004)
666 else if (iptr[0].val.l == 0x00000008)
668 else if (iptr[0].val.l == 0x00000010)
670 else if (iptr[0].val.l == 0x00000020)
672 else if (iptr[0].val.l == 0x00000040)
674 else if (iptr[0].val.l == 0x00000080)
676 else if (iptr[0].val.l == 0x00000100)
678 else if (iptr[0].val.l == 0x00000200)
680 else if (iptr[0].val.l == 0x00000400)
682 else if (iptr[0].val.l == 0x00000800)
684 else if (iptr[0].val.l == 0x00001000)
686 else if (iptr[0].val.l == 0x00002000)
688 else if (iptr[0].val.l == 0x00004000)
690 else if (iptr[0].val.l == 0x00008000)
692 else if (iptr[0].val.l == 0x00010000)
694 else if (iptr[0].val.l == 0x00020000)
696 else if (iptr[0].val.l == 0x00040000)
698 else if (iptr[0].val.l == 0x00080000)
700 else if (iptr[0].val.l == 0x00100000)
702 else if (iptr[0].val.l == 0x00200000)
704 else if (iptr[0].val.l == 0x00400000)
706 else if (iptr[0].val.l == 0x00800000)
708 else if (iptr[0].val.l == 0x01000000)
710 else if (iptr[0].val.l == 0x02000000)
712 else if (iptr[0].val.l == 0x04000000)
714 else if (iptr[0].val.l == 0x08000000)
716 else if (iptr[0].val.l == 0x10000000)
718 else if (iptr[0].val.l == 0x20000000)
720 else if (iptr[0].val.l == 0x40000000)
722 else if (iptr[0].val.l == 0x80000000)
728 iptr[0].opc = ICMD_LMULPOW2;
729 goto icmd_lconst_tail;
730 # endif /* SUPPORT_LONG_SHIFT */
731 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
734 if (iptr[0].val.l == 0x00000002)
736 else if (iptr[0].val.l == 0x00000004)
738 else if (iptr[0].val.l == 0x00000008)
740 else if (iptr[0].val.l == 0x00000010)
742 else if (iptr[0].val.l == 0x00000020)
744 else if (iptr[0].val.l == 0x00000040)
746 else if (iptr[0].val.l == 0x00000080)
748 else if (iptr[0].val.l == 0x00000100)
750 else if (iptr[0].val.l == 0x00000200)
752 else if (iptr[0].val.l == 0x00000400)
754 else if (iptr[0].val.l == 0x00000800)
756 else if (iptr[0].val.l == 0x00001000)
758 else if (iptr[0].val.l == 0x00002000)
760 else if (iptr[0].val.l == 0x00004000)
762 else if (iptr[0].val.l == 0x00008000)
764 else if (iptr[0].val.l == 0x00010000)
766 else if (iptr[0].val.l == 0x00020000)
768 else if (iptr[0].val.l == 0x00040000)
770 else if (iptr[0].val.l == 0x00080000)
772 else if (iptr[0].val.l == 0x00100000)
774 else if (iptr[0].val.l == 0x00200000)
776 else if (iptr[0].val.l == 0x00400000)
778 else if (iptr[0].val.l == 0x00800000)
780 else if (iptr[0].val.l == 0x01000000)
782 else if (iptr[0].val.l == 0x02000000)
784 else if (iptr[0].val.l == 0x04000000)
786 else if (iptr[0].val.l == 0x08000000)
788 else if (iptr[0].val.l == 0x10000000)
790 else if (iptr[0].val.l == 0x20000000)
792 else if (iptr[0].val.l == 0x40000000)
794 else if (iptr[0].val.l == 0x80000000)
800 iptr[0].opc = ICMD_LDIVPOW2;
801 goto icmd_lconst_tail;
803 if ((iptr[0].val.l == 0x00000002) ||
804 (iptr[0].val.l == 0x00000004) ||
805 (iptr[0].val.l == 0x00000008) ||
806 (iptr[0].val.l == 0x00000010) ||
807 (iptr[0].val.l == 0x00000020) ||
808 (iptr[0].val.l == 0x00000040) ||
809 (iptr[0].val.l == 0x00000080) ||
810 (iptr[0].val.l == 0x00000100) ||
811 (iptr[0].val.l == 0x00000200) ||
812 (iptr[0].val.l == 0x00000400) ||
813 (iptr[0].val.l == 0x00000800) ||
814 (iptr[0].val.l == 0x00001000) ||
815 (iptr[0].val.l == 0x00002000) ||
816 (iptr[0].val.l == 0x00004000) ||
817 (iptr[0].val.l == 0x00008000) ||
818 (iptr[0].val.l == 0x00010000) ||
819 (iptr[0].val.l == 0x00020000) ||
820 (iptr[0].val.l == 0x00040000) ||
821 (iptr[0].val.l == 0x00080000) ||
822 (iptr[0].val.l == 0x00100000) ||
823 (iptr[0].val.l == 0x00200000) ||
824 (iptr[0].val.l == 0x00400000) ||
825 (iptr[0].val.l == 0x00800000) ||
826 (iptr[0].val.l == 0x01000000) ||
827 (iptr[0].val.l == 0x02000000) ||
828 (iptr[0].val.l == 0x04000000) ||
829 (iptr[0].val.l == 0x08000000) ||
830 (iptr[0].val.l == 0x10000000) ||
831 (iptr[0].val.l == 0x20000000) ||
832 (iptr[0].val.l == 0x40000000) ||
833 (iptr[0].val.l == 0x80000000)) {
834 iptr[0].opc = ICMD_LREMPOW2;
836 goto icmd_lconst_tail;
840 #endif /* SUPPORT_LONG_DIV */
841 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
844 iptr[0].opc = ICMD_LANDCONST;
845 goto icmd_lconst_tail;
847 iptr[0].opc = ICMD_LORCONST;
848 goto icmd_lconst_tail;
850 iptr[0].opc = ICMD_LXORCONST;
851 goto icmd_lconst_tail;
852 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
853 #if !defined(NOLONG_CONDITIONAL)
855 if ((len > 1) && (iptr[2].val.i == 0)) {
856 switch (iptr[2].opc) {
858 iptr[0].opc = ICMD_IF_LEQ;
859 icmd_lconst_lcmp_tail:
860 iptr[0].op1 = iptr[2].op1;
863 /* iptr[1].opc = ICMD_NOP;
864 iptr[2].opc = ICMD_NOP; */
866 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
868 iptr[0].target = (void *) tbptr;
870 MARKREACHED(tbptr, copy);
871 COUNT(count_pcmd_bra);
872 COUNT(count_pcmd_op);
875 iptr[0].opc = ICMD_IF_LNE;
876 goto icmd_lconst_lcmp_tail;
878 iptr[0].opc = ICMD_IF_LLT;
879 goto icmd_lconst_lcmp_tail;
881 iptr[0].opc = ICMD_IF_LGT;
882 goto icmd_lconst_lcmp_tail;
884 iptr[0].opc = ICMD_IF_LLE;
885 goto icmd_lconst_lcmp_tail;
887 iptr[0].opc = ICMD_IF_LGE;
888 goto icmd_lconst_lcmp_tail;
891 } /* switch (iptr[2].opc) */
892 } /* if (iptr[2].val.i == 0) */
896 #endif /* !defined(NOLONG_CONDITIONAL) */
898 #if SUPPORT_CONST_STORE
900 #if SUPPORT_CONST_STORE_ZERO_ONLY
901 if (iptr[0].val.l == 0) {
902 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
903 iptr[0].opc = ICMD_LASTORECONST;
904 iptr[1].opc = ICMD_NOP;
905 OPTT2_0(TYPE_INT, TYPE_ADR);
906 COUNT(count_pcmd_op);
907 #if SUPPORT_CONST_STORE_ZERO_ONLY
910 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
915 #if SUPPORT_CONST_STORE_ZERO_ONLY
916 if (iptr[0].val.l == 0) {
917 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
918 switch (iptr[1].opc) {
920 iptr[0].opc = ICMD_PUTSTATICCONST;
924 iptr[0].opc = ICMD_PUTFIELDCONST;
929 iptr[1].opc = ICMD_NOP;
930 iptr[0].op1 = TYPE_LNG;
931 COUNT(count_pcmd_op);
932 #if SUPPORT_CONST_STORE_ZERO_ONLY
935 #endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
937 #endif /* SUPPORT_CONST_STORE */
947 COUNT(count_pcmd_load);
952 COUNT(count_pcmd_load);
957 COUNT(count_pcmd_load);
958 #if SUPPORT_CONST_STORE
959 if (len > 0 && iptr->val.a == 0) {
960 switch (iptr[1].opc) {
962 if (iptr[1].val.fp != BUILTIN_aastore) {
969 switch (iptr[1].opc) {
971 iptr[0].opc = ICMD_AASTORECONST;
972 OPTT2_0(TYPE_INT, TYPE_ADR);
975 iptr[0].opc = ICMD_PUTSTATICCONST;
976 iptr[0].op1 = TYPE_ADR;
980 iptr[0].opc = ICMD_PUTFIELDCONST;
981 iptr[0].op1 = TYPE_ADR;
986 iptr[1].opc = ICMD_NOP;
987 COUNT(count_pcmd_op);
994 #endif /* SUPPORT_CONST_STORE */
998 /* pop 0 push 1 load */
1005 COUNT(count_load_instruction);
1006 i = opcode-ICMD_ILOAD;
1007 iptr->op1 = argren[iptr->op1];
1008 rd->locals[iptr->op1][i].type = i;
1009 LOAD(i, LOCALVAR, iptr->op1);
1019 COUNT(count_check_null);
1020 COUNT(count_check_bound);
1021 COUNT(count_pcmd_mem);
1022 OP2IAT_1(opcode-ICMD_IALOAD);
1028 COUNT(count_check_null);
1029 COUNT(count_check_bound);
1030 COUNT(count_pcmd_mem);
1034 /* pop 0 push 0 iinc */
1037 #if defined(STATISTICS)
1041 count_store_depth[10]++;
1043 count_store_depth[i]++;
1049 if ((copy->varkind == LOCALVAR) &&
1050 (copy->varnum == iptr->op1)) {
1051 copy->varkind = TEMPVAR;
1060 /* pop 1 push 0 store */
1070 i = opcode - ICMD_ISTORE;
1071 rd->locals[iptr->op1][i].type = i;
1072 #if defined(STATISTICS)
1077 count_store_length[20]++;
1079 count_store_length[i]++;
1082 count_store_depth[10]++;
1084 count_store_depth[i]++;
1087 copy = curstack->prev;
1090 if ((copy->varkind == LOCALVAR) &&
1091 (copy->varnum == iptr->op1)) {
1092 copy->varkind = TEMPVAR;
1098 if ((new - curstack) == 1) {
1099 curstack->varkind = LOCALVAR;
1100 curstack->varnum = iptr->op1;
1102 STORE(opcode-ICMD_ISTORE);
1112 COUNT(count_check_null);
1113 COUNT(count_check_bound);
1114 COUNT(count_pcmd_mem);
1115 OP3TIA_0(opcode-ICMD_IASTORE);
1121 COUNT(count_check_null);
1122 COUNT(count_check_bound);
1123 COUNT(count_pcmd_mem);
1130 #ifdef TYPECHECK_STACK_COMPCAT
1133 if (IS_2_WORD_TYPE(curstack->type)) {
1134 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1147 COUNT(count_pcmd_return);
1148 OP1_0(opcode-ICMD_IRETURN);
1149 superblockend = true;
1153 COUNT(count_check_null);
1157 superblockend = true;
1160 case ICMD_PUTSTATIC:
1161 COUNT(count_pcmd_mem);
1165 /* pop 1 push 0 branch */
1168 case ICMD_IFNONNULL:
1169 COUNT(count_pcmd_bra);
1171 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1173 iptr[0].target = (void *) tbptr;
1175 MARKREACHED(tbptr, copy);
1187 COUNT(count_pcmd_bra);
1188 #if CONDITIONAL_LOADCONST
1189 tbptr = m->basicblocks + b_index;
1190 if ((b_count >= 3) &&
1191 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1192 (tbptr[1].pre_count == 1) &&
1193 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1194 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1195 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1196 (tbptr[2].pre_count == 1) &&
1197 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1198 (tbptr[2].icount==1)) {
1199 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1200 OP1_1(TYPE_INT, TYPE_INT);
1201 switch (iptr[0].opc) {
1203 iptr[0].opc = ICMD_IFNE_ICONST;
1206 iptr[0].opc = ICMD_IFEQ_ICONST;
1209 iptr[0].opc = ICMD_IFGE_ICONST;
1212 iptr[0].opc = ICMD_IFLT_ICONST;
1215 iptr[0].opc = ICMD_IFLE_ICONST;
1218 iptr[0].opc = ICMD_IFGT_ICONST;
1222 iptr[0].val.i = iptr[1].val.i;
1223 iptr[1].opc = ICMD_ELSE_ICONST;
1224 iptr[1].val.i = iptr[3].val.i;
1225 iptr[2].opc = ICMD_NOP;
1226 iptr[3].opc = ICMD_NOP;
1228 /* HACK: save compare value in iptr[1].op1 */
1229 iptr[1].op1 = iptr[0].val.i;
1230 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1231 iptr[1].opc = ICMD_ELSE_ICONST;
1232 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1233 tbptr[1].iinstr[0].opc = ICMD_NOP;
1234 tbptr[1].iinstr[1].opc = ICMD_NOP;
1235 tbptr[2].iinstr[0].opc = ICMD_NOP;
1237 tbptr[1].flags = BBDELETED;
1238 tbptr[2].flags = BBDELETED;
1239 tbptr[1].icount = 0;
1240 tbptr[2].icount = 0;
1241 if (tbptr[3].pre_count == 2) {
1242 len += tbptr[3].icount + 3;
1243 bptr->icount += tbptr[3].icount + 3;
1244 tbptr[3].flags = BBDELETED;
1245 tbptr[3].icount = 0;
1255 #endif /* CONDITIONAL_LOADCONST */
1258 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1260 iptr[0].target = (void *) tbptr;
1262 MARKREACHED(tbptr, copy);
1265 /* pop 0 push 0 branch */
1268 COUNT(count_pcmd_bra);
1269 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1271 iptr[0].target = (void *) tbptr;
1273 MARKREACHED(tbptr, copy);
1275 superblockend = true;
1278 /* pop 1 push 0 table branch */
1280 case ICMD_TABLESWITCH:
1281 COUNT(count_pcmd_table);
1283 s4ptr = iptr->val.a;
1284 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1285 MARKREACHED(tbptr, copy);
1286 i = *s4ptr++; /* low */
1287 i = *s4ptr++ - i + 1; /* high */
1289 tptr = DMNEW(void*, i+1);
1290 iptr->target = (void *) tptr;
1292 tptr[0] = (void *) tbptr;
1296 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1298 tptr[0] = (void *) tbptr;
1301 MARKREACHED(tbptr, copy);
1304 superblockend = true;
1307 /* pop 1 push 0 table branch */
1309 case ICMD_LOOKUPSWITCH:
1310 COUNT(count_pcmd_table);
1312 s4ptr = iptr->val.a;
1313 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1314 MARKREACHED(tbptr, copy);
1315 i = *s4ptr++; /* count */
1317 tptr = DMNEW(void*, i+1);
1318 iptr->target = (void *) tptr;
1320 tptr[0] = (void *) tbptr;
1324 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1326 tptr[0] = (void *) tbptr;
1329 MARKREACHED(tbptr, copy);
1333 superblockend = true;
1336 case ICMD_MONITORENTER:
1337 COUNT(count_check_null);
1338 case ICMD_MONITOREXIT:
1342 /* pop 2 push 0 branch */
1344 case ICMD_IF_ICMPEQ:
1345 case ICMD_IF_ICMPNE:
1346 case ICMD_IF_ICMPLT:
1347 case ICMD_IF_ICMPGE:
1348 case ICMD_IF_ICMPGT:
1349 case ICMD_IF_ICMPLE:
1350 COUNT(count_pcmd_bra);
1352 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1354 iptr[0].target = (void *) tbptr;
1356 MARKREACHED(tbptr, copy);
1359 case ICMD_IF_ACMPEQ:
1360 case ICMD_IF_ACMPNE:
1361 COUNT(count_pcmd_bra);
1363 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1365 iptr[0].target = (void *) tbptr;
1367 MARKREACHED(tbptr, copy);
1373 COUNT(count_check_null);
1374 COUNT(count_pcmd_mem);
1375 OPTT2_0(iptr->op1,TYPE_ADR);
1380 if (!IS_2_WORD_TYPE(curstack->type)) {
1382 #ifdef TYPECHECK_STACK_COMPCAT
1385 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1386 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1391 OP1_0ANY; /* second pop */
1394 iptr->opc = ICMD_POP;
1398 /* pop 0 push 1 dup */
1401 #ifdef TYPECHECK_STACK_COMPCAT
1404 if (IS_2_WORD_TYPE(curstack->type)) {
1405 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1410 COUNT(count_dup_instruction);
1416 if (IS_2_WORD_TYPE(curstack->type)) {
1418 iptr->opc = ICMD_DUP;
1423 /* ..., ????, cat1 */
1424 #ifdef TYPECHECK_STACK_COMPCAT
1426 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1427 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1433 NEWSTACK(copy->prev->type, copy->prev->varkind,
1434 copy->prev->varnum);
1435 NEWSTACK(copy->type, copy->varkind,
1442 /* pop 2 push 3 dup */
1445 #ifdef TYPECHECK_STACK_COMPCAT
1448 if (IS_2_WORD_TYPE(curstack->type) ||
1449 IS_2_WORD_TYPE(curstack->prev->type)) {
1450 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1460 if (IS_2_WORD_TYPE(curstack->type)) {
1461 /* ..., ????, cat2 */
1462 #ifdef TYPECHECK_STACK_COMPCAT
1464 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1465 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1470 iptr->opc = ICMD_DUP_X1;
1474 /* ..., ????, cat1 */
1475 #ifdef TYPECHECK_STACK_COMPCAT
1478 if (IS_2_WORD_TYPE(curstack->prev->type)
1479 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1480 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1489 /* pop 3 push 4 dup */
1493 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1494 /* ..., cat2, ???? */
1495 #ifdef TYPECHECK_STACK_COMPCAT
1497 if (IS_2_WORD_TYPE(curstack->type)) {
1498 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1503 iptr->opc = ICMD_DUP_X1;
1507 /* ..., cat1, ???? */
1508 #ifdef TYPECHECK_STACK_COMPCAT
1511 if (IS_2_WORD_TYPE(curstack->type)
1512 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1513 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1524 if (IS_2_WORD_TYPE(curstack->type)) {
1525 /* ..., ????, cat2 */
1526 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1527 /* ..., cat2, cat2 */
1528 iptr->opc = ICMD_DUP_X1;
1532 /* ..., cat1, cat2 */
1533 #ifdef TYPECHECK_STACK_COMPCAT
1536 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1537 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1542 iptr->opc = ICMD_DUP_X2;
1548 /* ..., ????, ????, cat1 */
1549 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1550 /* ..., cat2, ????, cat1 */
1551 #ifdef TYPECHECK_STACK_COMPCAT
1553 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1554 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1559 iptr->opc = ICMD_DUP2_X1;
1563 /* ..., cat1, ????, cat1 */
1564 #ifdef TYPECHECK_STACK_COMPCAT
1567 if (IS_2_WORD_TYPE(curstack->prev->type)
1568 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1569 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1579 /* pop 2 push 2 swap */
1582 #ifdef TYPECHECK_STACK_COMPCAT
1585 if (IS_2_WORD_TYPE(curstack->type)
1586 || IS_2_WORD_TYPE(curstack->prev->type)) {
1587 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1598 #if !SUPPORT_DIVISION
1599 iptr[0].opc = ICMD_BUILTIN2;
1600 iptr[0].op1 = TYPE_INT;
1601 iptr[0].val.fp = BUILTIN_idiv;
1602 m->isleafmethod = false;
1607 #if !SUPPORT_DIVISION
1608 /*log_text("ICMD_IREM: !SUPPORT_DIVISION");*/
1609 iptr[0].opc = ICMD_BUILTIN2;
1610 iptr[0].op1 = TYPE_INT;
1611 iptr[0].val.fp = BUILTIN_irem;
1612 m->isleafmethod = false;
1615 /*log_text("ICMD_IREM: SUPPORT_DIVISION");*/
1626 COUNT(count_pcmd_op);
1631 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1632 iptr[0].opc = ICMD_BUILTIN2;
1633 iptr[0].op1 = TYPE_LNG;
1634 iptr[0].val.fp = BUILTIN_ldiv;
1635 m->isleafmethod = false;
1640 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1641 iptr[0].opc = ICMD_BUILTIN2;
1642 iptr[0].op1 = TYPE_LNG;
1643 iptr[0].val.fp = BUILTIN_lrem;
1644 m->isleafmethod = false;
1651 #if SUPPORT_LONG_LOGICAL
1655 #endif /* SUPPORT_LONG_LOGICAL */
1656 COUNT(count_pcmd_op);
1663 COUNT(count_pcmd_op);
1672 COUNT(count_pcmd_op);
1681 COUNT(count_pcmd_op);
1686 COUNT(count_pcmd_op);
1687 #if !defined(NOLONG_CONDITIONAL)
1688 if ((len > 0) && (iptr[1].val.i == 0)) {
1689 switch (iptr[1].opc) {
1691 iptr[0].opc = ICMD_IF_LCMPEQ;
1693 iptr[0].op1 = iptr[1].op1;
1696 /* iptr[1].opc = ICMD_NOP; */
1698 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1700 iptr[0].target = (void *) tbptr;
1702 MARKREACHED(tbptr, copy);
1703 COUNT(count_pcmd_bra);
1706 iptr[0].opc = ICMD_IF_LCMPNE;
1707 goto icmd_lcmp_if_tail;
1709 iptr[0].opc = ICMD_IF_LCMPLT;
1710 goto icmd_lcmp_if_tail;
1712 iptr[0].opc = ICMD_IF_LCMPGT;
1713 goto icmd_lcmp_if_tail;
1715 iptr[0].opc = ICMD_IF_LCMPLE;
1716 goto icmd_lcmp_if_tail;
1718 iptr[0].opc = ICMD_IF_LCMPGE;
1719 goto icmd_lcmp_if_tail;
1721 OPTT2_1(TYPE_LNG, TYPE_INT);
1726 OPTT2_1(TYPE_LNG, TYPE_INT);
1730 COUNT(count_pcmd_op);
1731 OPTT2_1(TYPE_FLT, TYPE_INT);
1735 COUNT(count_pcmd_op);
1736 OPTT2_1(TYPE_DBL, TYPE_INT);
1744 case ICMD_INT2SHORT:
1745 COUNT(count_pcmd_op);
1746 OP1_1(TYPE_INT, TYPE_INT);
1749 COUNT(count_pcmd_op);
1750 OP1_1(TYPE_LNG, TYPE_LNG);
1753 COUNT(count_pcmd_op);
1754 OP1_1(TYPE_FLT, TYPE_FLT);
1757 COUNT(count_pcmd_op);
1758 OP1_1(TYPE_DBL, TYPE_DBL);
1762 COUNT(count_pcmd_op);
1763 OP1_1(TYPE_INT, TYPE_LNG);
1766 COUNT(count_pcmd_op);
1767 OP1_1(TYPE_INT, TYPE_FLT);
1770 COUNT(count_pcmd_op);
1771 OP1_1(TYPE_INT, TYPE_DBL);
1774 COUNT(count_pcmd_op);
1775 OP1_1(TYPE_LNG, TYPE_INT);
1778 COUNT(count_pcmd_op);
1779 OP1_1(TYPE_LNG, TYPE_FLT);
1782 COUNT(count_pcmd_op);
1783 OP1_1(TYPE_LNG, TYPE_DBL);
1786 COUNT(count_pcmd_op);
1787 OP1_1(TYPE_FLT, TYPE_INT);
1790 COUNT(count_pcmd_op);
1791 OP1_1(TYPE_FLT, TYPE_LNG);
1794 COUNT(count_pcmd_op);
1795 OP1_1(TYPE_FLT, TYPE_DBL);
1798 COUNT(count_pcmd_op);
1799 OP1_1(TYPE_DBL, TYPE_INT);
1802 COUNT(count_pcmd_op);
1803 OP1_1(TYPE_DBL, TYPE_LNG);
1806 COUNT(count_pcmd_op);
1807 OP1_1(TYPE_DBL, TYPE_FLT);
1810 case ICMD_CHECKCAST:
1811 OP1_1(TYPE_ADR, TYPE_ADR);
1814 case ICMD_INSTANCEOF:
1815 case ICMD_ARRAYLENGTH:
1816 OP1_1(TYPE_ADR, TYPE_INT);
1820 case ICMD_ANEWARRAY:
1821 OP1_1(TYPE_INT, TYPE_ADR);
1825 COUNT(count_check_null);
1826 COUNT(count_pcmd_mem);
1827 OP1_1(TYPE_ADR, iptr->op1);
1832 case ICMD_GETSTATIC:
1833 COUNT(count_pcmd_mem);
1843 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1845 iptr[0].target = (void *) tbptr;
1847 /* This is a dirty hack. The typechecker
1848 * needs it because the OP1_0ANY below
1849 * overwrites iptr->dst.
1851 iptr->val.a = (void *) iptr->dst;
1853 tbptr->type = BBTYPE_SBR;
1855 /* We need to check for overflow right here because
1856 * the pushed value is poped after MARKREACHED. */
1858 MARKREACHED(tbptr, copy);
1862 /* pop many push any */
1865 call_returntype = iptr->op1;
1868 #if defined(USEBUILTINTABLE) || !SUPPORT_DIVISION
1869 /* Just prevent a compiler warning... */
1873 call_returntype = iptr->op1;
1876 #if defined(USEBUILTINTABLE)
1877 /* Just prevent a compiler warning... */
1881 call_returntype = iptr->op1;
1884 case ICMD_INVOKEVIRTUAL:
1885 case ICMD_INVOKESPECIAL:
1886 case ICMD_INVOKEINTERFACE:
1887 case ICMD_INVOKESTATIC:
1888 COUNT(count_pcmd_met);
1890 #if defined(__X86_64__) || defined(__I386__) || defined(__ALPHA__)
1891 unresolved_method *um = iptr->target;
1892 /* if (lm->flags & ACC_STATIC) */
1893 /* {COUNT(count_check_null);} */
1894 call_argcount = iptr->op1;
1895 call_returntype = um->methodref->parseddesc.md->returntype.type;
1897 methodinfo *lm = iptr->val.a;
1898 if (lm->flags & ACC_STATIC)
1899 {COUNT(count_check_null);}
1900 call_argcount = iptr->op1;
1901 call_returntype = lm->returntype;
1907 if (i > rd->arguments_num)
1908 rd->arguments_num = i;
1911 /* Macro in codegen.h */
1915 copy->flags |= SAVEDVAR;
1921 if (call_returntype != TYPE_VOID)
1922 OP0_1(call_returntype);
1926 case ICMD_INLINE_START:
1927 case ICMD_INLINE_END:
1931 case ICMD_MULTIANEWARRAY:
1932 if (rd->argintreguse < 3)
1933 rd->argintreguse = 3;
1938 #ifdef SPECIALMEMUSE
1939 if (rd->ifmemuse < (i + rd->intreg_argnum + 6))
1940 rd->ifmemuse = i + rd->intreg_argnum + 6;
1942 # if defined(__I386__)
1943 if (rd->ifmemuse < i + 3)
1944 rd->ifmemuse = i + 3; /* n integer args spilled on stack */
1946 if (rd->ifmemuse < i)
1947 rd->ifmemuse = i; /* n integer args spilled on stack */
1948 # endif /* defined(__I386__) */
1950 if ((i + INT_ARG_CNT) > rd->arguments_num)
1951 rd->arguments_num = i + INT_ARG_CNT;
1954 /* check INT type here? Currently typecheck does this. */
1955 if (!(copy->flags & SAVEDVAR)) {
1956 copy->varkind = ARGVAR;
1957 copy->varnum = i + INT_ARG_CNT;
1958 copy->flags|=INMEMORY;
1959 #if defined(SPECIALMEMUSE)
1960 copy->regoff = i + rd->intreg_argnum + 6;
1962 # if defined(__I386__)
1963 copy->regoff = i + 3;
1966 # endif /* defined(__I386__) */
1967 #endif /* defined(SPECIALMEMUSE) */
1972 copy->flags |= SAVEDVAR;
1980 case ICMD_CLEAR_ARGREN:
1981 for (i = iptr->op1; i < cd->maxlocals; i++)
1983 iptr->opc = opcode = ICMD_NOP;
1987 case ICMD_READONLY_ARG:
1988 case ICMD_READONLY_ARG+1:
1989 case ICMD_READONLY_ARG+2:
1990 case ICMD_READONLY_ARG+3:
1991 case ICMD_READONLY_ARG+4:
1994 if (curstack->varkind == LOCALVAR) {
1995 i = curstack->varnum;
1996 argren[iptr->op1] = i;
1999 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2006 new_exception_message(string_java_lang_InternalError,
2013 } /* while instructions */
2015 bptr->outstack = curstack;
2016 bptr->outdepth = stackdepth;
2020 superblockend = true;
2022 } /* while blocks */
2023 } while (repeat && !deadcode);
2025 #if defined(STATISTICS)
2027 if (m->basicblockcount > count_max_basic_blocks)
2028 count_max_basic_blocks = m->basicblockcount;
2029 count_basic_blocks += m->basicblockcount;
2030 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2031 count_javainstr += m->instructioncount;
2032 if (m->stackcount > count_upper_bound_new_stack)
2033 count_upper_bound_new_stack = m->stackcount;
2034 if ((new - m->stack) > count_max_new_stack)
2035 count_max_new_stack = (new - m->stack);
2037 b_count = m->basicblockcount;
2038 bptr = m->basicblocks;
2039 while (--b_count >= 0) {
2040 if (bptr->flags > BBREACHED) {
2041 if (bptr->indepth >= 10)
2042 count_block_stack[10]++;
2044 count_block_stack[bptr->indepth]++;
2047 count_block_size_distribution[len]++;
2049 count_block_size_distribution[10]++;
2051 count_block_size_distribution[11]++;
2053 count_block_size_distribution[12]++;
2055 count_block_size_distribution[13]++;
2057 count_block_size_distribution[14]++;
2059 count_block_size_distribution[15]++;
2061 count_block_size_distribution[16]++;
2063 count_block_size_distribution[17]++;
2069 count_analyse_iterations[0]++;
2070 else if (loops == 2)
2071 count_analyse_iterations[1]++;
2072 else if (loops == 3)
2073 count_analyse_iterations[2]++;
2074 else if (loops == 4)
2075 count_analyse_iterations[3]++;
2077 count_analyse_iterations[4]++;
2079 if (m->basicblockcount <= 5)
2080 count_method_bb_distribution[0]++;
2081 else if (m->basicblockcount <= 10)
2082 count_method_bb_distribution[1]++;
2083 else if (m->basicblockcount <= 15)
2084 count_method_bb_distribution[2]++;
2085 else if (m->basicblockcount <= 20)
2086 count_method_bb_distribution[3]++;
2087 else if (m->basicblockcount <= 30)
2088 count_method_bb_distribution[4]++;
2089 else if (m->basicblockcount <= 40)
2090 count_method_bb_distribution[5]++;
2091 else if (m->basicblockcount <= 50)
2092 count_method_bb_distribution[6]++;
2093 else if (m->basicblockcount <= 75)
2094 count_method_bb_distribution[7]++;
2096 count_method_bb_distribution[8]++;
2100 /* just return methodinfo* to signal everything was ok */
2106 /**********************************************************************/
2107 /* DEBUGGING HELPERS */
2108 /**********************************************************************/
2110 void icmd_print_stack(codegendata *cd, stackptr s)
2122 j = cd->maxstack - i;
2127 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2128 if (s->flags & SAVEDVAR)
2129 switch (s->varkind) {
2131 if (s->flags & INMEMORY)
2132 printf(" M%02d", s->regoff);
2133 #ifdef HAS_ADDRESS_REGISTER_FILE
2134 else if (s->type == TYPE_ADR)
2135 printf(" R%02d", s->regoff);
2137 else if (IS_FLT_DBL_TYPE(s->type))
2138 printf(" F%02d", s->regoff);
2140 printf(" %3s", regs[s->regoff]);
2144 printf(" I%02d", s->varnum);
2147 printf(" L%02d", s->varnum);
2150 printf(" A%02d", s->varnum);
2151 #ifdef INVOKE_NEW_DEBUG
2152 if (s->flags & INMEMORY)
2153 printf("(M%i)", s->regoff);
2155 printf("(R%i)", s->regoff);
2159 printf(" !%02d", j);
2162 switch (s->varkind) {
2164 if (s->flags & INMEMORY)
2165 printf(" m%02d", s->regoff);
2166 #ifdef HAS_ADDRESS_REGISTER_FILE
2167 else if (s->type == TYPE_ADR)
2168 printf(" r%02d", s->regoff);
2170 else if (IS_FLT_DBL_TYPE(s->type))
2171 printf(" f%02d", s->regoff);
2173 printf(" %3s", regs[s->regoff]);
2177 printf(" i%02d", s->varnum);
2180 printf(" l%02d", s->varnum);
2183 printf(" a%02d", s->varnum);
2184 #ifdef INVOKE_NEW_DEBUG
2185 if (s->flags & INMEMORY)
2186 printf("(M%i)", s->regoff);
2188 printf("(R%i)", s->regoff);
2192 printf(" ?%02d", j);
2200 static void print_reg(stackptr s) {
2202 if (s->flags & SAVEDVAR)
2203 switch (s->varkind) {
2205 if (s->flags & INMEMORY)
2206 printf(" tm%02d", s->regoff);
2208 printf(" tr%02d", s->regoff);
2211 printf(" s %02d", s->varnum);
2214 printf(" l %02d", s->varnum);
2217 printf(" a %02d", s->varnum);
2220 printf(" ! %02d", s->varnum);
2223 switch (s->varkind) {
2225 if (s->flags & INMEMORY)
2226 printf(" Tm%02d", s->regoff);
2228 printf(" Tr%02d", s->regoff);
2231 printf(" S %02d", s->varnum);
2234 printf(" L %02d", s->varnum);
2237 printf(" A %02d", s->varnum);
2240 printf(" ? %02d", s->varnum);
2250 char *icmd_builtin_name(functionptr bptr)
2252 builtin_descriptor *bdesc = builtin_desc;
2253 while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
2255 return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
2259 static char *jit_type[] = {
2268 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2275 utf_fprint_classname(stdout, m->class->name);
2277 utf_fprint(stdout, m->name);
2278 utf_fprint_classname(stdout, m->descriptor);
2279 printf("\n\nMax locals: %d\n", (int) cd->maxlocals);
2280 printf("Max stack: %d\n", (int) cd->maxstack);
2282 printf("Line number table length: %d\n", m->linenumbercount);
2284 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2285 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2286 printf(" L%03d ... ", ex->start->debug_nr );
2287 printf("L%03d = ", ex->end->debug_nr);
2288 printf("L%03d\n", ex->handler->debug_nr);
2291 printf("Local Table:\n");
2292 for (i = 0; i < cd->maxlocals; i++) {
2293 printf(" %3d: ", i);
2294 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2295 if (rd->locals[i][j].type >= 0) {
2296 printf(" (%s) ", jit_type[j]);
2297 if (rd->locals[i][j].flags & INMEMORY)
2298 printf("m%2d", rd->locals[i][j].regoff);
2299 #ifdef HAS_ADDRESS_REGISTER_FILE
2300 else if (j == TYPE_ADR)
2301 printf("r%02d", rd->locals[i][j].regoff);
2303 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2304 printf("f%02d", rd->locals[i][j].regoff);
2306 printf("%3s", regs[rd->locals[i][j].regoff]);
2315 printf("Interface Table:\n");
2316 for (i = 0; i < cd->maxstack; i++) {
2317 if ((rd->interfaces[i][0].type >= 0) ||
2318 (rd->interfaces[i][1].type >= 0) ||
2319 (rd->interfaces[i][2].type >= 0) ||
2320 (rd->interfaces[i][3].type >= 0) ||
2321 (rd->interfaces[i][4].type >= 0)) {
2322 printf(" %3d: ", i);
2323 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2324 if (rd->interfaces[i][j].type >= 0) {
2325 printf(" (%s) ", jit_type[j]);
2326 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2327 if (rd->interfaces[i][j].flags & INMEMORY)
2328 printf("M%2d", rd->interfaces[i][j].regoff);
2329 #ifdef HAS_ADDRESS_REGISTER_FILE
2330 else if (j == TYPE_ADR)
2331 printf("R%02d", rd->interfaces[i][j].regoff);
2333 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2334 printf("F%02d", rd->interfaces[i][j].regoff);
2336 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2340 if (rd->interfaces[i][j].flags & INMEMORY)
2341 printf("m%2d", rd->interfaces[i][j].regoff);
2342 #ifdef HAS_ADDRESS_REGISTER_FILE
2343 else if (j == TYPE_ADR)
2344 printf("r%02d", rd->interfaces[i][j].regoff);
2346 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2347 printf("f%02d", rd->interfaces[i][j].regoff);
2349 printf("%3s", regs[rd->interfaces[i][j].regoff]);
2360 if (showdisassemble) {
2361 #if defined(__I386__) || defined(__X86_64__)
2365 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2366 for (i = 0; i < m->basicblocks[0].mpc;) {
2367 a = disassinstr(u1ptr);
2372 #elif defined(__XDSPCORE__)
2376 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2377 for (i = 0; i < m->basicblocks[0].mpc;) {
2378 a = disassinstr(stdout, s4ptr);
2387 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen);
2388 for (i = 0; i < m->basicblocks[0].mpc; i += 4, s4ptr++) {
2395 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2396 show_icmd_block(m, cd, bptr);
2401 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2407 if (bptr->flags != BBDELETED) {
2408 deadcode = bptr->flags <= BBREACHED;
2411 for (j = cd->maxstack; j > 0; j--)
2414 icmd_print_stack(cd, bptr->instack);
2415 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2416 iptr = bptr->iinstr;
2418 for (i = 0; i < bptr->icount; i++, iptr++) {
2421 for (j = cd->maxstack; j > 0; j--)
2425 icmd_print_stack(cd, iptr->dst);
2426 printf("] %4d ", i);
2429 if (icmd_uses_tmp[iptr->opc][0])
2433 if (icmd_uses_tmp[iptr->opc][1])
2437 if (icmd_uses_tmp[iptr->opc][2])
2443 show_icmd(iptr, deadcode);
2447 if (showdisassemble && (!deadcode)) {
2448 #if defined(__I386__) || defined(__X86_64__)
2454 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + i);
2456 if (bptr->next != NULL) {
2457 for (; i < bptr->next->mpc; ) {
2458 a = disassinstr(u1ptr);
2465 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength); ) {
2466 a = disassinstr(u1ptr);
2472 #elif defined(__XDSPCORE__)
2478 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2480 if (bptr->next != NULL) {
2481 for (; i < bptr->next->mpc;) {
2482 a = disassinstr(stdout, s4ptr);
2490 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); ) {
2491 a = disassinstr(stdout, s4ptr);
2502 s4ptr = (s4 *) ((ptrint) m->mcode + cd->dseglen + i);
2504 if (bptr->next != NULL) {
2505 for (; i < bptr->next->mpc; i += 4, s4ptr++)
2510 for (; s4ptr < (s4 *) ((ptrint) m->mcode + m->mcodelength); i += 4, s4ptr++)
2520 void show_icmd(instruction *iptr, bool deadcode)
2526 printf("%s", icmd_names[iptr->opc]);
2528 switch (iptr->opc) {
2529 case ICMD_IADDCONST:
2530 case ICMD_ISUBCONST:
2531 case ICMD_IMULCONST:
2535 case ICMD_IANDCONST:
2537 case ICMD_IXORCONST:
2538 case ICMD_ISHLCONST:
2539 case ICMD_ISHRCONST:
2540 case ICMD_IUSHRCONST:
2541 case ICMD_LSHLCONST:
2542 case ICMD_LSHRCONST:
2543 case ICMD_LUSHRCONST:
2545 case ICMD_ELSE_ICONST:
2546 case ICMD_IASTORECONST:
2547 case ICMD_BASTORECONST:
2548 case ICMD_CASTORECONST:
2549 case ICMD_SASTORECONST:
2550 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2553 case ICMD_IFEQ_ICONST:
2554 case ICMD_IFNE_ICONST:
2555 case ICMD_IFLT_ICONST:
2556 case ICMD_IFGE_ICONST:
2557 case ICMD_IFGT_ICONST:
2558 case ICMD_IFLE_ICONST:
2559 printf("(%d) %d", iptr[1].op1, iptr->val.i);
2562 case ICMD_LADDCONST:
2563 case ICMD_LSUBCONST:
2564 case ICMD_LMULCONST:
2568 case ICMD_LANDCONST:
2570 case ICMD_LXORCONST:
2572 case ICMD_LASTORECONST:
2573 #if defined(__I386__) || defined(__POWERPC__)
2574 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
2576 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
2581 printf(" %f", iptr->val.f);
2585 printf(" %f", iptr->val.d);
2589 case ICMD_AASTORECONST:
2590 printf(" %p", iptr->val.a);
2595 #if defined(__X86_64__) || defined(__I386__) || defined(__ALPHA__)
2597 printf(" %d, ", ((fieldinfo *) iptr->val.a)->offset);
2599 printf(" NOT RESOLVED, ");
2600 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2602 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2604 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2607 printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
2609 utf_display_classname(((fieldinfo *) iptr->val.a)->class->name);
2611 utf_display(((fieldinfo *) iptr->val.a)->name);
2613 utf_display(((fieldinfo *) iptr->val.a)->descriptor);
2618 case ICMD_PUTSTATIC:
2619 case ICMD_GETSTATIC:
2620 #if defined(__X86_64__) || defined(__I386__) || defined(__ALPHA__)
2622 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
2624 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
2626 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
2630 utf_display_classname(((fieldinfo *) iptr->val.a)->class->name);
2632 utf_display(((fieldinfo *) iptr->val.a)->name);
2634 utf_display(((fieldinfo *) iptr->val.a)->descriptor);
2639 case ICMD_PUTSTATICCONST:
2640 case ICMD_PUTFIELDCONST:
2641 switch (iptr[1].op1) {
2643 printf(" %d,", iptr->val.i);
2646 #if defined(__I386__) || defined(__POWERPC__)
2647 printf(" %lld,", iptr->val.l);
2649 printf(" %ld,", iptr->val.l);
2653 printf(" %p,", iptr->val.a);
2656 printf(" %g,", iptr->val.f);
2659 printf(" %g,", iptr->val.d);
2662 #if defined(__X86_64__)
2663 if (iptr->opc == ICMD_PUTFIELDCONST)
2664 printf(" NOT RESOLVED,");
2666 utf_display_classname(((unresolved_field *) iptr[1].target)->fieldref->classref->name);
2668 utf_display(((unresolved_field *) iptr[1].target)->fieldref->name);
2670 utf_display(((unresolved_field *) iptr[1].target)->fieldref->descriptor);
2673 if (iptr->opc == ICMD_PUTFIELDCONST)
2674 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
2676 utf_display_classname(((fieldinfo *) iptr[1].val.a)->class->name);
2678 utf_display(((fieldinfo *) iptr[1].val.a)->name);
2680 utf_display(((fieldinfo *) iptr[1].val.a)->descriptor);
2686 printf(" %d + %d", iptr->op1, iptr->val.i);
2721 printf(" %d", iptr->op1);
2726 utf_display_classname(((classinfo *) iptr->val.a)->name);
2730 switch (iptr->op1) {
2758 case ICMD_ANEWARRAY:
2761 utf_display_classname(((classinfo *) iptr->val.a)->name);
2765 case ICMD_MULTIANEWARRAY:
2768 printf(" %d ",iptr->op1);
2769 vft = (vftbl_t *)iptr->val.a;
2771 utf_display_classname(vft->class->name);
2777 case ICMD_CHECKCAST:
2778 case ICMD_INSTANCEOF:
2779 #if defined(__X86_64__) || defined(__I386__) || defined(__ALPHA__)
2781 classinfo *c = iptr->val.a;
2783 if (c->flags & ACC_INTERFACE)
2784 printf(" (INTERFACE) ");
2786 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2788 printf(" (NOT RESOLVED) ");
2790 utf_display_classname(((constant_classref *) iptr->target)->name);
2795 classinfo *c = iptr->val.a;
2796 if (c->flags & ACC_INTERFACE)
2797 printf(" (INTERFACE) ");
2799 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2800 utf_display_classname(c->name);
2804 case ICMD_INLINE_START:
2805 printf("\t\t\t%s.%s%s depth=%i",iptr->method->class->name->text,iptr->method->name->text,iptr->method->descriptor->text, iptr->op1);
2807 case ICMD_INLINE_END:
2813 printf(" %s", icmd_builtin_name((functionptr) iptr->val.fp));
2816 case ICMD_INVOKEVIRTUAL:
2817 case ICMD_INVOKESPECIAL:
2818 case ICMD_INVOKESTATIC:
2819 case ICMD_INVOKEINTERFACE:
2820 #if defined(__X86_64__) || defined(__I386__) || defined(__ALPHA__)
2822 printf(" (NOT RESOLVED) ");
2825 utf_display_classname(((unresolved_method *) iptr->target)->methodref->classref->name);
2827 utf_display(((unresolved_method *) iptr->target)->methodref->name);
2828 utf_display(((unresolved_method *) iptr->target)->methodref->descriptor);
2831 utf_display_classname(((methodinfo *) iptr->val.a)->class->name);
2833 utf_display(((methodinfo *) iptr->val.a)->name);
2834 utf_display(((methodinfo *) iptr->val.a)->descriptor);
2844 if (deadcode || !iptr->target)
2845 printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2847 printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2856 if (deadcode || !iptr->target)
2857 #if defined(__I386__) || defined(__POWERPC__)
2858 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2860 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
2863 #if defined(__I386__) || defined(__POWERPC__)
2864 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2866 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2873 case ICMD_IFNONNULL:
2874 case ICMD_IF_ICMPEQ:
2875 case ICMD_IF_ICMPNE:
2876 case ICMD_IF_ICMPLT:
2877 case ICMD_IF_ICMPGE:
2878 case ICMD_IF_ICMPGT:
2879 case ICMD_IF_ICMPLE:
2880 case ICMD_IF_LCMPEQ:
2881 case ICMD_IF_LCMPNE:
2882 case ICMD_IF_LCMPLT:
2883 case ICMD_IF_LCMPGE:
2884 case ICMD_IF_LCMPGT:
2885 case ICMD_IF_LCMPLE:
2886 case ICMD_IF_ACMPEQ:
2887 case ICMD_IF_ACMPNE:
2888 if (deadcode || !iptr->target)
2889 printf(" op1=%d", iptr->op1);
2891 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2894 case ICMD_TABLESWITCH:
2895 s4ptr = (s4*)iptr->val.a;
2897 if (deadcode || !iptr->target) {
2898 printf(" %d;", *s4ptr);
2901 tptr = (void **) iptr->target;
2902 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2906 s4ptr++; /* skip default */
2907 j = *s4ptr++; /* low */
2908 j = *s4ptr++ - j; /* high */
2910 if (deadcode || !*tptr)
2911 printf(" %d", *s4ptr++);
2913 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2920 case ICMD_LOOKUPSWITCH:
2921 s4ptr = (s4*)iptr->val.a;
2923 if (deadcode || !iptr->target) {
2924 printf(" %d;", *s4ptr);
2927 tptr = (void **) iptr->target;
2928 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2931 s4ptr++; /* default */
2932 j = *s4ptr++; /* count */
2935 if (deadcode || !*tptr) {
2936 s4ptr++; /* skip value */
2937 printf(" %d",*s4ptr++);
2940 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2946 printf(" Line number: %d, method:",iptr->line);
2948 utf_display(iptr->method->class->name);
2950 utf_display(iptr->method->name); */
2955 * These are local overrides for various environment variables in Emacs.
2956 * Please do not remove this and leave it at the end of the file, where
2957 * Emacs will automagically detect them.
2958 * ---------------------------------------------------------------------
2961 * indent-tabs-mode: t