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