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