* src/vm/jit/show.c (show_init): Do not define this function for
[cacao.git] / src / vm / jit / show.c
1 /* vm/jit/show.c - showing the intermediate representation
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Andreas Krall
28
29    Changes: Edwin Steiner
30             Christian Thalinger
31             Christian Ullrich
32
33    $Id$
34
35 */
36
37
38 #include "config.h"
39 #include "vm/types.h"
40
41 #include <assert.h>
42
43 #include "mm/memory.h"
44 #include "vm/global.h"
45 #include "vm/options.h"
46 #include "vm/builtin.h"
47 #include "vm/stringlocal.h"
48 #include "vm/jit/jit.h"
49 #include "vm/jit/show.h"
50 #include "vm/jit/disass.h"
51
52 #if defined(ENABLE_THREADS)
53 #include "threads/native/lock.h"
54 #endif
55
56 /* global variables ***********************************************************/
57
58 #if defined(ENABLE_THREADS) && !defined(NDEBUG)
59 static java_objectheader *show_global_lock;
60 #endif
61
62
63 /* show_init *******************************************************************
64
65    Initialized the show subsystem (called by jit_init).
66
67 *******************************************************************************/
68
69 #if !defined(NDEBUG)
70 bool show_init(void)
71 {
72 #if defined(ENABLE_THREADS)
73         /* initialize the show lock */
74
75         show_global_lock = NEW(java_objectheader);
76
77         lock_init_object_lock(show_global_lock);
78 #endif
79
80         /* everything's ok */
81
82         return true;
83 }
84 #endif
85
86
87 /* show_print_stack ************************************************************
88
89    Print the stack representation starting with the given top stackptr.
90
91    NOTE: Currently this function may only be called after register allocation!
92
93 *******************************************************************************/
94
95 #if !defined(NDEBUG)
96 static void show_print_stack(codegendata *cd, stackptr s)
97 {
98         int i, j;
99         stackptr t;
100
101         i = cd->maxstack;
102         t = s;
103         
104         while (t) {
105                 i--;
106                 t = t->prev;
107         }
108         j = cd->maxstack - i;
109         while (--i >= 0)
110                 printf("    ");
111
112         while (s) {
113                 j--;
114                 if (s->flags & SAVEDVAR)
115                         switch (s->varkind) {
116                         case TEMPVAR:
117                                 if (s->flags & INMEMORY)
118                                         printf(" M%02d", s->regoff);
119 #ifdef HAS_ADDRESS_REGISTER_FILE
120                                 else if (s->type == TYPE_ADR)
121                                         printf(" R%02d", s->regoff);
122 #endif
123                                 else if (IS_FLT_DBL_TYPE(s->type))
124                                         printf(" F%02d", s->regoff);
125                                 else {
126 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
127                                         if (IS_2_WORD_TYPE(s->type)) {
128 # if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
129 #  if defined(ENABLE_INTRP)
130                                                 if (opt_intrp)
131                                                         printf(" %3d/%3d", GET_LOW_REG(s->regoff),
132                                                                    GET_HIGH_REG(s->regoff));
133                                                 else
134 #  endif
135                                                         printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
136                                                                    regs[GET_HIGH_REG(s->regoff)]);
137 # else
138                                                 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
139                                                            GET_HIGH_REG(s->regoff));
140 # endif
141                                         } 
142                                         else 
143 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
144                                                 {
145 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
146 # if defined(ENABLE_INTRP)
147                                                         if (opt_intrp)
148                                                                 printf(" %3d", s->regoff);
149                                                         else
150 # endif
151                                                                 printf(" %3s", regs[s->regoff]);
152 #else
153                                                         printf(" %3d", s->regoff);
154 #endif
155                                                 }
156                                 }
157                                 break;
158                         case STACKVAR:
159                                 printf(" I%02d", s->varnum);
160                                 break;
161                         case LOCALVAR:
162                                 printf(" L%02d", s->varnum);
163                                 break;
164                         case ARGVAR:
165                                 if (s->varnum == -1) {
166                                         /* Return Value                                  */
167                                         /* varkind ARGVAR "misused for this special case */
168                                         printf("  V0");
169                                 } 
170                                 else /* "normal" Argvar */
171                                         printf(" A%02d", s->varnum);
172                                 break;
173                         default:
174                                 printf(" !%02d", j);
175                         }
176                 else
177                         switch (s->varkind) {
178                         case TEMPVAR:
179                                 if (s->flags & INMEMORY)
180                                         printf(" m%02d", s->regoff);
181 #ifdef HAS_ADDRESS_REGISTER_FILE
182                                 else if (s->type == TYPE_ADR)
183                                         printf(" r%02d", s->regoff);
184 #endif
185                                 else if (IS_FLT_DBL_TYPE(s->type))
186                                         printf(" f%02d", s->regoff);
187                                 else {
188 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
189                                         if (IS_2_WORD_TYPE(s->type)) {
190 # if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
191 #  if defined(ENABLE_INTRP)
192                                                 if (opt_intrp)
193                                                         printf(" %3d/%3d", GET_LOW_REG(s->regoff),
194                                                                    GET_HIGH_REG(s->regoff));
195                                                 else
196 #  endif
197                                                         printf(" %3s/%3s", regs[GET_LOW_REG(s->regoff)],
198                                                                    regs[GET_HIGH_REG(s->regoff)]);
199 # else
200                                                 printf(" %3d/%3d", GET_LOW_REG(s->regoff),
201                                                            GET_HIGH_REG(s->regoff));
202 # endif
203                                         } 
204                                         else
205 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
206                                                 {
207 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
208 # if defined(ENABLE_INTRP)
209                                                         if (opt_intrp)
210                                                                 printf(" %3d", s->regoff);
211                                                         else
212 # endif
213                                                                 printf(" %3s", regs[s->regoff]);
214 #else
215                                                         printf(" %3d", s->regoff);
216 #endif
217                                                 }
218                                 }
219                                 break;
220                         case STACKVAR:
221                                 printf(" i%02d", s->varnum);
222                                 break;
223                         case LOCALVAR:
224                                 printf(" l%02d", s->varnum);
225                                 break;
226                         case ARGVAR:
227                                 if (s->varnum == -1) {
228                                         /* Return Value                                  */
229                                         /* varkind ARGVAR "misused for this special case */
230                                         printf("  v0");
231                                 } 
232                                 else /* "normal" Argvar */
233                                 printf(" a%02d", s->varnum);
234                                 break;
235                         default:
236                                 printf(" ?%02d", j);
237                         }
238                 s = s->prev;
239         }
240 }
241 #endif /* !defined(NDEBUG) */
242
243
244 #if 0
245 static void print_reg(stackptr s) {
246         if (s) {
247                 if (s->flags & SAVEDVAR)
248                         switch (s->varkind) {
249                         case TEMPVAR:
250                                 if (s->flags & INMEMORY)
251                                         printf(" tm%02d", s->regoff);
252                                 else
253                                         printf(" tr%02d", s->regoff);
254                                 break;
255                         case STACKVAR:
256                                 printf(" s %02d", s->varnum);
257                                 break;
258                         case LOCALVAR:
259                                 printf(" l %02d", s->varnum);
260                                 break;
261                         case ARGVAR:
262                                 printf(" a %02d", s->varnum);
263                                 break;
264                         default:
265                                 printf(" ! %02d", s->varnum);
266                         }
267                 else
268                         switch (s->varkind) {
269                         case TEMPVAR:
270                                 if (s->flags & INMEMORY)
271                                         printf(" Tm%02d", s->regoff);
272                                 else
273                                         printf(" Tr%02d", s->regoff);
274                                 break;
275                         case STACKVAR:
276                                 printf(" S %02d", s->varnum);
277                                 break;
278                         case LOCALVAR:
279                                 printf(" L %02d", s->varnum);
280                                 break;
281                         case ARGVAR:
282                                 printf(" A %02d", s->varnum);
283                                 break;
284                         default:
285                                 printf(" ? %02d", s->varnum);
286                         }
287         }
288         else
289                 printf("     ");
290                 
291 }
292 #endif
293
294
295 #if !defined(NDEBUG)
296 static char *jit_type[] = {
297         "int",
298         "lng",
299         "flt",
300         "dbl",
301         "adr"
302 };
303 #endif
304
305
306 /* show_method *****************************************************************
307
308    Print the intermediate representation of a method.
309
310    NOTE: Currently this function may only be called after register allocation!
311
312 *******************************************************************************/
313
314 #if !defined(NDEBUG)
315 void show_method(jitdata *jd)
316 {
317         methodinfo     *m;
318         codeinfo       *code;
319         codegendata    *cd;
320         registerdata   *rd;
321         basicblock     *bptr;
322         exceptiontable *ex;
323         s4              i, j;
324         u1             *u1ptr;
325
326         /* get required compiler data */
327
328         m    = jd->m;
329         code = jd->code;
330         cd   = jd->cd;
331         rd   = jd->rd;
332
333 #if defined(ENABLE_THREADS)
334         /* We need to enter a lock here, since the binutils disassembler
335            is not reentrant-able and we could not read functions printed
336            at the same time. */
337
338         builtin_monitorenter(show_global_lock);
339 #endif
340
341         printf("\n");
342
343         method_println(m);
344
345         printf("\nBasic blocks: %d\n", m->basicblockcount);
346         printf("Max locals:   %d\n", cd->maxlocals);
347         printf("Max stack:    %d\n", cd->maxstack);
348         printf("Line number table length: %d\n", m->linenumbercount);
349
350         printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
351         for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
352                 printf("    L%03d ... ", ex->start->debug_nr );
353                 printf("L%03d  = ", ex->end->debug_nr);
354                 printf("L%03d", ex->handler->debug_nr);
355                 printf("  (catchtype: ");
356                 if (ex->catchtype.any)
357                         if (IS_CLASSREF(ex->catchtype))
358                                 utf_display_printable_ascii_classname(ex->catchtype.ref->name);
359                         else
360                                 utf_display_printable_ascii_classname(ex->catchtype.cls->name);
361                 else
362                         printf("ANY");
363                 printf(")\n");
364         }
365         
366         printf("Local Table:\n");
367         for (i = 0; i < cd->maxlocals; i++) {
368                 printf("   %3d: ", i);
369
370 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
371                 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
372 # if defined(ENABLE_INTRP)
373                         if (!opt_intrp) {
374 # endif
375                                 if (rd->locals[i][j].type >= 0) {
376                                         printf("   (%s) ", jit_type[j]);
377                                         if (rd->locals[i][j].flags & INMEMORY)
378                                                 printf("m%2d", rd->locals[i][j].regoff);
379 # ifdef HAS_ADDRESS_REGISTER_FILE
380                                         else if (j == TYPE_ADR)
381                                                 printf("r%02d", rd->locals[i][j].regoff);
382 # endif
383                                         else if ((j == TYPE_FLT) || (j == TYPE_DBL))
384                                                 printf("f%02d", rd->locals[i][j].regoff);
385                                         else {
386 # if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
387                                                 if (IS_2_WORD_TYPE(j))
388                                                         printf(" %3s/%3s",
389                                                                    regs[GET_LOW_REG(rd->locals[i][j].regoff)],
390                                                                    regs[GET_HIGH_REG(rd->locals[i][j].regoff)]);
391                                                 else
392 # endif
393                                                         printf("%3s", regs[rd->locals[i][j].regoff]);
394                                         }
395                                 }
396 # if defined(ENABLE_INTRP)
397                         }
398 # endif
399                 }
400 #endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
401
402                 printf("\n");
403         }
404         printf("\n");
405
406 #if defined(ENABLE_LSRA)
407         if (!opt_lsra) {
408 #endif
409 #if defined(ENABLE_INTRP)
410                 if (!opt_intrp) {
411 #endif
412         printf("Interface Table:\n");
413         for (i = 0; i < cd->maxstack; i++) {
414                 if ((rd->interfaces[i][0].type >= 0) ||
415                         (rd->interfaces[i][1].type >= 0) ||
416                     (rd->interfaces[i][2].type >= 0) ||
417                         (rd->interfaces[i][3].type >= 0) ||
418                     (rd->interfaces[i][4].type >= 0)) {
419                         printf("   %3d: ", i);
420
421 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
422 # if defined(ENABLE_INTRP)
423                         if (!opt_intrp) {
424 # endif
425                                 for (j = TYPE_INT; j <= TYPE_ADR; j++) {
426                                         if (rd->interfaces[i][j].type >= 0) {
427                                                 printf("   (%s) ", jit_type[j]);
428                                                 if (rd->interfaces[i][j].flags & SAVEDVAR) {
429                                                         if (rd->interfaces[i][j].flags & INMEMORY)
430                                                                 printf("M%2d", rd->interfaces[i][j].regoff);
431 #ifdef HAS_ADDRESS_REGISTER_FILE
432                                                         else if (j == TYPE_ADR)
433                                                                 printf("R%02d", rd->interfaces[i][j].regoff);
434 #endif
435                                                         else if ((j == TYPE_FLT) || (j == TYPE_DBL))
436                                                                 printf("F%02d", rd->interfaces[i][j].regoff);
437                                                         else {
438 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
439                                                                 if (IS_2_WORD_TYPE(j))
440                                                                         printf(" %3s/%3s",
441                                                                                    regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
442                                                                                    regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
443                                                                 else
444 #endif
445                                                                         printf("%3s",regs[rd->interfaces[i][j].regoff]);
446                                                         }
447                                                 }
448                                                 else {
449                                                         if (rd->interfaces[i][j].flags & INMEMORY)
450                                                                 printf("m%2d", rd->interfaces[i][j].regoff);
451 #ifdef HAS_ADDRESS_REGISTER_FILE
452                                                         else if (j == TYPE_ADR)
453                                                                 printf("r%02d", rd->interfaces[i][j].regoff);
454 #endif
455                                                         else if ((j == TYPE_FLT) || (j == TYPE_DBL))
456                                                                 printf("f%02d", rd->interfaces[i][j].regoff);
457                                                         else {
458 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
459                                                                 if (IS_2_WORD_TYPE(j))
460                                                                         printf(" %3s/%3s",
461                                                                                    regs[GET_LOW_REG(rd->interfaces[i][j].regoff)],
462                                                                                    regs[GET_HIGH_REG(rd->interfaces[i][j].regoff)]);
463                                                                 else
464 #endif
465                                                                         printf("%3s",regs[rd->interfaces[i][j].regoff]);
466                                                         }
467                                                 }
468                                         }
469                                 }
470                                 printf("\n");
471 # if defined(ENABLE_INTRP)
472                         }
473 # endif
474 #endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
475
476                 }
477         }
478         printf("\n");
479
480 #if defined(ENABLE_INTRP)
481                 }
482 #endif
483 #if defined(ENABLE_LSRA)
484         }
485 #endif
486
487         if (code->rplpoints) {
488                 printf("Replacement Points:\n");
489                 replace_show_replacement_points(code);
490                 printf("\n");
491         }
492
493 #if defined(ENABLE_DISASSEMBLER)
494         /* show code before first basic block */
495
496         if (opt_showdisassemble) {
497                 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
498
499                 for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + m->basicblocks[0].mpc);)
500                         DISASSINSTR(u1ptr);
501
502                 printf("\n");
503         }
504 #endif
505
506         /* show code of all basic blocks */
507
508         for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next)
509                 show_basicblock(jd, bptr);
510
511 #if defined(ENABLE_DISASSEMBLER)
512         /* show stubs code */
513
514         if (opt_showdisassemble && opt_showexceptionstubs) {
515                 printf("\nException stubs code:\n");
516                 printf("Length: %d\n\n", (s4) (code->mcodelength -
517                                                                            ((ptrint) cd->dseglen +
518                                                                                 m->basicblocks[m->basicblockcount].mpc)));
519
520                 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen +
521                                                 m->basicblocks[m->basicblockcount].mpc);
522
523                 for (; (ptrint) u1ptr < ((ptrint) code->mcode + code->mcodelength);)
524                         DISASSINSTR(u1ptr);
525
526                 printf("\n");
527         }
528 #endif
529
530 #if defined(ENABLE_THREADS)
531         builtin_monitorexit(show_global_lock);
532 #endif
533
534         /* finally flush the output */
535
536         fflush(stdout);
537 }
538 #endif /* !defined(NDEBUG) */
539
540
541 /* show_basicblock *************************************************************
542
543    Print the intermediate representation of a basic block.
544
545    NOTE: Currently this function may only be called after register allocation!
546
547 *******************************************************************************/
548
549 #if !defined(NDEBUG)
550 void show_basicblock(jitdata *jd, basicblock *bptr)
551 {
552         methodinfo  *m;
553         codeinfo    *code;
554         codegendata *cd;
555         s4           i, j;
556         bool         deadcode;
557         instruction *iptr;
558         u1          *u1ptr;
559
560         /* get required compiler data */
561
562         m    = jd->m;
563         code = jd->code;
564         cd   = jd->cd;
565
566         if (bptr->flags != BBDELETED) {
567                 deadcode = bptr->flags <= BBREACHED;
568
569                 printf("[");
570
571                 if (deadcode)
572                         for (j = cd->maxstack; j > 0; j--)
573                                 printf(" ?  ");
574                 else
575                         show_print_stack(cd, bptr->instack);
576
577                 printf("] %sL%03d(flags: %d, bitflags: %01x, next: %d, type: ",
578                                 (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : "",
579                            bptr->debug_nr, bptr->flags, bptr->bitflags, 
580                            (bptr->next) ? (bptr->next->debug_nr) : -1);
581
582                 switch (bptr->type) {
583                 case BBTYPE_STD:
584                         printf("STD");
585                         break;
586                 case BBTYPE_EXH:
587                         printf("EXH");
588                         break;
589                 case BBTYPE_SBR:
590                         printf("SBR");
591                         break;
592                 }
593
594                 printf(", instruction count: %d, predecessors: %d):\n",
595                            bptr->icount, bptr->pre_count);
596
597                 iptr = bptr->iinstr;
598
599                 for (i = 0; i < bptr->icount; i++, iptr++) {
600                         printf("[");
601
602                         if (deadcode)
603                                 for (j = cd->maxstack; j > 0; j--)
604                                         printf(" ?  ");
605                         else
606                                 show_print_stack(cd, iptr->dst);
607
608                         printf("] %5d (line: %5d)  ", i, iptr->line);
609
610                         show_icmd(iptr, deadcode);
611                         printf("\n");
612                 }
613
614 #if defined(ENABLE_DISASSEMBLER)
615                 if (opt_showdisassemble && (!deadcode)) {
616                         printf("\n");
617                         u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen + bptr->mpc);
618
619                         if (bptr->next != NULL) {
620                                 for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + bptr->next->mpc);)
621                                         DISASSINSTR(u1ptr);
622
623                         } 
624                         else {
625                                 for (; u1ptr < (u1 *) ((ptrint) code->mcode + code->mcodelength);)
626                                         DISASSINSTR(u1ptr); 
627                         }
628                         printf("\n");
629                 }
630 #endif
631         }
632 }
633 #endif /* !defined(NDEBUG) */
634
635
636 /* show_icmd *******************************************************************
637
638    Print the intermediate representation of an instruction.
639
640    NOTE: Currently this function may only be called after register allocation!
641
642 *******************************************************************************/
643
644 #if !defined(NDEBUG)
645 void show_icmd(instruction *iptr, bool deadcode)
646 {
647         u2                 opcode;
648         u2                 condition;
649         int j;
650         s4  *s4ptr;
651         void **tptr = NULL;
652         classinfo         *c;
653         fieldinfo         *f;
654         constant_classref *cr;
655         unresolved_field  *uf;
656
657         /* get the opcode and the condition */
658
659         opcode    =  iptr->opc & ICMD_OPCODE_MASK;
660         condition = (iptr->opc & ICMD_CONDITION_MASK) >> 8;
661
662         printf("%s", icmd_names[opcode]);
663
664         /* Print the condition for conditional instructions. */
665
666         if (condition != 0)
667                 printf(" (condition: %s)", icmd_names[condition]);
668
669         switch (opcode) {
670         case ICMD_IADDCONST:
671         case ICMD_ISUBCONST:
672         case ICMD_IMULCONST:
673         case ICMD_IMULPOW2:
674         case ICMD_IDIVPOW2:
675         case ICMD_IREMPOW2:
676         case ICMD_IANDCONST:
677         case ICMD_IORCONST:
678         case ICMD_IXORCONST:
679         case ICMD_ISHLCONST:
680         case ICMD_ISHRCONST:
681         case ICMD_IUSHRCONST:
682         case ICMD_LSHLCONST:
683         case ICMD_LSHRCONST:
684         case ICMD_LUSHRCONST:
685         case ICMD_ICONST:
686         case ICMD_IASTORECONST:
687         case ICMD_BASTORECONST:
688         case ICMD_CASTORECONST:
689         case ICMD_SASTORECONST:
690                 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
691                 break;
692
693         case ICMD_IFEQ_ICONST:
694         case ICMD_IFNE_ICONST:
695         case ICMD_IFLT_ICONST:
696         case ICMD_IFGE_ICONST:
697         case ICMD_IFGT_ICONST:
698         case ICMD_IFLE_ICONST:
699                 printf(" %d, %d (0x%08x)", iptr[1].op1, iptr->val.i, iptr->val.i);
700                 break;
701
702         case ICMD_ELSE_ICONST:
703                 printf("    %d (0x%08x)", iptr->val.i, iptr->val.i);
704                 break;
705
706         case ICMD_LADDCONST:
707         case ICMD_LSUBCONST:
708         case ICMD_LMULCONST:
709         case ICMD_LMULPOW2:
710         case ICMD_LDIVPOW2:
711         case ICMD_LREMPOW2:
712         case ICMD_LANDCONST:
713         case ICMD_LORCONST:
714         case ICMD_LXORCONST:
715         case ICMD_LCONST:
716         case ICMD_LASTORECONST:
717 #if SIZEOF_VOID_P == 4
718                 printf(" %lld (0x%016llx)", iptr->val.l, iptr->val.l);
719 #else
720                 printf(" %ld (0x%016lx)", iptr->val.l, iptr->val.l);
721 #endif
722                 break;
723
724         case ICMD_FCONST:
725                 printf(" %f (0x%08x)", iptr->val.f, iptr->val.i);
726                 break;
727
728         case ICMD_DCONST:
729 #if SIZEOF_VOID_P == 4
730                 printf(" %g (0x%016llx)", iptr->val.d, iptr->val.l);
731 #else
732                 printf(" %g (0x%016lx)", iptr->val.d, iptr->val.l);
733 #endif
734                 break;
735
736         case ICMD_ACONST:
737         case ICMD_AASTORECONST:
738                 /* check if this is a constant string or a class reference */
739
740                 if (ICMD_ACONST_IS_CLASS(iptr)) {
741                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
742                                 printf(" (NOT RESOLVED) classref = ");
743                                 class_classref_print(ICMD_ACONST_UNRESOLVED_CLASSREF(iptr));
744                         }
745                         else {
746                                 printf(" class = ");
747                                 class_print(ICMD_ACONST_RESOLVED_CLASSINFO(iptr));
748                         }
749                 }
750                 else {
751                         printf(" %p", iptr->val.a);
752
753                         if (iptr->val.a) {
754                                 printf(", String = \"");
755                                 utf_display_printable_ascii(javastring_toutf(iptr->val.a, false));
756                                 printf("\"");
757                         }
758                 }
759                 break;
760
761         case ICMD_GETFIELD:
762         case ICMD_PUTFIELD:
763                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
764                         uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
765                         printf(" (NOT RESOLVED) ");
766
767                         field_fieldref_print(uf->fieldref);
768                 }
769                 else {
770                         f = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
771                         printf(" %d, ", f->offset);
772
773                         field_print(f);
774                 }
775                 break;
776
777         case ICMD_PUTSTATIC:
778         case ICMD_GETSTATIC:
779                 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
780                         uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
781                         printf(" (NOT RESOLVED) ");
782
783                         field_fieldref_print(uf->fieldref);
784                 }
785                 else {
786                         f = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
787                         if (!CLASS_IS_OR_ALMOST_INITIALIZED(f->class))
788                                 printf(" (NOT INITIALIZED) ");
789                         else
790                                 printf(" ");
791
792                         field_print(f);
793                 }
794                 break;
795
796         case ICMD_PUTSTATICCONST:
797         case ICMD_PUTFIELDCONST:
798                 switch (iptr[1].op1) {
799                 case TYPE_INT:
800                         printf(" %d (0x%08x),", iptr->val.i, iptr->val.i);
801                         break;
802                 case TYPE_LNG:
803 #if SIZEOF_VOID_P == 4
804                         printf(" %lld (0x%016llx),", iptr->val.l, iptr->val.l);
805 #else
806                         printf(" %ld (0x%016lx),", iptr->val.l, iptr->val.l);
807 #endif
808                         break;
809                 case TYPE_ADR:
810                         printf(" %p,", iptr->val.a);
811                         break;
812                 case TYPE_FLT:
813                         printf(" %g (0x%08x),", iptr->val.f, iptr->val.i);
814                         break;
815                 case TYPE_DBL:
816 #if SIZEOF_VOID_P == 4
817                         printf(" %g (0x%016llx),", iptr->val.d, iptr->val.l);
818 #else
819                         printf(" %g (0x%016lx),", iptr->val.d, iptr->val.l);
820 #endif
821                         break;
822                 }
823
824                 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
825                         uf = INSTRUCTION_UNRESOLVED_FIELD(iptr + 1);
826                         printf(" (NOT RESOLVED) ");
827                         field_fieldref_print(uf->fieldref);
828                 }
829                 else {
830                         f = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
831                         if ((iptr->opc == ICMD_PUTSTATICCONST) &&
832                                 !CLASS_IS_OR_ALMOST_INITIALIZED(f->class))
833                                 printf(" (NOT INITIALIZED), ");
834                         else
835                                 printf(" %d, ", f->offset);
836                         field_print(f);
837                 }
838                 break;
839
840         case ICMD_IINC:
841                 printf(" %d + %d", iptr->op1, iptr->val.i);
842                 break;
843
844         case ICMD_IASTORE:
845         case ICMD_SASTORE:
846         case ICMD_BASTORE:
847         case ICMD_CASTORE:
848         case ICMD_LASTORE:
849         case ICMD_DASTORE:
850         case ICMD_FASTORE:
851         case ICMD_AASTORE:
852
853         case ICMD_IALOAD:
854         case ICMD_SALOAD:
855         case ICMD_BALOAD:
856         case ICMD_CALOAD:
857         case ICMD_LALOAD:
858         case ICMD_DALOAD:
859         case ICMD_FALOAD:
860         case ICMD_AALOAD:
861                 if (iptr->op1 != 0)
862                         printf("(opt.)");
863                 break;
864
865         case ICMD_RET:
866         case ICMD_ILOAD:
867         case ICMD_LLOAD:
868         case ICMD_FLOAD:
869         case ICMD_DLOAD:
870         case ICMD_ALOAD:
871         case ICMD_ISTORE:
872         case ICMD_LSTORE:
873         case ICMD_FSTORE:
874         case ICMD_DSTORE:
875         case ICMD_ASTORE:
876                 printf(" %d", iptr->op1);
877                 break;
878
879         case ICMD_NEW:
880                 c = iptr->val.a;
881                 printf(" ");
882                 utf_display_printable_ascii_classname(c->name);
883                 break;
884
885         case ICMD_NEWARRAY:
886                 switch (iptr->op1) {
887                 case 4:
888                         printf(" boolean");
889                         break;
890                 case 5:
891                         printf(" char");
892                         break;
893                 case 6:
894                         printf(" float");
895                         break;
896                 case 7:
897                         printf(" double");
898                         break;
899                 case 8:
900                         printf(" byte");
901                         break;
902                 case 9:
903                         printf(" short");
904                         break;
905                 case 10:
906                         printf(" int");
907                         break;
908                 case 11:
909                         printf(" long");
910                         break;
911                 }
912                 break;
913
914         case ICMD_ANEWARRAY:
915                 if (iptr->op1) {
916                         c = iptr->val.a;
917                         printf(" ");
918                         utf_display_printable_ascii_classname(c->name);
919                 }
920                 break;
921
922         case ICMD_MULTIANEWARRAY:
923                 c  = iptr->val.a;
924                 cr = iptr->target;
925
926                 if (c == NULL) {
927                         printf(" (NOT RESOLVED) %d ", iptr->op1);
928                         utf_display_printable_ascii(cr->name);
929                 } 
930                 else {
931                         printf(" %d ", iptr->op1);
932                         utf_display_printable_ascii_classname(c->name);
933                 }
934                 break;
935
936         case ICMD_CHECKCAST:
937         case ICMD_INSTANCEOF:
938                 c  = iptr->val.a;
939                 cr = iptr->target;
940
941                 if (c) {
942                         if (c->flags & ACC_INTERFACE)
943                                 printf(" (INTERFACE) ");
944                         else
945                                 printf(" (CLASS,%3d) ", c->vftbl->diffval);
946                 } else
947                         printf(" (NOT RESOLVED) ");
948                 utf_display_printable_ascii_classname(cr->name);
949                 break;
950
951         case ICMD_INLINE_START:
952         case ICMD_INLINE_END:
953                 {
954                         insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
955                         printf(" ");
956                         method_print(insinfo->method);
957                 }
958                 break;
959
960         case ICMD_BUILTIN:
961                 printf(" %s", ((builtintable_entry *) iptr->val.a)->name);
962                 break;
963
964         case ICMD_INVOKEVIRTUAL:
965         case ICMD_INVOKESPECIAL:
966         case ICMD_INVOKESTATIC:
967         case ICMD_INVOKEINTERFACE:
968                 {
969                         constant_FMIref *mref;
970                         
971                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
972                                 printf(" (NOT RESOLVED) ");
973                                 mref = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref;
974                         }
975                         else {
976                                 printf(" ");
977                                 mref = INSTRUCTION_RESOLVED_FMIREF(iptr);
978                         }
979                         method_methodref_print(mref);
980                 }
981                 break;
982
983         case ICMD_IFEQ:
984         case ICMD_IFNE:
985         case ICMD_IFLT:
986         case ICMD_IFGE:
987         case ICMD_IFGT:
988         case ICMD_IFLE:
989                 printf(" %d (0x%08x)", iptr->val.i, iptr->val.i);
990
991                 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
992                         if (deadcode || !iptr->target)
993                                 printf(" op1=%d", iptr->op1);
994                         else
995                                 printf(" L%03d (%p)", ((basicblock *) iptr->target)->debug_nr, iptr->target);
996                 }
997                 break;
998
999         case ICMD_IF_LEQ:
1000         case ICMD_IF_LNE:
1001         case ICMD_IF_LLT:
1002         case ICMD_IF_LGE:
1003         case ICMD_IF_LGT:
1004         case ICMD_IF_LLE:
1005 #if SIZEOF_VOID_P == 4
1006                 printf(" %lld (%016llx)", iptr->val.l, iptr->val.l);
1007 #else
1008                 printf(" %ld (%016lx)", iptr->val.l, iptr->val.l);
1009 #endif
1010
1011                 if ((iptr->opc & ICMD_CONDITION_MASK) == 0) {
1012                         if (deadcode || !iptr->target)
1013                                 printf(" op1=%d", iptr->op1);
1014                         else
1015                                 printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
1016                 }
1017                 break;
1018
1019         case ICMD_JSR:
1020         case ICMD_GOTO:
1021         case ICMD_INLINE_GOTO:
1022                 if (deadcode || !iptr->target)
1023                         printf(" op1=%d", iptr->op1);
1024                 else
1025                         printf(" L%03d (%p)", ((basicblock *) iptr->target)->debug_nr,iptr->target);
1026                 break;
1027
1028         case ICMD_IFNULL:
1029         case ICMD_IFNONNULL:
1030         case ICMD_IF_ICMPEQ:
1031         case ICMD_IF_ICMPNE:
1032         case ICMD_IF_ICMPLT:
1033         case ICMD_IF_ICMPGE:
1034         case ICMD_IF_ICMPGT:
1035         case ICMD_IF_ICMPLE:
1036
1037         case ICMD_IF_LCMPEQ:
1038         case ICMD_IF_LCMPNE:
1039         case ICMD_IF_LCMPLT:
1040         case ICMD_IF_LCMPGE:
1041         case ICMD_IF_LCMPGT:
1042         case ICMD_IF_LCMPLE:
1043
1044         case ICMD_IF_FCMPEQ:
1045         case ICMD_IF_FCMPNE:
1046
1047         case ICMD_IF_FCMPL_LT:
1048         case ICMD_IF_FCMPL_GE:
1049         case ICMD_IF_FCMPL_GT:
1050         case ICMD_IF_FCMPL_LE:
1051
1052         case ICMD_IF_FCMPG_LT:
1053         case ICMD_IF_FCMPG_GE:
1054         case ICMD_IF_FCMPG_GT:
1055         case ICMD_IF_FCMPG_LE:
1056
1057         case ICMD_IF_DCMPEQ:
1058         case ICMD_IF_DCMPNE:
1059
1060         case ICMD_IF_DCMPL_LT:
1061         case ICMD_IF_DCMPL_GE:
1062         case ICMD_IF_DCMPL_GT:
1063         case ICMD_IF_DCMPL_LE:
1064
1065         case ICMD_IF_DCMPG_LT:
1066         case ICMD_IF_DCMPG_GE:
1067         case ICMD_IF_DCMPG_GT:
1068         case ICMD_IF_DCMPG_LE:
1069
1070         case ICMD_IF_ACMPEQ:
1071         case ICMD_IF_ACMPNE:
1072                 if (!(iptr->opc & ICMD_CONDITION_MASK)) {
1073                         if (deadcode || !iptr->target)
1074                                 printf(" op1=%d", iptr->op1);
1075                         else
1076                                 printf(" L%03d (%p)", ((basicblock *) iptr->target)->debug_nr,iptr->target);
1077                 }
1078                 break;
1079
1080         case ICMD_TABLESWITCH:
1081                 s4ptr = (s4*)iptr->val.a;
1082
1083                 if (deadcode || !iptr->target) {
1084                         printf(" %d;", *s4ptr);
1085                 }
1086                 else {
1087                         tptr = (void **) iptr->target;
1088                         printf(" L%03d;", ((basicblock *) *tptr)->debug_nr); 
1089                         tptr++;
1090                 }
1091
1092                 s4ptr++;         /* skip default */
1093                 j = *s4ptr++;                               /* low     */
1094                 j = *s4ptr++ - j;                           /* high    */
1095                 while (j >= 0) {
1096                         if (deadcode || !*tptr)
1097                                 printf(" %d", *s4ptr++);
1098                         else {
1099                                 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
1100                                 tptr++;
1101                         }
1102                         j--;
1103                 }
1104                 break;
1105
1106         case ICMD_LOOKUPSWITCH:
1107                 s4ptr = (s4*)iptr->val.a;
1108
1109                 if (deadcode || !iptr->target) {
1110                         printf(" %d;", *s4ptr);
1111                 }
1112                 else {
1113                         tptr = (void **) iptr->target;
1114                         printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
1115                         tptr++;
1116                 }
1117                 s4ptr++;                                         /* default */
1118                 j = *s4ptr++;                                    /* count   */
1119
1120                 while (--j >= 0) {
1121                         if (deadcode || !*tptr) {
1122                                 s4ptr++; /* skip value */
1123                                 printf(" %d",*s4ptr++);
1124                         }
1125                         else {
1126                                 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
1127                                 tptr++;
1128                         }
1129                 }
1130                 break;
1131
1132         case ICMD_ARETURN:
1133                 if (iptr->val.a) {
1134                         printf(" (NOT RESOLVED) Class = \"");
1135                         utf_display_printable_ascii(((unresolved_class *) iptr->val.a)->classref->name);
1136                         printf("\"");
1137                 }
1138         }
1139 }
1140 #endif /* !defined(NDEBUG) */
1141
1142 /*
1143  * These are local overrides for various environment variables in Emacs.
1144  * Please do not remove this and leave it at the end of the file, where
1145  * Emacs will automagically detect them.
1146  * ---------------------------------------------------------------------
1147  * Local variables:
1148  * mode: c
1149  * indent-tabs-mode: t
1150  * c-basic-offset: 4
1151  * tab-width: 4
1152  * End:
1153  * vim:noexpandtab:sw=4:ts=4:
1154  */