Renamed loging to logging
[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 1067 2004-05-18 10:25:51Z stefan $
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':  *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                                 vftbl *arrayvftbl;
903                                 s4 v = code_get_u1(p + 3);
904
905                                 
906 /*                              vftbl *arrayvftbl = */
907 /*                                      ((classinfo *) class_getconstant(class, i, CONSTANT_Class))->vftbl; */
908 /*                              OP2A(opcode, v, arrayvftbl,currentline); */
909
910                                 
911                                 classinfo *component =
912                                         (classinfo *) class_getconstant(class, i, CONSTANT_Class);
913
914                                 class_load(component);
915                                 class_link(component);
916
917                                 arrayvftbl = component->vftbl;
918                                 OP2A(opcode, v, arrayvftbl,currentline);
919
920 /*                              classinfo *arrayclass = */
921 /*                                      (classinfo *) class_getconstant(class, i, CONSTANT_Class); */
922 /*                              OP2A(opcode, v, arrayclass, currentline); */
923                         }
924                         break;
925
926                 case JAVA_IFEQ:
927                 case JAVA_IFLT:
928                 case JAVA_IFLE:
929                 case JAVA_IFNE:
930                 case JAVA_IFGT:
931                 case JAVA_IFGE:
932                 case JAVA_IFNULL:
933                 case JAVA_IFNONNULL:
934                 case JAVA_IF_ICMPEQ:
935                 case JAVA_IF_ICMPNE:
936                 case JAVA_IF_ICMPLT:
937                 case JAVA_IF_ICMPGT:
938                 case JAVA_IF_ICMPLE:
939                 case JAVA_IF_ICMPGE:
940                 case JAVA_IF_ACMPEQ:
941                 case JAVA_IF_ACMPNE:
942                 case JAVA_GOTO:
943                 case JAVA_JSR:
944                         i = p + code_get_s2(p + 1);
945                         if (useinlining) { 
946                                 debug_writebranch;
947                                 i = label_index[i];
948                         }
949                         bound_check(i);
950                         block_insert(i);
951                         blockend = true;
952                         OP1(opcode, i);
953                         break;
954                 case JAVA_GOTO_W:
955                 case JAVA_JSR_W:
956                         i = p + code_get_s4(p + 1);
957                         if (useinlining) { 
958                                 debug_writebranch;
959                                 i = label_index[i];
960                         }
961                         bound_check(i);
962                         block_insert(i);
963                         blockend = true;
964                         OP1(opcode, i);
965                         break;
966
967                 case JAVA_RET:
968                         if (!iswide) {
969                                 i = code_get_u1(p + 1);
970                         } else {
971                                 i = code_get_u2(p + 1);
972                                 nextp = p + 3;
973                                 iswide = false;
974                         }
975                         blockend = true;
976                                 
977                         /*
978                           if (isinlinedmethod) {
979                           OP1(ICMD_GOTO, inlinfo->stopgp);
980                           break;
981                           }*/
982
983                         OP1LOAD(opcode, i + firstlocal);
984                         break;
985
986                 case JAVA_IRETURN:
987                 case JAVA_LRETURN:
988                 case JAVA_FRETURN:
989                 case JAVA_DRETURN:
990                 case JAVA_ARETURN:
991                 case JAVA_RETURN:
992                         if (isinlinedmethod) {
993                                 /*                                      if (p==jcodelength-1) {*/ /* return is at end of inlined method */
994                                 /*                                              OP(ICMD_NOP); */
995                                 /*                                              break; */
996                                 /*                                      } */
997                                 blockend = true;
998                                 OP1(ICMD_GOTO, inlinfo->stopgp);
999                                 break;
1000                         }
1001
1002                         blockend = true;
1003                         OP(opcode);
1004                         break;
1005
1006                 case JAVA_ATHROW:
1007                         blockend = true;
1008                         OP(opcode);
1009                         break;
1010                                 
1011
1012                         /* table jumps ********************************/
1013
1014                 case JAVA_LOOKUPSWITCH:
1015                         {
1016                                 s4 num, j;
1017                                 s4 *tablep;
1018                                 s4 prevvalue;
1019
1020                                 blockend = true;
1021                                 nextp = ALIGN((p + 1), 4);
1022                                 if (nextp + 8 > jcodelength)
1023                                         panic("Unexpected end of bytecode");
1024                                 if (!useinlining) {
1025                                         tablep = (s4*)(jcode + nextp);
1026
1027                                 } else {
1028                                         num = code_get_u4(nextp + 4);
1029                                         tablep = DMNEW(s4, num * 2 + 2);
1030                                 }
1031
1032                                 OP2A(opcode, 0, tablep,currentline);
1033
1034                                 /* default target */
1035
1036                                 j =  p + code_get_s4(nextp);
1037                                 if (useinlining) 
1038                                         j = label_index[j];
1039                                 *tablep = j;     /* restore for little endian */
1040                                 tablep++;
1041                                 nextp += 4;
1042                                 bound_check(j);
1043                                 block_insert(j);
1044
1045                                 /* number of pairs */
1046
1047                                 num = code_get_u4(nextp);
1048                                 *tablep = num;
1049                                 tablep++;
1050                                 nextp += 4;
1051
1052                                 if (nextp + 8*(num) > jcodelength)
1053                                         panic("Unexpected end of bytecode");
1054
1055                                 for (i = 0; i < num; i++) {
1056                                         /* value */
1057
1058                                         j = code_get_s4(nextp);
1059                                         *tablep = j; /* restore for little endian */
1060                                         tablep++;
1061                                         nextp += 4;
1062
1063                                         /* check if the lookup table is sorted correctly */
1064                                         
1065                                         if (i && (j <= prevvalue))
1066                                                 panic("invalid LOOKUPSWITCH: table not sorted");
1067                                         prevvalue = j;
1068
1069                                         /* target */
1070
1071                                         j = p + code_get_s4(nextp);
1072                                         if (useinlining)
1073                                                 j = label_index[j];
1074                                         *tablep = j; /* restore for little endian */
1075                                         tablep++;
1076                                         nextp += 4;
1077                                         bound_check(j);
1078                                         block_insert(j);
1079                                 }
1080
1081                                 break;
1082                         }
1083
1084
1085                 case JAVA_TABLESWITCH:
1086                         {
1087                                 s4 num, j;
1088                                 s4 *tablep;
1089
1090                                 blockend = true;
1091                                 nextp = ALIGN((p + 1), 4);
1092                                 if (nextp + 12 > jcodelength)
1093                                         panic("Unexpected end of bytecode");
1094                                 if (!useinlining) {
1095                                         tablep = (s4*)(jcode + nextp);
1096
1097                                 } else {
1098                                         num = code_get_u4(nextp + 8) - code_get_u4(nextp + 4);
1099                                         tablep = DMNEW(s4, num + 1 + 3);
1100                                 }
1101
1102                                 OP2A(opcode, 0, tablep,currentline);
1103
1104                                 /* default target */
1105
1106                                 j = p + code_get_s4(nextp);
1107                                 if (useinlining)
1108                                         j = label_index[j];
1109                                 *tablep = j;     /* restore for little endian */
1110                                 tablep++;
1111                                 nextp += 4;
1112                                 bound_check(j);
1113                                 block_insert(j);
1114
1115                                 /* lower bound */
1116
1117                                 j = code_get_s4(nextp);
1118                                 *tablep = j;     /* restore for little endian */
1119                                 tablep++;
1120                                 nextp += 4;
1121
1122                                 /* upper bound */
1123
1124                                 num = code_get_s4(nextp);
1125                                 *tablep = num;   /* restore for little endian */
1126                                 tablep++;
1127                                 nextp += 4;
1128
1129                                 num -= j;  /* difference of upper - lower */
1130                                 if (num < 0)
1131                                         panic("invalid TABLESWITCH: upper bound < lower bound");
1132
1133                                 if (nextp + 4*(num+1) > jcodelength)
1134                                         panic("Unexpected end of bytecode");
1135
1136                                 for (i = 0; i <= num; i++) {
1137                                         j = p + code_get_s4(nextp);
1138                                         if (useinlining)
1139                                                 j = label_index[j];
1140                                         *tablep = j; /* restore for little endian */
1141                                         tablep++;
1142                                         nextp += 4;
1143                                         bound_check(j);
1144                                         block_insert(j);
1145                                 }
1146
1147                                 break;
1148                         }
1149
1150
1151                         /* load and store of object fields *******************/
1152
1153                 case JAVA_AASTORE:
1154                         BUILTIN3(BUILTIN_aastore, TYPE_VOID,currentline);
1155                         break;
1156
1157                 case JAVA_PUTSTATIC:
1158                 case JAVA_GETSTATIC:
1159                         i = code_get_u2(p + 1);
1160                         {
1161                                 constant_FMIref *fr;
1162                                 fieldinfo *fi;
1163
1164                                 fr = class_getconstant(class, i, CONSTANT_Fieldref);
1165
1166                                 class_load(fr->class);
1167                                 class_link(fr->class);
1168
1169                                 fi = class_resolvefield(fr->class, fr->name, fr->descriptor, class, true);
1170                                 if (!fi)
1171                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1172                                 OP2A(opcode, fi->type, fi,currentline);
1173                                 if (!fi->class->initialized) {
1174                                         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 (class, i, CONSTANT_Fieldref);
1187
1188                                 class_load(fr->class);
1189                                 class_link(fr->class);
1190
1191                                 fi = class_resolvefield(fr->class, fr->name, fr->descriptor, class, true);
1192                                 if (!fi)
1193                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1194                                 OP2A(opcode, fi->type, fi,currentline);
1195                         }
1196                         break;
1197
1198
1199                         /* method invocation *****/
1200
1201                 case JAVA_INVOKESTATIC:
1202                         i = code_get_u2(p + 1);
1203                         {
1204                                 constant_FMIref *mr;
1205                                 methodinfo *mi;
1206                                 
1207                                 mr = class_getconstant(class, i, CONSTANT_Methodref);
1208
1209                                 class_load(mr->class);
1210                                 class_link(mr->class);
1211
1212                                 mi = class_resolveclassmethod(mr->class, mr->name, mr->descriptor, class, true);
1213                                 if (!mi)
1214                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1215                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1216                                         /*RTAprint*/    {printf(" method name =");
1217                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1218                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE STATIC\n");
1219                                         /*RTAprint*/    fflush(stdout);}
1220                                 if (!(mi->flags & ACC_STATIC))
1221                                         panic ("Static/Nonstatic mismatch calling static method");
1222                                 descriptor2types(mi);
1223
1224                                 isleafmethod=false;
1225                                 OP2A(opcode, mi->paramcount, mi,currentline);
1226                         }
1227                         break;
1228
1229                 case JAVA_INVOKESPECIAL:
1230                 case JAVA_INVOKEVIRTUAL:
1231                         i = code_get_u2(p + 1);
1232                         {
1233                                 constant_FMIref *mr;
1234                                 methodinfo *mi;
1235
1236                                 mr = class_getconstant(class, i, CONSTANT_Methodref);
1237
1238                                 class_load(mr->class);
1239                                 class_link(mr->class);
1240
1241                                 mi = class_resolveclassmethod(mr->class, mr->name, mr->descriptor, class, true);
1242                                 if (!mi)
1243                                         panic("Exception thrown while parsing bytecode");
1244
1245                                 /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
1246                                         /*RTAprint*/    {printf(" method name =");
1247                                         method_display(mi);
1248                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
1249                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
1250                                         /*RTAprint*/    fflush(stdout);}
1251
1252                                 if (mi->flags & ACC_STATIC)
1253                                         panic ("Static/Nonstatic mismatch calling static method");
1254                                 descriptor2types(mi);
1255                                 isleafmethod=false;
1256                                 OP2A(opcode, mi->paramcount, mi,currentline);
1257                         }
1258                         break;
1259
1260                 case JAVA_INVOKEINTERFACE:
1261                         i = code_get_u2(p + 1);
1262                         {
1263                                 constant_FMIref *mr;
1264                                 methodinfo *mi;
1265                                 
1266                                 mr = class_getconstant(class, i, CONSTANT_InterfaceMethodref);
1267
1268                                 class_load(mr->class);
1269                                 class_link(mr->class);
1270
1271                                 mi = class_resolveinterfacemethod(mr->class, mr->name, mr->descriptor, class, true);
1272                                 if (!mi)
1273                                         panic("Exception thrown while parsing bytecode"); /* XXX should be passed on */
1274                                 if (mi->flags & ACC_STATIC)
1275                                         panic ("Static/Nonstatic mismatch calling static method");
1276                                 descriptor2types(mi);
1277                                 isleafmethod=false;
1278                                 OP2A(opcode, mi->paramcount, mi,currentline);
1279                         }
1280                         break;
1281
1282                         /* miscellaneous object operations *******/
1283
1284                 case JAVA_NEW:
1285                         i = code_get_u2 (p+1);
1286
1287                         LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1288                         s_count++;
1289                         BUILTIN1(BUILTIN_new, TYPE_ADR,currentline);
1290                         OP2I(ICMD_CHECKOOM, 0, 0);
1291                         break;
1292
1293                 case JAVA_CHECKCAST:
1294                         i = code_get_u2(p+1);
1295                                 {
1296                                         classinfo *cls =
1297                                                 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
1298
1299                                         /* is the class loaded */
1300                                         if (!cls->loaded)
1301                                                 class_load(cls);
1302
1303                                         /* is the class linked */
1304                                         if (!cls->linked)
1305                                                 class_link(cls);
1306
1307                                         if (cls->vftbl->arraydesc) {
1308                                                 /* array type cast-check */
1309                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1310                                                 s_count++;
1311                                                 BUILTIN2(BUILTIN_checkarraycast, TYPE_ADR,currentline);
1312                                         }
1313                                         else { /* object type cast-check */
1314                                                 /*
1315 +                                                 LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1316 +                                                 s_count++;
1317 +                                                 BUILTIN2(BUILTIN_checkcast, TYPE_ADR,currentline);
1318 +                                               */
1319                                                 OP2A(opcode, 1, cls,currentline);
1320                                         }
1321                                 }
1322
1323                         break;
1324
1325                 case JAVA_INSTANCEOF:
1326                         i = code_get_u2(p+1);
1327
1328                                 {
1329                                         classinfo *cls =
1330                                                 (classinfo *) class_getconstant(class, i, CONSTANT_Class);
1331
1332                                         /* is the class loaded */
1333                                         if (!cls->loaded)
1334                                                 class_load(cls);
1335
1336                                         /* is the class linked */
1337                                         if (!cls->linked)
1338                                                 class_link(cls);
1339
1340                                         if (cls->vftbl->arraydesc) {
1341                                                 /* array type cast-check */
1342                                                 LOADCONST_A_BUILTIN(cls->vftbl);
1343                                                 s_count++;
1344                                                 BUILTIN2(BUILTIN_arrayinstanceof, TYPE_INT,currentline);
1345                                         }
1346                                         else { /* object type cast-check */
1347                                                 /*
1348                                                   LOADCONST_A_BUILTIN(class_getconstant(class, i, CONSTANT_Class));
1349                                                   s_count++;
1350                                                   BUILTIN2(BUILTIN_instanceof, TYPE_INT,currentline);
1351 +                                               */
1352                                                 OP2A(opcode, 1, cls,currentline);
1353                                         }
1354                                 }
1355                         break;
1356
1357                 case JAVA_MONITORENTER:
1358 #ifdef USE_THREADS
1359                         if (checksync) {
1360                                 BUILTIN1(BUILTIN_monitorenter, TYPE_VOID,currentline);
1361                         } else
1362 #endif
1363                                 {
1364                                         OP(ICMD_NULLCHECKPOP);
1365                                 }
1366                         break;
1367
1368                 case JAVA_MONITOREXIT:
1369 #ifdef USE_THREADS
1370                         if (checksync) {
1371                                 BUILTIN1(BUILTIN_monitorexit, TYPE_VOID,currentline);
1372                         }
1373                         else
1374 #endif
1375                                 {
1376                                         OP(ICMD_POP);
1377                                 }
1378                         break;
1379
1380                         /* any other basic operation **************************************/
1381
1382                 case JAVA_IDIV:
1383                         OP(opcode);
1384                         break;
1385
1386                 case JAVA_IREM:
1387                         OP(opcode);
1388                         break;
1389
1390                 case JAVA_LDIV:
1391                         OP(opcode);
1392                         break;
1393
1394                 case JAVA_LREM:
1395                         OP(opcode);
1396                         break;
1397
1398                 case JAVA_FREM:
1399 #if defined(__I386__)
1400                         OP(opcode);
1401 #else
1402                         BUILTIN2(BUILTIN_frem, TYPE_FLOAT,currentline);
1403 #endif
1404                         break;
1405
1406                 case JAVA_DREM:
1407 #if defined(__I386__)
1408                         OP(opcode);
1409 #else
1410                         BUILTIN2(BUILTIN_drem, TYPE_DOUBLE,currentline);
1411 #endif
1412                         break;
1413
1414                 case JAVA_F2I:
1415 #if defined(__ALPHA__)
1416                         if (!opt_noieee) {
1417                                 BUILTIN1(BUILTIN_f2i, TYPE_INT,currentline);
1418                         } else
1419 #endif
1420                                 {
1421                                         OP(opcode);
1422                                 }
1423                         break;
1424
1425                 case JAVA_F2L:
1426 #if defined(__ALPHA__)
1427                         if (!opt_noieee) {
1428                                 BUILTIN1(BUILTIN_f2l, TYPE_LONG,currentline);
1429                         } else 
1430 #endif
1431                                 {
1432                                         OP(opcode);
1433                                 }
1434                         break;
1435
1436                 case JAVA_D2I:
1437 #if defined(__ALPHA__)
1438                         if (!opt_noieee) {
1439                                 BUILTIN1(BUILTIN_d2i, TYPE_INT,currentline);
1440                         } else
1441 #endif
1442                                 {
1443                                         OP(opcode);
1444                                 }
1445                         break;
1446
1447                 case JAVA_D2L:
1448 #if defined(__ALPHA__)
1449                         if (!opt_noieee) {
1450                                 BUILTIN1(BUILTIN_d2l, TYPE_LONG,currentline);
1451                         } else
1452 #endif
1453                                 {
1454                                         OP(opcode);
1455                                 }
1456                         break;
1457
1458                 case JAVA_BREAKPOINT:
1459                         panic("Illegal opcode Breakpoint encountered");
1460                         break;
1461
1462                 case 186: /* unused opcode */
1463                 case 203:
1464                 case 204:
1465                 case 205:
1466                 case 206:
1467                 case 207:
1468                 case 208:
1469                 case 209:
1470                 case 210:
1471                 case 211:
1472                 case 212:
1473                 case 213:
1474                 case 214:
1475                 case 215:
1476                 case 216:
1477                 case 217:
1478                 case 218:
1479                 case 219:
1480                 case 220:
1481                 case 221:
1482                 case 222:
1483                 case 223:
1484                 case 224:
1485                 case 225:
1486                 case 226:
1487                 case 227:
1488                 case 228:
1489                 case 229:
1490                 case 230:
1491                 case 231:
1492                 case 232:
1493                 case 233:
1494                 case 234:
1495                 case 235:
1496                 case 236:
1497                 case 237:
1498                 case 238:
1499                 case 239:
1500                 case 240:
1501                 case 241:
1502                 case 242:
1503                 case 243:
1504                 case 244:
1505                 case 245:
1506                 case 246:
1507                 case 247:
1508                 case 248:
1509                 case 249:
1510                 case 250:
1511                 case 251:
1512                 case 252:
1513                 case 253:
1514                 case 254:
1515                 case 255:
1516                         printf("Illegal opcode %d at instr %d\n", opcode, ipc);
1517                         panic("Illegal opcode encountered");
1518                         break;
1519
1520                 default:
1521                         OP(opcode);
1522                         break;
1523                                 
1524                 } /* end switch */
1525
1526                 /* If WIDE was used correctly, iswide should have been reset by now. */
1527                 if (iswide && opcode != JAVA_WIDE)
1528                         panic("Illegal instruction: WIDE before incompatible opcode");
1529                 
1530                 /* INLINING */
1531                   
1532                 if (isinlinedmethod && p == jcodelength - 1) { /* end of an inlined method */
1533                         /*                printf("setting gp from %d to %d\n",gp, inlinfo->stopgp); */
1534                         gp = inlinfo->stopgp; 
1535                         inlining_restore_compiler_variables();
1536                         list_remove(inlinfo->inlinedmethods, list_first(inlinfo->inlinedmethods));
1537                         if (inlinfo->inlinedmethods == NULL) {
1538                                 nextgp = -1;
1539                         } else {
1540                                 tmpinlinf = list_first(inlinfo->inlinedmethods);
1541                                 nextgp = (tmpinlinf != NULL) ? tmpinlinf->startgp : -1;
1542                         }
1543                         /*                printf("nextpgp: %d\n", nextgp); */
1544                         label_index=inlinfo->label_index;
1545                         firstlocal = inlinfo->firstlocal;
1546                 }
1547         } /* end for */
1548
1549         if (p != jcodelength)
1550                 panic("Command-sequence crosses code-boundary");
1551
1552         if (!blockend)
1553                 panic("Code does not end with branch/return/athrow - stmt");
1554
1555         /* adjust block count if target 0 is not first intermediate instruction   */
1556
1557         if (!block_index[0] || (block_index[0] > 1))
1558                 b_count++;
1559
1560         /* copy local to global variables   */
1561
1562         instr_count = ipc;
1563         block_count = b_count;
1564         stack_count = s_count + block_count * maxstack;
1565
1566         /* allocate stack table */
1567
1568         stack = DMNEW(stackelement, stack_count);
1569
1570         {
1571                 basicblock  *bptr;
1572
1573                 bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1574
1575                 b_count = 0;
1576                 c_debug_nr = 0;
1577         
1578                 /* additional block if target 0 is not first intermediate instruction     */
1579
1580                 if (!block_index[0] || (block_index[0] > 1)) {
1581                         bptr->iinstr = instr;
1582                         bptr->mpc = -1;
1583                         bptr->flags = -1;
1584                         bptr->type = BBTYPE_STD;
1585                         bptr->branchrefs = NULL;
1586                         bptr->pre_count = 0;
1587                         bptr->debug_nr = c_debug_nr++;
1588                         bptr++;
1589                         b_count++;
1590                         (bptr - 1)->next = bptr;
1591                 }
1592
1593                 /* allocate blocks */
1594
1595                 for (p = 0; p < cumjcodelength; p++) {
1596                         if (block_index[p] & 1) {
1597                                 /* check if this block starts at the beginning of an instruction */
1598                                 if (!instructionstart[p])
1599                                         panic("Branch into middle of instruction");
1600                                 /* allocate the block */
1601                                 bptr->iinstr = instr + (block_index[p] >> 1);
1602                                 bptr->debug_nr = c_debug_nr++;
1603                                 if (b_count != 0)
1604                                         (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1605                                 bptr->mpc = -1;
1606                                 bptr->flags = -1;
1607                                 bptr->lflags = 0;
1608                                 bptr->type = BBTYPE_STD;
1609                                 bptr->branchrefs = NULL;
1610                                 block_index[p] = b_count;
1611                                 bptr->pre_count = 0;
1612                                 bptr++;
1613                                 b_count++;
1614                                 (bptr - 1)->next = bptr;
1615                         }
1616                 }
1617
1618                 /* allocate additional block at end */
1619
1620                 bptr->instack = bptr->outstack = NULL;
1621                 bptr->indepth = bptr->outdepth = 0;
1622                 bptr->iinstr = NULL;
1623                 (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1624                 bptr->icount = 0;
1625                 bptr->mpc = -1;
1626                 bptr->flags = -1;
1627                 bptr->lflags = 0;
1628                 bptr->type = BBTYPE_STD;
1629                 bptr->branchrefs = NULL;
1630                 bptr->pre_count = 0;
1631                 bptr->debug_nr = c_debug_nr++;
1632                 (bptr - 1)->next = bptr;
1633                 bptr->next = NULL;
1634
1635                 last_block = bptr;
1636
1637                 if (exceptiontablelength > 0)
1638                         extable[exceptiontablelength - 1].down = NULL;
1639                 else
1640                         extable = NULL;
1641
1642                 for (i = 0; i < exceptiontablelength; ++i) {
1643                         p = extable[i].startpc;
1644                         extable[i].start = block + block_index[p];
1645
1646                         p = extable[i].endpc;
1647                         extable[i].end = (p == cumjcodelength) ? last_block : (block + block_index[p]);
1648
1649                         p = extable[i].handlerpc;
1650                         extable[i].handler = block + block_index[p];
1651             }
1652         }
1653         
1654         if (useinlining) inlining_cleanup();
1655         useinlining = useinltmp;
1656
1657         if (compileverbose) {
1658                 char logtext[MAXLOGTEXT];
1659                 sprintf(logtext, "Parsing done: ");
1660                 utf_sprint_classname(logtext + strlen(logtext), method->class->name);
1661                 strcpy(logtext + strlen(logtext), ".");
1662                 utf_sprint(logtext + strlen(logtext), method->name);
1663                 utf_sprint_classname(logtext + strlen(logtext), method->descriptor);
1664                 log_text(logtext);
1665         }
1666 }
1667
1668
1669 /*
1670  * These are local overrides for various environment variables in Emacs.
1671  * Please do not remove this and leave it at the end of the file, where
1672  * Emacs will automagically detect them.
1673  * ---------------------------------------------------------------------
1674  * Local variables:
1675  * mode: c
1676  * indent-tabs-mode: t
1677  * c-basic-offset: 4
1678  * tab-width: 4
1679  * End:
1680  */