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