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