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