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