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