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