Initial revision
[cacao.git] / ncomp / nreg.c
1 /******************************* comp/reg.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         The register-manager.
8
9         Authors:  Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
10                   Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
11
12         Last Change: 1997/10/23
13
14 *******************************************************************************/
15
16 static varinfo5 *locals;
17 static varinfo5 *interfaces;
18
19 static int intregsnum;              /* absolute number of integer registers   */
20 static int floatregsnum;            /* absolute number of float registers     */ 
21
22 static int intreg_ret;              /* register to return integer values      */
23 static int intreg_argnum;           /* number of integer argument registers   */
24
25 static int floatreg_ret;            /* register for return float values       */
26 static int fltreg_argnum;           /* number of float argument registers     */
27
28
29 static int *argintregs;             /* scratch integer registers              */
30 static int *tmpintregs = NULL;      /* scratch integer registers              */
31 static int *savintregs;             /* saved integer registers                */
32 static int *argfltregs;             /* scratch float registers                */
33 static int *tmpfltregs;             /* scratch float registers                */
34 static int *savfltregs;             /* saved float registers                  */
35 static int *freetmpintregs;         /* free scratch integer registers         */
36 static int *freesavintregs;         /* free saved integer registers           */
37 static int *freetmpfltregs;         /* free scratch float registers           */
38 static int *freesavfltregs;         /* free saved float registers             */
39
40 static int *freemem;                /* free scratch memory                    */
41 static int memuse;                  /* used memory count                      */
42 static int ifmemuse;                /* interface used memory count            */
43 static int maxmemuse;               /* maximal used memory count (spills)     */
44 static int freememtop;              /* free memory count                      */
45
46 static int tmpintregcnt;            /* scratch integer register count         */
47 static int savintregcnt;            /* saved integer register count           */
48 static int tmpfltregcnt;            /* scratch float register count           */
49 static int savfltregcnt;            /* saved float register count             */
50
51 static int iftmpintregcnt;          /* iface scratch integer register count   */
52 static int ifsavintregcnt;          /* iface saved integer register count     */
53 static int iftmpfltregcnt;          /* iface scratch float register count     */
54 static int ifsavfltregcnt;          /* iface saved float register count       */
55
56 static int tmpintreguse;            /* used scratch integer register count    */
57 static int savintreguse;            /* used saved integer register count      */
58 static int tmpfltreguse;            /* used scratch float register count      */
59 static int savfltreguse;            /* used saved float register count        */
60
61 static int maxtmpintreguse;         /* max used scratch int register count    */
62 static int maxsavintreguse;         /* max used saved int register count      */
63 static int maxtmpfltreguse;         /* max used scratch float register count  */
64 static int maxsavfltreguse;         /* max used saved float register count    */
65
66 static int freetmpinttop;           /* free scratch integer register count    */
67 static int freesavinttop;           /* free saved integer register count      */
68 static int freetmpflttop;           /* free scratch float register count      */
69 static int freesavflttop;           /* free saved float register count        */
70
71 static int savedregs_num;       /* total number of registers to be saved      */
72 static int arguments_num;       /* size of parameter field in the stackframe  */
73
74
75
76 /****************** function reg_init ******************************************
77
78         initialises the register-allocator
79         
80 *******************************************************************************/
81
82 static void reg_init()
83 {
84         int n;
85         
86         if (!tmpintregs) {
87
88                 if (TYPE_INT != 0 || TYPE_ADR != 4) 
89                         panic ("JAVA-Basictypes have been changed");
90
91                 intreg_argnum = 0;
92                 tmpintregcnt = 0;
93                 savintregcnt = 0;
94
95                 for (intregsnum = 0; nregdescint[intregsnum] != REG_END; intregsnum++) {
96                         switch (nregdescint[intregsnum]) {
97                                 case REG_SAV: savintregcnt++;
98                                               break;
99                                 case REG_TMP: tmpintregcnt++;
100                                               break;
101                                 case REG_ARG: intreg_argnum++;
102                                 }
103                         }
104
105                 argintregs = MNEW (int, intreg_argnum);
106                 tmpintregs = MNEW (int, tmpintregcnt);
107                 savintregs = MNEW (int, savintregcnt);
108                 freetmpintregs = MNEW (int, tmpintregcnt);
109                 freesavintregs = MNEW (int, savintregcnt);
110
111                 intreg_argnum = 0;
112                 tmpintreguse = 0;
113                 savintreguse = 0;
114
115                 for (n = 0; n < intregsnum; n++) {
116                         switch (nregdescint[n]) {
117                                 case REG_RET: intreg_ret = n; 
118                                               break;
119                                 case REG_SAV: savintregs[savintreguse++] = n;
120                                               break;
121                                 case REG_TMP: tmpintregs[tmpintreguse++] = n;
122                                               break;
123                                 case REG_ARG: argintregs[intreg_argnum++] = n;
124                                               break;
125                                 }
126                         }
127                                         
128                 
129                 fltreg_argnum = 0;
130                 tmpfltregcnt = 0;
131                 savfltregcnt = 0;
132
133                 for (floatregsnum = 0; nregdescfloat[floatregsnum] != REG_END; floatregsnum++) {
134                         switch (nregdescfloat[floatregsnum]) {
135                                 case REG_SAV: savfltregcnt++;
136                                               break;
137                                 case REG_TMP: tmpfltregcnt++;
138                                               break;
139                                 case REG_ARG: fltreg_argnum++;
140                                               break;
141                                 }
142                         }
143
144                 argfltregs = MNEW (int, fltreg_argnum);
145                 tmpfltregs = MNEW (int, tmpfltregcnt);
146                 savfltregs = MNEW (int, savfltregcnt);
147                 freetmpfltregs = MNEW (int, tmpfltregcnt);
148                 freesavfltregs = MNEW (int, savfltregcnt);
149
150                 fltreg_argnum = 0;
151                 tmpfltreguse = 0;
152                 savfltreguse = 0;
153
154                 for (n = 0; n < floatregsnum; n++) {
155                         switch (nregdescfloat[n]) {
156                                 case REG_RET: floatreg_ret = n; 
157                                               break;
158                                 case REG_SAV: savfltregs[savfltreguse++] = n;
159                                               break;
160                                 case REG_TMP: tmpfltregs[tmpfltreguse++] = n;
161                                               break;
162                                 case REG_ARG: argfltregs[fltreg_argnum++] = n;
163                                               break;
164                                 }
165                         }
166                                         
167                 }
168
169 }
170
171
172 /********************** function reg_close *************************************
173
174         releases all allocated space for registers
175
176 *******************************************************************************/
177
178 static void reg_close ()
179 {
180         if (argintregs) MFREE (argintregs, int, intreg_argnum);
181         if (argfltregs) MFREE (argfltregs, int, fltreg_argnum);
182         if (tmpintregs) MFREE (tmpintregs, int, tmpintregcnt);
183         if (savintregs) MFREE (savintregs, int, savintregcnt);
184         if (tmpfltregs) MFREE (tmpfltregs, int, tmpfltregcnt);
185         if (savfltregs) MFREE (savfltregs, int, savfltregcnt);
186
187         if (freetmpintregs) MFREE (freetmpintregs, int, tmpintregcnt);
188         if (freesavintregs) MFREE (freesavintregs, int, savintregcnt);
189         if (freetmpfltregs) MFREE (freetmpfltregs, int, tmpfltregcnt);
190         if (freesavfltregs) MFREE (freesavfltregs, int, savfltregcnt);
191 }
192
193
194 /****************** function local_init ****************************************
195
196         initialises the local variable and interfaces table
197         
198 *******************************************************************************/
199
200 static void local_init()
201 {
202         int i;
203         varinfo5 *v;
204
205         freemem    = DMNEW(int, maxstack);
206         locals     = DMNEW(varinfo5, maxlocals);
207         interfaces = DMNEW(varinfo5, maxstack);
208
209         for (v = locals, i = maxlocals; i > 0; v++, i--) {
210                 v[0][TYPE_INT].type = -1;
211                 v[0][TYPE_LNG].type = -1;
212                 v[0][TYPE_FLT].type = -1;
213                 v[0][TYPE_DBL].type = -1;
214                 v[0][TYPE_ADR].type = -1;
215                 }
216
217         for (v = interfaces, i = maxstack; i > 0; v++, i--) {
218                 v[0][TYPE_INT].type = -1;
219                 v[0][TYPE_INT].flags = 0;
220                 v[0][TYPE_LNG].type = -1;
221                 v[0][TYPE_LNG].flags = 0;
222                 v[0][TYPE_FLT].type = -1;
223                 v[0][TYPE_FLT].flags = 0;
224                 v[0][TYPE_DBL].type = -1;
225                 v[0][TYPE_DBL].flags = 0;
226                 v[0][TYPE_ADR].type = -1;
227                 v[0][TYPE_ADR].flags = 0;
228                 }
229 }
230
231
232 /************************* function interface_regalloc *****************************
233
234         allocates registers for all interface variables
235         
236 *******************************************************************************/
237         
238 static void interface_regalloc ()
239 {
240         int     s, t, saved;
241         int     intalloc, fltalloc;
242         varinfo *v;
243         
244         /* allocate stack space for passing arguments to called methods */
245
246         if (arguments_num > intreg_argnum)
247                 ifmemuse = arguments_num - intreg_argnum;
248         else
249                 ifmemuse = 0;
250
251         iftmpintregcnt = tmpintregcnt;
252         ifsavintregcnt = savintregcnt;
253         iftmpfltregcnt = tmpfltregcnt;
254         ifsavfltregcnt = savfltregcnt;
255
256         for (s = 0; s < maxstack; s++) {
257                 intalloc = -1; fltalloc = -1;
258                 saved = (interfaces[s][TYPE_INT].flags | interfaces[s][TYPE_LNG].flags |
259                          interfaces[s][TYPE_FLT].flags | interfaces[s][TYPE_DBL].flags |
260                          interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
261                 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
262                         v = &interfaces[s][t];
263                         if (v->type >= 0) {
264                                 if (!saved) {
265                                         if (IS_FLT_DBL_TYPE(t)) {
266                                                 if (fltalloc >= 0) {
267                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
268                                                         v->regoff = interfaces[s][fltalloc].regoff;
269                                                         }
270                                                 else if (iftmpfltregcnt > 0) {
271                                                         iftmpfltregcnt--;
272                                                         v->regoff = tmpfltregs[iftmpfltregcnt];
273                                                         }
274                                                 else if (ifsavfltregcnt > 0) {
275                                                         ifsavfltregcnt--;
276                                                         v->regoff = savfltregs[ifsavfltregcnt];
277                                                         }
278                                                 else {
279                                                         v->flags |= INMEMORY;
280                                                         v->regoff = ifmemuse++;
281                                                         }
282                                                 fltalloc = t;
283                                                 }
284                                         else {
285                                                 if (intalloc >= 0) {
286                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
287                                                         v->regoff = interfaces[s][intalloc].regoff;
288                                                         }
289                                                 else if (iftmpintregcnt > 0) {
290                                                         iftmpintregcnt--;
291                                                         v->regoff = tmpintregs[iftmpintregcnt];
292                                                         }
293                                                 else if (ifsavintregcnt > 0) {
294                                                         ifsavintregcnt--;
295                                                         v->regoff = savintregs[ifsavintregcnt];
296                                                         }
297                                                 else {
298                                                         v->flags |= INMEMORY;
299                                                         v->regoff = ifmemuse++;
300                                                         }
301                                                 intalloc = t;
302                                                 }
303                                         }
304                                 else {
305                                         if (IS_FLT_DBL_TYPE(t)) {
306                                                 if (fltalloc >= 0) {
307                                                         v->flags |= interfaces[s][fltalloc].flags & INMEMORY;
308                                                         v->regoff = interfaces[s][fltalloc].regoff;
309                                                         }
310                                                 else if (ifsavfltregcnt > 0) {
311                                                         ifsavfltregcnt--;
312                                                         v->regoff = savfltregs[ifsavfltregcnt];
313                                                         }
314                                                 else {
315                                                         v->flags |= INMEMORY;
316                                                         v->regoff = ifmemuse++;
317                                                         }
318                                                 fltalloc = t;
319                                                 }
320                                         else {
321                                                 if (intalloc >= 0) {
322                                                         v->flags |= interfaces[s][intalloc].flags & INMEMORY;
323                                                         v->regoff = interfaces[s][intalloc].regoff;
324                                                         }
325                                                 else if (ifsavintregcnt > 0) {
326                                                         ifsavintregcnt--;
327                                                         v->regoff = savintregs[ifsavintregcnt];
328                                                         }
329                                                 else {
330                                                         v->flags |= INMEMORY;
331                                                         v->regoff = ifmemuse++;
332                                                         }
333                                                 intalloc = t;
334                                                 }
335                                         }
336                                 } /* if (type >= 0) */
337                         }     /* for t */
338                 }         /* for s */
339         maxmemuse = ifmemuse;
340         maxtmpintreguse = iftmpintregcnt;
341         maxsavintreguse = ifsavintregcnt;
342         maxtmpfltreguse = iftmpfltregcnt;
343         maxsavfltreguse = ifsavfltregcnt;
344 }
345
346
347 /************************* function local_regalloc *****************************
348
349         allocates registers for all local variables
350         
351 *******************************************************************************/
352         
353 static void local_regalloc ()
354 {
355         int     s, t;
356         int     intalloc, fltalloc;
357         varinfo *v;
358         
359         if (isleafmethod) {
360                 for (s = 0; s < maxlocals; s++) {
361                         intalloc = -1; fltalloc = -1;
362                         for (t = TYPE_INT; t <= TYPE_ADR; t++) {
363                                 v = &locals[s][t];
364                                 if (v->type >= 0) {
365                                         if (IS_FLT_DBL_TYPE(t)) {
366                                                 if (fltalloc >= 0) {
367                                                         v->flags = locals[s][fltalloc].flags;
368                                                         v->regoff = locals[s][fltalloc].regoff;
369                                                         }
370                                                 else if (s < fltreg_argnum) {
371                                                         v->flags = 0;
372                                                         v->regoff = argfltregs[s];
373                                                         }
374                                                 else if (maxtmpfltreguse > 0) {
375                                                         maxtmpfltreguse--;
376                                                         v->flags = 0;
377                                                         v->regoff = tmpfltregs[maxtmpfltreguse];
378                                                         }
379                                                 else if (maxsavfltreguse > 0) {
380                                                         maxsavfltreguse--;
381                                                         v->flags = 0;
382                                                         v->regoff = savfltregs[maxsavfltreguse];
383                                                         }
384                                                 else {
385                                                         v->flags = INMEMORY;
386                                                         v->regoff = maxmemuse++;
387                                                         }
388                                                 fltalloc = t;
389                                                 }
390                                         else {
391                                                 if (intalloc >= 0) {
392                                                         v->flags = locals[s][intalloc].flags;
393                                                         v->regoff = locals[s][intalloc].regoff;
394                                                         }
395                                                 else if (s < intreg_argnum) {
396                                                         v->flags = 0;
397                                                         v->regoff = argintregs[s];
398                                                         }
399                                                 else if (maxtmpintreguse > 0) {
400                                                         maxtmpintreguse--;
401                                                         v->flags = 0;
402                                                         v->regoff = tmpintregs[maxtmpintreguse];
403                                                         }
404                                                 else if (maxsavintreguse > 0) {
405                                                         maxsavintreguse--;
406                                                         v->flags = 0;
407                                                         v->regoff = savintregs[maxsavintreguse];
408                                                         }
409                                                 else {
410                                                         v->flags = INMEMORY;
411                                                         v->regoff = maxmemuse++;
412                                                         }
413                                                 intalloc = t;
414                                                 }
415                                         }
416                                 }
417                         }
418                 return;
419                 }
420         for (s = 0; s < maxlocals; s++) {
421                 intalloc = -1; fltalloc = -1;
422                 for (t=TYPE_INT; t<=TYPE_ADR; t++) {
423                         v = &locals[s][t];
424                         if (v->type >= 0) {
425                                 if (IS_FLT_DBL_TYPE(t)) {
426                                         if (fltalloc >= 0) {
427                                                 v->flags = locals[s][fltalloc].flags;
428                                                 v->regoff = locals[s][fltalloc].regoff;
429                                                 }
430                                         else if (maxsavfltreguse > 0) {
431                                                 maxsavfltreguse--;
432                                                 v->flags = 0;
433                                                 v->regoff = savfltregs[maxsavfltreguse];
434                                                 }
435                                         else {
436                                                 v->flags = INMEMORY;
437                                                 v->regoff = maxmemuse++;
438                                                 }
439                                         fltalloc = t;
440                                         }
441                                 else {
442                                         if (intalloc >= 0) {
443                                                 v->flags = locals[s][intalloc].flags;
444                                                 v->regoff = locals[s][intalloc].regoff;
445                                                 }
446                                         else if (maxsavintreguse > 0) {
447                                                 maxsavintreguse--;
448                                                 v->flags = 0;
449                                                 v->regoff = savintregs[maxsavintreguse];
450                                                 }
451                                         else {
452                                                 v->flags = INMEMORY;
453                                                 v->regoff = maxmemuse++;
454                                                 }
455                                         intalloc = t;
456                                         }
457                                 }
458                         }
459                 }
460 }
461
462
463 static void reg_init_temp()
464 {
465         freememtop = 0;
466         memuse = ifmemuse;
467
468         freetmpinttop = 0;
469         freesavinttop = 0;
470         freetmpflttop = 0;
471         freesavflttop = 0;
472         tmpintreguse = iftmpintregcnt;
473         savintreguse = ifsavintregcnt;
474         tmpfltreguse = iftmpfltregcnt;
475         savfltreguse = ifsavfltregcnt;
476 }
477
478
479 #define reg_new_temp(s) if(s->varkind==TEMPVAR)reg_new_temp_func(s)
480
481 static void reg_new_temp_func(stackptr s)
482 {
483 if (s->flags & SAVEDVAR) {
484         if (IS_FLT_DBL_TYPE(s->type)) {
485                 if (freesavflttop > 0) {
486                         freesavflttop--;
487                         s->regoff = freesavfltregs[freesavflttop];
488                         return;
489                         }
490                 else if (savfltreguse > 0) {
491                         savfltreguse--;
492                         if (savfltreguse < maxsavfltreguse)
493                                 maxsavfltreguse = savfltreguse;
494                         s->regoff = savfltregs[savfltreguse];
495                         return;
496                         }
497                 }
498         else {
499                 if (freesavinttop > 0) {
500                         freesavinttop--;
501                         s->regoff = freesavintregs[freesavinttop];
502                         return;
503                         }
504                 else if (savintreguse > 0) {
505                         savintreguse--;
506                         if (savintreguse < maxsavintreguse)
507                                 maxsavintreguse = savintreguse;
508                         s->regoff = savintregs[savintreguse];
509                         return;
510                         }
511                 }
512         }
513 else {
514         if (IS_FLT_DBL_TYPE(s->type)) {
515                 if (freetmpflttop > 0) {
516                         freetmpflttop--;
517                         s->regoff = freetmpfltregs[freetmpflttop];
518                         return;
519                         }
520                 else if (tmpfltreguse > 0) {
521                         tmpfltreguse--;
522                         if (tmpfltreguse < maxtmpfltreguse)
523                                 maxtmpfltreguse = tmpfltreguse;
524                         s->regoff = tmpfltregs[tmpfltreguse];
525                         return;
526                         }
527                 }
528         else {
529                 if (freetmpinttop > 0) {
530                         freetmpinttop--;
531                         s->regoff = freetmpintregs[freetmpinttop];
532                         return;
533                         }
534                 else if (tmpintreguse > 0) {
535                         tmpintreguse--;
536                         if (tmpintreguse < maxtmpintreguse)
537                                 maxtmpintreguse = tmpintreguse;
538                         s->regoff = tmpintregs[tmpintreguse];
539                         return;
540                         }
541                 }
542         }
543 if (freememtop > 0) {
544         freememtop--;
545         s->regoff = freemem[freememtop];
546         }
547 else {
548         s->regoff = memuse++;
549         if (memuse > maxmemuse)
550                 maxmemuse = memuse;
551         }
552 s->flags |= INMEMORY;
553 }
554
555
556 #define reg_free_temp(s) if(s->varkind==TEMPVAR)reg_free_temp_func(s)
557
558 static void reg_free_temp_func(stackptr s)
559 {
560 if (s->flags & INMEMORY)
561         freemem[freememtop++] = s->regoff;
562 else if (IS_FLT_DBL_TYPE(s->type)) {
563         if (s->flags & SAVEDVAR)
564                 freesavfltregs[freesavflttop++] = s->regoff;
565         else
566                 freetmpfltregs[freetmpflttop++] = s->regoff;
567         }
568 else
569         if (s->flags & SAVEDVAR)
570                 freesavintregs[freesavinttop++] = s->regoff;
571         else
572                 freetmpintregs[freetmpinttop++] = s->regoff;
573 }
574
575
576 static void allocate_scratch_registers()
577 {
578         int b_count;
579         int opcode, i, len;
580         stackptr    src, dst;
581         instruction *iptr = instr;
582         basicblock  *bptr;
583         
584         b_count = block_count;
585         bptr = block;
586         while (--b_count >= 0) {
587                 if (bptr->flags >= BBREACHED) {
588                         dst = bptr->instack;
589                         reg_init_temp();
590                         i = bptr[0].ipc;
591                         len = bptr[1].ipc - i;
592                         iptr = &instr[i];
593                         while (--len >= 0)  {
594                                 src = dst;
595                                 dst = iptr->dst;
596                                 opcode = iptr->opc;
597                                 switch (opcode) {
598
599                                         /* pop 0 push 0 */
600
601                                         case ICMD_NOP:
602                                         case ICMD_CHECKASIZE:
603                                         case ICMD_IINC:
604                                         case ICMD_JSR:
605                                         case ICMD_RET:
606                                         case ICMD_RETURN:
607                                         case ICMD_GOTO:
608                                                 break;
609
610                                         /* pop 0 push 1 const */
611                                         
612                                         case ICMD_ICONST:
613                                         case ICMD_LCONST:
614                                         case ICMD_FCONST:
615                                         case ICMD_DCONST:
616                                         case ICMD_ACONST:
617
618                                         /* pop 0 push 1 load */
619                                         
620                                         case ICMD_ILOAD:
621                                         case ICMD_LLOAD:
622                                         case ICMD_FLOAD:
623                                         case ICMD_DLOAD:
624                                         case ICMD_ALOAD:
625                                                 reg_new_temp(dst);
626                                                 break;
627
628                                         /* pop 2 push 1 */
629
630                                         case ICMD_IALOAD:
631                                         case ICMD_LALOAD:
632                                         case ICMD_FALOAD:
633                                         case ICMD_DALOAD:
634                                         case ICMD_AALOAD:
635
636                                         case ICMD_BALOAD:
637                                         case ICMD_CALOAD:
638                                         case ICMD_SALOAD:
639                                                 reg_free_temp(src);
640                                                 reg_free_temp(src->prev);
641                                                 reg_new_temp(dst);
642                                                 break;
643
644                                         /* pop 3 push 0 */
645
646                                         case ICMD_IASTORE:
647                                         case ICMD_LASTORE:
648                                         case ICMD_FASTORE:
649                                         case ICMD_DASTORE:
650                                         case ICMD_AASTORE:
651
652                                         case ICMD_BASTORE:
653                                         case ICMD_CASTORE:
654                                         case ICMD_SASTORE:
655                                                 reg_free_temp(src);
656                                                 reg_free_temp(src->prev);
657                                                 reg_free_temp(src->prev->prev);
658                                                 break;
659
660                                         /* pop 1 push 0 store */
661
662                                         case ICMD_ISTORE:
663                                         case ICMD_LSTORE:
664                                         case ICMD_FSTORE:
665                                         case ICMD_DSTORE:
666                                         case ICMD_ASTORE:
667
668                                         /* pop 1 push 0 */
669
670                                         case ICMD_POP:
671
672                                         case ICMD_IRETURN:
673                                         case ICMD_LRETURN:
674                                         case ICMD_FRETURN:
675                                         case ICMD_DRETURN:
676                                         case ICMD_ARETURN:
677
678                                         case ICMD_ATHROW:
679
680                                         case ICMD_PUTSTATIC:
681
682                                         /* pop 1 push 0 branch */
683
684                                         case ICMD_IFNULL:
685                                         case ICMD_IFNONNULL:
686
687                                         case ICMD_IFEQ:
688                                         case ICMD_IFNE:
689                                         case ICMD_IFLT:
690                                         case ICMD_IFGE:
691                                         case ICMD_IFGT:
692                                         case ICMD_IFLE:
693
694                                         case ICMD_IF_LEQ:
695                                         case ICMD_IF_LNE:
696                                         case ICMD_IF_LLT:
697                                         case ICMD_IF_LGE:
698                                         case ICMD_IF_LGT:
699                                         case ICMD_IF_LLE:
700
701                                         /* pop 1 push 0 table branch */
702
703                                         case ICMD_TABLESWITCH:
704                                         case ICMD_LOOKUPSWITCH:
705
706                                         case ICMD_NULLCHECKPOP:
707                                         case ICMD_MONITORENTER:
708                                         case ICMD_MONITOREXIT:
709                                                 reg_free_temp(src);
710                                                 break;
711
712                                         /* pop 2 push 0 branch */
713
714                                         case ICMD_IF_ICMPEQ:
715                                         case ICMD_IF_ICMPNE:
716                                         case ICMD_IF_ICMPLT:
717                                         case ICMD_IF_ICMPGE:
718                                         case ICMD_IF_ICMPGT:
719                                         case ICMD_IF_ICMPLE:
720
721                                         case ICMD_IF_LCMPEQ:
722                                         case ICMD_IF_LCMPNE:
723                                         case ICMD_IF_LCMPLT:
724                                         case ICMD_IF_LCMPGE:
725                                         case ICMD_IF_LCMPGT:
726                                         case ICMD_IF_LCMPLE:
727
728                                         case ICMD_IF_ACMPEQ:
729                                         case ICMD_IF_ACMPNE:
730
731                                         /* pop 2 push 0 */
732
733                                         case ICMD_POP2:
734
735                                         case ICMD_PUTFIELD:
736                                                 reg_free_temp(src);
737                                                 reg_free_temp(src->prev);
738                                                 break;
739
740                                         /* pop 0 push 1 dup */
741                                         
742                                         case ICMD_DUP:
743                                                 reg_new_temp(dst);
744                                                 break;
745
746                                         /* pop 0 push 2 dup */
747                                         
748                                         case ICMD_DUP2:
749                                                 reg_new_temp(dst->prev);
750                                                 reg_new_temp(dst);
751                                                 break;
752
753                                         /* pop 2 push 3 dup */
754                                         
755                                         case ICMD_DUP_X1:
756                                                 reg_new_temp(dst->prev->prev);
757                                                 reg_new_temp(dst->prev);
758                                                 reg_new_temp(dst);
759                                                 reg_free_temp(src);
760                                                 reg_free_temp(src->prev);
761                                                 break;
762
763                                         /* pop 3 push 4 dup */
764                                         
765                                         case ICMD_DUP_X2:
766                                                 reg_new_temp(dst->prev->prev->prev);
767                                                 reg_new_temp(dst->prev->prev);
768                                                 reg_new_temp(dst->prev);
769                                                 reg_new_temp(dst);
770                                                 reg_free_temp(src);
771                                                 reg_free_temp(src->prev);
772                                                 reg_free_temp(src->prev->prev);
773                                                 break;
774
775                                         /* pop 3 push 5 dup */
776                                         
777                                         case ICMD_DUP2_X1:
778                                                 reg_new_temp(dst->prev->prev->prev->prev);
779                                                 reg_new_temp(dst->prev->prev->prev);
780                                                 reg_new_temp(dst->prev->prev);
781                                                 reg_new_temp(dst->prev);
782                                                 reg_new_temp(dst);
783                                                 reg_free_temp(src);
784                                                 reg_free_temp(src->prev);
785                                                 reg_free_temp(src->prev->prev);
786                                                 break;
787
788                                         /* pop 4 push 6 dup */
789                                         
790                                         case ICMD_DUP2_X2:
791                                                 reg_new_temp(dst->prev->prev->prev->prev->prev);
792                                                 reg_new_temp(dst->prev->prev->prev->prev);
793                                                 reg_new_temp(dst->prev->prev->prev);
794                                                 reg_new_temp(dst->prev->prev);
795                                                 reg_new_temp(dst->prev);
796                                                 reg_new_temp(dst);
797                                                 reg_free_temp(src);
798                                                 reg_free_temp(src->prev);
799                                                 reg_free_temp(src->prev->prev);
800                                                 reg_free_temp(src->prev->prev->prev);
801                                                 break;
802
803                                         /* pop 2 push 2 swap */
804                                         
805                                         case ICMD_SWAP:
806                                                 reg_new_temp(dst->prev);
807                                                 reg_new_temp(dst);
808                                                 reg_free_temp(src);
809                                                 reg_free_temp(src->prev);
810                                                 break;
811
812                                         /* pop 2 push 1 */
813                                         
814                                         case ICMD_IADD:
815                                         case ICMD_ISUB:
816                                         case ICMD_IMUL:
817                                         case ICMD_IDIV:
818                                         case ICMD_IREM:
819
820                                         case ICMD_ISHL:
821                                         case ICMD_ISHR:
822                                         case ICMD_IUSHR:
823                                         case ICMD_IAND:
824                                         case ICMD_IOR:
825                                         case ICMD_IXOR:
826
827                                         case ICMD_LADD:
828                                         case ICMD_LSUB:
829                                         case ICMD_LMUL:
830                                         case ICMD_LDIV:
831                                         case ICMD_LREM:
832
833                                         case ICMD_LOR:
834                                         case ICMD_LAND:
835                                         case ICMD_LXOR:
836
837                                         case ICMD_LSHL:
838                                         case ICMD_LSHR:
839                                         case ICMD_LUSHR:
840
841                                         case ICMD_FADD:
842                                         case ICMD_FSUB:
843                                         case ICMD_FMUL:
844                                         case ICMD_FDIV:
845                                         case ICMD_FREM:
846
847                                         case ICMD_DADD:
848                                         case ICMD_DSUB:
849                                         case ICMD_DMUL:
850                                         case ICMD_DDIV:
851                                         case ICMD_DREM:
852
853                                         case ICMD_LCMP:
854                                         case ICMD_FCMPL:
855                                         case ICMD_FCMPG:
856                                         case ICMD_DCMPL:
857                                         case ICMD_DCMPG:
858                                                 reg_free_temp(src);
859                                                 reg_free_temp(src->prev);
860                                                 reg_new_temp(dst);
861                                                 break;
862
863                                         /* pop 1 push 1 */
864                                         
865                                         case ICMD_IADDCONST:
866                                         case ICMD_ISUBCONST:
867                                         case ICMD_IMULCONST:
868                                         case ICMD_IANDCONST:
869                                         case ICMD_IORCONST:
870                                         case ICMD_IXORCONST:
871                                         case ICMD_ISHLCONST:
872                                         case ICMD_ISHRCONST:
873                                         case ICMD_IUSHRCONST:
874
875                                         case ICMD_LADDCONST:
876                                         case ICMD_LSUBCONST:
877                                         case ICMD_LMULCONST:
878                                         case ICMD_LANDCONST:
879                                         case ICMD_LORCONST:
880                                         case ICMD_LXORCONST:
881                                         case ICMD_LSHLCONST:
882                                         case ICMD_LSHRCONST:
883                                         case ICMD_LUSHRCONST:
884
885                                         case ICMD_INEG:
886                                         case ICMD_INT2BYTE:
887                                         case ICMD_INT2CHAR:
888                                         case ICMD_INT2SHORT:
889                                         case ICMD_LNEG:
890                                         case ICMD_FNEG:
891                                         case ICMD_DNEG:
892
893                                         case ICMD_I2L:
894                                         case ICMD_I2F:
895                                         case ICMD_I2D:
896                                         case ICMD_L2I:
897                                         case ICMD_L2F:
898                                         case ICMD_L2D:
899                                         case ICMD_F2I:
900                                         case ICMD_F2L:
901                                         case ICMD_F2D:
902                                         case ICMD_D2I:
903                                         case ICMD_D2L:
904                                         case ICMD_D2F:
905
906                                         case ICMD_CHECKCAST:
907
908                                         case ICMD_ARRAYLENGTH:
909                                         case ICMD_INSTANCEOF:
910
911                                         case ICMD_NEWARRAY:
912                                         case ICMD_ANEWARRAY:
913
914                                         case ICMD_GETFIELD:
915                                                 reg_free_temp(src);
916                                                 reg_new_temp(dst);
917                                                 break;
918
919                                         /* pop 0 push 1 */
920                                         
921                                         case ICMD_GETSTATIC:
922
923                                         case ICMD_NEW:
924
925                                                 reg_new_temp(dst);
926                                                 break;
927
928                                         /* pop many push any */
929                                         
930                                         case ICMD_INVOKEVIRTUAL:
931                                         case ICMD_INVOKESPECIAL:
932                                         case ICMD_INVOKESTATIC:
933                                         case ICMD_INVOKEINTERFACE:
934                                                 {
935                                                 i = iptr->op1;
936                                                 while (--i >= 0) {
937                                                         reg_free_temp(src);
938                                                         src = src->prev;
939                                                         }
940                                                 if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
941                                                         reg_new_temp(dst);
942                                                 break;
943                                                 }
944
945                                         case ICMD_BUILTIN3:
946                                                 reg_free_temp(src);
947                                                 src = src->prev;
948                                         case ICMD_BUILTIN2:
949                                                 reg_free_temp(src);
950                                                 src = src->prev;
951                                         case ICMD_BUILTIN1:
952                                                 reg_free_temp(src);
953                                                 src = src->prev;
954                                                 if (iptr->op1 != TYPE_VOID)
955                                                         reg_new_temp(dst);
956                                                 break;
957
958                                         case ICMD_MULTIANEWARRAY:
959                                                 i = iptr->op1;
960                                                 while (--i >= 0) {
961                                                         reg_free_temp(src);
962                                                         src = src->prev;
963                                                         }
964                                                 reg_new_temp(dst);
965                                                 break;
966
967                                         default:
968                                                 printf("ICMD %d at %d\n", iptr->opc, (int)(iptr-instr));
969                                                 panic("Missing ICMD code during register allocation");
970                                         } /* switch */
971                                 iptr++;
972                                 } /* while instructions */
973                         } /* if */
974                 bptr++;
975         } /* while blocks */
976 }