added check for illegal opcode 186
[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 772 2003-12-14 12:24:02Z edwin $
33
34 */
35
36
37 #include <string.h>
38 #include "parse.h"
39 #include "global.h"
40 #include "jit.h"
41 #include "parseRT.h"
42 #include "inline.h"
43 #include "loop/loop.h"
44 #include "types.h"
45 #include "builtin.h"
46 #include "tables.h"
47 #include "native.h"
48 #include "loader.h"
49 #include "toolbox/memory.h"
50 #include "toolbox/loging.h"
51
52
53 /* data about the currently parsed method */
54
55 classinfo  *rt_class;    /* class the compiled method belongs to       */
56 methodinfo *rt_method;   /* pointer to method info of compiled method  */
57 utf *rt_descriptor;      /* type descriptor of compiled method         */
58 int rt_jcodelength;      /* length of JavaVM-codes                     */
59 u1  *rt_jcode;           /* pointer to start of JavaVM-code            */
60
61
62
63 /*INLINING*/
64 //#include "inline.c"
65 /*#define debug_writebranch printf("op: %s i: %d label_index[i]: %d\n",icmd_names[opcode], i, label_index[i]);*/
66 #define debug_writebranch
67
68
69
70 /* functionc compiler_addinitclass *********************************************
71
72         add class into the list of classes to initialize
73
74 *******************************************************************************/
75                                 
76 void compiler_addinitclass(classinfo *c)
77 {
78         classinfo *cl;
79
80         if (c->initialized) return;
81         
82         cl = chain_first(uninitializedclasses);
83         if (cl == c)
84                 return;
85         
86         if (cl == class)
87                 cl = chain_next(uninitializedclasses);
88         for (;;) {
89                 if (cl == c)
90                         return;
91                 if (cl == NULL) {
92                         if (runverbose) {
93                                 char logtext[MAXLOGTEXT];
94                                 sprintf(logtext, "compiler_addinitclass: ");
95                                 utf_sprint(logtext+strlen(logtext), c->name);
96                                 log_text(logtext);
97                         }
98                         chain_addlast(uninitializedclasses, c);
99                         return;
100                 }
101                 if (c < cl) {
102                         if (runverbose) {
103                                 char logtext[MAXLOGTEXT];
104                                 sprintf(logtext, "compiler_addinitclass: ");
105                                 utf_sprint(logtext+strlen(logtext), c->name);
106                                 log_text(logtext);
107                         }
108                         chain_addbefore(uninitializedclasses, c);
109                         return;
110                 }
111                 cl = chain_next(uninitializedclasses);
112         }
113 }                       
114
115
116
117 /* function descriptor2typesL ***************************************************
118
119         decodes a already checked method descriptor. The parameter count, the
120         return type and the argument types are stored in the passed methodinfo.
121         gets and saves classptr for object ref.s
122
123 *******************************************************************************/                
124
125 classSetNode *descriptor2typesL(methodinfo *m)
126 {
127         int debugInfo = 0;
128         int i;
129         u1 *types, *tptr;
130         int pcount, c;
131         char *utf_ptr;
132         classinfo** classtypes;
133         char *class; 
134         char *desc;
135         classSetNode *p=NULL;
136         if (debugInfo >= 1) {
137                 printf("In descriptor2typesL >>>\t"); fflush(stdout);
138                 utf_display(m->class->name); printf(".");
139                 method_display(m);fflush(stdout);
140         }
141
142         pcount = 0;
143         desc =       MNEW (char, 256); 
144         types = DMNEW (u1, m->descriptor->blength); 
145         classtypes = MNEW (classinfo*, m->descriptor->blength+1);
146         m->returnclass = NULL;
147         tptr = types;
148         if (!(m->flags & ACC_STATIC)) {
149                 *tptr++ = TYPE_ADR;
150                 if (debugInfo >= 1) {
151                         printf("param #0 (this?) method class =");utf_display(m->class->name);printf("\n");
152                 }
153                 classtypes[pcount] = m->class;
154                 p = addClassCone(p,  m->class);
155                 pcount++;
156         }
157
158         utf_ptr = m->descriptor->text + 1;
159         strcpy (desc,utf_ptr);
160    
161         while ((c = *desc++) != ')') {
162                 pcount++;
163                 switch (c) {
164                 case 'B':
165                 case 'C':
166                 case 'I':
167                 case 'S':
168                 case 'Z':  *tptr++ = TYPE_INT;
169                         break;
170                 case 'J':  *tptr++ = TYPE_LNG;
171                         break;
172                 case 'F':  *tptr++ = TYPE_FLT;
173                         break;
174                 case 'D':  *tptr++ = TYPE_DBL;
175                         break;
176                 case 'L':  *tptr++ = TYPE_ADR;
177                         /* get class string */
178                         class = strtok(desc,";");
179                         desc = strtok(NULL,"\0");
180                         /* get/save classinfo ptr */
181                         classtypes[pcount-1] = class_get(utf_new_char(class));
182                         p = addClassCone(p,  class_get(utf_new_char(class)));
183                         if (debugInfo >= 1) {
184                                 printf("LParam#%i 's class type is: %s\n",pcount-1,class);fflush(stdout);
185                                 printf("Lclasstypes[%i]=",pcount-1);fflush(stdout);
186                                 utf_display(classtypes[pcount-1]->name);
187                         }
188                         break;
189                 case '[':  *tptr++ = TYPE_ADR;
190                         while (c == '[')
191                                 c = *desc++;
192                         /* get class string */
193                         if (c == 'L') {
194                                 class = strtok(desc,";");
195                                 desc = strtok(NULL,"\0");
196                                 /* get/save classinfo ptr */
197                                 classtypes[pcount-1] = class_get(utf_new_char(class));
198                                 p= addClassCone(p,  class_get(utf_new_char(class)));
199                                 if (debugInfo >= 1) {
200                                         printf("[Param#%i 's class type is: %s\n",pcount-1,class);
201                                         printf("[classtypes[%i]=",pcount-1);fflush(stdout);
202                                         utf_display(classtypes[pcount-1]->name);
203                                         printf("\n");
204                                 }
205                         }
206                         else
207                                 classtypes[pcount-1] = NULL;
208                         break;
209                 default:   
210                         panic("Ill formed methodtype-descriptor");
211                 }
212         }
213
214         /* compute return type */
215         switch (*desc++) {
216         case 'B':
217         case 'C':
218         case 'I':
219         case 'S':
220         case 'Z':  m->returntype = TYPE_INT;
221                 break;
222         case 'J':  m->returntype = TYPE_LNG;
223                 break;
224         case 'F':  m->returntype = TYPE_FLT;
225                 break;
226         case 'D':  m->returntype = TYPE_DBL;
227                 break;
228         case '[':
229                 m->returntype = TYPE_ADR;
230                 c = *desc;
231                 while (c == '[')
232                         c = *desc++;
233                 if (c != 'L') break;
234                 *(desc++);
235                            
236         case 'L':  
237                 m->returntype = TYPE_ADR;
238                           
239                 /* get class string */
240                 class = strtok(desc,";");
241                 m->returnclass = class_get(utf_new_char(class));
242                 if (m->returnclass == NULL) {
243                         printf("class=%s :\t",class);
244                         panic ("return class not found");
245                 }
246                 break;
247         case 'V':  m->returntype = TYPE_VOID;
248                 break;
249
250         default:   panic("Ill formed methodtype-descriptor-ReturnType");
251         }
252
253         m->paramcount = pcount;
254         m->paramtypes = types;
255         m->paramclass = classtypes;
256
257         if (debugInfo >=1) {
258                 if (pcount > 0) {
259                         for (i=0; i< m->paramcount; i++) {
260                         if ((m->paramtypes[i] == TYPE_ADR) && (m->paramclass[i] != NULL)) {
261                                         printf("Param #%i is:\t",i);
262                                         utf_display(m->paramclass[i]->name);
263                                         printf("\n");
264                                 }
265                         }
266                 }
267                 if ((m->returntype == TYPE_ADR) && (m->returnclass != NULL)) { 
268                         printf("\tReturn Type is:\t"); fflush(stdout);
269                         utf_display(m->returnclass->name);
270                         printf("\n");
271                 }
272
273                 printf("params2types: START  results in a set \n");
274                 printf("param2types: A Set size=%i=\n",sizeOfSet(p));
275                 printSet(p);
276         }
277
278         return p;
279 }
280
281
282
283 /* function descriptor2types ***************************************************
284
285         decodes a already checked method descriptor. The parameter count, the
286         return type and the argument types are stored in the passed methodinfo.
287
288 *******************************************************************************/                
289
290 void descriptor2types(methodinfo *m)
291 {
292         u1 *types, *tptr;
293         int pcount, c;
294         char *utf_ptr;
295         pcount = 0;
296         types = DMNEW(u1, m->descriptor->blength); 
297         
298         tptr = types;
299         if (!(m->flags & ACC_STATIC)) {
300                 *tptr++ = TYPE_ADR;
301                 pcount++;
302         }
303
304         utf_ptr = m->descriptor->text + 1;
305    
306         while ((c = *utf_ptr++) != ')') {
307                 pcount++;
308                 switch (c) {
309                 case 'B':
310                 case 'C':
311                 case 'I':
312                 case 'S':
313                 case 'Z':  *tptr++ = TYPE_INT;
314                         break;
315                 case 'J':  *tptr++ = TYPE_LNG;
316                         break;
317                 case 'F':  *tptr++ = TYPE_FLT;
318                         break;
319                 case 'D':  *tptr++ = TYPE_DBL;
320                         break;
321                 case 'L':  *tptr++ = TYPE_ADR;
322                         while (*utf_ptr++ != ';');
323                         break;
324                 case '[':  *tptr++ = TYPE_ADR;
325                         while (c == '[')
326                                 c = *utf_ptr++;
327                         if (c == 'L')
328                                 while (*utf_ptr++ != ';') /* skip */;
329                         break;
330                 default:   panic ("Ill formed methodtype-descriptor");
331                 }
332         }
333
334         /* compute return type */
335
336         switch (*utf_ptr++) {
337         case 'B':
338         case 'C':
339         case 'I':
340         case 'S':
341         case 'Z':  m->returntype = TYPE_INT;
342                 break;
343         case 'J':  m->returntype = TYPE_LNG;
344                 break;
345         case 'F':  m->returntype = TYPE_FLT;
346                 break;
347         case 'D':  m->returntype = TYPE_DBL;
348                 break;
349         case '[':
350         case 'L':  m->returntype = TYPE_ADR;
351                 break;
352         case 'V':  m->returntype = TYPE_VOID;
353                 break;
354
355         default:   panic ("Ill formed methodtype-descriptor");
356         }
357
358         m->paramcount = pcount;
359         m->paramtypes = types;
360 }
361
362
363
364 /*******************************************************************************
365
366         function 'parse' scans the JavaVM code and generates intermediate code
367
368         During parsing the block index table is used to store at bit pos 0
369         a flag which marks basic block starts and at position 1 to 31 the
370         intermediate instruction index. After parsing the block index table
371         is scanned, for marked positions a block is generated and the block
372         number is stored in the block index table.
373
374 *******************************************************************************/
375
376 /* intermediate code generating macros */
377
378 #define PINC           iptr++;ipc++
379 #define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
380 #define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
381 #define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
382 #define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
383 #define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
384 #define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
385 #define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
386 #define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
387 #define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
388 #define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
389                        iptr->val.a=(v);PINC
390 #define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
391                        iptr->val.a=(v);PINC
392 #define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
393                        iptr->val.a=(v);PINC
394
395 #define INDEX_ONEWORD(num)                                                                              \
396         do { if((num)<0 || (num)>=maxlocals)                                            \
397                         panic("Invalid local variable index"); } while (0)
398 #define INDEX_TWOWORD(num)                                                                              \
399         do { if((num)<0 || ((num)+1)>=maxlocals)                                        \
400                         panic("Invalid local variable index"); } while (0)
401
402 #define OP1LOAD(o,o1)                                                   \
403         do {if (o == ICMD_LLOAD || o == ICMD_DLOAD)     \
404                         INDEX_TWOWORD(o1);                                      \
405                 else                                                                    \
406                         INDEX_ONEWORD(o1);                                      \
407                 OP1(o,o1);} while(0)
408
409 #define OP1STORE(o,o1)                                                          \
410         do {if (o == ICMD_LSTORE || o == ICMD_DSTORE)   \
411                         INDEX_TWOWORD(o1);                                              \
412                 else                                                                            \
413                         INDEX_ONEWORD(o1);                                              \
414                 OP1(o,o1);} while(0)
415
416 /* block generating and checking macros */
417
418 #define block_insert(i) \
419     do { \
420         if (!(block_index[(i)] & 1)) { \
421             b_count++; \
422             block_index[(i)] |= 1; \
423         } \
424     } while (0)
425
426
427 /* FIXME really use cumjcodelength for the bound_checkers ? */
428
429 #define bound_check(i) \
430     do { \
431         if (i < 0 || i >= cumjcodelength) { \
432             panic("branch target out of code-boundary"); \
433         } \
434     } while (0)
435
436 /* bound_check1 is used for the inclusive ends of exception handler ranges */
437 #define bound_check1(i) \
438     do { \
439         if (i < 0 || i > cumjcodelength) { \
440             panic("branch target out of code-boundary"); \
441         } \
442     } while (0)
443
444
445
446 static xtable* fillextable(xtable* extable, exceptiontable *raw_extable, int exceptiontablelength, int *label_index, int *block_count)
447 {
448         int b_count, i, p;
449         
450         if (exceptiontablelength == 0) 
451                 return extable;
452         
453         b_count = *block_count;
454         for (i = 0; i < exceptiontablelength; i++) {
455                                                                  
456                 p = raw_extable[i].startpc;
457                 if (label_index != NULL) p = label_index[p];
458                 extable[i].startpc = p;
459                 bound_check(p);
460                 block_insert(p);
461                 
462                 p = raw_extable[i].endpc;
463                 if (label_index != NULL) p = label_index[p];
464                 extable[i].endpc = p;
465                 bound_check1(p);
466                 if (p < cumjcodelength)
467                         block_insert(p);
468
469                 p = raw_extable[i].handlerpc;
470                 if (label_index != NULL) p = label_index[p];
471                 extable[i].handlerpc = p;
472                 bound_check(p);
473                 block_insert(p);
474
475                 extable[i].catchtype  = raw_extable[i].catchtype;
476
477                 extable[i].next = NULL;
478                 extable[i].down = &extable[i+1];
479                 }
480         *block_count = b_count;
481         return &extable[i];  /* return the next free xtable* */
482 }
483
484
485
486 void parse()
487 {
488         int  p;                     /* java instruction counter                   */
489         int  nextp;                 /* start of next java instruction             */
490         int  opcode;                /* java opcode                                */
491         int  i;                     /* temporary for different uses (counters)    */
492         int  ipc = 0;               /* intermediate instruction counter           */
493         int  b_count = 0;           /* basic block counter                        */
494         int  s_count = 0;           /* stack element counter                      */
495         bool blockend = false;      /* true if basic block end has been reached   */
496         bool iswide = false;        /* true if last instruction was a wide        */
497         instruction *iptr;          /* current pointer into instruction array     */
498         int gp;                     /* global java instruction counter            */
499                                     /* inlining info for current method           */
500         inlining_methodinfo *inlinfo = inlining_rootinfo;
501         inlining_methodinfo *tmpinlinf;
502         int nextgp = -1;            /* start of next method to be inlined         */
503         int *label_index = NULL;    /* label redirection table                    */
504         int firstlocal = 0;         /* first local variable of method             */
505         xtable* nextex;             /* points next free entry in extable          */
506         u1 *instructionstart;       /* 1 for pcs which are valid instr. starts    */
507
508         bool useinltmp;
509
510         if (compileverbose) {
511                 char logtext[MAXLOGTEXT];
512                 sprintf(logtext, "Parsing: ");
513                 utf_sprint(logtext+strlen(logtext), method->class->name);
514                 strcpy(logtext+strlen(logtext), ".");
515                 utf_sprint(logtext+strlen(logtext), method->name);
516                 utf_sprint(logtext+strlen(logtext), method->descriptor);
517                 log_text(logtext);
518         }
519
520         /* INLINING */
521         if (useinlining) {
522                 label_index = inlinfo->label_index;
523                 maxstack = cummaxstack;
524                 exceptiontablelength = cumextablelength;
525         }
526         
527         useinltmp = useinlining; /* FIXME remove this after debugging */
528     /*useinlining = false;*/     /* and merge the if-statements  */
529         
530         if (!useinlining) {
531                 cumjcodelength = jcodelength;
532
533         } else {
534                 tmpinlinf = (inlining_methodinfo*) list_first(inlinfo->inlinedmethods);
535                 if (tmpinlinf != NULL) nextgp = tmpinlinf->startgp;
536         }
537
538         if ((opt_rt || opt_xta || opt_vta) && (pOpcodes == 2 || pOpcodes == 3)) {
539                 printf("PARSE method name =");
540                 utf_display(method->class->name);
541                 printf(".");
542                 method_display(method);
543                 printf(">\n\n");
544                 fflush(stdout);
545         }
546
547         if (opt_rt || opt_xta) { 
548                 RT_jit_parse(method);
549
550         } else {
551                 if (opt_vta) 
552                         printf("VTA requested, but not yet implemented\n");
553         }
554          
555
556         /* allocate instruction array and block index table */
557         
558         /* 1 additional for end ipc and 3 for loop unrolling */
559         
560         block_index = DMNEW(int, cumjcodelength + 4);
561         instructionstart = DMNEW(u1, cumjcodelength + 4);
562         memset(instructionstart,0,sizeof(u1) * (cumjcodelength + 4));
563
564         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
565         /* additional MONITOREXITS are reached by branches which are 3 bytes */
566         
567         iptr = instr = DMNEW(instruction, cumjcodelength + 5);
568
569         /* XXX zero fields in the instructions loop? */
570         memset(iptr,0,sizeof(instruction) * (cumjcodelength + 5));
571         
572         /* initialize block_index table (unrolled four times) */
573
574         {
575                 int *ip;
576         
577                 for (i = 0, ip = block_index; i <= cumjcodelength; i += 4, ip += 4) {
578                         ip[0] = 0;
579                         ip[1] = 0;
580                         ip[2] = 0;
581                         ip[3] = 0;
582                 }
583         }
584
585         /* compute branch targets of exception table */
586
587         extable = DMNEW(xtable, exceptiontablelength + 1);
588         /*
589           for (i = 0; i < method->exceptiontablelength; i++) {
590
591           p = extable[i].startpc = raw_extable[i].startpc;
592           if (useinlining) p = label_index[p];
593           bound_check(p);
594           block_insert(p);
595
596           p = extable[i].endpc = raw_extable[i].endpc;
597           if (useinlining) p = label_index[p];
598           bound_check1(p);
599           if (p < cumjcodelength)
600           block_insert(p);
601
602           p = extable[i].handlerpc = raw_extable[i].handlerpc;
603           bound_check(p);
604           block_insert(p);
605
606           extable[i].catchtype  = raw_extable[i].catchtype;
607
608           extable[i].next = NULL;
609           extable[i].down = &extable[i+1];
610           }
611         */
612
613         nextex = fillextable(extable, raw_extable, method->exceptiontablelength, label_index, &b_count);
614
615         s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
616
617 #ifdef USE_THREADS
618         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
619                 isleafmethod = false;
620         }                       
621 #endif
622
623         /* scan all java instructions */
624
625         for (p = 0, gp = 0; p < jcodelength; gp += (nextp - p), p = nextp) {
626           
627                 /* DEBUG XXX */   /*printf("p:%d gp:%d ",p,gp);*/
628
629                 /* mark this position as a valid instruction start */
630                 if (!iswide)
631                         instructionstart[p] = 1;
632
633                 /*INLINING*/
634                 if ((useinlining) && (gp == nextgp)) {
635                         u1 *tptr;
636                         bool *readonly = NULL;
637
638                         opcode = code_get_u1(p);
639                         nextp = p += jcommandsize[opcode];
640                         if (nextp > jcodelength)
641                                 panic("Unexpected end of bytecode");
642                         tmpinlinf = list_first(inlinfo->inlinedmethods);
643                         firstlocal = tmpinlinf->firstlocal;
644                         label_index = tmpinlinf->label_index;
645                         readonly = tmpinlinf->readonly;
646
647                         for (i = 0, tptr = tmpinlinf->method->paramtypes + tmpinlinf->method->paramcount - 1; i < tmpinlinf->method->paramcount; i++, tptr--) {
648                                 int op;
649
650                                 if ((i == 0) && inlineparamopt) {
651                                         OP1(ICMD_CLEAR_ARGREN, firstlocal);
652                                 }
653
654                                 if (!inlineparamopt || !readonly[i]) {
655                                         op = ICMD_ISTORE;
656
657                                 } else {
658                                         op = ICMD_READONLY_ARG;
659                                 }
660
661                                 op += *tptr;
662                                 OP1(op, firstlocal + tmpinlinf->method->paramcount - 1 - i);
663
664                                 /* block_index[gp] |= (ipc << 1);*/  /*FIXME: necessary ? */
665                         }
666
667                         inlining_save_compiler_variables();
668                         inlining_set_compiler_variables(tmpinlinf);
669
670                         if (inlinfo->inlinedmethods == NULL) {
671                                 gp = -1;
672                         } else {
673                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
674                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
675                         }
676                         if (method->exceptiontablelength > 0) 
677                                 nextex = fillextable(nextex, method->exceptiontable, method->exceptiontablelength, label_index, &b_count);
678                         continue;
679                 }
680           
681                 opcode = code_get_u1(p);            /* fetch op code                  */
682
683           
684                 if (opt_rt && (pOpcodes == 2 || pOpcodes == 3)) {
685                         printf("Parse<%i> p=%i<%i<   opcode=<%i> %s\n",
686                                    pOpcodes, p, rt_jcodelength, opcode, icmd_names[opcode]);
687                 }
688           
689                 block_index[gp] |= (ipc << 1);      /* store intermediate count       */
690
691                 if (blockend) {
692                         block_insert(gp);               /* start new block                */
693                         blockend = false;
694                 }
695
696                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
697                 if (nextp > jcodelength)
698                         panic("Unexpected end of bytecode");
699                 s_count += stackreq[opcode];            /* compute stack element count    */
700
701                 switch (opcode) {
702                 case JAVA_NOP:
703                         break;
704
705                         /* pushing constants onto the stack p */
706
707                 case JAVA_BIPUSH:
708                         LOADCONST_I(code_get_s1(p+1));
709                         break;
710
711                 case JAVA_SIPUSH:
712                         LOADCONST_I(code_get_s2(p+1));
713                         break;
714
715                 case JAVA_LDC1:
716                         i = code_get_u1(p+1);
717                         goto pushconstantitem;
718                 case JAVA_LDC2:
719                 case JAVA_LDC2W:
720                         i = code_get_u2(p + 1);
721
722                 pushconstantitem:
723
724                         if (i >= class->cpcount) 
725                                 panic ("Attempt to access constant outside range");
726
727                         switch (class->cptags[i]) {
728                         case CONSTANT_Integer:
729                                 LOADCONST_I(((constant_integer*)
730                                                          (class->cpinfos[i]))->value);
731                                 break;
732                         case CONSTANT_Long:
733                                 LOADCONST_L(((constant_long*)
734                                                          (class->cpinfos[i]))->value);
735                                 break;
736                         case CONSTANT_Float:
737                                 LOADCONST_F(((constant_float*)
738                                                          (class->cpinfos[i]))->value);
739                                 break;
740                         case CONSTANT_Double:
741                                 LOADCONST_D(((constant_double*)
742                                                          (class->cpinfos[i]))->value);
743                                 break;
744                         case CONSTANT_String:
745                                 LOADCONST_A(literalstring_new((utf*)
746                                                                                           (class->cpinfos[i])));
747                                 break;
748                         default: panic("Invalid constant type to push");
749                         }
750                         break;
751
752                 case JAVA_ACONST_NULL:
753                         LOADCONST_A(NULL);
754                         break;
755
756                 case JAVA_ICONST_M1:
757                 case JAVA_ICONST_0:
758                 case JAVA_ICONST_1:
759                 case JAVA_ICONST_2:
760                 case JAVA_ICONST_3:
761                 case JAVA_ICONST_4:
762                 case JAVA_ICONST_5:
763                         LOADCONST_I(opcode - JAVA_ICONST_0);
764                         break;
765
766                 case JAVA_LCONST_0:
767                 case JAVA_LCONST_1:
768                         LOADCONST_L(opcode - JAVA_LCONST_0);
769                         break;
770
771                 case JAVA_FCONST_0:
772                 case JAVA_FCONST_1:
773                 case JAVA_FCONST_2:
774                         LOADCONST_F(opcode - JAVA_FCONST_0);
775                         break;
776
777                 case JAVA_DCONST_0:
778                 case JAVA_DCONST_1:
779                         LOADCONST_D(opcode - JAVA_DCONST_0);
780                         break;
781
782                         /* loading variables onto the stack */
783
784                 case JAVA_ILOAD:
785                 case JAVA_LLOAD:
786                 case JAVA_FLOAD:
787                 case JAVA_DLOAD:
788                 case JAVA_ALOAD:
789                         if (!iswide) {
790                                 i = code_get_u1(p + 1);
791                         } else {
792                                 i = code_get_u2(p + 1);
793                                 nextp = p + 3;
794                                 iswide = false;
795                         }
796                         OP1LOAD(opcode, i + firstlocal);
797                         break;
798
799                 case JAVA_ILOAD_0:
800                 case JAVA_ILOAD_1:
801                 case JAVA_ILOAD_2:
802                 case JAVA_ILOAD_3:
803                         OP1LOAD(ICMD_ILOAD, opcode - JAVA_ILOAD_0 + firstlocal);
804                         break;
805
806                 case JAVA_LLOAD_0:
807                 case JAVA_LLOAD_1:
808                 case JAVA_LLOAD_2:
809                 case JAVA_LLOAD_3:
810                         OP1LOAD(ICMD_LLOAD, opcode - JAVA_LLOAD_0 + firstlocal);
811                         break;
812
813                 case JAVA_FLOAD_0:
814                 case JAVA_FLOAD_1:
815                 case JAVA_FLOAD_2:
816                 case JAVA_FLOAD_3:
817                         OP1LOAD(ICMD_FLOAD, opcode - JAVA_FLOAD_0 + firstlocal);
818                         break;
819
820                 case JAVA_DLOAD_0:
821                 case JAVA_DLOAD_1:
822                 case JAVA_DLOAD_2:
823                 case JAVA_DLOAD_3:
824                         OP1LOAD(ICMD_DLOAD, opcode - JAVA_DLOAD_0 + firstlocal);
825                         break;
826
827                 case JAVA_ALOAD_0:
828                 case JAVA_ALOAD_1:
829                 case JAVA_ALOAD_2:
830                 case JAVA_ALOAD_3:
831                         OP1LOAD(ICMD_ALOAD, opcode - JAVA_ALOAD_0 + firstlocal);
832                         break;
833
834                         /* storing stack values into local variables */
835
836                 case JAVA_ISTORE:
837                 case JAVA_LSTORE:
838                 case JAVA_FSTORE:
839                 case JAVA_DSTORE:
840                 case JAVA_ASTORE:
841                         if (!iswide) {
842                                 i = code_get_u1(p + 1);
843                         } else {
844                                 i = code_get_u2(p + 1);
845                                 iswide = false;
846                                 nextp = p + 3;
847                         }
848                         OP1STORE(opcode, i + firstlocal);
849                         break;
850
851                 case JAVA_ISTORE_0:
852                 case JAVA_ISTORE_1:
853                 case JAVA_ISTORE_2:
854                 case JAVA_ISTORE_3:
855                         OP1STORE(ICMD_ISTORE, opcode - JAVA_ISTORE_0 + firstlocal);
856                         break;
857
858                 case JAVA_LSTORE_0:
859                 case JAVA_LSTORE_1:
860                 case JAVA_LSTORE_2:
861                 case JAVA_LSTORE_3:
862                         OP1STORE(ICMD_LSTORE, opcode - JAVA_LSTORE_0 + firstlocal);
863                         break;
864
865                 case JAVA_FSTORE_0:
866                 case JAVA_FSTORE_1:
867                 case JAVA_FSTORE_2:
868                 case JAVA_FSTORE_3:
869                         OP1STORE(ICMD_FSTORE, opcode - JAVA_FSTORE_0 + firstlocal);
870                         break;
871
872                 case JAVA_DSTORE_0:
873                 case JAVA_DSTORE_1:
874                 case JAVA_DSTORE_2:
875                 case JAVA_DSTORE_3:
876                         OP1STORE(ICMD_DSTORE, opcode - JAVA_DSTORE_0 + firstlocal);
877                         break;
878
879                 case JAVA_ASTORE_0:
880                 case JAVA_ASTORE_1:
881                 case JAVA_ASTORE_2:
882                 case JAVA_ASTORE_3:
883                         OP1STORE(ICMD_ASTORE, opcode - JAVA_ASTORE_0 + firstlocal);
884                         break;
885
886                 case JAVA_IINC:
887                         {
888                                 int v;
889                                 
890                                 if (!iswide) {
891                                         i = code_get_u1(p + 1);
892                                         v = code_get_s1(p + 2);
893
894                                 } else {
895                                         i = code_get_u2(p + 1);
896                                         v = code_get_s2(p + 3);
897                                         iswide = false;
898                                         nextp = p + 5;
899                                 }
900                                 INDEX_ONEWORD(i + firstlocal);
901                                 OP2I(opcode, i + firstlocal, v);
902                         }
903                         break;
904
905                         /* wider index for loading, storing and incrementing */
906
907                 case JAVA_WIDE:
908                         iswide = true;
909                         nextp = p + 1;
910                         break;
911
912                         /* managing arrays ************************************************/
913
914                 case JAVA_NEWARRAY:
915                         OP2I(ICMD_CHECKASIZE, 0, 0);
916                         switch (code_get_s1(p + 1)) {
917                         case 4:
918                                 BUILTIN1(BUILTIN_newarray_boolean, TYPE_ADR);
919                                 break;
920                         case 5:
921                                 BUILTIN1(BUILTIN_newarray_char, TYPE_ADR);
922                                 break;
923                         case 6:
924                                 BUILTIN1(BUILTIN_newarray_float, TYPE_ADR);
925                                 break;
926                         case 7:
927                                 BUILTIN1(BUILTIN_newarray_double, TYPE_ADR);
928                                 break;
929                         case 8:
930                                 BUILTIN1(BUILTIN_newarray_byte, TYPE_ADR);
931                                 break;
932                         case 9:
933                                 BUILTIN1(BUILTIN_newarray_short, TYPE_ADR);
934                                 break;
935                         case 10:
936                                 BUILTIN1(BUILTIN_newarray_int, TYPE_ADR);
937                                 break;
938                         case 11:
939                                 BUILTIN1(BUILTIN_newarray_long, TYPE_ADR);
940                                 break;
941                         default: panic("Invalid array-type to create");
942                         }
943                         break;
944
945                 case JAVA_ANEWARRAY:
946                         OP2I(ICMD_CHECKASIZE, 0, 0);
947                         i = code_get_u2(p + 1);
948                         {
949                                         classinfo *component = (classinfo*)class_getconstant(class, i, CONSTANT_Class);
950                                         LOADCONST_A(class_array_of(component)->vftbl);
951
952                                 s_count++;
953
954                                 BUILTIN2(BUILTIN_newarray, TYPE_ADR);
955                         }
956                         break;
957
958                 case JAVA_MULTIANEWARRAY:
959                         isleafmethod=false;
960                         i = code_get_u2(p + 1);
961                         {
962                                 int v = code_get_u1(p + 3);
963                                 vftbl *arrayvftbl = ((classinfo*)class_getconstant (class, i, CONSTANT_Class))->vftbl;
964                                 OP2A(opcode, v, arrayvftbl);                    
965                         }
966                         break;
967
968                 case JAVA_IFEQ:
969                 case JAVA_IFLT:
970                 case JAVA_IFLE:
971                 case JAVA_IFNE:
972                 case JAVA_IFGT:
973                 case JAVA_IFGE:
974                 case JAVA_IFNULL:
975                 case JAVA_IFNONNULL:
976                 case JAVA_IF_ICMPEQ:
977                 case JAVA_IF_ICMPNE:
978                 case JAVA_IF_ICMPLT:
979                 case JAVA_IF_ICMPGT:
980                 case JAVA_IF_ICMPLE:
981                 case JAVA_IF_ICMPGE:
982                 case JAVA_IF_ACMPEQ:
983                 case JAVA_IF_ACMPNE:
984                 case JAVA_GOTO:
985                 case JAVA_JSR:
986                         i = p + code_get_s2(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                 case JAVA_GOTO_W:
997                 case JAVA_JSR_W:
998                         i = p + code_get_s4(p + 1);
999                         if (useinlining) { 
1000                                 debug_writebranch;
1001                                 i = label_index[i];
1002                         }
1003                         bound_check(i);
1004                         block_insert(i);
1005                         blockend = true;
1006                         OP1(opcode, i);
1007                         break;
1008
1009                 case JAVA_RET:
1010                         if (!iswide) {
1011                                 i = code_get_u1(p + 1);
1012                         } else {
1013                                 i = code_get_u2(p + 1);
1014                                 nextp = p + 3;
1015                                 iswide = false;
1016                         }
1017                         blockend = true;
1018                                 
1019                         /*
1020                           if (isinlinedmethod) {
1021                           OP1(ICMD_GOTO, inlinfo->stopgp);
1022                           break;
1023                           }*/
1024
1025                         OP1LOAD(opcode, i + firstlocal);
1026                         break;
1027
1028                 case JAVA_IRETURN:
1029                 case JAVA_LRETURN:
1030                 case JAVA_FRETURN:
1031                 case JAVA_DRETURN:
1032                 case JAVA_ARETURN:
1033                 case JAVA_RETURN:
1034                         if (isinlinedmethod) {
1035                                 /*                                      if (p==jcodelength-1) {*/ /* return is at end of inlined method */
1036                                 /*                                              OP(ICMD_NOP); */
1037                                 /*                                              break; */
1038                                 /*                                      } */
1039                                 blockend = true;
1040                                 OP1(ICMD_GOTO, inlinfo->stopgp);
1041                                 break;
1042                         }
1043
1044                         blockend = true;
1045                         OP(opcode);
1046                         break;
1047
1048                 case JAVA_ATHROW:
1049                         blockend = true;
1050                         OP(opcode);
1051                         break;
1052                                 
1053
1054                         /* table jumps ********************************/
1055
1056                 case JAVA_LOOKUPSWITCH:
1057                         {
1058                                 s4 num, j;
1059                                 s4 *tablep;
1060
1061                                 blockend = true;
1062                                 nextp = ALIGN((p + 1), 4);
1063                                 if (nextp + 8 > jcodelength)
1064                                         panic("Unexpected end of bytecode");
1065                                 if (!useinlining) {
1066                                         tablep = (s4*)(jcode + nextp);
1067
1068                                 } else {
1069                                         num = code_get_u4(nextp + 4);
1070                                         tablep = DMNEW(s4, num * 2 + 2);
1071                                 }
1072
1073                                 OP2A(opcode, 0, tablep);
1074
1075                                 /* default target */
1076
1077                                 j =  p + code_get_s4(nextp);
1078                                 if (useinlining) 
1079                                         j = label_index[j];
1080                                 *tablep = j;     /* restore for little endian */
1081                                 tablep++;
1082                                 nextp += 4;
1083                                 bound_check(j);
1084                                 block_insert(j);
1085
1086                                 /* number of pairs */
1087
1088                                 num = code_get_u4(nextp);
1089                                 *tablep = num;
1090                                 tablep++;
1091                                 nextp += 4;
1092
1093                                 if (nextp + 8*(num) > jcodelength)
1094                                         panic("Unexpected end of bytecode");
1095
1096                                 for (i = 0; i < num; i++) {
1097                                         /* value */
1098
1099                                         j = code_get_s4(nextp);
1100                                         *tablep = j; /* restore for little endian */
1101                                         tablep++;
1102                                         nextp += 4;
1103
1104                                         /* target */
1105
1106                                         j = p + code_get_s4(nextp);
1107                                         if (useinlining)
1108                                                 j = label_index[j];
1109                                         *tablep = j; /* restore for little endian */
1110                                         tablep++;
1111                                         nextp += 4;
1112                                         bound_check(j);
1113                                         block_insert(j);
1114                                 }
1115
1116                                 break;
1117                         }
1118
1119
1120                 case JAVA_TABLESWITCH:
1121                         {
1122                                 s4 num, j;
1123                                 s4 *tablep;
1124
1125                                 blockend = true;
1126                                 nextp = ALIGN((p + 1), 4);
1127                                 if (nextp + 12 > jcodelength)
1128                                         panic("Unexpected end of bytecode");
1129                                 if (!useinlining) {
1130                                         tablep = (s4*)(jcode + nextp);
1131
1132                                 } else {
1133                                         num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
1134                                         tablep = DMNEW(s4, num + 1 + 3);
1135                                 }
1136
1137                                 OP2A(opcode, 0, tablep);
1138
1139                                 /* default target */
1140
1141                                 j = p + code_get_s4(nextp);
1142                                 if (useinlining)
1143                                         j = label_index[j];
1144                                 *tablep = j;     /* restore for little endian */
1145                                 tablep++;
1146                                 nextp += 4;
1147                                 bound_check(j);
1148                                 block_insert(j);
1149
1150                                 /* lower bound */
1151
1152                                 j = code_get_s4(nextp);
1153                                 *tablep = j;     /* restore for little endian */
1154                                 tablep++;
1155                                 nextp += 4;
1156
1157                                 /* upper bound */
1158
1159                                 num = code_get_s4(nextp);
1160                                 *tablep = num;   /* restore for little endian */
1161                                 tablep++;
1162                                 nextp += 4;
1163
1164                                 num -= j;
1165
1166                                 if (nextp + 4*(num+1) > jcodelength)
1167                                         panic("Unexpected end of bytecode");
1168
1169                                 for (i = 0; i <= num; i++) {
1170                                         j = p + code_get_s4(nextp);
1171                                         if (useinlining)
1172                                                 j = label_index[j];
1173                                         *tablep = j; /* restore for little endian */
1174                                         tablep++;
1175                                         nextp += 4;
1176                                         bound_check(j);
1177                                         block_insert(j);
1178                                 }
1179
1180                                 break;
1181                         }
1182
1183
1184                         /* load and store of object fields *******************/
1185
1186                 case JAVA_AASTORE:
1187                         BUILTIN3(BUILTIN_aastore, TYPE_VOID);
1188                         break;
1189
1190                 case JAVA_PUTSTATIC:
1191                 case JAVA_GETSTATIC:
1192                         i = code_get_u2(p + 1);
1193                         {
1194                                 constant_FMIref *fr;
1195                                 fieldinfo *fi;
1196                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
1197                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
1198                                 compiler_addinitclass (fr->class);
1199                                 OP2A(opcode, fi->type, fi);
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);
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);
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);
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);
1277                         }
1278                         break;
1279
1280                         /* miscellaneous object operations *******/
1281
1282                 case JAVA_NEW:
1283                         i = code_get_u2 (p+1);
1284
1285                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1286                         s_count++;
1287                         BUILTIN1(BUILTIN_new, TYPE_ADR);
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(cls->vftbl);
1300                                                 s_count++;
1301                                                 BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR);
1302                                         }
1303                                         else { /* object type cast-check */
1304                                                 /*
1305 +                                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1306 +                                                 s_count++;
1307 +                                                 BUILTIN2(BUILTIN_checkcast, TYPE_ADR);
1308 +                                               */
1309                                                 OP2A(opcode, 1, cls);
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(cls->vftbl);
1326                                                 s_count++;
1327                                                 BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT);
1328                                         }
1329                                         else { /* object type cast-check */
1330                                                 /*
1331                                                   LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
1332                                                   s_count++;
1333                                                   BUILTIN2(BUILTIN_instanceof, TYPE_INT);
1334 +                                               */
1335                                                 OP2A(opcode, 1, cls);
1336                                         }
1337                                 }
1338                         break;
1339
1340                 case JAVA_MONITORENTER:
1341 #ifdef USE_THREADS
1342                         if (checksync) {
1343                                 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID);
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);
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);
1386 #endif
1387                         break;
1388
1389                 case JAVA_DREM:
1390 #if defined(__I386__)
1391                         OP(opcode);
1392 #else
1393                         BUILTIN2(BUILTIN_drem, TYPE_DOUBLE);
1394 #endif
1395                         break;
1396
1397                 case JAVA_F2I:
1398 #if defined(__ALPHA__)
1399                         if (!opt_noieee) {
1400                                 BUILTIN1(BUILTIN_f2i, TYPE_INT);
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);
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);
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);
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"); /* XXX change message */
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 = 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  */