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