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