GNU header update.
[cacao.git] / src / vm / jit / reg.inc
1 /* vm/jit/reg.inc - register allocator
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    Changes: Stefan Ring
30             Christian Thalinger
31
32    $Id: reg.inc 1735 2004-12-07 14:33:27Z twisti $
33
34 */
35
36
37 #include "mm/memory.h"
38 #include "vm/jit/reg.h"
39
40
41 /* function prototypes for this file */
42
43 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
44 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
45 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
46
47
48 /* reg_init ********************************************************************
49
50    TODO
51         
52 *******************************************************************************/
53
54 void reg_init()
55 {
56         /* void */
57 }
58
59
60 /* reg_setup *******************************************************************
61
62    TODO
63
64 *******************************************************************************/
65
66 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
67 {
68         s4 i;
69         varinfo5 *v;
70
71         /* setup the integer register table */
72         rd->intreg_argnum = 0;
73         rd->tmpintregcnt = 0;
74         rd->savintregcnt = 0;
75
76         for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
77                 switch (nregdescint[rd->intregsnum]) {
78                 case REG_SAV:
79                         rd->savintregcnt++;
80                         break;
81                 case REG_TMP:
82                         rd->tmpintregcnt++;
83                         break;
84                 case REG_ARG:
85                         rd->intreg_argnum++;
86                         break;
87                 }
88         }
89
90         rd->argintregs = DMNEW(s4, rd->intreg_argnum);
91         rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
92         rd->savintregs = DMNEW(s4, rd->savintregcnt);
93         rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
94         rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
95         rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
96 #ifdef USETWOREGS
97         rd->secondregs = DMNEW(s4, rd->intregsnum);
98 #endif
99
100         rd->intreg_argnum = 0;
101         rd->argintreguse = 0;
102         rd->tmpintreguse = 0;
103         rd->savintreguse = 0;
104
105         for (i = 0; i < rd->intregsnum; i++) {
106                 switch (nregdescint[i]) {
107                 case REG_RET:
108                         rd->intreg_ret = i; 
109                         break;
110                 case REG_SAV:
111                         rd->savintregs[rd->savintreguse++] = i;
112                         break;
113                 case REG_TMP:
114                         rd->tmpintregs[rd->tmpintreguse++] = i;
115                         break;
116                 case REG_ARG:
117                         rd->argintregs[rd->intreg_argnum++] = i;
118                         rd->argintreguse++;
119                         break;
120                 }
121         }
122
123 #if defined(__X86_64__)
124         /* 
125          * on x86_64 the argument registers are not in ascending order 
126          * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
127          */
128         i = rd->argintregs[3];
129         rd->argintregs[3] = rd->argintregs[0];
130         rd->argintregs[0] = i;
131
132         i = rd->argintregs[2];
133         rd->argintregs[2] = rd->argintregs[1];
134         rd->argintregs[1] = i;
135 #endif
136                 
137 #ifdef USETWOREGS
138         for (i = 1; i < rd->intreg_argnum; i++)
139                 rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
140         for (i = 1; i < rd->tmpintregcnt; i++)
141                 rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
142         for (i = 1; i < rd->savintregcnt; i++)
143                 rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
144
145         rd->secondregs[REG_ITMP1] = REG_ITMP2;
146         rd->secondregs[REG_ITMP3] = REG_ITMP2;
147         rd->secondregs[REG_RESULT] = REG_RESULT + 1;
148         rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
149 #endif
150
151         /* setup the float register table */
152         rd->fltreg_argnum = 0;
153         rd->tmpfltregcnt = 0;
154         rd->savfltregcnt = 0;
155
156         for (rd->floatregsnum = 0; nregdescfloat[rd->floatregsnum] != REG_END; rd->floatregsnum++) {
157                 switch (nregdescfloat[rd->floatregsnum]) {
158                 case REG_SAV:
159                         rd->savfltregcnt++;
160                         break;
161                 case REG_TMP:
162                         rd->tmpfltregcnt++;
163                         break;
164                 case REG_ARG:
165                         rd->fltreg_argnum++;
166                         break;
167                 }
168         }
169
170         rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
171         rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
172         rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
173         rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
174         rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
175         rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
176
177         rd->fltreg_argnum = 0;
178         rd->argfltreguse = 0;
179         rd->tmpfltreguse = 0;
180         rd->savfltreguse = 0;
181
182         for (i = 0; i < rd->floatregsnum; i++) {
183                 switch (nregdescfloat[i]) {
184                 case REG_RET:
185                         rd->floatreg_ret = i; 
186                         break;
187                 case REG_SAV:
188                         rd->savfltregs[rd->savfltreguse++] = i;
189                         break;
190                 case REG_TMP:
191                         rd->tmpfltregs[rd->tmpfltreguse++] = i;
192                         break;
193                 case REG_ARG:
194                         rd->argfltregs[rd->fltreg_argnum++] = i;
195                         rd->argfltreguse++;
196                         break;
197                 }
198         }
199
200
201         rd->freemem    = DMNEW(s4, id->cummaxstack);
202         rd->locals     = DMNEW(varinfo5, id->cumlocals);
203         rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
204
205         for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
206                 v[0][TYPE_INT].type = -1;
207                 v[0][TYPE_LNG].type = -1;
208                 v[0][TYPE_FLT].type = -1;
209                 v[0][TYPE_DBL].type = -1;
210                 v[0][TYPE_ADR].type = -1;
211         }
212
213         for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
214                 v[0][TYPE_INT].type = -1;
215                 v[0][TYPE_INT].flags = 0;
216                 v[0][TYPE_LNG].type = -1;
217                 v[0][TYPE_LNG].flags = 0;
218                 v[0][TYPE_FLT].type = -1;
219                 v[0][TYPE_FLT].flags = 0;
220                 v[0][TYPE_DBL].type = -1;
221                 v[0][TYPE_DBL].flags = 0;
222                 v[0][TYPE_ADR].type = -1;
223                 v[0][TYPE_ADR].flags = 0;
224         }
225 }
226
227
228 /* function reg_free ***********************************************************
229
230    releases all allocated space for registers
231
232 *******************************************************************************/
233
234 void reg_free(methodinfo *m, registerdata *rd)
235 {
236         /* void */
237 }
238
239
240 /* reg_close *******************************************************************
241
242    TODO
243
244 *******************************************************************************/
245
246 void reg_close()
247 {
248         /* void */
249 }
250
251
252 /* function interface_regalloc *************************************************
253
254         allocates registers for all interface variables
255         
256 *******************************************************************************/
257         
258 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
259 {
260         interface_regalloc(m, cd, rd);
261         allocate_scratch_registers(m, rd);
262         local_regalloc(m, cd, rd);
263 }
264
265
266 /* function interface_regalloc *************************************************
267
268         allocates registers for all interface variables
269         
270 *******************************************************************************/
271         
272 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
273 {
274         int     s, t, saved;
275         int     intalloc, fltalloc;
276         varinfo *v;
277         int             regsneeded = 0;
278
279         /* allocate stack space for passing arguments to called methods */
280
281 #ifndef SPECIALMEMUSE
282 #if defined(__X86_64__)
283         /*
284          * XXX: we have a problem here, but allocating a little more stack space
285          *      is better than having a bug
286          */
287         /*      if (arguments_num > (intreg_argnum + fltreg_argnum)) */
288         /*              ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
289         if (rd->arguments_num > rd->fltreg_argnum)
290                 rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum;
291 #else
292         if (rd->arguments_num > rd->intreg_argnum)
293                 rd->ifmemuse = rd->arguments_num - rd->intreg_argnum;
294 #endif
295         else
296                 rd->ifmemuse = 0;
297 #endif
298
299         rd->iftmpintregcnt = rd->tmpintregcnt;
300         rd->ifsavintregcnt = rd->savintregcnt;
301         rd->iftmpfltregcnt = rd->tmpfltregcnt;
302         rd->ifsavfltregcnt = rd->savfltregcnt;
303
304         for (s = 0; s < cd->maxstack; s++) {
305                 intalloc = -1; fltalloc = -1;
306                 saved = (rd->interfaces[s][TYPE_INT].flags |
307                                  rd->interfaces[s][TYPE_LNG].flags |
308                          rd->interfaces[s][TYPE_FLT].flags |
309                                  rd->interfaces[s][TYPE_DBL].flags |
310                          rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
311  
312                 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
313                         v = &rd->interfaces[s][t];
314                         if (v->type >= 0) {
315 #ifdef USETWOREGS
316                                 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
317 #endif
318                                 if (!saved) {
319                                         if (IS_FLT_DBL_TYPE(t)) {
320                                                 if (fltalloc >= 0) {
321                                                         v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
322                                                         v->regoff = rd->interfaces[s][fltalloc].regoff;
323                                                 }
324                                                 else if (rd->iftmpfltregcnt > 0) {
325                                                         rd->iftmpfltregcnt--;
326                                                         v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
327                                                 }
328                                                 else if (rd->ifsavfltregcnt > 0) {
329                                                         rd->ifsavfltregcnt--;
330                                                         v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
331                                                 }
332                                                 else {
333                                                         v->flags |= INMEMORY;
334                                                         v->regoff = rd->ifmemuse;
335                                                         rd->ifmemuse += regsneeded + 1;
336                                                 }
337                                                 fltalloc = t;
338                                         }
339                                         else {
340 #if defined(__I386__)
341                                                 /*
342                                                  * for i386 put all longs in memory
343                                                  */
344                                                 if (IS_2_WORD_TYPE(t)) {
345                                                         v->flags |= INMEMORY;
346                                                         v->regoff = rd->ifmemuse++;
347                                                 } else {
348 #endif
349                                                         if (intalloc >= 0) {
350                                                                 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
351                                                                 v->regoff = rd->interfaces[s][intalloc].regoff;
352                                                         }
353                                                         else if (rd->iftmpintregcnt > regsneeded) {
354                                                                 rd->iftmpintregcnt -= regsneeded + 1;
355                                                                 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
356                                                         }
357                                                         else if (rd->ifsavintregcnt > regsneeded) {
358                                                                 rd->ifsavintregcnt -= regsneeded + 1;
359                                                                 v->regoff = rd->savintregs[rd->ifsavintregcnt];
360                                                         }
361                                                         else {
362                                                                 v->flags |= INMEMORY;
363                                                                 v->regoff = rd->ifmemuse;
364                                                                 rd->ifmemuse += regsneeded + 1;
365                                                         }
366 #if defined(__I386__)
367                                                 }
368 #endif
369                                                 intalloc = t;
370                                         }
371                                 }
372                                 else {
373                                         if (IS_FLT_DBL_TYPE(t)) {
374                                                 if (fltalloc >= 0) {
375                                                         v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
376                                                         v->regoff = rd->interfaces[s][fltalloc].regoff;
377                                                 }
378                                                 else if (rd->ifsavfltregcnt > 0) {
379                                                         rd->ifsavfltregcnt--;
380                                                         v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
381                                                 }
382                                                 else {
383                                                         v->flags |= INMEMORY;
384                                                         v->regoff = rd->ifmemuse;
385                                                         rd->ifmemuse += regsneeded + 1;
386                                                 }
387                                                 fltalloc = t;
388                                         }
389                                         else {
390 #if defined(__I386__)
391                                                 /*
392                                                  * for i386 put all longs in memory
393                                                  */
394                                                 if (IS_2_WORD_TYPE(t)) {
395                                                         v->flags |= INMEMORY;
396                                                         v->regoff = rd->ifmemuse++;
397                                                 } else {
398 #endif
399                                                         if (intalloc >= 0) {
400                                                                 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
401                                                                 v->regoff = rd->interfaces[s][intalloc].regoff;
402                                                         }
403                                                         else if (rd->ifsavintregcnt > regsneeded) {
404                                                                 rd->ifsavintregcnt -= regsneeded + 1;
405                                                                 v->regoff = rd->savintregs[rd->ifsavintregcnt];
406                                                         }
407                                                         else {
408                                                                 v->flags |= INMEMORY;
409                                                                 v->regoff = rd->ifmemuse;
410                                                                 rd->ifmemuse += regsneeded + 1;
411                                                         }
412 #if defined(__I386__)
413                                                 }
414 #endif
415                                                 intalloc = t;
416                                         }
417                                 }
418                         } /* if (type >= 0) */
419                 } /* for t */
420         } /* for s */
421
422         rd->maxmemuse = rd->ifmemuse;
423         rd->maxargintreguse = -1;
424         rd->maxtmpintreguse = rd->iftmpintregcnt;
425         rd->maxsavintreguse = rd->ifsavintregcnt;
426         rd->maxargfltreguse = -1;
427         rd->maxtmpfltreguse = rd->iftmpfltregcnt;
428         rd->maxsavfltreguse = rd->ifsavfltregcnt;
429 }
430
431
432
433 /* function local_regalloc *****************************************************
434
435         allocates registers for all local variables
436         
437 *******************************************************************************/
438         
439 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
440 {
441         int      s, t, tt;
442         int      intalloc, fltalloc;
443         varinfo *v;
444         int      regsneeded = 0;
445         int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
446
447         if (m->isleafmethod) {
448                 int arg, doublewordarg, iargcnt, fargcnt;
449
450                 arg = 0, iargcnt = 0, fargcnt = 0;
451                 doublewordarg = 0;
452                 for (s = 0; s < cd->maxlocals; s++) {
453                         intalloc = -1; fltalloc = -1;
454                         for (tt = 0; tt <= 4; tt++) {
455                                 t = typeloop[tt];
456                                 v = &rd->locals[s][t];
457
458                                 if (v->type >= 0) {
459 #ifdef USETWOREGS
460                                         regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
461 #endif
462                                         if (IS_FLT_DBL_TYPE(t)) {
463 #if !defined(CONSECUTIVE_FLOATARGS)
464                                                 fargcnt = arg;
465 #endif
466                                                 if (fltalloc >= 0) {
467                                                         v->flags = rd->locals[s][fltalloc].flags;
468                                                         v->regoff = rd->locals[s][fltalloc].regoff;
469                                                 }
470                                                 else if (!doublewordarg && (arg < m->paramcount) &&
471                                                                  (fargcnt < rd->fltreg_argnum)) {
472                                                         v->flags = 0;
473                                                         v->regoff = rd->argfltregs[fargcnt];
474                                                 }
475                                                 else if (rd->maxtmpfltreguse > 0) {
476                                                         rd->maxtmpfltreguse--;
477                                                         v->flags = 0;
478                                                         v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
479                                                 }
480                                                 else if (rd->maxsavfltreguse > 0) {
481                                                         rd->maxsavfltreguse--;
482                                                         v->flags = 0;
483                                                         v->regoff = rd->savfltregs[rd->maxsavfltreguse];
484                                                 }
485                                                 else {
486                                                         v->flags = INMEMORY;
487                                                         v->regoff = rd->maxmemuse;
488                                                         rd->maxmemuse += regsneeded + 1;
489                                                 }
490                                                 fltalloc = t;
491
492                                         } else {
493                                                 int regtouse;
494 #if defined(__I386__)
495                                                 /*
496                                                  * for i386 put all longs in memory
497                                                  */
498                                                 if (IS_2_WORD_TYPE(t)) {
499                                                         v->flags = INMEMORY;
500                                                         v->regoff = rd->maxmemuse++;
501                                                 } else {
502 #endif
503 #if !defined(CONSECUTIVE_INTARGS)
504                                                         iargcnt = arg;
505 #endif
506                                                         if (intalloc >= 0) {
507                                                                 v->flags = rd->locals[s][intalloc].flags;
508                                                                 v->regoff = rd->locals[s][intalloc].regoff;
509                                                         }
510                                                         else if (!doublewordarg && (arg < m->paramcount)
511 #ifndef USETWOREGS
512                                                                          && ((regtouse = iargcnt) < rd->intreg_argnum)
513 #else
514                                                                          && ((regtouse = s) < rd->intreg_argnum - regsneeded)
515 #endif
516                                                                          ) {
517                                                                 v->flags = 0;
518                                                                 v->regoff = rd->argintregs[regtouse];
519                                                         }
520                                                         else if (rd->maxtmpintreguse > regsneeded) {
521                                                                 rd->maxtmpintreguse -= regsneeded + 1;
522                                                                 v->flags = 0;
523                                                                 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
524                                                         }
525                                                         else if (rd->maxsavintreguse > regsneeded) {
526                                                                 rd->maxsavintreguse -= regsneeded + 1;
527                                                                 v->flags = 0;
528                                                                 v->regoff = rd->savintregs[rd->maxsavintreguse];
529                                                         }
530                                                         /*
531                                                          * use unused argument registers as local registers
532                                                          */
533                                                         else if (!doublewordarg && (arg >= m->paramcount) &&
534                                                                          (iargcnt < rd->intreg_argnum)) {
535                                                                 v->flags = 0;
536                                                                 v->regoff = rd->argintregs[iargcnt];
537                                                                 iargcnt++;
538                                                                 arg++;
539                                                         }
540                                                         else {
541                                                                 v->flags = INMEMORY;
542                                                                 v->regoff = rd->maxmemuse;
543                                                                 rd->maxmemuse += regsneeded + 1;
544                                                         }
545 #if defined(__I386__)
546                                                 }
547 #endif
548                                                 intalloc = t;
549                                         }
550                                 }
551                         }
552                         if (arg < m->paramcount) {
553                                 if (doublewordarg) {
554                                         doublewordarg = 0;
555                                         /* what type was the double arg? */
556                                         if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
557                                                 fargcnt++;
558
559                                         } else {
560                                                 iargcnt++;
561                                         }
562                                         arg++;
563
564                                 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
565                                         doublewordarg = 1;
566
567                                 } else {
568                                         if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
569                                                 fargcnt++;
570
571                                         } else {
572                                                 iargcnt++;
573                                         }
574                                         arg++;
575                                 }
576                         }
577                 }
578                 return;
579         }
580
581         for (s = 0; s < cd->maxlocals; s++) {
582                 intalloc = -1; fltalloc = -1;
583                 for (tt=0; tt<=4; tt++) {
584                         t = typeloop[tt];
585                         v = &rd->locals[s][t];
586                         if (v->type >= 0) {
587 #ifdef USETWOREGS
588                                 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
589 #endif
590                                 if (IS_FLT_DBL_TYPE(t)) {
591                                         if (fltalloc >= 0) {
592                                                 v->flags = rd->locals[s][fltalloc].flags;
593                                                 v->regoff = rd->locals[s][fltalloc].regoff;
594                                         }
595                                         else if (rd->maxsavfltreguse > 0) {
596                                                 rd->maxsavfltreguse--;
597                                                 v->flags = 0;
598                                                 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
599                                         }
600                                         else {
601                                                 v->flags = INMEMORY;
602                                                 v->regoff = rd->maxmemuse;
603                                                 rd->maxmemuse += regsneeded + 1;
604                                         }
605                                         fltalloc = t;
606                                 }
607                                 else {
608 #if defined(__I386__)
609                                         /*
610                                          * for i386 put all longs in memory
611                                          */
612                                         if (IS_2_WORD_TYPE(t)) {
613                                                 v->flags = INMEMORY;
614                                                 v->regoff = rd->maxmemuse++;
615                                         } else {
616 #endif
617                                                 if (intalloc >= 0) {
618                                                         v->flags = rd->locals[s][intalloc].flags;
619                                                         v->regoff = rd->locals[s][intalloc].regoff;
620                                                 }
621                                                 else if (rd->maxsavintreguse > regsneeded) {
622                                                         rd->maxsavintreguse -= regsneeded+1;
623                                                         v->flags = 0;
624                                                         v->regoff = rd->savintregs[rd->maxsavintreguse];
625                                                 }
626                                                 else {
627                                                         v->flags = INMEMORY;
628                                                         v->regoff = rd->maxmemuse;
629                                                         rd->maxmemuse += regsneeded + 1;
630                                                 }
631 #if defined(__I386__)
632                                         }
633 #endif
634                                         intalloc = t;
635                                 }
636                         }
637                 }
638         }
639 }
640
641
642
643 static void reg_init_temp(registerdata *rd)
644 {
645         rd->freememtop = 0;
646         rd->memuse = rd->ifmemuse;
647
648         rd->freetmpinttop = 0;
649         rd->freesavinttop = 0;
650         rd->freetmpflttop = 0;
651         rd->freesavflttop = 0;
652
653         rd->tmpintreguse = rd->iftmpintregcnt;
654         rd->savintreguse = rd->ifsavintregcnt;
655         rd->tmpfltreguse = rd->iftmpfltregcnt;
656         rd->savfltreguse = rd->ifsavfltregcnt;
657
658         /* all argument registers are available */
659         rd->argintreguse = rd->intreg_argnum;
660         rd->argfltreguse = rd->fltreg_argnum;
661 }
662
663
664 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
665
666
667 static void reg_new_temp_func(registerdata *rd, stackptr s)
668 {
669         s4 regsneeded;
670         s4 tryagain;
671
672         /* Try to allocate a saved register if there is no temporary one          */
673         /* available. This is what happens during the second run.                 */
674         tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
675
676 #ifdef USETWOREGS
677         regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
678 #else
679         regsneeded = 0;
680 #endif
681
682         for(; tryagain; --tryagain) {
683                 if (tryagain == 1) {
684                         if (!(s->flags & SAVEDVAR))
685                                 s->flags |= SAVEDTMP;
686                         if (IS_FLT_DBL_TYPE(s->type)) {
687                                 if (rd->freesavflttop > 0) {
688                                         rd->freesavflttop--;
689                                         s->regoff = rd->freesavfltregs[rd->freesavflttop];
690                                         return;
691
692                                 } else if (rd->savfltreguse > 0) {
693                                         rd->savfltreguse--;
694                                         if (rd->savfltreguse < rd->maxsavfltreguse)
695                                                 rd->maxsavfltreguse = rd->savfltreguse;
696                                         s->regoff = rd->savfltregs[rd->savfltreguse];
697                                         return;
698                                 }
699
700                         } else {
701 #if defined(__I386__)
702                                 /*
703                                  * for i386 put all longs in memory
704                                  */
705                                 if (!IS_2_WORD_TYPE(s->type)) {
706 #endif
707                                         if (rd->freesavinttop > regsneeded) {
708                                                 rd->freesavinttop -= regsneeded + 1;
709                                                 s->regoff = rd->freesavintregs[rd->freesavinttop];
710                                                 return;
711
712                                         } else if (rd->savintreguse > regsneeded) {
713                                                 rd->savintreguse -= regsneeded + 1;
714                                                 if (rd->savintreguse < rd->maxsavintreguse)
715                                                         rd->maxsavintreguse = rd->savintreguse;
716                                                 s->regoff = rd->savintregs[rd->savintreguse];
717                                                 return;
718                                         }
719 #if defined(__I386__)
720                                 }
721 #endif
722                         }
723
724                 } else {
725                         if (IS_FLT_DBL_TYPE(s->type)) {
726                                 if (rd->freetmpflttop > 0) {
727                                         rd->freetmpflttop--;
728                                         s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
729                                         return;
730
731                                 } else if (rd->tmpfltreguse > 0) {
732                                         rd->tmpfltreguse--;
733                                         if (rd->tmpfltreguse < rd->maxtmpfltreguse)
734                                                 rd->maxtmpfltreguse = rd->tmpfltreguse;
735                                         s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
736                                         return;
737                                 }
738
739                         } else {
740 #if defined(__I386__)
741                                 /*
742                                  * for i386 put all longs in memory
743                                  */
744                                 if (!IS_2_WORD_TYPE(s->type)) {
745 #endif
746                                         if (rd->freetmpinttop > regsneeded) {
747                                                 rd->freetmpinttop -= regsneeded + 1;
748                                                 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
749                                                 return;
750
751                                         } else if (rd->tmpintreguse > regsneeded) {
752                                                 rd->tmpintreguse -= regsneeded + 1;
753                                                 if (rd->tmpintreguse < rd->maxtmpintreguse)
754                                                         rd->maxtmpintreguse = rd->tmpintreguse;
755                                                 s->regoff = rd->tmpintregs[rd->tmpintreguse];
756                                                 return;
757                                         }
758 #if defined(__I386__)
759                                 }
760 #endif
761                         }
762                 }
763         }
764
765         if (rd->freememtop > regsneeded) {
766                 rd->freememtop -= regsneeded + 1;
767                 s->regoff = rd->freemem[rd->freememtop];
768
769         } else {
770                 s->regoff = rd->memuse;
771                 rd->memuse += regsneeded + 1;
772                 if (rd->memuse > rd->maxmemuse)
773                         rd->maxmemuse = rd->memuse;
774         }
775         s->flags |= INMEMORY;
776 }
777
778
779 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
780
781
782 static void reg_free_temp_func(registerdata *rd, stackptr s)
783 {
784         s4 regsneeded;
785
786 #ifdef USETWOREGS
787         regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
788 #else
789         regsneeded = 0;
790 #endif
791
792         if (s->flags & INMEMORY) {
793                 rd->freemem[rd->freememtop] = s->regoff;
794                 if (regsneeded)
795                         rd->freemem[rd->freememtop + 1] = s->regoff + 1;
796                 rd->freememtop += regsneeded + 1;
797
798         } else if (IS_FLT_DBL_TYPE(s->type)) {
799                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
800                         s->flags &= ~SAVEDTMP;
801                         rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
802
803                 } else
804                         rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
805
806         } else {
807                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
808                         s->flags &= ~SAVEDTMP;
809                         rd->freesavintregs[rd->freesavinttop] = s->regoff;
810 #ifdef USETWOREGS
811                         if (regsneeded)
812                                 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
813 #endif
814                         rd->freesavinttop += regsneeded + 1;
815
816                 } else {
817                         rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
818 #ifdef USETWOREGS
819                         if (regsneeded)
820                                 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
821 #endif
822                         rd->freetmpinttop += regsneeded + 1;
823                 }
824         }
825 }
826
827
828
829 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
830 {
831         s4 opcode;
832         s4 i;
833         s4 len;
834         stackptr    src;
835         stackptr    dst;
836         instruction *iptr;
837         basicblock  *bptr;
838
839         bptr = m->basicblocks;
840
841         while (bptr != NULL) {
842                 if (bptr->flags >= BBREACHED) {
843                         dst = bptr->instack;
844
845                         /* initialize temp registers */
846                         reg_init_temp(rd);
847
848                         iptr = bptr->iinstr;
849                         len = bptr->icount;
850
851                         while (--len >= 0)  {
852                                 src = dst;
853                                 dst = iptr->dst;
854                                 opcode = iptr->opc;
855
856                                 switch (opcode) {
857
858                                         /* pop 0 push 0 */
859
860                                 case ICMD_NOP:
861                                 case ICMD_ELSE_ICONST:
862                                 case ICMD_CHECKASIZE:
863                                 case ICMD_CHECKEXCEPTION:
864                                 case ICMD_IINC:
865                                 case ICMD_JSR:
866                                 case ICMD_RET:
867                                 case ICMD_RETURN:
868                                 case ICMD_GOTO:
869                                 case ICMD_INLINE_START:
870                                 case ICMD_INLINE_END:
871                                         break;
872
873                                         /* pop 0 push 1 const */
874                                         
875                                 case ICMD_ICONST:
876                                 case ICMD_LCONST:
877                                 case ICMD_FCONST:
878                                 case ICMD_DCONST:
879                                 case ICMD_ACONST:
880
881                                         /* pop 0 push 1 load */
882                                         
883                                 case ICMD_ILOAD:
884                                 case ICMD_LLOAD:
885                                 case ICMD_FLOAD:
886                                 case ICMD_DLOAD:
887                                 case ICMD_ALOAD:
888                                         reg_new_temp(rd, dst);
889                                         break;
890
891                                         /* pop 2 push 1 */
892
893                                 case ICMD_IALOAD:
894                                 case ICMD_LALOAD:
895                                 case ICMD_FALOAD:
896                                 case ICMD_DALOAD:
897                                 case ICMD_AALOAD:
898
899                                 case ICMD_BALOAD:
900                                 case ICMD_CALOAD:
901                                 case ICMD_SALOAD:
902                                         reg_free_temp(rd, src);
903                                         reg_free_temp(rd, src->prev);
904                                         reg_new_temp(rd, dst);
905                                         break;
906
907                                         /* pop 3 push 0 */
908
909                                 case ICMD_IASTORE:
910                                 case ICMD_LASTORE:
911                                 case ICMD_FASTORE:
912                                 case ICMD_DASTORE:
913                                 case ICMD_AASTORE:
914
915                                 case ICMD_BASTORE:
916                                 case ICMD_CASTORE:
917                                 case ICMD_SASTORE:
918                                         reg_free_temp(rd, src);
919                                         reg_free_temp(rd, src->prev);
920                                         reg_free_temp(rd, src->prev->prev);
921                                         break;
922
923                                         /* pop 1 push 0 store */
924
925                                 case ICMD_ISTORE:
926                                 case ICMD_LSTORE:
927                                 case ICMD_FSTORE:
928                                 case ICMD_DSTORE:
929                                 case ICMD_ASTORE:
930
931                                         /* pop 1 push 0 */
932
933                                 case ICMD_POP:
934
935                                 case ICMD_IRETURN:
936                                 case ICMD_LRETURN:
937                                 case ICMD_FRETURN:
938                                 case ICMD_DRETURN:
939                                 case ICMD_ARETURN:
940
941                                 case ICMD_ATHROW:
942
943                                 case ICMD_PUTSTATIC:
944
945                                         /* pop 1 push 0 branch */
946
947                                 case ICMD_IFNULL:
948                                 case ICMD_IFNONNULL:
949
950                                 case ICMD_IFEQ:
951                                 case ICMD_IFNE:
952                                 case ICMD_IFLT:
953                                 case ICMD_IFGE:
954                                 case ICMD_IFGT:
955                                 case ICMD_IFLE:
956
957                                 case ICMD_IF_LEQ:
958                                 case ICMD_IF_LNE:
959                                 case ICMD_IF_LLT:
960                                 case ICMD_IF_LGE:
961                                 case ICMD_IF_LGT:
962                                 case ICMD_IF_LLE:
963
964                                         /* pop 1 push 0 table branch */
965
966                                 case ICMD_TABLESWITCH:
967                                 case ICMD_LOOKUPSWITCH:
968
969                                 case ICMD_NULLCHECKPOP:
970                                 case ICMD_MONITORENTER:
971                                 case ICMD_MONITOREXIT:
972                                         reg_free_temp(rd, src);
973                                         break;
974
975                                         /* pop 2 push 0 branch */
976
977                                 case ICMD_IF_ICMPEQ:
978                                 case ICMD_IF_ICMPNE:
979                                 case ICMD_IF_ICMPLT:
980                                 case ICMD_IF_ICMPGE:
981                                 case ICMD_IF_ICMPGT:
982                                 case ICMD_IF_ICMPLE:
983
984                                 case ICMD_IF_LCMPEQ:
985                                 case ICMD_IF_LCMPNE:
986                                 case ICMD_IF_LCMPLT:
987                                 case ICMD_IF_LCMPGE:
988                                 case ICMD_IF_LCMPGT:
989                                 case ICMD_IF_LCMPLE:
990
991                                 case ICMD_IF_ACMPEQ:
992                                 case ICMD_IF_ACMPNE:
993
994                                         /* pop 2 push 0 */
995
996                                 case ICMD_POP2:
997
998                                 case ICMD_PUTFIELD:
999
1000                                 case ICMD_IASTORECONST:
1001                                 case ICMD_LASTORECONST:
1002                                 case ICMD_AASTORECONST:
1003                                 case ICMD_BASTORECONST:
1004                                 case ICMD_CASTORECONST:
1005                                 case ICMD_SASTORECONST:
1006                                         reg_free_temp(rd, src);
1007                                         reg_free_temp(rd, src->prev);
1008                                         break;
1009
1010                                         /* pop 0 push 1 dup */
1011                                         
1012                                 case ICMD_DUP:
1013                                         reg_new_temp(rd, dst);
1014                                         break;
1015
1016                                         /* pop 0 push 2 dup */
1017                                         
1018                                 case ICMD_DUP2:
1019                                         reg_new_temp(rd, dst->prev);
1020                                         reg_new_temp(rd, dst);
1021                                         break;
1022
1023                                         /* pop 2 push 3 dup */
1024                                         
1025                                 case ICMD_DUP_X1:
1026                                         reg_free_temp(rd, src);
1027                                         reg_new_temp(rd, dst);
1028                                         reg_free_temp(rd, src->prev);
1029                                         reg_new_temp(rd, dst->prev);
1030                                         reg_new_temp(rd, dst->prev->prev);
1031                                         break;
1032
1033                                         /* pop 3 push 4 dup */
1034                                         
1035                                 case ICMD_DUP_X2:
1036                                         reg_free_temp(rd, src);
1037                                         reg_new_temp(rd, dst);
1038                                         reg_free_temp(rd, src->prev);
1039                                         reg_new_temp(rd, dst->prev);
1040                                         reg_free_temp(rd, src->prev->prev);
1041                                         reg_new_temp(rd, dst->prev->prev);
1042                                         reg_new_temp(rd, dst->prev->prev->prev);
1043                                         break;
1044
1045                                         /* pop 3 push 5 dup */
1046                                         
1047                                 case ICMD_DUP2_X1:
1048                                         reg_free_temp(rd, src);
1049                                         reg_new_temp(rd, dst);
1050                                         reg_free_temp(rd, src->prev);
1051                                         reg_new_temp(rd, dst->prev);
1052                                         reg_free_temp(rd, src->prev->prev);
1053                                         reg_new_temp(rd, dst->prev->prev);
1054                                         reg_new_temp(rd, dst->prev->prev->prev);
1055                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1056                                         break;
1057
1058                                         /* pop 4 push 6 dup */
1059                                         
1060                                 case ICMD_DUP2_X2:
1061                                         reg_free_temp(rd, src);
1062                                         reg_new_temp(rd, dst);
1063                                         reg_free_temp(rd, src->prev);
1064                                         reg_new_temp(rd, dst->prev);
1065                                         reg_free_temp(rd, src->prev->prev);
1066                                         reg_new_temp(rd, dst->prev->prev);
1067                                         reg_free_temp(rd, src->prev->prev->prev);
1068                                         reg_new_temp(rd, dst->prev->prev->prev);
1069                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1070                                         reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1071                                         break;
1072
1073                                         /* pop 2 push 2 swap */
1074                                         
1075                                 case ICMD_SWAP:
1076                                         reg_free_temp(rd, src);
1077                                         reg_new_temp(rd, dst->prev);
1078                                         reg_free_temp(rd, src->prev);
1079                                         reg_new_temp(rd, dst);
1080                                         break;
1081
1082                                         /* pop 2 push 1 */
1083                                         
1084                                 case ICMD_IADD:
1085                                 case ICMD_ISUB:
1086                                 case ICMD_IMUL:
1087                                 case ICMD_IDIV:
1088                                 case ICMD_IREM:
1089
1090                                 case ICMD_ISHL:
1091                                 case ICMD_ISHR:
1092                                 case ICMD_IUSHR:
1093                                 case ICMD_IAND:
1094                                 case ICMD_IOR:
1095                                 case ICMD_IXOR:
1096
1097                                 case ICMD_LADD:
1098                                 case ICMD_LSUB:
1099                                 case ICMD_LMUL:
1100                                 case ICMD_LDIV:
1101                                 case ICMD_LREM:
1102
1103                                 case ICMD_LOR:
1104                                 case ICMD_LAND:
1105                                 case ICMD_LXOR:
1106
1107                                 case ICMD_LSHL:
1108                                 case ICMD_LSHR:
1109                                 case ICMD_LUSHR:
1110
1111                                 case ICMD_FADD:
1112                                 case ICMD_FSUB:
1113                                 case ICMD_FMUL:
1114                                 case ICMD_FDIV:
1115                                 case ICMD_FREM:
1116
1117                                 case ICMD_DADD:
1118                                 case ICMD_DSUB:
1119                                 case ICMD_DMUL:
1120                                 case ICMD_DDIV:
1121                                 case ICMD_DREM:
1122
1123                                 case ICMD_LCMP:
1124                                 case ICMD_FCMPL:
1125                                 case ICMD_FCMPG:
1126                                 case ICMD_DCMPL:
1127                                 case ICMD_DCMPG:
1128                                         reg_free_temp(rd, src);
1129                                         reg_free_temp(rd, src->prev);
1130                                         reg_new_temp(rd, dst);
1131                                         break;
1132
1133                                         /* pop 1 push 1 */
1134                                         
1135                                 case ICMD_IADDCONST:
1136                                 case ICMD_ISUBCONST:
1137                                 case ICMD_IMULCONST:
1138                                 case ICMD_IDIVPOW2:
1139                                 case ICMD_IREMPOW2:
1140                                 case ICMD_IANDCONST:
1141                                 case ICMD_IORCONST:
1142                                 case ICMD_IXORCONST:
1143                                 case ICMD_ISHLCONST:
1144                                 case ICMD_ISHRCONST:
1145                                 case ICMD_IUSHRCONST:
1146
1147                                 case ICMD_LADDCONST:
1148                                 case ICMD_LSUBCONST:
1149                                 case ICMD_LMULCONST:
1150                                 case ICMD_LDIVPOW2:
1151                                 case ICMD_LREMPOW2:
1152                                 case ICMD_LANDCONST:
1153                                 case ICMD_LORCONST:
1154                                 case ICMD_LXORCONST:
1155                                 case ICMD_LSHLCONST:
1156                                 case ICMD_LSHRCONST:
1157                                 case ICMD_LUSHRCONST:
1158
1159                                 case ICMD_IFEQ_ICONST:
1160                                 case ICMD_IFNE_ICONST:
1161                                 case ICMD_IFLT_ICONST:
1162                                 case ICMD_IFGE_ICONST:
1163                                 case ICMD_IFGT_ICONST:
1164                                 case ICMD_IFLE_ICONST:
1165
1166                                 case ICMD_INEG:
1167                                 case ICMD_INT2BYTE:
1168                                 case ICMD_INT2CHAR:
1169                                 case ICMD_INT2SHORT:
1170                                 case ICMD_LNEG:
1171                                 case ICMD_FNEG:
1172                                 case ICMD_DNEG:
1173
1174                                 case ICMD_I2L:
1175                                 case ICMD_I2F:
1176                                 case ICMD_I2D:
1177                                 case ICMD_L2I:
1178                                 case ICMD_L2F:
1179                                 case ICMD_L2D:
1180                                 case ICMD_F2I:
1181                                 case ICMD_F2L:
1182                                 case ICMD_F2D:
1183                                 case ICMD_D2I:
1184                                 case ICMD_D2L:
1185                                 case ICMD_D2F:
1186
1187                                 case ICMD_CHECKCAST:
1188
1189                                 case ICMD_ARRAYLENGTH:
1190                                 case ICMD_INSTANCEOF:
1191
1192                                 case ICMD_NEWARRAY:
1193                                 case ICMD_ANEWARRAY:
1194
1195                                 case ICMD_GETFIELD:
1196                                         reg_free_temp(rd, src);
1197                                         reg_new_temp(rd, dst);
1198                                         break;
1199
1200                                         /* pop 0 push 1 */
1201                                         
1202                                 case ICMD_GETSTATIC:
1203
1204                                 case ICMD_NEW:
1205                                         reg_new_temp(rd, dst);
1206                                         break;
1207
1208                                         /* pop many push any */
1209                                         
1210                                 case ICMD_INVOKEVIRTUAL:
1211                                 case ICMD_INVOKESPECIAL:
1212                                 case ICMD_INVOKESTATIC:
1213                                 case ICMD_INVOKEINTERFACE:
1214                                         i = iptr->op1;
1215                                         while (--i >= 0) {
1216                                                 reg_free_temp(rd, src);
1217                                                 src = src->prev;
1218                                         }
1219                                         if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1220                                                 reg_new_temp(rd, dst);
1221                                         break;
1222
1223                                 case ICMD_BUILTIN3:
1224                                         reg_free_temp(rd, src);
1225                                         src = src->prev;
1226                                 case ICMD_BUILTIN2:
1227                                         reg_free_temp(rd, src);
1228                                         src = src->prev;
1229                                 case ICMD_BUILTIN1:
1230                                         reg_free_temp(rd, src);
1231                                         src = src->prev;
1232                                         if (iptr->op1 != TYPE_VOID)
1233                                                 reg_new_temp(rd, dst);
1234                                         break;
1235
1236                                 case ICMD_MULTIANEWARRAY:
1237                                         i = iptr->op1;
1238                                         while (--i >= 0) {
1239                                                 reg_free_temp(rd, src);
1240                                                 src = src->prev;
1241                                         }
1242                                         reg_new_temp(rd, dst);
1243                                         break;
1244
1245                                 default:
1246                                         printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1247                                         panic("Missing ICMD code during register allocation");
1248                                 } /* switch */
1249                                 iptr++;
1250                         } /* while instructions */
1251                 } /* if */
1252                 bptr = bptr->next;
1253         } /* while blocks */
1254 }
1255
1256
1257 /*
1258  * These are local overrides for various environment variables in Emacs.
1259  * Please do not remove this and leave it at the end of the file, where
1260  * Emacs will automagically detect them.
1261  * ---------------------------------------------------------------------
1262  * Local variables:
1263  * mode: c
1264  * indent-tabs-mode: t
1265  * c-basic-offset: 4
1266  * tab-width: 4
1267  * End:
1268  */