ea00cfae13b90e365ca43754783acb36e9c3d37c
[cacao.git] / src / vm / jit / parse.c
1 /* jit/parse.c *****************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Parser for JavaVM to intermediate code translation
8         
9         Author: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
10
11         Last Change: 1998/05/07
12
13 *******************************************************************************/
14
15 #include "math.h"
16
17
18 /* macros for byte code fetching ***********************************************
19
20         fetch a byte code of given size from position p in code array jcode
21
22 *******************************************************************************/
23
24 #define code_get_u1(p)  jcode[p]
25 #define code_get_s1(p)  ((s1)jcode[p])
26 #define code_get_u2(p)  ((((u2)jcode[p])<<8)+jcode[p+1])
27 #define code_get_s2(p)  ((s2)((((u2)jcode[p])<<8)+jcode[p+1]))
28 #define code_get_u4(p)  ((((u4)jcode[p])<<24)+(((u4)jcode[p+1])<<16)\
29                            +(((u4)jcode[p+2])<<8)+jcode[p+3])
30 #define code_get_s4(p)  ((s4)((((u4)jcode[p])<<24)+(((u4)jcode[p+1])<<16)\
31                            +(((u4)jcode[p+2])<<8)+jcode[p+3]))
32
33
34 /* functionc compiler_addinitclass *********************************************
35
36         add class into the list of classes to initialize
37
38 *******************************************************************************/
39                                 
40 static void compiler_addinitclass (classinfo *c)
41 {
42         classinfo *cl;
43
44         if (c->initialized) return;
45         
46         cl = chain_first(uninitializedclasses);
47         if (cl == c)
48                 return;
49         
50         if (cl == class)
51                 cl = chain_next(uninitializedclasses);
52         for (;;) {
53                 if (cl == c)
54                         return;
55                 if (cl == NULL) {
56                         if (runverbose) {
57                                 sprintf(logtext, "compiler_addinitclass: ");
58                                 unicode_sprint(logtext+strlen(logtext), c->name);
59                                 dolog();
60                                 }
61                         chain_addlast(uninitializedclasses, c);
62                         return;
63                         }
64                 if (c < cl) {
65                         if (runverbose) {
66                                 sprintf(logtext, "compiler_addinitclass: ");
67                                 unicode_sprint(logtext+strlen(logtext), c->name);
68                                 dolog();
69                                 }
70                         chain_addbefore(uninitializedclasses, c);
71                         return;
72                         }
73                 cl = chain_next(uninitializedclasses);
74                 }
75 }                       
76
77
78 /* function descriptor2types ***************************************************
79
80         decodes a already checked method descriptor. The parameter count, the
81         return type and the argument types are stored in the passed methodinfo.
82
83 *******************************************************************************/                
84
85 static void descriptor2types (methodinfo *m)
86 {
87         u1 *types, *tptr;
88         int pcount, c;
89         u2 *cptr;
90
91         pcount = 0;
92         types = DMNEW (u1, m->descriptor->length);
93         
94         tptr = types;
95         if (!(m->flags & ACC_STATIC)) {
96                 *tptr++ = TYPE_ADR;
97                 pcount++;
98                 }
99
100         cptr = m->descriptor->text;
101         cptr++;
102         while ((c = *cptr++) != ')') {
103                 pcount++;
104                 switch (c) {
105                         case 'B':
106                         case 'C':
107                         case 'I':
108                         case 'S':
109                         case 'Z':  *tptr++ = TYPE_INT;
110                                    break;
111                         case 'J':  *tptr++ = TYPE_LNG;
112                                    break;
113                         case 'F':  *tptr++ = TYPE_FLT;
114                                    break;
115                         case 'D':  *tptr++ = TYPE_DBL;
116                                    break;
117                         case 'L':  *tptr++ = TYPE_ADR;
118                                    while (*cptr++ != ';');
119                                    break;
120                         case '[':  *tptr++ = TYPE_ADR;
121                                    while (c == '[')
122                                        c = *cptr++;
123                                    if (c == 'L')
124                                        while (*cptr++ != ';') /* skip */;
125                                    break;
126                         default:   panic ("Ill formed methodtype-descriptor");
127                         }
128                 }
129
130         /* compute return type */
131
132         switch (*cptr) {
133                 case 'B':
134                 case 'C':
135                 case 'I':
136                 case 'S':
137                 case 'Z':  m->returntype = TYPE_INT;
138                            break;
139                 case 'J':  m->returntype = TYPE_LNG;
140                            break;
141                 case 'F':  m->returntype = TYPE_FLT;
142                            break;
143                 case 'D':  m->returntype = TYPE_DBL;
144                            break;
145                 case '[':
146                 case 'L':  m->returntype = TYPE_ADR;
147                            break;
148                 case 'V':  m->returntype = TYPE_VOID;
149                            break;
150
151                 default:   panic ("Ill formed methodtype-descriptor");
152                 }
153
154         m->paramcount = pcount;
155         m->paramtypes = types;
156 }
157
158
159 #ifdef OLD_COMPILER
160
161 /* function allocate_literals **************************************************
162
163         Scans the JavaVM code of a method and allocates string literals (in the
164         same order as the old JIT). Needed to generate the same addresses as the
165         old JIT compiler.
166         
167 *******************************************************************************/
168
169 static void allocate_literals()
170 {
171         int     p, nextp;
172         int     opcode, i;
173         s4      num;
174         unicode *s;
175
176         for (p = 0; p < jcodelength; p = nextp) {
177
178                 opcode = jcode[p];
179                 nextp = p + jcommandsize[opcode];
180
181                 switch (opcode) {
182                         case JAVA_WIDE:
183                                 if (code_get_u1(p + 1) == JAVA_IINC)
184                                         nextp = p + 6;
185                                 else
186                                         nextp = p + 4;
187                                 break;
188                                                         
189                         case JAVA_LOOKUPSWITCH:
190                                 nextp = ALIGN((p + 1), 4);
191                                 num = code_get_u4(nextp + 4);
192                                 nextp = nextp + 8 + 8 * num;
193                                 break;
194
195                         case JAVA_TABLESWITCH:
196                                 nextp = ALIGN ((p + 1),4);
197                                 num = code_get_s4(nextp + 4);
198                                 num = code_get_s4(nextp + 8) - num;
199                                 nextp = nextp + 16 + 4 * num;
200                                 break;
201
202                         case JAVA_LDC1:
203                                 i = code_get_u1(p+1);
204                                 goto pushconstantitem;
205                         case JAVA_LDC2:
206                         case JAVA_LDC2W:
207                                 i = code_get_u2(p + 1);
208                         pushconstantitem:
209                                 if (class_constanttype(class, i) == CONSTANT_String) {
210                                         s = class_getconstant(class, i, CONSTANT_String);
211                                         (void) literalstring_new(s);
212                                         }
213                                 break;
214                         } /* end switch */
215                 } /* end while */
216 }
217 #endif
218
219
220 /*******************************************************************************
221
222         function 'parse' scans the JavaVM code and generates intermediate code
223
224         During parsing the block index table is used to store at bit pos 0
225         a flag which marks basic block starts and at position 1 to 31 the
226         intermediate instruction index. After parsing the block index table
227         is scanned, for marked positions a block is generated and the block
228         number is stored in the block index table.
229
230 *******************************************************************************/
231
232 /* intermediate code generating macros */
233
234 #define PINC           iptr++;ipc++
235 #define LOADCONST_I(v) iptr->opc=ICMD_ICONST;iptr->op1=0;iptr->val.i=(v);PINC
236 #define LOADCONST_L(v) iptr->opc=ICMD_LCONST;iptr->op1=0;iptr->val.l=(v);PINC
237 #define LOADCONST_F(v) iptr->opc=ICMD_FCONST;iptr->op1=0;iptr->val.f=(v);PINC
238 #define LOADCONST_D(v) iptr->opc=ICMD_DCONST;iptr->op1=0;iptr->val.d=(v);PINC
239 #define LOADCONST_A(v) iptr->opc=ICMD_ACONST;iptr->op1=0;iptr->val.a=(v);PINC
240 #define OP(o)          iptr->opc=(o);iptr->op1=0;iptr->val.l=0;PINC
241 #define OP1(o,o1)      iptr->opc=(o);iptr->op1=(o1);iptr->val.l=(0);PINC
242 #define OP2I(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.i=(v);PINC
243 #define OP2A(o,o1,v)   iptr->opc=(o);iptr->op1=(o1);iptr->val.a=(v);PINC
244 #define BUILTIN1(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN1;iptr->op1=t;\
245                        iptr->val.a=(v);PINC
246 #define BUILTIN2(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN2;iptr->op1=t;\
247                        iptr->val.a=(v);PINC
248 #define BUILTIN3(v,t)  isleafmethod=false;iptr->opc=ICMD_BUILTIN3;iptr->op1=t;\
249                        iptr->val.a=(v);PINC
250
251
252 /* block generating and checking macros */
253
254 #define block_insert(i)    {if(!(block_index[i]&1))\
255                                {b_count++;block_index[i] |= 1;}}
256 #define bound_check(i)     {if((i< 0) || (i>=jcodelength)) \
257                                panic("branch target out of code-boundary");}
258 #define bound_check1(i)    {if((i< 0) || (i>jcodelength)) \
259                                panic("branch target out of code-boundary");}
260
261
262 static void parse()
263 {
264         int  p;                     /* java instruction counter                   */
265         int  nextp;                 /* start of next java instruction             */
266         int  opcode;                /* java opcode                                */
267         int  i;                     /* temporary for different uses (counters)    */
268         int  ipc = 0;               /* intermediate instruction counter           */
269         int  b_count = 0;           /* basic block counter                        */
270         int  s_count = 0;           /* stack element counter                      */
271         bool blockend = false;      /* true if basic block end has been reached   */
272         bool iswide = false;        /* true if last instruction was a wide        */
273         instruction *iptr;          /* current pointer into instruction array     */
274
275
276 #ifdef OLD_COMPILER
277         /* generate the same addresses as the old JIT compiler */
278
279         if (runverbose)
280                 allocate_literals();
281 #endif
282
283         /* allocate instruction array and block index table */
284         
285         /* 1 additional for end ipc and 3 for loop unrolling */
286         
287         block_index = DMNEW(int, jcodelength + 3);
288
289         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
290         /* additional MONITOREXITS are reached by branches which are 3 bytes */
291         
292         iptr = instr = DMNEW(instruction, jcodelength + 5);
293         
294         /* initialize block_index table (unrolled four times) */
295
296         {
297         int *ip;
298         
299         for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
300                 ip[0] = 0;
301                 ip[1] = 0;
302                 ip[2] = 0;
303                 ip[3] = 0;
304                 }
305         }
306
307         /* compute branch targets of exception table */
308
309         for (i = 0; i < exceptiontablelength; i++) {
310                 p = extable[i].startpc;
311                 bound_check(p);
312                 block_insert(p);
313                 p = extable[i].endpc;
314                 bound_check1(p);
315                 if (p < jcodelength)
316                         block_insert(p);
317                 p = extable[i].handlerpc;
318                 bound_check(p);
319                 block_insert(p);
320                 }
321
322         s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
323
324 #ifdef USE_THREADS
325         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
326                 isleafmethod=false;
327                 }                       
328 #endif
329
330         /* scan all java instructions */
331
332         for (p = 0; p < jcodelength; p = nextp) {
333
334                 opcode = code_get_u1 (p);           /* fetch op code                  */
335
336                 block_index[p] |= (ipc << 1);       /* store intermediate count       */
337
338                 if (blockend) {
339                         block_insert(p);                /* start new block                */
340                         blockend = false;
341                         }
342
343                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
344                 s_count += stackreq[opcode];            /* compute stack element count    */
345
346                 switch (opcode) {
347
348                         case JAVA_NOP:
349                                 break;
350
351                         /* pushing constants onto the stack p */
352
353                         case JAVA_BIPUSH:
354                                 LOADCONST_I(code_get_s1(p+1));
355                                 break;
356
357                         case JAVA_SIPUSH:
358                                 LOADCONST_I(code_get_s2(p+1));
359                                 break;
360
361                         case JAVA_LDC1:
362                                 i = code_get_u1(p+1);
363                                 goto pushconstantitem;
364                         case JAVA_LDC2:
365                         case JAVA_LDC2W:
366                                 i = code_get_u2(p + 1);
367
368                         pushconstantitem:
369
370                                 if (i >= class->cpcount) 
371                                         panic ("Attempt to access constant outside range");
372
373                                 switch (class->cptags[i]) {
374                                         case CONSTANT_Integer:
375                                                 LOADCONST_I(((constant_integer*)
376                                                              (class->cpinfos[i]))->value);
377                                                 break;
378                                         case CONSTANT_Long:
379                                                 LOADCONST_L(((constant_long*)
380                                                              (class->cpinfos[i]))->value);
381                                                 break;
382                                         case CONSTANT_Float:
383                                                 LOADCONST_F(((constant_float*)
384                                                              (class->cpinfos[i]))->value);
385                                                 break;
386                                         case CONSTANT_Double:
387                                                 LOADCONST_D(((constant_double*)
388                                                              (class->cpinfos[i]))->value);
389                                                 break;
390                                         case CONSTANT_String:
391                                                 LOADCONST_A(literalstring_new((unicode*)
392                                                                               (class->cpinfos[i])));
393                                                 break;
394                                         default: panic("Invalid constant type to push");
395                                         }
396                                 break;
397
398                         case JAVA_ACONST_NULL:
399                                 LOADCONST_A(NULL);
400                                 break;
401
402                         case JAVA_ICONST_M1:
403                         case JAVA_ICONST_0:
404                         case JAVA_ICONST_1:
405                         case JAVA_ICONST_2:
406                         case JAVA_ICONST_3:
407                         case JAVA_ICONST_4:
408                         case JAVA_ICONST_5:
409                                 LOADCONST_I(opcode - JAVA_ICONST_0);
410                                 break;
411
412                         case JAVA_LCONST_0:
413                         case JAVA_LCONST_1:
414                                 LOADCONST_L(opcode - JAVA_LCONST_0);
415                                 break;
416
417                         case JAVA_FCONST_0:
418                         case JAVA_FCONST_1:
419                         case JAVA_FCONST_2:
420                                 LOADCONST_F(opcode - JAVA_FCONST_0);
421                                 break;
422
423                         case JAVA_DCONST_0:
424                         case JAVA_DCONST_1:
425                                 LOADCONST_D(opcode - JAVA_DCONST_0);
426                                 break;
427
428                         /* loading variables onto the stack */
429
430                         case JAVA_ILOAD:
431                         case JAVA_LLOAD:
432                         case JAVA_FLOAD:
433                         case JAVA_DLOAD:
434                         case JAVA_ALOAD:
435                                 if (!iswide)
436                                         i = code_get_u1(p+1);
437                                 else {
438                                         i = code_get_u2(p+1);
439                                         nextp = p+3;
440                                         iswide = false;
441                                         }
442                                 OP1(opcode, i);
443                                 break;
444
445                         case JAVA_ILOAD_0:
446                         case JAVA_ILOAD_1:
447                         case JAVA_ILOAD_2:
448                         case JAVA_ILOAD_3:
449                                 OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
450                                 break;
451
452                         case JAVA_LLOAD_0:
453                         case JAVA_LLOAD_1:
454                         case JAVA_LLOAD_2:
455                         case JAVA_LLOAD_3:
456                                 OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
457                                 break;
458
459                         case JAVA_FLOAD_0:
460                         case JAVA_FLOAD_1:
461                         case JAVA_FLOAD_2:
462                         case JAVA_FLOAD_3:
463                                 OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
464                                 break;
465
466                         case JAVA_DLOAD_0:
467                         case JAVA_DLOAD_1:
468                         case JAVA_DLOAD_2:
469                         case JAVA_DLOAD_3:
470                                 OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
471                                 break;
472
473                         case JAVA_ALOAD_0:
474                         case JAVA_ALOAD_1:
475                         case JAVA_ALOAD_2:
476                         case JAVA_ALOAD_3:
477                                 OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
478                                 break;
479
480                         /* storing stack values into local variables */
481
482                         case JAVA_ISTORE:
483                         case JAVA_LSTORE:
484                         case JAVA_FSTORE:
485                         case JAVA_DSTORE:
486                         case JAVA_ASTORE:
487                                 if (!iswide)
488                                         i = code_get_u1(p+1);
489                                 else {
490                                         i = code_get_u2(p+1);
491                                         iswide=false;
492                                         nextp = p+3;
493                                         }
494                                 OP1(opcode, i);
495                                 break;
496
497                         case JAVA_ISTORE_0:
498                         case JAVA_ISTORE_1:
499                         case JAVA_ISTORE_2:
500                         case JAVA_ISTORE_3:
501                                 OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
502                                 break;
503
504                         case JAVA_LSTORE_0:
505                         case JAVA_LSTORE_1:
506                         case JAVA_LSTORE_2:
507                         case JAVA_LSTORE_3:
508                                 OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
509                                 break;
510
511                         case JAVA_FSTORE_0:
512                         case JAVA_FSTORE_1:
513                         case JAVA_FSTORE_2:
514                         case JAVA_FSTORE_3:
515                                 OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
516                                 break;
517
518                         case JAVA_DSTORE_0:
519                         case JAVA_DSTORE_1:
520                         case JAVA_DSTORE_2:
521                         case JAVA_DSTORE_3:
522                                 OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
523                                 break;
524
525                         case JAVA_ASTORE_0:
526                         case JAVA_ASTORE_1:
527                         case JAVA_ASTORE_2:
528                         case JAVA_ASTORE_3:
529                                 OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
530                                 break;
531
532                         case JAVA_IINC:
533                                 {
534                                 int v;
535                                 
536                                 if (!iswide) {
537                                         i = code_get_u1(p + 1);
538                                         v = code_get_s1(p + 2);
539                                         }
540                                 else {
541                                         i = code_get_u2(p + 1);
542                                         v = code_get_s2(p + 3);
543                                         iswide = false;
544                                         nextp = p+5;
545                                         }
546                                 OP2I(opcode, i, v);
547                                 }
548                                 break;
549
550                         /* wider index for loading, storing and incrementing */
551
552                         case JAVA_WIDE:
553                                 iswide = true;
554                                 nextp = p + 1;
555                                 break;
556
557                         /* managing arrays ************************************************/
558
559                         case JAVA_NEWARRAY:
560                                 OP2I(ICMD_CHECKASIZE, 0, 0);
561                                 switch (code_get_s1(p+1)) {
562                                         case 4:
563                                                 BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
564                                                 break;
565                                         case 5:
566                                                 BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
567                                                 break;
568                                         case 6:
569                                                 BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
570                                                 break;
571                                         case 7:
572                                                 BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
573                                                 break;
574                                         case 8:
575                                                 BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
576                                                 break;
577                                         case 9:
578                                                 BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
579                                                 break;
580                                         case 10:
581                                                 BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
582                                                 break;
583                                         case 11:
584                                                 BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
585                                                 break;
586                                         default: panic("Invalid array-type to create");
587                                         }
588                                 break;
589
590                         case JAVA_ANEWARRAY:
591                                 OP2I(ICMD_CHECKASIZE, 0, 0);
592                                 i = code_get_u2(p+1);
593                                 /* array or class type ? */
594                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
595                                         LOADCONST_A(class_getconstant(class, i,
596                                                                       CONSTANT_Arraydescriptor));
597                                         BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
598                                         }
599                                 else {
600                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
601                                         BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
602                                         }
603                                 break;
604
605                         case JAVA_MULTIANEWARRAY:
606                                 isleafmethod=false;
607                                 i = code_get_u2(p+1);
608                                 {
609                                 int v = code_get_u1(p+3);
610                                 constant_arraydescriptor *desc =
611                                     class_getconstant (class, i, CONSTANT_Arraydescriptor);
612                                 OP2A(opcode, v, desc);
613                                 }
614                                 break;
615
616                         case JAVA_IFEQ:
617                         case JAVA_IFLT:
618                         case JAVA_IFLE:
619                         case JAVA_IFNE:
620                         case JAVA_IFGT:
621                         case JAVA_IFGE:
622                         case JAVA_IFNULL:
623                         case JAVA_IFNONNULL:
624                         case JAVA_IF_ICMPEQ:
625                         case JAVA_IF_ICMPNE:
626                         case JAVA_IF_ICMPLT:
627                         case JAVA_IF_ICMPGT:
628                         case JAVA_IF_ICMPLE:
629                         case JAVA_IF_ICMPGE:
630                         case JAVA_IF_ACMPEQ:
631                         case JAVA_IF_ACMPNE:
632                         case JAVA_GOTO:
633                         case JAVA_JSR:
634                                 i = p + code_get_s2(p+1);
635                                 bound_check(i);
636                                 block_insert(i);
637                                 blockend = true;
638                                 OP1(opcode, i);
639                                 break;
640                         case JAVA_GOTO_W:
641                         case JAVA_JSR_W:
642                                 i = p + code_get_s4(p+1);
643                                 bound_check(i);
644                                 block_insert(i);
645                                 blockend = true;
646                                 OP1(opcode, i);
647                                 break;
648
649                         case JAVA_RET:
650                                 if (!iswide)
651                                         i = code_get_u1(p+1);
652                                 else {
653                                         i = code_get_u2(p+1);
654                                         nextp = p+3;
655                                         iswide = false;
656                                         }
657                                 blockend = true;
658                                 OP1(opcode, i);
659                                 break;
660
661                         case JAVA_IRETURN:
662                         case JAVA_LRETURN:
663                         case JAVA_FRETURN:
664                         case JAVA_DRETURN:
665                         case JAVA_ARETURN:
666                         case JAVA_RETURN:
667                                 blockend = true;
668                                 OP(opcode);
669                                 break;
670
671                         case JAVA_ATHROW:
672                                 blockend = true;
673                                 OP(opcode);
674                                 break;
675                                 
676
677                         /* table jumps ********************************/
678
679                         case JAVA_LOOKUPSWITCH:
680                                 {
681                                 s4 num, j;
682
683                                 blockend = true;
684                                 nextp = ALIGN((p + 1), 4);
685                                 OP2A(opcode, 0, jcode + nextp);
686
687                                 /* default target */
688
689                                 j =  p + code_get_s4(nextp);
690                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
691                                 nextp += 4;
692                                 bound_check(j);
693                                 block_insert(j);
694
695                                 /* number of pairs */
696
697                                 num = code_get_u4(nextp);
698                                 *((s4*)(jcode + nextp)) = num;
699                                 nextp += 4;
700
701                                 for (i = 0; i < num; i++) {
702
703                                         /* value */
704
705                                         j = code_get_s4(nextp);
706                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
707                                         nextp += 4;
708
709                                         /* target */
710
711                                         j = p + code_get_s4(nextp);
712                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
713                                         nextp += 4;
714                                         bound_check(j);
715                                         block_insert(j);
716                                         }
717
718                                 break;
719                                 }
720
721
722                         case JAVA_TABLESWITCH:
723                                 {
724                                 s4 num, j;
725
726                                 blockend = true;
727                                 nextp = ALIGN((p + 1), 4);
728                                 OP2A(opcode, 0, jcode + nextp);
729
730                                 /* default target */
731
732                                 j = p + code_get_s4(nextp);
733                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
734                                 nextp += 4;
735                                 bound_check(j);
736                                 block_insert(j);
737
738                                 /* lower bound */
739
740                                 j = code_get_s4(nextp);
741                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
742                                 nextp += 4;
743
744                                 /* upper bound */
745
746                                 num = code_get_s4(nextp);
747                                 *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
748                                 nextp += 4;
749
750                                 num -= j;
751
752                                 for (i = 0; i <= num; i++) {
753                                         j = p + code_get_s4(nextp);
754                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
755                                         nextp += 4;
756                                         bound_check(j);
757                                         block_insert(j);
758                                         }
759
760                                 break;
761                                 }
762
763
764                         /* load and store of object fields *******************/
765
766                         case JAVA_AASTORE:
767                                 BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
768                                 break;
769
770                         case JAVA_PUTSTATIC:
771                         case JAVA_GETSTATIC:
772                                 i = code_get_u2(p + 1);
773                                 {
774                                 constant_FMIref *fr;
775                                 fieldinfo *fi;
776                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
777                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
778                                 compiler_addinitclass (fr->class);
779                                 OP2A(opcode, fi->type, fi);
780                                 }
781                                 break;
782                         case JAVA_PUTFIELD:
783                         case JAVA_GETFIELD:
784                                 i = code_get_u2(p + 1);
785                                 {
786                                 constant_FMIref *fr;
787                                 fieldinfo *fi;
788                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
789                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
790                                 OP2A(opcode, fi->type, fi);
791                                 }
792                                 break;
793
794
795                         /* method invocation *****/
796
797                         case JAVA_INVOKESTATIC:
798                                 i = code_get_u2(p + 1);
799                                 {
800                                 constant_FMIref *mr;
801                                 methodinfo *mi;
802                                 
803                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
804                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
805                                 if (! (mi->flags & ACC_STATIC))
806                                         panic ("Static/Nonstatic mismatch calling static method");
807                                 descriptor2types(mi);
808                                 isleafmethod=false;
809                                 OP2A(opcode, mi->paramcount, mi);
810                                 }
811                                 break;
812                         case JAVA_INVOKESPECIAL:
813                         case JAVA_INVOKEVIRTUAL:
814                                 i = code_get_u2(p + 1);
815                                 {
816                                 constant_FMIref *mr;
817                                 methodinfo *mi;
818                                 
819                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
820                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
821                                 if (mi->flags & ACC_STATIC)
822                                         panic ("Static/Nonstatic mismatch calling static method");
823                                 descriptor2types(mi);
824                                 isleafmethod=false;
825                                 OP2A(opcode, mi->paramcount, mi);
826                                 }
827                                 break;
828                         case JAVA_INVOKEINTERFACE:
829                                 i = code_get_u2(p + 1);
830                                 {
831                                 constant_FMIref *mr;
832                                 methodinfo *mi;
833                                 
834                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
835                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
836                                 if (mi->flags & ACC_STATIC)
837                                         panic ("Static/Nonstatic mismatch calling static method");
838                                 descriptor2types(mi);
839                                 isleafmethod=false;
840                                 OP2A(opcode, mi->paramcount, mi);
841                                 }
842                                 break;
843
844                         /* miscellaneous object operations *******/
845
846                         case JAVA_NEW:
847                                 i = code_get_u2 (p+1);
848                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
849                                 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
850                                 break;
851
852                         case JAVA_CHECKCAST:
853                                 i = code_get_u2(p+1);
854
855                                 /* array type cast-check */
856                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
857                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
858                                         BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
859                                         }
860                                 else { /* object type cast-check */
861                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
862                                         }
863                                 break;
864
865                         case JAVA_INSTANCEOF:
866                                 i = code_get_u2(p+1);
867
868                                 /* array type cast-check */
869                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
870                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
871                                         BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
872                                         }
873                                 else { /* object type cast-check */
874                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
875                                         }
876                                 break;
877
878                         case JAVA_MONITORENTER:
879 #ifdef USE_THREADS
880                                 if (checksync) {
881 #ifdef SOFTNULLPTRCHECK
882                                         if (checknull) {
883                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
884                                                 }
885                                         else {
886 /*                                              BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
887                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
888                                                 }
889 #else
890                                         BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
891 #endif
892                                         }
893                                 else
894 #endif
895                                         {
896                                         OP(ICMD_NULLCHECKPOP);
897                                         }
898                                 break;
899
900                         case JAVA_MONITOREXIT:
901 #ifdef USE_THREADS
902                                 if (checksync) {
903                                         BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
904                                         }
905                                 else
906 #endif
907                                         {
908                                         OP(ICMD_POP);
909                                         }
910                                 break;
911
912                         /* any other basic operation **************************************/
913
914                         case JAVA_IDIV:
915                                 OP(opcode);
916                                 break;
917
918                         case JAVA_IREM:
919                                 OP(opcode);
920                                 break;
921
922                         case JAVA_LDIV:
923                                 OP(opcode);
924                                 break;
925
926                         case JAVA_LREM:
927                                 OP(opcode);
928                                 break;
929
930                         case JAVA_FREM:
931                                 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
932                                 break;
933
934                         case JAVA_DREM:
935                                 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
936                                 break;
937
938                         case JAVA_F2I:
939                                 if (checkfloats) {
940                                         BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
941                                         }
942                                 else {
943                                         OP(opcode);
944                                         }
945                                 break;
946
947                         case JAVA_F2L:
948                                 if (checkfloats) {
949                                         BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
950                                         }
951                                 else {
952                                         OP(opcode);
953                                         }
954                                 break;
955
956                         case JAVA_D2I:
957                                 if (checkfloats) {
958                                         BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
959                                         }
960                                 else {
961                                         OP(opcode);
962                                         }
963                                 break;
964
965                         case JAVA_D2L:
966                                 if (checkfloats) {
967                                         BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
968                                         }
969                                 else {
970                                         OP(opcode);
971                                         }
972                                 break;
973
974                         case JAVA_BREAKPOINT:
975                                 panic("Illegal opcode Breakpoint encountered");
976                                 break;
977
978                         case 203:
979                         case 204:
980                         case 205:
981                         case 206:
982                         case 207:
983                         case 208:
984                         case 209:
985                         case 210:
986                         case 211:
987                         case 212:
988                         case 213:
989                         case 214:
990                         case 215:
991                         case 216:
992                         case 217:
993                         case 218:
994                         case 219:
995                         case 220:
996                         case 221:
997                         case 222:
998                         case 223:
999                         case 224:
1000                         case 225:
1001                         case 226:
1002                         case 227:
1003                         case 228:
1004                         case 229:
1005                         case 230:
1006                         case 231:
1007                         case 232:
1008                         case 233:
1009                         case 234:
1010                         case 235:
1011                         case 236:
1012                         case 237:
1013                         case 238:
1014                         case 239:
1015                         case 240:
1016                         case 241:
1017                         case 242:
1018                         case 243:
1019                         case 244:
1020                         case 245:
1021                         case 246:
1022                         case 247:
1023                         case 248:
1024                         case 249:
1025                         case 250:
1026                         case 251:
1027                         case 252:
1028                         case 253:
1029                         case 254:
1030                         case 255:
1031                                 printf("Illegal opcode %d at instr %d", opcode, ipc);
1032                                 panic("encountered");
1033                                 break;
1034
1035                         default:
1036                                 OP(opcode);
1037                                 break;
1038
1039                         } /* end switch */
1040
1041                 } /* end for */
1042
1043         if (p != jcodelength)
1044                 panic("Command-sequence crosses code-boundary");
1045
1046         if (!blockend)
1047                 panic("Code does not end with branch/return/athrow - stmt");    
1048
1049         /* adjust block count if target 0 is not first intermediate instruction   */
1050
1051         if (!block_index[0] || (block_index[0] > 1))
1052                 b_count++;
1053
1054         /* copy local to global variables   */
1055
1056         instr_count = ipc;
1057         block_count = b_count;
1058         stack_count = s_count + block_count * maxstack;
1059
1060         /* allocate stack table */
1061
1062         stack = DMNEW(stackelement, stack_count);
1063
1064         {
1065         basicblock  *bptr;
1066
1067         bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1068
1069         b_count = 0;
1070         
1071         /* additional block if target 0 is not first intermediate instruction     */
1072
1073         if (!block_index[0] || (block_index[0] > 1)) {
1074                 bptr->iinstr = instr;
1075                 bptr->mpc = -1;
1076                 bptr->flags = -1;
1077                 bptr->type = BBTYPE_STD;
1078                 bptr->branchrefs = NULL;
1079                 bptr->pre_count = 0;
1080                 bptr++;
1081                 b_count++;
1082                 }
1083
1084         /* allocate blocks */
1085
1086         for (p = 0; p < jcodelength; p++)
1087                 if (block_index[p] & 1) {
1088                         bptr->iinstr = instr + (block_index[p] >> 1);
1089                         if (b_count != 0)
1090                                 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1091                         bptr->mpc = -1;
1092                         bptr->flags = -1;
1093                         bptr->type = BBTYPE_STD;
1094                         bptr->branchrefs = NULL;
1095                         block_index[p] = b_count;
1096                         bptr->pre_count = 0;
1097                         bptr++;
1098                         b_count++;
1099                         }
1100
1101         /* allocate additional block at end */
1102
1103         bptr->iinstr = NULL;
1104         (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1105         bptr->icount = 0;
1106         bptr->mpc = -1;
1107         bptr->flags = -1;
1108         bptr->type = BBTYPE_STD;
1109         bptr->branchrefs = NULL;
1110         bptr->pre_count = 0;
1111         }
1112 }
1113
1114
1115 /*
1116  * These are local overrides for various environment variables in Emacs.
1117  * Please do not remove this and leave it at the end of the file, where
1118  * Emacs will automagically detect them.
1119  * ---------------------------------------------------------------------
1120  * Local variables:
1121  * mode: c
1122  * indent-tabs-mode: t
1123  * c-basic-offset: 4
1124  * tab-width: 4
1125  * End:
1126  */