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