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