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