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