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