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