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