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