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