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 4524 2006-02-16 19:39:36Z christian $
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/codegen-common.h"
59 #include "vm/jit/disass.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/stack.h"
63 #include "vm/jit/allocator/lsra.h"
66 /* global variables ***********************************************************/
68 #if defined(USE_THREADS)
69 static java_objectheader *lock_show_icmd;
73 /* stack_init ******************************************************************
75 Initialized the stack analysis subsystem (called by jit_init).
77 *******************************************************************************/
81 #if defined(USE_THREADS)
82 /* initialize the show lock */
84 lock_show_icmd = NEW(java_objectheader);
86 # if defined(NATIVE_THREADS)
87 initObjectLock(lock_show_icmd);
97 /**********************************************************************/
99 /**********************************************************************/
101 /* analyse_stack uses the intermediate code created by parse.c to
102 * build a model of the JVM operand stack for the current method.
104 * The following checks are performed:
105 * - check for operand stack underflow (before each instruction)
106 * - check for operand stack overflow (after[1] each instruction)
107 * - check for matching stack depth at merging points
108 * - check for matching basic types[2] at merging points
109 * - check basic types for instruction input (except for BUILTIN*
110 * opcodes, INVOKE* opcodes and MULTIANEWARRAY)
112 * [1]) Checking this after the instruction should be ok. parse.c
113 * counts the number of required stack slots in such a way that it is
114 * only vital that we don't exceed `maxstack` at basic block
117 * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
118 * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
119 * types are not discerned.
122 methodinfo *analyse_stack(methodinfo *m, codegendata *cd, registerdata *rd)
130 int opcode, i, j, len, loops;
131 int superblockend, repeat, deadcode;
138 s4 *last_store;/* instruction index of last XSTORE */
139 /* [ local_index * 5 + type ] */
140 s4 last_pei; /* instruction index of last possible exception */
141 /* used for conflict resolution for copy */
142 /* elimination (XLOAD, IINC, XSTORE) */
145 builtintable_entry *bte;
146 unresolved_method *um;
149 #if defined(ENABLE_LSRA)
153 argren = DMNEW(s4, cd->maxlocals); /* table for argument renaming */
154 for (i = 0; i < cd->maxlocals; i++)
157 last_store = DMNEW(s4 , cd->maxlocals * 5);
161 m->basicblocks[0].flags = BBREACHED;
162 m->basicblocks[0].instack = 0;
163 m->basicblocks[0].indepth = 0;
165 for (i = 0; i < cd->exceptiontablelength; i++) {
166 bptr = &m->basicblocks[m->basicblockindex[cd->exceptiontable[i].handlerpc]];
167 bptr->flags = BBREACHED;
168 bptr->type = BBTYPE_EXH;
171 bptr->pre_count = 10000;
176 #if CONDITIONAL_LOADCONST
177 b_count = m->basicblockcount;
178 bptr = m->basicblocks;
179 while (--b_count >= 0) {
180 if (bptr->icount != 0) {
181 iptr = bptr->iinstr + bptr->icount - 1;
214 m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
217 case ICMD_TABLESWITCH:
219 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
220 i = *s4ptr++; /* low */
221 i = *s4ptr++ - i + 1; /* high */
223 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
227 case ICMD_LOOKUPSWITCH:
229 m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
230 i = *s4ptr++; /* count */
232 m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
243 #endif /* CONDITIONAL_LOADCONST */
248 b_count = m->basicblockcount;
249 bptr = m->basicblocks;
250 superblockend = true;
255 while (--b_count >= 0) {
256 if (bptr->flags == BBDELETED) {
259 } else if (superblockend && (bptr->flags < BBREACHED)) {
262 } else if (bptr->flags <= BBREACHED) {
264 stackdepth = bptr->indepth;
266 } else if (bptr->flags < BBREACHED) {
268 bptr->instack = copy;
269 bptr->indepth = stackdepth;
271 } else if (bptr->indepth != stackdepth) {
272 /*show_icmd_method(m, cd, rd);
273 printf("Block: %d, required depth: %d, current depth: %d\n",
274 bptr->debug_nr, bptr->indepth, stackdepth);*/
275 *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
279 curstack = bptr->instack;
281 superblockend = false;
282 bptr->flags = BBFINISHED;
285 b_index = bptr - m->basicblocks;
289 for( i = 0; i < cd->maxlocals; i++)
290 for( j = 0; j < 5; j++)
291 last_store[5 * i + j] = -1;
298 #if defined(USEBUILTINTABLE)
299 # if defined(ENABLE_INTRP)
302 bte = builtintable_get_automatic(opcode);
304 if (bte && bte->opcode == opcode) {
305 iptr->opc = ICMD_BUILTIN;
306 iptr->op1 = false; /* don't check for exception */
308 m->isleafmethod = false;
311 # if defined(ENABLE_INTRP)
314 #endif /* defined(USEBUILTINTABLE) */
321 COUNT(count_check_null);
324 case ICMD_IFEQ_ICONST:
325 case ICMD_IFNE_ICONST:
326 case ICMD_IFLT_ICONST:
327 case ICMD_IFGE_ICONST:
328 case ICMD_IFGT_ICONST:
329 case ICMD_IFLE_ICONST:
330 case ICMD_ELSE_ICONST:
335 #if defined(ENABLE_INTRP)
338 rd->locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
340 COUNT(count_pcmd_return);
342 superblockend = true;
345 /* pop 0 push 1 const */
348 COUNT(count_pcmd_load);
350 switch (iptr[1].opc) {
352 iptr[0].opc = ICMD_IADDCONST;
354 iptr[1].opc = ICMD_NOP;
355 OP1_1(TYPE_INT, TYPE_INT);
356 COUNT(count_pcmd_op);
359 iptr[0].opc = ICMD_ISUBCONST;
360 goto icmd_iconst_tail;
361 #if SUPPORT_CONST_MUL
363 iptr[0].opc = ICMD_IMULCONST;
364 goto icmd_iconst_tail;
365 #else /* SUPPORT_CONST_MUL */
367 if (iptr[0].val.i == 0x00000002)
369 else if (iptr[0].val.i == 0x00000004)
371 else if (iptr[0].val.i == 0x00000008)
373 else if (iptr[0].val.i == 0x00000010)
375 else if (iptr[0].val.i == 0x00000020)
377 else if (iptr[0].val.i == 0x00000040)
379 else if (iptr[0].val.i == 0x00000080)
381 else if (iptr[0].val.i == 0x00000100)
383 else if (iptr[0].val.i == 0x00000200)
385 else if (iptr[0].val.i == 0x00000400)
387 else if (iptr[0].val.i == 0x00000800)
389 else if (iptr[0].val.i == 0x00001000)
391 else if (iptr[0].val.i == 0x00002000)
393 else if (iptr[0].val.i == 0x00004000)
395 else if (iptr[0].val.i == 0x00008000)
397 else if (iptr[0].val.i == 0x00010000)
399 else if (iptr[0].val.i == 0x00020000)
401 else if (iptr[0].val.i == 0x00040000)
403 else if (iptr[0].val.i == 0x00080000)
405 else if (iptr[0].val.i == 0x00100000)
407 else if (iptr[0].val.i == 0x00200000)
409 else if (iptr[0].val.i == 0x00400000)
411 else if (iptr[0].val.i == 0x00800000)
413 else if (iptr[0].val.i == 0x01000000)
415 else if (iptr[0].val.i == 0x02000000)
417 else if (iptr[0].val.i == 0x04000000)
419 else if (iptr[0].val.i == 0x08000000)
421 else if (iptr[0].val.i == 0x10000000)
423 else if (iptr[0].val.i == 0x20000000)
425 else if (iptr[0].val.i == 0x40000000)
427 else if (iptr[0].val.i == 0x80000000)
433 iptr[0].opc = ICMD_IMULPOW2;
434 goto icmd_iconst_tail;
435 #endif /* SUPPORT_CONST_MUL */
437 if (iptr[0].val.i == 0x00000002)
439 else if (iptr[0].val.i == 0x00000004)
441 else if (iptr[0].val.i == 0x00000008)
443 else if (iptr[0].val.i == 0x00000010)
445 else if (iptr[0].val.i == 0x00000020)
447 else if (iptr[0].val.i == 0x00000040)
449 else if (iptr[0].val.i == 0x00000080)
451 else if (iptr[0].val.i == 0x00000100)
453 else if (iptr[0].val.i == 0x00000200)
455 else if (iptr[0].val.i == 0x00000400)
457 else if (iptr[0].val.i == 0x00000800)
459 else if (iptr[0].val.i == 0x00001000)
461 else if (iptr[0].val.i == 0x00002000)
463 else if (iptr[0].val.i == 0x00004000)
465 else if (iptr[0].val.i == 0x00008000)
467 else if (iptr[0].val.i == 0x00010000)
469 else if (iptr[0].val.i == 0x00020000)
471 else if (iptr[0].val.i == 0x00040000)
473 else if (iptr[0].val.i == 0x00080000)
475 else if (iptr[0].val.i == 0x00100000)
477 else if (iptr[0].val.i == 0x00200000)
479 else if (iptr[0].val.i == 0x00400000)
481 else if (iptr[0].val.i == 0x00800000)
483 else if (iptr[0].val.i == 0x01000000)
485 else if (iptr[0].val.i == 0x02000000)
487 else if (iptr[0].val.i == 0x04000000)
489 else if (iptr[0].val.i == 0x08000000)
491 else if (iptr[0].val.i == 0x10000000)
493 else if (iptr[0].val.i == 0x20000000)
495 else if (iptr[0].val.i == 0x40000000)
497 else if (iptr[0].val.i == 0x80000000)
503 iptr[0].opc = ICMD_IDIVPOW2;
504 goto icmd_iconst_tail;
506 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
507 if ((iptr[0].val.i == 0x00000002) ||
508 (iptr[0].val.i == 0x00000004) ||
509 (iptr[0].val.i == 0x00000008) ||
510 (iptr[0].val.i == 0x00000010) ||
511 (iptr[0].val.i == 0x00000020) ||
512 (iptr[0].val.i == 0x00000040) ||
513 (iptr[0].val.i == 0x00000080) ||
514 (iptr[0].val.i == 0x00000100) ||
515 (iptr[0].val.i == 0x00000200) ||
516 (iptr[0].val.i == 0x00000400) ||
517 (iptr[0].val.i == 0x00000800) ||
518 (iptr[0].val.i == 0x00001000) ||
519 (iptr[0].val.i == 0x00002000) ||
520 (iptr[0].val.i == 0x00004000) ||
521 (iptr[0].val.i == 0x00008000) ||
522 (iptr[0].val.i == 0x00010000) ||
523 (iptr[0].val.i == 0x00020000) ||
524 (iptr[0].val.i == 0x00040000) ||
525 (iptr[0].val.i == 0x00080000) ||
526 (iptr[0].val.i == 0x00100000) ||
527 (iptr[0].val.i == 0x00200000) ||
528 (iptr[0].val.i == 0x00400000) ||
529 (iptr[0].val.i == 0x00800000) ||
530 (iptr[0].val.i == 0x01000000) ||
531 (iptr[0].val.i == 0x02000000) ||
532 (iptr[0].val.i == 0x04000000) ||
533 (iptr[0].val.i == 0x08000000) ||
534 (iptr[0].val.i == 0x10000000) ||
535 (iptr[0].val.i == 0x20000000) ||
536 (iptr[0].val.i == 0x40000000) ||
537 (iptr[0].val.i == 0x80000000)) {
538 iptr[0].opc = ICMD_IREMPOW2;
540 goto icmd_iconst_tail;
544 #if SUPPORT_CONST_LOGICAL
546 iptr[0].opc = ICMD_IANDCONST;
547 goto icmd_iconst_tail;
549 iptr[0].opc = ICMD_IORCONST;
550 goto icmd_iconst_tail;
552 iptr[0].opc = ICMD_IXORCONST;
553 goto icmd_iconst_tail;
554 #endif /* SUPPORT_CONST_LOGICAL */
556 iptr[0].opc = ICMD_ISHLCONST;
557 goto icmd_iconst_tail;
559 iptr[0].opc = ICMD_ISHRCONST;
560 goto icmd_iconst_tail;
562 iptr[0].opc = ICMD_IUSHRCONST;
563 goto icmd_iconst_tail;
564 #if SUPPORT_LONG_SHIFT
566 iptr[0].opc = ICMD_LSHLCONST;
567 goto icmd_lconst_tail;
569 iptr[0].opc = ICMD_LSHRCONST;
570 goto icmd_lconst_tail;
572 iptr[0].opc = ICMD_LUSHRCONST;
573 goto icmd_lconst_tail;
574 #endif /* SUPPORT_LONG_SHIFT */
576 iptr[0].opc = ICMD_IFEQ;
578 iptr[0].op1 = iptr[1].op1;
579 /* IF_ICMPxx is the last instruction in the */
580 /* basic block, just remove it */
581 /* iptr[1].opc = ICMD_NOP; */
586 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
588 iptr[0].target = (void *) tbptr;
590 MARKREACHED(tbptr, copy);
591 COUNT(count_pcmd_bra);
594 iptr[0].opc = ICMD_IFLT;
595 goto icmd_if_icmp_tail;
597 iptr[0].opc = ICMD_IFLE;
598 goto icmd_if_icmp_tail;
600 iptr[0].opc = ICMD_IFNE;
601 goto icmd_if_icmp_tail;
603 iptr[0].opc = ICMD_IFGT;
604 goto icmd_if_icmp_tail;
606 iptr[0].opc = ICMD_IFGE;
607 goto icmd_if_icmp_tail;
609 #if SUPPORT_CONST_STORE
614 # if defined(ENABLE_INTRP)
617 # if SUPPORT_CONST_STORE_ZERO_ONLY
618 if (iptr[0].val.i == 0) {
619 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
620 switch (iptr[1].opc) {
622 iptr[0].opc = ICMD_IASTORECONST;
625 iptr[0].opc = ICMD_BASTORECONST;
628 iptr[0].opc = ICMD_CASTORECONST;
631 iptr[0].opc = ICMD_SASTORECONST;
635 iptr[1].opc = ICMD_NOP;
636 OPTT2_0(TYPE_INT, TYPE_ADR);
637 COUNT(count_pcmd_op);
638 # if SUPPORT_CONST_STORE_ZERO_ONLY
641 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
642 # if defined(ENABLE_INTRP)
650 # if defined(ENABLE_INTRP)
653 # if SUPPORT_CONST_STORE_ZERO_ONLY
654 if (iptr[0].val.i == 0) {
655 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
656 switch (iptr[1].opc) {
658 iptr[0].opc = ICMD_PUTSTATICCONST;
662 iptr[0].opc = ICMD_PUTFIELDCONST;
667 iptr[1].opc = ICMD_NOP;
668 iptr[0].op1 = TYPE_INT;
669 COUNT(count_pcmd_op);
670 # if SUPPORT_CONST_STORE_ZERO_ONLY
673 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
674 # if defined(ENABLE_INTRP)
679 #endif /* SUPPORT_CONST_STORE */
689 COUNT(count_pcmd_load);
691 switch (iptr[1].opc) {
694 iptr[0].opc = ICMD_LADDCONST;
696 iptr[1].opc = ICMD_NOP;
697 OP1_1(TYPE_LNG,TYPE_LNG);
698 COUNT(count_pcmd_op);
701 iptr[0].opc = ICMD_LSUBCONST;
702 goto icmd_lconst_tail;
703 #endif /* SUPPORT_LONG_ADD */
704 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
706 iptr[0].opc = ICMD_LMULCONST;
707 goto icmd_lconst_tail;
708 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
709 # if SUPPORT_LONG_SHIFT
711 if (iptr[0].val.l == 0x00000002)
713 else if (iptr[0].val.l == 0x00000004)
715 else if (iptr[0].val.l == 0x00000008)
717 else if (iptr[0].val.l == 0x00000010)
719 else if (iptr[0].val.l == 0x00000020)
721 else if (iptr[0].val.l == 0x00000040)
723 else if (iptr[0].val.l == 0x00000080)
725 else if (iptr[0].val.l == 0x00000100)
727 else if (iptr[0].val.l == 0x00000200)
729 else if (iptr[0].val.l == 0x00000400)
731 else if (iptr[0].val.l == 0x00000800)
733 else if (iptr[0].val.l == 0x00001000)
735 else if (iptr[0].val.l == 0x00002000)
737 else if (iptr[0].val.l == 0x00004000)
739 else if (iptr[0].val.l == 0x00008000)
741 else if (iptr[0].val.l == 0x00010000)
743 else if (iptr[0].val.l == 0x00020000)
745 else if (iptr[0].val.l == 0x00040000)
747 else if (iptr[0].val.l == 0x00080000)
749 else if (iptr[0].val.l == 0x00100000)
751 else if (iptr[0].val.l == 0x00200000)
753 else if (iptr[0].val.l == 0x00400000)
755 else if (iptr[0].val.l == 0x00800000)
757 else if (iptr[0].val.l == 0x01000000)
759 else if (iptr[0].val.l == 0x02000000)
761 else if (iptr[0].val.l == 0x04000000)
763 else if (iptr[0].val.l == 0x08000000)
765 else if (iptr[0].val.l == 0x10000000)
767 else if (iptr[0].val.l == 0x20000000)
769 else if (iptr[0].val.l == 0x40000000)
771 else if (iptr[0].val.l == 0x80000000)
777 iptr[0].opc = ICMD_LMULPOW2;
778 goto icmd_lconst_tail;
779 # endif /* SUPPORT_LONG_SHIFT */
780 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
783 if (iptr[0].val.l == 0x00000002)
785 else if (iptr[0].val.l == 0x00000004)
787 else if (iptr[0].val.l == 0x00000008)
789 else if (iptr[0].val.l == 0x00000010)
791 else if (iptr[0].val.l == 0x00000020)
793 else if (iptr[0].val.l == 0x00000040)
795 else if (iptr[0].val.l == 0x00000080)
797 else if (iptr[0].val.l == 0x00000100)
799 else if (iptr[0].val.l == 0x00000200)
801 else if (iptr[0].val.l == 0x00000400)
803 else if (iptr[0].val.l == 0x00000800)
805 else if (iptr[0].val.l == 0x00001000)
807 else if (iptr[0].val.l == 0x00002000)
809 else if (iptr[0].val.l == 0x00004000)
811 else if (iptr[0].val.l == 0x00008000)
813 else if (iptr[0].val.l == 0x00010000)
815 else if (iptr[0].val.l == 0x00020000)
817 else if (iptr[0].val.l == 0x00040000)
819 else if (iptr[0].val.l == 0x00080000)
821 else if (iptr[0].val.l == 0x00100000)
823 else if (iptr[0].val.l == 0x00200000)
825 else if (iptr[0].val.l == 0x00400000)
827 else if (iptr[0].val.l == 0x00800000)
829 else if (iptr[0].val.l == 0x01000000)
831 else if (iptr[0].val.l == 0x02000000)
833 else if (iptr[0].val.l == 0x04000000)
835 else if (iptr[0].val.l == 0x08000000)
837 else if (iptr[0].val.l == 0x10000000)
839 else if (iptr[0].val.l == 0x20000000)
841 else if (iptr[0].val.l == 0x40000000)
843 else if (iptr[0].val.l == 0x80000000)
849 iptr[0].opc = ICMD_LDIVPOW2;
850 goto icmd_lconst_tail;
852 if ((iptr[0].val.l == 0x00000002) ||
853 (iptr[0].val.l == 0x00000004) ||
854 (iptr[0].val.l == 0x00000008) ||
855 (iptr[0].val.l == 0x00000010) ||
856 (iptr[0].val.l == 0x00000020) ||
857 (iptr[0].val.l == 0x00000040) ||
858 (iptr[0].val.l == 0x00000080) ||
859 (iptr[0].val.l == 0x00000100) ||
860 (iptr[0].val.l == 0x00000200) ||
861 (iptr[0].val.l == 0x00000400) ||
862 (iptr[0].val.l == 0x00000800) ||
863 (iptr[0].val.l == 0x00001000) ||
864 (iptr[0].val.l == 0x00002000) ||
865 (iptr[0].val.l == 0x00004000) ||
866 (iptr[0].val.l == 0x00008000) ||
867 (iptr[0].val.l == 0x00010000) ||
868 (iptr[0].val.l == 0x00020000) ||
869 (iptr[0].val.l == 0x00040000) ||
870 (iptr[0].val.l == 0x00080000) ||
871 (iptr[0].val.l == 0x00100000) ||
872 (iptr[0].val.l == 0x00200000) ||
873 (iptr[0].val.l == 0x00400000) ||
874 (iptr[0].val.l == 0x00800000) ||
875 (iptr[0].val.l == 0x01000000) ||
876 (iptr[0].val.l == 0x02000000) ||
877 (iptr[0].val.l == 0x04000000) ||
878 (iptr[0].val.l == 0x08000000) ||
879 (iptr[0].val.l == 0x10000000) ||
880 (iptr[0].val.l == 0x20000000) ||
881 (iptr[0].val.l == 0x40000000) ||
882 (iptr[0].val.l == 0x80000000)) {
883 iptr[0].opc = ICMD_LREMPOW2;
885 goto icmd_lconst_tail;
889 #endif /* SUPPORT_LONG_DIV */
890 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
893 iptr[0].opc = ICMD_LANDCONST;
894 goto icmd_lconst_tail;
896 iptr[0].opc = ICMD_LORCONST;
897 goto icmd_lconst_tail;
899 iptr[0].opc = ICMD_LXORCONST;
900 goto icmd_lconst_tail;
901 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
903 #if SUPPORT_LONG_CMP_CONST
905 if ((len > 1) && (iptr[2].val.i == 0)) {
906 switch (iptr[2].opc) {
908 iptr[0].opc = ICMD_IF_LEQ;
909 icmd_lconst_lcmp_tail:
910 iptr[0].op1 = iptr[2].op1;
913 /* iptr[1].opc = ICMD_NOP;
914 iptr[2].opc = ICMD_NOP; */
916 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
918 iptr[0].target = (void *) tbptr;
920 MARKREACHED(tbptr, copy);
921 COUNT(count_pcmd_bra);
922 COUNT(count_pcmd_op);
925 iptr[0].opc = ICMD_IF_LNE;
926 goto icmd_lconst_lcmp_tail;
928 iptr[0].opc = ICMD_IF_LLT;
929 goto icmd_lconst_lcmp_tail;
931 iptr[0].opc = ICMD_IF_LGT;
932 goto icmd_lconst_lcmp_tail;
934 iptr[0].opc = ICMD_IF_LLE;
935 goto icmd_lconst_lcmp_tail;
937 iptr[0].opc = ICMD_IF_LGE;
938 goto icmd_lconst_lcmp_tail;
941 } /* switch (iptr[2].opc) */
942 } /* if (iptr[2].val.i == 0) */
946 #endif /* SUPPORT_LONG_CMP_CONST */
948 #if SUPPORT_CONST_STORE
950 # if defined(ENABLE_INTRP)
953 # if SUPPORT_CONST_STORE_ZERO_ONLY
954 if (iptr[0].val.l == 0) {
955 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
956 iptr[0].opc = ICMD_LASTORECONST;
957 iptr[1].opc = ICMD_NOP;
958 OPTT2_0(TYPE_INT, TYPE_ADR);
959 COUNT(count_pcmd_op);
960 # if SUPPORT_CONST_STORE_ZERO_ONLY
963 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
964 # if defined(ENABLE_INTRP)
972 # if defined(ENABLE_INTRP)
975 # if SUPPORT_CONST_STORE_ZERO_ONLY
976 if (iptr[0].val.l == 0) {
977 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
978 switch (iptr[1].opc) {
980 iptr[0].opc = ICMD_PUTSTATICCONST;
984 iptr[0].opc = ICMD_PUTFIELDCONST;
989 iptr[1].opc = ICMD_NOP;
990 iptr[0].op1 = TYPE_LNG;
991 COUNT(count_pcmd_op);
992 # if SUPPORT_CONST_STORE_ZERO_ONLY
995 # endif /* SUPPORT_CONST_STORE_ZERO_ONLY */
996 # if defined(ENABLE_INTRP)
1001 #endif /* SUPPORT_CONST_STORE */
1003 PUSHCONST(TYPE_LNG);
1007 PUSHCONST(TYPE_LNG);
1011 COUNT(count_pcmd_load);
1012 PUSHCONST(TYPE_FLT);
1016 COUNT(count_pcmd_load);
1017 PUSHCONST(TYPE_DBL);
1021 COUNT(count_pcmd_load);
1022 #if SUPPORT_CONST_STORE
1023 # if defined(ENABLE_INTRP)
1026 if ((len > 0) && (iptr->val.a == 0)) {
1027 switch (iptr[1].opc) {
1029 case ICMD_PUTSTATIC:
1031 switch (iptr[1].opc) {
1033 iptr[0].opc = ICMD_AASTORECONST;
1034 OPTT2_0(TYPE_INT, TYPE_ADR);
1036 case ICMD_PUTSTATIC:
1037 iptr[0].opc = ICMD_PUTSTATICCONST;
1038 iptr[0].op1 = TYPE_ADR;
1042 iptr[0].opc = ICMD_PUTFIELDCONST;
1043 iptr[0].op1 = TYPE_ADR;
1048 iptr[1].opc = ICMD_NOP;
1049 COUNT(count_pcmd_op);
1053 PUSHCONST(TYPE_ADR);
1057 PUSHCONST(TYPE_ADR);
1058 # if defined(ENABLE_INTRP)
1060 PUSHCONST(TYPE_ADR);
1062 #else /* SUPPORT_CONST_STORE */
1063 PUSHCONST(TYPE_ADR);
1064 #endif /* SUPPORT_CONST_STORE */
1067 /* pop 0 push 1 load */
1074 COUNT(count_load_instruction);
1075 i = opcode - ICMD_ILOAD;
1076 iptr->op1 = argren[iptr->op1];
1077 #if defined(ENABLE_INTRP)
1080 rd->locals[iptr->op1][i].type = i;
1081 LOAD(i, LOCALVAR, iptr->op1);
1091 COUNT(count_check_null);
1092 COUNT(count_check_bound);
1093 COUNT(count_pcmd_mem);
1094 OP2IAT_1(opcode - ICMD_IALOAD);
1100 COUNT(count_check_null);
1101 COUNT(count_check_bound);
1102 COUNT(count_pcmd_mem);
1106 /* pop 0 push 0 iinc */
1109 #if defined(ENABLE_STATISTICS)
1113 count_store_depth[10]++;
1115 count_store_depth[i]++;
1118 last_store[5 * iptr->op1 + TYPE_INT] = bptr->icount - len - 1;
1123 if ((copy->varkind == LOCALVAR) &&
1124 (copy->varnum == iptr->op1)) {
1125 copy->varkind = TEMPVAR;
1135 /* pop 1 push 0 store */
1145 i = opcode - ICMD_ISTORE;
1146 #if defined(ENABLE_INTRP)
1149 rd->locals[iptr->op1][i].type = i;
1150 #if defined(ENABLE_STATISTICS)
1155 count_store_length[20]++;
1157 count_store_length[i]++;
1160 count_store_depth[10]++;
1162 count_store_depth[i]++;
1165 /* check for conflicts as described in Figure 5.2 */
1166 copy = curstack->prev;
1169 if ((copy->varkind == LOCALVAR) &&
1170 (copy->varnum == iptr->op1)) {
1171 copy->varkind = TEMPVAR;
1178 /* do not change instack Stackslots */
1179 /* it won't improve performance if we copy the interface */
1180 /* at the BB begin or here, and lsra relies that no */
1181 /* instack stackslot is marked LOCALVAR */
1182 if (curstack->varkind == STACKVAR)
1183 goto _possible_conflict;
1185 /* check for a DUPX,SWAP while the lifetime of curstack */
1186 /* and as creator curstack */
1187 if (last_dupx != -1) {
1188 /* we have to look at the dst stack of DUPX */
1189 /* == src Stack of PEI */
1190 copy = bptr->iinstr[last_dupx].dst;
1193 copy = bptr->instack;
1195 copy = bptr->iinstr[last_pei-1].dst;
1197 if ((copy != NULL) && (curstack <= copy)) {
1198 /* curstack alive at or created by DUPX */
1201 /* now look, if there is a LOCALVAR at anyone of */
1202 /* the src stacklots used by DUPX */
1204 goto _possible_conflict;
1208 /* check for a PEI while the lifetime of curstack */
1209 if (last_pei != -1) {
1210 /* && there are exception handler in this method */
1211 /* when this is checked prevent ARGVAR from */
1212 /* overwriting LOCALVAR!!! */
1214 /* we have to look at the stack _before_ the PEI! */
1215 /* == src Stack of PEI */
1217 copy = bptr->instack;
1219 copy = bptr->iinstr[last_pei-1].dst;
1220 if ((copy != NULL) && (curstack <= copy)) {
1221 /* curstack alive at PEI */
1222 goto _possible_conflict;
1226 /* check if there is a possible conflicting XSTORE */
1227 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] != -1) {
1228 /* we have to look at the stack _before_ the XSTORE! */
1229 /* == src Stack of XSTORE */
1230 if (last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] == 0)
1231 copy = bptr->instack;
1233 copy = bptr->iinstr[last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] - 1].dst;
1234 if ((copy != NULL) && (curstack <= copy)) {
1235 /* curstack alive at Last Store */
1236 goto _possible_conflict;
1240 /* check if there is a conflict with a XLOAD */
1241 /* this is done indirectly by looking if a Stackslot is */
1242 /* marked LOCALVAR and is live while curstack is live */
1243 /* see figure 5.3 */
1245 /* First check "above" stackslots of the instack */
1246 copy = curstack + 1;
1247 for(;(copy <= bptr->instack); copy++)
1248 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1249 goto _possible_conflict;
1252 /* "intra" Basic Block Stackslots are allocated above */
1253 /* bptr->stack (see doc/stack.txt), so if curstack + 1 */
1254 /* is an instack, copy could point now to the stackslots */
1255 /* of an inbetween analysed Basic Block */
1256 if (copy < bptr->stack)
1258 while (copy < new) {
1259 if ((copy->varkind == LOCALVAR) && (copy->varnum == iptr->op1)) {
1260 goto _possible_conflict;
1264 /* no conflict - mark the Stackslot as LOCALVAR */
1265 curstack->varkind = LOCALVAR;
1266 curstack->varnum = iptr->op1;
1270 if ((curstack->varkind == LOCALVAR)
1271 && (curstack->varnum == iptr->op1)) {
1272 curstack->varkind = TEMPVAR;
1273 curstack->varnum = stackdepth-1;
1276 last_store[5 * iptr->op1 + opcode - ICMD_ISTORE] = bptr->icount - len - 1;
1278 STORE(opcode - ICMD_ISTORE);
1284 COUNT(count_check_null);
1285 COUNT(count_check_bound);
1286 COUNT(count_pcmd_mem);
1288 bte = builtintable_get_internal(BUILTIN_canstore);
1291 if (md->memuse > rd->memuse)
1292 rd->memuse = md->memuse;
1293 if (md->argintreguse > rd->argintreguse)
1294 rd->argintreguse = md->argintreguse;
1296 /* make all stack variables saved */
1300 copy->flags |= SAVEDVAR;
1311 COUNT(count_check_null);
1312 COUNT(count_check_bound);
1313 COUNT(count_pcmd_mem);
1314 OP3TIA_0(opcode - ICMD_IASTORE);
1320 COUNT(count_check_null);
1321 COUNT(count_check_bound);
1322 COUNT(count_pcmd_mem);
1329 #ifdef TYPECHECK_STACK_COMPCAT
1332 if (IS_2_WORD_TYPE(curstack->type)) {
1333 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1346 #if defined(ENABLE_JIT)
1347 # if defined(ENABLE_INTRP)
1350 md_return_alloc(m, rd, opcode - ICMD_IRETURN,
1353 COUNT(count_pcmd_return);
1354 OP1_0(opcode - ICMD_IRETURN);
1355 superblockend = true;
1359 COUNT(count_check_null);
1363 superblockend = true;
1366 case ICMD_PUTSTATIC:
1367 COUNT(count_pcmd_mem);
1371 /* pop 1 push 0 branch */
1374 case ICMD_IFNONNULL:
1375 COUNT(count_pcmd_bra);
1377 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1379 iptr[0].target = (void *) tbptr;
1381 MARKREACHED(tbptr, copy);
1390 COUNT(count_pcmd_bra);
1391 #if CONDITIONAL_LOADCONST
1392 # if defined(ENABLE_INTRP)
1395 tbptr = m->basicblocks + b_index;
1396 if ((b_count >= 3) &&
1397 ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
1398 (tbptr[1].pre_count == 1) &&
1399 (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
1400 (tbptr[1].iinstr[1].opc == ICMD_GOTO) &&
1401 ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
1402 (tbptr[2].pre_count == 1) &&
1403 (tbptr[2].iinstr[0].opc == ICMD_ICONST) &&
1404 (tbptr[2].icount==1)) {
1405 /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
1406 OP1_1(TYPE_INT, TYPE_INT);
1407 switch (iptr[0].opc) {
1409 iptr[0].opc = ICMD_IFNE_ICONST;
1412 iptr[0].opc = ICMD_IFEQ_ICONST;
1415 iptr[0].opc = ICMD_IFGE_ICONST;
1418 iptr[0].opc = ICMD_IFLT_ICONST;
1421 iptr[0].opc = ICMD_IFLE_ICONST;
1424 iptr[0].opc = ICMD_IFGT_ICONST;
1428 iptr[0].val.i = iptr[1].val.i;
1429 iptr[1].opc = ICMD_ELSE_ICONST;
1430 iptr[1].val.i = iptr[3].val.i;
1431 iptr[2].opc = ICMD_NOP;
1432 iptr[3].opc = ICMD_NOP;
1434 /* HACK: save compare value in iptr[1].op1 */
1435 iptr[1].op1 = iptr[0].val.i;
1436 iptr[0].val.i = tbptr[1].iinstr[0].val.i;
1437 iptr[1].opc = ICMD_ELSE_ICONST;
1438 iptr[1].val.i = tbptr[2].iinstr[0].val.i;
1439 tbptr[1].iinstr[0].opc = ICMD_NOP;
1440 tbptr[1].iinstr[1].opc = ICMD_NOP;
1441 tbptr[2].iinstr[0].opc = ICMD_NOP;
1443 tbptr[1].flags = BBDELETED;
1444 tbptr[2].flags = BBDELETED;
1445 tbptr[1].icount = 0;
1446 tbptr[2].icount = 0;
1447 if (tbptr[3].pre_count == 2) {
1448 len += tbptr[3].icount + 3;
1449 bptr->icount += tbptr[3].icount + 3;
1450 tbptr[3].flags = BBDELETED;
1451 tbptr[3].icount = 0;
1461 # if defined(ENABLE_INTRP)
1465 #endif /* CONDITIONAL_LOADCONST */
1469 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1471 iptr[0].target = (void *) tbptr;
1473 MARKREACHED(tbptr, copy);
1476 /* pop 0 push 0 branch */
1479 COUNT(count_pcmd_bra);
1480 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1482 iptr[0].target = (void *) tbptr;
1484 MARKREACHED(tbptr, copy);
1486 superblockend = true;
1489 /* pop 1 push 0 table branch */
1491 case ICMD_TABLESWITCH:
1492 COUNT(count_pcmd_table);
1494 s4ptr = iptr->val.a;
1495 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1496 MARKREACHED(tbptr, copy);
1497 i = *s4ptr++; /* low */
1498 i = *s4ptr++ - i + 1; /* high */
1500 tptr = DMNEW(void*, i+1);
1501 iptr->target = (void *) tptr;
1503 tptr[0] = (void *) tbptr;
1507 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1509 tptr[0] = (void *) tbptr;
1512 MARKREACHED(tbptr, copy);
1515 superblockend = true;
1518 /* pop 1 push 0 table branch */
1520 case ICMD_LOOKUPSWITCH:
1521 COUNT(count_pcmd_table);
1523 s4ptr = iptr->val.a;
1524 tbptr = m->basicblocks + m->basicblockindex[*s4ptr++];
1525 MARKREACHED(tbptr, copy);
1526 i = *s4ptr++; /* count */
1528 tptr = DMNEW(void*, i+1);
1529 iptr->target = (void *) tptr;
1531 tptr[0] = (void *) tbptr;
1535 tbptr = m->basicblocks + m->basicblockindex[s4ptr[1]];
1537 tptr[0] = (void *) tbptr;
1540 MARKREACHED(tbptr, copy);
1544 superblockend = true;
1547 case ICMD_MONITORENTER:
1548 COUNT(count_check_null);
1549 case ICMD_MONITOREXIT:
1553 /* pop 2 push 0 branch */
1555 case ICMD_IF_ICMPEQ:
1556 case ICMD_IF_ICMPNE:
1557 case ICMD_IF_ICMPLT:
1558 case ICMD_IF_ICMPGE:
1559 case ICMD_IF_ICMPGT:
1560 case ICMD_IF_ICMPLE:
1561 COUNT(count_pcmd_bra);
1563 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1565 iptr[0].target = (void *) tbptr;
1567 MARKREACHED(tbptr, copy);
1570 case ICMD_IF_ACMPEQ:
1571 case ICMD_IF_ACMPNE:
1572 COUNT(count_pcmd_bra);
1574 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1576 iptr[0].target = (void *) tbptr;
1578 MARKREACHED(tbptr, copy);
1584 COUNT(count_check_null);
1585 COUNT(count_pcmd_mem);
1586 OPTT2_0(iptr->op1,TYPE_ADR);
1591 if (!IS_2_WORD_TYPE(curstack->type)) {
1593 #ifdef TYPECHECK_STACK_COMPCAT
1596 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1597 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1602 OP1_0ANY; /* second pop */
1605 iptr->opc = ICMD_POP;
1609 /* pop 0 push 1 dup */
1612 #ifdef TYPECHECK_STACK_COMPCAT
1615 if (IS_2_WORD_TYPE(curstack->type)) {
1616 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1621 last_dupx = bptr->icount - len - 1;
1622 COUNT(count_dup_instruction);
1627 last_dupx = bptr->icount - len - 1;
1629 if (IS_2_WORD_TYPE(curstack->type)) {
1631 iptr->opc = ICMD_DUP;
1636 /* ..., ????, cat1 */
1637 #ifdef TYPECHECK_STACK_COMPCAT
1639 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1640 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1646 NEWSTACK(copy->prev->type, copy->prev->varkind,
1647 copy->prev->varnum);
1648 NEWSTACK(copy->type, copy->varkind,
1655 /* pop 2 push 3 dup */
1658 #ifdef TYPECHECK_STACK_COMPCAT
1661 if (IS_2_WORD_TYPE(curstack->type) ||
1662 IS_2_WORD_TYPE(curstack->prev->type)) {
1663 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1668 last_dupx = bptr->icount - len - 1;
1673 last_dupx = bptr->icount - len - 1;
1675 if (IS_2_WORD_TYPE(curstack->type)) {
1676 /* ..., ????, cat2 */
1677 #ifdef TYPECHECK_STACK_COMPCAT
1679 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1680 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1685 iptr->opc = ICMD_DUP_X1;
1689 /* ..., ????, cat1 */
1690 #ifdef TYPECHECK_STACK_COMPCAT
1693 if (IS_2_WORD_TYPE(curstack->prev->type)
1694 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1695 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1704 /* pop 3 push 4 dup */
1707 last_dupx = bptr->icount - len - 1;
1709 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1710 /* ..., cat2, ???? */
1711 #ifdef TYPECHECK_STACK_COMPCAT
1713 if (IS_2_WORD_TYPE(curstack->type)) {
1714 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1719 iptr->opc = ICMD_DUP_X1;
1723 /* ..., cat1, ???? */
1724 #ifdef TYPECHECK_STACK_COMPCAT
1727 if (IS_2_WORD_TYPE(curstack->type)
1728 || IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1729 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1739 last_dupx = bptr->icount - len - 1;
1741 if (IS_2_WORD_TYPE(curstack->type)) {
1742 /* ..., ????, cat2 */
1743 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1744 /* ..., cat2, cat2 */
1745 iptr->opc = ICMD_DUP_X1;
1749 /* ..., cat1, cat2 */
1750 #ifdef TYPECHECK_STACK_COMPCAT
1753 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1754 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1759 iptr->opc = ICMD_DUP_X2;
1765 /* ..., ????, ????, cat1 */
1766 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1767 /* ..., cat2, ????, cat1 */
1768 #ifdef TYPECHECK_STACK_COMPCAT
1770 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1771 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1776 iptr->opc = ICMD_DUP2_X1;
1780 /* ..., cat1, ????, cat1 */
1781 #ifdef TYPECHECK_STACK_COMPCAT
1784 if (IS_2_WORD_TYPE(curstack->prev->type)
1785 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type)) {
1786 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1796 /* pop 2 push 2 swap */
1799 last_dupx = bptr->icount - len - 1;
1800 #ifdef TYPECHECK_STACK_COMPCAT
1803 if (IS_2_WORD_TYPE(curstack->type)
1804 || IS_2_WORD_TYPE(curstack->prev->type)) {
1805 *exceptionptr = new_verifyerror(m, "Attempt to split long or double on the stack");
1817 #if !SUPPORT_DIVISION
1818 bte = (builtintable_entry *) iptr->val.a;
1822 if (md->memuse > rd->memuse)
1823 rd->memuse = md->memuse;
1824 if (md->argintreguse > rd->argintreguse)
1825 rd->argintreguse = md->argintreguse;
1827 /* make all stack variables saved */
1831 copy->flags |= SAVEDVAR;
1836 #endif /* !SUPPORT_DIVISION */
1847 COUNT(count_pcmd_op);
1853 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1854 bte = (builtintable_entry *) iptr->val.a;
1858 if (md->memuse > rd->memuse)
1859 rd->memuse = md->memuse;
1860 if (md->argintreguse > rd->argintreguse)
1861 rd->argintreguse = md->argintreguse;
1863 /* make all stack variables saved */
1867 copy->flags |= SAVEDVAR;
1872 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
1877 #if SUPPORT_LONG_LOGICAL
1881 #endif /* SUPPORT_LONG_LOGICAL */
1882 COUNT(count_pcmd_op);
1889 COUNT(count_pcmd_op);
1898 COUNT(count_pcmd_op);
1907 COUNT(count_pcmd_op);
1912 COUNT(count_pcmd_op);
1913 #if SUPPORT_LONG_CMP_CONST
1914 if ((len > 0) && (iptr[1].val.i == 0)) {
1915 switch (iptr[1].opc) {
1917 iptr[0].opc = ICMD_IF_LCMPEQ;
1919 iptr[0].op1 = iptr[1].op1;
1922 /* iptr[1].opc = ICMD_NOP; */
1924 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
1926 iptr[0].target = (void *) tbptr;
1928 MARKREACHED(tbptr, copy);
1929 COUNT(count_pcmd_bra);
1932 iptr[0].opc = ICMD_IF_LCMPNE;
1933 goto icmd_lcmp_if_tail;
1935 iptr[0].opc = ICMD_IF_LCMPLT;
1936 goto icmd_lcmp_if_tail;
1938 iptr[0].opc = ICMD_IF_LCMPGT;
1939 goto icmd_lcmp_if_tail;
1941 iptr[0].opc = ICMD_IF_LCMPLE;
1942 goto icmd_lcmp_if_tail;
1944 iptr[0].opc = ICMD_IF_LCMPGE;
1945 goto icmd_lcmp_if_tail;
1947 OPTT2_1(TYPE_LNG, TYPE_INT);
1951 #endif /* SUPPORT_LONG_CMP_CONST */
1952 OPTT2_1(TYPE_LNG, TYPE_INT);
1956 COUNT(count_pcmd_op);
1957 OPTT2_1(TYPE_FLT, TYPE_INT);
1961 COUNT(count_pcmd_op);
1962 OPTT2_1(TYPE_DBL, TYPE_INT);
1970 case ICMD_INT2SHORT:
1971 COUNT(count_pcmd_op);
1972 OP1_1(TYPE_INT, TYPE_INT);
1975 COUNT(count_pcmd_op);
1976 OP1_1(TYPE_LNG, TYPE_LNG);
1979 COUNT(count_pcmd_op);
1980 OP1_1(TYPE_FLT, TYPE_FLT);
1983 COUNT(count_pcmd_op);
1984 OP1_1(TYPE_DBL, TYPE_DBL);
1988 COUNT(count_pcmd_op);
1989 OP1_1(TYPE_INT, TYPE_LNG);
1992 COUNT(count_pcmd_op);
1993 OP1_1(TYPE_INT, TYPE_FLT);
1996 COUNT(count_pcmd_op);
1997 OP1_1(TYPE_INT, TYPE_DBL);
2000 COUNT(count_pcmd_op);
2001 OP1_1(TYPE_LNG, TYPE_INT);
2004 COUNT(count_pcmd_op);
2005 OP1_1(TYPE_LNG, TYPE_FLT);
2008 COUNT(count_pcmd_op);
2009 OP1_1(TYPE_LNG, TYPE_DBL);
2012 COUNT(count_pcmd_op);
2013 OP1_1(TYPE_FLT, TYPE_INT);
2016 COUNT(count_pcmd_op);
2017 OP1_1(TYPE_FLT, TYPE_LNG);
2020 COUNT(count_pcmd_op);
2021 OP1_1(TYPE_FLT, TYPE_DBL);
2024 COUNT(count_pcmd_op);
2025 OP1_1(TYPE_DBL, TYPE_INT);
2028 COUNT(count_pcmd_op);
2029 OP1_1(TYPE_DBL, TYPE_LNG);
2032 COUNT(count_pcmd_op);
2033 OP1_1(TYPE_DBL, TYPE_FLT);
2036 case ICMD_CHECKCAST:
2037 if (iptr->op1 == 0) {
2038 /* array type cast-check */
2040 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2043 if (md->memuse > rd->memuse)
2044 rd->memuse = md->memuse;
2045 if (md->argintreguse > rd->argintreguse)
2046 rd->argintreguse = md->argintreguse;
2048 /* make all stack variables saved */
2052 copy->flags |= SAVEDVAR;
2056 OP1_1(TYPE_ADR, TYPE_ADR);
2059 case ICMD_INSTANCEOF:
2060 case ICMD_ARRAYLENGTH:
2061 OP1_1(TYPE_ADR, TYPE_INT);
2065 case ICMD_ANEWARRAY:
2066 OP1_1(TYPE_INT, TYPE_ADR);
2070 COUNT(count_check_null);
2071 COUNT(count_pcmd_mem);
2072 OP1_1(TYPE_ADR, iptr->op1);
2077 case ICMD_GETSTATIC:
2078 COUNT(count_pcmd_mem);
2088 tbptr = m->basicblocks + m->basicblockindex[iptr->op1];
2090 iptr[0].target = (void *) tbptr;
2092 /* This is a dirty hack. The typechecker
2093 * needs it because the OP1_0ANY below
2094 * overwrites iptr->dst.
2096 iptr->val.a = (void *) iptr->dst;
2098 tbptr->type = BBTYPE_SBR;
2100 /* We need to check for overflow right here because
2101 * the pushed value is poped after MARKREACHED. */
2103 MARKREACHED(tbptr, copy);
2107 /* pop many push any */
2110 #if defined(USEBUILTINTABLE)
2113 bte = (builtintable_entry *) iptr->val.a;
2117 case ICMD_INVOKESTATIC:
2118 case ICMD_INVOKESPECIAL:
2119 case ICMD_INVOKEVIRTUAL:
2120 case ICMD_INVOKEINTERFACE:
2121 COUNT(count_pcmd_met);
2123 md = um->methodref->parseddesc.md;
2124 /* if (lm->flags & ACC_STATIC) */
2125 /* {COUNT(count_check_null);} */
2129 last_pei = bptr->icount - len - 1;
2133 if (md->memuse > rd->memuse)
2134 rd->memuse = md->memuse;
2135 if (md->argintreguse > rd->argintreguse)
2136 rd->argintreguse = md->argintreguse;
2137 if (md->argfltreguse > rd->argfltreguse)
2138 rd->argfltreguse = md->argfltreguse;
2143 for (i-- ; i >= 0; i--) {
2144 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2145 /* If we pass float arguments in integer argument registers, we
2146 * are not allowed to precolor them here. Floats have to be moved
2147 * to this regs explicitly in codegen().
2148 * Only arguments that are passed by stack anyway can be precolored
2149 * (michi 2005/07/24) */
2150 if (!(copy->flags & SAVEDVAR) &&
2151 (!IS_FLT_DBL_TYPE(copy->type) || md->params[i].inmemory)) {
2153 if (!(copy->flags & SAVEDVAR)) {
2155 copy->varkind = ARGVAR;
2158 #if defined(ENABLE_INTRP)
2161 if (md->params[i].inmemory) {
2162 copy->flags = INMEMORY;
2163 copy->regoff = md->params[i].regoff;
2166 if (IS_FLT_DBL_TYPE(copy->type))
2167 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2168 assert(0); /* XXX is this assert ok? */
2171 rd->argfltregs[md->params[i].regoff];
2174 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2175 if (IS_2_WORD_TYPE(copy->type))
2176 copy->regoff = PACK_REGS(
2177 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2178 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2182 rd->argintregs[md->params[i].regoff];
2185 #if defined(ENABLE_INTRP)
2193 copy->flags |= SAVEDVAR;
2199 if (md->returntype.type != TYPE_VOID)
2200 OP0_1(md->returntype.type);
2203 case ICMD_INLINE_START:
2204 case ICMD_INLINE_END:
2208 case ICMD_MULTIANEWARRAY:
2209 if (rd->argintreguse < 3)
2210 rd->argintreguse = 3;
2215 #if defined(SPECIALMEMUSE)
2216 # if defined(__DARWIN__)
2217 if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
2218 rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
2220 if (rd->memuse < (i + LA_WORD_SIZE + 3))
2221 rd->memuse = i + LA_WORD_SIZE + 3;
2224 # if defined(__I386__)
2225 if (rd->memuse < i + 3)
2226 rd->memuse = i + 3; /* n integer args spilled on stack */
2227 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2228 if (rd->memuse < i + 2)
2229 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2232 rd->memuse = i; /* n integer args spilled on stack */
2233 # endif /* defined(__I386__) */
2237 /* check INT type here? Currently typecheck does this. */
2238 if (!(copy->flags & SAVEDVAR)) {
2239 copy->varkind = ARGVAR;
2240 copy->varnum = i + INT_ARG_CNT;
2241 copy->flags |= INMEMORY;
2242 #if defined(SPECIALMEMUSE)
2243 # if defined(__DARWIN__)
2244 copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
2246 copy->regoff = i + LA_WORD_SIZE + 3;
2249 # if defined(__I386__)
2250 copy->regoff = i + 3;
2251 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2252 copy->regoff = i + 2;
2255 # endif /* defined(__I386__) */
2256 #endif /* defined(SPECIALMEMUSE) */
2261 copy->flags |= SAVEDVAR;
2269 case ICMD_CLEAR_ARGREN:
2270 for (i = iptr->op1; i < cd->maxlocals; i++)
2272 iptr->opc = opcode = ICMD_NOP;
2276 case ICMD_READONLY_ARG:
2277 case ICMD_READONLY_ARG+1:
2278 case ICMD_READONLY_ARG+2:
2279 case ICMD_READONLY_ARG+3:
2280 case ICMD_READONLY_ARG+4:
2283 if (curstack->varkind == LOCALVAR) {
2284 i = curstack->varnum;
2285 argren[iptr->op1] = i;
2288 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2295 new_internalerror("Unknown ICMD %d", opcode);
2301 } /* while instructions */
2303 bptr->outstack = curstack;
2304 bptr->outdepth = stackdepth;
2308 superblockend = true;
2310 } /* while blocks */
2311 } while (repeat && !deadcode);
2313 #if defined(ENABLE_STATISTICS)
2315 if (m->basicblockcount > count_max_basic_blocks)
2316 count_max_basic_blocks = m->basicblockcount;
2317 count_basic_blocks += m->basicblockcount;
2318 if (m->instructioncount > count_max_javainstr) count_max_javainstr = m->instructioncount;
2319 count_javainstr += m->instructioncount;
2320 if (m->stackcount > count_upper_bound_new_stack)
2321 count_upper_bound_new_stack = m->stackcount;
2322 if ((new - m->stack) > count_max_new_stack)
2323 count_max_new_stack = (new - m->stack);
2325 b_count = m->basicblockcount;
2326 bptr = m->basicblocks;
2327 while (--b_count >= 0) {
2328 if (bptr->flags > BBREACHED) {
2329 if (bptr->indepth >= 10)
2330 count_block_stack[10]++;
2332 count_block_stack[bptr->indepth]++;
2335 count_block_size_distribution[len]++;
2337 count_block_size_distribution[10]++;
2339 count_block_size_distribution[11]++;
2341 count_block_size_distribution[12]++;
2343 count_block_size_distribution[13]++;
2345 count_block_size_distribution[14]++;
2347 count_block_size_distribution[15]++;
2349 count_block_size_distribution[16]++;
2351 count_block_size_distribution[17]++;
2357 count_analyse_iterations[0]++;
2358 else if (loops == 2)
2359 count_analyse_iterations[1]++;
2360 else if (loops == 3)
2361 count_analyse_iterations[2]++;
2362 else if (loops == 4)
2363 count_analyse_iterations[3]++;
2365 count_analyse_iterations[4]++;
2367 if (m->basicblockcount <= 5)
2368 count_method_bb_distribution[0]++;
2369 else if (m->basicblockcount <= 10)
2370 count_method_bb_distribution[1]++;
2371 else if (m->basicblockcount <= 15)
2372 count_method_bb_distribution[2]++;
2373 else if (m->basicblockcount <= 20)
2374 count_method_bb_distribution[3]++;
2375 else if (m->basicblockcount <= 30)
2376 count_method_bb_distribution[4]++;
2377 else if (m->basicblockcount <= 40)
2378 count_method_bb_distribution[5]++;
2379 else if (m->basicblockcount <= 50)
2380 count_method_bb_distribution[6]++;
2381 else if (m->basicblockcount <= 75)
2382 count_method_bb_distribution[7]++;
2384 count_method_bb_distribution[8]++;
2386 #endif /* defined(ENABLE_STATISTICS) */
2388 /* just return methodinfo* to signal everything was ok */
2394 /* debugging helpers **********************************************************/
2396 void icmd_print_stack(codegendata *cd, stackptr s)
2408 j = cd->maxstack - i;
2414 if (s->flags & SAVEDVAR)
2415 switch (s->varkind) {
2417 if (s->flags & INMEMORY)
2418 printf(" M%02d", s->regoff);
2419 #ifdef HAS_ADDRESS_REGISTER_FILE
2420 else if (s->type == TYPE_ADR)
2421 printf(" R%02d", s->regoff);
2423 else if (IS_FLT_DBL_TYPE(s->type))
2424 printf(" F%02d", s->regoff);
2426 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2427 if (IS_2_WORD_TYPE(s->type)) {
2428 # if defined(ENABLE_JIT)
2429 # if defined(ENABLE_INTRP)
2431 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2432 GET_HIGH_REG(s->regoff));
2435 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2436 regs[GET_HIGH_REG(s->regoff)]);
2438 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2439 GET_HIGH_REG(s->regoff));
2442 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
2444 #if defined(ENABLE_JIT)
2445 # if defined(ENABLE_INTRP)
2447 printf(" %3d", s->regoff);
2450 printf(" %3s", regs[s->regoff]);
2452 printf(" %3d", s->regoff);
2458 printf(" I%02d", s->varnum);
2461 printf(" L%02d", s->varnum);
2464 if (s->varnum == -1) {
2466 /* varkind ARGVAR "misused for this special case */
2468 } else /* "normal" Argvar */
2469 printf(" A%02d", s->varnum);
2472 printf(" !%02d", j);
2475 switch (s->varkind) {
2477 if (s->flags & INMEMORY)
2478 printf(" m%02d", s->regoff);
2479 #ifdef HAS_ADDRESS_REGISTER_FILE
2480 else if (s->type == TYPE_ADR)
2481 printf(" r%02d", s->regoff);
2483 else if (IS_FLT_DBL_TYPE(s->type))
2484 printf(" f%02d", s->regoff);
2486 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2487 if (IS_2_WORD_TYPE(s->type)) {
2488 # if defined(ENABLE_JIT)
2489 # if defined(ENABLE_INTRP)
2491 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2492 GET_HIGH_REG(s->regoff));
2495 printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
2496 regs[GET_HIGH_REG(s->regoff)]);
2498 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
2499 GET_HIGH_REG(s->regoff));
2502 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
2504 #if defined(ENABLE_JIT)
2505 # if defined(ENABLE_INTRP)
2507 printf(" %3d", s->regoff);
2510 printf(" %3s", regs[s->regoff]);
2512 printf(" %3d", s->regoff);
2518 printf(" i%02d", s->varnum);
2521 printf(" l%02d", s->varnum);
2524 if (s->varnum == -1) {
2526 /* varkind ARGVAR "misused for this special case */
2528 } else /* "normal" Argvar */
2529 printf(" a%02d", s->varnum);
2532 printf(" ?%02d", j);
2540 static void print_reg(stackptr s) {
2542 if (s->flags & SAVEDVAR)
2543 switch (s->varkind) {
2545 if (s->flags & INMEMORY)
2546 printf(" tm%02d", s->regoff);
2548 printf(" tr%02d", s->regoff);
2551 printf(" s %02d", s->varnum);
2554 printf(" l %02d", s->varnum);
2557 printf(" a %02d", s->varnum);
2560 printf(" ! %02d", s->varnum);
2563 switch (s->varkind) {
2565 if (s->flags & INMEMORY)
2566 printf(" Tm%02d", s->regoff);
2568 printf(" Tr%02d", s->regoff);
2571 printf(" S %02d", s->varnum);
2574 printf(" L %02d", s->varnum);
2577 printf(" A %02d", s->varnum);
2580 printf(" ? %02d", s->varnum);
2590 static char *jit_type[] = {
2599 /* show_icmd_method ************************************************************
2603 *******************************************************************************/
2605 #if !defined(NDEBUG)
2606 void show_icmd_method(methodinfo *m, codegendata *cd, registerdata *rd)
2613 #if defined(USE_THREADS)
2614 /* We need to enter a lock here, since the binutils disassembler
2615 is not reentrant-able and we could not read functions printed
2616 at the same time. */
2618 builtin_monitorenter(lock_show_icmd);
2625 printf("\nBasic blocks: %d\n", m->basicblockcount);
2626 printf("Max locals: %d\n", cd->maxlocals);
2627 printf("Max stack: %d\n", cd->maxstack);
2628 printf("Line number table length: %d\n", m->linenumbercount);
2630 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
2631 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
2632 printf(" L%03d ... ", ex->start->debug_nr );
2633 printf("L%03d = ", ex->end->debug_nr);
2634 printf("L%03d", ex->handler->debug_nr);
2635 printf(" (catchtype: ");
2636 if (ex->catchtype.any)
2637 if (IS_CLASSREF(ex->catchtype))
2638 utf_display_classname(ex->catchtype.ref->name);
2640 utf_display_classname(ex->catchtype.cls->name);
2646 printf("Local Table:\n");
2647 for (i = 0; i < cd->maxlocals; i++) {
2648 printf(" %3d: ", i);
2650 #if defined(ENABLE_JIT)
2651 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
2652 # if defined(ENABLE_INTRP)
2655 if (rd->locals[i][j].type >= 0) {
2656 printf(" (%s) ", jit_type[j]);
2657 if (rd->locals[i][j].flags & INMEMORY)
2658 printf("m%2d", rd->locals[i][j].regoff);
2659 # ifdef HAS_ADDRESS_REGISTER_FILE
2660 else if (j == TYPE_ADR)
2661 printf("r%02d", rd->locals[i][j].regoff);
2663 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2664 printf("f%02d", rd->locals[i][j].regoff);
2666 # if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2667 if (IS_2_WORD_TYPE(j))
2669 regs[GET_LOW_REG(rd->locals[i][j].regoff)],
2670 regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
2673 printf("%3s", regs[rd->locals[i][j].regoff]);
2676 # if defined(ENABLE_INTRP)
2680 #endif /* defined(ENABLE_JIT) */
2686 #if defined(ENABLE_LSRA)
2689 #if defined(ENABLE_INTRP)
2692 printf("Interface Table:\n");
2693 for (i = 0; i < cd->maxstack; i++) {
2694 if ((rd->interfaces[i][0].type >= 0) ||
2695 (rd->interfaces[i][1].type >= 0) ||
2696 (rd->interfaces[i][2].type >= 0) ||
2697 (rd->interfaces[i][3].type >= 0) ||
2698 (rd->interfaces[i][4].type >= 0)) {
2699 printf(" %3d: ", i);
2701 #if defined(ENABLE_JIT)
2702 # if defined(ENABLE_INTRP)
2705 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
2706 if (rd->interfaces[i][j].type >= 0) {
2707 printf(" (%s) ", jit_type[j]);
2708 if (rd->interfaces[i][j].flags & SAVEDVAR) {
2709 if (rd->interfaces[i][j].flags & INMEMORY)
2710 printf("M%2d", rd->interfaces[i][j].regoff);
2711 #ifdef HAS_ADDRESS_REGISTER_FILE
2712 else if (j == TYPE_ADR)
2713 printf("R%02d", rd->interfaces[i][j].regoff);
2715 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2716 printf("F%02d", rd->interfaces[i][j].regoff);
2718 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2719 if (IS_2_WORD_TYPE(j))
2721 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2722 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2725 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2729 if (rd->interfaces[i][j].flags & INMEMORY)
2730 printf("m%2d", rd->interfaces[i][j].regoff);
2731 #ifdef HAS_ADDRESS_REGISTER_FILE
2732 else if (j == TYPE_ADR)
2733 printf("r%02d", rd->interfaces[i][j].regoff);
2735 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2736 printf("f%02d", rd->interfaces[i][j].regoff);
2738 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2739 if (IS_2_WORD_TYPE(j))
2741 regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
2742 regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
2745 printf("%3s",regs[rd->interfaces[i][j].regoff]);
2751 # if defined(ENABLE_INTRP)
2754 #endif /* defined(ENABLE_JIT) */
2760 #if defined(ENABLE_INTRP)
2763 #if defined(ENABLE_LSRA)
2767 /* show code before first basic block */
2769 if (opt_showdisassemble) {
2770 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen);
2772 for (; u1ptr < (u1 *) ((ptrint) m->mcode + cd->dseglen + m->basicblocks[0].mpc);)
2778 /* show code of all basic blocks */
2780 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
2781 show_icmd_block(m, cd, bptr);
2784 /* show stubs code */
2786 if (opt_showdisassemble && opt_showexceptionstubs) {
2787 printf("\nException stubs code:\n");
2788 printf("Length: %d\n\n", (s4) (m->mcodelength -
2789 ((ptrint) cd->dseglen +
2790 m->basicblocks[m->basicblockcount].mpc)));
2792 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen +
2793 m->basicblocks[m->basicblockcount].mpc);
2795 for (; (ptrint) u1ptr < ((ptrint) m->mcode + m->mcodelength);)
2801 #if defined(USE_THREADS)
2802 builtin_monitorexit(lock_show_icmd);
2805 #endif /* !defined(NDEBUG) */
2808 /* show_icmd_block *************************************************************
2812 *******************************************************************************/
2814 #if !defined(NDEBUG)
2815 void show_icmd_block(methodinfo *m, codegendata *cd, basicblock *bptr)
2822 if (bptr->flags != BBDELETED) {
2823 deadcode = bptr->flags <= BBREACHED;
2828 for (j = cd->maxstack; j > 0; j--)
2831 icmd_print_stack(cd, bptr->instack);
2833 printf("] L%03d(flags: %d, next: %d, type: ",
2834 bptr->debug_nr, bptr->flags, (bptr->next) ? (bptr->next->debug_nr) : -1);
2836 switch (bptr->type) {
2848 printf(", instruction count: %d, predecessors: %d):\n",
2849 bptr->icount, bptr->pre_count);
2851 iptr = bptr->iinstr;
2853 for (i = 0; i < bptr->icount; i++, iptr++) {
2857 for (j = cd->maxstack; j > 0; j--)
2860 icmd_print_stack(cd, iptr->dst);
2862 printf("] %5d (line: %5d) ", i, iptr->line);
2864 show_icmd(iptr, deadcode);
2868 if (opt_showdisassemble && (!deadcode)) {
2870 u1ptr = (u1 *) ((ptrint) m->mcode + cd->dseglen + bptr->mpc);
2872 if (bptr->next != NULL) {
2873 for (; u1ptr < (u1 *) ((ptrint) m->mcode + cd->dseglen + bptr->next->mpc);)
2877 for (; u1ptr < (u1 *) ((ptrint) m->mcode + m->mcodelength);)
2884 #endif /* !defined(NDEBUG) */
2887 /* show_icmd *******************************************************************
2891 *******************************************************************************/
2893 #if !defined(NDEBUG)
2894 void show_icmd(instruction *iptr, bool deadcode)
2900 printf("%s", icmd_names[iptr->opc]);
2902 switch (iptr->opc) {
2903 case ICMD_IADDCONST:
2904 case ICMD_ISUBCONST:
2905 case ICMD_IMULCONST:
2909 case ICMD_IANDCONST:
2911 case ICMD_IXORCONST:
2912 case ICMD_ISHLCONST:
2913 case ICMD_ISHRCONST:
2914 case ICMD_IUSHRCONST:
2915 case ICMD_LSHLCONST:
2916 case ICMD_LSHRCONST:
2917 case ICMD_LUSHRCONST:
2919 case ICMD_IASTORECONST:
2920 case ICMD_BASTORECONST:
2921 case ICMD_CASTORECONST:
2922 case ICMD_SASTORECONST:
2923 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2926 case ICMD_IFEQ_ICONST:
2927 case ICMD_IFNE_ICONST:
2928 case ICMD_IFLT_ICONST:
2929 case ICMD_IFGE_ICONST:
2930 case ICMD_IFGT_ICONST:
2931 case ICMD_IFLE_ICONST:
2932 printf(" %d, %d (0x%08x)", iptr[1].op1, iptr->val.i, iptr->val.i);
2935 case ICMD_ELSE_ICONST:
2936 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
2939 case ICMD_LADDCONST:
2940 case ICMD_LSUBCONST:
2941 case ICMD_LMULCONST:
2945 case ICMD_LANDCONST:
2947 case ICMD_LXORCONST:
2949 case ICMD_LASTORECONST:
2950 #if SIZEOF_VOID_P == 4
2951 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
2953 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
2958 printf(" %f (0x%08x)", iptr->val.f, iptr->val.i);
2962 #if SIZEOF_VOID_P == 4
2963 printf(" %g (0x%016llx)", iptr->val.d, iptr->val.l);
2965 printf(" %g (0x%016lx)", iptr->val.d, iptr->val.l);
2970 case ICMD_AASTORECONST:
2971 /* check if this is a constant string or a class reference */
2975 printf(" %p", iptr->val.a);
2977 printf(" (NOT RESOLVED)");
2979 printf(", Class = \"");
2980 utf_display(((constant_classref *) iptr->target)->name);
2984 printf(" %p", iptr->val.a);
2986 printf(", String = \"");
2987 utf_display(javastring_toutf(iptr->val.a, false));
2996 printf(" %d, ", ((fieldinfo *) iptr->val.a)->offset);
2998 printf(" (NOT RESOLVED), ");
2999 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
3001 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
3003 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
3007 case ICMD_PUTSTATIC:
3008 case ICMD_GETSTATIC:
3010 if (!CLASS_IS_OR_ALMOST_INITIALIZED(((fieldinfo *) iptr->val.a)->class))
3011 printf(" (NOT INITIALIZED) ");
3015 printf(" (NOT RESOLVED) ");
3016 utf_display_classname(((unresolved_field *) iptr->target)->fieldref->classref->name);
3018 utf_display(((unresolved_field *) iptr->target)->fieldref->name);
3020 utf_display(((unresolved_field *) iptr->target)->fieldref->descriptor);
3024 case ICMD_PUTSTATICCONST:
3025 case ICMD_PUTFIELDCONST:
3026 switch (iptr[1].op1) {
3028 printf(" %d (0x%08x),", iptr->val.i, iptr->val.i);
3031 #if SIZEOF_VOID_P == 4
3032 printf(" %lld (0x%016llx),", iptr->val.l, iptr->val.l);
3034 printf(" %ld (0x%016lx),", iptr->val.l, iptr->val.l);
3038 printf(" %p,", iptr->val.a);
3041 printf(" %g (0x%08x),", iptr->val.f, iptr->val.i);
3044 #if SIZEOF_VOID_P == 4
3045 printf(" %g (0x%016llx),", iptr->val.d, iptr->val.l);
3047 printf(" %g (0x%016lx),", iptr->val.d, iptr->val.l);
3051 if (iptr->opc == ICMD_PUTFIELDCONST) {
3053 printf(" %d,", ((fieldinfo *) iptr[1].val.a)->offset);
3055 printf(" (NOT RESOLVED),");
3058 utf_display_classname(((unresolved_field *) iptr[1].target)->fieldref->classref->name);
3060 utf_display(((unresolved_field *) iptr[1].target)->fieldref->name);
3062 utf_display(((unresolved_field *) iptr[1].target)->fieldref->descriptor);
3067 printf(" %d + %d", iptr->op1, iptr->val.i);
3102 printf(" %d", iptr->op1);
3107 utf_display_classname(((classinfo *) iptr->val.a)->name);
3111 switch (iptr->op1) {
3139 case ICMD_ANEWARRAY:
3142 utf_display_classname(((classinfo *) iptr->val.a)->name);
3146 case ICMD_MULTIANEWARRAY:
3147 if (iptr->val.a == NULL) {
3148 printf(" (NOT RESOLVED) %d ", iptr->op1);
3149 utf_display(((constant_classref *) iptr->target)->name);
3151 printf(" %d ",iptr->op1);
3152 utf_display_classname(((classinfo *) iptr->val.a)->name);
3156 case ICMD_CHECKCAST:
3157 case ICMD_INSTANCEOF:
3159 classinfo *c = iptr->val.a;
3161 if (c->flags & ACC_INTERFACE)
3162 printf(" (INTERFACE) ");
3164 printf(" (CLASS,%3d) ", c->vftbl->diffval);
3166 printf(" (NOT RESOLVED) ");
3168 utf_display_classname(((constant_classref *) iptr->target)->name);
3172 case ICMD_INLINE_START:
3173 case ICMD_INLINE_END:
3175 utf_display_classname(iptr->method->class->name);
3177 utf_display_classname(iptr->method->name);
3178 utf_display_classname(iptr->method->descriptor);
3182 printf(" %s", ((builtintable_entry *) iptr->val.a)->name);
3185 case ICMD_INVOKEVIRTUAL:
3186 case ICMD_INVOKESPECIAL:
3187 case ICMD_INVOKESTATIC:
3188 case ICMD_INVOKEINTERFACE:
3190 printf(" (NOT RESOLVED) ");
3193 utf_display_classname(((unresolved_method *) iptr->target)->methodref->classref->name);
3195 utf_display(((unresolved_method *) iptr->target)->methodref->name);
3196 utf_display(((unresolved_method *) iptr->target)->methodref->descriptor);
3205 if (deadcode || !iptr->target)
3206 printf(" %d (0x%08x) op1=%d", iptr->val.i, iptr->val.i, iptr->op1);
3208 printf(" %d (0x%08x) L%03d (%p)", iptr->val.i, iptr->val.i, ((basicblock *) iptr->target)->debug_nr,iptr->target);
3217 if (deadcode || !iptr->target)
3218 #if SIZEOF_VOID_P == 4
3219 printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
3221 printf("(%ld) op1=%d", iptr->val.l, iptr->op1);
3224 #if SIZEOF_VOID_P == 4
3225 printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
3227 printf("(%ld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
3234 case ICMD_IFNONNULL:
3235 case ICMD_IF_ICMPEQ:
3236 case ICMD_IF_ICMPNE:
3237 case ICMD_IF_ICMPLT:
3238 case ICMD_IF_ICMPGE:
3239 case ICMD_IF_ICMPGT:
3240 case ICMD_IF_ICMPLE:
3241 case ICMD_IF_LCMPEQ:
3242 case ICMD_IF_LCMPNE:
3243 case ICMD_IF_LCMPLT:
3244 case ICMD_IF_LCMPGE:
3245 case ICMD_IF_LCMPGT:
3246 case ICMD_IF_LCMPLE:
3247 case ICMD_IF_ACMPEQ:
3248 case ICMD_IF_ACMPNE:
3249 case ICMD_INLINE_GOTO:
3250 if (deadcode || !iptr->target)
3251 printf(" op1=%d", iptr->op1);
3253 printf(" L%03d (%p)", ((basicblock *) iptr->target)->debug_nr,iptr->target);
3256 case ICMD_TABLESWITCH:
3257 s4ptr = (s4*)iptr->val.a;
3259 if (deadcode || !iptr->target) {
3260 printf(" %d;", *s4ptr);
3263 tptr = (void **) iptr->target;
3264 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
3268 s4ptr++; /* skip default */
3269 j = *s4ptr++; /* low */
3270 j = *s4ptr++ - j; /* high */
3272 if (deadcode || !*tptr)
3273 printf(" %d", *s4ptr++);
3275 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
3282 case ICMD_LOOKUPSWITCH:
3283 s4ptr = (s4*)iptr->val.a;
3285 if (deadcode || !iptr->target) {
3286 printf(" %d;", *s4ptr);
3289 tptr = (void **) iptr->target;
3290 printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
3293 s4ptr++; /* default */
3294 j = *s4ptr++; /* count */
3297 if (deadcode || !*tptr) {
3298 s4ptr++; /* skip value */
3299 printf(" %d",*s4ptr++);
3302 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
3310 printf(" (NOT RESOLVED), Class = \"");
3311 utf_display(((unresolved_class *) iptr->val.a)->classref->name);
3316 #endif /* !defined(NDEBUG) */
3320 * These are local overrides for various environment variables in Emacs.
3321 * Please do not remove this and leave it at the end of the file, where
3322 * Emacs will automagically detect them.
3323 * ---------------------------------------------------------------------
3326 * indent-tabs-mode: t
3330 * vim:noexpandtab:sw=4:ts=4: