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