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