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