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