*** empty log message ***
[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 384 2003-07-08 21:49:19Z 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                                         nextp = p+3;
488                                         iswide = false;
489                                         }
490                                 OP1(opcode, i);
491                                 break;
492
493                         case JAVA_ILOAD_0:
494                         case JAVA_ILOAD_1:
495                         case JAVA_ILOAD_2:
496                         case JAVA_ILOAD_3:
497                                 OP1(ICMD_ILOAD, opcode - JAVA_ILOAD_0);
498                                 break;
499
500                         case JAVA_LLOAD_0:
501                         case JAVA_LLOAD_1:
502                         case JAVA_LLOAD_2:
503                         case JAVA_LLOAD_3:
504                                 OP1(ICMD_LLOAD, opcode - JAVA_LLOAD_0);
505                                 break;
506
507                         case JAVA_FLOAD_0:
508                         case JAVA_FLOAD_1:
509                         case JAVA_FLOAD_2:
510                         case JAVA_FLOAD_3:
511                                 OP1(ICMD_FLOAD, opcode - JAVA_FLOAD_0);
512                                 break;
513
514                         case JAVA_DLOAD_0:
515                         case JAVA_DLOAD_1:
516                         case JAVA_DLOAD_2:
517                         case JAVA_DLOAD_3:
518                                 OP1(ICMD_DLOAD, opcode - JAVA_DLOAD_0);
519                                 break;
520
521                         case JAVA_ALOAD_0:
522                         case JAVA_ALOAD_1:
523                         case JAVA_ALOAD_2:
524                         case JAVA_ALOAD_3:
525                                 OP1(ICMD_ALOAD, opcode - JAVA_ALOAD_0);
526                                 break;
527
528                         /* storing stack values into local variables */
529
530                         case JAVA_ISTORE:
531                         case JAVA_LSTORE:
532                         case JAVA_FSTORE:
533                         case JAVA_DSTORE:
534                         case JAVA_ASTORE:
535                                 if (!iswide)
536                                         i = code_get_u1(p+1);
537                                 else {
538                                         i = code_get_u2(p+1);
539                                         iswide=false;
540                                         nextp = p+3;
541                                         }
542                                 OP1(opcode, i);
543                                 break;
544
545                         case JAVA_ISTORE_0:
546                         case JAVA_ISTORE_1:
547                         case JAVA_ISTORE_2:
548                         case JAVA_ISTORE_3:
549                                 OP1(ICMD_ISTORE, opcode - JAVA_ISTORE_0);
550                                 break;
551
552                         case JAVA_LSTORE_0:
553                         case JAVA_LSTORE_1:
554                         case JAVA_LSTORE_2:
555                         case JAVA_LSTORE_3:
556                                 OP1(ICMD_LSTORE, opcode - JAVA_LSTORE_0);
557                                 break;
558
559                         case JAVA_FSTORE_0:
560                         case JAVA_FSTORE_1:
561                         case JAVA_FSTORE_2:
562                         case JAVA_FSTORE_3:
563                                 OP1(ICMD_FSTORE, opcode - JAVA_FSTORE_0);
564                                 break;
565
566                         case JAVA_DSTORE_0:
567                         case JAVA_DSTORE_1:
568                         case JAVA_DSTORE_2:
569                         case JAVA_DSTORE_3:
570                                 OP1(ICMD_DSTORE, opcode - JAVA_DSTORE_0);
571                                 break;
572
573                         case JAVA_ASTORE_0:
574                         case JAVA_ASTORE_1:
575                         case JAVA_ASTORE_2:
576                         case JAVA_ASTORE_3:
577                                 OP1(ICMD_ASTORE, opcode - JAVA_ASTORE_0);
578                                 break;
579
580                         case JAVA_IINC:
581                                 {
582                                 int v;
583                                 
584                                 if (!iswide) {
585                                         i = code_get_u1(p + 1);
586                                         v = code_get_s1(p + 2);
587                                         }
588                                 else {
589                                         i = code_get_u2(p + 1);
590                                         v = code_get_s2(p + 3);
591                                         iswide = false;
592                                         nextp = p+5;
593                                         }
594                                 OP2I(opcode, i, v);
595                                 }
596                                 break;
597
598                         /* wider index for loading, storing and incrementing */
599
600                         case JAVA_WIDE:
601                                 iswide = true;
602                                 nextp = p + 1;
603                                 break;
604
605                         /* managing arrays ************************************************/
606
607                         case JAVA_NEWARRAY:
608                                 OP2I(ICMD_CHECKASIZE, 0, 0);
609                                 switch (code_get_s1(p+1)) {
610                                         case 4:
611                                                 BUILTIN1((functionptr)builtin_newarray_boolean, TYPE_ADR);
612                                                 break;
613                                         case 5:
614                                                 BUILTIN1((functionptr)builtin_newarray_char, TYPE_ADR);
615                                                 break;
616                                         case 6:
617                                                 BUILTIN1((functionptr)builtin_newarray_float, TYPE_ADR);
618                                                 break;
619                                         case 7:
620                                                 BUILTIN1((functionptr)builtin_newarray_double, TYPE_ADR);
621                                                 break;
622                                         case 8:
623                                                 BUILTIN1((functionptr)builtin_newarray_byte, TYPE_ADR);
624                                                 break;
625                                         case 9:
626                                                 BUILTIN1((functionptr)builtin_newarray_short, TYPE_ADR);
627                                                 break;
628                                         case 10:
629                                                 BUILTIN1((functionptr)builtin_newarray_int, TYPE_ADR);
630                                                 break;
631                                         case 11:
632                                                 BUILTIN1((functionptr)builtin_newarray_long, TYPE_ADR);
633                                                 break;
634                                         default: panic("Invalid array-type to create");
635                                         }
636                                 break;
637
638                         case JAVA_ANEWARRAY:
639                                 OP2I(ICMD_CHECKASIZE, 0, 0);
640                                 i = code_get_u2(p+1);
641                                 /* array or class type ? */
642                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
643                                         s_count++;
644                                         LOADCONST_A(class_getconstant(class, i,
645                                                                       CONSTANT_Arraydescriptor));
646 #ifdef __I386__
647                                         BUILTIN2((functionptr) asm_builtin_newarray_array, TYPE_ADR);
648 #else
649                                         BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
650 #endif
651                                         }
652                                 else {
653                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
654                                         s_count++;
655 #ifdef __I386__
656                                         BUILTIN2((functionptr) asm_builtin_anewarray, TYPE_ADR);
657 #else
658                                         BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
659 #endif
660                                         }
661                                 break;
662
663                         case JAVA_MULTIANEWARRAY:
664                                 isleafmethod=false;
665                                 i = code_get_u2(p+1);
666                                 {
667                                 int v = code_get_u1(p+3);
668                                 constant_arraydescriptor *desc =
669                                     class_getconstant (class, i, CONSTANT_Arraydescriptor);
670                                 OP2A(opcode, v, desc);
671                                 }
672                                 break;
673
674                         case JAVA_IFEQ:
675                         case JAVA_IFLT:
676                         case JAVA_IFLE:
677                         case JAVA_IFNE:
678                         case JAVA_IFGT:
679                         case JAVA_IFGE:
680                         case JAVA_IFNULL:
681                         case JAVA_IFNONNULL:
682                         case JAVA_IF_ICMPEQ:
683                         case JAVA_IF_ICMPNE:
684                         case JAVA_IF_ICMPLT:
685                         case JAVA_IF_ICMPGT:
686                         case JAVA_IF_ICMPLE:
687                         case JAVA_IF_ICMPGE:
688                         case JAVA_IF_ACMPEQ:
689                         case JAVA_IF_ACMPNE:
690                         case JAVA_GOTO:
691                         case JAVA_JSR:
692                                 i = p + code_get_s2(p+1);
693                                 bound_check(i);
694                                 block_insert(i);
695                                 blockend = true;
696                                 OP1(opcode, i);
697                                 break;
698                         case JAVA_GOTO_W:
699                         case JAVA_JSR_W:
700                                 i = p + code_get_s4(p+1);
701                                 bound_check(i);
702                                 block_insert(i);
703                                 blockend = true;
704                                 OP1(opcode, i);
705                                 break;
706
707                         case JAVA_RET:
708                                 if (!iswide)
709                                         i = code_get_u1(p+1);
710                                 else {
711                                         i = code_get_u2(p+1);
712                                         nextp = p+3;
713                                         iswide = false;
714                                         }
715                                 blockend = true;
716                                 OP1(opcode, i);
717                                 break;
718
719                         case JAVA_IRETURN:
720                         case JAVA_LRETURN:
721                         case JAVA_FRETURN:
722                         case JAVA_DRETURN:
723                         case JAVA_ARETURN:
724                         case JAVA_RETURN:
725                                 blockend = true;
726                                 OP(opcode);
727                                 break;
728
729                         case JAVA_ATHROW:
730                                 blockend = true;
731                                 OP(opcode);
732                                 break;
733                                 
734
735                         /* table jumps ********************************/
736
737                         case JAVA_LOOKUPSWITCH:
738                                 {
739                                 s4 num, j;
740
741                                 blockend = true;
742                                 nextp = ALIGN((p + 1), 4);
743                                 OP2A(opcode, 0, jcode + nextp);
744
745                                 /* default target */
746
747                                 j =  p + code_get_s4(nextp);
748                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
749                                 nextp += 4;
750                                 bound_check(j);
751                                 block_insert(j);
752
753                                 /* number of pairs */
754
755                                 num = code_get_u4(nextp);
756                                 *((s4*)(jcode + nextp)) = num;
757                                 nextp += 4;
758
759                                 for (i = 0; i < num; i++) {
760
761                                         /* value */
762
763                                         j = code_get_s4(nextp);
764                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
765                                         nextp += 4;
766
767                                         /* target */
768
769                                         j = p + code_get_s4(nextp);
770                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
771                                         nextp += 4;
772                                         bound_check(j);
773                                         block_insert(j);
774                                         }
775
776                                 break;
777                                 }
778
779
780                         case JAVA_TABLESWITCH:
781                                 {
782                                 s4 num, j;
783
784                                 blockend = true;
785                                 nextp = ALIGN((p + 1), 4);
786                                 OP2A(opcode, 0, jcode + nextp);
787
788                                 /* default target */
789
790                                 j = p + code_get_s4(nextp);
791                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
792                                 nextp += 4;
793                                 bound_check(j);
794                                 block_insert(j);
795
796                                 /* lower bound */
797
798                                 j = code_get_s4(nextp);
799                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
800                                 nextp += 4;
801
802                                 /* upper bound */
803
804                                 num = code_get_s4(nextp);
805                                 *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
806                                 nextp += 4;
807
808                                 num -= j;
809
810                                 for (i = 0; i <= num; i++) {
811                                         j = p + code_get_s4(nextp);
812                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
813                                         nextp += 4;
814                                         bound_check(j);
815                                         block_insert(j);
816                                         }
817
818                                 break;
819                                 }
820
821
822                         /* load and store of object fields *******************/
823
824                         case JAVA_AASTORE:
825                                 BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
826                                 break;
827
828                         case JAVA_PUTSTATIC:
829                         case JAVA_GETSTATIC:
830                                 i = code_get_u2(p + 1);
831                                 {
832                                 constant_FMIref *fr;
833                                 fieldinfo *fi;
834                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
835                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
836                                 compiler_addinitclass (fr->class);
837                                 OP2A(opcode, fi->type, fi);
838                                 }
839                                 break;
840                         case JAVA_PUTFIELD:
841                         case JAVA_GETFIELD:
842                                 i = code_get_u2(p + 1);
843                                 {
844                                 constant_FMIref *fr;
845                                 fieldinfo *fi;
846                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
847                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
848                                 OP2A(opcode, fi->type, fi);
849                                 }
850                                 break;
851
852
853                         /* method invocation *****/
854
855                         case JAVA_INVOKESTATIC:
856                                 i = code_get_u2(p + 1);
857                                 {
858                                 constant_FMIref *mr;
859                                 methodinfo *mi;
860                                 
861                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
862                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
863                                         /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
864                                         /*RTAprint*/    {printf(" method name =");
865                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
866                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE STATIC\n");
867                                         /*RTAprint*/    fflush(stdout);}
868                                 if (! (mi->flags & ACC_STATIC))
869                                         panic ("Static/Nonstatic mismatch calling static method");
870                                 descriptor2types(mi);
871                                 isleafmethod=false;
872                                 OP2A(opcode, mi->paramcount, mi);
873                                 }
874                                 break;
875                         case JAVA_INVOKESPECIAL:
876                         case JAVA_INVOKEVIRTUAL:
877                                 i = code_get_u2(p + 1);
878                                 {
879                                 constant_FMIref *mr;
880                                 methodinfo *mi;
881                                 
882                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
883                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
884                                         /*RTAprint*/ if (((pOpcodes == 2) || (pOpcodes == 3)) && opt_rt)
885                                         /*RTAprint*/    {printf(" method name =");
886                                                         method_display(mi);
887                                         /*RTAprint*/    utf_display(mi->class->name); printf(".");
888                                         /*RTAprint*/    utf_display(mi->name);printf("\tINVOKE SPECIAL/VIRTUAL\n");
889                                         /*RTAprint*/    fflush(stdout);}
890
891                                 if (mi->flags & ACC_STATIC)
892                                         panic ("Static/Nonstatic mismatch calling static method");
893                                 descriptor2types(mi);
894                                 isleafmethod=false;
895                                 OP2A(opcode, mi->paramcount, mi);
896                                 }
897                                 break;
898                         case JAVA_INVOKEINTERFACE:
899                                 i = code_get_u2(p + 1);
900                                 {
901                                 constant_FMIref *mr;
902                                 methodinfo *mi;
903                                 
904                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
905                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
906                                 if (mi->flags & ACC_STATIC)
907                                         panic ("Static/Nonstatic mismatch calling static method");
908                                 descriptor2types(mi);
909                                 isleafmethod=false;
910                                 OP2A(opcode, mi->paramcount, mi);
911                                 }
912                                 break;
913
914                         /* miscellaneous object operations *******/
915
916                         case JAVA_NEW:
917                                 i = code_get_u2 (p+1);
918
919                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
920                                 s_count++;
921                                 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
922                                 break;
923
924                         case JAVA_CHECKCAST:
925                                 i = code_get_u2(p+1);
926
927                                 /* array type cast-check */
928                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
929                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
930                                         s_count++;
931                                         BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
932                                         }
933                                 else { /* object type cast-check */
934                                         /*
935                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
936                                         s_count++;
937                                         BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
938                                         */
939                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
940                                         }
941                                 break;
942
943                         case JAVA_INSTANCEOF:
944                                 i = code_get_u2(p+1);
945
946                                 /* array type cast-check */
947                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
948                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
949                                         s_count++;
950 #ifdef __I386__
951                                         BUILTIN2((functionptr) asm_builtin_arrayinstanceof, TYPE_INT);
952 #else
953                                         BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
954 #endif
955                                         }
956                                 else { /* object type cast-check */
957                                         /*
958                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
959                                         s_count++;
960                                         BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
961                                         */
962                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
963                                         }
964                                 break;
965
966                         case JAVA_MONITORENTER:
967 #ifdef USE_THREADS
968                                 if (checksync) {
969 #ifdef SOFTNULLPTRCHECK
970                                         if (checknull) {
971                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
972                                                 }
973                                         else {
974 /*                                              BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
975                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
976                                                 }
977 #else
978                                         BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
979 #endif
980                                         }
981                                 else
982 #endif
983                                         {
984                                         OP(ICMD_NULLCHECKPOP);
985                                         }
986                                 break;
987
988                         case JAVA_MONITOREXIT:
989 #ifdef USE_THREADS
990                                 if (checksync) {
991                                         BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
992                                         }
993                                 else
994 #endif
995                                         {
996                                         OP(ICMD_POP);
997                                         }
998                                 break;
999
1000                         /* any other basic operation **************************************/
1001
1002                         case JAVA_IDIV:
1003                                 OP(opcode);
1004                                 break;
1005
1006                         case JAVA_IREM:
1007                                 OP(opcode);
1008                                 break;
1009
1010                         case JAVA_LDIV:
1011                                 OP(opcode);
1012                                 break;
1013
1014                         case JAVA_LREM:
1015                                 OP(opcode);
1016                                 break;
1017
1018                         case JAVA_FREM:
1019 #ifdef __I386__
1020 /*                              BUILTIN2((functionptr) asm_builtin_frem, TYPE_FLOAT); */
1021                                 OP(opcode);
1022 #else
1023                                 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
1024 #endif
1025                                 break;
1026
1027                         case JAVA_DREM:
1028 #ifdef __I386__
1029                                 OP(opcode);
1030 #else
1031                                 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
1032 #endif
1033                                 break;
1034
1035                         case JAVA_F2I:
1036                                 if (checkfloats) {
1037                                         BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
1038                                         }
1039                                 else {
1040                                         OP(opcode);
1041                                         }
1042                                 break;
1043
1044                         case JAVA_F2L:
1045                                 if (checkfloats) {
1046                                         BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
1047                                         }
1048                                 else {
1049                                         OP(opcode);
1050                                         }
1051                                 break;
1052
1053                         case JAVA_D2I:
1054                                 if (checkfloats) {
1055                                         BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
1056                                         }
1057                                 else {
1058                                         OP(opcode);
1059                                         }
1060                                 break;
1061
1062                         case JAVA_D2L:
1063                                 if (checkfloats) {
1064                                         BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
1065                                         }
1066                                 else {
1067                                         OP(opcode);
1068                                         }
1069                                 break;
1070
1071                         case JAVA_BREAKPOINT:
1072                                 panic("Illegal opcode Breakpoint encountered");
1073                                 break;
1074
1075                         case 203:
1076                         case 204:
1077                         case 205:
1078                         case 206:
1079                         case 207:
1080                         case 208:
1081                         case 209:
1082                         case 210:
1083                         case 211:
1084                         case 212:
1085                         case 213:
1086                         case 214:
1087                         case 215:
1088                         case 216:
1089                         case 217:
1090                         case 218:
1091                         case 219:
1092                         case 220:
1093                         case 221:
1094                         case 222:
1095                         case 223:
1096                         case 224:
1097                         case 225:
1098                         case 226:
1099                         case 227:
1100                         case 228:
1101                         case 229:
1102                         case 230:
1103                         case 231:
1104                         case 232:
1105                         case 233:
1106                         case 234:
1107                         case 235:
1108                         case 236:
1109                         case 237:
1110                         case 238:
1111                         case 239:
1112                         case 240:
1113                         case 241:
1114                         case 242:
1115                         case 243:
1116                         case 244:
1117                         case 245:
1118                         case 246:
1119                         case 247:
1120                         case 248:
1121                         case 249:
1122                         case 250:
1123                         case 251:
1124                         case 252:
1125                         case 253:
1126                         case 254:
1127                         case 255:
1128                                 printf("Illegal opcode %d at instr %d", opcode, ipc);
1129                                 panic("encountered");
1130                                 break;
1131
1132                         default:
1133                                 OP(opcode);
1134                                 break;
1135
1136                         } /* end switch */
1137
1138                 } /* end for */
1139
1140         if (p != jcodelength)
1141                 panic("Command-sequence crosses code-boundary");
1142
1143         if (!blockend)
1144                 panic("Code does not end with branch/return/athrow - stmt");    
1145
1146         /* adjust block count if target 0 is not first intermediate instruction   */
1147
1148         if (!block_index[0] || (block_index[0] > 1))
1149                 b_count++;
1150
1151         /* copy local to global variables   */
1152
1153         instr_count = ipc;
1154         block_count = b_count;
1155         stack_count = s_count + block_count * maxstack;
1156
1157         /* allocate stack table */
1158
1159         stack = DMNEW(stackelement, stack_count);
1160
1161         {
1162         basicblock  *bptr;
1163
1164         bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1165
1166         b_count = 0;
1167         c_debug_nr = 0;
1168         
1169         /* additional block if target 0 is not first intermediate instruction     */
1170
1171         if (!block_index[0] || (block_index[0] > 1)) {
1172                 bptr->iinstr = instr;
1173                 bptr->mpc = -1;
1174                 bptr->flags = -1;
1175                 bptr->type = BBTYPE_STD;
1176                 bptr->branchrefs = NULL;
1177                 bptr->pre_count = 0;
1178                 bptr->debug_nr = c_debug_nr++;
1179                 bptr++;
1180                 b_count++;
1181                 (bptr - 1)->next = bptr;
1182         
1183                 }
1184
1185         /* allocate blocks */
1186
1187
1188         for (p = 0; p < jcodelength; p++)
1189                 
1190                 if (block_index[p] & 1) {
1191                         bptr->iinstr = instr + (block_index[p] >> 1);
1192                         bptr->debug_nr = c_debug_nr++;
1193                         if (b_count != 0)
1194                                 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1195                         bptr->mpc = -1;
1196                         bptr->flags = -1;
1197                         bptr->lflags = 0;
1198                         bptr->type = BBTYPE_STD;
1199                         bptr->branchrefs = NULL;
1200                         block_index[p] = b_count;
1201                         bptr->pre_count = 0;
1202                         bptr++;
1203                         b_count++;
1204
1205                         (bptr - 1)->next = bptr;
1206                         }
1207
1208         /* allocate additional block at end */
1209
1210         
1211         bptr->instack = bptr->outstack = NULL;
1212         bptr->indepth = bptr->outdepth = 0;
1213         bptr->iinstr = NULL;
1214         (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1215         bptr->icount = 0;
1216         bptr->mpc = -1;
1217         bptr->flags = -1;
1218         bptr->lflags = 0;
1219         bptr->type = BBTYPE_STD;
1220         bptr->branchrefs = NULL;
1221         bptr->pre_count = 0;
1222         bptr->debug_nr = c_debug_nr++;
1223                         
1224         (bptr - 1)->next = bptr;
1225         bptr->next = NULL;
1226
1227         last_block = bptr;
1228
1229
1230
1231         for (i = 0; i < exceptiontablelength; ++i) {
1232                 p = extable[i].startpc;
1233                 extable[i].start = block + block_index[p];
1234
1235                 p = extable[i].endpc;
1236                 extable[i].end = block + block_index[p]; 
1237
1238                 p = extable[i].handlerpc;
1239                 extable[i].handler = block + block_index[p];
1240             }
1241         }
1242 }
1243
1244 #include "parseRT.h"
1245 #include "parseXTA.h"
1246
1247 /*
1248  * These are local overrides for various environment variables in Emacs.
1249  * Please do not remove this and leave it at the end of the file, where
1250  * Emacs will automagically detect them.
1251  * ---------------------------------------------------------------------
1252  * Local variables:
1253  * mode: c
1254  * indent-tabs-mode: t
1255  * c-basic-offset: 4
1256  * tab-width: 4
1257  * End:
1258  */