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