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