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