RTA update - statistics only until inlining
[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: $Id: parse.c 383 2003-07-08 21:01:26Z 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         static int xta1 = 0;
283
284                 /*RTAprint*/ if  ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
285                 /*RTAprint*/    {printf("PARSE method name =");
286                 /*RTAprint*/    utf_display(method->class->name);printf(".");
287                 /*RTAprint*/    method_display(method); printf(">\n\n");fflush(stdout);}
288         if (opt_rt) { 
289             RT_jit_parse(method);
290             }
291         else {
292                 if ((opt_xta) && (xta1 == 0)) { 
293                         /*printf("XTA - not available yet\n"); */
294                         /*xta1++;  */
295                          XTA_jit_parse(method);
296                                 /*XTAprint*/ if (((pOpcodes == 1) || (pOpcodes == 3)) && opt_rt)
297                                 /*XTAprint*/    {printf("XTA PARSE method name =");
298                                 /*XTAprint*/    utf_display(rt_method->class->name);printf(".");
299                                 /*XTAprint*/    method_display(rt_method); printf(">\n\n");fflush(stdout);}
300
301                         }
302         
303            }
304
305 #ifdef OLD_COMPILER
306         /* generate the same addresses as the old JIT compiler */
307
308         if (runverbose)
309                 allocate_literals();
310 #endif
311
312         /* allocate instruction array and block index table */
313         
314         /* 1 additional for end ipc and 3 for loop unrolling */
315         
316         block_index = DMNEW(int, jcodelength + 4);
317
318         /* 1 additional for TRACEBUILTIN and 4 for MONITORENTER/EXIT */
319         /* additional MONITOREXITS are reached by branches which are 3 bytes */
320         
321         iptr = instr = DMNEW(instruction, jcodelength + 5); 
322         
323         /* initialize block_index table (unrolled four times) */
324
325         {
326         int *ip;
327         
328         for (i = 0, ip = block_index; i <= jcodelength; i += 4, ip += 4) {
329                 ip[0] = 0;
330                 ip[1] = 0;
331                 ip[2] = 0;
332                 ip[3] = 0;
333                 }
334         }
335
336         /* compute branch targets of exception table */
337
338         extable = DMNEW(xtable, exceptiontablelength + 1);
339
340         for (i = 0; i < exceptiontablelength; i++) {
341
342                 p = extable[i].startpc = raw_extable[i].startpc;
343                 bound_check(p);
344                 block_insert(p);
345
346                 p = extable[i].endpc = raw_extable[i].endpc;
347                 bound_check1(p);
348                 if (p < jcodelength)
349                         block_insert(p);
350
351                 p = extable[i].handlerpc = raw_extable[i].handlerpc;
352                 bound_check(p);
353                 block_insert(p);
354
355                 extable[i].catchtype  = raw_extable[i].catchtype;
356
357                 extable[i].next = NULL;
358                 extable[i].down = &extable[i+1];
359                 }
360
361         if (exceptiontablelength > 0)
362                 extable[exceptiontablelength-1].down = NULL;
363         else
364                 extable = NULL;
365
366         s_count = 1 + exceptiontablelength; /* initialize stack element counter   */
367
368 #ifdef USE_THREADS
369         if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
370                 isleafmethod=false;
371                 }                       
372 #endif
373
374         /* scan all java instructions */
375
376         for (p = 0; p < jcodelength; p = nextp) {
377
378                 opcode = code_get_u1 (p);           /* fetch op code                  */
379
380                                 /*RTAprint*/ if  ((opt_rt) && ((pOpcodes == 2) || (pOpcodes == 3)) )
381                                 /*RTAprint*/    {printf("Parse<%i> p=%i<%i<   opcode=<%i> %s\n",
382                                 /*RTAprint*/            pOpcodes, p,jcodelength,opcode,opcode_names[opcode]);}
383
384                 block_index[p] |= (ipc << 1);       /* store intermediate count       */
385
386                 if (blockend) {
387                         block_insert(p);                /* start new block                */
388                         blockend = false;
389                         }
390
391                 nextp = p + jcommandsize[opcode];   /* compute next instruction start */
392                 s_count += stackreq[opcode];            /* compute stack element count    */
393
394                 switch (opcode) {
395
396                         case JAVA_NOP:
397                                 break;
398
399                         /* pushing constants onto the stack p */
400
401                         case JAVA_BIPUSH:
402                                 LOADCONST_I(code_get_s1(p+1));
403                                 break;
404
405                         case JAVA_SIPUSH:
406                                 LOADCONST_I(code_get_s2(p+1));
407                                 break;
408
409                         case JAVA_LDC1:
410                                 i = code_get_u1(p+1);
411                                 goto pushconstantitem;
412                         case JAVA_LDC2:
413                         case JAVA_LDC2W:
414                                 i = code_get_u2(p + 1);
415
416                         pushconstantitem:
417
418                                 if (i >= class->cpcount) 
419                                         panic ("Attempt to access constant outside range");
420
421                                 switch (class->cptags[i]) {
422                                         case CONSTANT_Integer:
423                                                 LOADCONST_I(((constant_integer*)
424                                                              (class->cpinfos[i]))->value);
425                                                 break;
426                                         case CONSTANT_Long:
427                                                 LOADCONST_L(((constant_long*)
428                                                              (class->cpinfos[i]))->value);
429                                                 break;
430                                         case CONSTANT_Float:
431                                                 LOADCONST_F(((constant_float*)
432                                                              (class->cpinfos[i]))->value);
433                                                 break;
434                                         case CONSTANT_Double:
435                                                 LOADCONST_D(((constant_double*)
436                                                              (class->cpinfos[i]))->value);
437                                                 break;
438                                         case CONSTANT_String:
439                                                 LOADCONST_A(literalstring_new((utf*)
440                                                                               (class->cpinfos[i])));
441                                                 break;
442                                         default: panic("Invalid constant type to push");
443                                         }
444                                 break;
445
446                         case JAVA_ACONST_NULL:
447                                 LOADCONST_A(NULL);
448                                 break;
449
450                         case JAVA_ICONST_M1:
451                         case JAVA_ICONST_0:
452                         case JAVA_ICONST_1:
453                         case JAVA_ICONST_2:
454                         case JAVA_ICONST_3:
455                         case JAVA_ICONST_4:
456                         case JAVA_ICONST_5:
457                                 LOADCONST_I(opcode - JAVA_ICONST_0);
458                                 break;
459
460                         case JAVA_LCONST_0:
461                         case JAVA_LCONST_1:
462                                 LOADCONST_L(opcode - JAVA_LCONST_0);
463                                 break;
464
465                         case JAVA_FCONST_0:
466                         case JAVA_FCONST_1:
467                         case JAVA_FCONST_2:
468                                 LOADCONST_F(opcode - JAVA_FCONST_0);
469                                 break;
470
471                         case JAVA_DCONST_0:
472                         case JAVA_DCONST_1:
473                                 LOADCONST_D(opcode - JAVA_DCONST_0);
474                                 break;
475
476                         /* loading variables onto the stack */
477
478                         case JAVA_ILOAD:
479                         case JAVA_LLOAD:
480                         case JAVA_FLOAD:
481                         case JAVA_DLOAD:
482                         case JAVA_ALOAD:
483                                 if (!iswide)
484                                         i = code_get_u1(p+1);
485                                 else {
486                                         i = code_get_u2(p+1);
487 //printf("WIDE ");
488                                         nextp = p+3;
489                                         iswide = false;
490                                         }
491                                 OP1(opcode, i);
492 // printf("I-ALOAD %s i=%i <%x>\n", opcode_names[opcode],i,jcode[p+1]);
493                                 break;
494
495                         case JAVA_ILOAD_0:
496                         case JAVA_ILOAD_1:
497                         case JAVA_ILOAD_2:
498                         case JAVA_ILOAD_3:
499                                 OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
500                                 break;
501
502                         case JAVA_LLOAD_0:
503                         case JAVA_LLOAD_1:
504                         case JAVA_LLOAD_2:
505                         case JAVA_LLOAD_3:
506                                 OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
507                                 break;
508
509                         case JAVA_FLOAD_0:
510                         case JAVA_FLOAD_1:
511                         case JAVA_FLOAD_2:
512                         case JAVA_FLOAD_3:
513                                 OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
514                                 break;
515
516                         case JAVA_DLOAD_0:
517                         case JAVA_DLOAD_1:
518                         case JAVA_DLOAD_2:
519                         case JAVA_DLOAD_3:
520                                 OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
521                                 break;
522
523                         case JAVA_ALOAD_0:
524                         case JAVA_ALOAD_1:
525                         case JAVA_ALOAD_2:
526                         case JAVA_ALOAD_3:
527                                 OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
528                                 break;
529
530                         /* storing stack values into local variables */
531
532                         case JAVA_ISTORE:
533                         case JAVA_LSTORE:
534                         case JAVA_FSTORE:
535                         case JAVA_DSTORE:
536                         case JAVA_ASTORE:
537                                 if (!iswide)
538                                         i = code_get_u1(p+1);
539                                 else {
540                                         i = code_get_u2(p+1);
541 //printf("WIDE ");
542                                         iswide=false;
543                                         nextp = p+3;
544                                         }
545 //printf("I-ASTORE %s i=%i <%x>\n", opcode_names[opcode],i,jcode[p+1]);
546                                 OP1(opcode, i);
547                                 break;
548
549                         case JAVA_ISTORE_0:
550                         case JAVA_ISTORE_1:
551                         case JAVA_ISTORE_2:
552                         case JAVA_ISTORE_3:
553                                 OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
554                                 break;
555
556                         case JAVA_LSTORE_0:
557                         case JAVA_LSTORE_1:
558                         case JAVA_LSTORE_2:
559                         case JAVA_LSTORE_3:
560                                 OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
561                                 break;
562
563                         case JAVA_FSTORE_0:
564                         case JAVA_FSTORE_1:
565                         case JAVA_FSTORE_2:
566                         case JAVA_FSTORE_3:
567                                 OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
568                                 break;
569
570                         case JAVA_DSTORE_0:
571                         case JAVA_DSTORE_1:
572                         case JAVA_DSTORE_2:
573                         case JAVA_DSTORE_3:
574                                 OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
575                                 break;
576
577                         case JAVA_ASTORE_0:
578                         case JAVA_ASTORE_1:
579                         case JAVA_ASTORE_2:
580                         case JAVA_ASTORE_3:
581                                 OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
582                                 break;
583
584                         case JAVA_IINC:
585                                 {
586                                 int v;
587                                 
588                                 if (!iswide) {
589                                         i = code_get_u1(p + 1);
590                                         v = code_get_s1(p + 2);
591                                         }
592                                 else {
593                                         i = code_get_u2(p + 1);
594                                         v = code_get_s2(p + 3);
595                                         iswide = false;
596                                         nextp = p+5;
597                                         }
598                                 OP2I(opcode, i, v);
599                                 }
600                                 break;
601
602                         /* wider index for loading, storing and incrementing */
603
604                         case JAVA_WIDE:
605                                 iswide = true;
606                                 nextp = p + 1;
607                                 break;
608
609                         /* managing arrays ************************************************/
610
611                         case JAVA_NEWARRAY:
612                                 OP2I(ICMD_CHECKASIZE, 0, 0);
613                                 switch (code_get_s1(p+1)) {
614                                         case 4:
615                                                 BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
616                                                 break;
617                                         case 5:
618                                                 BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
619                                                 break;
620                                         case 6:
621                                                 BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
622                                                 break;
623                                         case 7:
624                                                 BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
625                                                 break;
626                                         case 8:
627                                                 BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
628                                                 break;
629                                         case 9:
630                                                 BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
631                                                 break;
632                                         case 10:
633                                                 BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
634                                                 break;
635                                         case 11:
636                                                 BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
637                                                 break;
638                                         default: panic("Invalid array-type to create");
639                                         }
640                                 break;
641
642                         case JAVA_ANEWARRAY:
643                                 OP2I(ICMD_CHECKASIZE, 0, 0);
644                                 i = code_get_u2(p+1);
645                                 /* array or class type ? */
646                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
647                                         s_count++;
648                                         LOADCONST_A(class_getconstant(class, i,
649                                                                       CONSTANT_Arraydescriptor));
650 #ifdef __I386__
651                                         BUILTIN2((functionptr) asm_builtin_newarray_array, TYPE_ADR);
652 #else
653                                         BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
654 #endif
655                                         }
656                                 else {
657                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
658                                         s_count++;
659 #ifdef __I386__
660                                         BUILTIN2((functionptr) asm_builtin_anewarray, TYPE_ADR);
661 #else
662                                         BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
663 #endif
664                                         }
665                                 break;
666
667                         case JAVA_MULTIANEWARRAY:
668                                 isleafmethod=false;
669                                 i = code_get_u2(p+1);
670                                 {
671                                 int v = code_get_u1(p+3);
672                                 constant_arraydescriptor *desc =
673                                     class_getconstant (class, i, CONSTANT_Arraydescriptor);
674                                 OP2A(opcode, v, desc);
675                                 }
676                                 break;
677
678                         case JAVA_IFEQ:
679                         case JAVA_IFLT:
680                         case JAVA_IFLE:
681                         case JAVA_IFNE:
682                         case JAVA_IFGT:
683                         case JAVA_IFGE:
684                         case JAVA_IFNULL:
685                         case JAVA_IFNONNULL:
686                         case JAVA_IF_ICMPEQ:
687                         case JAVA_IF_ICMPNE:
688                         case JAVA_IF_ICMPLT:
689                         case JAVA_IF_ICMPGT:
690                         case JAVA_IF_ICMPLE:
691                         case JAVA_IF_ICMPGE:
692                         case JAVA_IF_ACMPEQ:
693                         case JAVA_IF_ACMPNE:
694                         case JAVA_GOTO:
695                         case JAVA_JSR:
696                                 i = p + code_get_s2(p+1);
697                                 bound_check(i);
698                                 block_insert(i);
699                                 blockend = true;
700                                 OP1(opcode, i);
701                                 break;
702                         case JAVA_GOTO_W:
703                         case JAVA_JSR_W:
704                                 i = p + code_get_s4(p+1);
705                                 bound_check(i);
706                                 block_insert(i);
707                                 blockend = true;
708                                 OP1(opcode, i);
709                                 break;
710
711                         case JAVA_RET:
712                                 if (!iswide)
713                                         i = code_get_u1(p+1);
714                                 else {
715                                         i = code_get_u2(p+1);
716                                         nextp = p+3;
717                                         iswide = false;
718                                         }
719                                 blockend = true;
720                                 OP1(opcode, i);
721                                 break;
722
723                         case JAVA_IRETURN:
724                         case JAVA_LRETURN:
725                         case JAVA_FRETURN:
726                         case JAVA_DRETURN:
727                         case JAVA_ARETURN:
728                         case JAVA_RETURN:
729                                 blockend = true;
730                                 OP(opcode);
731                                 break;
732
733                         case JAVA_ATHROW:
734                                 blockend = true;
735                                 OP(opcode);
736                                 break;
737                                 
738
739                         /* table jumps ********************************/
740
741                         case JAVA_LOOKUPSWITCH:
742                                 {
743                                 s4 num, j;
744
745                                 blockend = true;
746                                 nextp = ALIGN((p + 1), 4);
747                                 OP2A(opcode, 0, jcode + nextp);
748
749                                 /* default target */
750
751                                 j =  p + code_get_s4(nextp);
752                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
753                                 nextp += 4;
754                                 bound_check(j);
755                                 block_insert(j);
756
757                                 /* number of pairs */
758
759                                 num = code_get_u4(nextp);
760                                 *((s4*)(jcode + nextp)) = num;
761                                 nextp += 4;
762
763                                 for (i = 0; i < num; i++) {
764
765                                         /* value */
766
767                                         j = code_get_s4(nextp);
768                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
769                                         nextp += 4;
770
771                                         /* target */
772
773                                         j = p + code_get_s4(nextp);
774                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
775                                         nextp += 4;
776                                         bound_check(j);
777                                         block_insert(j);
778                                         }
779
780                                 break;
781                                 }
782
783
784                         case JAVA_TABLESWITCH:
785                                 {
786                                 s4 num, j;
787
788                                 blockend = true;
789                                 nextp = ALIGN((p + 1), 4);
790                                 OP2A(opcode, 0, jcode + nextp);
791
792                                 /* default target */
793
794                                 j = p + code_get_s4(nextp);
795                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
796                                 nextp += 4;
797                                 bound_check(j);
798                                 block_insert(j);
799
800                                 /* lower bound */
801
802                                 j = code_get_s4(nextp);
803                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
804                                 nextp += 4;
805
806                                 /* upper bound */
807
808                                 num = code_get_s4(nextp);
809                                 *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
810                                 nextp += 4;
811
812                                 num -= j;
813
814                                 for (i = 0; i <= num; i++) {
815                                         j = p + code_get_s4(nextp);
816                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
817                                         nextp += 4;
818                                         bound_check(j);
819                                         block_insert(j);
820                                         }
821
822                                 break;
823                                 }
824
825
826                         /* load and store of object fields *******************/
827
828                         case JAVA_AASTORE:
829                                 BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
830                                 break;
831
832                         case JAVA_PUTSTATIC:
833                         case JAVA_GETSTATIC:
834                                 i = code_get_u2(p + 1);
835                                 {
836                                 constant_FMIref *fr;
837                                 fieldinfo *fi;
838                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
839                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
840                                 compiler_addinitclass (fr->class);
841                                 OP2A(opcode, fi->type, fi);
842                                 }
843                                 break;
844                         case JAVA_PUTFIELD:
845                         case JAVA_GETFIELD:
846                                 i = code_get_u2(p + 1);
847                                 {
848                                 constant_FMIref *fr;
849                                 fieldinfo *fi;
850                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
851                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
852                                 OP2A(opcode, fi->type, fi);
853                                 }
854                                 break;
855
856
857                         /* method invocation *****/
858
859                         case JAVA_INVOKESTATIC:
860                                 i = code_get_u2(p + 1);
861                                 {
862                                 constant_FMIref *mr;
863                                 methodinfo *mi;
864                                 
865                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
866                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
867                                         /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
868                                         /*RTAprint*/    {printf(" method name =");
869                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
870                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE STATIC\n");
871                                         /*RTAprint*/    fflush(stdout);}
872                                 if (! (mi->flags & ACC_STATIC))
873                                         panic ("Static/Nonstatic mismatch calling static method");
874                                 descriptor2types(mi);
875                                 isleafmethod=false;
876                                 OP2A(opcode, mi->paramcount, mi);
877                                 }
878                                 break;
879                         case JAVA_INVOKESPECIAL:
880                         case JAVA_INVOKEVIRTUAL:
881                                 i = code_get_u2(p + 1);
882                                 {
883                                 constant_FMIref *mr;
884                                 methodinfo *mi;
885                                 
886                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
887                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
888                                         /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
889                                         /*RTAprint*/    {printf(" method name =");
890                                                         method_display(mi);
891                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
892                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
893                                         /*RTAprint*/    fflush(stdout);}
894
895                                 if (mi->flags & ACC_STATIC)
896                                         panic ("Static/Nonstatic mismatch calling static method");
897                                 descriptor2types(mi);
898                                 isleafmethod=false;
899                                 OP2A(opcode, mi->paramcount, mi);
900                                 }
901                                 break;
902                         case JAVA_INVOKEINTERFACE:
903                                 i = code_get_u2(p + 1);
904                                 {
905                                 constant_FMIref *mr;
906                                 methodinfo *mi;
907                                 
908                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
909                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
910                                 if (mi->flags & ACC_STATIC)
911                                         panic ("Static/Nonstatic mismatch calling static method");
912                                 descriptor2types(mi);
913                                 isleafmethod=false;
914                                 OP2A(opcode, mi->paramcount, mi);
915                                 }
916                                 break;
917
918                         /* miscellaneous object operations *******/
919
920                         case JAVA_NEW:
921                                 i = code_get_u2 (p+1);
922
923                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
924                                 s_count++;
925                                 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
926                                 break;
927
928                         case JAVA_CHECKCAST:
929                                 i = code_get_u2(p+1);
930
931                                 /* array type cast-check */
932                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
933                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
934                                         s_count++;
935                                         BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
936                                         }
937                                 else { /* object type cast-check */
938                                         /*
939                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
940                                         s_count++;
941                                         BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
942                                         */
943                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
944                                         }
945                                 break;
946
947                         case JAVA_INSTANCEOF:
948                                 i = code_get_u2(p+1);
949
950                                 /* array type cast-check */
951                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
952                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
953                                         s_count++;
954 #ifdef __I386__
955                                         BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
956 #else
957                                         BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
958 #endif
959                                         }
960                                 else { /* object type cast-check */
961                                         /*
962                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
963                                         s_count++;
964                                         BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
965                                         */
966                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
967                                         }
968                                 break;
969
970                         case JAVA_MONITORENTER:
971 #ifdef USE_THREADS
972                                 if (checksync) {
973 #ifdef SOFTNULLPTRCHECK
974                                         if (checknull) {
975                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
976                                                 }
977                                         else {
978 /*                                              BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
979                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
980                                                 }
981 #else
982                                         BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
983 #endif
984                                         }
985                                 else
986 #endif
987                                         {
988                                         OP(ICMD_NULLCHECKPOP);
989                                         }
990                                 break;
991
992                         case JAVA_MONITOREXIT:
993 #ifdef USE_THREADS
994                                 if (checksync) {
995                                         BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
996                                         }
997                                 else
998 #endif
999                                         {
1000                                         OP(ICMD_POP);
1001                                         }
1002                                 break;
1003
1004                         /* any other basic operation **************************************/
1005
1006                         case JAVA_IDIV:
1007                                 OP(opcode);
1008                                 break;
1009
1010                         case JAVA_IREM:
1011                                 OP(opcode);
1012                                 break;
1013
1014                         case JAVA_LDIV:
1015                                 OP(opcode);
1016                                 break;
1017
1018                         case JAVA_LREM:
1019                                 OP(opcode);
1020                                 break;
1021
1022                         case JAVA_FREM:
1023 #ifdef __I386__
1024 /*                              BUILTIN2((functionptr) asm_builtin_frem, TYPE_FLOAT); */
1025                                 OP(opcode);
1026 #else
1027                                 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
1028 #endif
1029                                 break;
1030
1031                         case JAVA_DREM:
1032 #ifdef __I386__
1033                                 OP(opcode);
1034 #else
1035                                 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
1036 #endif
1037                                 break;
1038
1039                         case JAVA_F2I:
1040                                 if (checkfloats) {
1041                                         BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
1042                                         }
1043                                 else {
1044                                         OP(opcode);
1045                                         }
1046                                 break;
1047
1048                         case JAVA_F2L:
1049                                 if (checkfloats) {
1050                                         BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
1051                                         }
1052                                 else {
1053                                         OP(opcode);
1054                                         }
1055                                 break;
1056
1057                         case JAVA_D2I:
1058                                 if (checkfloats) {
1059                                         BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
1060                                         }
1061                                 else {
1062                                         OP(opcode);
1063                                         }
1064                                 break;
1065
1066                         case JAVA_D2L:
1067                                 if (checkfloats) {
1068                                         BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
1069                                         }
1070                                 else {
1071                                         OP(opcode);
1072                                         }
1073                                 break;
1074
1075                         case JAVA_BREAKPOINT:
1076                                 panic("Illegal opcode Breakpoint encountered");
1077                                 break;
1078
1079                         case 203:
1080                         case 204:
1081                         case 205:
1082                         case 206:
1083                         case 207:
1084                         case 208:
1085                         case 209:
1086                         case 210:
1087                         case 211:
1088                         case 212:
1089                         case 213:
1090                         case 214:
1091                         case 215:
1092                         case 216:
1093                         case 217:
1094                         case 218:
1095                         case 219:
1096                         case 220:
1097                         case 221:
1098                         case 222:
1099                         case 223:
1100                         case 224:
1101                         case 225:
1102                         case 226:
1103                         case 227:
1104                         case 228:
1105                         case 229:
1106                         case 230:
1107                         case 231:
1108                         case 232:
1109                         case 233:
1110                         case 234:
1111                         case 235:
1112                         case 236:
1113                         case 237:
1114                         case 238:
1115                         case 239:
1116                         case 240:
1117                         case 241:
1118                         case 242:
1119                         case 243:
1120                         case 244:
1121                         case 245:
1122                         case 246:
1123                         case 247:
1124                         case 248:
1125                         case 249:
1126                         case 250:
1127                         case 251:
1128                         case 252:
1129                         case 253:
1130                         case 254:
1131                         case 255:
1132                                 printf("Illegal opcode %d at instr %d", opcode, ipc);
1133                                 panic("encountered");
1134                                 break;
1135
1136                         default:
1137                                 OP(opcode);
1138                                 break;
1139
1140                         } /* end switch */
1141
1142                 } /* end for */
1143
1144         if (p != jcodelength)
1145                 panic("Command-sequence crosses code-boundary");
1146
1147         if (!blockend)
1148                 panic("Code does not end with branch/return/athrow - stmt");    
1149
1150         /* adjust block count if target 0 is not first intermediate instruction   */
1151
1152         if (!block_index[0] || (block_index[0] > 1))
1153                 b_count++;
1154
1155         /* copy local to global variables   */
1156
1157         instr_count = ipc;
1158         block_count = b_count;
1159         stack_count = s_count + block_count * maxstack;
1160
1161         /* allocate stack table */
1162
1163         stack = DMNEW(stackelement, stack_count);
1164
1165         {
1166         basicblock  *bptr;
1167
1168         bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1169
1170         b_count = 0;
1171         c_debug_nr = 0;
1172         
1173         /* additional block if target 0 is not first intermediate instruction     */
1174
1175         if (!block_index[0] || (block_index[0] > 1)) {
1176                 bptr->iinstr = instr;
1177                 bptr->mpc = -1;
1178                 bptr->flags = -1;
1179                 bptr->type = BBTYPE_STD;
1180                 bptr->branchrefs = NULL;
1181                 bptr->pre_count = 0;
1182                 bptr->debug_nr = c_debug_nr++;
1183                 bptr++;
1184                 b_count++;
1185                 (bptr - 1)->next = bptr;
1186         
1187                 }
1188
1189         /* allocate blocks */
1190
1191
1192         for (p = 0; p < jcodelength; p++)
1193                 
1194                 if (block_index[p] & 1) {
1195                         bptr->iinstr = instr + (block_index[p] >> 1);
1196                         bptr->debug_nr = c_debug_nr++;
1197                         if (b_count != 0)
1198                                 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1199                         bptr->mpc = -1;
1200                         bptr->flags = -1;
1201                         bptr->lflags = 0;
1202                         bptr->type = BBTYPE_STD;
1203                         bptr->branchrefs = NULL;
1204                         block_index[p] = b_count;
1205                         bptr->pre_count = 0;
1206                         bptr++;
1207                         b_count++;
1208
1209                         (bptr - 1)->next = bptr;
1210                         }
1211
1212         /* allocate additional block at end */
1213
1214         
1215         bptr->instack = bptr->outstack = NULL;
1216         bptr->indepth = bptr->outdepth = 0;
1217         bptr->iinstr = NULL;
1218         (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1219         bptr->icount = 0;
1220         bptr->mpc = -1;
1221         bptr->flags = -1;
1222         bptr->lflags = 0;
1223         bptr->type = BBTYPE_STD;
1224         bptr->branchrefs = NULL;
1225         bptr->pre_count = 0;
1226         bptr->debug_nr = c_debug_nr++;
1227                         
1228         (bptr - 1)->next = bptr;
1229         bptr->next = NULL;
1230
1231         last_block = bptr;
1232
1233
1234
1235         for (i = 0; i < exceptiontablelength; ++i) {
1236                 p = extable[i].startpc;
1237                 extable[i].start = block + block_index[p];
1238
1239                 p = extable[i].endpc;
1240                 extable[i].end = block + block_index[p]; 
1241
1242                 p = extable[i].handlerpc;
1243                 extable[i].handler = block + block_index[p];
1244             }
1245         }
1246 }
1247
1248 #include "parseRT.h"
1249 #include "parseXTA.h"
1250
1251 /*
1252  * These are local overrides for various environment variables in Emacs.
1253  * Please do not remove this and leave it at the end of the file, where
1254  * Emacs will automagically detect them.
1255  * ---------------------------------------------------------------------
1256  * Local variables:
1257  * mode: c
1258  * indent-tabs-mode: t
1259  * c-basic-offset: 4
1260  * tab-width: 4
1261  * End:
1262  */