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