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