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