433507199146ddff946022b6ab07a6a6a4b24397
[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, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Author: Andreas Krall
28
29    Changes: Carolyn Oates
30             Edwin Steiner
31             Joseph Wenninger
32             Christian Thalinger
33
34    $Id: parse.c 5785 2006-10-15 22:25:54Z edwin $
35
36 */
37
38
39 #include "config.h"
40
41 #include <assert.h>
42 #include <string.h>
43
44 #include "vm/types.h"
45
46 #include "mm/memory.h"
47 #include "native/native.h"
48
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/lock.h"
51 #endif
52
53 #include "toolbox/logging.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/linker.h"
58 #include "vm/loader.h"
59 #include "vm/resolve.h"
60 #include "vm/options.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
63 #include "vm/suck.h"
64 #include "vm/jit/asmpart.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/loop/loop.h"
69
70 #define INSTRUCTIONS_INCREMENT  5  /* number of additional instructions to    */
71                                    /* allocate if space runs out              */
72
73
74 /* parserdata_t ***************************************************************/
75
76 typedef struct parsedata_t parsedata_t;
77
78 struct parsedata_t {
79         instruction *instructions;          /* instruction array                  */
80         s4           instructionslength;    /* length of the instruction array    */
81         u1          *instructionstart;
82 };
83
84
85 /* parse_setup *****************************************************************
86
87    Fills the passed parsedata_t structure.
88
89 *******************************************************************************/
90
91 static void parse_setup(jitdata *jd, parsedata_t *pd)
92 {
93         methodinfo *m;
94
95         /* get required compiler data */
96
97         m = jd->m;
98
99         /* Allocate instruction array and block index table (1 additional
100            for end ipc). */
101
102         jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
103         pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
104
105         MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
106         MZERO(pd->instructionstart, u1, m->jcodelength + 1);
107
108         /* Set the length of the instruction array.  We simply add 5 more
109            instruction, as this seems to be a reasonable value. */
110
111         pd->instructionslength = m->jcodelength + 1;
112
113         /* allocate the instruction array */
114
115         pd->instructions = DMNEW(instruction, pd->instructionslength);
116
117         /* Zero the intermediate instructions array so we don't have any
118            invalid pointers in it if we cannot finish stack_analyse(). */
119
120         MZERO(pd->instructions, instruction, pd->instructionslength);
121 }
122
123
124 /* parse_realloc_instructions **************************************************
125
126    Reallocate the instructions array so there is room for at least N 
127    additional instructions.
128
129    RETURN VALUE:
130        the new value for iptr
131
132 *******************************************************************************/
133
134 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
135 {
136         /* increase the size of the instruction array */
137
138         pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
139
140         /* reallocate the array */
141
142         pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
143                                                                  pd->instructionslength);
144
145         /* return the iptr */
146
147         return pd->instructions + ipc;
148 }
149
150
151 /* parse_mark_exception_boundaries *********************************************
152
153    Mark exception handlers and the boundaries of the handled regions as
154    basic block boundaries.
155
156    IN:
157        jd...............current jitdata
158
159    RETURN VALUE:
160        >= 0.............the number of new basic blocks marked
161            -1...............an exception has been thrown
162
163 *******************************************************************************/
164
165 static int parse_mark_exception_boundaries(jitdata *jd)
166 {
167         s4                   b_count;
168         s4                   pc;
169         s4                   i;
170         s4                   len;
171         raw_exception_entry *rex;
172         methodinfo          *m;
173
174         m = jd->m;
175         
176         len = m->rawexceptiontablelength;
177
178         if (len == 0)
179                 return 0;
180
181         b_count = 0;
182         rex = m->rawexceptiontable;
183
184         for (i = 0; i < len; ++i, ++rex) {
185
186                 /* the start of the handled region becomes a basic block start */
187
188                 pc = rex->startpc;
189                 CHECK_BYTECODE_INDEX(pc);
190                 MARK_BASICBLOCK(pc);
191                 
192                 pc = rex->endpc; /* see JVM Spec 4.7.3 */
193                 CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
194
195                 /* check that the range is valid */
196
197 #if defined(ENABLE_VERIFIER)
198                 if (pc <= rex->startpc) {
199                         exceptions_throw_verifyerror(m,
200                                 "Invalid exception handler range");
201                         return -1;
202                 }
203 #endif
204                 
205                 /* end of handled region becomes a basic block boundary  */
206                 /* (If it is the bytecode end, we'll use the special     */
207                 /* end block that is created anyway.)                    */
208
209                 if (pc < m->jcodelength)
210                         MARK_BASICBLOCK(pc);
211
212                 /* the start of the handler becomes a basic block start  */
213
214                 pc = rex->handlerpc;
215                 CHECK_BYTECODE_INDEX(pc);
216                 MARK_BASICBLOCK(pc);
217         }
218
219         /* everything ok */
220
221         return b_count;
222
223 #if defined(ENABLE_VERIFIER)
224 throw_invalid_bytecode_index:
225         exceptions_throw_verifyerror(m,
226                                                                  "Illegal bytecode index in exception table");
227         return -1;
228 #endif
229 }
230
231
232 /* parse_resolve_exception_table ***********************************************
233
234    Enter the exception handlers and their ranges, resolved to basicblock *s,
235    in the jitdata.
236
237    IN:
238        jd...............current jitdata
239
240    RETURN VALUE:
241            true.............everything ok
242            false............an exception has been thrown
243
244 *******************************************************************************/
245
246 static bool parse_resolve_exception_table(jitdata *jd)
247 {
248         codegendata         *cd;
249         methodinfo          *m;
250         raw_exception_entry *rex;
251         exception_entry     *ex;
252         s4                   i;
253         s4                   len;
254         classinfo           *exclass;
255
256         m = jd->m;
257         cd = jd->cd;
258
259         len = m->rawexceptiontablelength;
260
261         /* common case: no handler entries */
262
263         if (len == 0)
264                 return true;
265
266         /* allocate the exception table */
267
268         jd->exceptiontablelength = len;
269         jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
270
271         /* copy and resolve the entries */
272
273         ex = jd->exceptiontable;
274         rex = m->rawexceptiontable;
275
276         for (i = 0; i < len; ++i, ++rex, ++ex) {
277                 /* resolve instruction indices to basic blocks */
278
279                 ex->start   = BLOCK_OF(rex->startpc);
280                 ex->end     = BLOCK_OF(rex->endpc);
281                 ex->handler = BLOCK_OF(rex->handlerpc);
282
283                 /* lazily resolve the catchtype */
284
285                 if (rex->catchtype.any != NULL) {
286                         if (!resolve_classref_or_classinfo(m,
287                                                                                            rex->catchtype,
288                                                                                            resolveLazy, true, false,
289                                                                                            &exclass))
290                                 return false;
291
292                         /* if resolved, enter the result of resolution in the table */
293
294                         if (exclass != NULL)
295                                 rex->catchtype.cls = exclass;
296                 }
297
298                 ex->catchtype = rex->catchtype;
299                 ex->next = NULL;   /* set by loop analysis */
300                 ex->down = ex + 1; /* link to next exception entry */
301         }
302
303         /* terminate the ->down linked list */
304
305         assert(ex != jd->exceptiontable);
306         ex[-1].down = NULL;
307
308         return true;
309 }
310
311
312 /*******************************************************************************
313
314         function 'parse' scans the JavaVM code and generates intermediate code
315
316         During parsing the block index table is used to store at bit pos 0
317         a flag which marks basic block starts and at position 1 to 31 the
318         intermediate instruction index. After parsing the block index table
319         is scanned, for marked positions a block is generated and the block
320         number is stored in the block index table.
321
322 *******************************************************************************/
323
324 /*** macro for checking the length of the bytecode ***/
325
326 #if defined(ENABLE_VERIFIER)
327 #define CHECK_END_OF_BYTECODE(neededlength) \
328         do { \
329                 if ((neededlength) > m->jcodelength) \
330                         goto throw_unexpected_end_of_bytecode; \
331         } while (0)
332 #else /* !ENABLE_VERIFIER */
333 #define CHECK_END_OF_BYTECODE(neededlength)
334 #endif /* ENABLE_VERIFIER */
335
336 bool parse(jitdata *jd)
337 {
338         methodinfo  *m;                     /* method being parsed                */
339         codeinfo    *code;
340         codegendata *cd;
341         parsedata_t  pd;
342         instruction *iptr;                  /* current ptr into instruction array */
343         s4           ipc;                   /* intermediate instruction counter   */
344         s4           p;                     /* java instruction counter           */
345         s4           nextp;                 /* start of next java instruction     */
346         s4           opcode;                /* java opcode                        */
347         s4           i;
348         s4           j;
349         int  b_count;               /* basic block counter                      */
350         int  s_count = 0;           /* stack element counter                    */
351         bool blockend = false;      /* true if basic block end has been reached */
352         bool iswide = false;        /* true if last instruction was a wide      */
353         constant_classref  *cr;
354         constant_classref  *compr;
355         classinfo          *c;
356         builtintable_entry *bte;
357         constant_FMIref    *mr;
358         methoddesc         *md;
359         unresolved_method  *um;
360         resolve_result_t    result;
361         u2                  lineindex = 0;
362         u2                  currentline = 0;
363         u2                  linepcchange = 0;
364         u4                  flags;
365         basicblock         *bptr;
366
367         int                *local_map; /* local pointer to renaming structore     */
368                                        /* is assigned to rd->local_map at the end */
369         /* get required compiler data */
370
371         m    = jd->m;
372         code = jd->code;
373         cd   = jd->cd;
374
375         /* allocate buffers for local variable renaming */
376         local_map = DMNEW(int, cd->maxlocals * 5);
377         for (i = 0; i < cd->maxlocals; i++) {
378                 local_map[i * 5 + 0] = 0;
379                 local_map[i * 5 + 1] = 0;
380                 local_map[i * 5 + 2] = 0;
381                 local_map[i * 5 + 3] = 0;
382                 local_map[i * 5 + 4] = 0;
383         }
384
385         /* initialize the parse data structures */
386   
387         parse_setup(jd, &pd);
388   
389         /* initialize local variables */
390   
391         iptr = pd.instructions;
392         ipc  = 0;
393   
394         /* mark basic block boundaries for exception table */
395
396         b_count = parse_mark_exception_boundaries(jd);
397         if (b_count < 0)
398                 return false;
399
400         /* initialize stack element counter */
401
402         s_count = 1 + m->rawexceptiontablelength;
403
404 #if defined(ENABLE_THREADS)
405         if (checksync && (m->flags & ACC_SYNCHRONIZED))
406                 jd->isleafmethod = false;
407 #endif
408
409         /* setup line number info */
410
411         currentline = 0;
412         linepcchange = 0;
413
414         if (m->linenumbercount == 0) {
415                 lineindex = 0;
416         }
417         else {
418                 linepcchange = m->linenumbers[0].start_pc;
419         }
420
421         /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
422
423         for (p = 0; p < m->jcodelength; p = nextp) {
424
425                 /* mark this position as a valid instruction start */
426
427                 pd.instructionstart[p] = 1;
428
429                 /* change the current line number, if necessary */
430
431                 /* XXX rewrite this using pointer arithmetic */
432
433                 if (linepcchange == p) {
434                         if (m->linenumbercount > lineindex) {
435 next_linenumber:
436                                 currentline = m->linenumbers[lineindex].line_number;
437                                 lineindex++;
438                                 if (lineindex < m->linenumbercount) {
439                                         linepcchange = m->linenumbers[lineindex].start_pc;
440                                         if (linepcchange == p)
441                                                 goto next_linenumber;
442                                 }
443                         }
444                 }
445
446 fetch_opcode:
447                 /* fetch next opcode  */        
448
449                 opcode = SUCK_BE_U1(m->jcode + p);
450
451                 /* some compilers put a JAVA_NOP after a blockend instruction */
452
453                 if (blockend && (opcode != JAVA_NOP)) {
454                         /* start new block */
455
456                         MARK_BASICBLOCK(p);
457                         blockend = false;
458                 }
459
460                 /* We need a NOP as last instruction in each basic block
461                    for basic block reordering (may be replaced with a GOTO
462                    later). */
463
464                 if (jd->basicblockindex[p] & 1) {
465                         INSTRUCTIONS_CHECK(1);
466                         OP(ICMD_NOP);
467                 }
468
469                 /* store intermediate instruction count (bit 0 mark block starts) */
470
471                 jd->basicblockindex[p] |= (ipc << 1);
472
473                 /* compute next instruction start */
474
475                 nextp = p + jcommandsize[opcode];
476
477                 CHECK_END_OF_BYTECODE(nextp);
478
479                 /* add stack elements produced by this instruction */
480
481                 s_count += stackreq[opcode];
482
483                 /* We check here for the space of 1 instruction in the
484                    instruction array.  If an opcode is converted to more than
485                    1 instruction, this is checked in the corresponding
486                    case. */
487
488                 INSTRUCTIONS_CHECK(1);
489
490                 /* translate this bytecode instruction */
491                 switch (opcode) {
492
493                 case JAVA_NOP:
494                         break;
495
496                 /* pushing constants onto the stack ***********************************/
497
498                 case JAVA_BIPUSH:
499                         OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
500                         break;
501
502                 case JAVA_SIPUSH:
503                         OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
504                         break;
505
506                 case JAVA_LDC1:
507                         i = SUCK_BE_U1(m->jcode + p + 1);
508                         goto pushconstantitem;
509
510                 case JAVA_LDC2:
511                 case JAVA_LDC2W:
512                         i = SUCK_BE_U2(m->jcode + p + 1);
513
514                 pushconstantitem:
515
516 #if defined(ENABLE_VERIFIER)
517                         if (i >= m->class->cpcount) {
518                                 exceptions_throw_verifyerror(m,
519                                         "Attempt to access constant outside range");
520                                 return false;
521                         }
522 #endif
523
524                         switch (m->class->cptags[i]) {
525                         case CONSTANT_Integer:
526                                 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
527                                 break;
528                         case CONSTANT_Long:
529                                 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
530                                 break;
531                         case CONSTANT_Float:
532                                 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
533                                 break;
534                         case CONSTANT_Double:
535                                 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
536                                 break;
537                         case CONSTANT_String:
538                                 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
539                                 break;
540                         case CONSTANT_Class:
541                                 cr = (constant_classref *) (m->class->cpinfos[i]);
542
543                                 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
544                                         return false;
545
546                                 /* if not resolved, c == NULL */
547
548                                 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
549
550                                 break;
551
552 #if defined(ENABLE_VERIFIER)
553                         default:
554                                 exceptions_throw_verifyerror(m,
555                                                 "Invalid constant type to push");
556                                 return false;
557 #endif
558                         }
559                         break;
560
561                 case JAVA_ACONST_NULL:
562                         OP_LOADCONST_NULL();
563                         break;
564
565                 case JAVA_ICONST_M1:
566                 case JAVA_ICONST_0:
567                 case JAVA_ICONST_1:
568                 case JAVA_ICONST_2:
569                 case JAVA_ICONST_3:
570                 case JAVA_ICONST_4:
571                 case JAVA_ICONST_5:
572                         OP_LOADCONST_I(opcode - JAVA_ICONST_0);
573                         break;
574
575                 case JAVA_LCONST_0:
576                 case JAVA_LCONST_1:
577                         OP_LOADCONST_L(opcode - JAVA_LCONST_0);
578                         break;
579
580                 case JAVA_FCONST_0:
581                 case JAVA_FCONST_1:
582                 case JAVA_FCONST_2:
583                         OP_LOADCONST_F(opcode - JAVA_FCONST_0);
584                         break;
585
586                 case JAVA_DCONST_0:
587                 case JAVA_DCONST_1:
588                         OP_LOADCONST_D(opcode - JAVA_DCONST_0);
589                         break;
590
591                 /* stack operations ***************************************************/
592
593                 /* We need space for additional ICMDs so we can translate these       */
594                 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
595
596                 case JAVA_DUP_X1:
597                         INSTRUCTIONS_CHECK(4);
598                         OP(opcode);
599                         OP(ICMD_NOP);
600                         OP(ICMD_NOP);
601                         OP(ICMD_NOP);
602                         break;
603
604                 case JAVA_DUP_X2:
605                         INSTRUCTIONS_CHECK(6);
606                         OP(opcode);
607                         OP(ICMD_NOP);
608                         OP(ICMD_NOP);
609                         OP(ICMD_NOP);
610                         OP(ICMD_NOP);
611                         OP(ICMD_NOP);
612                         break;
613
614                 case JAVA_DUP2:
615                         INSTRUCTIONS_CHECK(2);
616                         OP(opcode);
617                         OP(ICMD_NOP);
618                         break;
619
620                 case JAVA_DUP2_X1:
621                         INSTRUCTIONS_CHECK(7);
622                         OP(opcode);
623                         OP(ICMD_NOP);
624                         OP(ICMD_NOP);
625                         OP(ICMD_NOP);
626                         OP(ICMD_NOP);
627                         OP(ICMD_NOP);
628                         OP(ICMD_NOP);
629                         break;
630
631                 case JAVA_DUP2_X2:
632                         INSTRUCTIONS_CHECK(9);
633                         OP(opcode);
634                         OP(ICMD_NOP);
635                         OP(ICMD_NOP);
636                         OP(ICMD_NOP);
637                         OP(ICMD_NOP);
638                         OP(ICMD_NOP);
639                         OP(ICMD_NOP);
640                         OP(ICMD_NOP);
641                         OP(ICMD_NOP);
642                         break;
643
644                 case JAVA_SWAP:
645                         INSTRUCTIONS_CHECK(3);
646                         OP(opcode);
647                         OP(ICMD_NOP);
648                         OP(ICMD_NOP);
649                         break;
650
651                 /* local variable access instructions *********************************/
652
653                 case JAVA_ILOAD:
654                 case JAVA_FLOAD:
655                 case JAVA_ALOAD:
656                         if (iswide == false) {
657                                 i = SUCK_BE_U1(m->jcode + p + 1);
658                         }
659                         else {
660                                 i = SUCK_BE_U2(m->jcode + p + 1);
661                                 nextp = p + 3;
662                                 iswide = false;
663                         }
664                         OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
665                         break;
666
667                 case JAVA_LLOAD:
668                 case JAVA_DLOAD:
669                         if (iswide == false) {
670                                 i = SUCK_BE_U1(m->jcode + p + 1);
671                         }
672                         else {
673                                 i = SUCK_BE_U2(m->jcode + p + 1);
674                                 nextp = p + 3;
675                                 iswide = false;
676                         }
677                         OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
678                         break;
679
680                 case JAVA_ILOAD_0:
681                 case JAVA_ILOAD_1:
682                 case JAVA_ILOAD_2:
683                 case JAVA_ILOAD_3:
684                         OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
685                         break;
686
687                 case JAVA_LLOAD_0:
688                 case JAVA_LLOAD_1:
689                 case JAVA_LLOAD_2:
690                 case JAVA_LLOAD_3:
691                         OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
692                         break;
693
694                 case JAVA_FLOAD_0:
695                 case JAVA_FLOAD_1:
696                 case JAVA_FLOAD_2:
697                 case JAVA_FLOAD_3:
698                         OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
699                         break;
700
701                 case JAVA_DLOAD_0:
702                 case JAVA_DLOAD_1:
703                 case JAVA_DLOAD_2:
704                 case JAVA_DLOAD_3:
705                         OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
706                         break;
707
708                 case JAVA_ALOAD_0:
709                 case JAVA_ALOAD_1:
710                 case JAVA_ALOAD_2:
711                 case JAVA_ALOAD_3:
712                         OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
713                         break;
714
715                 case JAVA_ISTORE:
716                 case JAVA_FSTORE:
717                 case JAVA_ASTORE:
718                         if (iswide == false) {
719                                 i = SUCK_BE_U1(m->jcode + p + 1);
720                         }
721                         else {
722                                 i = SUCK_BE_U2(m->jcode + p + 1);
723                                 iswide = false;
724                                 nextp = p + 3;
725                         }
726                         OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
727                         break;
728
729                 case JAVA_LSTORE:
730                 case JAVA_DSTORE:
731                         if (iswide == false) {
732                                 i = SUCK_BE_U1(m->jcode + p + 1);
733                         }
734                         else {
735                                 i = SUCK_BE_U2(m->jcode + p + 1);
736                                 iswide = false;
737                                 nextp = p + 3;
738                         }
739                         OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
740                         break;
741
742                 case JAVA_ISTORE_0:
743                 case JAVA_ISTORE_1:
744                 case JAVA_ISTORE_2:
745                 case JAVA_ISTORE_3:
746                         OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
747                         break;
748
749                 case JAVA_LSTORE_0:
750                 case JAVA_LSTORE_1:
751                 case JAVA_LSTORE_2:
752                 case JAVA_LSTORE_3:
753                         OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
754                         break;
755
756                 case JAVA_FSTORE_0:
757                 case JAVA_FSTORE_1:
758                 case JAVA_FSTORE_2:
759                 case JAVA_FSTORE_3:
760                         OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
761                         break;
762
763                 case JAVA_DSTORE_0:
764                 case JAVA_DSTORE_1:
765                 case JAVA_DSTORE_2:
766                 case JAVA_DSTORE_3:
767                         OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
768                         break;
769
770                 case JAVA_ASTORE_0:
771                 case JAVA_ASTORE_1:
772                 case JAVA_ASTORE_2:
773                 case JAVA_ASTORE_3:
774                         OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
775                         break;
776
777                 case JAVA_IINC:
778                         {
779                                 int v;
780
781                                 if (iswide == false) {
782                                         i = SUCK_BE_U1(m->jcode + p + 1);
783                                         v = SUCK_BE_S1(m->jcode + p + 2);
784
785                                 }
786                                 else {
787                                         i = SUCK_BE_U2(m->jcode + p + 1);
788                                         v = SUCK_BE_S2(m->jcode + p + 3);
789                                         iswide = false;
790                                         nextp = p + 5;
791                                 }
792                                 INDEX_ONEWORD(i);
793                                 LOCALTYPE_USED(i, TYPE_INT);
794                                 OP_LOCALINDEX_I(opcode, i, v);
795                         }
796                         break;
797
798                 /* wider index for loading, storing and incrementing ******************/
799
800                 case JAVA_WIDE:
801                         iswide = true;
802                         p++;
803                         goto fetch_opcode;
804
805                 /* managing arrays ****************************************************/
806
807                 case JAVA_NEWARRAY:
808                         switch (SUCK_BE_S1(m->jcode + p + 1)) {
809                         case 4:
810                                 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
811                                 break;
812                         case 5:
813                                 bte = builtintable_get_internal(BUILTIN_newarray_char);
814                                 break;
815                         case 6:
816                                 bte = builtintable_get_internal(BUILTIN_newarray_float);
817                                 break;
818                         case 7:
819                                 bte = builtintable_get_internal(BUILTIN_newarray_double);
820                                 break;
821                         case 8:
822                                 bte = builtintable_get_internal(BUILTIN_newarray_byte);
823                                 break;
824                         case 9:
825                                 bte = builtintable_get_internal(BUILTIN_newarray_short);
826                                 break;
827                         case 10:
828                                 bte = builtintable_get_internal(BUILTIN_newarray_int);
829                                 break;
830                         case 11:
831                                 bte = builtintable_get_internal(BUILTIN_newarray_long);
832                                 break;
833 #if defined(ENABLE_VERIFIER)
834                         default:
835                                 exceptions_throw_verifyerror(m, "Invalid array-type to create");
836                                 return false;
837 #endif
838                         }
839                         OP_BUILTIN_CHECK_EXCEPTION(bte);
840                         break;
841
842                 case JAVA_ANEWARRAY:
843                         i = SUCK_BE_U2(m->jcode + p + 1);
844                         compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
845                         if (!compr)
846                                 return false;
847
848                         if (!(cr = class_get_classref_multiarray_of(1, compr)))
849                                 return false;
850
851                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
852                                 return false;
853
854                         INSTRUCTIONS_CHECK(2);
855                         OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
856                         bte = builtintable_get_internal(BUILTIN_newarray);
857                         OP_BUILTIN_CHECK_EXCEPTION(bte);
858                         s_count++;
859                         break;
860
861                 case JAVA_MULTIANEWARRAY:
862                         jd->isleafmethod = false;
863                         i = SUCK_BE_U2(m->jcode + p + 1);
864                         j = SUCK_BE_U1(m->jcode + p + 3);
865   
866                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
867                         if (cr == NULL)
868                                 return false;
869   
870                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
871                                 return false;
872   
873                         /* if unresolved, c == NULL */
874   
875                         iptr->s1.argcount = j;
876                         OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
877                         break;
878
879                 /* control flow instructions ******************************************/
880
881                 case JAVA_IFEQ:
882                 case JAVA_IFLT:
883                 case JAVA_IFLE:
884                 case JAVA_IFNE:
885                 case JAVA_IFGT:
886                 case JAVA_IFGE:
887                 case JAVA_IFNULL:
888                 case JAVA_IFNONNULL:
889                 case JAVA_IF_ICMPEQ:
890                 case JAVA_IF_ICMPNE:
891                 case JAVA_IF_ICMPLT:
892                 case JAVA_IF_ICMPGT:
893                 case JAVA_IF_ICMPLE:
894                 case JAVA_IF_ICMPGE:
895                 case JAVA_IF_ACMPEQ:
896                 case JAVA_IF_ACMPNE:
897                 case JAVA_GOTO:
898                         i = p + SUCK_BE_S2(m->jcode + p + 1);
899                         CHECK_BYTECODE_INDEX(i);
900                         MARK_BASICBLOCK(i);
901                         blockend = true;
902                         OP_INSINDEX(opcode, i);
903                         break;
904
905                 case JAVA_GOTO_W:
906                         i = p + SUCK_BE_S4(m->jcode + p + 1);
907                         CHECK_BYTECODE_INDEX(i);
908                         MARK_BASICBLOCK(i);
909                         blockend = true;
910                         OP_INSINDEX(opcode, i);
911                         break;
912
913                 case JAVA_JSR:
914                         i = p + SUCK_BE_S2(m->jcode + p + 1);
915 jsr_tail:
916                         CHECK_BYTECODE_INDEX(i);
917                         MARK_BASICBLOCK(i);
918                         blockend = true;
919                         OP_PREPARE_ZEROFLAGS(JAVA_JSR);
920                         iptr->sx.s23.s3.jsrtarget.insindex = i;
921                         PINC;
922                         break;
923
924                 case JAVA_JSR_W:
925                         i = p + SUCK_BE_S4(m->jcode + p + 1);
926                         goto jsr_tail;
927
928                 case JAVA_RET:
929                         if (iswide == false) {
930                                 i = SUCK_BE_U1(m->jcode + p + 1);
931                         }
932                         else {
933                                 i = SUCK_BE_U2(m->jcode + p + 1);
934                                 nextp = p + 3;
935                                 iswide = false;
936                         }
937                         blockend = true;
938
939                         OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
940                         break;
941
942                 case JAVA_IRETURN:
943                 case JAVA_LRETURN:
944                 case JAVA_FRETURN:
945                 case JAVA_DRETURN:
946                 case JAVA_ARETURN:
947                 case JAVA_RETURN:
948                         blockend = true;
949                         /* XXX ARETURN will need a flag in the typechecker */
950                         OP(opcode);
951                         break;
952
953                 case JAVA_ATHROW:
954                         blockend = true;
955                         /* XXX ATHROW will need a flag in the typechecker */
956                         OP(opcode);
957                         break;
958
959
960                 /* table jumps ********************************************************/
961
962                 case JAVA_LOOKUPSWITCH:
963                         {
964                                 s4 num, j;
965                                 lookup_target_t *lookup;
966 #if defined(ENABLE_VERIFIER)
967                                 s4 prevvalue = 0;
968 #endif
969                                 blockend = true;
970                                 nextp = ALIGN((p + 1), 4);
971
972                                 CHECK_END_OF_BYTECODE(nextp + 8);
973
974                                 OP_PREPARE_ZEROFLAGS(opcode);
975
976                                 /* default target */
977
978                                 j = p + SUCK_BE_S4(m->jcode + nextp);
979                                 iptr->sx.s23.s3.lookupdefault.insindex = j;
980                                 nextp += 4;
981                                 CHECK_BYTECODE_INDEX(j);
982                                 MARK_BASICBLOCK(j);
983
984                                 /* number of pairs */
985
986                                 num = SUCK_BE_U4(m->jcode + nextp);
987                                 iptr->sx.s23.s2.lookupcount = num;
988                                 nextp += 4;
989
990                                 /* allocate the intermediate code table */
991
992                                 lookup = DMNEW(lookup_target_t, num);
993                                 iptr->dst.lookup = lookup;
994
995                                 /* iterate over the lookup table */
996
997                                 CHECK_END_OF_BYTECODE(nextp + 8 * num);
998
999                                 for (i = 0; i < num; i++) {
1000                                         /* value */
1001
1002                                         j = SUCK_BE_S4(m->jcode + nextp);
1003                                         lookup->value = j;
1004
1005                                         nextp += 4;
1006
1007 #if defined(ENABLE_VERIFIER)
1008                                         /* check if the lookup table is sorted correctly */
1009
1010                                         if (i && (j <= prevvalue)) {
1011                                                 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1012                                                 return false;
1013                                         }
1014                                         prevvalue = j;
1015 #endif
1016                                         /* target */
1017
1018                                         j = p + SUCK_BE_S4(m->jcode + nextp);
1019                                         lookup->target.insindex = j;
1020                                         lookup++;
1021                                         nextp += 4;
1022                                         CHECK_BYTECODE_INDEX(j);
1023                                         MARK_BASICBLOCK(j);
1024                                 }
1025
1026                                 PINC;
1027                                 break;
1028                         }
1029
1030
1031                 case JAVA_TABLESWITCH:
1032                         {
1033                                 s4 num, j;
1034                                 s4 deftarget;
1035                                 branch_target_t *table;
1036
1037                                 blockend = true;
1038                                 nextp = ALIGN((p + 1), 4);
1039
1040                                 CHECK_END_OF_BYTECODE(nextp + 12);
1041
1042                                 OP_PREPARE_ZEROFLAGS(opcode);
1043
1044                                 /* default target */
1045
1046                                 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
1047                                 nextp += 4;
1048                                 CHECK_BYTECODE_INDEX(deftarget);
1049                                 MARK_BASICBLOCK(deftarget);
1050
1051                                 /* lower bound */
1052
1053                                 j = SUCK_BE_S4(m->jcode + nextp);
1054                                 iptr->sx.s23.s2.tablelow = j;
1055                                 nextp += 4;
1056
1057                                 /* upper bound */
1058
1059                                 num = SUCK_BE_S4(m->jcode + nextp);
1060                                 iptr->sx.s23.s3.tablehigh = num;
1061                                 nextp += 4;
1062
1063                                 /* calculate the number of table entries */
1064
1065                                 num = num - j + 1;
1066
1067 #if defined(ENABLE_VERIFIER)
1068                                 if (num < 1) {
1069                                         exceptions_throw_verifyerror(m,
1070                                                         "invalid TABLESWITCH: upper bound < lower bound");
1071                                         return false;
1072                                 }
1073 #endif
1074                                 /* create the intermediate code table */
1075                                 /* the first entry is the default target */
1076
1077                                 table = MNEW(branch_target_t, 1 + num);
1078                                 iptr->dst.table = table;
1079                                 (table++)->insindex = deftarget;
1080
1081                                 /* iterate over the target table */
1082
1083                                 CHECK_END_OF_BYTECODE(nextp + 4 * num);
1084
1085                                 for (i = 0; i < num; i++) {
1086                                         j = p + SUCK_BE_S4(m->jcode + nextp);
1087                                         (table++)->insindex = j;
1088                                         nextp += 4;
1089                                         CHECK_BYTECODE_INDEX(j);
1090                                         MARK_BASICBLOCK(j);
1091                                 }
1092
1093                                 PINC;
1094                                 break;
1095                         }
1096
1097
1098                 /* load and store of object fields ************************************/
1099
1100                 case JAVA_AASTORE:
1101                         OP(opcode);
1102                         jd->isleafmethod = false;
1103                         break;
1104
1105                 case JAVA_GETSTATIC:
1106                 case JAVA_PUTSTATIC:
1107                 case JAVA_GETFIELD:
1108                 case JAVA_PUTFIELD:
1109                         {
1110                                 constant_FMIref  *fr;
1111                                 unresolved_field *uf;
1112
1113                                 i = SUCK_BE_U2(m->jcode + p + 1);
1114                                 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1115                                 if (!fr)
1116                                         return false;
1117
1118                                 OP_PREPARE_ZEROFLAGS(opcode);
1119                                 iptr->sx.s23.s3.fmiref = fr;
1120
1121                                 /* only with -noverify, otherwise the typechecker does this */
1122
1123 #if defined(ENABLE_VERIFIER)
1124                                 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1125 #endif
1126                                         result = resolve_field_lazy(m, fr);
1127                                         if (result == resolveFailed)
1128                                                 return false;
1129
1130                                         if (result != resolveSucceeded) {
1131                                                 uf = resolve_create_unresolved_field(m->class, m, iptr);
1132
1133                                                 if (uf == NULL)
1134                                                         return false;
1135
1136                                                 /* store the unresolved_field pointer */
1137
1138                                                 iptr->sx.s23.s3.uf = uf;
1139                                                 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1140                                         }
1141 #if defined(ENABLE_VERIFIER)
1142                                 }
1143 #endif
1144                                 PINC;
1145                         }
1146                         break;
1147
1148
1149                 /* method invocation **************************************************/
1150
1151                 case JAVA_INVOKESTATIC:
1152                         i = SUCK_BE_U2(m->jcode + p + 1);
1153                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1154
1155                         if (mr == NULL)
1156                                 return false;
1157
1158                         md = mr->parseddesc.md;
1159
1160                         if (md->params == NULL)
1161                                 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1162                                         return false;
1163
1164                         goto invoke_method;
1165
1166                 case JAVA_INVOKEINTERFACE:
1167                         i = SUCK_BE_U2(m->jcode + p + 1);
1168
1169                         mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1170
1171                         goto invoke_nonstatic_method;
1172
1173                 case JAVA_INVOKESPECIAL:
1174                 case JAVA_INVOKEVIRTUAL:
1175                         i = SUCK_BE_U2(m->jcode + p + 1);
1176                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1177
1178 invoke_nonstatic_method:
1179                         if (mr == NULL)
1180                                 return false;
1181
1182                         md = mr->parseddesc.md;
1183
1184                         if (md->params == NULL)
1185                                 if (!descriptor_params_from_paramtypes(md, 0))
1186                                         return false;
1187
1188 invoke_method:
1189                         jd->isleafmethod = false;
1190
1191                         OP_PREPARE_ZEROFLAGS(opcode);
1192                         iptr->sx.s23.s3.fmiref = mr;
1193
1194                         /* only with -noverify, otherwise the typechecker does this */
1195
1196 #if defined(ENABLE_VERIFIER)
1197                         if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1198 #endif
1199                                 result = resolve_method_lazy(m, mr, 
1200                                                 (opcode == JAVA_INVOKESPECIAL));
1201                                 if (result == resolveFailed)
1202                                         return false;
1203
1204                                 if (result == resolveSucceeded) {
1205                                         methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1206
1207                                         /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1208
1209                                         assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1210
1211                                         if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1212                                                 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1213                                         {
1214                                                 iptr->opc = ICMD_INVOKESPECIAL;
1215                                         }
1216                                 }
1217                                 else {
1218                                         um = resolve_create_unresolved_method(m->class, m, mr,
1219                                                         (opcode == JAVA_INVOKESTATIC),
1220                                                         (opcode == JAVA_INVOKESPECIAL));
1221
1222                                         if (!um)
1223                                                 return false;
1224
1225                                         /* store the unresolved_method pointer */
1226
1227                                         iptr->sx.s23.s3.um = um;
1228                                         iptr->flags.bits = INS_FLAG_UNRESOLVED;
1229                                 }
1230 #if defined(ENABLE_VERIFIER)
1231                         }
1232 #endif
1233                         PINC;
1234                         break;
1235
1236                 /* instructions taking class arguments ********************************/
1237
1238                 case JAVA_NEW:
1239                         i = SUCK_BE_U2(m->jcode + p + 1);
1240                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1241                         if (!cr)
1242                                 return false;
1243
1244                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1245                                 return false;
1246
1247                         INSTRUCTIONS_CHECK(2);
1248                         OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1249                         bte = builtintable_get_internal(BUILTIN_new);
1250                         OP_BUILTIN_CHECK_EXCEPTION(bte);
1251                         s_count++;
1252                         break;
1253
1254                 case JAVA_CHECKCAST:
1255                         i = SUCK_BE_U2(m->jcode + p + 1);
1256                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1257                         if (cr == NULL)
1258                                 return false;
1259
1260                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1261                                 return false;
1262
1263                         if (cr->name->text[0] == '[') {
1264                                 /* array type cast-check */
1265                                 flags = INS_FLAG_ARRAY;
1266                                 jd->isleafmethod = false;
1267                         }
1268                         else {
1269                                 /* object type cast-check */
1270                                 flags = 0;
1271                         }
1272                         OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1273                         break;
1274
1275                 case JAVA_INSTANCEOF:
1276                         i = SUCK_BE_U2(m->jcode + p + 1);
1277                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1278                         if (cr == NULL)
1279                                 return false;
1280
1281                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1282                                 return false;
1283
1284                         if (cr->name->text[0] == '[') {
1285                                 /* array type cast-check */
1286                                 INSTRUCTIONS_CHECK(2);
1287                                 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1288                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1289                                 OP_BUILTIN_NO_EXCEPTION(bte);
1290                                 s_count++;
1291                         }
1292                         else {
1293                                 /* object type cast-check */
1294                                 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1295                         }
1296                         break;
1297
1298                 /* synchronization instructions ***************************************/
1299
1300                 case JAVA_MONITORENTER:
1301 #if defined(ENABLE_THREADS)
1302                         if (checksync) {
1303                                 bte = builtintable_get_internal(LOCK_monitor_enter);
1304                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1305                         }
1306                         else
1307 #endif
1308                         {
1309                                 OP(ICMD_CHECKNULL_POP);
1310                         }
1311                         break;
1312
1313                 case JAVA_MONITOREXIT:
1314 #if defined(ENABLE_THREADS)
1315                         if (checksync) {
1316                                 bte = builtintable_get_internal(LOCK_monitor_exit);
1317                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1318                         }
1319                         else
1320 #endif
1321                         {
1322                                 OP(ICMD_CHECKNULL_POP);
1323                         }
1324                         break;
1325
1326                 /* arithmetic instructions that may become builtin functions **********/
1327
1328                 case JAVA_IDIV:
1329 #if !SUPPORT_DIVISION
1330                         bte = builtintable_get_internal(BUILTIN_idiv);
1331                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1332 #else
1333                         OP(opcode);
1334 #endif
1335                         break;
1336
1337                 case JAVA_IREM:
1338 #if !SUPPORT_DIVISION
1339                         bte = builtintable_get_internal(BUILTIN_irem);
1340                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1341 #else
1342                         OP(opcode);
1343 #endif
1344                         break;
1345
1346                 case JAVA_LDIV:
1347 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1348                         bte = builtintable_get_internal(BUILTIN_ldiv);
1349                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1350 #else
1351                         OP(opcode);
1352 #endif
1353                         break;
1354
1355                 case JAVA_LREM:
1356 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1357                         bte = builtintable_get_internal(BUILTIN_lrem);
1358                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1359 #else
1360                         OP(opcode);
1361 #endif
1362                         break;
1363
1364                 case JAVA_FREM:
1365 #if defined(__I386__)
1366                         OP(opcode);
1367 #else
1368                         bte = builtintable_get_internal(BUILTIN_frem);
1369                         OP_BUILTIN_NO_EXCEPTION(bte);
1370 #endif
1371                         break;
1372
1373                 case JAVA_DREM:
1374 #if defined(__I386__)
1375                         OP(opcode);
1376 #else
1377                         bte = builtintable_get_internal(BUILTIN_drem);
1378                         OP_BUILTIN_NO_EXCEPTION(bte);
1379 #endif
1380                         break;
1381
1382                 case JAVA_F2I:
1383 #if defined(__ALPHA__)
1384                         if (!opt_noieee) {
1385                                 bte = builtintable_get_internal(BUILTIN_f2i);
1386                                 OP_BUILTIN_NO_EXCEPTION(bte);
1387                         }
1388                         else
1389 #endif
1390                         {
1391                                 OP(opcode);
1392                         }
1393                         break;
1394
1395                 case JAVA_F2L:
1396 #if defined(__ALPHA__)
1397                         if (!opt_noieee) {
1398                                 bte = builtintable_get_internal(BUILTIN_f2l);
1399                                 OP_BUILTIN_NO_EXCEPTION(bte);
1400                         }
1401                         else
1402 #endif
1403                         {
1404                                 OP(opcode);
1405                         }
1406                         break;
1407
1408                 case JAVA_D2I:
1409 #if defined(__ALPHA__)
1410                         if (!opt_noieee) {
1411                                 bte = builtintable_get_internal(BUILTIN_d2i);
1412                                 OP_BUILTIN_NO_EXCEPTION(bte);
1413                         }
1414                         else
1415 #endif
1416                         {
1417                                 OP(opcode);
1418                         }
1419                         break;
1420
1421                 case JAVA_D2L:
1422 #if defined(__ALPHA__)
1423                         if (!opt_noieee) {
1424                                 bte = builtintable_get_internal(BUILTIN_d2l);
1425                                 OP_BUILTIN_NO_EXCEPTION(bte);
1426                         }
1427                         else
1428 #endif
1429                         {
1430                                 OP(opcode);
1431                         }
1432                         break;
1433
1434                 /* invalid opcodes ****************************************************/
1435
1436                         /* check for invalid opcodes if the verifier is enabled */
1437 #if defined(ENABLE_VERIFIER)
1438                 case JAVA_BREAKPOINT:
1439                         exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1440                         return false;
1441
1442                 case 186: /* unused opcode */
1443                 case 203:
1444                 case 204:
1445                 case 205:
1446                 case 206:
1447                 case 207:
1448                 case 208:
1449                 case 209:
1450                 case 210:
1451                 case 211:
1452                 case 212:
1453                 case 213:
1454                 case 214:
1455                 case 215:
1456                 case 216:
1457                 case 217:
1458                 case 218:
1459                 case 219:
1460                 case 220:
1461                 case 221:
1462                 case 222:
1463                 case 223:
1464                 case 224:
1465                 case 225:
1466                 case 226:
1467                 case 227:
1468                 case 228:
1469                 case 229:
1470                 case 230:
1471                 case 231:
1472                 case 232:
1473                 case 233:
1474                 case 234:
1475                 case 235:
1476                 case 236:
1477                 case 237:
1478                 case 238:
1479                 case 239:
1480                 case 240:
1481                 case 241:
1482                 case 242:
1483                 case 243:
1484                 case 244:
1485                 case 245:
1486                 case 246:
1487                 case 247:
1488                 case 248:
1489                 case 249:
1490                 case 250:
1491                 case 251:
1492                 case 252:
1493                 case 253:
1494                 case 254:
1495                 case 255:
1496                         exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1497                                                                                  opcode, ipc);
1498                         return false;
1499                         break;
1500 #endif /* defined(ENABLE_VERIFIER) */
1501
1502                 /* opcodes that don't require translation *****************************/
1503
1504                 default:
1505                         /* straight-forward translation to ICMD */
1506                         OP(opcode);
1507                         break;
1508
1509                 } /* end switch */
1510
1511                 /* verifier checks ****************************************************/
1512
1513 #if defined(ENABLE_VERIFIER)
1514                 /* If WIDE was used correctly, iswide should have been reset by now. */
1515                 if (iswide) {
1516                         exceptions_throw_verifyerror(m,
1517                                         "Illegal instruction: WIDE before incompatible opcode");
1518                         return false;
1519                 }
1520 #endif /* defined(ENABLE_VERIFIER) */
1521
1522         } /* end for */
1523
1524         if (JITDATA_HAS_FLAG_REORDER(jd)) {
1525                 /* add a NOP to the last basic block */
1526
1527                 INSTRUCTIONS_CHECK(1);
1528                 OP(ICMD_NOP);
1529         }
1530
1531         /*** END OF LOOP **********************************************************/
1532
1533         /* assert that we did not write more ICMDs than allocated */
1534
1535         assert(ipc <= pd.instructionslength);
1536         assert(ipc == (iptr - pd.instructions));
1537
1538         /*** verifier checks ******************************************************/
1539
1540 #if defined(ENABLE_VERIFIER)
1541         if (p != m->jcodelength) {
1542                 exceptions_throw_verifyerror(m,
1543                                 "Command-sequence crosses code-boundary");
1544                 return false;
1545         }
1546
1547         if (!blockend) {
1548                 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1549                 return false;
1550         }
1551 #endif /* defined(ENABLE_VERIFIER) */
1552
1553         /*** setup the methodinfo, allocate stack and basic blocks ****************/
1554
1555         /* adjust block count if target 0 is not first intermediate instruction */
1556
1557         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1558                 b_count++;
1559
1560         /* copy local to method variables */
1561
1562         jd->instructions = pd.instructions;
1563         jd->instructioncount = ipc;
1564         jd->basicblockcount = b_count;
1565         jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
1566
1567         /* allocate stack table */
1568
1569         jd->stack = DMNEW(stackelement, jd->stackcount);
1570
1571         /* build basic block list */
1572
1573         bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1574
1575         /* zero out all basic block structures */
1576
1577         MZERO(bptr, basicblock, b_count + 1);
1578
1579         b_count = 0;
1580
1581         /* additional block if target 0 is not first intermediate instruction */
1582
1583         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1584                 BASICBLOCK_INIT(bptr, m);
1585
1586                 bptr->iinstr = jd->instructions;
1587                 /* bptr->icount is set when the next block is allocated */
1588
1589                 bptr->nr = b_count++;
1590                 bptr++;
1591                 bptr[-1].next = bptr;
1592         }
1593
1594         /* allocate blocks */
1595
1596         for (p = 0; p < m->jcodelength; p++) {
1597                 if (jd->basicblockindex[p] & 1) {
1598 #if defined(ENABLE_VERIFIER)
1599                         /* Check if this block starts at the beginning of an
1600                            instruction. */
1601
1602                         if (!pd.instructionstart[p]) {
1603                                 exceptions_throw_verifyerror(m,
1604                                                 "Branch into middle of instruction");
1605                                 return false;
1606                         }
1607 #endif
1608
1609                         /* allocate the block */
1610
1611                         BASICBLOCK_INIT(bptr, m);
1612
1613                         bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
1614                         if (b_count) {
1615                                 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1616                         }
1617                         /* bptr->icount is set when the next block is allocated */
1618
1619                         jd->basicblockindex[p] = b_count;
1620
1621                         bptr->nr = b_count++;
1622                         bptr++;
1623                         bptr[-1].next = bptr;
1624                 }
1625         }
1626
1627         /* set instruction count of last real block */
1628
1629         if (b_count) {
1630                 bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
1631         }
1632
1633         /* allocate additional block at end */
1634
1635         BASICBLOCK_INIT(bptr,m);
1636         bptr->nr = b_count;
1637         jd->basicblockindex[m->jcodelength] = b_count;
1638
1639         /* set basicblock pointers in exception table */
1640
1641         if (!parse_resolve_exception_table(jd))
1642                 return false;
1643
1644         /* store the local map */
1645
1646         jd->local_map = local_map;
1647
1648         /* calculate local variable renaming */
1649
1650         {
1651                 s4 nlocals = 0;
1652                 s4 i;
1653
1654                 s4 *mapptr;
1655
1656                 mapptr = local_map;
1657
1658                 /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
1659                 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1660                 /* -> == new local var index */
1661                 for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
1662                         if (*mapptr)
1663                                 *mapptr = nlocals++;
1664                         else
1665                                 *mapptr = UNUSED;
1666                 }
1667
1668                 jd->localcount = nlocals;
1669
1670                 /* calculate the (maximum) number of variables needed */
1671
1672                 jd->varcount = 
1673                           nlocals                                      /* local variables */
1674                         + jd->basicblockcount * m->maxstack                 /* invars */
1675                         + s_count;         /* variables created within blocks (non-invar) */
1676
1677                 /* reserve the first indices for local variables */
1678
1679                 jd->vartop = nlocals;
1680
1681                 /* reserve extra variables needed by stack analyse */
1682
1683                 jd->varcount += STACK_EXTRA_VARS;
1684                 jd->vartop   += STACK_EXTRA_VARS;
1685
1686                 /* The verifier needs space for saving invars in some cases and */
1687                 /* extra variables.                                             */
1688
1689 #if defined(ENABLE_VERIFIER)
1690                 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1691                         jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1692                         jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1693                 }
1694 #endif
1695                 /* allocate and initialize the variable array */
1696
1697                 jd->var = DMNEW(varinfo, jd->varcount);
1698                 MZERO(jd->var, varinfo, jd->varcount);
1699
1700                 /* set types of all locals in jd->var */
1701
1702                 for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
1703                         if (*mapptr != UNUSED)
1704                                 VAR(*mapptr)->type = i%5;
1705         }
1706
1707         /* everything's ok */
1708
1709         return true;
1710
1711         /*** goto labels for throwing verifier exceptions *************************/
1712
1713 #if defined(ENABLE_VERIFIER)
1714
1715 throw_unexpected_end_of_bytecode:
1716         exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1717         return false;
1718
1719 throw_invalid_bytecode_index:
1720         exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1721         return false;
1722
1723 throw_illegal_local_variable_number:
1724         exceptions_throw_verifyerror(m, "Illegal local variable number");
1725         return false;
1726
1727 #endif /* ENABLE_VERIFIER */
1728 }
1729
1730
1731 /*
1732  * These are local overrides for various environment variables in Emacs.
1733  * Please do not remove this and leave it at the end of the file, where
1734  * Emacs will automagically detect them.
1735  * ---------------------------------------------------------------------
1736  * Local variables:
1737  * mode: c
1738  * indent-tabs-mode: t
1739  * c-basic-offset: 4
1740  * tab-width: 4
1741  * End:
1742  * vim:noexpandtab:sw=4:ts=4:
1743  */