missing extern and ;
[cacao.git] / src / vm / jit / parse.c
1 /* jit/parse.c - parser for JavaVM to intermediate code translation
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    Author: Andreas Krall
28
29    Changes: Carolyn Oates
30             Edwin Steiner
31
32    $Id: parse.c 942 2004-03-06 17:32:16Z jowenn $
33
34 */
35
36
37 #include <string.h>
38 #include "parse.h"
39 #include "global.h"
40 #include "main.h"
41 #include "jit.h"
42 #include "parseRT.h"
43 #include "inline.h"
44 #include "loop/loop.h"
45 #include "types.h"
46 #include "builtin.h"
47 #include "tables.h"
48 #include "native.h"
49 #include "loader.h"
50 #include "toolbox/memory.h"
51 #include "toolbox/loging.h"
52
53
54 /* data about the currently parsed method */
55
56 classinfo  *rt_class;    /* class the compiled method belongs to       */
57 methodinfo *rt_method;   /* pointer to method info of compiled method  */
58 utf *rt_descriptor;      /* type descriptor of compiled method         */
59 int rt_jcodelength;      /* length of JavaVM-codes                     */
60 u1  *rt_jcode;           /* pointer to start of JavaVM-code            */
61
62
63
64 /*INLINING*/
65 //#include "inline.c"
66 /*#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);*/
67 #define debug_writebranch
68
69
70 /* function descriptor2typesL ***************************************************
71
72         decodes a already checked method descriptor. The parameter count, the
73         return type and the argument types are stored in the passed methodinfo.
74         gets and saves classptr for object ref.s
75
76 *******************************************************************************/                
77
78 classSetNode *descriptor2typesL(methodinfo *m)
79 {
80         int debugInfo = 0;
81         int i;
82         u1 *types, *tptr;
83         int pcount, c;
84         char *utf_ptr;
85         classinfo** classtypes;
86         char *class; 
87         char *desc;
88         classSetNode *p=NULL;
89         if (debugInfo >= 1) {
90                 printf("In descriptor2typesL >>>\t"); fflush(stdout);
91                 utf_display(m->class->name); printf(".");
92                 method_display(m);fflush(stdout);
93         }
94
95         pcount = 0;
96         desc =       MNEW (char, 256); 
97         types = DMNEW (u1, m->descriptor->blength); 
98         classtypes = MNEW (classinfo*, m->descriptor->blength+1);
99         m->returnclass = NULL;
100         tptr = types;
101         if (!(m->flags & ACC_STATIC)) {
102                 *tptr++ = TYPE_ADR;
103                 if (debugInfo >= 1) {
104                         printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
105                 }
106                 classtypes[pcount] = m->class;
107                 p = addClassCone(p,  m->class);
108                 pcount++;
109         }
110
111         utf_ptr = m->descriptor->text + 1;
112         strcpy (desc,utf_ptr);
113    
114         while ((c = *desc++) != ')') {
115                 pcount++;
116                 switch (c) {
117                 case 'B':
118                 case 'C':
119                 case 'I':
120                 case 'S':
121                 case 'Z':  *tptr++ = TYPE_INT;
122                         break;
123                 case 'J':  *tptr++ = TYPE_LNG;
124                         break;
125                 case 'F':  *tptr++ = TYPE_FLT;
126                         break;
127                 case 'D':  *tptr++ = TYPE_DBL;
128                         break;
129                 case 'L':  *tptr++ = TYPE_ADR;
130                         /* get class string */
131                         class = strtok(desc,";");
132                         desc = strtok(NULL,"\0");
133                         /* get/save classinfo ptr */
134                         classtypes[pcount-1] = class_get(utf_new_char(class));
135                         p = addClassCone(p,  class_get(utf_new_char(class)));
136                         if (debugInfo >= 1) {
137                                 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
138                                 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
139                                 utf_display(classtypes[pcount-1]->name);
140                         }
141                         break;
142                 case '[':  *tptr++ = TYPE_ADR;
143                         while (c == '[')
144                                 c = *desc++;
145                         /* get class string */
146                         if (c == 'L') {
147                                 class = strtok(desc,";");
148                                 desc = strtok(NULL,"\0");
149                                 /* get/save classinfo ptr */
150                                 classtypes[pcount-1] = class_get(utf_new_char(class));
151                                 p= addClassCone(p,  class_get(utf_new_char(class)));
152                                 if (debugInfo >= 1) {
153                                         printf("[Param#%i 's class type is: %s\n",pcount-1,class);
154                                         printf("[classtypes[%i]=",pcount-1);fflush(stdout);
155                                         utf_display(classtypes[pcount-1]->name);
156                                         printf("\n");
157                                 }
158                         }
159                         else
160                                 classtypes[pcount-1] = NULL;
161                         break;
162                 default:   
163                         panic("Ill formed methodtype-descriptor");
164                 }
165         }
166
167         /* compute return type */
168         switch (*desc++) {
169         case 'B':
170         case 'C':
171         case 'I':
172         case 'S':
173         case 'Z':  m->returntype = TYPE_INT;
174                 break;
175         case 'J':  m->returntype = TYPE_LNG;
176                 break;
177         case 'F':  m->returntype = TYPE_FLT;
178                 break;
179         case 'D':  m->returntype = TYPE_DBL;
180                 break;
181         case '[':
182                 m->returntype = TYPE_ADR;
183                 c = *desc;
184                 while (c == '[')
185                         c = *desc++;
186                 if (c != 'L') break;
187                 *(desc++);
188                            
189         case 'L':  
190                 m->returntype = TYPE_ADR;
191                           
192                 /* get class string */
193                 class = strtok(desc,";");
194                 m->returnclass = class_get(utf_new_char(class));
195                 if (m->returnclass == NULL) {
196                         printf("class=%s :\t",class);
197                         panic ("return class not found");
198                 }
199                 break;
200         case 'V':  m->returntype = TYPE_VOID;
201                 break;
202
203         default:   panic("Ill formed methodtype-descriptor-ReturnType");
204         }
205
206         m->paramcount = pcount;
207         m->paramtypes = types;
208         m->paramclass = classtypes;
209
210         if (debugInfo >=1) {
211                 if (pcount > 0) {
212                         for (i=0; i< m->paramcount; i++) {
213                         if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
214                                         printf("Param #%i is:\t",i);
215                                         utf_display(m->paramclass[i]->name);
216                                         printf("\n");
217                                 }
218                         }
219                 }
220                 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) { 
221                         printf("\tReturn Type is:\t"); fflush(stdout);
222                         utf_display(m->returnclass->name);
223                         printf("\n");
224                 }
225
226                 printf("params2types: START  results in a set \n");
227                 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
228                 printSet(p);
229         }
230
231         return p;
232 }
233
234
235
236 /* function descriptor2types ***************************************************
237
238         decodes a already checked method descriptor. The parameter count, the
239         return type and the argument types are stored in the passed methodinfo.
240
241 *******************************************************************************/                
242
243 void descriptor2types(methodinfo *m)
244 {
245         u1 *types, *tptr;
246         int pcount, c;
247         char *utf_ptr;
248         pcount = 0;
249         types = DMNEW(u1, m->descriptor->blength); 
250         
251         tptr = types;
252         if (!(m->flags & ACC_STATIC)) {
253                 *tptr++ = TYPE_ADR;
254                 pcount++;
255         }
256
257         utf_ptr = m->descriptor->text + 1;
258    
259         while ((c = *utf_ptr++) != ')') {
260                 pcount++;
261                 switch (c) {
262                 case 'B':
263                 case 'C':
264                 case 'I':
265                 case 'S':
266                 case 'Z':  *tptr++ = TYPE_INT;
267                         break;
268                 case 'J':  *tptr++ = TYPE_LNG;
269                         break;
270                 case 'F':  *tptr++ = TYPE_FLT;
271                         break;
272                 case 'D':  *tptr++ = TYPE_DBL;
273                         break;
274                 case 'L':  *tptr++ = TYPE_ADR;
275                         while (*utf_ptr++ != ';');
276                         break;
277                 case '[':  *tptr++ = TYPE_ADR;
278                         while (c == '[')
279                                 c = *utf_ptr++;
280                         if (c == 'L')
281                                 while (*utf_ptr++ != ';') /* skip */;
282                         break;
283                 default:   panic ("Ill formed methodtype-descriptor");
284                 }
285         }
286
287         /* compute return type */
288
289         switch (*utf_ptr++) {
290         case 'B':
291         case 'C':
292         case 'I':
293         case 'S':
294         case 'Z':  m->returntype = TYPE_INT;
295                 break;
296         case 'J':  m->returntype = TYPE_LNG;
297                 break;
298         case 'F':  m->returntype = TYPE_FLT;
299                 break;
300         case 'D':  m->returntype = TYPE_DBL;
301                 break;
302         case '[':
303         case 'L':  m->returntype = TYPE_ADR;
304                 break;
305         case 'V':  m->returntype = TYPE_VOID;
306                 break;
307
308         default:   panic ("Ill formed methodtype-descriptor");
309         }
310
311         m->paramcount = pcount;
312         m->paramtypes = types;
313 }
314
315
316
317 /*******************************************************************************
318
319         function 'parse' scans the JavaVM code and generates intermediate code
320
321         During parsing the block index table is used to store at bit pos 0
322         a flag which marks basic block starts and at position 1 to 31 the
323         intermediate instruction index. After parsing the block index table
324         is scanned, for marked positions a block is generated and the block
325         number is stored in the block index table.
326
327 *******************************************************************************/
328
329 /* intermediate code generating macros */
330
331 #define PINC           iptr++;ipc++
332 #define LOADCONST_I(v) iptr->opc=ICMD_ICONST;/*iptr->op1=0*/;iptr->val.i=(v);PINC
333 #define LOADCONST_L(v) iptr->opc=ICMD_LCONST;/*iptr->op1=0*/;iptr->val.l=(v);PINC
334 #define LOADCONST_F(v) iptr->opc=ICMD_FCONST;/*iptr->op1=0*/;iptr->val.f=(v);PINC
335 #define LOADCONST_D(v) iptr->opc=ICMD_DCONST;/*iptr->op1=0*/;iptr->val.d=(v);PINC
336 #define LOADCONST_A(v) iptr->opc=ICMD_ACONST;/*iptr->op1=0*/;iptr->val.a=(v);PINC
337
338 /* ACONST instructions generated as arguments for builtin functions
339  * have op1 set to non-zero. This is used for stack overflow checking
340  * in stack.c. */
341 #define LOADCONST_A_BUILTIN(v) \
342                        iptr->opc=ICMD_ACONST;iptr->op1=1;iptr->val.a=(v);PINC
343
344 #define OP(o)          iptr->opc=(o);/*iptr->op1=0*/;/*iptr->val.l=0*/;PINC
345 #define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);/*iptr->val.l=(0)*/;PINC
346 #define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
347 #define OP2A(o,o1,v,l)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);iptr->line=l;PINC
348 #define BUILTIN1(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
349                        iptr->val.a=(v);iptr->line=l;PINC
350 #define BUILTIN2(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
351                        iptr->val.a=(v);iptr->line=l;PINC
352 #define BUILTIN3(v,t,l)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
353                        iptr->val.a=(v);iptr->line=l;PINC
354
355 /* We have to check local variables indices here because they are
356  * used in stack.c to index the locals array. */
357
358 #define INDEX_ONEWORD(num)                                                                              \
359         do { if((num)<0 || (num)>=maxlocals)                                            \
360                         panic("Invalid local variable index"); } while (0)
361 #define INDEX_TWOWORD(num)                                                                              \
362         do { if((num)<0 || ((num)+1)>=maxlocals)                                        \
363                         panic("Invalid local variable index"); } while (0)
364
365 #define OP1LOAD(o,o1)                                                   \
366         do {if (o == ICMD_LLOAD || o == ICMD_DLOAD)     \
367                         INDEX_TWOWORD(o1);                                      \
368                 else                                                                    \
369                         INDEX_ONEWORD(o1);                                      \
370                 OP1(o,o1);} while(0)
371
372 #define OP1STORE(o,o1)                                                          \
373         do {if (o == ICMD_LSTORE || o == ICMD_DSTORE)   \
374                         INDEX_TWOWORD(o1);                                              \
375                 else                                                                            \
376                         INDEX_ONEWORD(o1);                                              \
377                 OP1(o,o1);} while(0)
378
379 /* block generating and checking macros */
380
381 #define block_insert(i) \
382     do { \
383         if (!(block_index[(i)] & 1)) { \
384             b_count++; \
385             block_index[(i)] |= 1; \
386         } \
387     } while (0)
388
389
390 /* FIXME really use cumjcodelength for the bound_checkers ? */
391
392 #define bound_check(i) \
393     do { \
394         if (i < 0 || i >= cumjcodelength) { \
395             panic("branch target out of code-boundary"); \
396         } \
397     } while (0)
398
399 /* bound_check1 is used for the inclusive ends of exception handler ranges */
400 #define bound_check1(i) \
401     do { \
402         if (i < 0 || i > cumjcodelength) { \
403             panic("branch target out of code-boundary"); \
404         } \
405     } while (0)
406
407
408
409 static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
410 {
411         int b_count, i, p;
412         
413         if (exceptiontablelength == 0) 
414                 return extable;
415         
416         b_count = *block_count;
417
418         for (i = 0; i < exceptiontablelength; i++) {
419                 p = raw_extable[i].startpc;
420                 if (label_index != NULL) p = label_index[p];
421                 extable[i].startpc = p;
422                 bound_check(p);
423                 block_insert(p);
424                 
425                 p = raw_extable[i].endpc;
426                 if (p <= raw_extable[i].startpc)
427                         panic("Invalid exception handler range");
428                 if (label_index != NULL) p = label_index[p];
429                 extable[i].endpc = p;
430                 bound_check1(p);
431                 if (p < cumjcodelength)
432                         block_insert(p);
433
434                 p = raw_extable[i].handlerpc;
435                 if (label_index != NULL) p = label_index[p];
436                 extable[i].handlerpc = p;
437                 bound_check(p);
438                 block_insert(p);
439
440                 extable[i].catchtype  = raw_extable[i].catchtype;
441
442                 extable[i].next = NULL;
443                 extable[i].down = &extable[i + 1];
444         }
445
446         *block_count = b_count;
447         return &extable[i];  /* return the next free xtable* */
448 }
449
450
451
452 void parse()
453 {
454         int  p;                     /* java instruction counter                   */
455         int  nextp;                 /* start of next java instruction             */
456         int  opcode;                /* java opcode                                */
457         int  i;                     /* temporary for different uses (counters)    */
458         int  ipc = 0;               /* intermediate instruction counter           */
459         int  b_count = 0;           /* basic block counter                        */
460         int  s_count = 0;           /* stack element counter                      */
461         bool blockend = false;      /* true if basic block end has been reached   */
462         bool iswide = false;        /* true if last instruction was a wide        */
463         instruction *iptr;          /* current pointer into instruction array     */
464         int gp;                     /* global java instruction counter            */
465                                     /* inlining info for current method           */
466         inlining_methodinfo *inlinfo = inlining_rootinfo;
467         inlining_methodinfo *tmpinlinf;
468         int nextgp = -1;            /* start of next method to be inlined         */
469         int *label_index = NULL;    /* label redirection table                    */
470         int firstlocal = 0;         /* first local variable of method             */
471         xtable* nextex;             /* points next free entry in extable          */
472         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
473
474         u2 lineindex=0;
475         u2 currentline=0;
476         u2 linepcchange=0;
477
478         bool useinltmp;
479
480         if (compileverbose) {
481                 char logtext[MAXLOGTEXT];
482                 sprintf(logtext, "Parsing: ");
483                 utf_sprint(logtext+strlen(logtext), method->class->name);
484                 strcpy(logtext+strlen(logtext), ".");
485                 utf_sprint(logtext+strlen(logtext), method->name);
486                 utf_sprint(logtext+strlen(logtext), method->descriptor);
487                 log_text(logtext);
488         }
489
490         /* INLINING */
491         if (useinlining) {
492                 label_index = inlinfo->label_index;
493                 maxstack = cummaxstack;
494                 exceptiontablelength = cumextablelength;
495         }
496         
497         useinltmp = useinlining; /* FIXME remove this after debugging */
498     /*useinlining = false;*/     /* and merge the if-statements  */
499         
500         if (!useinlining) {
501                 cumjcodelength = jcodelength;
502
503         } else {
504                 tmpinlinf = (inlining_methodinfo*) list_first(inlinfo->inlinedmethods);
505                 if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
506         }
507
508         if ((opt_rt || opt_xta || opt_vta) && (pOpcodes == 2 || pOpcodes == 3)) {
509                 printf("PARSE method name =");
510                 utf_display(method->class->name);
511                 printf(".");
512                 method_display(method);
513                 printf(">\n\n");
514                 fflush(stdout);
515         }
516
517         if (opt_rt || opt_xta) { 
518                 RT_jit_parse(method);
519
520         } else {
521                 if (opt_vta) 
522                         printf("VTA requested, but not yet implemented\n");
523         }
524          
525
526         /* allocate instruction array and block index table */
527         
528         /* 1 additional for end ipc and 3 for loop unrolling */
529         
530         block_index = DMNEW(int, cumjcodelength + 4);
531         instructionstart = DMNEW(u1, cumjcodelength + 4);
532         memset(instructionstart,0,sizeof(u1) * (cumjcodelength + 4));
533
534         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
535         /* additional MONITOREXITS are reached by branches which are 3 bytes */
536         
537         iptr = instr = DMNEW(instruction, cumjcodelength + 5);
538
539         /* Zero the intermediate instructions array so we don't have any
540          * invalid pointers in it if we cannot finish analyse_stack(). */
541         memset(iptr,0,sizeof(instruction) * (cumjcodelength + 5));
542         
543         /* initialize block_index table (unrolled four times) */
544
545         {
546                 int *ip;
547         
548                 for (i = 0, ip = block_index; i <= cumjcodelength; i += 4, ip += 4) {
549                         ip[0] = 0;
550                         ip[1] = 0;
551                         ip[2] = 0;
552                         ip[3] = 0;
553                 }
554         }
555
556         /* compute branch targets of exception table */
557
558         extable = DMNEW(xtable, exceptiontablelength + 1);
559         /*
560           for (i = 0; i < method->exceptiontablelength; i++) {
561
562           p = extable[i].startpc = raw_extable[i].startpc;
563           if (useinlining) p = label_index[p];
564           bound_check(p);
565           block_insert(p);
566
567           p = extable[i].endpc = raw_extable[i].endpc;
568           if (useinlining) p = label_index[p];
569           bound_check1(p);
570           if (p < cumjcodelength)
571           block_insert(p);
572
573           p = extable[i].handlerpc = raw_extable[i].handlerpc;
574           bound_check(p);
575           block_insert(p);
576
577           extable[i].catchtype  = raw_extable[i].catchtype;
578
579           extable[i].next = NULL;
580           extable[i].down = &extable[i+1];
581           }
582         */
583
584         nextex = fillextable(extable, raw_extable, method->exceptiontablelength, label_index, &b_count);
585
586         s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
587
588 #ifdef USE_THREADS
589         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
590                 isleafmethod = false;
591         }                       
592 #endif
593
594         /* scan all java instructions */
595         currentline=0;
596         linepcchange=0;
597         if (jlinenumbercount==0) {
598                 lineindex=0;
599         } else {
600                 linepcchange=jlinenumbers[0].start_pc;
601         }
602
603         for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
604           
605                 /* DEBUG */       /*printf("p:%d gp:%d ",p,gp);*/
606
607                 /* mark this position as a valid instruction start */
608                 if (!iswide) {
609                         instructionstart[p] = 1;
610                         /*log_text("new start of instruction");*/
611                         if (linepcchange==p) {
612                                 if (jlinenumbercount>lineindex) {
613                                         currentline=jlinenumbers[lineindex].line_number;
614                                         lineindex++;
615                                         if (lineindex<jlinenumbercount)
616                                                 linepcchange=jlinenumbers[lineindex].start_pc;
617                                         /*printf("Line number changed to: %ld\n",currentline);*/
618                                 }
619                         }
620                 }
621
622                 /*INLINING*/
623                 if ((useinlining) && (gp == nextgp)) {
624                         u1 *tptr;
625                         bool *readonly = NULL;
626
627                         opcode = code_get_u1(p);
628                         nextp = p += jcommandsize[opcode];
629                         if (nextp > jcodelength)
630                                 panic("Unexpected end of bytecode");
631                         tmpinlinf = list_first(inlinfo->inlinedmethods);
632                         firstlocal = tmpinlinf->firstlocal;
633                         label_index = tmpinlinf->label_index;
634                         readonly = tmpinlinf->readonly;
635
636                         for (i = 0, tptr = tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1; i < tmpinlinf->method->paramcount; i++, tptr--) {
637                                 int op;
638
639                                 if ((i == 0) && inlineparamopt) {
640                                         OP1(ICMD_CLEAR_ARGREN, firstlocal);
641                                 }
642
643                                 if (!inlineparamopt || !readonly[i]) {
644                                         op = ICMD_ISTORE;
645
646                                 } else {
647                                         op = ICMD_READONLY_ARG;
648                                 }
649
650                                 op += *tptr;
651                                 OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
652
653                                 /* block_index[gp] |= (ipc << 1);*/  /*FIXME: necessary ? */
654                         }
655
656                         inlining_save_compiler_variables();
657                         inlining_set_compiler_variables(tmpinlinf);
658
659                         if (inlinfo->inlinedmethods == NULL) {
660                                 gp = -1;
661                         } else {
662                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
663                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
664                         }
665                         if (method->exceptiontablelength > 0) 
666                                 nextex = fillextable(nextex, method->exceptiontable, method->exceptiontablelength, label_index, &b_count);
667                         continue;
668                 }
669           
670                 opcode = code_get_u1(p);            /* fetch op code                  */
671
672           
673                 if (opt_rt && (pOpcodes == 2 || pOpcodes == 3)) {
674                         printf("Parse<%i> p=%i<%i<   opcode=<%i> %s\n",
675                                    pOpcodes, p, rt_jcodelength, opcode, icmd_names[opcode]);
676                 }
677           
678                 block_index[gp] |= (ipc << 1);      /* store intermediate count       */
679
680                 if (blockend) {
681                         block_insert(gp);               /* start new block                */
682                         blockend = false;
683                 }
684
685                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
686                 if (nextp > jcodelength)
687                         panic("Unexpected end of bytecode");
688                 s_count += stackreq[opcode];            /* compute stack element count    */
689
690                 switch (opcode) {
691                 case JAVA_NOP:
692                         break;
693
694                         /* pushing constants onto the stack p */
695
696                 case JAVA_BIPUSH:
697                         LOADCONST_I(code_get_s1(p+1));
698                         break;
699
700                 case JAVA_SIPUSH:
701                         LOADCONST_I(code_get_s2(p+1));
702                         break;
703
704                 case JAVA_LDC1:
705                         i = code_get_u1(p+1);
706                         goto pushconstantitem;
707                 case JAVA_LDC2:
708                 case JAVA_LDC2W:
709                         i = code_get_u2(p + 1);
710
711                 pushconstantitem:
712
713                         if (i >= class->cpcount) 
714                                 panic ("Attempt to access constant outside range");
715
716                         switch (class->cptags[i]) {
717                         case CONSTANT_Integer:
718                                 LOADCONST_I(((constant_integer*)
719                                                          (class->cpinfos[i]))->value);
720                                 break;
721                         case CONSTANT_Long:
722                                 LOADCONST_L(((constant_long*)
723                                                          (class->cpinfos[i]))->value);
724                                 break;
725                         case CONSTANT_Float:
726                                 LOADCONST_F(((constant_float*)
727                                                          (class->cpinfos[i]))->value);
728                                 break;
729                         case CONSTANT_Double:
730                                 LOADCONST_D(((constant_double*)
731                                                          (class->cpinfos[i]))->value);
732                                 break;
733                         case CONSTANT_String:
734                                 LOADCONST_A(literalstring_new((utf*)
735                                                                                           (class->cpinfos[i])));
736                                 break;
737                         default: panic("Invalid constant type to push");
738                         }
739                         break;
740
741                 case JAVA_ACONST_NULL:
742                         LOADCONST_A(NULL);
743                         break;
744
745                 case JAVA_ICONST_M1:
746                 case JAVA_ICONST_0:
747                 case JAVA_ICONST_1:
748                 case JAVA_ICONST_2:
749                 case JAVA_ICONST_3:
750                 case JAVA_ICONST_4:
751                 case JAVA_ICONST_5:
752                         LOADCONST_I(opcode - JAVA_ICONST_0);
753                         break;
754
755                 case JAVA_LCONST_0:
756                 case JAVA_LCONST_1:
757                         LOADCONST_L(opcode - JAVA_LCONST_0);
758                         break;
759
760                 case JAVA_FCONST_0:
761                 case JAVA_FCONST_1:
762                 case JAVA_FCONST_2:
763                         LOADCONST_F(opcode - JAVA_FCONST_0);
764                         break;
765
766                 case JAVA_DCONST_0:
767                 case JAVA_DCONST_1:
768                         LOADCONST_D(opcode - JAVA_DCONST_0);
769                         break;
770
771                         /* loading variables onto the stack */
772
773                 case JAVA_ILOAD:
774                 case JAVA_LLOAD:
775                 case JAVA_FLOAD:
776                 case JAVA_DLOAD:
777                 case JAVA_ALOAD:
778                         if (!iswide) {
779                                 i = code_get_u1(p + 1);
780                         } else {
781                                 i = code_get_u2(p + 1);
782                                 nextp = p + 3;
783                                 iswide = false;
784                         }
785                         OP1LOAD(opcode, i + firstlocal);
786                         break;
787
788                 case JAVA_ILOAD_0:
789                 case JAVA_ILOAD_1:
790                 case JAVA_ILOAD_2:
791                 case JAVA_ILOAD_3:
792                         OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
793                         break;
794
795                 case JAVA_LLOAD_0:
796                 case JAVA_LLOAD_1:
797                 case JAVA_LLOAD_2:
798                 case JAVA_LLOAD_3:
799                         OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
800                         break;
801
802                 case JAVA_FLOAD_0:
803                 case JAVA_FLOAD_1:
804                 case JAVA_FLOAD_2:
805                 case JAVA_FLOAD_3:
806                         OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
807                         break;
808
809                 case JAVA_DLOAD_0:
810                 case JAVA_DLOAD_1:
811                 case JAVA_DLOAD_2:
812                 case JAVA_DLOAD_3:
813                         OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
814                         break;
815
816                 case JAVA_ALOAD_0:
817                 case JAVA_ALOAD_1:
818                 case JAVA_ALOAD_2:
819                 case JAVA_ALOAD_3:
820                         OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
821                         break;
822
823                         /* storing stack values into local variables */
824
825                 case JAVA_ISTORE:
826                 case JAVA_LSTORE:
827                 case JAVA_FSTORE:
828                 case JAVA_DSTORE:
829                 case JAVA_ASTORE:
830                         if (!iswide) {
831                                 i = code_get_u1(p + 1);
832                         } else {
833                                 i = code_get_u2(p + 1);
834                                 iswide = false;
835                                 nextp = p + 3;
836                         }
837                         OP1STORE(opcode, i + firstlocal);
838                         break;
839
840                 case JAVA_ISTORE_0:
841                 case JAVA_ISTORE_1:
842                 case JAVA_ISTORE_2:
843                 case JAVA_ISTORE_3:
844                         OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
845                         break;
846
847                 case JAVA_LSTORE_0:
848                 case JAVA_LSTORE_1:
849                 case JAVA_LSTORE_2:
850                 case JAVA_LSTORE_3:
851                         OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
852                         break;
853
854                 case JAVA_FSTORE_0:
855                 case JAVA_FSTORE_1:
856                 case JAVA_FSTORE_2:
857                 case JAVA_FSTORE_3:
858                         OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
859                         break;
860
861                 case JAVA_DSTORE_0:
862                 case JAVA_DSTORE_1:
863                 case JAVA_DSTORE_2:
864                 case JAVA_DSTORE_3:
865                         OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
866                         break;
867
868                 case JAVA_ASTORE_0:
869                 case JAVA_ASTORE_1:
870                 case JAVA_ASTORE_2:
871                 case JAVA_ASTORE_3:
872                         OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
873                         break;
874
875                 case JAVA_IINC:
876                         {
877                                 int v;
878                                 
879                                 if (!iswide) {
880                                         i = code_get_u1(p + 1);
881                                         v = code_get_s1(p + 2);
882
883                                 } else {
884                                         i = code_get_u2(p + 1);
885                                         v = code_get_s2(p + 3);
886                                         iswide = false;
887                                         nextp = p + 5;
888                                 }
889                                 INDEX_ONEWORD(i + firstlocal);
890                                 OP2I(opcode, i + firstlocal, v);
891                         }
892                         break;
893
894                         /* wider index for loading, storing and incrementing */
895
896                 case JAVA_WIDE:
897                         iswide = true;
898                         nextp = p + 1;
899                         break;
900
901                         /* managing arrays ************************************************/
902
903                 case JAVA_NEWARRAY:
904                         OP2I(ICMD_CHECKASIZE, 0, 0);
905                         switch (code_get_s1(p + 1)) {
906                         case 4:
907                                 BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR,currentline);
908                                 break;
909                         case 5:
910                                 BUILTIN1(BUILTIN_newarray_char, TYPE_ADR,currentline);
911                                 break;
912                         case 6:
913                                 BUILTIN1(BUILTIN_newarray_float, TYPE_ADR,currentline);
914                                 break;
915                         case 7:
916                                 BUILTIN1(BUILTIN_newarray_double, TYPE_ADR,currentline);
917                                 break;
918                         case 8:
919                                 BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR,currentline);
920                                 break;
921                         case 9:
922                                 BUILTIN1(BUILTIN_newarray_short, TYPE_ADR,currentline);
923                                 break;
924                         case 10:
925                                 BUILTIN1(BUILTIN_newarray_int, TYPE_ADR,currentline);
926                                 break;
927                         case 11:
928                                 BUILTIN1(BUILTIN_newarray_long, TYPE_ADR,currentline);
929                                 break;
930                         default: panic("Invalid array-type to create");
931                         }
932                         break;
933
934                 case JAVA_ANEWARRAY:
935                         OP2I(ICMD_CHECKASIZE, 0, 0);
936                         i = code_get_u2(p + 1);
937                         {
938                                         classinfo *component = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
939                                         LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
940
941                                 s_count++;
942
943                                 BUILTIN2(BUILTIN_newarray, TYPE_ADR,currentline);
944                         }
945                         break;
946
947                 case JAVA_MULTIANEWARRAY:
948                         isleafmethod=false;
949                         i = code_get_u2(p + 1);
950                         {
951                                 int v = code_get_u1(p + 3);
952                                 vftbl *arrayvftbl = ((classinfo*)class_getconstant (class, i, CONSTANT_Class))->vftbl;
953                                 OP2A(opcode, v, arrayvftbl,currentline);                        
954                         }
955                         break;
956
957                 case JAVA_IFEQ:
958                 case JAVA_IFLT:
959                 case JAVA_IFLE:
960                 case JAVA_IFNE:
961                 case JAVA_IFGT:
962                 case JAVA_IFGE:
963                 case JAVA_IFNULL:
964                 case JAVA_IFNONNULL:
965                 case JAVA_IF_ICMPEQ:
966                 case JAVA_IF_ICMPNE:
967                 case JAVA_IF_ICMPLT:
968                 case JAVA_IF_ICMPGT:
969                 case JAVA_IF_ICMPLE:
970                 case JAVA_IF_ICMPGE:
971                 case JAVA_IF_ACMPEQ:
972                 case JAVA_IF_ACMPNE:
973                 case JAVA_GOTO:
974                 case JAVA_JSR:
975                         i = p + code_get_s2(p + 1);
976                         if (useinlining) { 
977                                 debug_writebranch;
978                                 i = label_index[i];
979                         }
980                         bound_check(i);
981                         block_insert(i);
982                         blockend = true;
983                         OP1(opcode, i);
984                         break;
985                 case JAVA_GOTO_W:
986                 case JAVA_JSR_W:
987                         i = p + code_get_s4(p + 1);
988                         if (useinlining) { 
989                                 debug_writebranch;
990                                 i = label_index[i];
991                         }
992                         bound_check(i);
993                         block_insert(i);
994                         blockend = true;
995                         OP1(opcode, i);
996                         break;
997
998                 case JAVA_RET:
999                         if (!iswide) {
1000                                 i = code_get_u1(p + 1);
1001                         } else {
1002                                 i = code_get_u2(p + 1);
1003                                 nextp = p + 3;
1004                                 iswide = false;
1005                         }
1006                         blockend = true;
1007                                 
1008                         /*
1009                           if (isinlinedmethod) {
1010                           OP1(ICMD_GOTO, inlinfo->stopgp);
1011                           break;
1012                           }*/
1013
1014                         OP1LOAD(opcode, i + firstlocal);
1015                         break;
1016
1017                 case JAVA_IRETURN:
1018                 case JAVA_LRETURN:
1019                 case JAVA_FRETURN:
1020                 case JAVA_DRETURN:
1021                 case JAVA_ARETURN:
1022                 case JAVA_RETURN:
1023                         if (isinlinedmethod) {
1024                                 /*                                      if (p==jcodelength-1) {*/ /* return is at end of inlined method */
1025                                 /*                                              OP(ICMD_NOP); */
1026                                 /*                                              break; */
1027                                 /*                                      } */
1028                                 blockend = true;
1029                                 OP1(ICMD_GOTO, inlinfo->stopgp);
1030                                 break;
1031                         }
1032
1033                         blockend = true;
1034                         OP(opcode);
1035                         break;
1036
1037                 case JAVA_ATHROW:
1038                         blockend = true;
1039                         OP(opcode);
1040                         break;
1041                                 
1042
1043                         /* table jumps ********************************/
1044
1045                 case JAVA_LOOKUPSWITCH:
1046                         {
1047                                 s4 num, j;
1048                                 s4 *tablep;
1049                                 s4 prevvalue;
1050
1051                                 blockend = true;
1052                                 nextp = ALIGN((p + 1), 4);
1053                                 if (nextp + 8 > jcodelength)
1054                                         panic("Unexpected end of bytecode");
1055                                 if (!useinlining) {
1056                                         tablep = (s4*)(jcode + nextp);
1057
1058                                 } else {
1059                                         num = code_get_u4(nextp + 4);
1060                                         tablep = DMNEW(s4, num * 2 + 2);
1061                                 }
1062
1063                                 OP2A(opcode, 0, tablep,currentline);
1064
1065                                 /* default target */
1066
1067                                 j =  p + code_get_s4(nextp);
1068                                 if (useinlining) 
1069                                         j = label_index[j];
1070                                 *tablep = j;     /* restore for little endian */
1071                                 tablep++;
1072                                 nextp += 4;
1073                                 bound_check(j);
1074                                 block_insert(j);
1075
1076                                 /* number of pairs */
1077
1078                                 num = code_get_u4(nextp);
1079                                 *tablep = num;
1080                                 tablep++;
1081                                 nextp += 4;
1082
1083                                 if (nextp + 8*(num) > jcodelength)
1084                                         panic("Unexpected end of bytecode");
1085
1086                                 for (i = 0; i < num; i++) {
1087                                         /* value */
1088
1089                                         j = code_get_s4(nextp);
1090                                         *tablep = j; /* restore for little endian */
1091                                         tablep++;
1092                                         nextp += 4;
1093
1094                                         /* check if the lookup table is sorted correctly */
1095                                         
1096                                         if (i && (j <= prevvalue))
1097                                                 panic("invalid LOOKUPSWITCH: table not sorted");
1098                                         prevvalue = j;
1099
1100                                         /* target */
1101
1102                                         j = p + code_get_s4(nextp);
1103                                         if (useinlining)
1104                                                 j = label_index[j];
1105                                         *tablep = j; /* restore for little endian */
1106                                         tablep++;
1107                                         nextp += 4;
1108                                         bound_check(j);
1109                                         block_insert(j);
1110                                 }
1111
1112                                 break;
1113                         }
1114
1115
1116                 case JAVA_TABLESWITCH:
1117                         {
1118                                 s4 num, j;
1119                                 s4 *tablep;
1120
1121                                 blockend = true;
1122                                 nextp = ALIGN((p + 1), 4);
1123                                 if (nextp + 12 > jcodelength)
1124                                         panic("Unexpected end of bytecode");
1125                                 if (!useinlining) {
1126                                         tablep = (s4*)(jcode + nextp);
1127
1128                                 } else {
1129                                         num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
1130                                         tablep = DMNEW(s4, num + 1 + 3);
1131                                 }
1132
1133                                 OP2A(opcode, 0, tablep,currentline);
1134
1135                                 /* default target */
1136
1137                                 j = p + code_get_s4(nextp);
1138                                 if (useinlining)
1139                                         j = label_index[j];
1140                                 *tablep = j;     /* restore for little endian */
1141                                 tablep++;
1142                                 nextp += 4;
1143                                 bound_check(j);
1144                                 block_insert(j);
1145
1146                                 /* lower bound */
1147
1148                                 j = code_get_s4(nextp);
1149                                 *tablep = j;     /* restore for little endian */
1150                                 tablep++;
1151                                 nextp += 4;
1152
1153                                 /* upper bound */
1154
1155                                 num = code_get_s4(nextp);
1156                                 *tablep = num;   /* restore for little endian */
1157                                 tablep++;
1158                                 nextp += 4;
1159
1160                                 num -= j;  /* difference of upper - lower */
1161                                 if (num < 0)
1162                                         panic("invalid TABLESWITCH: upper bound < lower bound");
1163
1164                                 if (nextp + 4*(num+1) > jcodelength)
1165                                         panic("Unexpected end of bytecode");
1166
1167                                 for (i = 0; i <= num; i++) {
1168                                         j = p + code_get_s4(nextp);
1169                                         if (useinlining)
1170                                                 j = label_index[j];
1171                                         *tablep = j; /* restore for little endian */
1172                                         tablep++;
1173                                         nextp += 4;
1174                                         bound_check(j);
1175                                         block_insert(j);
1176                                 }
1177
1178                                 break;
1179                         }
1180
1181
1182                         /* load and store of object fields *******************/
1183
1184                 case JAVA_AASTORE:
1185                         BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
1186                         break;
1187
1188                 case JAVA_PUTSTATIC:
1189                 case JAVA_GETSTATIC:
1190                         i = code_get_u2(p + 1);
1191                         {
1192                                 constant_FMIref *fr;
1193                                 fieldinfo *fi;
1194                                 fr = class_getconstant(class, i, CONSTANT_Fieldref);
1195                                 fi = class_findfield(fr->class, fr->name, fr->descriptor);
1196                                 OP2A(opcode, fi->type, fi,currentline);
1197                                 if (!fi->class->initialized) {
1198                                         isleafmethod = false;
1199                                 }
1200                         }
1201                         break;
1202
1203                 case JAVA_PUTFIELD:
1204                 case JAVA_GETFIELD:
1205                         i = code_get_u2(p + 1);
1206                         {
1207                                 constant_FMIref *fr;
1208                                 fieldinfo *fi;
1209                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1210                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1211                                 OP2A(opcode, fi->type, fi,currentline);
1212                         }
1213                         break;
1214
1215
1216                         /* method invocation *****/
1217
1218                 case JAVA_INVOKESTATIC:
1219                         i = code_get_u2(p + 1);
1220                         {
1221                                 constant_FMIref *mr;
1222                                 methodinfo *mi;
1223                                 
1224                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
1225                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1226                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1227                                         /*RTAprint*/    {printf(" method name =");
1228                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1229                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE STATIC\n");
1230                                         /*RTAprint*/    fflush(stdout);}
1231                                 if (!(mi->flags & ACC_STATIC))
1232                                         panic ("Static/Nonstatic mismatch calling static method");
1233                                 descriptor2types(mi);
1234
1235                                 isleafmethod=false;
1236                                 OP2A(opcode, mi->paramcount, mi,currentline);
1237                         }
1238                         break;
1239
1240                 case JAVA_INVOKESPECIAL:
1241                 case JAVA_INVOKEVIRTUAL:
1242                         i = code_get_u2(p + 1);
1243                         {
1244                                 constant_FMIref *mr;
1245                                 methodinfo *mi;
1246
1247                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
1248                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1249                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1250                                         /*RTAprint*/    {printf(" method name =");
1251                                         method_display(mi);
1252                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1253                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
1254                                         /*RTAprint*/    fflush(stdout);}
1255
1256                                 if (mi->flags & ACC_STATIC)
1257                                         panic ("Static/Nonstatic mismatch calling static method");
1258                                 descriptor2types(mi);
1259                                 isleafmethod=false;
1260                                 OP2A(opcode, mi->paramcount, mi,currentline);
1261                         }
1262                         break;
1263
1264                 case JAVA_INVOKEINTERFACE:
1265                         i = code_get_u2(p + 1);
1266                         {
1267                                 constant_FMIref *mr;
1268                                 methodinfo *mi;
1269                                 
1270                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
1271                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1272                                 if (mi->flags & ACC_STATIC)
1273                                         panic ("Static/Nonstatic mismatch calling static method");
1274                                 descriptor2types(mi);
1275                                 isleafmethod=false;
1276                                 OP2A(opcode, mi->paramcount, mi,currentline);
1277                         }
1278                         break;
1279
1280                         /* miscellaneous object operations *******/
1281
1282                 case JAVA_NEW:
1283                         i = code_get_u2 (p+1);
1284
1285                         LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1286                         s_count++;
1287                         BUILTIN1(BUILTIN_new, TYPE_ADR,currentline);
1288                         break;
1289
1290                 case JAVA_CHECKCAST:
1291 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1292                         isleafmethod = false;
1293 #endif
1294                         i = code_get_u2(p+1);
1295                                 {
1296                                         classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
1297                                         if (cls->vftbl->arraydesc) {
1298                                                 /* array type cast-check */
1299                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1300                                                 s_count++;
1301                                                 BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
1302                                         }
1303                                         else { /* object type cast-check */
1304                                                 /*
1305 +                                                 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1306 +                                                 s_count++;
1307 +                                                 BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
1308 +                                               */
1309                                                 OP2A(opcode, 1, cls,currentline);
1310                                         }
1311                                 }
1312
1313                         break;
1314
1315                 case JAVA_INSTANCEOF:
1316 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1317                         isleafmethod = false;
1318 #endif
1319                         i = code_get_u2(p+1);
1320
1321                                 {
1322                                         classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
1323                                         if (cls->vftbl->arraydesc) {
1324                                                 /* array type cast-check */
1325                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1326                                                 s_count++;
1327                                                 BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT,currentline);
1328                                         }
1329                                         else { /* object type cast-check */
1330                                                 /*
1331                                                   LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1332                                                   s_count++;
1333                                                   BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
1334 +                                               */
1335                                                 OP2A(opcode, 1, cls,currentline);
1336                                         }
1337                                 }
1338                         break;
1339
1340                 case JAVA_MONITORENTER:
1341 #ifdef USE_THREADS
1342                         if (checksync) {
1343                                 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
1344                         } else
1345 #endif
1346                                 {
1347                                         OP(ICMD_NULLCHECKPOP);
1348                                 }
1349                         break;
1350
1351                 case JAVA_MONITOREXIT:
1352 #ifdef USE_THREADS
1353                         if (checksync) {
1354                                 BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
1355                         }
1356                         else
1357 #endif
1358                                 {
1359                                         OP(ICMD_POP);
1360                                 }
1361                         break;
1362
1363                         /* any other basic operation **************************************/
1364
1365                 case JAVA_IDIV:
1366                         OP(opcode);
1367                         break;
1368
1369                 case JAVA_IREM:
1370                         OP(opcode);
1371                         break;
1372
1373                 case JAVA_LDIV:
1374                         OP(opcode);
1375                         break;
1376
1377                 case JAVA_LREM:
1378                         OP(opcode);
1379                         break;
1380
1381                 case JAVA_FREM:
1382 #if defined(__I386__)
1383                         OP(opcode);
1384 #else
1385                         BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
1386 #endif
1387                         break;
1388
1389                 case JAVA_DREM:
1390 #if defined(__I386__)
1391                         OP(opcode);
1392 #else
1393                         BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
1394 #endif
1395                         break;
1396
1397                 case JAVA_F2I:
1398 #if defined(__ALPHA__)
1399                         if (!opt_noieee) {
1400                                 BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
1401                         } else
1402 #endif
1403                                 {
1404                                         OP(opcode);
1405                                 }
1406                         break;
1407
1408                 case JAVA_F2L:
1409 #if defined(__ALPHA__)
1410                         if (!opt_noieee) {
1411                                 BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
1412                         } else 
1413 #endif
1414                                 {
1415                                         OP(opcode);
1416                                 }
1417                         break;
1418
1419                 case JAVA_D2I:
1420 #if defined(__ALPHA__)
1421                         if (!opt_noieee) {
1422                                 BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
1423                         } else
1424 #endif
1425                                 {
1426                                         OP(opcode);
1427                                 }
1428                         break;
1429
1430                 case JAVA_D2L:
1431 #if defined(__ALPHA__)
1432                         if (!opt_noieee) {
1433                                 BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
1434                         } else
1435 #endif
1436                                 {
1437                                         OP(opcode);
1438                                 }
1439                         break;
1440
1441                 case JAVA_BREAKPOINT:
1442                         panic("Illegal opcode Breakpoint encountered");
1443                         break;
1444
1445                   case 186: /* unused opcode */
1446                 case 203:
1447                 case 204:
1448                 case 205:
1449                 case 206:
1450                 case 207:
1451                 case 208:
1452                 case 209:
1453                 case 210:
1454                 case 211:
1455                 case 212:
1456                 case 213:
1457                 case 214:
1458                 case 215:
1459                 case 216:
1460                 case 217:
1461                 case 218:
1462                 case 219:
1463                 case 220:
1464                 case 221:
1465                 case 222:
1466                 case 223:
1467                 case 224:
1468                 case 225:
1469                 case 226:
1470                 case 227:
1471                 case 228:
1472                 case 229:
1473                 case 230:
1474                 case 231:
1475                 case 232:
1476                 case 233:
1477                 case 234:
1478                 case 235:
1479                 case 236:
1480                 case 237:
1481                 case 238:
1482                 case 239:
1483                 case 240:
1484                 case 241:
1485                 case 242:
1486                 case 243:
1487                 case 244:
1488                 case 245:
1489                 case 246:
1490                 case 247:
1491                 case 248:
1492                 case 249:
1493                 case 250:
1494                 case 251:
1495                 case 252:
1496                 case 253:
1497                 case 254:
1498                 case 255:
1499                         printf("Illegal opcode %d at instr %d\n", opcode, ipc);
1500                         panic("Illegal opcode encountered");
1501                         break;
1502
1503                 default:
1504                         OP(opcode);
1505                         break;
1506                                 
1507                 } /* end switch */
1508
1509                 /* If WIDE was used correctly, iswide should have been reset by now. */
1510                 if (iswide && opcode != JAVA_WIDE)
1511                         panic("Illegal instruction: WIDE before incompatible opcode");
1512                 
1513                 /* INLINING */
1514                   
1515                 if (isinlinedmethod && p == jcodelength - 1) { /* end of an inlined method */
1516                         /*                printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
1517                         gp = inlinfo->stopgp; 
1518                         inlining_restore_compiler_variables();
1519                         list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1520                         if (inlinfo->inlinedmethods == NULL) {
1521                                 nextgp = -1;
1522                         } else {
1523                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
1524                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1525                         }
1526                         /*                printf("nextpgp: %d\n", nextgp); */
1527                         label_index=inlinfo->label_index;
1528                         firstlocal = inlinfo->firstlocal;
1529                 }
1530         } /* end for */
1531
1532         if (p != jcodelength)
1533                 panic("Command-sequence crosses code-boundary");
1534
1535         if (!blockend)
1536                 panic("Code does not end with branch/return/athrow - stmt");    
1537
1538         /* adjust block count if target 0 is not first intermediate instruction   */
1539
1540         if (!block_index[0] || (block_index[0] > 1))
1541                 b_count++;
1542
1543         /* copy local to global variables   */
1544
1545         instr_count = ipc;
1546         block_count = b_count;
1547         stack_count = s_count + block_count * maxstack;
1548
1549         /* allocate stack table */
1550
1551         stack = DMNEW(stackelement, stack_count);
1552
1553         {
1554                 basicblock  *bptr;
1555
1556                 bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1557
1558                 b_count = 0;
1559                 c_debug_nr = 0;
1560         
1561                 /* additional block if target 0 is not first intermediate instruction     */
1562
1563                 if (!block_index[0] || (block_index[0] > 1)) {
1564                         bptr->iinstr = instr;
1565                         bptr->mpc = -1;
1566                         bptr->flags = -1;
1567                         bptr->type = BBTYPE_STD;
1568                         bptr->branchrefs = NULL;
1569                         bptr->pre_count = 0;
1570                         bptr->debug_nr = c_debug_nr++;
1571                         bptr++;
1572                         b_count++;
1573                         (bptr - 1)->next = bptr;
1574                 }
1575
1576                 /* allocate blocks */
1577
1578                 for (p = 0; p < cumjcodelength; p++) {
1579                         if (block_index[p] & 1) {
1580                                 /* check if this block starts at the beginning of an instruction */
1581                                 if (!instructionstart[p])
1582                                         panic("Branch into middle of instruction");
1583                                 /* allocate the block */
1584                                 bptr->iinstr = instr + (block_index[p] >> 1);
1585                                 bptr->debug_nr = c_debug_nr++;
1586                                 if (b_count != 0)
1587                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1588                                 bptr->mpc = -1;
1589                                 bptr->flags = -1;
1590                                 bptr->lflags = 0;
1591                                 bptr->type = BBTYPE_STD;
1592                                 bptr->branchrefs = NULL;
1593                                 block_index[p] = b_count;
1594                                 bptr->pre_count = 0;
1595                                 bptr++;
1596                                 b_count++;
1597                                 (bptr - 1)->next = bptr;
1598                         }
1599                 }
1600
1601                 /* allocate additional block at end */
1602
1603                 bptr->instack = bptr->outstack = NULL;
1604                 bptr->indepth = bptr->outdepth = 0;
1605                 bptr->iinstr = NULL;
1606                 (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1607                 bptr->icount = 0;
1608                 bptr->mpc = -1;
1609                 bptr->flags = -1;
1610                 bptr->lflags = 0;
1611                 bptr->type = BBTYPE_STD;
1612                 bptr->branchrefs = NULL;
1613                 bptr->pre_count = 0;
1614                 bptr->debug_nr = c_debug_nr++;
1615                 (bptr - 1)->next = bptr;
1616                 bptr->next = NULL;
1617
1618                 last_block = bptr;
1619
1620                 if (exceptiontablelength > 0)
1621                         extable[exceptiontablelength - 1].down = NULL;
1622                 else
1623                         extable = NULL;
1624
1625                 for (i = 0; i < exceptiontablelength; ++i) {
1626                         p = extable[i].startpc;
1627                         extable[i].start = block + block_index[p];
1628
1629                         p = extable[i].endpc;
1630                         extable[i].end = (p == cumjcodelength) ? last_block : (block + block_index[p]);
1631
1632                         p = extable[i].handlerpc;
1633                         extable[i].handler = block + block_index[p];
1634             }
1635         }
1636         
1637         if (useinlining) inlining_cleanup();
1638         useinlining = useinltmp;
1639 }
1640
1641
1642 /*
1643  * These are local overrides for various environment variables in Emacs.
1644  * Please do not remove this and leave it at the end of the file, where
1645  * Emacs will automagically detect them.
1646  * ---------------------------------------------------------------------
1647  * Local variables:
1648  * mode: c
1649  * indent-tabs-mode: t
1650  * c-basic-offset: 4
1651  * tab-width: 4
1652  * End:
1653  */