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