Added documentation for java.net.
[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 139 1999-11-11 19:21:30Z andi $
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                                         s_count++;
609                                         LOADCONST_A(class_getconstant(class, i,
610                                                                       CONSTANT_Arraydescriptor));
611                                         BUILTIN2((functionptr)builtin_newarray_array, TYPE_ADR);
612                                         }
613                                 else {
614                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
615                                         s_count++;
616                                         BUILTIN2((functionptr)builtin_anewarray, TYPE_ADR);
617                                         }
618                                 break;
619
620                         case JAVA_MULTIANEWARRAY:
621                                 isleafmethod=false;
622                                 i = code_get_u2(p+1);
623                                 {
624                                 int v = code_get_u1(p+3);
625                                 constant_arraydescriptor *desc =
626                                     class_getconstant (class, i, CONSTANT_Arraydescriptor);
627                                 OP2A(opcode, v, desc);
628                                 }
629                                 break;
630
631                         case JAVA_IFEQ:
632                         case JAVA_IFLT:
633                         case JAVA_IFLE:
634                         case JAVA_IFNE:
635                         case JAVA_IFGT:
636                         case JAVA_IFGE:
637                         case JAVA_IFNULL:
638                         case JAVA_IFNONNULL:
639                         case JAVA_IF_ICMPEQ:
640                         case JAVA_IF_ICMPNE:
641                         case JAVA_IF_ICMPLT:
642                         case JAVA_IF_ICMPGT:
643                         case JAVA_IF_ICMPLE:
644                         case JAVA_IF_ICMPGE:
645                         case JAVA_IF_ACMPEQ:
646                         case JAVA_IF_ACMPNE:
647                         case JAVA_GOTO:
648                         case JAVA_JSR:
649                                 i = p + code_get_s2(p+1);
650                                 bound_check(i);
651                                 block_insert(i);
652                                 blockend = true;
653                                 OP1(opcode, i);
654                                 break;
655                         case JAVA_GOTO_W:
656                         case JAVA_JSR_W:
657                                 i = p + code_get_s4(p+1);
658                                 bound_check(i);
659                                 block_insert(i);
660                                 blockend = true;
661                                 OP1(opcode, i);
662                                 break;
663
664                         case JAVA_RET:
665                                 if (!iswide)
666                                         i = code_get_u1(p+1);
667                                 else {
668                                         i = code_get_u2(p+1);
669                                         nextp = p+3;
670                                         iswide = false;
671                                         }
672                                 blockend = true;
673                                 OP1(opcode, i);
674                                 break;
675
676                         case JAVA_IRETURN:
677                         case JAVA_LRETURN:
678                         case JAVA_FRETURN:
679                         case JAVA_DRETURN:
680                         case JAVA_ARETURN:
681                         case JAVA_RETURN:
682                                 blockend = true;
683                                 OP(opcode);
684                                 break;
685
686                         case JAVA_ATHROW:
687                                 blockend = true;
688                                 OP(opcode);
689                                 break;
690                                 
691
692                         /* table jumps ********************************/
693
694                         case JAVA_LOOKUPSWITCH:
695                                 {
696                                 s4 num, j;
697
698                                 blockend = true;
699                                 nextp = ALIGN((p + 1), 4);
700                                 OP2A(opcode, 0, jcode + nextp);
701
702                                 /* default target */
703
704                                 j =  p + code_get_s4(nextp);
705                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
706                                 nextp += 4;
707                                 bound_check(j);
708                                 block_insert(j);
709
710                                 /* number of pairs */
711
712                                 num = code_get_u4(nextp);
713                                 *((s4*)(jcode + nextp)) = num;
714                                 nextp += 4;
715
716                                 for (i = 0; i < num; i++) {
717
718                                         /* value */
719
720                                         j = code_get_s4(nextp);
721                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
722                                         nextp += 4;
723
724                                         /* target */
725
726                                         j = p + code_get_s4(nextp);
727                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
728                                         nextp += 4;
729                                         bound_check(j);
730                                         block_insert(j);
731                                         }
732
733                                 break;
734                                 }
735
736
737                         case JAVA_TABLESWITCH:
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                                 /* lower bound */
754
755                                 j = code_get_s4(nextp);
756                                 *((s4*)(jcode + nextp)) = j;     /* restore for little endian */
757                                 nextp += 4;
758
759                                 /* upper bound */
760
761                                 num = code_get_s4(nextp);
762                                 *((s4*)(jcode + nextp)) = num;   /* restore for little endian */
763                                 nextp += 4;
764
765                                 num -= j;
766
767                                 for (i = 0; i <= num; i++) {
768                                         j = p + code_get_s4(nextp);
769                                         *((s4*)(jcode + nextp)) = j; /* restore for little endian */
770                                         nextp += 4;
771                                         bound_check(j);
772                                         block_insert(j);
773                                         }
774
775                                 break;
776                                 }
777
778
779                         /* load and store of object fields *******************/
780
781                         case JAVA_AASTORE:
782                                 BUILTIN3((functionptr) asm_builtin_aastore, TYPE_VOID);
783                                 break;
784
785                         case JAVA_PUTSTATIC:
786                         case JAVA_GETSTATIC:
787                                 i = code_get_u2(p + 1);
788                                 {
789                                 constant_FMIref *fr;
790                                 fieldinfo *fi;
791                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
792                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
793                                 compiler_addinitclass (fr->class);
794                                 OP2A(opcode, fi->type, fi);
795                                 }
796                                 break;
797                         case JAVA_PUTFIELD:
798                         case JAVA_GETFIELD:
799                                 i = code_get_u2(p + 1);
800                                 {
801                                 constant_FMIref *fr;
802                                 fieldinfo *fi;
803                                 fr = class_getconstant (class, i, CONSTANT_Fieldref);
804                                 fi = class_findfield (fr->class, fr->name, fr->descriptor);
805                                 OP2A(opcode, fi->type, fi);
806                                 }
807                                 break;
808
809
810                         /* method invocation *****/
811
812                         case JAVA_INVOKESTATIC:
813                                 i = code_get_u2(p + 1);
814                                 {
815                                 constant_FMIref *mr;
816                                 methodinfo *mi;
817                                 
818                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
819                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
820                                 if (! (mi->flags & ACC_STATIC))
821                                         panic ("Static/Nonstatic mismatch calling static method");
822                                 descriptor2types(mi);
823                                 isleafmethod=false;
824                                 OP2A(opcode, mi->paramcount, mi);
825                                 }
826                                 break;
827                         case JAVA_INVOKESPECIAL:
828                         case JAVA_INVOKEVIRTUAL:
829                                 i = code_get_u2(p + 1);
830                                 {
831                                 constant_FMIref *mr;
832                                 methodinfo *mi;
833                                 
834                                 mr = class_getconstant (class, i, CONSTANT_Methodref);
835                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
836                                 if (mi->flags & ACC_STATIC)
837                                         panic ("Static/Nonstatic mismatch calling static method");
838                                 descriptor2types(mi);
839                                 isleafmethod=false;
840                                 OP2A(opcode, mi->paramcount, mi);
841                                 }
842                                 break;
843                         case JAVA_INVOKEINTERFACE:
844                                 i = code_get_u2(p + 1);
845                                 {
846                                 constant_FMIref *mr;
847                                 methodinfo *mi;
848                                 
849                                 mr = class_getconstant (class, i, CONSTANT_InterfaceMethodref);
850                                 mi = class_findmethod (mr->class, mr->name, mr->descriptor);
851                                 if (mi->flags & ACC_STATIC)
852                                         panic ("Static/Nonstatic mismatch calling static method");
853                                 descriptor2types(mi);
854                                 isleafmethod=false;
855                                 OP2A(opcode, mi->paramcount, mi);
856                                 }
857                                 break;
858
859                         /* miscellaneous object operations *******/
860
861                         case JAVA_NEW:
862                                 i = code_get_u2 (p+1);
863                                 LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
864                                 s_count++;
865                                 BUILTIN1((functionptr) builtin_new, TYPE_ADR);
866                                 break;
867
868                         case JAVA_CHECKCAST:
869                                 i = code_get_u2(p+1);
870
871                                 /* array type cast-check */
872                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
873                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
874                                         s_count++;
875                                         BUILTIN2((functionptr) asm_builtin_checkarraycast, TYPE_ADR);
876                                         }
877                                 else { /* object type cast-check */
878                                         /*
879                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
880                                         s_count++;
881                                         BUILTIN2((functionptr) asm_builtin_checkcast, TYPE_ADR);
882                                         */
883                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
884                                         }
885                                 break;
886
887                         case JAVA_INSTANCEOF:
888                                 i = code_get_u2(p+1);
889
890                                 /* array type cast-check */
891                                 if (class_constanttype (class, i) == CONSTANT_Arraydescriptor) {
892                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Arraydescriptor));
893                                         s_count++;
894                                         BUILTIN2((functionptr) builtin_arrayinstanceof, TYPE_INT);
895                                         }
896                                 else { /* object type cast-check */
897                                         /*
898                                         LOADCONST_A(class_getconstant(class, i, CONSTANT_Class));
899                                         s_count++;
900                                         BUILTIN2((functionptr) builtin_instanceof, TYPE_INT);
901                                         */
902                                         OP2A(opcode, 1, (class_getconstant(class, i, CONSTANT_Class)));
903                                         }
904                                 break;
905
906                         case JAVA_MONITORENTER:
907 #ifdef USE_THREADS
908                                 if (checksync) {
909 #ifdef SOFTNULLPTRCHECK
910                                         if (checknull) {
911                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
912                                                 }
913                                         else {
914 /*                                              BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID); */
915                                                 BUILTIN1((functionptr) asm_builtin_monitorenter, TYPE_VOID);
916                                                 }
917 #else
918                                         BUILTIN1((functionptr) builtin_monitorenter, TYPE_VOID);
919 #endif
920                                         }
921                                 else
922 #endif
923                                         {
924                                         OP(ICMD_NULLCHECKPOP);
925                                         }
926                                 break;
927
928                         case JAVA_MONITOREXIT:
929 #ifdef USE_THREADS
930                                 if (checksync) {
931                                         BUILTIN1((functionptr) builtin_monitorexit, TYPE_VOID);
932                                         }
933                                 else
934 #endif
935                                         {
936                                         OP(ICMD_POP);
937                                         }
938                                 break;
939
940                         /* any other basic operation **************************************/
941
942                         case JAVA_IDIV:
943                                 OP(opcode);
944                                 break;
945
946                         case JAVA_IREM:
947                                 OP(opcode);
948                                 break;
949
950                         case JAVA_LDIV:
951                                 OP(opcode);
952                                 break;
953
954                         case JAVA_LREM:
955                                 OP(opcode);
956                                 break;
957
958                         case JAVA_FREM:
959                                 BUILTIN2((functionptr) builtin_frem, TYPE_FLOAT);
960                                 break;
961
962                         case JAVA_DREM:
963                                 BUILTIN2((functionptr) builtin_drem, TYPE_DOUBLE);
964                                 break;
965
966                         case JAVA_F2I:
967                                 if (checkfloats) {
968                                         BUILTIN1((functionptr) builtin_f2i, TYPE_INT);
969                                         }
970                                 else {
971                                         OP(opcode);
972                                         }
973                                 break;
974
975                         case JAVA_F2L:
976                                 if (checkfloats) {
977                                         BUILTIN1((functionptr) builtin_f2l, TYPE_LONG);
978                                         }
979                                 else {
980                                         OP(opcode);
981                                         }
982                                 break;
983
984                         case JAVA_D2I:
985                                 if (checkfloats) {
986                                         BUILTIN1((functionptr) builtin_d2i, TYPE_INT);
987                                         }
988                                 else {
989                                         OP(opcode);
990                                         }
991                                 break;
992
993                         case JAVA_D2L:
994                                 if (checkfloats) {
995                                         BUILTIN1((functionptr) builtin_d2l, TYPE_LONG);
996                                         }
997                                 else {
998                                         OP(opcode);
999                                         }
1000                                 break;
1001
1002                         case JAVA_BREAKPOINT:
1003                                 panic("Illegal opcode Breakpoint encountered");
1004                                 break;
1005
1006                         case 203:
1007                         case 204:
1008                         case 205:
1009                         case 206:
1010                         case 207:
1011                         case 208:
1012                         case 209:
1013                         case 210:
1014                         case 211:
1015                         case 212:
1016                         case 213:
1017                         case 214:
1018                         case 215:
1019                         case 216:
1020                         case 217:
1021                         case 218:
1022                         case 219:
1023                         case 220:
1024                         case 221:
1025                         case 222:
1026                         case 223:
1027                         case 224:
1028                         case 225:
1029                         case 226:
1030                         case 227:
1031                         case 228:
1032                         case 229:
1033                         case 230:
1034                         case 231:
1035                         case 232:
1036                         case 233:
1037                         case 234:
1038                         case 235:
1039                         case 236:
1040                         case 237:
1041                         case 238:
1042                         case 239:
1043                         case 240:
1044                         case 241:
1045                         case 242:
1046                         case 243:
1047                         case 244:
1048                         case 245:
1049                         case 246:
1050                         case 247:
1051                         case 248:
1052                         case 249:
1053                         case 250:
1054                         case 251:
1055                         case 252:
1056                         case 253:
1057                         case 254:
1058                         case 255:
1059                                 printf("Illegal opcode %d at instr %d", opcode, ipc);
1060                                 panic("encountered");
1061                                 break;
1062
1063                         default:
1064                                 OP(opcode);
1065                                 break;
1066
1067                         } /* end switch */
1068
1069                 } /* end for */
1070
1071         if (p != jcodelength)
1072                 panic("Command-sequence crosses code-boundary");
1073
1074         if (!blockend)
1075                 panic("Code does not end with branch/return/athrow - stmt");    
1076
1077         /* adjust block count if target 0 is not first intermediate instruction   */
1078
1079         if (!block_index[0] || (block_index[0] > 1))
1080                 b_count++;
1081
1082         /* copy local to global variables   */
1083
1084         instr_count = ipc;
1085         block_count = b_count;
1086         stack_count = s_count + block_count * maxstack;
1087
1088         /* allocate stack table */
1089
1090         stack = DMNEW(stackelement, stack_count);
1091
1092         {
1093         basicblock  *bptr;
1094
1095         bptr = block = DMNEW(basicblock, b_count + 1);    /* one more for end ipc */
1096
1097         b_count = 0;
1098         c_debug_nr = 0;
1099         
1100         /* additional block if target 0 is not first intermediate instruction     */
1101
1102         if (!block_index[0] || (block_index[0] > 1)) {
1103                 bptr->iinstr = instr;
1104                 bptr->mpc = -1;
1105                 bptr->flags = -1;
1106                 bptr->type = BBTYPE_STD;
1107                 bptr->branchrefs = NULL;
1108                 bptr->pre_count = 0;
1109                 bptr->debug_nr = c_debug_nr++;
1110                 bptr++;
1111                 b_count++;
1112                 (bptr - 1)->next = bptr;
1113         
1114                 }
1115
1116         /* allocate blocks */
1117
1118
1119         for (p = 0; p < jcodelength; p++)
1120                 
1121                 if (block_index[p] & 1) {
1122                         bptr->iinstr = instr + (block_index[p] >> 1);
1123                         bptr->debug_nr = c_debug_nr++;
1124                         if (b_count != 0)
1125                                 (bptr - 1)->icount = bptr->iinstr - (bptr - 1)->iinstr;
1126                         bptr->mpc = -1;
1127                         bptr->flags = -1;
1128                         bptr->lflags = 0;
1129                         bptr->type = BBTYPE_STD;
1130                         bptr->branchrefs = NULL;
1131                         block_index[p] = b_count;
1132                         bptr->pre_count = 0;
1133                         bptr++;
1134                         b_count++;
1135
1136                         (bptr - 1)->next = bptr;
1137                         }
1138
1139         /* allocate additional block at end */
1140
1141         
1142         bptr->instack = bptr->outstack = NULL;
1143         bptr->indepth = bptr->outdepth = 0;
1144         bptr->iinstr = NULL;
1145         (bptr - 1)->icount = (instr + instr_count) - (bptr - 1)->iinstr;
1146         bptr->icount = 0;
1147         bptr->mpc = -1;
1148         bptr->flags = -1;
1149         bptr->lflags = 0;
1150         bptr->type = BBTYPE_STD;
1151         bptr->branchrefs = NULL;
1152         bptr->pre_count = 0;
1153         bptr->debug_nr = c_debug_nr++;
1154                         
1155         (bptr - 1)->next = bptr;
1156         bptr->next = NULL;
1157
1158         last_block = bptr;
1159
1160
1161
1162         for (i = 0; i < exceptiontablelength; ++i) {
1163                 p = extable[i].startpc;
1164                 extable[i].start = block + block_index[p];
1165
1166                 p = extable[i].endpc;
1167                 extable[i].end = block + block_index[p]; 
1168
1169                 p = extable[i].handlerpc;
1170                 extable[i].handler = block + block_index[p];
1171             }
1172         }
1173 }
1174
1175
1176 /*
1177  * These are local overrides for various environment variables in Emacs.
1178  * Please do not remove this and leave it at the end of the file, where
1179  * Emacs will automagically detect them.
1180  * ---------------------------------------------------------------------
1181  * Local variables:
1182  * mode: c
1183  * indent-tabs-mode: t
1184  * c-basic-offset: 4
1185  * tab-width: 4
1186  * End:
1187  */