retrieve line number information
[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 941 2004-03-06 17:27:56Z 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                         if (linepcchange==p) {
611                                 if (jlinenumbercount>lineindex) {
612                                         currentline=jlinenumbers[lineindex].line_number;
613                                         lineindex++;
614                                         if (lineindex<jlinenumbercount)
615                                                 linepcchange=jlinenumbers[lineindex].start_pc;
616 /*                                      printf("Line number changed to: %ld\n",currentline);*/
617                                 }
618                         }
619                 }
620
621                 /*INLINING*/
622                 if ((useinlining) && (gp == nextgp)) {
623                         u1 *tptr;
624                         bool *readonly = NULL;
625
626                         opcode = code_get_u1(p);
627                         nextp = p += jcommandsize[opcode];
628                         if (nextp > jcodelength)
629                                 panic("Unexpected end of bytecode");
630                         tmpinlinf = list_first(inlinfo->inlinedmethods);
631                         firstlocal = tmpinlinf->firstlocal;
632                         label_index = tmpinlinf->label_index;
633                         readonly = tmpinlinf->readonly;
634
635                         for (i = 0, tptr = tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1; i < tmpinlinf->method->paramcount; i++, tptr--) {
636                                 int op;
637
638                                 if ((i == 0) && inlineparamopt) {
639                                         OP1(ICMD_CLEAR_ARGREN, firstlocal);
640                                 }
641
642                                 if (!inlineparamopt || !readonly[i]) {
643                                         op = ICMD_ISTORE;
644
645                                 } else {
646                                         op = ICMD_READONLY_ARG;
647                                 }
648
649                                 op += *tptr;
650                                 OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
651
652                                 /* block_index[gp] |= (ipc << 1);*/  /*FIXME: necessary ? */
653                         }
654
655                         inlining_save_compiler_variables();
656                         inlining_set_compiler_variables(tmpinlinf);
657
658                         if (inlinfo->inlinedmethods == NULL) {
659                                 gp = -1;
660                         } else {
661                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
662                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
663                         }
664                         if (method->exceptiontablelength > 0) 
665                                 nextex = fillextable(nextex, method->exceptiontable, method->exceptiontablelength, label_index, &b_count);
666                         continue;
667                 }
668           
669                 opcode = code_get_u1(p);            /* fetch op code                  */
670
671           
672                 if (opt_rt && (pOpcodes == 2 || pOpcodes == 3)) {
673                         printf("Parse<%i> p=%i<%i<   opcode=<%i> %s\n",
674                                    pOpcodes, p, rt_jcodelength, opcode, icmd_names[opcode]);
675                 }
676           
677                 block_index[gp] |= (ipc << 1);      /* store intermediate count       */
678
679                 if (blockend) {
680                         block_insert(gp);               /* start new block                */
681                         blockend = false;
682                 }
683
684                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
685                 if (nextp > jcodelength)
686                         panic("Unexpected end of bytecode");
687                 s_count += stackreq[opcode];            /* compute stack element count    */
688
689                 switch (opcode) {
690                 case JAVA_NOP:
691                         break;
692
693                         /* pushing constants onto the stack p */
694
695                 case JAVA_BIPUSH:
696                         LOADCONST_I(code_get_s1(p+1));
697                         break;
698
699                 case JAVA_SIPUSH:
700                         LOADCONST_I(code_get_s2(p+1));
701                         break;
702
703                 case JAVA_LDC1:
704                         i = code_get_u1(p+1);
705                         goto pushconstantitem;
706                 case JAVA_LDC2:
707                 case JAVA_LDC2W:
708                         i = code_get_u2(p + 1);
709
710                 pushconstantitem:
711
712                         if (i >= class->cpcount) 
713                                 panic ("Attempt to access constant outside range");
714
715                         switch (class->cptags[i]) {
716                         case CONSTANT_Integer:
717                                 LOADCONST_I(((constant_integer*)
718                                                          (class->cpinfos[i]))->value);
719                                 break;
720                         case CONSTANT_Long:
721                                 LOADCONST_L(((constant_long*)
722                                                          (class->cpinfos[i]))->value);
723                                 break;
724                         case CONSTANT_Float:
725                                 LOADCONST_F(((constant_float*)
726                                                          (class->cpinfos[i]))->value);
727                                 break;
728                         case CONSTANT_Double:
729                                 LOADCONST_D(((constant_double*)
730                                                          (class->cpinfos[i]))->value);
731                                 break;
732                         case CONSTANT_String:
733                                 LOADCONST_A(literalstring_new((utf*)
734                                                                                           (class->cpinfos[i])));
735                                 break;
736                         default: panic("Invalid constant type to push");
737                         }
738                         break;
739
740                 case JAVA_ACONST_NULL:
741                         LOADCONST_A(NULL);
742                         break;
743
744                 case JAVA_ICONST_M1:
745                 case JAVA_ICONST_0:
746                 case JAVA_ICONST_1:
747                 case JAVA_ICONST_2:
748                 case JAVA_ICONST_3:
749                 case JAVA_ICONST_4:
750                 case JAVA_ICONST_5:
751                         LOADCONST_I(opcode - JAVA_ICONST_0);
752                         break;
753
754                 case JAVA_LCONST_0:
755                 case JAVA_LCONST_1:
756                         LOADCONST_L(opcode - JAVA_LCONST_0);
757                         break;
758
759                 case JAVA_FCONST_0:
760                 case JAVA_FCONST_1:
761                 case JAVA_FCONST_2:
762                         LOADCONST_F(opcode - JAVA_FCONST_0);
763                         break;
764
765                 case JAVA_DCONST_0:
766                 case JAVA_DCONST_1:
767                         LOADCONST_D(opcode - JAVA_DCONST_0);
768                         break;
769
770                         /* loading variables onto the stack */
771
772                 case JAVA_ILOAD:
773                 case JAVA_LLOAD:
774                 case JAVA_FLOAD:
775                 case JAVA_DLOAD:
776                 case JAVA_ALOAD:
777                         if (!iswide) {
778                                 i = code_get_u1(p + 1);
779                         } else {
780                                 i = code_get_u2(p + 1);
781                                 nextp = p + 3;
782                                 iswide = false;
783                         }
784                         OP1LOAD(opcode, i + firstlocal);
785                         break;
786
787                 case JAVA_ILOAD_0:
788                 case JAVA_ILOAD_1:
789                 case JAVA_ILOAD_2:
790                 case JAVA_ILOAD_3:
791                         OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
792                         break;
793
794                 case JAVA_LLOAD_0:
795                 case JAVA_LLOAD_1:
796                 case JAVA_LLOAD_2:
797                 case JAVA_LLOAD_3:
798                         OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
799                         break;
800
801                 case JAVA_FLOAD_0:
802                 case JAVA_FLOAD_1:
803                 case JAVA_FLOAD_2:
804                 case JAVA_FLOAD_3:
805                         OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
806                         break;
807
808                 case JAVA_DLOAD_0:
809                 case JAVA_DLOAD_1:
810                 case JAVA_DLOAD_2:
811                 case JAVA_DLOAD_3:
812                         OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
813                         break;
814
815                 case JAVA_ALOAD_0:
816                 case JAVA_ALOAD_1:
817                 case JAVA_ALOAD_2:
818                 case JAVA_ALOAD_3:
819                         OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
820                         break;
821
822                         /* storing stack values into local variables */
823
824                 case JAVA_ISTORE:
825                 case JAVA_LSTORE:
826                 case JAVA_FSTORE:
827                 case JAVA_DSTORE:
828                 case JAVA_ASTORE:
829                         if (!iswide) {
830                                 i = code_get_u1(p + 1);
831                         } else {
832                                 i = code_get_u2(p + 1);
833                                 iswide = false;
834                                 nextp = p + 3;
835                         }
836                         OP1STORE(opcode, i + firstlocal);
837                         break;
838
839                 case JAVA_ISTORE_0:
840                 case JAVA_ISTORE_1:
841                 case JAVA_ISTORE_2:
842                 case JAVA_ISTORE_3:
843                         OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
844                         break;
845
846                 case JAVA_LSTORE_0:
847                 case JAVA_LSTORE_1:
848                 case JAVA_LSTORE_2:
849                 case JAVA_LSTORE_3:
850                         OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
851                         break;
852
853                 case JAVA_FSTORE_0:
854                 case JAVA_FSTORE_1:
855                 case JAVA_FSTORE_2:
856                 case JAVA_FSTORE_3:
857                         OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
858                         break;
859
860                 case JAVA_DSTORE_0:
861                 case JAVA_DSTORE_1:
862                 case JAVA_DSTORE_2:
863                 case JAVA_DSTORE_3:
864                         OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
865                         break;
866
867                 case JAVA_ASTORE_0:
868                 case JAVA_ASTORE_1:
869                 case JAVA_ASTORE_2:
870                 case JAVA_ASTORE_3:
871                         OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
872                         break;
873
874                 case JAVA_IINC:
875                         {
876                                 int v;
877                                 
878                                 if (!iswide) {
879                                         i = code_get_u1(p + 1);
880                                         v = code_get_s1(p + 2);
881
882                                 } else {
883                                         i = code_get_u2(p + 1);
884                                         v = code_get_s2(p + 3);
885                                         iswide = false;
886                                         nextp = p + 5;
887                                 }
888                                 INDEX_ONEWORD(i + firstlocal);
889                                 OP2I(opcode, i + firstlocal, v);
890                         }
891                         break;
892
893                         /* wider index for loading, storing and incrementing */
894
895                 case JAVA_WIDE:
896                         iswide = true;
897                         nextp = p + 1;
898                         break;
899
900                         /* managing arrays ************************************************/
901
902                 case JAVA_NEWARRAY:
903                         OP2I(ICMD_CHECKASIZE, 0, 0);
904                         switch (code_get_s1(p + 1)) {
905                         case 4:
906                                 BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR,currentline);
907                                 break;
908                         case 5:
909                                 BUILTIN1(BUILTIN_newarray_char, TYPE_ADR,currentline);
910                                 break;
911                         case 6:
912                                 BUILTIN1(BUILTIN_newarray_float, TYPE_ADR,currentline);
913                                 break;
914                         case 7:
915                                 BUILTIN1(BUILTIN_newarray_double, TYPE_ADR,currentline);
916                                 break;
917                         case 8:
918                                 BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR,currentline);
919                                 break;
920                         case 9:
921                                 BUILTIN1(BUILTIN_newarray_short, TYPE_ADR,currentline);
922                                 break;
923                         case 10:
924                                 BUILTIN1(BUILTIN_newarray_int, TYPE_ADR,currentline);
925                                 break;
926                         case 11:
927                                 BUILTIN1(BUILTIN_newarray_long, TYPE_ADR,currentline);
928                                 break;
929                         default: panic("Invalid array-type to create");
930                         }
931                         break;
932
933                 case JAVA_ANEWARRAY:
934                         OP2I(ICMD_CHECKASIZE, 0, 0);
935                         i = code_get_u2(p + 1);
936                         {
937                                         classinfo *component = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
938                                         LOADCONST_A_BUILTIN(class_array_of(component)->vftbl);
939
940                                 s_count++;
941
942                                 BUILTIN2(BUILTIN_newarray, TYPE_ADR,currentline);
943                         }
944                         break;
945
946                 case JAVA_MULTIANEWARRAY:
947                         isleafmethod=false;
948                         i = code_get_u2(p + 1);
949                         {
950                                 int v = code_get_u1(p + 3);
951                                 vftbl *arrayvftbl = ((classinfo*)class_getconstant (class, i, CONSTANT_Class))->vftbl;
952                                 OP2A(opcode, v, arrayvftbl,currentline);                        
953                         }
954                         break;
955
956                 case JAVA_IFEQ:
957                 case JAVA_IFLT:
958                 case JAVA_IFLE:
959                 case JAVA_IFNE:
960                 case JAVA_IFGT:
961                 case JAVA_IFGE:
962                 case JAVA_IFNULL:
963                 case JAVA_IFNONNULL:
964                 case JAVA_IF_ICMPEQ:
965                 case JAVA_IF_ICMPNE:
966                 case JAVA_IF_ICMPLT:
967                 case JAVA_IF_ICMPGT:
968                 case JAVA_IF_ICMPLE:
969                 case JAVA_IF_ICMPGE:
970                 case JAVA_IF_ACMPEQ:
971                 case JAVA_IF_ACMPNE:
972                 case JAVA_GOTO:
973                 case JAVA_JSR:
974                         i = p + code_get_s2(p + 1);
975                         if (useinlining) { 
976                                 debug_writebranch;
977                                 i = label_index[i];
978                         }
979                         bound_check(i);
980                         block_insert(i);
981                         blockend = true;
982                         OP1(opcode, i);
983                         break;
984                 case JAVA_GOTO_W:
985                 case JAVA_JSR_W:
986                         i = p + code_get_s4(p + 1);
987                         if (useinlining) { 
988                                 debug_writebranch;
989                                 i = label_index[i];
990                         }
991                         bound_check(i);
992                         block_insert(i);
993                         blockend = true;
994                         OP1(opcode, i);
995                         break;
996
997                 case JAVA_RET:
998                         if (!iswide) {
999                                 i = code_get_u1(p + 1);
1000                         } else {
1001                                 i = code_get_u2(p + 1);
1002                                 nextp = p + 3;
1003                                 iswide = false;
1004                         }
1005                         blockend = true;
1006                                 
1007                         /*
1008                           if (isinlinedmethod) {
1009                           OP1(ICMD_GOTO, inlinfo->stopgp);
1010                           break;
1011                           }*/
1012
1013                         OP1LOAD(opcode, i + firstlocal);
1014                         break;
1015
1016                 case JAVA_IRETURN:
1017                 case JAVA_LRETURN:
1018                 case JAVA_FRETURN:
1019                 case JAVA_DRETURN:
1020                 case JAVA_ARETURN:
1021                 case JAVA_RETURN:
1022                         if (isinlinedmethod) {
1023                                 /*                                      if (p==jcodelength-1) {*/ /* return is at end of inlined method */
1024                                 /*                                              OP(ICMD_NOP); */
1025                                 /*                                              break; */
1026                                 /*                                      } */
1027                                 blockend = true;
1028                                 OP1(ICMD_GOTO, inlinfo->stopgp);
1029                                 break;
1030                         }
1031
1032                         blockend = true;
1033                         OP(opcode);
1034                         break;
1035
1036                 case JAVA_ATHROW:
1037                         blockend = true;
1038                         OP(opcode);
1039                         break;
1040                                 
1041
1042                         /* table jumps ********************************/
1043
1044                 case JAVA_LOOKUPSWITCH:
1045                         {
1046                                 s4 num, j;
1047                                 s4 *tablep;
1048                                 s4 prevvalue;
1049
1050                                 blockend = true;
1051                                 nextp = ALIGN((p + 1), 4);
1052                                 if (nextp + 8 > jcodelength)
1053                                         panic("Unexpected end of bytecode");
1054                                 if (!useinlining) {
1055                                         tablep = (s4*)(jcode + nextp);
1056
1057                                 } else {
1058                                         num = code_get_u4(nextp + 4);
1059                                         tablep = DMNEW(s4, num * 2 + 2);
1060                                 }
1061
1062                                 OP2A(opcode, 0, tablep,currentline);
1063
1064                                 /* default target */
1065
1066                                 j =  p + code_get_s4(nextp);
1067                                 if (useinlining) 
1068                                         j = label_index[j];
1069                                 *tablep = j;     /* restore for little endian */
1070                                 tablep++;
1071                                 nextp += 4;
1072                                 bound_check(j);
1073                                 block_insert(j);
1074
1075                                 /* number of pairs */
1076
1077                                 num = code_get_u4(nextp);
1078                                 *tablep = num;
1079                                 tablep++;
1080                                 nextp += 4;
1081
1082                                 if (nextp + 8*(num) > jcodelength)
1083                                         panic("Unexpected end of bytecode");
1084
1085                                 for (i = 0; i < num; i++) {
1086                                         /* value */
1087
1088                                         j = code_get_s4(nextp);
1089                                         *tablep = j; /* restore for little endian */
1090                                         tablep++;
1091                                         nextp += 4;
1092
1093                                         /* check if the lookup table is sorted correctly */
1094                                         
1095                                         if (i && (j <= prevvalue))
1096                                                 panic("invalid LOOKUPSWITCH: table not sorted");
1097                                         prevvalue = j;
1098
1099                                         /* target */
1100
1101                                         j = p + code_get_s4(nextp);
1102                                         if (useinlining)
1103                                                 j = label_index[j];
1104                                         *tablep = j; /* restore for little endian */
1105                                         tablep++;
1106                                         nextp += 4;
1107                                         bound_check(j);
1108                                         block_insert(j);
1109                                 }
1110
1111                                 break;
1112                         }
1113
1114
1115                 case JAVA_TABLESWITCH:
1116                         {
1117                                 s4 num, j;
1118                                 s4 *tablep;
1119
1120                                 blockend = true;
1121                                 nextp = ALIGN((p + 1), 4);
1122                                 if (nextp + 12 > jcodelength)
1123                                         panic("Unexpected end of bytecode");
1124                                 if (!useinlining) {
1125                                         tablep = (s4*)(jcode + nextp);
1126
1127                                 } else {
1128                                         num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
1129                                         tablep = DMNEW(s4, num + 1 + 3);
1130                                 }
1131
1132                                 OP2A(opcode, 0, tablep,currentline);
1133
1134                                 /* default target */
1135
1136                                 j = p + code_get_s4(nextp);
1137                                 if (useinlining)
1138                                         j = label_index[j];
1139                                 *tablep = j;     /* restore for little endian */
1140                                 tablep++;
1141                                 nextp += 4;
1142                                 bound_check(j);
1143                                 block_insert(j);
1144
1145                                 /* lower bound */
1146
1147                                 j = code_get_s4(nextp);
1148                                 *tablep = j;     /* restore for little endian */
1149                                 tablep++;
1150                                 nextp += 4;
1151
1152                                 /* upper bound */
1153
1154                                 num = code_get_s4(nextp);
1155                                 *tablep = num;   /* restore for little endian */
1156                                 tablep++;
1157                                 nextp += 4;
1158
1159                                 num -= j;  /* difference of upper - lower */
1160                                 if (num < 0)
1161                                         panic("invalid TABLESWITCH: upper bound < lower bound");
1162
1163                                 if (nextp + 4*(num+1) > jcodelength)
1164                                         panic("Unexpected end of bytecode");
1165
1166                                 for (i = 0; i <= num; i++) {
1167                                         j = p + code_get_s4(nextp);
1168                                         if (useinlining)
1169                                                 j = label_index[j];
1170                                         *tablep = j; /* restore for little endian */
1171                                         tablep++;
1172                                         nextp += 4;
1173                                         bound_check(j);
1174                                         block_insert(j);
1175                                 }
1176
1177                                 break;
1178                         }
1179
1180
1181                         /* load and store of object fields *******************/
1182
1183                 case JAVA_AASTORE:
1184                         BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
1185                         break;
1186
1187                 case JAVA_PUTSTATIC:
1188                 case JAVA_GETSTATIC:
1189                         i = code_get_u2(p + 1);
1190                         {
1191                                 constant_FMIref *fr;
1192                                 fieldinfo *fi;
1193                                 fr = class_getconstant(class, i, CONSTANT_Fieldref);
1194                                 fi = class_findfield(fr->class, fr->name, fr->descriptor);
1195                                 OP2A(opcode, fi->type, fi,currentline);
1196                                 if (!fi->class->initialized) {
1197                                         isleafmethod = false;
1198                                 }
1199                         }
1200                         break;
1201
1202                 case JAVA_PUTFIELD:
1203                 case JAVA_GETFIELD:
1204                         i = code_get_u2(p + 1);
1205                         {
1206                                 constant_FMIref *fr;
1207                                 fieldinfo *fi;
1208                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1209                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1210                                 OP2A(opcode, fi->type, fi,currentline);
1211                         }
1212                         break;
1213
1214
1215                         /* method invocation *****/
1216
1217                 case JAVA_INVOKESTATIC:
1218                         i = code_get_u2(p + 1);
1219                         {
1220                                 constant_FMIref *mr;
1221                                 methodinfo *mi;
1222                                 
1223                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
1224                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1225                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1226                                         /*RTAprint*/    {printf(" method name =");
1227                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1228                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE STATIC\n");
1229                                         /*RTAprint*/    fflush(stdout);}
1230                                 if (!(mi->flags & ACC_STATIC))
1231                                         panic ("Static/Nonstatic mismatch calling static method");
1232                                 descriptor2types(mi);
1233
1234                                 isleafmethod=false;
1235                                 OP2A(opcode, mi->paramcount, mi,currentline);
1236                         }
1237                         break;
1238
1239                 case JAVA_INVOKESPECIAL:
1240                 case JAVA_INVOKEVIRTUAL:
1241                         i = code_get_u2(p + 1);
1242                         {
1243                                 constant_FMIref *mr;
1244                                 methodinfo *mi;
1245
1246                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
1247                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1248                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1249                                         /*RTAprint*/    {printf(" method name =");
1250                                         method_display(mi);
1251                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1252                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
1253                                         /*RTAprint*/    fflush(stdout);}
1254
1255                                 if (mi->flags & ACC_STATIC)
1256                                         panic ("Static/Nonstatic mismatch calling static method");
1257                                 descriptor2types(mi);
1258                                 isleafmethod=false;
1259                                 OP2A(opcode, mi->paramcount, mi,currentline);
1260                         }
1261                         break;
1262
1263                 case JAVA_INVOKEINTERFACE:
1264                         i = code_get_u2(p + 1);
1265                         {
1266                                 constant_FMIref *mr;
1267                                 methodinfo *mi;
1268                                 
1269                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
1270                                 mi = class_fetchmethod (mr->class, mr->name, mr->descriptor);
1271                                 if (mi->flags & ACC_STATIC)
1272                                         panic ("Static/Nonstatic mismatch calling static method");
1273                                 descriptor2types(mi);
1274                                 isleafmethod=false;
1275                                 OP2A(opcode, mi->paramcount, mi,currentline);
1276                         }
1277                         break;
1278
1279                         /* miscellaneous object operations *******/
1280
1281                 case JAVA_NEW:
1282                         i = code_get_u2 (p+1);
1283
1284                         LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1285                         s_count++;
1286                         BUILTIN1(BUILTIN_new, TYPE_ADR,currentline);
1287                         break;
1288
1289                 case JAVA_CHECKCAST:
1290 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1291                         isleafmethod = false;
1292 #endif
1293                         i = code_get_u2(p+1);
1294                                 {
1295                                         classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
1296                                         if (cls->vftbl->arraydesc) {
1297                                                 /* array type cast-check */
1298                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1299                                                 s_count++;
1300                                                 BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
1301                                         }
1302                                         else { /* object type cast-check */
1303                                                 /*
1304 +                                                 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1305 +                                                 s_count++;
1306 +                                                 BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
1307 +                                               */
1308                                                 OP2A(opcode, 1, cls,currentline);
1309                                         }
1310                                 }
1311
1312                         break;
1313
1314                 case JAVA_INSTANCEOF:
1315 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1316                         isleafmethod = false;
1317 #endif
1318                         i = code_get_u2(p+1);
1319
1320                                 {
1321                                         classinfo *cls = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
1322                                         if (cls->vftbl->arraydesc) {
1323                                                 /* array type cast-check */
1324                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1325                                                 s_count++;
1326                                                 BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT,currentline);
1327                                         }
1328                                         else { /* object type cast-check */
1329                                                 /*
1330                                                   LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1331                                                   s_count++;
1332                                                   BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
1333 +                                               */
1334                                                 OP2A(opcode, 1, cls,currentline);
1335                                         }
1336                                 }
1337                         break;
1338
1339                 case JAVA_MONITORENTER:
1340 #ifdef USE_THREADS
1341                         if (checksync) {
1342                                 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
1343                         } else
1344 #endif
1345                                 {
1346                                         OP(ICMD_NULLCHECKPOP);
1347                                 }
1348                         break;
1349
1350                 case JAVA_MONITOREXIT:
1351 #ifdef USE_THREADS
1352                         if (checksync) {
1353                                 BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
1354                         }
1355                         else
1356 #endif
1357                                 {
1358                                         OP(ICMD_POP);
1359                                 }
1360                         break;
1361
1362                         /* any other basic operation **************************************/
1363
1364                 case JAVA_IDIV:
1365                         OP(opcode);
1366                         break;
1367
1368                 case JAVA_IREM:
1369                         OP(opcode);
1370                         break;
1371
1372                 case JAVA_LDIV:
1373                         OP(opcode);
1374                         break;
1375
1376                 case JAVA_LREM:
1377                         OP(opcode);
1378                         break;
1379
1380                 case JAVA_FREM:
1381 #if defined(__I386__)
1382                         OP(opcode);
1383 #else
1384                         BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
1385 #endif
1386                         break;
1387
1388                 case JAVA_DREM:
1389 #if defined(__I386__)
1390                         OP(opcode);
1391 #else
1392                         BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
1393 #endif
1394                         break;
1395
1396                 case JAVA_F2I:
1397 #if defined(__ALPHA__)
1398                         if (!opt_noieee) {
1399                                 BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
1400                         } else
1401 #endif
1402                                 {
1403                                         OP(opcode);
1404                                 }
1405                         break;
1406
1407                 case JAVA_F2L:
1408 #if defined(__ALPHA__)
1409                         if (!opt_noieee) {
1410                                 BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
1411                         } else 
1412 #endif
1413                                 {
1414                                         OP(opcode);
1415                                 }
1416                         break;
1417
1418                 case JAVA_D2I:
1419 #if defined(__ALPHA__)
1420                         if (!opt_noieee) {
1421                                 BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
1422                         } else
1423 #endif
1424                                 {
1425                                         OP(opcode);
1426                                 }
1427                         break;
1428
1429                 case JAVA_D2L:
1430 #if defined(__ALPHA__)
1431                         if (!opt_noieee) {
1432                                 BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
1433                         } else
1434 #endif
1435                                 {
1436                                         OP(opcode);
1437                                 }
1438                         break;
1439
1440                 case JAVA_BREAKPOINT:
1441                         panic("Illegal opcode Breakpoint encountered");
1442                         break;
1443
1444                   case 186: /* unused opcode */
1445                 case 203:
1446                 case 204:
1447                 case 205:
1448                 case 206:
1449                 case 207:
1450                 case 208:
1451                 case 209:
1452                 case 210:
1453                 case 211:
1454                 case 212:
1455                 case 213:
1456                 case 214:
1457                 case 215:
1458                 case 216:
1459                 case 217:
1460                 case 218:
1461                 case 219:
1462                 case 220:
1463                 case 221:
1464                 case 222:
1465                 case 223:
1466                 case 224:
1467                 case 225:
1468                 case 226:
1469                 case 227:
1470                 case 228:
1471                 case 229:
1472                 case 230:
1473                 case 231:
1474                 case 232:
1475                 case 233:
1476                 case 234:
1477                 case 235:
1478                 case 236:
1479                 case 237:
1480                 case 238:
1481                 case 239:
1482                 case 240:
1483                 case 241:
1484                 case 242:
1485                 case 243:
1486                 case 244:
1487                 case 245:
1488                 case 246:
1489                 case 247:
1490                 case 248:
1491                 case 249:
1492                 case 250:
1493                 case 251:
1494                 case 252:
1495                 case 253:
1496                 case 254:
1497                 case 255:
1498                         printf("Illegal opcode %d at instr %d\n", opcode, ipc);
1499                         panic("Illegal opcode encountered");
1500                         break;
1501
1502                 default:
1503                         OP(opcode);
1504                         break;
1505                                 
1506                 } /* end switch */
1507
1508                 /* If WIDE was used correctly, iswide should have been reset by now. */
1509                 if (iswide && opcode != JAVA_WIDE)
1510                         panic("Illegal instruction: WIDE before incompatible opcode");
1511                 
1512                 /* INLINING */
1513                   
1514                 if (isinlinedmethod && p == jcodelength - 1) { /* end of an inlined method */
1515                         /*                printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
1516                         gp = inlinfo->stopgp; 
1517                         inlining_restore_compiler_variables();
1518                         list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1519                         if (inlinfo->inlinedmethods == NULL) {
1520                                 nextgp = -1;
1521                         } else {
1522                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
1523                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1524                         }
1525                         /*                printf("nextpgp: %d\n", nextgp); */
1526                         label_index=inlinfo->label_index;
1527                         firstlocal = inlinfo->firstlocal;
1528                 }
1529         } /* end for */
1530
1531         if (p != jcodelength)
1532                 panic("Command-sequence crosses code-boundary");
1533
1534         if (!blockend)
1535                 panic("Code does not end with branch/return/athrow - stmt");    
1536
1537         /* adjust block count if target 0 is not first intermediate instruction   */
1538
1539         if (!block_index[0] || (block_index[0] > 1))
1540                 b_count++;
1541
1542         /* copy local to global variables   */
1543
1544         instr_count = ipc;
1545         block_count = b_count;
1546         stack_count = s_count + block_count * maxstack;
1547
1548         /* allocate stack table */
1549
1550         stack = DMNEW(stackelement, stack_count);
1551
1552         {
1553                 basicblock  *bptr;
1554
1555                 bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1556
1557                 b_count = 0;
1558                 c_debug_nr = 0;
1559         
1560                 /* additional block if target 0 is not first intermediate instruction     */
1561
1562                 if (!block_index[0] || (block_index[0] > 1)) {
1563                         bptr->iinstr = instr;
1564                         bptr->mpc = -1;
1565                         bptr->flags = -1;
1566                         bptr->type = BBTYPE_STD;
1567                         bptr->branchrefs = NULL;
1568                         bptr->pre_count = 0;
1569                         bptr->debug_nr = c_debug_nr++;
1570                         bptr++;
1571                         b_count++;
1572                         (bptr - 1)->next = bptr;
1573                 }
1574
1575                 /* allocate blocks */
1576
1577                 for (p = 0; p < cumjcodelength; p++) {
1578                         if (block_index[p] & 1) {
1579                                 /* check if this block starts at the beginning of an instruction */
1580                                 if (!instructionstart[p])
1581                                         panic("Branch into middle of instruction");
1582                                 /* allocate the block */
1583                                 bptr->iinstr = instr + (block_index[p] >> 1);
1584                                 bptr->debug_nr = c_debug_nr++;
1585                                 if (b_count != 0)
1586                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1587                                 bptr->mpc = -1;
1588                                 bptr->flags = -1;
1589                                 bptr->lflags = 0;
1590                                 bptr->type = BBTYPE_STD;
1591                                 bptr->branchrefs = NULL;
1592                                 block_index[p] = b_count;
1593                                 bptr->pre_count = 0;
1594                                 bptr++;
1595                                 b_count++;
1596                                 (bptr - 1)->next = bptr;
1597                         }
1598                 }
1599
1600                 /* allocate additional block at end */
1601
1602                 bptr->instack = bptr->outstack = NULL;
1603                 bptr->indepth = bptr->outdepth = 0;
1604                 bptr->iinstr = NULL;
1605                 (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1606                 bptr->icount = 0;
1607                 bptr->mpc = -1;
1608                 bptr->flags = -1;
1609                 bptr->lflags = 0;
1610                 bptr->type = BBTYPE_STD;
1611                 bptr->branchrefs = NULL;
1612                 bptr->pre_count = 0;
1613                 bptr->debug_nr = c_debug_nr++;
1614                 (bptr - 1)->next = bptr;
1615                 bptr->next = NULL;
1616
1617                 last_block = bptr;
1618
1619                 if (exceptiontablelength > 0)
1620                         extable[exceptiontablelength - 1].down = NULL;
1621                 else
1622                         extable = NULL;
1623
1624                 for (i = 0; i < exceptiontablelength; ++i) {
1625                         p = extable[i].startpc;
1626                         extable[i].start = block + block_index[p];
1627
1628                         p = extable[i].endpc;
1629                         extable[i].end = (p == cumjcodelength) ? last_block : (block + block_index[p]);
1630
1631                         p = extable[i].handlerpc;
1632                         extable[i].handler = block + block_index[p];
1633             }
1634         }
1635         
1636         if (useinlining) inlining_cleanup();
1637         useinlining = useinltmp;
1638 }
1639
1640
1641 /*
1642  * These are local overrides for various environment variables in Emacs.
1643  * Please do not remove this and leave it at the end of the file, where
1644  * Emacs will automagically detect them.
1645  * ---------------------------------------------------------------------
1646  * Local variables:
1647  * mode: c
1648  * indent-tabs-mode: t
1649  * c-basic-offset: 4
1650  * tab-width: 4
1651  * End:
1652  */