70aca732c3b71d20ee666ca726bc7fd559333675
[cacao.git] / jit / stack.c
1 /* jit/stack.c - stack analysis
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    Changes: Edwin Steiner
30
31    $Id: stack.c 1095 2004-05-27 15:54:42Z twisti $
32
33 */
34
35
36 #include <stdio.h>
37 #include <string.h>
38 #include "stack.h"
39 #include "global.h"
40 #include "main.h"
41 #include "native.h"
42 #include "jit.h"
43 #include "builtin.h"
44 #include "disass.h"
45 #include "reg.h"
46 #include "tables.h"
47 #include "types.h"
48 #include "toolbox/logging.h"
49 #include "toolbox/memory.h"
50
51
52 /* from codegen.inc */
53 extern int dseglen;
54
55 /**********************************************************************/
56 /* Macros used internally by analyse_stack                            */
57 /**********************************************************************/
58
59 #ifdef STATISTICS
60 #define COUNT(cnt) cnt++
61 #else
62 #define COUNT(cnt)
63 #endif
64  
65 /* convenient abbreviations */
66 #define CURKIND    curstack->varkind
67 #define CURTYPE    curstack->type
68
69 /*--------------------------------------------------*/
70 /* SIGNALING ERRORS                                 */
71 /*--------------------------------------------------*/
72
73 #define TYPEPANIC  {show_icmd_method();panic("Stack type mismatch");}
74
75
76 /*--------------------------------------------------*/
77 /* STACK UNDERFLOW/OVERFLOW CHECKS                  */
78 /*--------------------------------------------------*/
79
80 /* underflow checks */
81
82 #define REQUIRE(num) \
83     do { \
84         if (stackdepth < (num)) { \
85             sprintf(msg, "(class: "); \
86             utf_sprint(msg + strlen(msg), m->class->name); \
87             sprintf(msg + strlen(msg), ", method: "); \
88             utf_sprint(msg + strlen(msg), m->name); \
89             sprintf(msg + strlen(msg), ", signature: "); \
90             utf_sprint(msg + strlen(msg), m->descriptor); \
91             sprintf(msg + strlen(msg), ") Unable to pop operand off an empty stack"); \
92             *exceptionptr = \
93                 new_exception_message(string_java_lang_VerifyError, msg); \
94             return NULL; \
95         } \
96     } while(0)
97
98 #define REQUIRE_1     REQUIRE(1)
99 #define REQUIRE_2     REQUIRE(2)
100 #define REQUIRE_3     REQUIRE(3)
101 #define REQUIRE_4     REQUIRE(4)
102
103
104 /* overflow check */
105 /* We allow ACONST instructions inserted as arguments to builtin
106  * functions to exceed the maximum stack depth.  Maybe we should check
107  * against maximum stack depth only at block boundaries?
108  */
109
110 #define CHECKOVERFLOW \
111         do { \
112                 if (stackdepth > maxstack) { \
113                         if (iptr[0].opc != ICMD_ACONST \
114                 || iptr[0].op1 == 0) { \
115                 sprintf(msg, "(class: "); \
116                 utf_sprint_classname(msg + strlen(msg), m->class->name); \
117                 sprintf(msg + strlen(msg), ", method: "); \
118                 utf_sprint(msg + strlen(msg), m->name); \
119                 sprintf(msg + strlen(msg), ", signature: "); \
120                 utf_sprint(msg + strlen(msg), m->descriptor); \
121                 sprintf(msg + strlen(msg), ") Stack size too large"); \
122                 *exceptionptr = \
123                     new_exception_message(string_java_lang_VerifyError, msg); \
124                 return NULL; \
125             } \
126                 } \
127         } while(0)
128
129
130 /*--------------------------------------------------*/
131 /* ALLOCATING STACK SLOTS                           */
132 /*--------------------------------------------------*/
133
134 #define NEWSTACK(s,v,n) {new->prev=curstack;new->type=s;new->flags=0;   \
135                         new->varkind=v;new->varnum=n;curstack=new;new++;}
136 #define NEWSTACKn(s,n)  NEWSTACK(s,UNDEFVAR,n)
137 #define NEWSTACK0(s)    NEWSTACK(s,UNDEFVAR,0)
138
139 /* allocate the input stack for an exception handler */
140 #define NEWXSTACK   {NEWSTACK(TYPE_ADR,STACKVAR,0);curstack=0;}
141
142
143 /*--------------------------------------------------*/
144 /* STACK MANIPULATION                               */
145 /*--------------------------------------------------*/
146
147 /* resetting to an empty operand stack */
148 #define STACKRESET {curstack=0;stackdepth=0;}
149
150 /* set the output stack of the current instruction */
151 #define SETDST      {iptr->dst=curstack;}
152
153 /* The following macros do NOT check stackdepth, set stackdepth or iptr->dst */
154 #define POP(s)      {if(s!=curstack->type){TYPEPANIC;}                                                                          \
155                      if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;\
156                      curstack=curstack->prev;}
157 #define POPANY      {if(curstack->varkind==UNDEFVAR)curstack->varkind=TEMPVAR;  \
158                      curstack=curstack->prev;}
159 #define COPY(s,d)   {(d)->flags=0;(d)->type=(s)->type;\
160                      (d)->varkind=(s)->varkind;(d)->varnum=(s)->varnum;}
161
162
163 /*--------------------------------------------------*/
164 /* STACK OPERATIONS MODELING                        */
165 /*--------------------------------------------------*/
166
167 /* The following macros are used to model the stack manipulations of
168  * different kinds of instructions.
169  *
170  * These macros check the input stackdepth and they set the output
171  * stackdepth and the output stack of the instruction (iptr->dst).
172  *
173  * These macros do *not* check for stack overflows!
174  */
175    
176 #define PUSHCONST(s){NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
177 #define LOAD(s,v,n) {NEWSTACK(s,v,n);SETDST;stackdepth++;}
178 #define STORE(s)    {REQUIRE_1;POP(s);SETDST;stackdepth--;}
179 #define OP1_0(s)    {REQUIRE_1;POP(s);SETDST;stackdepth--;}
180 #define OP1_0ANY    {REQUIRE_1;POPANY;SETDST;stackdepth--;}
181 #define OP0_1(s)    {NEWSTACKn(s,stackdepth);SETDST;stackdepth++;}
182 #define OP1_1(s,d)  {REQUIRE_1;POP(s);NEWSTACKn(d,stackdepth-1);SETDST;}
183 #define OP2_0(s)    {REQUIRE_2;POP(s);POP(s);SETDST;stackdepth-=2;}
184 #define OPTT2_0(t,b){REQUIRE_2;POP(t);POP(b);SETDST;stackdepth-=2;}
185 #define OP2_1(s)    {REQUIRE_2;POP(s);POP(s);NEWSTACKn(s,stackdepth-2);SETDST;stackdepth--;}
186 #define OP2IAT_1(s) {REQUIRE_2;POP(TYPE_INT);POP(TYPE_ADR);NEWSTACKn(s,stackdepth-2);\
187                      SETDST;stackdepth--;}
188 #define OP2IT_1(s)  {REQUIRE_2;POP(TYPE_INT);POP(s);NEWSTACKn(s,stackdepth-2);\
189                      SETDST;stackdepth--;}
190 #define OPTT2_1(s,d){REQUIRE_2;POP(s);POP(s);NEWSTACKn(d,stackdepth-2);SETDST;stackdepth--;}
191 #define OP2_2(s)    {REQUIRE_2;POP(s);POP(s);NEWSTACKn(s,stackdepth-2);\
192                      NEWSTACKn(s,stackdepth-1);SETDST;}
193 #define OP3TIA_0(s) {REQUIRE_3;POP(s);POP(TYPE_INT);POP(TYPE_ADR);SETDST;stackdepth-=3;}
194 #define OP3_0(s)    {REQUIRE_3;POP(s);POP(s);POP(s);SETDST;stackdepth-=3;}
195 #define POPMANY(i)  {REQUIRE(i);stackdepth-=i;while(--i>=0){POPANY;}SETDST;}
196 #define DUP         {REQUIRE_1;NEWSTACK(CURTYPE,CURKIND,curstack->varnum);SETDST; \
197                     stackdepth++;}
198 #define SWAP        {REQUIRE_2;COPY(curstack,new);POPANY;COPY(curstack,new+1);POPANY;\
199                     new[0].prev=curstack;new[1].prev=new;\
200                     curstack=new+1;new+=2;SETDST;}
201 #define DUP_X1      {REQUIRE_2;COPY(curstack,new);COPY(curstack,new+2);POPANY;\
202                     COPY(curstack,new+1);POPANY;new[0].prev=curstack;\
203                     new[1].prev=new;new[2].prev=new+1;\
204                     curstack=new+2;new+=3;SETDST;stackdepth++;}
205 #define DUP2_X1     {REQUIRE_3;COPY(curstack,new+1);COPY(curstack,new+4);POPANY;\
206                     COPY(curstack,new);COPY(curstack,new+3);POPANY;\
207                     COPY(curstack,new+2);POPANY;new[0].prev=curstack;\
208                     new[1].prev=new;new[2].prev=new+1;\
209                     new[3].prev=new+2;new[4].prev=new+3;\
210                     curstack=new+4;new+=5;SETDST;stackdepth+=2;}
211 #define DUP_X2      {REQUIRE_3;COPY(curstack,new);COPY(curstack,new+3);POPANY;\
212                     COPY(curstack,new+2);POPANY;COPY(curstack,new+1);POPANY;\
213                     new[0].prev=curstack;new[1].prev=new;\
214                     new[2].prev=new+1;new[3].prev=new+2;\
215                     curstack=new+3;new+=4;SETDST;stackdepth++;}
216 #define DUP2_X2     {REQUIRE_4;COPY(curstack,new+1);COPY(curstack,new+5);POPANY;\
217                     COPY(curstack,new);COPY(curstack,new+4);POPANY;\
218                     COPY(curstack,new+3);POPANY;COPY(curstack,new+2);POPANY;\
219                     new[0].prev=curstack;new[1].prev=new;\
220                     new[2].prev=new+1;new[3].prev=new+2;\
221                     new[4].prev=new+3;new[5].prev=new+4;\
222                     curstack=new+5;new+=6;SETDST;stackdepth+=2;}
223
224
225 /*--------------------------------------------------*/
226 /* MACROS FOR HANDLING BASIC BLOCKS                 */
227 /*--------------------------------------------------*/
228
229 /* COPYCURSTACK makes a copy of the current operand stack (curstack)
230  * and returns it in the variable copy.
231  *
232  * This macro is used to propagate the operand stack from one basic
233  * block to another. The destination block receives the copy as its
234  * input stack.
235  */
236 #define COPYCURSTACK(copy) {\
237         int d;\
238         stackptr s;\
239         if(curstack){\
240                 s=curstack;\
241                 new+=stackdepth;\
242                 d=stackdepth;\
243                 copy=new;\
244                 while(s){\
245                         copy--;d--;\
246                         copy->prev=copy-1;\
247                         copy->type=s->type;\
248                         copy->flags=0;\
249                         copy->varkind=STACKVAR;\
250                         copy->varnum=d;\
251                         s=s->prev;\
252                         }\
253                 copy->prev=NULL;\
254                 copy=new-1;\
255                 }\
256         else\
257                 copy=NULL;\
258 }
259
260 /* BBEND is called at the end of each basic block (after the last
261  * instruction of the block has been processed).
262  */
263
264 #define BBEND(s,i){ \
265         i = stackdepth - 1; \
266         copy = s; \
267         while (copy) { \
268                 if ((copy->varkind == STACKVAR) && (copy->varnum > i)) \
269                         copy->varkind = TEMPVAR; \
270                 else { \
271                         copy->varkind = STACKVAR; \
272                         copy->varnum = i;\
273                 } \
274                 interfaces[i][copy->type].type = copy->type; \
275                 interfaces[i][copy->type].flags |= copy->flags; \
276                 i--; copy = copy->prev; \
277         } \
278         i = bptr->indepth - 1; \
279         copy = bptr->instack; \
280         while (copy) { \
281                 interfaces[i][copy->type].type = copy->type; \
282                 if (copy->varkind == STACKVAR) { \
283                         if (copy->flags & SAVEDVAR) \
284                                 interfaces[i][copy->type].flags |= SAVEDVAR; \
285                 } \
286                 i--; copy = copy->prev; \
287         } \
288 }
289
290
291 /* MARKREACHED marks the destination block <b> as reached. If this
292  * block has been reached before we check if stack depth and types
293  * match. Otherwise the destination block receives a copy of the
294  * current stack as its input stack.
295  *
296  * b...destination block
297  * c...current stack
298  */
299 #define MARKREACHED(b,c) {                                                                                              \
300         if(b->flags<0)                                                                                                          \
301                 {COPYCURSTACK(c);b->flags=0;b->instack=c;b->indepth=stackdepth;} \
302         else {stackptr s=curstack;stackptr t=b->instack;                                        \
303                 if(b->indepth!=stackdepth)                                                                              \
304                         {show_icmd_method();panic("Stack depth mismatch");}                     \
305                 while(s){if (s->type!=t->type)                                                                  \
306                                 TYPEPANIC                                                                                               \
307                         s=s->prev;t=t->prev;                                                                            \
308                         }                                                                                                                       \
309                 }                                                                                                                               \
310 }
311
312
313 /**********************************************************************/
314 /* analyse_stack                                                      */
315 /**********************************************************************/
316
317 /* analyse_stack uses the intermediate code created by parse.c to
318  * build a model of the JVM operand stack for the current method.
319  *
320  * The following checks are performed:
321  *   - check for operand stack underflow (before each instruction)
322  *   - check for operand stack overflow (after[1] each instruction)
323  *   - check for matching stack depth at merging points
324  *   - check for matching basic types[2] at merging points
325  *   - check basic types for instruction input (except for BUILTIN*
326  *         opcodes, INVOKE* opcodes and MULTIANEWARRAY)
327  *
328  * [1]) Checking this after the instruction should be ok. parse.c
329  * counts the number of required stack slots in such a way that it is
330  * only vital that we don't exceed `maxstack` at basic block
331  * boundaries.
332  *
333  * [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
334  * DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
335  * types are not discerned.
336  */
337
338 methodinfo *analyse_stack(methodinfo *m)
339 {
340         int b_count;
341         int b_index;
342         int stackdepth;
343         stackptr curstack;
344         stackptr new;
345         stackptr copy;
346         int opcode, i, len, loops;
347         int superblockend, repeat, deadcode;
348         instruction *iptr;
349         basicblock *bptr;
350         basicblock *tbptr;
351         s4 *s4ptr;
352         void* *tptr;
353         int *argren;
354         char msg[MAXLOGTEXT];               /* maybe we get an exception          */
355
356         argren = DMNEW(int, maxlocals);
357         /*int *argren = (int *)alloca(maxlocals * sizeof(int));*/ /* table for argument renaming */
358         for (i = 0; i < maxlocals; i++)
359                 argren[i] = i;
360         
361         arguments_num = 0;
362         new = stack;
363         loops = 0;
364         block[0].flags = BBREACHED;
365         block[0].instack = 0;
366         block[0].indepth = 0;
367
368         for (i = 0; i < exceptiontablelength; i++) {
369                 bptr = &block[block_index[extable[i].handlerpc]];
370                 bptr->flags = BBREACHED;
371                 bptr->type = BBTYPE_EXH;
372                 bptr->instack = new;
373                 bptr->indepth = 1;
374                 bptr->pre_count = 10000;
375                 STACKRESET;
376                 NEWXSTACK;
377         }
378
379 #ifdef CONDITIONAL_LOADCONST
380         b_count = block_count;
381         bptr = block;
382         while (--b_count >= 0) {
383                 if (bptr->icount != 0) {
384                         iptr = bptr->iinstr + bptr->icount - 1;
385                         switch (iptr->opc) {
386                         case ICMD_RET:
387                         case ICMD_RETURN:
388                         case ICMD_IRETURN:
389                         case ICMD_LRETURN:
390                         case ICMD_FRETURN:
391                         case ICMD_DRETURN:
392                         case ICMD_ARETURN:
393                         case ICMD_ATHROW:
394                                 break;
395
396                         case ICMD_IFEQ:
397                         case ICMD_IFNE:
398                         case ICMD_IFLT:
399                         case ICMD_IFGE:
400                         case ICMD_IFGT:
401                         case ICMD_IFLE:
402
403                         case ICMD_IFNULL:
404                         case ICMD_IFNONNULL:
405
406                         case ICMD_IF_ICMPEQ:
407                         case ICMD_IF_ICMPNE:
408                         case ICMD_IF_ICMPLT:
409                         case ICMD_IF_ICMPGE:
410                         case ICMD_IF_ICMPGT:
411                         case ICMD_IF_ICMPLE:
412
413                         case ICMD_IF_ACMPEQ:
414                         case ICMD_IF_ACMPNE:
415                                 bptr[1].pre_count++;
416                         case ICMD_GOTO:
417                                 block[block_index[iptr->op1]].pre_count++;
418                                 break;
419
420                         case ICMD_TABLESWITCH:
421                                 s4ptr = iptr->val.a;
422                                 block[block_index[*s4ptr++]].pre_count++;   /* default */
423                                 i = *s4ptr++;                               /* low     */
424                                 i = *s4ptr++ - i + 1;                       /* high    */
425                                 while (--i >= 0) {
426                                         block[block_index[*s4ptr++]].pre_count++;
427                                 }
428                                 break;
429                                         
430                         case ICMD_LOOKUPSWITCH:
431                                 s4ptr = iptr->val.a;
432                                 block[block_index[*s4ptr++]].pre_count++;   /* default */
433                                 i = *s4ptr++;                               /* count   */
434                                 while (--i >= 0) {
435                                         block[block_index[s4ptr[1]]].pre_count++;
436                                         s4ptr += 2;
437                                 }
438                                 break;
439                         default:
440                                 bptr[1].pre_count++;
441                                 break;
442                         }
443                 }
444                 bptr++;
445         }
446 #endif
447
448
449         do {
450                 loops++;
451                 b_count = block_count;
452                 bptr = block;
453                 superblockend = true;
454                 repeat = false;
455                 STACKRESET;
456                 deadcode = true;
457                 while (--b_count >= 0) {
458                         if (bptr->flags == BBDELETED) {
459                                 /* do nothing */
460                         }
461                         else if (superblockend && (bptr->flags < BBREACHED))
462                                 repeat = true;
463                         else if (bptr->flags <= BBREACHED) {
464                                 if (superblockend)
465                                         stackdepth = bptr->indepth;
466                                 else if (bptr->flags < BBREACHED) {
467                                         COPYCURSTACK(copy);
468                                         bptr->instack = copy;
469                                         bptr->indepth = stackdepth;
470                                 }
471                                 else if (bptr->indepth != stackdepth) {
472                                         show_icmd_method();
473                                         panic("Stack depth mismatch");
474                                         
475                                 }
476                                 curstack = bptr->instack;
477                                 deadcode = false;
478                                 superblockend = false;
479                                 bptr->flags = BBFINISHED;
480                                 len = bptr->icount;
481                                 iptr = bptr->iinstr;
482                                 b_index = bptr - block;
483                                 while (--len >= 0)  {
484                                         opcode = iptr->opc;
485                                         iptr->target = NULL;
486
487 /*                                      dolog("p: %04d op: %s stack: %p", iptr - instr, icmd_names[opcode], curstack); */
488
489 #ifdef USEBUILTINTABLE
490                                         {
491 #if 0
492                                                 stdopdescriptor *breplace;
493                                                 breplace = find_builtin(opcode);
494
495                                                 if (breplace && opcode == breplace->opcode) {
496                                                         iptr[0].opc = breplace->icmd;
497                                                         iptr[0].op1 = breplace->type_d;
498                                                         iptr[0].val.a = breplace->builtin;
499                                                         isleafmethod = false;
500                                                         switch (breplace->icmd) {
501                                                         case ICMD_BUILTIN1:
502                                                                 goto builtin1;
503                                                         case ICMD_BUILTIN2:
504                                                                 goto builtin2;
505                                                         }
506                                                 }
507 #endif
508                                                 builtin_descriptor *breplace;
509                                                 breplace = find_builtin(opcode);
510
511                                                 if (breplace && opcode == breplace->opcode) {
512                                                         iptr[0].opc = breplace->icmd;
513                                                         iptr[0].op1 = breplace->type_d;
514                                                         iptr[0].val.a = breplace->builtin;
515                                                         isleafmethod = false;
516                                                         switch (breplace->icmd) {
517                                                         case ICMD_BUILTIN1:
518                                                                 goto builtin1;
519                                                         case ICMD_BUILTIN2:
520                                                                 goto builtin2;
521                                                         }
522                                                 }
523                                         }
524 #endif
525                                         
526                                         switch (opcode) {
527
528                                                 /* pop 0 push 0 */
529
530                                         case ICMD_NOP:
531                                         case ICMD_CHECKASIZE:
532                                         case ICMD_CHECKEXCEPTION:
533
534                                         case ICMD_IFEQ_ICONST:
535                                         case ICMD_IFNE_ICONST:
536                                         case ICMD_IFLT_ICONST:
537                                         case ICMD_IFGE_ICONST:
538                                         case ICMD_IFGT_ICONST:
539                                         case ICMD_IFLE_ICONST:
540                                         case ICMD_ELSE_ICONST:
541                                                 SETDST;
542                                                 break;
543
544                                         case ICMD_RET:
545                                                 locals[iptr->op1][TYPE_ADR].type = TYPE_ADR;
546                                         case ICMD_RETURN:
547                                                 COUNT(count_pcmd_return);
548                                                 SETDST;
549                                                 superblockend = true;
550                                                 break;
551
552                                                 /* pop 0 push 1 const */
553                                                 
554                                         case ICMD_ICONST:
555                                                 COUNT(count_pcmd_load);
556                                                 if (len > 0) {
557                                                         switch (iptr[1].opc) {
558                                                         case ICMD_IADD:
559                                                                 iptr[0].opc = ICMD_IADDCONST;
560                                                         icmd_iconst_tail:
561                                                                 iptr[1].opc = ICMD_NOP;
562                                                                 OP1_1(TYPE_INT,TYPE_INT);
563                                                                 COUNT(count_pcmd_op);
564                                                                 break;
565                                                         case ICMD_ISUB:
566                                                                 iptr[0].opc = ICMD_ISUBCONST;
567                                                                 goto icmd_iconst_tail;
568                                                         case ICMD_IMUL:
569                                                                 iptr[0].opc = ICMD_IMULCONST;
570                                                                 goto icmd_iconst_tail;
571                                                         case ICMD_IDIV:
572                                                                 if (iptr[0].val.i == 0x00000002)
573                                                                         iptr[0].val.i = 1;
574                                                                 else if (iptr[0].val.i == 0x00000004)
575                                                                         iptr[0].val.i = 2;
576                                                                 else if (iptr[0].val.i == 0x00000008)
577                                                                         iptr[0].val.i = 3;
578                                                                 else if (iptr[0].val.i == 0x00000010)
579                                                                         iptr[0].val.i = 4;
580                                                                 else if (iptr[0].val.i == 0x00000020)
581                                                                         iptr[0].val.i = 5;
582                                                                 else if (iptr[0].val.i == 0x00000040)
583                                                                         iptr[0].val.i = 6;
584                                                                 else if (iptr[0].val.i == 0x00000080)
585                                                                         iptr[0].val.i = 7;
586                                                                 else if (iptr[0].val.i == 0x00000100)
587                                                                         iptr[0].val.i = 8;
588                                                                 else if (iptr[0].val.i == 0x00000200)
589                                                                         iptr[0].val.i = 9;
590                                                                 else if (iptr[0].val.i == 0x00000400)
591                                                                         iptr[0].val.i = 10;
592                                                                 else if (iptr[0].val.i == 0x00000800)
593                                                                         iptr[0].val.i = 11;
594                                                                 else if (iptr[0].val.i == 0x00001000)
595                                                                         iptr[0].val.i = 12;
596                                                                 else if (iptr[0].val.i == 0x00002000)
597                                                                         iptr[0].val.i = 13;
598                                                                 else if (iptr[0].val.i == 0x00004000)
599                                                                         iptr[0].val.i = 14;
600                                                                 else if (iptr[0].val.i == 0x00008000)
601                                                                         iptr[0].val.i = 15;
602                                                                 else if (iptr[0].val.i == 0x00010000)
603                                                                         iptr[0].val.i = 16;
604                                                                 else if (iptr[0].val.i == 0x00020000)
605                                                                         iptr[0].val.i = 17;
606                                                                 else if (iptr[0].val.i == 0x00040000)
607                                                                         iptr[0].val.i = 18;
608                                                                 else if (iptr[0].val.i == 0x00080000)
609                                                                         iptr[0].val.i = 19;
610                                                                 else if (iptr[0].val.i == 0x00100000)
611                                                                         iptr[0].val.i = 20;
612                                                                 else if (iptr[0].val.i == 0x00200000)
613                                                                         iptr[0].val.i = 21;
614                                                                 else if (iptr[0].val.i == 0x00400000)
615                                                                         iptr[0].val.i = 22;
616                                                                 else if (iptr[0].val.i == 0x00800000)
617                                                                         iptr[0].val.i = 23;
618                                                                 else if (iptr[0].val.i == 0x01000000)
619                                                                         iptr[0].val.i = 24;
620                                                                 else if (iptr[0].val.i == 0x02000000)
621                                                                         iptr[0].val.i = 25;
622                                                                 else if (iptr[0].val.i == 0x04000000)
623                                                                         iptr[0].val.i = 26;
624                                                                 else if (iptr[0].val.i == 0x08000000)
625                                                                         iptr[0].val.i = 27;
626                                                                 else if (iptr[0].val.i == 0x10000000)
627                                                                         iptr[0].val.i = 28;
628                                                                 else if (iptr[0].val.i == 0x20000000)
629                                                                         iptr[0].val.i = 29;
630                                                                 else if (iptr[0].val.i == 0x40000000)
631                                                                         iptr[0].val.i = 30;
632                                                                 else if (iptr[0].val.i == 0x80000000)
633                                                                         iptr[0].val.i = 31;
634                                                                 else {
635                                                                         PUSHCONST(TYPE_INT);
636                                                                         break;
637                                                                 }
638                                                                 iptr[0].opc = ICMD_IDIVPOW2;
639                                                                 goto icmd_iconst_tail;
640                                                         case ICMD_IREM:
641 #if !defined(NO_DIV_OPT)
642                                                                 if (iptr[0].val.i == 0x10001) {
643                                                                         iptr[0].opc = ICMD_IREM0X10001;
644                                                                         goto icmd_iconst_tail;
645                                                                 }
646 #endif
647                                                                 if ((iptr[0].val.i == 0x00000002) ||
648                                                                         (iptr[0].val.i == 0x00000004) ||
649                                                                         (iptr[0].val.i == 0x00000008) ||
650                                                                         (iptr[0].val.i == 0x00000010) ||
651                                                                         (iptr[0].val.i == 0x00000020) ||
652                                                                         (iptr[0].val.i == 0x00000040) ||
653                                                                         (iptr[0].val.i == 0x00000080) ||
654                                                                         (iptr[0].val.i == 0x00000100) ||
655                                                                         (iptr[0].val.i == 0x00000200) ||
656                                                                         (iptr[0].val.i == 0x00000400) ||
657                                                                         (iptr[0].val.i == 0x00000800) ||
658                                                                         (iptr[0].val.i == 0x00001000) ||
659                                                                         (iptr[0].val.i == 0x00002000) ||
660                                                                         (iptr[0].val.i == 0x00004000) ||
661                                                                         (iptr[0].val.i == 0x00008000) ||
662                                                                         (iptr[0].val.i == 0x00010000) ||
663                                                                         (iptr[0].val.i == 0x00020000) ||
664                                                                         (iptr[0].val.i == 0x00040000) ||
665                                                                         (iptr[0].val.i == 0x00080000) ||
666                                                                         (iptr[0].val.i == 0x00100000) ||
667                                                                         (iptr[0].val.i == 0x00200000) ||
668                                                                         (iptr[0].val.i == 0x00400000) ||
669                                                                         (iptr[0].val.i == 0x00800000) ||
670                                                                         (iptr[0].val.i == 0x01000000) ||
671                                                                         (iptr[0].val.i == 0x02000000) ||
672                                                                         (iptr[0].val.i == 0x04000000) ||
673                                                                         (iptr[0].val.i == 0x08000000) ||
674                                                                         (iptr[0].val.i == 0x10000000) ||
675                                                                         (iptr[0].val.i == 0x20000000) ||
676                                                                         (iptr[0].val.i == 0x40000000) ||
677                                                                         (iptr[0].val.i == 0x80000000)) {
678                                                                         iptr[0].opc = ICMD_IREMPOW2;
679                                                                         iptr[0].val.i -= 1;
680 #if defined(__I386__)
681                                                                         method_uses_ecx = true;
682 #endif
683                                                                         goto icmd_iconst_tail;
684                                                                 }
685                                                                 PUSHCONST(TYPE_INT);
686                                                                 break;
687                                                         case ICMD_IAND:
688                                                                 iptr[0].opc = ICMD_IANDCONST;
689                                                                 goto icmd_iconst_tail;
690                                                         case ICMD_IOR:
691                                                                 iptr[0].opc = ICMD_IORCONST;
692                                                                 goto icmd_iconst_tail;
693                                                         case ICMD_IXOR:
694                                                                 iptr[0].opc = ICMD_IXORCONST;
695                                                                 goto icmd_iconst_tail;
696                                                         case ICMD_ISHL:
697                                                                 iptr[0].opc = ICMD_ISHLCONST;
698                                                                 goto icmd_iconst_tail;
699                                                         case ICMD_ISHR:
700                                                                 iptr[0].opc = ICMD_ISHRCONST;
701                                                                 goto icmd_iconst_tail;
702                                                         case ICMD_IUSHR:
703                                                                 iptr[0].opc = ICMD_IUSHRCONST;
704                                                                 goto icmd_iconst_tail;
705 #if SUPPORT_LONG_SHIFT
706                                                         case ICMD_LSHL:
707                                                                 iptr[0].opc = ICMD_LSHLCONST;
708 #if defined(__I386__)
709                                                                 method_uses_ecx = true;
710 #endif
711                                                                 goto icmd_lconst_tail;
712                                                         case ICMD_LSHR:
713                                                                 iptr[0].opc = ICMD_LSHRCONST;
714 #if defined(__I386__)
715                                                                 method_uses_ecx = true;
716 #endif
717                                                                 goto icmd_lconst_tail;
718                                                         case ICMD_LUSHR:
719                                                                 iptr[0].opc = ICMD_LUSHRCONST;
720 #if defined(__I386__)
721                                                                 method_uses_ecx = true;
722 #endif
723                                                                 goto icmd_lconst_tail;
724 #endif
725                                                         case ICMD_IF_ICMPEQ:
726                                                                 iptr[0].opc = ICMD_IFEQ;
727                                                         icmd_if_icmp_tail:
728                                                                 iptr[0].op1 = iptr[1].op1;
729                                                                 bptr->icount--;
730                                                                 len--;
731                                                                 /* iptr[1].opc = ICMD_NOP; */
732                                                                 OP1_0(TYPE_INT);
733                                                                 tbptr = block + block_index[iptr->op1];
734
735                                                                 iptr[0].target = (void *) tbptr;
736
737                                                                 MARKREACHED(tbptr, copy);
738                                                                 COUNT(count_pcmd_bra);
739                                                                 break;
740                                                         case ICMD_IF_ICMPLT:
741                                                                 iptr[0].opc = ICMD_IFLT;
742                                                                 goto icmd_if_icmp_tail;
743                                                         case ICMD_IF_ICMPLE:
744                                                                 iptr[0].opc = ICMD_IFLE;
745                                                                 goto icmd_if_icmp_tail;
746                                                         case ICMD_IF_ICMPNE:
747                                                                 iptr[0].opc = ICMD_IFNE;
748                                                                 goto icmd_if_icmp_tail;
749                                                         case ICMD_IF_ICMPGT:
750                                                                 iptr[0].opc = ICMD_IFGT;
751                                                                 goto icmd_if_icmp_tail;
752                                                         case ICMD_IF_ICMPGE:
753                                                                 iptr[0].opc = ICMD_IFGE;
754                                                                 goto icmd_if_icmp_tail;
755                                                         default:
756                                                                 PUSHCONST(TYPE_INT);
757                                                         }
758                                                 }
759                                                 else
760                                                         PUSHCONST(TYPE_INT);
761                                                 break;
762                                         case ICMD_LCONST:
763                                                 COUNT(count_pcmd_load);
764                                                 if (len > 0) {
765                                                         switch (iptr[1].opc) {
766 #if SUPPORT_LONG_ADD
767                                                         case ICMD_LADD:
768                                                                 iptr[0].opc = ICMD_LADDCONST;
769                                                         icmd_lconst_tail:
770                                                                 iptr[1].opc = ICMD_NOP;
771                                                                 OP1_1(TYPE_LNG,TYPE_LNG);
772                                                                 COUNT(count_pcmd_op);
773                                                                 break;
774                                                         case ICMD_LSUB:
775                                                                 iptr[0].opc = ICMD_LSUBCONST;
776                                                                 goto icmd_lconst_tail;
777 #endif
778 #if SUPPORT_LONG_MUL
779                                                         case ICMD_LMUL:
780                                                                 iptr[0].opc = ICMD_LMULCONST;
781 #if defined(__I386__)
782                                                                 method_uses_ecx = true;
783                                                                 method_uses_edx = true;
784 #endif
785                                                                 goto icmd_lconst_tail;
786 #endif
787 #if SUPPORT_LONG_DIV
788                                                         case ICMD_LDIV:
789                                                                 if (iptr[0].val.l == 0x00000002)
790                                                                         iptr[0].val.i = 1;
791                                                                 else if (iptr[0].val.l == 0x00000004)
792                                                                         iptr[0].val.i = 2;
793                                                                 else if (iptr[0].val.l == 0x00000008)
794                                                                         iptr[0].val.i = 3;
795                                                                 else if (iptr[0].val.l == 0x00000010)
796                                                                         iptr[0].val.i = 4;
797                                                                 else if (iptr[0].val.l == 0x00000020)
798                                                                         iptr[0].val.i = 5;
799                                                                 else if (iptr[0].val.l == 0x00000040)
800                                                                         iptr[0].val.i = 6;
801                                                                 else if (iptr[0].val.l == 0x00000080)
802                                                                         iptr[0].val.i = 7;
803                                                                 else if (iptr[0].val.l == 0x00000100)
804                                                                         iptr[0].val.i = 8;
805                                                                 else if (iptr[0].val.l == 0x00000200)
806                                                                         iptr[0].val.i = 9;
807                                                                 else if (iptr[0].val.l == 0x00000400)
808                                                                         iptr[0].val.i = 10;
809                                                                 else if (iptr[0].val.l == 0x00000800)
810                                                                         iptr[0].val.i = 11;
811                                                                 else if (iptr[0].val.l == 0x00001000)
812                                                                         iptr[0].val.i = 12;
813                                                                 else if (iptr[0].val.l == 0x00002000)
814                                                                         iptr[0].val.i = 13;
815                                                                 else if (iptr[0].val.l == 0x00004000)
816                                                                         iptr[0].val.i = 14;
817                                                                 else if (iptr[0].val.l == 0x00008000)
818                                                                         iptr[0].val.i = 15;
819                                                                 else if (iptr[0].val.l == 0x00010000)
820                                                                         iptr[0].val.i = 16;
821                                                                 else if (iptr[0].val.l == 0x00020000)
822                                                                         iptr[0].val.i = 17;
823                                                                 else if (iptr[0].val.l == 0x00040000)
824                                                                         iptr[0].val.i = 18;
825                                                                 else if (iptr[0].val.l == 0x00080000)
826                                                                         iptr[0].val.i = 19;
827                                                                 else if (iptr[0].val.l == 0x00100000)
828                                                                         iptr[0].val.i = 20;
829                                                                 else if (iptr[0].val.l == 0x00200000)
830                                                                         iptr[0].val.i = 21;
831                                                                 else if (iptr[0].val.l == 0x00400000)
832                                                                         iptr[0].val.i = 22;
833                                                                 else if (iptr[0].val.l == 0x00800000)
834                                                                         iptr[0].val.i = 23;
835                                                                 else if (iptr[0].val.l == 0x01000000)
836                                                                         iptr[0].val.i = 24;
837                                                                 else if (iptr[0].val.l == 0x02000000)
838                                                                         iptr[0].val.i = 25;
839                                                                 else if (iptr[0].val.l == 0x04000000)
840                                                                         iptr[0].val.i = 26;
841                                                                 else if (iptr[0].val.l == 0x08000000)
842                                                                         iptr[0].val.i = 27;
843                                                                 else if (iptr[0].val.l == 0x10000000)
844                                                                         iptr[0].val.i = 28;
845                                                                 else if (iptr[0].val.l == 0x20000000)
846                                                                         iptr[0].val.i = 29;
847                                                                 else if (iptr[0].val.l == 0x40000000)
848                                                                         iptr[0].val.i = 30;
849                                                                 else if (iptr[0].val.l == 0x80000000)
850                                                                         iptr[0].val.i = 31;
851                                                                 else {
852                                                                         PUSHCONST(TYPE_LNG);
853                                                                         break;
854                                                                 }
855                                                                 iptr[0].opc = ICMD_LDIVPOW2;
856 #if defined(__I386__)
857                                                                 method_uses_ecx = true;
858 #endif
859                                                                 goto icmd_lconst_tail;
860                                                         case ICMD_LREM:
861 #if !defined(NO_DIV_OPT)
862                                                                 if (iptr[0].val.l == 0x10001) {
863                                                                         iptr[0].opc = ICMD_LREM0X10001;
864                                                                         goto icmd_lconst_tail;
865                                                                 }
866 #endif
867                                                                 if ((iptr[0].val.l == 0x00000002) ||
868                                                                         (iptr[0].val.l == 0x00000004) ||
869                                                                         (iptr[0].val.l == 0x00000008) ||
870                                                                         (iptr[0].val.l == 0x00000010) ||
871                                                                         (iptr[0].val.l == 0x00000020) ||
872                                                                         (iptr[0].val.l == 0x00000040) ||
873                                                                         (iptr[0].val.l == 0x00000080) ||
874                                                                         (iptr[0].val.l == 0x00000100) ||
875                                                                         (iptr[0].val.l == 0x00000200) ||
876                                                                         (iptr[0].val.l == 0x00000400) ||
877                                                                         (iptr[0].val.l == 0x00000800) ||
878                                                                         (iptr[0].val.l == 0x00001000) ||
879                                                                         (iptr[0].val.l == 0x00002000) ||
880                                                                         (iptr[0].val.l == 0x00004000) ||
881                                                                         (iptr[0].val.l == 0x00008000) ||
882                                                                         (iptr[0].val.l == 0x00010000) ||
883                                                                         (iptr[0].val.l == 0x00020000) ||
884                                                                         (iptr[0].val.l == 0x00040000) ||
885                                                                         (iptr[0].val.l == 0x00080000) ||
886                                                                         (iptr[0].val.l == 0x00100000) ||
887                                                                         (iptr[0].val.l == 0x00200000) ||
888                                                                         (iptr[0].val.l == 0x00400000) ||
889                                                                         (iptr[0].val.l == 0x00800000) ||
890                                                                         (iptr[0].val.l == 0x01000000) ||
891                                                                         (iptr[0].val.l == 0x02000000) ||
892                                                                         (iptr[0].val.l == 0x04000000) ||
893                                                                         (iptr[0].val.l == 0x08000000) ||
894                                                                         (iptr[0].val.l == 0x10000000) ||
895                                                                         (iptr[0].val.l == 0x20000000) ||
896                                                                         (iptr[0].val.l == 0x40000000) ||
897                                                                         (iptr[0].val.l == 0x80000000)) {
898                                                                         iptr[0].opc = ICMD_LREMPOW2;
899                                                                         iptr[0].val.l -= 1;
900 #if defined(__I386__)
901                                                                         method_uses_ecx = true;
902 #endif
903                                                                         goto icmd_lconst_tail;
904                                                                 }
905                                                                 PUSHCONST(TYPE_LNG);
906                                                                 break;
907 #endif
908 #if SUPPORT_LONG_LOG
909                                                         case ICMD_LAND:
910                                                                 iptr[0].opc = ICMD_LANDCONST;
911                                                                 goto icmd_lconst_tail;
912                                                         case ICMD_LOR:
913                                                                 iptr[0].opc = ICMD_LORCONST;
914                                                                 goto icmd_lconst_tail;
915                                                         case ICMD_LXOR:
916                                                                 iptr[0].opc = ICMD_LXORCONST;
917                                                                 goto icmd_lconst_tail;
918 #endif
919 #if !defined(NOLONG_CONDITIONAL)
920                                                         case ICMD_LCMP:
921                                                                 if ((len > 1) && (iptr[2].val.i == 0)) {
922                                                                         switch (iptr[2].opc) {
923                                                                         case ICMD_IFEQ:
924                                                                                 iptr[0].opc = ICMD_IF_LEQ;
925 #if defined(__I386__)
926                                                                                 method_uses_ecx = true;
927 #endif
928                                                                         icmd_lconst_lcmp_tail:
929                                                                                 iptr[0].op1 = iptr[2].op1;
930                                                                                 bptr->icount -= 2;
931                                                                                 len -= 2;
932                                                                                 /* iptr[1].opc = ICMD_NOP;
933                                                                                    iptr[2].opc = ICMD_NOP; */
934                                                                                 OP1_0(TYPE_LNG);
935                                                                                 tbptr = block + block_index[iptr->op1];
936
937                                                                                 iptr[0].target = (void *) tbptr;
938
939                                                                                 MARKREACHED(tbptr, copy);
940                                                                                 COUNT(count_pcmd_bra);
941                                                                                 COUNT(count_pcmd_op);
942                                                                                 break;
943                                                                         case ICMD_IFNE:
944                                                                                 iptr[0].opc = ICMD_IF_LNE;
945 #if defined(__I386__)
946                                                                                 method_uses_ecx = true;
947 #endif
948                                                                                 goto icmd_lconst_lcmp_tail;
949                                                                         case ICMD_IFLT:
950                                                                                 iptr[0].opc = ICMD_IF_LLT;
951                                                                                 goto icmd_lconst_lcmp_tail;
952                                                                         case ICMD_IFGT:
953                                                                                 iptr[0].opc = ICMD_IF_LGT;
954                                                                                 goto icmd_lconst_lcmp_tail;
955                                                                         case ICMD_IFLE:
956                                                                                 iptr[0].opc = ICMD_IF_LLE;
957                                                                                 goto icmd_lconst_lcmp_tail;
958                                                                         case ICMD_IFGE:
959                                                                                 iptr[0].opc = ICMD_IF_LGE;
960                                                                                 goto icmd_lconst_lcmp_tail;
961                                                                         default:
962                                                                                 PUSHCONST(TYPE_LNG);
963                                                                         } /* switch (iptr[2].opc) */
964                                                                 } /* if (iptr[2].val.i == 0) */
965                                                                 else
966                                                                         PUSHCONST(TYPE_LNG);
967                                                                 break;
968 #endif
969                                                         default:
970                                                                 PUSHCONST(TYPE_LNG);
971                                                         }
972                                                 }
973                                                 else
974                                                         PUSHCONST(TYPE_LNG);
975                                                 break;
976                                         case ICMD_FCONST:
977                                                 COUNT(count_pcmd_load);
978                                                 PUSHCONST(TYPE_FLT);
979                                                 break;
980                                         case ICMD_DCONST:
981                                                 COUNT(count_pcmd_load);
982                                                 PUSHCONST(TYPE_DBL);
983                                                 break;
984                                         case ICMD_ACONST:
985                                                 COUNT(count_pcmd_load);
986                                                 PUSHCONST(TYPE_ADR);
987                                                 break;
988
989                                                 /* pop 0 push 1 load */
990                                                 
991                                         case ICMD_ILOAD:
992                                         case ICMD_LLOAD:
993                                         case ICMD_FLOAD:
994                                         case ICMD_DLOAD:
995                                         case ICMD_ALOAD:
996                                                 COUNT(count_load_instruction);
997                                                 i = opcode-ICMD_ILOAD;
998                                                 iptr->op1 = argren[iptr->op1];
999                                                 locals[iptr->op1][i].type = i;
1000                                                 LOAD(i, LOCALVAR, iptr->op1);
1001                                                 break;
1002
1003                                                 /* pop 2 push 1 */
1004
1005                                         case ICMD_LALOAD:
1006 #if defined(__I386__)
1007                                                 method_uses_ecx = true;
1008                                                 method_uses_edx = true;
1009 #endif
1010                                         case ICMD_IALOAD:
1011                                         case ICMD_FALOAD:
1012                                         case ICMD_DALOAD:
1013                                         case ICMD_AALOAD:
1014                                                 COUNT(count_check_null);
1015                                                 COUNT(count_check_bound);
1016                                                 COUNT(count_pcmd_mem);
1017                                                 OP2IAT_1(opcode-ICMD_IALOAD);
1018 #if defined(__I386__)
1019                                                 method_uses_ecx = true;
1020 #endif
1021                                                 break;
1022
1023                                         case ICMD_BALOAD:
1024                                         case ICMD_CALOAD:
1025                                         case ICMD_SALOAD:
1026                                                 COUNT(count_check_null);
1027                                                 COUNT(count_check_bound);
1028                                                 COUNT(count_pcmd_mem);
1029                                                 OP2IAT_1(TYPE_INT);
1030 #if defined(__I386__)
1031                                                 method_uses_ecx = true;
1032 #endif
1033                                                 break;
1034
1035                                                 /* pop 0 push 0 iinc */
1036
1037                                         case ICMD_IINC:
1038 #ifdef STATISTICS
1039                                                 i = stackdepth;
1040                                                 if (i >= 10)
1041                                                         count_store_depth[10]++;
1042                                                 else
1043                                                         count_store_depth[i]++;
1044 #endif
1045                                                 copy = curstack;
1046                                                 i = stackdepth - 1;
1047                                                 while (copy) {
1048                                                         if ((copy->varkind == LOCALVAR) &&
1049                                                                 (copy->varnum == iptr->op1)) {
1050                                                                 copy->varkind = TEMPVAR;
1051                                                                 copy->varnum = i;
1052                                                         }
1053                                                         i--;
1054                                                         copy = copy->prev;
1055                                                 }
1056                                                 SETDST;
1057                                                 break;
1058
1059                                                 /* pop 1 push 0 store */
1060
1061                                         case ICMD_ISTORE:
1062                                         case ICMD_LSTORE:
1063                                         case ICMD_FSTORE:
1064                                         case ICMD_DSTORE:
1065                                         case ICMD_ASTORE:
1066                                         icmd_store:
1067                                                 REQUIRE_1;
1068
1069                                         i = opcode - ICMD_ISTORE;
1070                                         locals[iptr->op1][i].type = i;
1071 #ifdef STATISTICS
1072                                         count_pcmd_store++;
1073                                         i = new - curstack;
1074                                         if (i >= 20)
1075                                                 count_store_length[20]++;
1076                                         else
1077                                                 count_store_length[i]++;
1078                                         i = stackdepth - 1;
1079                                         if (i >= 10)
1080                                                 count_store_depth[10]++;
1081                                         else
1082                                                 count_store_depth[i]++;
1083 #endif
1084                                         copy = curstack->prev;
1085                                         i = stackdepth - 2;
1086                                         while (copy) {
1087                                                 if ((copy->varkind == LOCALVAR) &&
1088                                                         (copy->varnum == iptr->op1)) {
1089                                                         copy->varkind = TEMPVAR;
1090                                                         copy->varnum = i;
1091                                                 }
1092                                                 i--;
1093                                                 copy = copy->prev;
1094                                         }
1095                                         if ((new - curstack) == 1) {
1096                                                 curstack->varkind = LOCALVAR;
1097                                                 curstack->varnum = iptr->op1;
1098                                         };
1099                                         STORE(opcode-ICMD_ISTORE);
1100                                         break;
1101
1102                                         /* pop 3 push 0 */
1103
1104                                         case ICMD_IASTORE:
1105                                         case ICMD_AASTORE:
1106                                         case ICMD_LASTORE:
1107 #if defined(__I386__)
1108                                                 method_uses_ecx = true;
1109                                                 method_uses_edx = true;
1110 #endif
1111                                         case ICMD_FASTORE:
1112                                         case ICMD_DASTORE:
1113                                                 COUNT(count_check_null);
1114                                                 COUNT(count_check_bound);
1115                                                 COUNT(count_pcmd_mem);
1116                                                 OP3TIA_0(opcode-ICMD_IASTORE);
1117                                                 break;
1118
1119                                         case ICMD_BASTORE:
1120                                         case ICMD_CASTORE:
1121                                         case ICMD_SASTORE:
1122                                                 COUNT(count_check_null);
1123                                                 COUNT(count_check_bound);
1124                                                 COUNT(count_pcmd_mem);
1125                                                 OP3TIA_0(TYPE_INT);
1126 #if defined(__I386__)
1127                                                 method_uses_ecx = true;
1128                                                 method_uses_edx = true;
1129 #endif
1130                                                 break;
1131
1132                                                 /* pop 1 push 0 */
1133
1134                                         case ICMD_POP:
1135 #ifdef TYPECHECK_STACK_COMPCAT
1136                                                 if (opt_verify) {
1137                                                         REQUIRE_1;
1138                                                         if (IS_2_WORD_TYPE(curstack->type))
1139                                                                 panic("Illegal instruction: POP on category 2 type");
1140                                                 }
1141 #endif
1142                                                 OP1_0ANY;
1143                                                 break;
1144
1145                                         case ICMD_IRETURN:
1146                                         case ICMD_LRETURN:
1147                                         case ICMD_FRETURN:
1148                                         case ICMD_DRETURN:
1149                                         case ICMD_ARETURN:
1150                                                 COUNT(count_pcmd_return);
1151                                                 OP1_0(opcode-ICMD_IRETURN);
1152                                                 superblockend = true;
1153                                                 break;
1154
1155                                         case ICMD_ATHROW:
1156                                                 COUNT(count_check_null);
1157                                                 OP1_0(TYPE_ADR);
1158                                                 STACKRESET;
1159                                                 SETDST;
1160                                                 superblockend = true;
1161                                                 break;
1162
1163                                         case ICMD_PUTSTATIC:
1164                                                 COUNT(count_pcmd_mem);
1165                                                 OP1_0(iptr->op1);
1166 #if defined(__I386__)
1167                                                 method_uses_ecx = true;
1168 #endif
1169                                                 break;
1170
1171                                                 /* pop 1 push 0 branch */
1172
1173                                         case ICMD_IFNULL:
1174                                         case ICMD_IFNONNULL:
1175                                                 COUNT(count_pcmd_bra);
1176                                                 OP1_0(TYPE_ADR);
1177                                                 tbptr = block + block_index[iptr->op1];
1178
1179                                                 iptr[0].target = (void *) tbptr;
1180
1181                                                 MARKREACHED(tbptr, copy);
1182                                                 break;
1183
1184                                         case ICMD_IFEQ:
1185                                         case ICMD_IFNE:
1186                                         case ICMD_IFLT:
1187                                         case ICMD_IFGE:
1188                                         case ICMD_IFGT:
1189                                         case ICMD_IFLE:
1190                                                 COUNT(count_pcmd_bra);
1191 #ifdef CONDITIONAL_LOADCONST
1192                                                 {
1193                                                         tbptr = block + b_index;
1194                                                         if ((b_count >= 3) &&
1195                                                             ((b_index + 2) == block_index[iptr[0].op1]) &&
1196                                                             (tbptr[1].pre_count == 1) &&
1197                                                             (iptr[1].opc == ICMD_ICONST) &&
1198                                                             (iptr[2].opc == ICMD_GOTO)   &&
1199                                                             ((b_index + 3) == block_index[iptr[2].op1]) &&
1200                                                             (tbptr[2].pre_count == 1) &&
1201                                                             (iptr[3].opc == ICMD_ICONST)) {
1202                                                                 OP1_1(TYPE_INT, TYPE_INT);
1203                                                                 switch (iptr[0].opc) {
1204                                                                 case ICMD_IFEQ:
1205                                                                         iptr[0].opc = ICMD_IFNE_ICONST;
1206                                                                         break;
1207                                                                 case ICMD_IFNE:
1208                                                                         iptr[0].opc = ICMD_IFEQ_ICONST;
1209                                                                         break;
1210                                                                 case ICMD_IFLT:
1211                                                                         iptr[0].opc = ICMD_IFGE_ICONST;
1212                                                                         break;
1213                                                                 case ICMD_IFGE:
1214                                                                         iptr[0].opc = ICMD_IFLT_ICONST;
1215                                                                         break;
1216                                                                 case ICMD_IFGT:
1217                                                                         iptr[0].opc = ICMD_IFLE_ICONST;
1218                                                                         break;
1219                                                                 case ICMD_IFLE:
1220                                                                         iptr[0].opc = ICMD_IFGT_ICONST;
1221                                                                         break;
1222                                                                 }
1223                                                                 iptr[0].val.i = iptr[1].val.i;
1224                                                                 iptr[1].opc = ICMD_ELSE_ICONST;
1225                                                                 iptr[1].val.i = iptr[3].val.i;
1226                                                                 iptr[2].opc = ICMD_NOP;
1227                                                                 iptr[3].opc = ICMD_NOP;
1228                                                                 tbptr[1].flags = BBDELETED;
1229                                                                 tbptr[2].flags = BBDELETED;
1230                                                                 tbptr[1].icount = 0;
1231                                                                 tbptr[2].icount = 0;
1232                                                                 if (tbptr[3].pre_count == 2) {
1233                                                                         len += tbptr[3].icount + 3;
1234                                                                         bptr->icount += tbptr[3].icount + 3;
1235                                                                         tbptr[3].flags = BBDELETED;
1236                                                                         tbptr[3].icount = 0;
1237                                                                         b_index++;
1238                                                                 }
1239                                                                 else {
1240                                                                         bptr->icount++;
1241                                                                         len ++;
1242                                                                 }
1243                                                                 b_index += 2;
1244                                                                 break;
1245                                                         }
1246                                                 }
1247 #endif
1248                                                 OP1_0(TYPE_INT);
1249                                                 tbptr = block + block_index[iptr->op1];
1250
1251                                                 iptr[0].target = (void *) tbptr;
1252
1253                                                 MARKREACHED(tbptr, copy);
1254                                                 break;
1255
1256                                                 /* pop 0 push 0 branch */
1257
1258                                         case ICMD_GOTO:
1259                                                 COUNT(count_pcmd_bra);
1260                                                 tbptr = block + block_index[iptr->op1];
1261
1262                                                 iptr[0].target = (void *) tbptr;
1263
1264                                                 MARKREACHED(tbptr, copy);
1265                                                 SETDST;
1266                                                 superblockend = true;
1267                                                 break;
1268
1269                                                 /* pop 1 push 0 table branch */
1270
1271                                         case ICMD_TABLESWITCH:
1272                                                 COUNT(count_pcmd_table);
1273                                                 OP1_0(TYPE_INT);
1274                                                 s4ptr = iptr->val.a;
1275                                                 tbptr = block + block_index[*s4ptr++]; /* default */
1276                                                 MARKREACHED(tbptr, copy);
1277                                                 i = *s4ptr++;                          /* low     */
1278                                                 i = *s4ptr++ - i + 1;                  /* high    */
1279
1280                                                 tptr = DMNEW(void*, i+1);
1281                                                 iptr->target = (void *) tptr;
1282
1283                                                 tptr[0] = (void *) tbptr;
1284                                                 tptr++;
1285
1286                                                 while (--i >= 0) {
1287                                                         tbptr = block + block_index[*s4ptr++];
1288
1289                                                         tptr[0] = (void *) tbptr;
1290                                                         tptr++;
1291
1292                                                         MARKREACHED(tbptr, copy);
1293                                                 }
1294                                                 SETDST;
1295                                                 superblockend = true;
1296 #if defined(__I386__)
1297                                                 method_uses_ecx = true;
1298 #endif
1299                                                 break;
1300                                                         
1301                                                 /* pop 1 push 0 table branch */
1302
1303                                         case ICMD_LOOKUPSWITCH:
1304                                                 COUNT(count_pcmd_table);
1305                                                 OP1_0(TYPE_INT);
1306                                                 s4ptr = iptr->val.a;
1307                                                 tbptr = block + block_index[*s4ptr++]; /* default */
1308                                                 MARKREACHED(tbptr, copy);
1309                                                 i = *s4ptr++;                          /* count   */
1310
1311                                                 tptr = DMNEW(void*, i+1);
1312                                                 iptr->target = (void *) tptr;
1313
1314                                                 tptr[0] = (void *) tbptr;
1315                                                 tptr++;
1316
1317                                                 while (--i >= 0) {
1318                                                         tbptr = block + block_index[s4ptr[1]];
1319
1320                                                         tptr[0] = (void *) tbptr;
1321                                                         tptr++;
1322                                                                 
1323                                                         MARKREACHED(tbptr, copy);
1324                                                         s4ptr += 2;
1325                                                 }
1326                                                 SETDST;
1327                                                 superblockend = true;
1328                                                 break;
1329
1330                                         case ICMD_NULLCHECKPOP:
1331                                         case ICMD_MONITORENTER:
1332                                                 COUNT(count_check_null);
1333                                         case ICMD_MONITOREXIT:
1334                                                 OP1_0(TYPE_ADR);
1335                                                 break;
1336
1337                                                 /* pop 2 push 0 branch */
1338
1339                                         case ICMD_IF_ICMPEQ:
1340                                         case ICMD_IF_ICMPNE:
1341                                         case ICMD_IF_ICMPLT:
1342                                         case ICMD_IF_ICMPGE:
1343                                         case ICMD_IF_ICMPGT:
1344                                         case ICMD_IF_ICMPLE:
1345                                                 COUNT(count_pcmd_bra);
1346                                                 OP2_0(TYPE_INT);
1347                                                 tbptr = block + block_index[iptr->op1];
1348                                                         
1349                                                 iptr[0].target = (void *) tbptr;
1350
1351                                                 MARKREACHED(tbptr, copy);
1352                                                 break;
1353
1354                                         case ICMD_IF_ACMPEQ:
1355                                         case ICMD_IF_ACMPNE:
1356                                                 COUNT(count_pcmd_bra);
1357                                                 OP2_0(TYPE_ADR);
1358                                                 tbptr = block + block_index[iptr->op1];
1359
1360                                                 iptr[0].target = (void *) tbptr;
1361
1362                                                 MARKREACHED(tbptr, copy);
1363                                                 break;
1364
1365                                                 /* pop 2 push 0 */
1366
1367                                         case ICMD_PUTFIELD:
1368                                                 COUNT(count_check_null);
1369                                                 COUNT(count_pcmd_mem);
1370                                                 OPTT2_0(iptr->op1,TYPE_ADR);
1371 #if defined(__I386__)
1372                                                 method_uses_ecx = true;
1373 #endif
1374                                                 break;
1375
1376                                         case ICMD_POP2:
1377                                                 REQUIRE_1;
1378                                                 if (! IS_2_WORD_TYPE(curstack->type)) {
1379                                                         /* ..., cat1 */
1380 #ifdef TYPECHECK_STACK_COMPCAT
1381                                                         if (opt_verify) {
1382                                                                 REQUIRE_2;
1383                                                                 if (IS_2_WORD_TYPE(curstack->prev->type))
1384                                                                         panic("Illegal instruction: POP2 on cat2, cat1 types");
1385                                                         }
1386 #endif
1387                                                         OP1_0ANY;                /* second pop */
1388                                                 }
1389                                                 else
1390                                                         iptr->opc = ICMD_POP;
1391                                                 OP1_0ANY;
1392                                                 break;
1393
1394                                                 /* pop 0 push 1 dup */
1395                                                 
1396                                         case ICMD_DUP:
1397 #ifdef TYPECHECK_STACK_COMPCAT
1398                                                 if (opt_verify) {
1399                                                         REQUIRE_1;
1400                                                         if (IS_2_WORD_TYPE(curstack->type))
1401                                                                 panic("Illegal instruction: DUP on category 2 type");
1402                                                 }
1403 #endif
1404                                                 COUNT(count_dup_instruction);
1405                                                 DUP;
1406                                                 break;
1407
1408                                         case ICMD_DUP2:
1409                                                 REQUIRE_1;
1410                                                 if (IS_2_WORD_TYPE(curstack->type)) {
1411                                                         /* ..., cat2 */
1412                                                         iptr->opc = ICMD_DUP;
1413                                                         DUP;
1414                                                 }
1415                                                 else {
1416                                                         REQUIRE_2;
1417                                                         /* ..., ????, cat1 */
1418 #ifdef TYPECHECK_STACK_COMPCAT
1419                                                         if (opt_verify) {
1420                                                                 if (IS_2_WORD_TYPE(curstack->prev->type))
1421                                                                         panic("Illegal instruction: DUP2 on cat2, cat1 types");
1422                                                         }
1423 #endif
1424                                                         copy = curstack;
1425                                                         NEWSTACK(copy->prev->type, copy->prev->varkind,
1426                                                                          copy->prev->varnum);
1427                                                         NEWSTACK(copy->type, copy->varkind,
1428                                                                          copy->varnum);
1429                                                         SETDST;
1430                                                         stackdepth+=2;
1431                                                 }
1432                                                 break;
1433
1434                                                 /* pop 2 push 3 dup */
1435                                                 
1436                                         case ICMD_DUP_X1:
1437 #ifdef TYPECHECK_STACK_COMPCAT
1438                                                 if (opt_verify) {
1439                                                         REQUIRE_2;
1440                                                         if (IS_2_WORD_TYPE(curstack->type) ||
1441                                                                 IS_2_WORD_TYPE(curstack->prev->type))
1442                                                                 panic("Illegal instruction: DUP_X1 on cat 2 type");
1443                                                 }
1444 #endif
1445                                                 DUP_X1;
1446                                                 break;
1447
1448                                         case ICMD_DUP2_X1:
1449                                                 REQUIRE_2;
1450                                                 if (IS_2_WORD_TYPE(curstack->type)) {
1451                                                         /* ..., ????, cat2 */
1452 #ifdef TYPECHECK_STACK_COMPCAT
1453                                                         if (opt_verify) {
1454                                                                 if (IS_2_WORD_TYPE(curstack->prev->type))
1455                                                                         panic("Illegal instruction: DUP2_X1 on cat2, cat2 types");
1456                                                         }
1457 #endif
1458                                                         iptr->opc = ICMD_DUP_X1;
1459                                                         DUP_X1;
1460                                                 }
1461                                                 else {
1462                                                         /* ..., ????, cat1 */
1463 #ifdef TYPECHECK_STACK_COMPCAT
1464                                                         if (opt_verify) {
1465                                                                 REQUIRE_3;
1466                                                                 if (IS_2_WORD_TYPE(curstack->prev->type)
1467                                                                         || IS_2_WORD_TYPE(curstack->prev->prev->type))
1468                                                                         panic("Illegal instruction: DUP2_X1 on invalid types");
1469                                                         }
1470 #endif
1471                                                         DUP2_X1;
1472                                                 }
1473                                                 break;
1474
1475                                                 /* pop 3 push 4 dup */
1476                                                 
1477                                         case ICMD_DUP_X2:
1478                                                 REQUIRE_2;
1479                                                 if (IS_2_WORD_TYPE(curstack->prev->type)) {
1480                                                         /* ..., cat2, ???? */
1481 #ifdef TYPECHECK_STACK_COMPCAT
1482                                                         if (opt_verify) {
1483                                                                 if (IS_2_WORD_TYPE(curstack->type))
1484                                                                         panic("Illegal instruction: DUP_X2 on cat2, cat2 types");
1485                                                         }
1486 #endif
1487                                                         iptr->opc = ICMD_DUP_X1;
1488                                                         DUP_X1;
1489                                                 }
1490                                                 else {
1491                                                         /* ..., cat1, ???? */
1492 #ifdef TYPECHECK_STACK_COMPCAT
1493                                                         if (opt_verify) {
1494                                                                 REQUIRE_3;
1495                                                                 if (IS_2_WORD_TYPE(curstack->type)
1496                                                                         || IS_2_WORD_TYPE(curstack->prev->prev->type))
1497                                                                         panic("Illegal instruction: DUP_X2 on invalid types");
1498                                                         }
1499 #endif
1500                                                         DUP_X2;
1501                                                 }
1502                                                 break;
1503
1504                                         case ICMD_DUP2_X2:
1505                                                 REQUIRE_2;
1506                                                 if (IS_2_WORD_TYPE(curstack->type)) {
1507                                                         /* ..., ????, cat2 */
1508                                                         if (IS_2_WORD_TYPE(curstack->prev->type)) {
1509                                                                 /* ..., cat2, cat2 */
1510                                                                 iptr->opc = ICMD_DUP_X1;
1511                                                                 DUP_X1;
1512                                                         }
1513                                                         else {
1514                                                                 /* ..., cat1, cat2 */
1515 #ifdef TYPECHECK_STACK_COMPCAT
1516                                                                 if (opt_verify) {
1517                                                                         REQUIRE_3;
1518                                                                         if (IS_2_WORD_TYPE(curstack->prev->prev->type))
1519                                                                                 panic("Illegal instruction: DUP2_X2 on invalid types");
1520                                                                 }
1521 #endif
1522                                                                 iptr->opc = ICMD_DUP_X2;
1523                                                                 DUP_X2;
1524                                                         }
1525                                                 }
1526                                                 else {
1527                                                         REQUIRE_3;
1528                                                         /* ..., ????, ????, cat1 */
1529                                                         if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
1530                                                                 /* ..., cat2, ????, cat1 */
1531 #ifdef TYPECHECK_STACK_COMPCAT
1532                                                                 if (opt_verify) {
1533                                                                         if (IS_2_WORD_TYPE(curstack->prev->type))
1534                                                                                 panic("Illegal instruction: DUP2_X2 on invalid types");
1535                                                                 }
1536 #endif
1537                                                                 iptr->opc = ICMD_DUP2_X1;
1538                                                                 DUP2_X1;
1539                                                         }
1540                                                         else {
1541                                                                 /* ..., cat1, ????, cat1 */
1542 #ifdef TYPECHECK_STACK_COMPCAT
1543                                                                 if (opt_verify) {
1544                                                                         REQUIRE_4;
1545                                                                         if (IS_2_WORD_TYPE(curstack->prev->type)
1546                                                                                 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
1547                                                                                 panic("Illegal instruction: DUP2_X2 on invalid types");
1548                                                                 }
1549 #endif
1550                                                                 DUP2_X2;
1551                                                         }
1552                                                 }
1553                                                 break;
1554
1555                                                 /* pop 2 push 2 swap */
1556                                                 
1557                                         case ICMD_SWAP:
1558 #ifdef TYPECHECK_STACK_COMPCAT
1559                                                 if (opt_verify) {
1560                                                         REQUIRE_2;
1561                                                         if (IS_2_WORD_TYPE(curstack->type)
1562                                                                 || IS_2_WORD_TYPE(curstack->prev->type))
1563                                                                 panic("Illegal instruction: SWAP on category 2 type");
1564                                                 }
1565 #endif
1566                                                 SWAP;
1567                                                 break;
1568
1569                                                 /* pop 2 push 1 */
1570                                                 
1571                                         case ICMD_IDIV:
1572 #if !SUPPORT_DIVISION
1573                                                 iptr[0].opc = ICMD_BUILTIN2;
1574                                                 iptr[0].op1 = TYPE_INT;
1575                                                 iptr[0].val.a = BUILTIN_idiv;
1576                                                 isleafmethod = false;
1577                                                 goto builtin2;
1578 #endif
1579
1580                                         case ICMD_IREM:
1581 #if !SUPPORT_DIVISION
1582                                                 iptr[0].opc = ICMD_BUILTIN2;
1583                                                 iptr[0].op1 = TYPE_INT;
1584                                                 iptr[0].val.a = BUILTIN_irem;
1585                                                 isleafmethod = false;
1586                                                 goto builtin2;
1587 #endif
1588 #if defined(__I386__)
1589                                                 method_uses_ecx = true;
1590                                                 method_uses_edx = true;
1591 #endif
1592
1593                                         case ICMD_ISHL:
1594                                         case ICMD_ISHR:
1595                                         case ICMD_IUSHR:
1596 #if defined(__I386__)
1597                                                 method_uses_ecx = true;
1598 #endif
1599                                         case ICMD_IADD:
1600                                         case ICMD_ISUB:
1601                                         case ICMD_IMUL:
1602                                         case ICMD_IAND:
1603                                         case ICMD_IOR:
1604                                         case ICMD_IXOR:
1605                                                 COUNT(count_pcmd_op);
1606                                                 OP2_1(TYPE_INT);
1607                                                 break;
1608
1609                                         case ICMD_LDIV:
1610 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1611                                                 iptr[0].opc = ICMD_BUILTIN2;
1612                                                 iptr[0].op1 = TYPE_LNG;
1613                                                 iptr[0].val.a = BUILTIN_ldiv;
1614                                                 isleafmethod = false;
1615                                                 goto builtin2;
1616 #endif
1617
1618                                         case ICMD_LREM:
1619 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1620                                                 iptr[0].opc = ICMD_BUILTIN2;
1621                                                 iptr[0].op1 = TYPE_LNG;
1622                                                 iptr[0].val.a = BUILTIN_lrem;
1623                                                 isleafmethod = false;
1624                                                 goto builtin2;
1625 #endif
1626
1627                                         case ICMD_LMUL:
1628 #if defined(__I386__)
1629                                                 method_uses_ecx = true;
1630                                                 method_uses_edx = true;
1631 #endif
1632                                         case ICMD_LADD:
1633                                         case ICMD_LSUB:
1634                                         case ICMD_LOR:
1635                                         case ICMD_LAND:
1636                                         case ICMD_LXOR:
1637                                                 /* DEBUG */ /*dolog("OP2_1(TYPE_LNG)"); */
1638                                                 COUNT(count_pcmd_op);
1639                                                 OP2_1(TYPE_LNG);
1640                                                 break;
1641
1642                                         case ICMD_LSHL:
1643                                         case ICMD_LSHR:
1644                                         case ICMD_LUSHR:
1645                                                 COUNT(count_pcmd_op);
1646                                                 OP2IT_1(TYPE_LNG);
1647 #if defined(__I386__)
1648                                                 method_uses_ecx = true;
1649                                                 method_uses_edx = true;
1650 #endif
1651                                                 break;
1652
1653                                         case ICMD_FADD:
1654                                         case ICMD_FSUB:
1655                                         case ICMD_FMUL:
1656                                         case ICMD_FDIV:
1657                                         case ICMD_FREM:
1658                                                 COUNT(count_pcmd_op);
1659                                                 OP2_1(TYPE_FLT);
1660                                                 break;
1661
1662                                         case ICMD_DADD:
1663                                         case ICMD_DSUB:
1664                                         case ICMD_DMUL:
1665                                         case ICMD_DDIV:
1666                                         case ICMD_DREM:
1667                                                 COUNT(count_pcmd_op);
1668                                                 OP2_1(TYPE_DBL);
1669                                                 break;
1670
1671                                         case ICMD_LCMP:
1672                                                 COUNT(count_pcmd_op);
1673 #if !defined(NOLONG_CONDITIONAL)
1674                                                 if ((len > 0) && (iptr[1].val.i == 0)) {
1675                                                         switch (iptr[1].opc) {
1676                                                         case ICMD_IFEQ:
1677                                                                 iptr[0].opc = ICMD_IF_LCMPEQ;
1678 #if defined(__I386__)
1679                                                                 method_uses_ecx = true;
1680 #endif
1681                                                         icmd_lcmp_if_tail:
1682                                                                 iptr[0].op1 = iptr[1].op1;
1683                                                                 len--;
1684                                                                 bptr->icount--;
1685                                                                 /* iptr[1].opc = ICMD_NOP; */
1686                                                                 OP2_0(TYPE_LNG);
1687                                                                 tbptr = block + block_index[iptr->op1];
1688                         
1689                                                                 iptr[0].target = (void *) tbptr;
1690
1691                                                                 MARKREACHED(tbptr, copy);
1692                                                                 COUNT(count_pcmd_bra);
1693                                                                 break;
1694                                                         case ICMD_IFNE:
1695                                                                 iptr[0].opc = ICMD_IF_LCMPNE;
1696 #if defined(__I386__)
1697                                                                 method_uses_ecx = true;
1698 #endif
1699                                                                 goto icmd_lcmp_if_tail;
1700                                                         case ICMD_IFLT:
1701                                                                 iptr[0].opc = ICMD_IF_LCMPLT;
1702                                                                 goto icmd_lcmp_if_tail;
1703                                                         case ICMD_IFGT:
1704                                                                 iptr[0].opc = ICMD_IF_LCMPGT;
1705                                                                 goto icmd_lcmp_if_tail;
1706                                                         case ICMD_IFLE:
1707                                                                 iptr[0].opc = ICMD_IF_LCMPLE;
1708                                                                 goto icmd_lcmp_if_tail;
1709                                                         case ICMD_IFGE:
1710                                                                 iptr[0].opc = ICMD_IF_LCMPGE;
1711                                                                 goto icmd_lcmp_if_tail;
1712                                                         default:
1713                                                                 OPTT2_1(TYPE_LNG, TYPE_INT);
1714                                                         }
1715                                                 }
1716                                                 else
1717 #endif
1718                                                         OPTT2_1(TYPE_LNG, TYPE_INT);
1719                                                 break;
1720                                         case ICMD_FCMPL:
1721                                         case ICMD_FCMPG:
1722                                                 COUNT(count_pcmd_op);
1723                                                 OPTT2_1(TYPE_FLT, TYPE_INT);
1724                                                 break;
1725                                         case ICMD_DCMPL:
1726                                         case ICMD_DCMPG:
1727                                                 COUNT(count_pcmd_op);
1728                                                 OPTT2_1(TYPE_DBL, TYPE_INT);
1729                                                 break;
1730
1731                                                 /* pop 1 push 1 */
1732                                                 
1733                                         case ICMD_INEG:
1734                                         case ICMD_INT2BYTE:
1735                                         case ICMD_INT2CHAR:
1736                                         case ICMD_INT2SHORT:
1737                                                 COUNT(count_pcmd_op);
1738                                                 OP1_1(TYPE_INT, TYPE_INT);
1739                                                 break;
1740                                         case ICMD_LNEG:
1741                                                 COUNT(count_pcmd_op);
1742                                                 OP1_1(TYPE_LNG, TYPE_LNG);
1743                                                 break;
1744                                         case ICMD_FNEG:
1745                                                 COUNT(count_pcmd_op);
1746                                                 OP1_1(TYPE_FLT, TYPE_FLT);
1747                                                 break;
1748                                         case ICMD_DNEG:
1749                                                 COUNT(count_pcmd_op);
1750                                                 OP1_1(TYPE_DBL, TYPE_DBL);
1751                                                 break;
1752
1753                                         case ICMD_I2L:
1754                                                 COUNT(count_pcmd_op);
1755                                                 OP1_1(TYPE_INT, TYPE_LNG);
1756 #if defined(__I386__)
1757                                                 method_uses_edx = true;
1758 #endif
1759                                                 break;
1760                                         case ICMD_I2F:
1761                                                 COUNT(count_pcmd_op);
1762                                                 OP1_1(TYPE_INT, TYPE_FLT);
1763                                                 break;
1764                                         case ICMD_I2D:
1765                                                 COUNT(count_pcmd_op);
1766                                                 OP1_1(TYPE_INT, TYPE_DBL);
1767                                                 break;
1768                                         case ICMD_L2I:
1769                                                 COUNT(count_pcmd_op);
1770                                                 OP1_1(TYPE_LNG, TYPE_INT);
1771                                                 break;
1772                                         case ICMD_L2F:
1773                                                 COUNT(count_pcmd_op);
1774                                                 OP1_1(TYPE_LNG, TYPE_FLT);
1775                                                 break;
1776                                         case ICMD_L2D:
1777                                                 COUNT(count_pcmd_op);
1778                                                 OP1_1(TYPE_LNG, TYPE_DBL);
1779                                                 break;
1780                                         case ICMD_F2I:
1781                                                 COUNT(count_pcmd_op);
1782                                                 OP1_1(TYPE_FLT, TYPE_INT);
1783                                                 break;
1784                                         case ICMD_F2L:
1785                                                 COUNT(count_pcmd_op);
1786                                                 OP1_1(TYPE_FLT, TYPE_LNG);
1787 #if defined(__I386__)
1788                                                 method_uses_edx = true;
1789 #endif
1790                                                 break;
1791                                         case ICMD_F2D:
1792                                                 COUNT(count_pcmd_op);
1793                                                 OP1_1(TYPE_FLT, TYPE_DBL);
1794                                                 break;
1795                                         case ICMD_D2I:
1796                                                 COUNT(count_pcmd_op);
1797                                                 OP1_1(TYPE_DBL, TYPE_INT);
1798                                                 break;
1799                                         case ICMD_D2L:
1800                                                 COUNT(count_pcmd_op);
1801                                                 OP1_1(TYPE_DBL, TYPE_LNG);
1802 #if defined(__I386__)
1803                                                 method_uses_edx = true;
1804 #endif
1805                                                 break;
1806                                         case ICMD_D2F:
1807                                                 COUNT(count_pcmd_op);
1808                                                 OP1_1(TYPE_DBL, TYPE_FLT);
1809                                                 break;
1810
1811                                         case ICMD_CHECKCAST:
1812                                                 OP1_1(TYPE_ADR, TYPE_ADR);
1813 #if defined(__I386__)
1814                                                 method_uses_ecx = true;
1815                                                 method_uses_edx = true;
1816 #endif
1817                                                 break;
1818
1819                                         case ICMD_INSTANCEOF:
1820 #if defined(__I386__)
1821                                                 method_uses_ecx = true;
1822                                                 method_uses_edx = true;
1823 #endif
1824                                         case ICMD_ARRAYLENGTH:
1825                                                 OP1_1(TYPE_ADR, TYPE_INT);
1826                                                 break;
1827
1828                                         case ICMD_NEWARRAY:
1829                                         case ICMD_ANEWARRAY:
1830                                                 OP1_1(TYPE_INT, TYPE_ADR);
1831                                                 break;
1832
1833                                         case ICMD_GETFIELD:
1834                                                 COUNT(count_check_null);
1835                                                 COUNT(count_pcmd_mem);
1836                                                 OP1_1(TYPE_ADR, iptr->op1);
1837 #if defined(__I386__)
1838                                                 method_uses_ecx = true;
1839 #endif
1840                                                 break;
1841
1842                                                 /* pop 0 push 1 */
1843                                                 
1844                                         case ICMD_GETSTATIC:
1845                                                 COUNT(count_pcmd_mem);
1846                                                 OP0_1(iptr->op1);
1847 #if defined(__I386__)
1848                                                 method_uses_ecx = true;
1849 #endif
1850                                                 break;
1851
1852                                         case ICMD_NEW:
1853                                                 OP0_1(TYPE_ADR);
1854                                                 break;
1855
1856                                         case ICMD_JSR:
1857                                                 OP0_1(TYPE_ADR);
1858                                                 tbptr = block + block_index[iptr->op1];
1859
1860                                                 iptr[0].target = (void *) tbptr;
1861
1862                                                 /* This is a dirty hack. The typechecker
1863                                                  * needs it because the OP1_0ANY below
1864                                                  * overwrites iptr->dst.
1865                                                  */
1866                                                 iptr->val.a = (void *) iptr->dst;
1867
1868                                                 tbptr->type = BBTYPE_SBR;
1869
1870                                                 /* We need to check for overflow right here because
1871                                                  * the pushed value is poped after MARKREACHED. */
1872                                                 CHECKOVERFLOW;
1873                                                 MARKREACHED(tbptr, copy);
1874                                                 OP1_0ANY;
1875                                                 break;
1876
1877                                                 /* pop many push any */
1878                                                 
1879                                         case ICMD_INVOKEVIRTUAL:
1880                                         case ICMD_INVOKESPECIAL:
1881                                         case ICMD_INVOKEINTERFACE:
1882                                         case ICMD_INVOKESTATIC:
1883                                                 COUNT(count_pcmd_met);
1884 #if defined(__I386__)
1885                                                 method_uses_ecx = true;
1886 #endif
1887                                                 {
1888                                                         methodinfo *m = iptr->val.a;
1889                                                         if (m->flags & ACC_STATIC)
1890                                                                 {COUNT(count_check_null);}
1891                                                         i = iptr->op1;
1892                                                         if (i > arguments_num)
1893                                                                 arguments_num = i;
1894                                                         REQUIRE(i);
1895 #if defined(__X86_64__)
1896                                                         {
1897                                                                 int iarg = 0;
1898                                                                 int farg = 0;
1899                                                                 int stackargs = 0;
1900
1901                                                                 copy = curstack;
1902                                                                 while (--i >= 0) {
1903                                                                         (IS_FLT_DBL_TYPE(copy->type)) ? farg++ : iarg++;
1904                                                                         copy = copy->prev;
1905                                                                 }
1906
1907                                                                 stackargs += (iarg < intreg_argnum) ? 0 : (iarg - intreg_argnum);
1908                                                                 stackargs += (farg < fltreg_argnum) ? 0 : (farg - fltreg_argnum);
1909
1910                                                                 i = iptr->op1;
1911                                                                 copy = curstack;
1912                                                                 while (--i >= 0) {
1913                                                                         if (!(copy->flags & SAVEDVAR)) {
1914                                                                                 copy->varkind = ARGVAR;
1915                                                                                 if (IS_FLT_DBL_TYPE(copy->type)) {
1916                                                                                         if (--farg < fltreg_argnum) {
1917                                                                                                 copy->varnum = farg;
1918                                                                                         } else {
1919                                                                                                 copy->varnum = --stackargs + intreg_argnum;
1920                                                                                         }
1921                                                                                 } else {
1922                                                                                         if (--iarg < intreg_argnum) {
1923                                                                                                 copy->varnum = iarg;
1924                                                                                         } else {
1925                                                                                                 copy->varnum = --stackargs + intreg_argnum;
1926                                                                                         }
1927                                                                                 }
1928                                                                         } else {
1929                                                                                 (IS_FLT_DBL_TYPE(copy->type)) ? --farg : --iarg;
1930                                                                         }
1931                                                                         copy = copy->prev;
1932                                                                 }
1933                                                         }
1934 #else
1935                                                         copy = curstack;
1936                                                         while (--i >= 0) {
1937                                                                 if (! (copy->flags & SAVEDVAR)) {
1938                                                                         copy->varkind = ARGVAR;
1939                                                                         copy->varnum = i;
1940                                                                 }
1941                                                                 copy = copy->prev;
1942                                                         }
1943 #endif
1944                                                         while (copy) {
1945                                                                 copy->flags |= SAVEDVAR;
1946                                                                 copy = copy->prev;
1947                                                         }
1948                                                         i = iptr->op1;
1949                                                         POPMANY(i);
1950                                                         if (m->returntype != TYPE_VOID) {
1951                                                                 OP0_1(m->returntype);
1952                                                         }
1953                                                         break;
1954                                                 }
1955
1956                                         case ICMD_BUILTIN3:
1957                                                 /* DEBUG */ /*dolog("builtin3");*/
1958                                                 REQUIRE_3;
1959                                                 if (! (curstack->flags & SAVEDVAR)) {
1960                                                         curstack->varkind = ARGVAR;
1961                                                         curstack->varnum = 2;
1962                                                 }
1963                                                 if (3 > arguments_num) {
1964                                                         arguments_num = 3;
1965                                                 }
1966                                                 OP1_0ANY;
1967
1968                                         case ICMD_BUILTIN2:
1969                                         builtin2:
1970                                                 REQUIRE_2;
1971                                                 /* DEBUG */ /*dolog("builtin2");*/
1972                                         if (!(curstack->flags & SAVEDVAR)) {
1973                                                 curstack->varkind = ARGVAR;
1974                                                 curstack->varnum = 1;
1975                                         }
1976                                         if (2 > arguments_num) {
1977                                                 arguments_num = 2;
1978                                         }
1979                                         OP1_0ANY;
1980
1981                                         case ICMD_BUILTIN1:
1982                                         builtin1:
1983                                                 REQUIRE_1;
1984                                                 /* DEBUG */ /*dolog("builtin1");*/
1985                                         if (!(curstack->flags & SAVEDVAR)) {
1986                                                 curstack->varkind = ARGVAR;
1987                                                 curstack->varnum = 0;
1988                                         }
1989                                         if (1 > arguments_num) {
1990                                                 arguments_num = 1;
1991                                         }
1992                                         OP1_0ANY;
1993                                         copy = curstack;
1994                                         while (copy) {
1995                                                 copy->flags |= SAVEDVAR;
1996                                                 copy = copy->prev;
1997                                         }
1998                                         if (iptr->op1 != TYPE_VOID)
1999                                                 OP0_1(iptr->op1);
2000                                         break;
2001
2002                                         case ICMD_MULTIANEWARRAY:
2003                                                 i = iptr->op1;
2004                                                 REQUIRE(i);
2005                                                 if ((i + intreg_argnum) > arguments_num)
2006                                                         arguments_num = i + intreg_argnum;
2007                                                 copy = curstack;
2008                                                 while (--i >= 0) {
2009                                                         /* check INT type here? Currently typecheck does this. */
2010                                                         if (! (copy->flags & SAVEDVAR)) {
2011                                                                 copy->varkind = ARGVAR;
2012                                                                 copy->varnum = i + intreg_argnum;
2013                                                         }
2014                                                         copy = copy->prev;
2015                                                 }
2016                                                 while (copy) {
2017                                                         copy->flags |= SAVEDVAR;
2018                                                         copy = copy->prev;
2019                                                 }
2020                                                 i = iptr->op1;
2021                                                 POPMANY(i);
2022                                                 OP0_1(TYPE_ADR);
2023                                                 break;
2024
2025                                         case ICMD_CLEAR_ARGREN:
2026                                                 for (i = iptr->op1; i<maxlocals; i++) 
2027                                                         argren[i] = i;
2028                                                 iptr->opc = opcode = ICMD_NOP;
2029                                                 SETDST;
2030                                                 break;
2031                                                 
2032                                         case ICMD_READONLY_ARG:
2033                                         case ICMD_READONLY_ARG+1:
2034                                         case ICMD_READONLY_ARG+2:
2035                                         case ICMD_READONLY_ARG+3:
2036                                         case ICMD_READONLY_ARG+4:
2037
2038                                                 REQUIRE_1;
2039                                                 if (curstack->varkind == LOCALVAR) {
2040                                                         i = curstack->varnum;
2041                                                         argren[iptr->op1] = i;
2042                                                         iptr->op1 = i;
2043                                                 }
2044                                                 opcode = iptr->opc = opcode - ICMD_READONLY_ARG + ICMD_ISTORE;
2045                                                 goto icmd_store;
2046
2047                                                 break;
2048
2049                                         default:
2050                                                 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
2051                                                 panic("Missing ICMD code during stack analysis");
2052                                         } /* switch */
2053
2054                                         CHECKOVERFLOW;
2055                                         
2056                                         /* DEBUG */ /*dolog("iptr++");*/
2057                                         iptr++;
2058                                 } /* while instructions */
2059                                 bptr->outstack = curstack;
2060                                 bptr->outdepth = stackdepth;
2061                                 BBEND(curstack, i);
2062                         } /* if */
2063                         else
2064                                 superblockend = true;
2065                         bptr++;
2066                 } /* while blocks */
2067         } while (repeat && !deadcode);
2068
2069 #ifdef STATISTICS
2070         if (block_count > count_max_basic_blocks)
2071                 count_max_basic_blocks = block_count;
2072         count_basic_blocks += block_count;
2073         if (instr_count > count_max_javainstr)
2074                 count_max_javainstr = instr_count;
2075         count_javainstr += instr_count;
2076         if (stack_count > count_upper_bound_new_stack)
2077                 count_upper_bound_new_stack = stack_count;
2078         if ((new - stack) > count_max_new_stack)
2079                 count_max_new_stack = (new - stack);
2080
2081         b_count = block_count;
2082         bptr = block;
2083         while (--b_count >= 0) {
2084                 if (bptr->flags > BBREACHED) {
2085                         if (bptr->indepth >= 10)
2086                                 count_block_stack[10]++;
2087                         else
2088                                 count_block_stack[bptr->indepth]++;
2089                         len = bptr->icount;
2090                         if (len < 10) 
2091                                 count_block_size_distribution[len]++;
2092                         else if (len <= 12)
2093                                 count_block_size_distribution[10]++;
2094                         else if (len <= 14)
2095                                 count_block_size_distribution[11]++;
2096                         else if (len <= 16)
2097                                 count_block_size_distribution[12]++;
2098                         else if (len <= 18)
2099                                 count_block_size_distribution[13]++;
2100                         else if (len <= 20)
2101                                 count_block_size_distribution[14]++;
2102                         else if (len <= 25)
2103                                 count_block_size_distribution[15]++;
2104                         else if (len <= 30)
2105                                 count_block_size_distribution[16]++;
2106                         else
2107                                 count_block_size_distribution[17]++;
2108                 }
2109                 bptr++;
2110         }
2111
2112         if (loops == 1)
2113                 count_analyse_iterations[0]++;
2114         else if (loops == 2)
2115                 count_analyse_iterations[1]++;
2116         else if (loops == 3)
2117                 count_analyse_iterations[2]++;
2118         else if (loops == 4)
2119                 count_analyse_iterations[3]++;
2120         else
2121                 count_analyse_iterations[4]++;
2122
2123         if (block_count <= 5)
2124                 count_method_bb_distribution[0]++;
2125         else if (block_count <= 10)
2126                 count_method_bb_distribution[1]++;
2127         else if (block_count <= 15)
2128                 count_method_bb_distribution[2]++;
2129         else if (block_count <= 20)
2130                 count_method_bb_distribution[3]++;
2131         else if (block_count <= 30)
2132                 count_method_bb_distribution[4]++;
2133         else if (block_count <= 40)
2134                 count_method_bb_distribution[5]++;
2135         else if (block_count <= 50)
2136                 count_method_bb_distribution[6]++;
2137         else if (block_count <= 75)
2138                 count_method_bb_distribution[7]++;
2139         else
2140                 count_method_bb_distribution[8]++;
2141 #endif
2142
2143         /* just return methodinfo* to signal everything was ok */
2144
2145         return m;
2146 }
2147
2148
2149 /**********************************************************************/
2150 /* DEBUGGING HELPERS                                                  */
2151 /**********************************************************************/
2152
2153 void icmd_print_stack(stackptr s)
2154 {
2155         int i, j;
2156         stackptr t;
2157
2158         i = maxstack;
2159         t = s;
2160         
2161         while (t) {
2162                 i--;
2163                 t = t->prev;
2164         }
2165         j = maxstack - i;
2166         while (--i >= 0)
2167                 printf("    ");
2168         while (s) {
2169                 j--;
2170                 /* DEBUG */ /*printf("(%d,%d,%d,%d)",s->varkind,s->flags,s->regoff,s->varnum); fflush(stdout);*/
2171                 if (s->flags & SAVEDVAR)
2172                         switch (s->varkind) {
2173                         case TEMPVAR:
2174                                 if (s->flags & INMEMORY)
2175                                         printf((regs_ok) ? " M%02d" : " M??", s->regoff);
2176                                 else if ((s->type == TYPE_FLT) || (s->type == TYPE_DBL))
2177                                         printf((regs_ok) ? " F%02d" : " F??", s->regoff);
2178                                 else {
2179                                         if (regs_ok) printf(" %3s",regs[s->regoff]); else printf(" ???");
2180                                 }
2181                                 break;
2182                         case STACKVAR:
2183                                 printf(" I%02d", s->varnum);
2184                                 break;
2185                         case LOCALVAR:
2186                                 printf(" L%02d", s->varnum);
2187                                 break;
2188                         case ARGVAR:
2189                                 printf(" A%02d", s->varnum);
2190                                 break;
2191                         default:
2192                                 printf(" !%02d", j);
2193                         }
2194                 else
2195                         switch (s->varkind) {
2196                         case TEMPVAR:
2197                                 if (s->flags & INMEMORY)
2198                                         printf((regs_ok) ? " m%02d" : " m??", s->regoff);
2199                                 else if ((s->type == TYPE_FLT) || (s->type == TYPE_DBL))
2200                                         printf((regs_ok) ? " f%02d" : " f??", s->regoff);
2201                                 else {
2202                                         if (regs_ok) printf(" %3s",regs[s->regoff]); else printf(" ???");
2203                                 }
2204                                 break;
2205                         case STACKVAR:
2206                                 printf(" i%02d", s->varnum);
2207                                 break;
2208                         case LOCALVAR:
2209                                 printf(" l%02d", s->varnum);
2210                                 break;
2211                         case ARGVAR:
2212                                 printf(" a%02d", s->varnum);
2213                                 break;
2214                         default:
2215                                 printf(" ?%02d", j);
2216                         }
2217                 s = s->prev;
2218         }
2219 }
2220
2221
2222 #if 0
2223 static void print_reg(stackptr s) {
2224         if (s) {
2225                 if (s->flags & SAVEDVAR)
2226                         switch (s->varkind) {
2227                         case TEMPVAR:
2228                                 if (s->flags & INMEMORY)
2229                                         printf(" tm%02d", s->regoff);
2230                                 else
2231                                         printf(" tr%02d", s->regoff);
2232                                 break;
2233                         case STACKVAR:
2234                                 printf(" s %02d", s->varnum);
2235                                 break;
2236                         case LOCALVAR:
2237                                 printf(" l %02d", s->varnum);
2238                                 break;
2239                         case ARGVAR:
2240                                 printf(" a %02d", s->varnum);
2241                                 break;
2242                         default:
2243                                 printf(" ! %02d", s->varnum);
2244                         }
2245                 else
2246                         switch (s->varkind) {
2247                         case TEMPVAR:
2248                                 if (s->flags & INMEMORY)
2249                                         printf(" Tm%02d", s->regoff);
2250                                 else
2251                                         printf(" Tr%02d", s->regoff);
2252                                 break;
2253                         case STACKVAR:
2254                                 printf(" S %02d", s->varnum);
2255                                 break;
2256                         case LOCALVAR:
2257                                 printf(" L %02d", s->varnum);
2258                                 break;
2259                         case ARGVAR:
2260                                 printf(" A %02d", s->varnum);
2261                                 break;
2262                         default:
2263                                 printf(" ? %02d", s->varnum);
2264                         }
2265         }
2266         else
2267                 printf("     ");
2268                 
2269 }
2270 #endif
2271
2272
2273 char *icmd_builtin_name(functionptr bptr)
2274 {
2275         builtin_descriptor *bdesc = builtin_desc;
2276         while ((bdesc->opcode != 0) && (bdesc->builtin != bptr))
2277                 bdesc++;
2278         return (bdesc->opcode) ? bdesc->name : "<NOT IN TABLE>";
2279 }
2280
2281
2282 static char *jit_type[] = {
2283         "int",
2284         "lng",
2285         "flt",
2286         "dbl",
2287         "adr"
2288 };
2289
2290
2291 void show_icmd_method()
2292 {
2293         int i, j;
2294         basicblock *bptr;
2295         xtable *ex;
2296
2297         printf("\n");
2298         utf_fprint_classname(stdout, class->name);
2299         printf(".");
2300         utf_fprint(stdout, method->name);
2301         utf_fprint_classname(stdout, method->descriptor);
2302         printf ("\n\nMax locals: %d\n", (int) maxlocals);
2303         printf ("Max stack:  %d\n", (int) maxstack);
2304
2305         printf ("Line number table length: %d\n",method->linenumbercount);
2306
2307         printf ("Exceptions (Number: %d):\n", exceptiontablelength);
2308         for (ex = extable; ex != NULL; ex = ex->down) {
2309                 printf("    L%03d ... ", ex->start->debug_nr );
2310                 printf("L%03d  = ", ex->end->debug_nr);
2311                 printf("L%03d\n", ex->handler->debug_nr);
2312         }
2313         
2314         printf ("Local Table:\n");
2315         for (i = 0; i < maxlocals; i++) {
2316                 printf("   %3d: ", i);
2317                 for (j = TYPE_INT; j <= TYPE_ADR; j++)
2318                         if (locals[i][j].type >= 0) {
2319                                 printf("   (%s) ", jit_type[j]);
2320                                 if (locals[i][j].flags & INMEMORY)
2321                                         printf((regs_ok) ? "m%2d" : "m??", locals[i][j].regoff);
2322                                 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2323                                         printf((regs_ok) ? "f%02d" : "f??", locals[i][j].regoff);
2324                                 else {
2325                                         if (regs_ok) printf("%3s",regs[locals[i][j].regoff]); else printf("???");
2326                                 }
2327                         }
2328                 printf("\n");
2329         }
2330         printf("\n");
2331
2332         printf ("Interface Table:\n");
2333         for (i = 0; i < maxstack; i++) {
2334                 if ((interfaces[i][0].type >= 0) || (interfaces[i][1].type >= 0) ||
2335                     (interfaces[i][2].type >= 0) || (interfaces[i][3].type >= 0) ||
2336                     (interfaces[i][4].type >= 0)) {
2337                         printf("   %3d: ", i);
2338                         for (j = TYPE_INT; j <= TYPE_ADR; j++)
2339                                 if (interfaces[i][j].type >= 0) {
2340                                         printf("   (%s) ", jit_type[j]);
2341                                         if (interfaces[i][j].flags & SAVEDVAR) {
2342                                                 if (interfaces[i][j].flags & INMEMORY)
2343                                                         printf((regs_ok) ? "M%2d" : "M??", interfaces[i][j].regoff);
2344                                                 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2345                                                         printf((regs_ok) ? "F%02d" : "F??", interfaces[i][j].regoff);
2346                                                 else {
2347                                                         if (regs_ok) printf("%3s",regs[interfaces[i][j].regoff]); else printf("???");
2348                                                 }
2349                                         }
2350                                         else {
2351                                                 if (interfaces[i][j].flags & INMEMORY)
2352                                                         printf((regs_ok) ? "m%2d" : "m??", interfaces[i][j].regoff);
2353                                                 else if ((j == TYPE_FLT) || (j == TYPE_DBL))
2354                                                         printf((regs_ok) ? "f%02d" : "f??", interfaces[i][j].regoff);
2355                                                 else {
2356                                                         if (regs_ok) printf("%3s",regs[interfaces[i][j].regoff]); else printf("???");
2357                                                 }
2358                                         }
2359                                 }
2360                         printf("\n");
2361                 }
2362         }
2363         printf("\n");
2364
2365         if (showdisassemble) {
2366 #if defined(__I386__) || defined(__X86_64__)
2367                 u1 *u1ptr;
2368                 int a;
2369
2370                 u1ptr = method->mcode + dseglen;
2371                 for (i = 0; i < block[0].mpc; i++, u1ptr++) {
2372                         a = disassinstr(u1ptr, i);
2373                         i += a;
2374                         u1ptr += a;
2375                 }
2376                 printf("\n");
2377 #else
2378                 s4 *s4ptr;
2379
2380                 s4ptr = (s4 *) (method->mcode + dseglen);
2381                 for (i = 0; i < block[0].mpc; i += 4, s4ptr++) {
2382                         disassinstr(s4ptr, i); 
2383                 }
2384                 printf("\n");
2385 #endif
2386         }
2387         
2388         for (bptr = block; bptr != NULL; bptr = bptr->next) {
2389                 show_icmd_block(bptr);
2390         }
2391 }
2392
2393
2394 void show_icmd_block(basicblock *bptr)
2395 {
2396         int i, j;
2397         int deadcode;
2398         instruction *iptr;
2399
2400         if (bptr->flags != BBDELETED) {
2401                 deadcode = bptr->flags <= BBREACHED;
2402                 printf("[");
2403                 if (deadcode)
2404                         for (j = method->maxstack; j > 0; j--)
2405                                 printf(" ?  ");
2406                 else
2407                         icmd_print_stack(bptr->instack);
2408                 printf("] L%03d(%d - %d) flags=%d:\n", bptr->debug_nr, bptr->icount, bptr->pre_count,bptr->flags);
2409                 iptr = bptr->iinstr;
2410
2411                 for (i=0; i < bptr->icount; i++, iptr++) {
2412                         printf("[");
2413                         if (deadcode) {
2414                                 for (j = method->maxstack; j > 0; j--)
2415                                         printf(" ?  ");
2416                         }
2417                         else
2418                                 icmd_print_stack(iptr->dst);
2419                         printf("]     %4d  ", i);
2420                         /* DEBUG */ /*fflush(stdout);*/
2421                         show_icmd(iptr,deadcode);
2422                         printf("\n");
2423                 }
2424
2425                 if (showdisassemble && (!deadcode)) {
2426 #if defined(__I386__) || defined(__X86_64__)
2427                         u1 *u1ptr;
2428                         int a;
2429
2430                         printf("\n");
2431                         i = bptr->mpc;
2432                         u1ptr = method->mcode + dseglen + i;
2433
2434                         if (bptr->next != NULL) {
2435                                 for (; i < bptr->next->mpc; i++, u1ptr++) {
2436                                         a = disassinstr(u1ptr, i);
2437                                         i += a;
2438                                         u1ptr += a;
2439                                 }
2440                                 printf("\n");
2441
2442                         } else {
2443                                 for (; u1ptr < (u1 *) (method->mcode + method->mcodelength); i++, u1ptr++) {
2444                                         a = disassinstr(u1ptr, i); 
2445                                         i += a;
2446                                         u1ptr += a;
2447                                 }
2448                                 printf("\n");
2449                         }
2450 #else
2451                         s4 *s4ptr;
2452
2453                         printf("\n");
2454                         i = bptr->mpc;
2455                         s4ptr = (s4 *) (method->mcode + dseglen + i);
2456
2457                         if (bptr->next != NULL) {
2458                                 for (; i < bptr->next->mpc; i += 4, s4ptr++) {
2459                                         disassinstr(s4ptr, i); 
2460                                 }
2461                                 printf("\n");
2462
2463                         } else {
2464                                 for (; s4ptr < (s4 *) (method->mcode + method->mcodelength); i += 4, s4ptr++) {
2465                                         disassinstr(s4ptr, i); 
2466                                 }
2467                                 printf("\n");
2468                         }
2469 #endif
2470                 }
2471         }
2472 }
2473
2474
2475 void show_icmd(instruction *iptr,bool deadcode)
2476 {
2477         int j;
2478         s4  *s4ptr;
2479         void **tptr = NULL;
2480         
2481         printf("%s", icmd_names[iptr->opc]);
2482
2483         switch ((int) iptr->opc) {
2484         case ICMD_IADDCONST:
2485         case ICMD_ISUBCONST:
2486         case ICMD_IMULCONST:
2487         case ICMD_IDIVPOW2:
2488         case ICMD_IREMPOW2:
2489         case ICMD_IREM0X10001:
2490         case ICMD_IANDCONST:
2491         case ICMD_IORCONST:
2492         case ICMD_IXORCONST:
2493         case ICMD_ISHLCONST:
2494         case ICMD_ISHRCONST:
2495         case ICMD_IUSHRCONST:
2496         case ICMD_LSHLCONST:
2497         case ICMD_LSHRCONST:
2498         case ICMD_LUSHRCONST:
2499         case ICMD_ICONST:
2500         case ICMD_ELSE_ICONST:
2501         case ICMD_IFEQ_ICONST:
2502         case ICMD_IFNE_ICONST:
2503         case ICMD_IFLT_ICONST:
2504         case ICMD_IFGE_ICONST:
2505         case ICMD_IFGT_ICONST:
2506         case ICMD_IFLE_ICONST:
2507                 printf(" %d", iptr->val.i);
2508                 break;
2509
2510         case ICMD_LADDCONST:
2511         case ICMD_LSUBCONST:
2512         case ICMD_LMULCONST:
2513         case ICMD_LDIVPOW2:
2514         case ICMD_LREMPOW2:
2515         case ICMD_LANDCONST:
2516         case ICMD_LORCONST:
2517         case ICMD_LXORCONST:
2518         case ICMD_LCONST:
2519 #if defined(__I386__)
2520                 printf(" %lld", iptr->val.l);
2521 #else
2522                 printf(" %ld", iptr->val.l);
2523 #endif
2524                 break;
2525
2526         case ICMD_FCONST:
2527                 printf(" %f", iptr->val.f);
2528                 break;
2529
2530         case ICMD_DCONST:
2531                 printf(" %f", iptr->val.d);
2532                 break;
2533
2534         case ICMD_ACONST:
2535                 printf(" %p", iptr->val.a);
2536                 break;
2537
2538         case ICMD_GETFIELD:
2539         case ICMD_PUTFIELD:
2540                 printf(" %d,", ((fieldinfo *) iptr->val.a)->offset);
2541         case ICMD_PUTSTATIC:
2542         case ICMD_GETSTATIC:
2543                 printf(" ");
2544                 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->class->name);
2545                 printf(".");
2546                 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->name);
2547                 printf(" (type ");
2548                 utf_fprint(stdout, ((fieldinfo *) iptr->val.a)->descriptor);
2549                 printf(")");
2550                 break;
2551
2552         case ICMD_IINC:
2553                 printf(" %d + %d", iptr->op1, iptr->val.i);
2554                 break;
2555
2556         case ICMD_IASTORE:
2557         case ICMD_SASTORE:
2558         case ICMD_BASTORE:
2559         case ICMD_CASTORE:
2560         case ICMD_LASTORE:
2561         case ICMD_DASTORE:
2562         case ICMD_FASTORE:
2563         case ICMD_AASTORE:
2564
2565         case ICMD_IALOAD:
2566         case ICMD_SALOAD:
2567         case ICMD_BALOAD:
2568         case ICMD_CALOAD:
2569         case ICMD_LALOAD:
2570         case ICMD_DALOAD:
2571         case ICMD_FALOAD:
2572         case ICMD_AALOAD:
2573                 if (iptr->op1 != 0)
2574                         printf("(opt.)");
2575                 break;
2576
2577         case ICMD_RET:
2578         case ICMD_ILOAD:
2579         case ICMD_LLOAD:
2580         case ICMD_FLOAD:
2581         case ICMD_DLOAD:
2582         case ICMD_ALOAD:
2583         case ICMD_ISTORE:
2584         case ICMD_LSTORE:
2585         case ICMD_FSTORE:
2586         case ICMD_DSTORE:
2587         case ICMD_ASTORE:
2588                 printf(" %d", iptr->op1);
2589                 break;
2590
2591         case ICMD_NEW:
2592                 printf(" ");
2593                 utf_fprint(stdout,
2594                                    ((classinfo *) iptr->val.a)->name);
2595                 break;
2596
2597         case ICMD_NEWARRAY:
2598                 switch (iptr->op1) {
2599                 case 4:
2600                         printf(" boolean");
2601                         break;
2602                 case 5:
2603                         printf(" char");
2604                         break;
2605                 case 6:
2606                         printf(" float");
2607                         break;
2608                 case 7:
2609                         printf(" double");
2610                         break;
2611                 case 8:
2612                         printf(" byte");
2613                         break;
2614                 case 9:
2615                         printf(" short");
2616                         break;
2617                 case 10:
2618                         printf(" int");
2619                         break;
2620                 case 11:
2621                         printf(" long");
2622                         break;
2623                 }
2624                 break;
2625
2626         case ICMD_ANEWARRAY:
2627                 if (iptr->op1) {
2628                         printf(" ");
2629                         utf_fprint(stdout,
2630                                            ((classinfo *) iptr->val.a)->name);
2631                 }
2632                 break;
2633
2634         case ICMD_MULTIANEWARRAY:
2635                 {
2636                         vftbl *vft;
2637                         printf(" %d ",iptr->op1);
2638                         vft = (vftbl *)iptr->val.a;
2639                         if (vft)
2640                                 utf_fprint(stdout,vft->class->name);
2641                         else
2642                                 printf("<null>");
2643                 }
2644                 break;
2645
2646         case ICMD_CHECKCAST:
2647         case ICMD_INSTANCEOF:
2648                 if (iptr->op1) {
2649                         classinfo *c = iptr->val.a;
2650                         if (c->flags & ACC_INTERFACE)
2651                                 printf(" (INTERFACE) ");
2652                         else
2653                                 printf(" (CLASS,%3d) ", c->vftbl->diffval);
2654                         utf_fprint(stdout, c->name);
2655                 }
2656                 break;
2657
2658         case ICMD_BUILTIN3:
2659         case ICMD_BUILTIN2:
2660         case ICMD_BUILTIN1:
2661                 printf(" %s", icmd_builtin_name((functionptr) iptr->val.a));
2662                 break;
2663
2664         case ICMD_INVOKEVIRTUAL:
2665         case ICMD_INVOKESPECIAL:
2666         case ICMD_INVOKESTATIC:
2667         case ICMD_INVOKEINTERFACE:
2668                 printf(" ");
2669                 utf_fprint(stdout,
2670                                    ((methodinfo *) iptr->val.a)->class->name);
2671                 printf(".");
2672                 utf_fprint(stdout,
2673                                    ((methodinfo *) iptr->val.a)->name);
2674                 break;
2675
2676         case ICMD_IFEQ:
2677         case ICMD_IFNE:
2678         case ICMD_IFLT:
2679         case ICMD_IFGE:
2680         case ICMD_IFGT:
2681         case ICMD_IFLE:
2682                 if (deadcode || !iptr->target)
2683                         printf("(%d) op1=%d", iptr->val.i, iptr->op1);
2684                 else
2685                         printf("(%d) L%03d", iptr->val.i, ((basicblock *) iptr->target)->debug_nr);
2686                 break;
2687
2688         case ICMD_IF_LEQ:
2689         case ICMD_IF_LNE:
2690         case ICMD_IF_LLT:
2691         case ICMD_IF_LGE:
2692         case ICMD_IF_LGT:
2693         case ICMD_IF_LLE:
2694                 if (deadcode || !iptr->target)
2695                         printf("(%lld) op1=%d", iptr->val.l, iptr->op1);
2696                 else
2697                         printf("(%lld) L%03d", iptr->val.l, ((basicblock *) iptr->target)->debug_nr);
2698                 break;
2699
2700         case ICMD_JSR:
2701         case ICMD_GOTO:
2702         case ICMD_IFNULL:
2703         case ICMD_IFNONNULL:
2704         case ICMD_IF_ICMPEQ:
2705         case ICMD_IF_ICMPNE:
2706         case ICMD_IF_ICMPLT:
2707         case ICMD_IF_ICMPGE:
2708         case ICMD_IF_ICMPGT:
2709         case ICMD_IF_ICMPLE:
2710         case ICMD_IF_LCMPEQ:
2711         case ICMD_IF_LCMPNE:
2712         case ICMD_IF_LCMPLT:
2713         case ICMD_IF_LCMPGE:
2714         case ICMD_IF_LCMPGT:
2715         case ICMD_IF_LCMPLE:
2716         case ICMD_IF_ACMPEQ:
2717         case ICMD_IF_ACMPNE:
2718                 if (deadcode || !iptr->target)
2719                         printf(" op1=%d", iptr->op1);
2720                 else
2721                         printf(" L%03d", ((basicblock *) iptr->target)->debug_nr);
2722                 break;
2723
2724         case ICMD_TABLESWITCH:
2725                 s4ptr = (s4*)iptr->val.a;
2726
2727                 if (deadcode || !iptr->target) {
2728                         printf(" %d;", *s4ptr);
2729                 }
2730                 else {
2731                         tptr = (void **) iptr->target;
2732                         printf(" L%03d;", ((basicblock *) *tptr)->debug_nr); 
2733                         tptr++;
2734                 }
2735
2736                 s4ptr++;         /* skip default */
2737                 j = *s4ptr++;                               /* low     */
2738                 j = *s4ptr++ - j;                           /* high    */
2739                 while (j >= 0) {
2740                         if (deadcode || !*tptr)
2741                                 printf(" %d", *s4ptr++);
2742                         else {
2743                                 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2744                                 tptr++;
2745                         }
2746                         j--;
2747                 }
2748                 break;
2749
2750         case ICMD_LOOKUPSWITCH:
2751                 s4ptr = (s4*)iptr->val.a;
2752
2753                 if (deadcode || !iptr->target) {
2754                         printf(" %d;", *s4ptr);
2755                 }
2756                 else {
2757                         tptr = (void **) iptr->target;
2758                         printf(" L%03d;", ((basicblock *) *tptr)->debug_nr);
2759                         tptr++;
2760                 }
2761                 s4ptr++;                                         /* default */
2762                 j = *s4ptr++;                                    /* count   */
2763
2764                 while (--j >= 0) {
2765                         if (deadcode || !*tptr) {
2766                                 s4ptr++; /* skip value */
2767                                 printf(" %d",*s4ptr++);
2768                         }
2769                         else {
2770                                 printf(" L%03d", ((basicblock *) *tptr)->debug_nr);
2771                                 tptr++;
2772                         }
2773                 }
2774                 break;
2775         }
2776         printf(" Line number: %d, class:",iptr->line);
2777         utf_display(iptr->method->class->name);
2778         printf(".");
2779         utf_display(iptr->method->name);
2780 }
2781
2782
2783 /*
2784  * These are local overrides for various environment variables in Emacs.
2785  * Please do not remove this and leave it at the end of the file, where
2786  * Emacs will automagically detect them.
2787  * ---------------------------------------------------------------------
2788  * Local variables:
2789  * mode: c
2790  * indent-tabs-mode: t
2791  * c-basic-offset: 4
2792  * tab-width: 4
2793  * End:
2794  */