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