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