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