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