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