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