* src/vm/jit/parse.c (parse_realloc_instructions): Renamed ipc to
[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 7619 2007-03-30 11:41:27Z 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 icount, 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, icount,
141                                                                  pd->instructionslength);
142         MZERO(pd->instructions + icount, instruction,
143                   (pd->instructionslength - icount));
144
145         /* return the iptr */
146
147         return pd->instructions + icount;
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           icount;                /* 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         icount = 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] |= (icount << 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                         OP_PREPARE_ZEROFLAGS(opcode);
1144
1145                         i = SUCK_BE_U2(m->jcode + p + 1);
1146                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1147
1148                         if (mr == NULL)
1149                                 return false;
1150
1151                         md = mr->parseddesc.md;
1152
1153                         if (md->params == NULL)
1154                                 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1155                                         return false;
1156
1157                         goto invoke_method;
1158
1159                 case JAVA_INVOKESPECIAL:
1160                         OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1161
1162                         i = SUCK_BE_U2(m->jcode + p + 1);
1163                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1164
1165                         goto invoke_nonstatic_method;
1166
1167                 case JAVA_INVOKEINTERFACE:
1168                         OP_PREPARE_ZEROFLAGS(opcode);
1169
1170                         i = SUCK_BE_U2(m->jcode + p + 1);
1171                         mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1172
1173                         goto invoke_nonstatic_method;
1174
1175                 case JAVA_INVOKEVIRTUAL:
1176                         OP_PREPARE_ZEROFLAGS(opcode);
1177
1178                         i = SUCK_BE_U2(m->jcode + p + 1);
1179                         mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1180
1181 invoke_nonstatic_method:
1182                         if (mr == NULL)
1183                                 return false;
1184
1185                         md = mr->parseddesc.md;
1186
1187                         if (md->params == NULL)
1188                                 if (!descriptor_params_from_paramtypes(md, 0))
1189                                         return false;
1190
1191 invoke_method:
1192                         jd->isleafmethod = false;
1193
1194                         iptr->sx.s23.s3.fmiref = mr;
1195
1196                         /* only with -noverify, otherwise the typechecker does this */
1197
1198 #if defined(ENABLE_VERIFIER)
1199                         if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1200 #endif
1201                                 result = resolve_method_lazy(m, mr, 
1202                                                 (opcode == JAVA_INVOKESPECIAL));
1203                                 if (result == resolveFailed)
1204                                         return false;
1205
1206                                 if (result == resolveSucceeded) {
1207                                         methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1208
1209                                         /* if this call is monomorphic, turn it into an
1210                                            INVOKESPECIAL */
1211
1212                                         assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1213
1214                                         if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1215                                                 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1216                                         {
1217                                                 iptr->opc         = ICMD_INVOKESPECIAL;
1218                                                 iptr->flags.bits |= INS_FLAG_CHECK;
1219                                         }
1220                                 }
1221                                 else {
1222                                         um = resolve_create_unresolved_method(m->class, m, mr,
1223                                                         (opcode == JAVA_INVOKESTATIC),
1224                                                         (opcode == JAVA_INVOKESPECIAL));
1225
1226                                         if (!um)
1227                                                 return false;
1228
1229                                         /* store the unresolved_method pointer */
1230
1231                                         iptr->sx.s23.s3.um = um;
1232                                         iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1233                                 }
1234 #if defined(ENABLE_VERIFIER)
1235                         }
1236 #endif
1237                         PINC;
1238                         break;
1239
1240                 /* instructions taking class arguments ********************************/
1241
1242                 case JAVA_NEW:
1243                         i = SUCK_BE_U2(m->jcode + p + 1);
1244                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1245                         if (!cr)
1246                                 return false;
1247
1248                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1249                                 return false;
1250
1251                         INSTRUCTIONS_CHECK(2);
1252                         OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1253                         bte = builtintable_get_internal(BUILTIN_new);
1254                         OP_BUILTIN_CHECK_EXCEPTION(bte);
1255                         s_count++;
1256                         break;
1257
1258                 case JAVA_CHECKCAST:
1259                         i = SUCK_BE_U2(m->jcode + p + 1);
1260                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1261                         if (cr == NULL)
1262                                 return false;
1263
1264                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1265                                 return false;
1266
1267                         if (cr->name->text[0] == '[') {
1268                                 /* array type cast-check */
1269                                 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1270                                 jd->isleafmethod = false;
1271                         }
1272                         else {
1273                                 /* object type cast-check */
1274                                 flags = INS_FLAG_CHECK;
1275                         }
1276                         OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1277                         break;
1278
1279                 case JAVA_INSTANCEOF:
1280                         i = SUCK_BE_U2(m->jcode + p + 1);
1281                         cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1282                         if (cr == NULL)
1283                                 return false;
1284
1285                         if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1286                                 return false;
1287
1288                         if (cr->name->text[0] == '[') {
1289                                 /* array type cast-check */
1290                                 INSTRUCTIONS_CHECK(2);
1291                                 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1292                                 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1293                                 OP_BUILTIN_NO_EXCEPTION(bte);
1294                                 s_count++;
1295                         }
1296                         else {
1297                                 /* object type cast-check */
1298                                 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1299                         }
1300                         break;
1301
1302                 /* synchronization instructions ***************************************/
1303
1304                 case JAVA_MONITORENTER:
1305 #if defined(ENABLE_THREADS)
1306                         if (checksync) {
1307                                 bte = builtintable_get_internal(LOCK_monitor_enter);
1308                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1309                         }
1310                         else
1311 #endif
1312                         {
1313                                 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1314                                 OP(ICMD_POP);
1315                         }
1316                         break;
1317
1318                 case JAVA_MONITOREXIT:
1319 #if defined(ENABLE_THREADS)
1320                         if (checksync) {
1321                                 bte = builtintable_get_internal(LOCK_monitor_exit);
1322                                 OP_BUILTIN_CHECK_EXCEPTION(bte);
1323                         }
1324                         else
1325 #endif
1326                         {
1327                                 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1328                                 OP(ICMD_POP);
1329                         }
1330                         break;
1331
1332                 /* arithmetic instructions that may become builtin functions **********/
1333
1334                 case JAVA_IDIV:
1335 #if !SUPPORT_DIVISION
1336                         bte = builtintable_get_internal(BUILTIN_idiv);
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_IREM:
1348 #if !SUPPORT_DIVISION
1349                         bte = builtintable_get_internal(BUILTIN_irem);
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_LDIV:
1361 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1362                         bte = builtintable_get_internal(BUILTIN_ldiv);
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_LREM:
1374 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1375                         bte = builtintable_get_internal(BUILTIN_lrem);
1376                         OP_BUILTIN_ARITHMETIC(opcode, bte);
1377 #else
1378 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1379                         OP(opcode);
1380 # else
1381                         OP_CHECK_EXCEPTION(opcode);
1382 # endif
1383 #endif
1384                         break;
1385
1386                 case JAVA_FREM:
1387 #if defined(__I386__)
1388                         OP(opcode);
1389 #else
1390                         bte = builtintable_get_internal(BUILTIN_frem);
1391                         OP_BUILTIN_NO_EXCEPTION(bte);
1392 #endif
1393                         break;
1394
1395                 case JAVA_DREM:
1396 #if defined(__I386__)
1397                         OP(opcode);
1398 #else
1399                         bte = builtintable_get_internal(BUILTIN_drem);
1400                         OP_BUILTIN_NO_EXCEPTION(bte);
1401 #endif
1402                         break;
1403
1404                 case JAVA_F2I:
1405 #if defined(__ALPHA__)
1406                         if (!opt_noieee) {
1407                                 bte = builtintable_get_internal(BUILTIN_f2i);
1408                                 OP_BUILTIN_NO_EXCEPTION(bte);
1409                         }
1410                         else
1411 #endif
1412                         {
1413                                 OP(opcode);
1414                         }
1415                         break;
1416
1417                 case JAVA_F2L:
1418 #if defined(__ALPHA__)
1419                         if (!opt_noieee) {
1420                                 bte = builtintable_get_internal(BUILTIN_f2l);
1421                                 OP_BUILTIN_NO_EXCEPTION(bte);
1422                         }
1423                         else
1424 #endif
1425                         {
1426                                 OP(opcode);
1427                         }
1428                         break;
1429
1430                 case JAVA_D2I:
1431 #if defined(__ALPHA__)
1432                         if (!opt_noieee) {
1433                                 bte = builtintable_get_internal(BUILTIN_d2i);
1434                                 OP_BUILTIN_NO_EXCEPTION(bte);
1435                         }
1436                         else
1437 #endif
1438                         {
1439                                 OP(opcode);
1440                         }
1441                         break;
1442
1443                 case JAVA_D2L:
1444 #if defined(__ALPHA__)
1445                         if (!opt_noieee) {
1446                                 bte = builtintable_get_internal(BUILTIN_d2l);
1447                                 OP_BUILTIN_NO_EXCEPTION(bte);
1448                         }
1449                         else
1450 #endif
1451                         {
1452                                 OP(opcode);
1453                         }
1454                         break;
1455
1456                 /* invalid opcodes ****************************************************/
1457
1458                         /* check for invalid opcodes if the verifier is enabled */
1459 #if defined(ENABLE_VERIFIER)
1460                 case JAVA_BREAKPOINT:
1461                         exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1462                         return false;
1463
1464                 case 186: /* unused opcode */
1465                 case 203:
1466                 case 204:
1467                 case 205:
1468                 case 206:
1469                 case 207:
1470                 case 208:
1471                 case 209:
1472                 case 210:
1473                 case 211:
1474                 case 212:
1475                 case 213:
1476                 case 214:
1477                 case 215:
1478                 case 216:
1479                 case 217:
1480                 case 218:
1481                 case 219:
1482                 case 220:
1483                 case 221:
1484                 case 222:
1485                 case 223:
1486                 case 224:
1487                 case 225:
1488                 case 226:
1489                 case 227:
1490                 case 228:
1491                 case 229:
1492                 case 230:
1493                 case 231:
1494                 case 232:
1495                 case 233:
1496                 case 234:
1497                 case 235:
1498                 case 236:
1499                 case 237:
1500                 case 238:
1501                 case 239:
1502                 case 240:
1503                 case 241:
1504                 case 242:
1505                 case 243:
1506                 case 244:
1507                 case 245:
1508                 case 246:
1509                 case 247:
1510                 case 248:
1511                 case 249:
1512                 case 250:
1513                 case 251:
1514                 case 252:
1515                 case 253:
1516                 case 254:
1517                 case 255:
1518                         exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1519                                                                                  opcode, icount);
1520                         return false;
1521                         break;
1522 #endif /* defined(ENABLE_VERIFIER) */
1523
1524                 /* opcodes that don't require translation *****************************/
1525
1526                 default:
1527                         /* straight-forward translation to ICMD */
1528                         OP(opcode);
1529                         break;
1530
1531                 } /* end switch */
1532
1533                 /* verifier checks ****************************************************/
1534
1535 #if defined(ENABLE_VERIFIER)
1536                 /* If WIDE was used correctly, iswide should have been reset by now. */
1537                 if (iswide) {
1538                         exceptions_throw_verifyerror(m,
1539                                         "Illegal instruction: WIDE before incompatible opcode");
1540                         return false;
1541                 }
1542 #endif /* defined(ENABLE_VERIFIER) */
1543
1544         } /* end for */
1545
1546         if (JITDATA_HAS_FLAG_REORDER(jd)) {
1547                 /* add a NOP to the last basic block */
1548
1549                 INSTRUCTIONS_CHECK(1);
1550                 OP(ICMD_NOP);
1551         }
1552
1553         /*** END OF LOOP **********************************************************/
1554
1555         /* assert that we did not write more ICMDs than allocated */
1556
1557         assert(icount <= pd.instructionslength);
1558         assert(icount == (iptr - pd.instructions));
1559
1560         /*** verifier checks ******************************************************/
1561
1562 #if defined(ENABLE_VERIFIER)
1563         if (p != m->jcodelength) {
1564                 exceptions_throw_verifyerror(m,
1565                                 "Command-sequence crosses code-boundary");
1566                 return false;
1567         }
1568
1569         if (!blockend) {
1570                 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1571                 return false;
1572         }
1573 #endif /* defined(ENABLE_VERIFIER) */
1574
1575         /*** setup the methodinfo, allocate stack and basic blocks ****************/
1576
1577         /* adjust block count if target 0 is not first intermediate instruction */
1578
1579         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1580                 b_count++;
1581         else
1582                 jd->branchtoentry = true;
1583
1584         /* build basic block list */
1585
1586         bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1587
1588         /* zero out all basic block structures */
1589
1590         MZERO(bptr, basicblock, b_count + 1);
1591
1592         b_count = 0;
1593
1594         /* additional block if target 0 is not first intermediate instruction */
1595
1596         if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1597                 BASICBLOCK_INIT(bptr, m);
1598
1599                 bptr->iinstr = pd.instructions;
1600
1601                 /* bptr->icount is set when the next block is allocated */
1602
1603                 bptr->nr = b_count++;
1604                 bptr++;
1605                 bptr[-1].next = bptr;
1606         }
1607
1608         /* allocate blocks */
1609
1610         for (p = 0; p < m->jcodelength; p++) {
1611                 if (jd->basicblockindex[p] & 1) {
1612 #if defined(ENABLE_VERIFIER)
1613                         /* Check if this block starts at the beginning of an
1614                            instruction. */
1615
1616                         if (!pd.instructionstart[p]) {
1617                                 exceptions_throw_verifyerror(m,
1618                                                 "Branch into middle of instruction");
1619                                 return false;
1620                         }
1621 #endif
1622
1623                         /* allocate the block */
1624
1625                         BASICBLOCK_INIT(bptr, m);
1626
1627                         bptr->iinstr = pd.instructions + (jd->basicblockindex[p] >> 1);
1628
1629                         if (b_count) {
1630                                 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1631                         }
1632                         /* bptr->icount is set when the next block is allocated */
1633
1634                         jd->basicblockindex[p] = b_count;
1635
1636                         bptr->nr = b_count++;
1637                         bptr++;
1638                         bptr[-1].next = bptr;
1639                 }
1640         }
1641
1642         /* set instruction count of last real block */
1643
1644         if (b_count) {
1645                 bptr[-1].icount = (pd.instructions + icount) - bptr[-1].iinstr;
1646         }
1647
1648         /* allocate additional block at end */
1649
1650         BASICBLOCK_INIT(bptr,m);
1651         bptr->nr = b_count;
1652         jd->basicblockindex[m->jcodelength] = b_count;
1653
1654         /* set basicblock pointers in exception table */
1655
1656         if (!parse_resolve_exception_table(jd))
1657                 return false;
1658
1659         /* store the local map */
1660
1661         jd->local_map = local_map;
1662
1663         /* calculate local variable renaming */
1664
1665         {
1666                 s4 nlocals = 0;
1667                 s4 i;
1668
1669                 s4 *mapptr;
1670
1671                 mapptr = local_map;
1672
1673                 /* iterate over local_map[0..m->maxlocals*5] and set all existing  */
1674                 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1675                 /* -> == new local var index */
1676                 for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1677                         if (*mapptr)
1678                                 *mapptr = nlocals++;
1679                         else
1680                                 *mapptr = UNUSED;
1681                 }
1682
1683                 jd->localcount = nlocals;
1684
1685                 /* calculate the (maximum) number of variables needed */
1686
1687                 jd->varcount = 
1688                           nlocals                                      /* local variables */
1689                         + b_count * m->maxstack                                 /* invars */
1690                         + s_count;         /* variables created within blocks (non-invar) */
1691
1692                 /* reserve the first indices for local variables */
1693
1694                 jd->vartop = nlocals;
1695
1696                 /* reserve extra variables needed by stack analyse */
1697
1698                 jd->varcount += STACK_EXTRA_VARS;
1699                 jd->vartop   += STACK_EXTRA_VARS;
1700
1701                 /* The verifier needs space for saving invars in some cases and */
1702                 /* extra variables.                                             */
1703
1704 #if defined(ENABLE_VERIFIER)
1705                 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1706                 jd->vartop   += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1707 #endif
1708                 /* allocate and initialize the variable array */
1709
1710                 jd->var = DMNEW(varinfo, jd->varcount);
1711                 MZERO(jd->var, varinfo, jd->varcount);
1712
1713                 /* set types of all locals in jd->var */
1714
1715                 for(mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1716                         if (*mapptr != UNUSED)
1717                                 VAR(*mapptr)->type = i%5;
1718         }
1719
1720         /* assign local variables to method variables */
1721
1722         jd->instructions     = pd.instructions;
1723         jd->instructioncount = icount;
1724         jd->basicblockcount  = b_count;
1725         jd->stackcount       = s_count + b_count * m->maxstack; /* in-stacks */
1726
1727         /* allocate stack table */
1728
1729         jd->stack = DMNEW(stackelement, jd->stackcount);
1730
1731         /* everything's ok */
1732
1733         return true;
1734
1735         /*** goto labels for throwing verifier exceptions *************************/
1736
1737 #if defined(ENABLE_VERIFIER)
1738
1739 throw_unexpected_end_of_bytecode:
1740         exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1741         return false;
1742
1743 throw_invalid_bytecode_index:
1744         exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1745         return false;
1746
1747 throw_illegal_local_variable_number:
1748         exceptions_throw_verifyerror(m, "Illegal local variable number");
1749         return false;
1750
1751 #endif /* ENABLE_VERIFIER */
1752 }
1753
1754
1755 /*
1756  * These are local overrides for various environment variables in Emacs.
1757  * Please do not remove this and leave it at the end of the file, where
1758  * Emacs will automagically detect them.
1759  * ---------------------------------------------------------------------
1760  * Local variables:
1761  * mode: c
1762  * indent-tabs-mode: t
1763  * c-basic-offset: 4
1764  * tab-width: 4
1765  * End:
1766  * vim:noexpandtab:sw=4:ts=4:
1767  */