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