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