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