* src/vm/jit/show.c (new_show_method): Only show allocation of locals
[cacao.git] / src / vm / jit / show.c
1 /* src/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
45 #if defined(ENABLE_THREADS)
46 # include "threads/native/lock.h"
47 #else
48 # include "threads/none/lock.h"
49 #endif
50
51 #include "vm/global.h"
52 #include "vm/options.h"
53 #include "vm/builtin.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/show.h"
57 #include "vm/jit/disass.h"
58 #include "vm/jit/stack.h"
59
60
61 /* global variables ***********************************************************/
62
63 #if defined(ENABLE_THREADS) && !defined(NDEBUG)
64 static java_objectheader *show_global_lock;
65 #endif
66
67
68 /* forward declarations *******************************************************/
69
70 #if !defined(NDEBUG)
71 static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage);
72 static void show_allocation(s4 type, s4 flags, s4 regoff);
73 static void show_variable(jitdata *jd, s4 index, int stage);
74 #endif
75
76
77 /* show_init *******************************************************************
78
79    Initialized the show subsystem (called by jit_init).
80
81 *******************************************************************************/
82
83 #if !defined(NDEBUG)
84 bool show_init(void)
85 {
86 #if defined(ENABLE_THREADS)
87         /* initialize the show lock */
88
89         show_global_lock = NEW(java_objectheader);
90
91         lock_init_object_lock(show_global_lock);
92 #endif
93
94         /* everything's ok */
95
96         return true;
97 }
98 #endif
99
100
101 #if !defined(NDEBUG)
102 char *show_jit_type_names[] = {
103         "INT",
104         "LNG",
105         "FLT",
106         "DBL",
107         "ADR",
108         "??5",
109         "??6",
110         "??7",
111         "RET"
112 };
113 char show_jit_type_letters[] = {
114         'I',
115         'L',
116         'F',
117         'D',
118         'A',
119         '5',
120         '6',
121         '7',
122         'R'
123 };
124 #endif
125
126
127 /* show_method *****************************************************************
128
129    Print the intermediate representation of a method.
130
131    NOTE: Currently this function may only be called after register allocation!
132
133 *******************************************************************************/
134
135 #if !defined(NDEBUG)
136 void new_show_method(jitdata *jd, int stage)
137 {
138         methodinfo     *m;
139         codeinfo       *code;
140         codegendata    *cd;
141         registerdata   *rd;
142         basicblock     *bptr;
143         basicblock     *lastbptr;
144         exceptiontable *ex;
145         s4              i, j;
146         u1             *u1ptr;
147
148         /* get required compiler data */
149
150         m    = jd->m;
151         code = jd->code;
152         cd   = jd->cd;
153         rd   = jd->rd;
154
155         /* We need to enter a lock here, since the binutils disassembler
156            is not reentrant-able and we could not read functions printed
157            at the same time. */
158
159         LOCK_MONITOR_ENTER(show_global_lock);
160
161         /* get the last basic block */
162
163         for (lastbptr = jd->new_basicblocks; lastbptr->next != NULL; lastbptr = lastbptr->next);
164
165         printf("\n");
166
167         method_println(m);
168
169         printf("\n(NEW INSTRUCTION FORMAT)\n");
170         if (jd->isleafmethod)
171                 printf("LEAFMETHOD\n");
172         printf("\nBasic blocks: %d\n", jd->new_basicblockcount);
173         if (stage >= SHOW_CODE) {
174                 printf("Code length:  %d\n", (lastbptr->mpc - jd->new_basicblocks[0].mpc));
175                 printf("Data length:  %d\n", cd->dseglen);
176                 printf("Stub length:  %d\n", (s4) (code->mcodelength -
177                                                                                    ((ptrint) cd->dseglen + lastbptr->mpc)));
178         }
179         printf("Max locals:   %d\n", cd->maxlocals);
180         printf("Max stack:    %d\n", cd->maxstack);
181         printf("Line number table length: %d\n", m->linenumbercount);
182
183         if (stage >= SHOW_PARSE) {
184                 printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
185                 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
186                         printf("    L%03d ... ", ex->start->nr );
187                         printf("L%03d  = ", ex->end->nr);
188                         printf("L%03d", ex->handler->nr);
189                         printf("  (catchtype: ");
190                         if (ex->catchtype.any)
191                                 if (IS_CLASSREF(ex->catchtype))
192                                         class_classref_print(ex->catchtype.ref);
193                                 else
194                                         class_print(ex->catchtype.cls);
195                         else
196                                 printf("ANY");
197                         printf(")\n");
198                 }
199         }
200         
201         if (stage >= SHOW_PARSE && rd && jd->localcount > 0) {
202                 printf("Local Table:\n");
203                 for (i = 0; i < jd->localcount; i++) {
204                         printf("   %3d: ", i);
205
206 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
207 # if defined(ENABLE_INTRP)
208                         if (!opt_intrp) {
209 # endif
210                                 printf("   (%s) ", show_jit_type_names[jd->var[i].type]);
211                                 if (stage >= SHOW_REGS)
212                                         show_allocation(jd->var[i].type, jd->var[i].flags, jd->var[i].vv.regoff);
213                                 printf("\n");
214 # if defined(ENABLE_INTRP)
215                         }
216 # endif
217 #endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
218                 }
219                 printf("\n");
220         }
221
222         if (cd->maxlocals > 0) {
223                 printf("Local Map:\n");
224                 printf("    index ");
225                 for (j = 0; j < cd->maxlocals; j++) {
226                         printf(" [%2d]", j);
227                 }
228                 printf("\n");
229                 for (i = 0; i < 5; i++) {
230                         printf("    %5s ",show_jit_type_names[i]);
231                         for (j = 0; j < cd->maxlocals; j++) {
232                                 if (jd->local_map[j*5+i] == UNUSED)
233                                         printf("  -- ");
234                                 else
235                                         printf("%4i ",jd->local_map[j*5+i]);
236                         }
237                         printf("\n");
238                 }
239                 printf("\n");
240         }
241
242         if (cd->maxstack > 0 && jd->interface_map && stage >= SHOW_STACK) {
243                 bool exist = false;
244                 interface_info *mapptr = jd->interface_map;
245                 
246                 /* look if there exist any IN/OUTVARS */
247                 for (i = 0; (i < (5 * cd->maxstack)) && !exist; i++, mapptr++)
248                         exist = (mapptr->flags != UNUSED);
249
250                 if (exist) {
251                         printf("Interface Table: (In/Outvars)\n");
252                         printf("    depth ");
253                         for (j = 0; j < cd->maxstack; j++) {
254                                 printf("      [%2d]", j);
255                         }
256                         printf("\n");
257
258                         for (i = 0; i < 5; i++) {
259                                 printf("    %5s      ",show_jit_type_names[i]);
260                                 for (j = 0; j < cd->maxstack; j++) {
261                                         s4 flags  = jd->interface_map[j*5+i].flags;
262                                         s4 regoff = jd->interface_map[j*5+i].regoff;
263                                         if (flags == UNUSED)
264                                                 printf("  --      ");
265                                         else {
266                                                 int ch;
267
268                                                 if (stage >= SHOW_REGS) {
269                                                         if (flags & SAVEDVAR) {
270                                                                 if (flags & INMEMORY)
271                                                                         ch = 'M';
272                                                                 else
273                                                                         ch = 'R';
274                                                         }
275                                                         else {
276                                                                 if (flags & INMEMORY)
277                                                                         ch = 'm';
278                                                                 else
279                                                                         ch = 'r';
280                                                         }
281                                                         printf("%c%03d(", ch, regoff);
282                                                         show_allocation(i, flags, regoff);
283                                                         printf(") ");
284                                                 }
285                                                 else {
286                                                         if (flags & SAVEDVAR)
287                                                                 printf("  I       ");
288                                                         else
289                                                                 printf("  i       ");
290                                                 }
291                                         }
292                                 }
293                                 printf("\n");
294                         }
295                         printf("\n");
296                 }
297         }
298
299         if (rd->memuse && stage >= SHOW_REGS) {
300                 int max;
301
302                 max = rd->memuse;
303                 printf("Stack slots: (memuse=%d", rd->memuse);
304                 if (stage >= SHOW_CODE) {
305                         printf(", stackframesize=%d", cd->stackframesize);
306                         max = cd->stackframesize;
307                 }
308                 printf(")\n");
309                 for (i=0; i<max; ++i) {
310 #if defined(HAS_4BYTE_STACKSLOT)
311                         printf("    M%02d = 0x%02x(sp): ", i, i * 4);
312 #else
313                         printf("    M%02d = 0x%02x(sp): ", i, i * 8);
314 #endif
315                         for (j=0; j<jd->varcount; ++j) {
316                                 varinfo *v = jd->var + j;
317                                 if ((v->flags & INMEMORY) && (v->vv.regoff == i)) {
318                                         show_variable(jd, j, stage);
319                                         putchar(' ');
320                                 }
321                         }
322
323                         printf("\n");
324
325                 }
326                 printf("\n");
327         }
328
329         if (code->rplpoints) {
330                 printf("Replacement Points:\n");
331                 replace_show_replacement_points(code);
332                 printf("\n");
333         }
334
335 #if defined(ENABLE_DISASSEMBLER)
336         /* show code before first basic block */
337
338         if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
339                 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
340
341                 for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->new_basicblocks[0].mpc);)
342                         DISASSINSTR(u1ptr);
343
344                 printf("\n");
345         }
346 #endif
347
348         /* show code of all basic blocks */
349
350         for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next)
351                 new_show_basicblock(jd, bptr, stage);
352
353 #if defined(ENABLE_DISASSEMBLER)
354         /* show stubs code */
355
356         if (stage >= SHOW_CODE && opt_showdisassemble && opt_showexceptionstubs) {
357                 printf("\nStubs code:\n");
358                 printf("Length: %d\n\n", (s4) (code->mcodelength -
359                                                                            ((ptrint) cd->dseglen + lastbptr->mpc)));
360
361                 u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen + lastbptr->mpc);
362
363                 for (; (ptrint) u1ptr < ((ptrint) code->mcode + code->mcodelength);)
364                         DISASSINSTR(u1ptr);
365
366                 printf("\n");
367         }
368 #endif
369
370         LOCK_MONITOR_EXIT(show_global_lock);
371
372         /* finally flush the output */
373
374         fflush(stdout);
375 }
376 #endif /* !defined(NDEBUG) */
377
378
379 /* show_basicblock *************************************************************
380
381    Print the intermediate representation of a basic block.
382
383    NOTE: Currently this function may only be called after register allocation!
384
385 *******************************************************************************/
386
387 #if !defined(NDEBUG)
388 void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
389 {
390         methodinfo  *m;
391         codeinfo    *code;
392         codegendata *cd;
393         s4           i;
394         bool         deadcode;
395         instruction *iptr;
396         u1          *u1ptr;
397
398         /* get required compiler data */
399
400         m    = jd->m;
401         code = jd->code;
402         cd   = jd->cd;
403
404         if (bptr->flags != BBDELETED) {
405                 deadcode = bptr->flags <= BBREACHED;
406
407                 printf("======== %sL%03d ======== %s(flags: %d, bitflags: %01x, next: %d, type: ",
408                                 (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : "",
409                            bptr->nr, 
410                            (deadcode && stage >= SHOW_STACK) ? "DEADCODE! " : "",
411                            bptr->flags, bptr->bitflags, 
412                            (bptr->next) ? (bptr->next->nr) : -1);
413
414                 switch (bptr->type) {
415                 case BBTYPE_STD:
416                         printf("STD");
417                         break;
418                 case BBTYPE_EXH:
419                         printf("EXH");
420                         break;
421                 case BBTYPE_SBR:
422                         printf("SBR");
423                         break;
424                 }
425
426                 printf(", icount: %d, preds: %d [ ",
427                            bptr->icount, bptr->predecessorcount);
428
429                 for (i = 0; i < bptr->predecessorcount; i++)
430                         printf("%d ", bptr->predecessors[i]->nr);
431
432                 printf("]):");
433
434                 if (bptr->original)
435                         printf(" (clone of L%03d)", bptr->original->nr);
436                 else {
437                         basicblock *b = bptr->copied_to;
438                         if (b) {
439                                 printf(" (copied to ");
440                                 for (; b; b = b->copied_to)
441                                         printf("L%03d ", b->nr);
442                                 printf(")");
443                         }
444                 }
445
446                 printf("\n");
447
448                 if (stage >= SHOW_STACK) {
449                         printf("IN:  ");
450                         new_show_variable_array(jd, bptr->invars, bptr->indepth, stage);
451                         printf("\n");
452                 }
453
454                 iptr = bptr->iinstr;
455
456                 for (i = 0; i < bptr->icount; i++, iptr++) {
457                         printf("%4d:  ", iptr->line);
458
459                         new_show_icmd(jd, iptr, deadcode, stage);
460                         printf("\n");
461                 }
462
463                 if (stage >= SHOW_STACK) {
464                         printf("OUT: ");
465                         new_show_variable_array(jd, bptr->outvars, bptr->outdepth, stage);
466                         printf("\n");
467                 }
468
469 #if defined(ENABLE_DISASSEMBLER)
470                 if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) &&
471                         (!deadcode)) 
472                 {
473                         printf("\n");
474                         u1ptr = (u1 *) (code->mcode + cd->dseglen + bptr->mpc);
475
476                         if (bptr->next != NULL) {
477                                 for (; u1ptr < (u1 *) (code->mcode + cd->dseglen + bptr->next->mpc);)
478                                         DISASSINSTR(u1ptr);
479
480                         } 
481                         else {
482                                 for (; u1ptr < (u1 *) (code->mcode + code->mcodelength);)
483                                         DISASSINSTR(u1ptr); 
484                         }
485                         printf("\n");
486                 }
487 #endif
488         }
489 }
490 #endif /* !defined(NDEBUG) */
491
492
493 /* show_icmd *******************************************************************
494
495    Print the intermediate representation of an instruction.
496
497    NOTE: Currently this function may only be called after register allocation!
498
499 *******************************************************************************/
500
501 #if !defined(NDEBUG)
502
503 #define SHOW_TARGET(target)                                          \
504         if (stage >= SHOW_STACK) {                                   \
505             printf("--> L%03d ", (target).block->nr);                \
506         }                                                            \
507         else if (stage >= SHOW_PARSE) {                              \
508             printf("--> insindex %d (L%03d) ", (target).insindex,    \
509                 jd->new_basicblocks[jd->new_basicblockindex[         \
510                 (target).insindex]].nr);                             \
511         }                                                            \
512         else {                                                       \
513             printf("--> insindex %d ", (target).insindex);           \
514         }
515
516 #define SHOW_INT_CONST(val)                                          \
517         if (stage >= SHOW_PARSE) {                                   \
518             printf("%ld ", (long) (val));                            \
519         }                                                            \
520         else {                                                       \
521             printf("iconst ");                                       \
522         }
523
524 #define SHOW_LNG_CONST(val)                                          \
525         if (stage >= SHOW_PARSE) {                                   \
526             printf("%lld ", (long long)(val));                       \
527         }                                                            \
528         else {                                                       \
529             printf("lconst ");                                       \
530         }
531
532 #define SHOW_FLT_CONST(val)                                          \
533         if (stage >= SHOW_PARSE) {                                   \
534             printf("%g ", (val));                                    \
535         }                                                            \
536         else {                                                       \
537             printf("fconst ");                                       \
538         }
539
540 #define SHOW_DBL_CONST(val)                                          \
541         if (stage >= SHOW_PARSE) {                                   \
542             printf("%g ", (val));                                    \
543         }                                                            \
544         else {                                                       \
545             printf("dconst ");                                       \
546         }
547
548 #define SHOW_INDEX(index)                                            \
549         if (stage >= SHOW_PARSE) {                                   \
550             printf("%d ", index);                                    \
551         }                                                            \
552         else {                                                       \
553             printf("index");                                         \
554         }
555
556 #define SHOW_STRING(val)                                             \
557         if (stage >= SHOW_PARSE) {                                   \
558             putchar('"');                                            \
559             utf_display_printable_ascii(                             \
560                 javastring_toutf((java_lang_String *)(val), false)); \
561             printf("\" ");                                           \
562         }                                                            \
563         else {                                                       \
564             printf("string ");                                       \
565         }
566
567 #define SHOW_CLASSREF_OR_CLASSINFO(c)                                \
568         if (stage >= SHOW_PARSE) {                                   \
569             if (IS_CLASSREF(c))                                      \
570                 class_classref_print(c.ref);                         \
571             else                                                     \
572                 class_print(c.cls);                                  \
573             putchar(' ');                                            \
574         }                                                            \
575         else {                                                       \
576             printf("class ");                                        \
577         }
578
579 #define SHOW_FIELD(fmiref)                                           \
580         if (stage >= SHOW_PARSE) {                                   \
581             field_fieldref_print(fmiref);                            \
582             putchar(' ');                                            \
583         }                                                            \
584         else {                                                       \
585             printf("field ");                                        \
586         }
587
588 #define SHOW_VARIABLE(v)                                             \
589     show_variable(jd, (v), stage)
590
591 #define SHOW_S1(iptr)                                                \
592         if (stage >= SHOW_STACK) {                                   \
593             SHOW_VARIABLE(iptr->s1.varindex);                        \
594         }
595
596 #define SHOW_S2(iptr)                                                \
597         if (stage >= SHOW_STACK) {                                   \
598             SHOW_VARIABLE(iptr->sx.s23.s2.varindex);                 \
599         }
600
601 #define SHOW_S3(iptr)                                                \
602     if (stage >= SHOW_STACK) {                                       \
603         SHOW_VARIABLE(iptr->sx.s23.s3.varindex);                     \
604     }
605
606 #define SHOW_DST(iptr)                                               \
607     if (stage >= SHOW_STACK) {                                       \
608         printf("=> ");                                               \
609         SHOW_VARIABLE(iptr->dst.varindex);                           \
610     }
611
612 #define SHOW_S1_LOCAL(iptr)                                          \
613     if (stage >= SHOW_STACK) {                                       \
614         printf("L%d ", iptr->s1.varindex);                           \
615     }                                                                \
616     else {                                                           \
617         printf("JavaL%d ", iptr->s1.varindex);                       \
618     }
619
620 #define SHOW_DST_LOCAL(iptr)                                         \
621     if (stage >= SHOW_STACK) {                                       \
622         printf("=> L%d ", iptr->dst.varindex);                       \
623     }                                                                \
624     else {                                                           \
625         printf("=> JavaL%d ", iptr->dst.varindex);                   \
626     }
627
628 static void show_allocation(s4 type, s4 flags, s4 regoff)
629 {
630         if (flags & INMEMORY) {
631                 printf("M%02d", regoff);
632                 return;
633         }
634
635 #ifdef HAS_ADDRESS_REGISTER_FILE
636         if (type == TYPE_ADR) {
637                 printf("R%02d", regoff);
638                 return;
639         }
640 #endif
641
642         if (IS_FLT_DBL_TYPE(type)) {
643                 printf("F%02d", regoff);
644                 return;
645         }
646
647 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
648         if (IS_2_WORD_TYPE(type)) {
649 # if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
650 #  if defined(ENABLE_INTRP)
651                 if (opt_intrp)
652                         printf("%3d/%3d", GET_LOW_REG(regoff),
653                                         GET_HIGH_REG(regoff));
654                 else
655 #  endif
656                         printf("%3s/%3s", regs[GET_LOW_REG(regoff)],
657                                         regs[GET_HIGH_REG(regoff)]);
658 # else
659                 printf("%3d/%3d", GET_LOW_REG(regoff),
660                                 GET_HIGH_REG(regoff));
661 # endif
662                 return;
663         } 
664 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
665
666 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
667 # if defined(ENABLE_INTRP)
668         if (opt_intrp)
669                 printf("%3d", regoff);
670         else
671 # endif
672                 printf("%3s", regs[regoff]);
673 #else
674         printf("%3d", regoff);
675 #endif
676 }
677
678 static void show_variable(jitdata *jd, s4 index, int stage)
679 {
680         char type;
681         char kind;
682         varinfo *v;
683
684         v = &(jd->var[index]);
685
686         switch (v->type) {
687                 case TYPE_INT: type = 'i'; break;
688                 case TYPE_LNG: type = 'l'; break;
689                 case TYPE_FLT: type = 'f'; break;
690                 case TYPE_DBL: type = 'd'; break;
691                 case TYPE_ADR: type = 'a'; break;
692                 case TYPE_RET: type = 'r'; break;
693                 default:       type = '?';
694         }
695
696         if (index < jd->localcount) {
697                 kind = 'L';
698                 if (v->flags & (PREALLOC | OUTVAR))
699                                 printf("<INVALID FLAGS!>");
700         }
701         else {
702                 if (v->flags & PREALLOC) {
703                         kind = 'A';
704                         if (v->flags & OUTVAR)
705                                 printf("<INVALID FLAGS!>");
706                 }
707                 else if (v->flags & OUTVAR)
708                         kind = 'I';
709                 else
710                         kind = 'T';
711         }
712
713         printf("%c%c%d", kind, type, index);
714
715         if (v->flags & SAVEDVAR)
716                 putchar('!');
717
718         if (stage >= SHOW_REGS) {
719                 putchar('(');
720                 show_allocation(v->type, v->flags, v->vv.regoff);
721                 putchar(')');
722         }
723         putchar(' ');
724         fflush(stdout);
725 }
726
727 static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
728 {
729         int i;
730
731         printf("[");
732         for (i=0; i<n; ++i) {
733                 if (i)
734                         printf(" ");
735                 show_variable(jd, vars[i], stage);
736         }
737         printf("]");
738 }
739
740 void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
741 {
742         u2                 opcode;
743         branch_target_t   *table;
744         lookup_target_t   *lookup;
745         constant_FMIref   *fmiref;
746         s4          *argp;
747         s4                 i;
748
749         /* get the opcode and the condition */
750
751         opcode    =  iptr->opc;
752
753         printf("%s ", icmd_names[opcode]);
754
755         if (stage < SHOW_PARSE)
756                 return;
757
758         if (deadcode)
759                 stage = SHOW_PARSE;
760
761         /* Print the condition for conditional instructions. */
762
763         /* XXX print condition from flags */
764
765         if (iptr->flags.bits & INS_FLAG_UNRESOLVED)
766                 printf("(UNRESOLVED) ");
767
768         switch (opcode) {
769
770         case ICMD_POP:
771         case ICMD_CHECKNULL:
772         case ICMD_CHECKNULL_POP:
773                 SHOW_S1(iptr);
774                 break;
775
776                 /* unary */
777         case ICMD_ARRAYLENGTH:
778         case ICMD_INEG:
779         case ICMD_LNEG:
780         case ICMD_FNEG:
781         case ICMD_DNEG:
782         case ICMD_I2L:
783         case ICMD_I2F:
784         case ICMD_I2D:
785         case ICMD_L2I:
786         case ICMD_L2F:
787         case ICMD_L2D:
788         case ICMD_F2I:
789         case ICMD_F2L:
790         case ICMD_F2D:
791         case ICMD_D2I:
792         case ICMD_D2L:
793         case ICMD_D2F:
794         case ICMD_INT2BYTE:
795         case ICMD_INT2CHAR:
796         case ICMD_INT2SHORT:
797                 SHOW_S1(iptr);
798                 SHOW_DST(iptr);
799                 break;
800
801                 /* binary */
802         case ICMD_IADD:
803         case ICMD_LADD:
804         case ICMD_FADD:
805         case ICMD_DADD:
806         case ICMD_ISUB:
807         case ICMD_LSUB:
808         case ICMD_FSUB:
809         case ICMD_DSUB:
810         case ICMD_IMUL:
811         case ICMD_LMUL:
812         case ICMD_FMUL:
813         case ICMD_DMUL:
814         case ICMD_IDIV:
815         case ICMD_LDIV:
816         case ICMD_FDIV:
817         case ICMD_DDIV:
818         case ICMD_IREM:
819         case ICMD_LREM:
820         case ICMD_FREM:
821         case ICMD_DREM:
822         case ICMD_ISHL:
823         case ICMD_LSHL:
824         case ICMD_ISHR:
825         case ICMD_LSHR:
826         case ICMD_IUSHR:
827         case ICMD_LUSHR:
828         case ICMD_IAND:
829         case ICMD_LAND:
830         case ICMD_IOR:
831         case ICMD_LOR:
832         case ICMD_IXOR:
833         case ICMD_LXOR:
834         case ICMD_LCMP:
835         case ICMD_FCMPL:
836         case ICMD_FCMPG:
837         case ICMD_DCMPL:
838         case ICMD_DCMPG:
839                 SHOW_S1(iptr);
840                 SHOW_S2(iptr);
841                 SHOW_DST(iptr);
842                 break;
843
844                 /* binary/const INT */
845         case ICMD_IADDCONST:
846         case ICMD_ISUBCONST:
847         case ICMD_IMULCONST:
848         case ICMD_IMULPOW2:
849         case ICMD_IDIVPOW2:
850         case ICMD_IREMPOW2:
851         case ICMD_IANDCONST:
852         case ICMD_IORCONST:
853         case ICMD_IXORCONST:
854         case ICMD_ISHLCONST:
855         case ICMD_ISHRCONST:
856         case ICMD_IUSHRCONST:
857         case ICMD_LSHLCONST:
858         case ICMD_LSHRCONST:
859         case ICMD_LUSHRCONST:
860                 SHOW_S1(iptr);
861                 SHOW_INT_CONST(iptr->sx.val.i); 
862                 SHOW_DST(iptr);
863                 break;
864
865                 /* ?ASTORECONST (trinary/const INT) */
866         case ICMD_IASTORECONST:
867         case ICMD_BASTORECONST:
868         case ICMD_CASTORECONST:
869         case ICMD_SASTORECONST:
870                 SHOW_S1(iptr);
871                 SHOW_S2(iptr);
872                 SHOW_INT_CONST(iptr->sx.s23.s3.constval);
873                 break;
874
875                 /* const INT */
876         case ICMD_ICONST:
877                 SHOW_INT_CONST(iptr->sx.val.i); 
878                 SHOW_DST(iptr);
879                 break;
880
881                 /* binary/const LNG */
882         case ICMD_LADDCONST:
883         case ICMD_LSUBCONST:
884         case ICMD_LMULCONST:
885         case ICMD_LMULPOW2:
886         case ICMD_LDIVPOW2:
887         case ICMD_LREMPOW2:
888         case ICMD_LANDCONST:
889         case ICMD_LORCONST:
890         case ICMD_LXORCONST:
891                 SHOW_S1(iptr);
892                 SHOW_LNG_CONST(iptr->sx.val.l); 
893                 SHOW_DST(iptr);
894                 break;
895
896                 /* trinary/const LNG (<= pointer size) */
897         case ICMD_LASTORECONST:
898                 SHOW_S1(iptr);
899                 SHOW_S2(iptr);
900                 SHOW_LNG_CONST(iptr->sx.s23.s3.constval);
901                 break;
902
903                 /* const LNG */
904         case ICMD_LCONST:
905                 SHOW_LNG_CONST(iptr->sx.val.l); 
906                 SHOW_DST(iptr);
907                 break;
908
909                 /* const FLT */
910         case ICMD_FCONST:
911                 SHOW_FLT_CONST(iptr->sx.val.f); 
912                 SHOW_DST(iptr);
913                 break;
914
915                 /* const DBL */
916         case ICMD_DCONST:
917                 SHOW_DBL_CONST(iptr->sx.val.d); 
918                 SHOW_DST(iptr);
919                 break;
920
921                 /* const ADR */
922         case ICMD_ACONST:
923                 if (iptr->flags.bits & INS_FLAG_CLASS) {
924                         SHOW_CLASSREF_OR_CLASSINFO(iptr->sx.val.c);
925                 }
926                 else if (iptr->sx.val.anyptr == NULL) {
927                         printf("NULL ");
928                 }
929                 else {
930                         SHOW_STRING(iptr->sx.val.stringconst);
931                 }
932                 SHOW_DST(iptr);
933                 break;
934
935         case ICMD_AASTORECONST:
936                 SHOW_S1(iptr);
937                 SHOW_S2(iptr);
938                 printf("%p ", (void*) iptr->sx.s23.s3.constval);
939                 break;
940
941         case ICMD_GETFIELD:        /* 1 -> 1 */
942         case ICMD_PUTFIELD:        /* 2 -> 0 */
943         case ICMD_PUTSTATIC:       /* 1 -> 0 */
944         case ICMD_GETSTATIC:       /* 0 -> 1 */
945         case ICMD_PUTSTATICCONST:  /* 0 -> 0 */
946         case ICMD_PUTFIELDCONST:   /* 1 -> 0 */
947                 if (opcode != ICMD_GETSTATIC && opcode != ICMD_PUTSTATICCONST) {
948                         SHOW_S1(iptr);
949                         if (opcode == ICMD_PUTFIELD) {
950                                 SHOW_S2(iptr);
951                         }
952                 }
953                 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
954                 SHOW_FIELD(fmiref);
955
956                 if (opcode == ICMD_GETSTATIC || opcode == ICMD_GETFIELD) {
957                         SHOW_DST(iptr);
958                 }
959                 break;
960
961         case ICMD_IINC:
962                 SHOW_S1_LOCAL(iptr);
963                 SHOW_INT_CONST(iptr->sx.val.i);
964                 SHOW_DST_LOCAL(iptr);
965                 break;
966
967         case ICMD_IASTORE:
968         case ICMD_SASTORE:
969         case ICMD_BASTORE:
970         case ICMD_CASTORE:
971         case ICMD_LASTORE:
972         case ICMD_DASTORE:
973         case ICMD_FASTORE:
974         case ICMD_AASTORE:
975                 SHOW_S1(iptr);
976                 SHOW_S2(iptr);
977                 SHOW_S3(iptr);
978                 break;
979
980         case ICMD_IALOAD:
981         case ICMD_SALOAD:
982         case ICMD_BALOAD:
983         case ICMD_CALOAD:
984         case ICMD_LALOAD:
985         case ICMD_DALOAD:
986         case ICMD_FALOAD:
987         case ICMD_AALOAD:
988                 SHOW_S1(iptr);
989                 SHOW_S2(iptr);
990                 SHOW_DST(iptr);
991                 break;
992
993         case ICMD_RET:
994                 SHOW_S1_LOCAL(iptr);
995                 if (stage >= SHOW_STACK) {
996                         printf(" ---> L%03d", iptr->dst.block->nr);
997                 }
998                 break;
999
1000         case ICMD_ILOAD:
1001         case ICMD_LLOAD:
1002         case ICMD_FLOAD:
1003         case ICMD_DLOAD:
1004         case ICMD_ALOAD:
1005                 SHOW_S1_LOCAL(iptr);
1006                 SHOW_DST(iptr);
1007                 break;
1008
1009         case ICMD_ISTORE:
1010         case ICMD_LSTORE:
1011         case ICMD_FSTORE:
1012         case ICMD_DSTORE:
1013         case ICMD_ASTORE:
1014                 SHOW_S1(iptr);
1015                 SHOW_DST_LOCAL(iptr);
1016                 break;
1017
1018         case ICMD_NEW:
1019                 SHOW_DST(iptr);
1020                 break;
1021
1022         case ICMD_NEWARRAY:
1023                 SHOW_DST(iptr);
1024                 break;
1025
1026         case ICMD_ANEWARRAY:
1027                 SHOW_DST(iptr);
1028                 break;
1029
1030         case ICMD_MULTIANEWARRAY:
1031                 if (stage >= SHOW_STACK) {
1032                         argp = iptr->sx.s23.s2.args;
1033                         i = iptr->s1.argcount;
1034                         while (i--) {
1035                                 SHOW_VARIABLE(*(argp++));
1036                         }
1037                 }
1038                 else {
1039                         printf("argcount=%d ", iptr->s1.argcount);
1040                 }
1041                 SHOW_DST(iptr);
1042                 break;
1043
1044         case ICMD_CHECKCAST:
1045                 SHOW_S1(iptr);
1046                 putchar(' ');
1047                 class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
1048                 SHOW_DST(iptr);
1049                 break;
1050
1051         case ICMD_INSTANCEOF:
1052                 SHOW_S1(iptr);
1053                 SHOW_DST(iptr);
1054                 break;
1055
1056         case ICMD_INLINE_START:
1057         case ICMD_INLINE_END:
1058                 break;
1059
1060         case ICMD_BUILTIN:
1061                 if (stage >= SHOW_STACK) {
1062                         argp = iptr->sx.s23.s2.args;
1063                         i = iptr->s1.argcount;
1064                         while (i--) {
1065                                 if ((iptr->s1.argcount - 1 - i) == iptr->sx.s23.s3.bte->md->paramcount)
1066                                         printf(" pass-through: ");
1067                                 SHOW_VARIABLE(*(argp++));
1068                         }
1069                 }
1070                 printf("%s ", iptr->sx.s23.s3.bte->cname);
1071                 if (iptr->sx.s23.s3.bte->md->returntype.type != TYPE_VOID) {
1072                         SHOW_DST(iptr);
1073                 }
1074                 break;
1075
1076         case ICMD_INVOKEVIRTUAL:
1077         case ICMD_INVOKESPECIAL:
1078         case ICMD_INVOKESTATIC:
1079         case ICMD_INVOKEINTERFACE:
1080                 if (stage >= SHOW_STACK) {
1081                         methoddesc *md;
1082                         INSTRUCTION_GET_METHODDESC(iptr, md);
1083                         argp = iptr->sx.s23.s2.args;
1084                         i = iptr->s1.argcount;
1085                         while (i--) {
1086                                 if ((iptr->s1.argcount - 1 - i) == md->paramcount)
1087                                         printf(" pass-through: ");
1088                                 SHOW_VARIABLE(*(argp++));
1089                         }
1090                 }
1091                 INSTRUCTION_GET_METHODREF(iptr, fmiref);
1092                 method_methodref_print(fmiref);
1093                 if (fmiref->parseddesc.md->returntype.type != TYPE_VOID) {
1094                         putchar(' ');
1095                         SHOW_DST(iptr);
1096                 }
1097                 break;
1098
1099         case ICMD_IFEQ:
1100         case ICMD_IFNE:
1101         case ICMD_IFLT:
1102         case ICMD_IFGE:
1103         case ICMD_IFGT:
1104         case ICMD_IFLE:
1105                 SHOW_S1(iptr);
1106                 SHOW_TARGET(iptr->dst);
1107                 break;
1108
1109         case ICMD_IF_LEQ:
1110         case ICMD_IF_LNE:
1111         case ICMD_IF_LLT:
1112         case ICMD_IF_LGE:
1113         case ICMD_IF_LGT:
1114         case ICMD_IF_LLE:
1115                 SHOW_S1(iptr);
1116                 SHOW_TARGET(iptr->dst);
1117                 break;
1118
1119         case ICMD_GOTO:
1120         case ICMD_INLINE_GOTO:
1121                 SHOW_TARGET(iptr->dst);
1122                 break;
1123
1124         case ICMD_JSR:
1125                 SHOW_TARGET(iptr->sx.s23.s3.jsrtarget);
1126                 SHOW_DST(iptr);
1127                 break;
1128
1129         case ICMD_IFNULL:
1130         case ICMD_IFNONNULL:
1131                 SHOW_S1(iptr);
1132                 SHOW_TARGET(iptr->dst);
1133                 break;
1134
1135         case ICMD_IF_ICMPEQ:
1136         case ICMD_IF_ICMPNE:
1137         case ICMD_IF_ICMPLT:
1138         case ICMD_IF_ICMPGE:
1139         case ICMD_IF_ICMPGT:
1140         case ICMD_IF_ICMPLE:
1141
1142         case ICMD_IF_LCMPEQ:
1143         case ICMD_IF_LCMPNE:
1144         case ICMD_IF_LCMPLT:
1145         case ICMD_IF_LCMPGE:
1146         case ICMD_IF_LCMPGT:
1147         case ICMD_IF_LCMPLE:
1148
1149         case ICMD_IF_FCMPEQ:
1150         case ICMD_IF_FCMPNE:
1151
1152         case ICMD_IF_FCMPL_LT:
1153         case ICMD_IF_FCMPL_GE:
1154         case ICMD_IF_FCMPL_GT:
1155         case ICMD_IF_FCMPL_LE:
1156
1157         case ICMD_IF_FCMPG_LT:
1158         case ICMD_IF_FCMPG_GE:
1159         case ICMD_IF_FCMPG_GT:
1160         case ICMD_IF_FCMPG_LE:
1161
1162         case ICMD_IF_DCMPEQ:
1163         case ICMD_IF_DCMPNE:
1164
1165         case ICMD_IF_DCMPL_LT:
1166         case ICMD_IF_DCMPL_GE:
1167         case ICMD_IF_DCMPL_GT:
1168         case ICMD_IF_DCMPL_LE:
1169
1170         case ICMD_IF_DCMPG_LT:
1171         case ICMD_IF_DCMPG_GE:
1172         case ICMD_IF_DCMPG_GT:
1173         case ICMD_IF_DCMPG_LE:
1174
1175         case ICMD_IF_ACMPEQ:
1176         case ICMD_IF_ACMPNE:
1177                 SHOW_S1(iptr);
1178                 SHOW_S2(iptr);
1179                 SHOW_TARGET(iptr->dst);
1180                 break;
1181
1182         case ICMD_TABLESWITCH:
1183                 SHOW_S1(iptr);
1184                 table = iptr->dst.table;
1185
1186                 i = iptr->sx.s23.s3.tablehigh
1187                         - iptr->sx.s23.s2.tablelow + 1;
1188
1189                 printf("high=%d low=%d count=%d\n", iptr->sx.s23.s3.tablehigh, iptr->sx.s23.s2.tablelow, i);
1190                 while (--i >= 0) {
1191                         printf("\t\t%d --> ", table - iptr->dst.table);
1192                         if (stage >= SHOW_STACK) {
1193                                 printf("L%03d\n", table->block->nr);
1194                         }
1195                         else {
1196                                 printf("insindex %d (L%03d)\n", table->insindex, BLOCK_OF(table->insindex)->nr);
1197                         }
1198                         table++;
1199                 }
1200
1201                 break;
1202
1203         case ICMD_LOOKUPSWITCH:
1204                 SHOW_S1(iptr);
1205
1206                 printf("count=%d, default=", iptr->sx.s23.s2.lookupcount);
1207                 if (stage >= SHOW_STACK) {
1208                         printf("L%03d\n", iptr->sx.s23.s3.lookupdefault.block->nr);
1209                 }
1210                 else {
1211                         printf("insindex %d (L%03d)\n", iptr->sx.s23.s3.lookupdefault.insindex, BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->nr);
1212                 }
1213
1214                 lookup = iptr->dst.lookup;
1215                 i = iptr->sx.s23.s2.lookupcount;
1216                 while (--i >= 0) {
1217                         printf("\t\t%d --> ", lookup->value);
1218                         if (stage >= SHOW_STACK) {
1219                                 printf("L%03d\n", lookup->target.block->nr);
1220                         }
1221                         else {
1222                                 printf("insindex %d (L%03d)\n", lookup->target.insindex, BLOCK_OF(lookup->target.insindex)->nr);
1223                         }
1224                         lookup++;
1225                 }
1226                 break;
1227
1228         case ICMD_ARETURN:
1229                 SHOW_S1(iptr);
1230                 break;
1231
1232         case ICMD_ATHROW:
1233                 SHOW_S1(iptr);
1234                 break;
1235
1236         case ICMD_COPY:
1237         case ICMD_MOVE:
1238                 SHOW_S1(iptr);
1239                 SHOW_DST(iptr);
1240                 break;
1241         }
1242         fflush(stdout);
1243 }
1244 #endif /* !defined(NDEBUG) */
1245
1246
1247 /*
1248  * These are local overrides for various environment variables in Emacs.
1249  * Please do not remove this and leave it at the end of the file, where
1250  * Emacs will automagically detect them.
1251  * ---------------------------------------------------------------------
1252  * Local variables:
1253  * mode: c
1254  * indent-tabs-mode: t
1255  * c-basic-offset: 4
1256  * tab-width: 4
1257  * End:
1258  * vim:noexpandtab:sw=4:ts=4:
1259  */