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