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