new Stack memory allocation, use of unused arg regs as temp disabled
[cacao.git] / src / vm / jit / reg.inc
1 /* src/vm/jit/reg.inc - register allocator
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    Changes: Stefan Ring
30             Christian Thalinger
31
32    $Id: reg.inc 2620 2005-06-09 07:28:50Z christian $
33
34 */
35
36
37 #include "arch.h"
38 #include "mm/memory.h"
39 #include "vm/method.h"   
40 #include "vm/resolve.h"
41 #include "vm/jit/reg.h"
42
43
44 /* function prototypes for this file */
45
46 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
47 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
48 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
49
50
51 /* reg_init ********************************************************************
52
53    TODO
54         
55 *******************************************************************************/
56
57 void reg_init()
58 {
59         /* void */
60 }
61
62
63 /* reg_setup *******************************************************************
64
65    TODO
66
67 *******************************************************************************/
68
69 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
70 {
71         s4 i;
72         varinfo5 *v;
73
74         /* setup the integer register table */
75         rd->intreg_argnum = 0;
76         rd->tmpintregcnt = 0;
77         rd->savintregcnt = 0;
78
79         for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
80                 switch (nregdescint[rd->intregsnum]) {
81                 case REG_SAV:
82                         rd->savintregcnt++;
83                         break;
84                 case REG_TMP:
85                         rd->tmpintregcnt++;
86                         break;
87                 case REG_ARG:
88                         rd->intreg_argnum++;
89                         break;
90                 }
91         }
92
93         rd->argintregs = DMNEW(s4, rd->intreg_argnum);
94         rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
95         rd->savintregs = DMNEW(s4, rd->savintregcnt);
96         rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
97         rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
98         rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
99 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
100         rd->secondregs = DMNEW(s4, rd->intregsnum);
101 #endif
102
103         rd->intreg_argnum = 0;
104         rd->argintreguse = 0;
105         rd->tmpintreguse = 0;
106         rd->savintreguse = 0;
107
108         for (i = 0; i < rd->intregsnum; i++) {
109                 switch (nregdescint[i]) {
110                 case REG_RET:
111                         rd->intreg_ret = i; 
112                         break;
113                 case REG_SAV:
114                         rd->savintregs[rd->savintreguse++] = i;
115                         break;
116                 case REG_TMP:
117                         rd->tmpintregs[rd->tmpintreguse++] = i; 
118                         break;
119                 case REG_ARG:
120                         rd->argintregs[rd->intreg_argnum++] = i;
121                         rd->argintreguse++;
122                         break;
123                 }
124         }
125
126 #if defined(__X86_64__)
127         /* 
128          * on x86_64 the argument registers are not in ascending order 
129          * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
130          */
131         i = rd->argintregs[3];
132         rd->argintregs[3] = rd->argintregs[0];
133         rd->argintregs[0] = i;
134
135         i = rd->argintregs[2];
136         rd->argintregs[2] = rd->argintregs[1];
137         rd->argintregs[1] = i;
138 #endif
139                 
140 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
141         for (i = 1; i < rd->intreg_argnum; i++)
142                 rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
143         for (i = 1; i < rd->tmpintregcnt; i++)
144                 rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
145         for (i = 1; i < rd->savintregcnt; i++)
146                 rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
147
148         rd->secondregs[REG_ITMP1] = REG_ITMP2;
149         rd->secondregs[REG_ITMP3] = REG_ITMP2;
150         rd->secondregs[REG_RESULT] = REG_RESULT + 1;
151         rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
152 #endif
153
154 #ifdef HAS_ADDRESS_REGISTER_FILE
155         /* setup the address register table */
156         rd->adrreg_argnum = 0;
157         rd->tmpadrregcnt = 0;
158         rd->savadrregcnt = 0;
159
160         for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) {
161                 switch (nregdescadr[rd->adrregsnum]) {
162                 case REG_SAV:
163                         rd->savadrregcnt++;
164                         break;
165                 case REG_TMP:
166                         rd->tmpadrregcnt++;
167                         break;
168                 case REG_ARG:
169                         rd->adrreg_argnum++;
170                         break;
171                 }
172         }
173
174         rd->argadrregs = DMNEW(s4, rd->adrreg_argnum);
175         rd->tmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
176         rd->savadrregs = DMNEW(s4, rd->savadrregcnt);
177         rd->freeargadrregs = DMNEW(s4, rd->adrreg_argnum);
178         rd->freetmpadrregs = DMNEW(s4, rd->tmpadrregcnt);
179         rd->freesavadrregs = DMNEW(s4, rd->savadrregcnt);
180
181         rd->adrreg_argnum = 0;
182         rd->argadrreguse = 0;
183         rd->tmpadrreguse = 0;
184         rd->savadrreguse = 0;
185
186         for (i = 0; i < rd->adrregsnum; i++) {
187                 switch (nregdescadr[i]) {
188                 case REG_RET:
189                         rd->adrreg_ret = i; 
190                         break;
191                 case REG_SAV:
192                         rd->savadrregs[rd->savadrreguse++] = i;
193                         break;
194                 case REG_TMP:
195                         rd->tmpadrregs[rd->tmpadrreguse++] = i; 
196                         break;
197                 case REG_ARG:
198                         rd->argadrregs[rd->adrreg_argnum++] = i;
199                         rd->argadrreguse++;
200                         break;
201                 }
202         }
203 #endif
204                 
205         /* setup the float register table */
206         rd->fltreg_argnum = 0;
207         rd->tmpfltregcnt = 0;
208         rd->savfltregcnt = 0;
209
210         for (rd->fltregsnum = 0; nregdescfloat[rd->fltregsnum] != REG_END; rd->fltregsnum++) {
211                 switch (nregdescfloat[rd->fltregsnum]) {
212                 case REG_SAV:
213                         rd->savfltregcnt++;
214                         break;
215                 case REG_TMP:
216                         rd->tmpfltregcnt++;
217                         break;
218                 case REG_ARG:
219                         rd->fltreg_argnum++;
220                         break;
221                 }
222         }
223
224         rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
225         rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
226         rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
227         rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
228         rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
229         rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
230
231         rd->fltreg_argnum = 0;
232         rd->argfltreguse = 0;
233         rd->tmpfltreguse = 0;
234         rd->savfltreguse = 0;
235
236         for (i = 0; i < rd->fltregsnum; i++) {
237                 switch (nregdescfloat[i]) {
238                 case REG_RET:
239                         rd->fltreg_ret = i;
240                         break;
241                 case REG_SAV:
242                         rd->savfltregs[rd->savfltreguse++] = i;
243                         break;
244                 case REG_TMP:
245                         rd->tmpfltregs[rd->tmpfltreguse++] = i;
246                         break;
247                 case REG_ARG:
248                         rd->argfltregs[rd->fltreg_argnum++] = i;
249                         rd->argfltreguse++;
250                         break;
251                 }
252         }
253
254
255         rd->freemem    = DMNEW(s4, id->cummaxstack);
256 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
257         rd->freemem_2  = DMNEW(s4, id->cummaxstack);
258 #endif
259         rd->locals     = DMNEW(varinfo5, id->cumlocals);
260         rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
261         for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
262                 v[0][TYPE_INT].type = -1;
263                 v[0][TYPE_LNG].type = -1;
264                 v[0][TYPE_FLT].type = -1;
265                 v[0][TYPE_DBL].type = -1;
266                 v[0][TYPE_ADR].type = -1;
267         }
268
269         for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
270                 v[0][TYPE_INT].type = -1;
271                 v[0][TYPE_INT].flags = 0;
272                 v[0][TYPE_LNG].type = -1;
273                 v[0][TYPE_LNG].flags = 0;
274                 v[0][TYPE_FLT].type = -1;
275                 v[0][TYPE_FLT].flags = 0;
276                 v[0][TYPE_DBL].type = -1;
277                 v[0][TYPE_DBL].flags = 0;
278                 v[0][TYPE_ADR].type = -1;
279                 v[0][TYPE_ADR].flags = 0;
280         }
281
282 #if defined(SPECIALMEMUSE)
283 # if defined(__DARWIN__)
284         rd->ifmemuse = LA_WORD_SIZE + INT_ARG_CNT; /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */
285 # else
286         rd->ifmemuse = LA_WORD_SIZE;
287 # endif
288 #else
289         rd->ifmemuse = 0; /* init to zero -> analyse_stack will set it to a higher value, if appropriate */
290 #endif
291
292 #if defined(HAS_ADDRESS_REGISTER_FILE)
293         rd->argadrreguse = 0;
294 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
295         rd->argintreguse = 0;/*Set argintreguse to rd->intreg_argnum to not use unused arguments as temp register*/
296         rd->argfltreguse = 0;/*Set argfltreguse to rd->fltreg_argnum to not use unused arguments as temp register*/
297 }
298
299
300 /* function reg_free ***********************************************************
301
302    releases all allocated space for registers
303
304 *******************************************************************************/
305
306 void reg_free(methodinfo *m, registerdata *rd)
307 {
308         /* void */
309 }
310
311
312 /* reg_close *******************************************************************
313
314    TODO
315
316 *******************************************************************************/
317
318 void reg_close()
319 {
320         /* void */
321 }
322
323
324 /* function interface_regalloc *************************************************
325
326         allocates registers for all interface variables
327         
328 *******************************************************************************/
329         
330 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
331 {
332         interface_regalloc(m, cd, rd);
333         allocate_scratch_registers(m, rd);
334         local_regalloc(m, cd, rd);
335 #ifdef INVOKE_NEW_DEBUG
336                 if (compileverbose) {
337                         printf("maxmemuse by reg.inc: %3i\n",rd->maxmemuse);
338                 }
339 #endif
340 }
341
342
343 /* function interface_regalloc *************************************************
344
345         allocates registers for all interface variables
346         
347 *******************************************************************************/
348         
349 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
350 {
351         int     s, t, saved;
352         int     intalloc, fltalloc; /* ?per Interface slot only one flt or one int type can be allocated to a register? */
353         varinfo *v;
354         int             intregsneeded = 0;
355         int             memneeded = 0;
356
357         /* rd->ifmemuse was already set in stack.c to allocate stack space for */
358         /* passing arguments to called methods                                 */
359         
360 #if defined(__I386__)
361         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
362                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
363                 if (rd->ifmemuse < 1)
364                         rd->ifmemuse = 1;
365         }
366 #endif
367 #ifdef INVOKE_NEW_DEBUG
368         if (compileverbose) {
369                 if (checksync && (m->flags & ACC_SYNCHRONIZED))
370                         printf("ACC_SYNCHRONIZED\n");
371                 printf("analyse: argintru %3i argfltru %3i ifmemu %3i\n", rd->argintreguse, rd->argfltreguse, rd->ifmemuse);
372         }
373 #endif
374
375         rd->iftmpintregcnt = rd->tmpintregcnt;
376         rd->ifsavintregcnt = rd->savintregcnt;
377         rd->iftmpfltregcnt = rd->tmpfltregcnt;
378         rd->ifsavfltregcnt = rd->savfltregcnt;
379 #ifdef HAS_ADDRESS_REGISTER_FILE
380         rd->iftmpadrregcnt = rd->tmpadrregcnt;
381         rd->ifsavadrregcnt = rd->savadrregcnt;
382 #endif
383         rd->ifargintregcnt = rd->argintreguse;
384         rd->ifargfltregcnt = rd->argfltreguse;
385         for (s = 0; s < cd->maxstack; s++) {
386                 intalloc = -1; fltalloc = -1;
387                 saved = (rd->interfaces[s][TYPE_INT].flags |
388                                  rd->interfaces[s][TYPE_LNG].flags |
389                          rd->interfaces[s][TYPE_FLT].flags |
390                                  rd->interfaces[s][TYPE_DBL].flags |
391                          rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
392  
393                 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
394                         v = &rd->interfaces[s][t];
395                         if (v->type >= 0) {
396 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
397                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
398 #endif
399 #if defined(HAS_4BYTE_STACKSLOT)
400                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
401 #endif
402                                 if (!saved) {
403 #if defined(HAS_ADDRESS_REGISTER_FILE)
404                                         if (t == TYPE_ADR) {
405                                                 if (!m->isleafmethod &&(rd->ifargadrregcnt < rd->adrreg_argnum)) {
406                                                         v->regoff = rd->argadrregs[rd->ifargadrregcnt++];
407                                                 } else 
408                                                         if (rd->iftmpadrregcnt > 0) {
409                                                                 rd->iftmpadrregcnt--;
410                                                                 v->regoff = rd->tmpadrregs[rd->iftmpadrregcnt];
411                                                         }
412                                                         else if (rd->ifsavadrregcnt > 0) {
413                                                                 rd->ifsavadrregcnt--;
414                                                                 v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
415                                                         }
416                                                         else {
417                                                                 v->flags |= INMEMORY;
418                                                                 v->regoff = rd->ifmemuse;
419                                                                 rd->ifmemuse++;
420                                                         }                                               
421                                         } else {
422 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
423                                                 if (IS_FLT_DBL_TYPE(t)) {
424                                                         if (fltalloc >= 0) {
425                                                                 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
426                                                                 v->regoff = rd->interfaces[s][fltalloc].regoff;
427                                                         }
428                                                         else if (!m->isleafmethod &&(rd->ifargfltregcnt < rd->fltreg_argnum)) {
429                                                                 v->regoff = rd->argfltregs[rd->ifargfltregcnt++];
430                                                         }
431                                                         else if (rd->iftmpfltregcnt > 0) {
432                                                                 rd->iftmpfltregcnt--;
433                                                                 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
434                                                         }
435                                                         else if (rd->ifsavfltregcnt > 0) {
436                                                                 rd->ifsavfltregcnt--;
437                                                                 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
438                                                         }
439                                                         else {
440                                                                 v->flags |= INMEMORY;
441                                                                 v->regoff = rd->ifmemuse;
442                                                                 rd->ifmemuse += memneeded + 1;
443                                                         }
444                                                         fltalloc = t;
445                                                 }
446                                                 else {
447                                                         /* #if defined(__I386__) */
448 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
449                                                         /*
450                                                          * for i386 put all longs in memory
451                                                          */
452                                                         if (IS_2_WORD_TYPE(t)) {
453                                                                 v->flags |= INMEMORY;
454                                                                 v->regoff = rd->ifmemuse;
455                                                                 rd->ifmemuse += memneeded + 1;
456                                                         } else
457 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
458 /* #if !defined(HAS_4BYTE_STACKSLOT) */
459                                                                 if (intalloc >= 0) {
460                                                                         v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
461                                                                         v->regoff = rd->interfaces[s][intalloc].regoff;
462                                                                 }
463                                                                 else 
464 /* #endif *//* !defined(HAS_4BYTE_STACKSLOT) */
465                                                                         if (!m->isleafmethod &&(rd->ifargintregcnt + intregsneeded < rd->intreg_argnum)) {
466                                                                                 v->regoff = rd->argintregs[rd->ifargintregcnt];
467                                                                                 rd->ifargintregcnt += intregsneeded + 1;
468                                                                         }
469                                                                         else if (rd->iftmpintregcnt > intregsneeded) {
470                                                                                 rd->iftmpintregcnt -= intregsneeded + 1;
471                                                                                 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
472                                                                         }
473                                                                         else if (rd->ifsavintregcnt > intregsneeded) {
474                                                                                 rd->ifsavintregcnt -= intregsneeded + 1;
475                                                                                 v->regoff = rd->savintregs[rd->ifsavintregcnt];
476                                                                         }
477                                                                         else {
478                                                                                 v->flags |= INMEMORY;
479                                                                                 v->regoff = rd->ifmemuse;
480                                                                                 rd->ifmemuse += memneeded + 1;
481                                                                         }
482
483                                                         intalloc = t;
484                                                 }
485 #ifdef HAS_ADDRESS_REGISTER_FILE
486                                         }
487 #endif
488                                 }
489                                 else {
490 #ifdef HAS_ADDRESS_REGISTER_FILE
491                                         if (t == TYPE_ADR) {
492                                                 if (rd->ifsavadrregcnt > 0) {
493                                                         rd->ifsavadrregcnt--;
494                                                         v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
495                                                 }
496                                                 else {
497                                                         v->flags |= INMEMORY;
498                                                         v->regoff = rd->ifmemuse;
499                                                         rd->ifmemuse++;
500                                                 }                                               
501                                         } else {
502 #endif
503                                         if (IS_FLT_DBL_TYPE(t)) {
504                                                 if (fltalloc >= 0) {
505                                                         v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
506                                                         v->regoff = rd->interfaces[s][fltalloc].regoff;
507                                                 } else
508                                                 if (rd->ifsavfltregcnt > 0) {
509                                                         rd->ifsavfltregcnt--;
510                                                         v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
511                                                 }
512                                                 else {
513                                                         v->flags |= INMEMORY;
514                                                         v->regoff = rd->ifmemuse;
515                                                         rd->ifmemuse += memneeded + 1;
516                                                 }
517                                                 fltalloc = t;
518                                         }
519                                         else {
520 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
521                                                 /*
522                                                  * for i386 put all longs in memory
523                                                  */
524                                                 if (IS_2_WORD_TYPE(t)) {
525                                                         v->flags |= INMEMORY;
526                                                         v->regoff = rd->ifmemuse;
527                                                         rd->ifmemuse += memneeded + 1;
528                                                 } else
529 #endif
530 /* #if !defined(HAS_4BYTE_STACKSLOT) */
531                                                         if (intalloc >= 0) {
532                                                                 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
533                                                                 v->regoff = rd->interfaces[s][intalloc].regoff;
534                                                         } else
535 /* #endif */
536                                                         if (rd->ifsavintregcnt > intregsneeded) {
537                                                                 rd->ifsavintregcnt -= intregsneeded + 1;
538                                                                 v->regoff = rd->savintregs[rd->ifsavintregcnt];
539                                                         }
540                                                         else {
541                                                                 v->flags |= INMEMORY;
542                                                                 v->regoff = rd->ifmemuse;
543                                                                 rd->ifmemuse += memneeded + 1;
544                                                         }
545                                                 intalloc = t;
546                                         }
547 #ifdef HAS_ADDRESS_REGISTER_FILE
548                                         }
549 #endif
550                                 }
551                         } /* if (type >= 0) */
552                 } /* for t */
553         } /* for s */
554
555         rd->maxmemuse = rd->ifmemuse;
556
557         rd->maxargintreguse = rd->ifargintregcnt;
558         rd->maxargfltreguse = rd->ifargfltregcnt;
559
560         rd->maxtmpintreguse = rd->iftmpintregcnt;
561         rd->maxsavintreguse = rd->ifsavintregcnt;
562
563         rd->maxtmpfltreguse = rd->iftmpfltregcnt;
564         rd->maxsavfltreguse = rd->ifsavfltregcnt;
565
566 #if defined(HAS_ADDRESS_REGISTER_FILE)
567
568         rd->maxargadrreguse = rd->ifargadrregcnt;
569         rd->maxtmpadrreguse = rd->iftmpadrregcnt;
570         rd->maxsavadrreguse = rd->ifsavadrregcnt;
571 #endif
572 }
573
574
575
576 /* function local_regalloc *****************************************************
577
578         allocates registers for all local variables
579         
580 *******************************************************************************/
581         
582 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
583 {
584         int     p, s, t, tt;
585         int     intalloc, fltalloc;
586         varinfo *v;
587         int     intregsneeded = 0;
588         int     memneeded = 0;
589         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
590         int     fargcnt, iargcnt;
591 #ifdef HAS_ADDRESS_REGISTER_FILE
592         int     aargcnt;
593 #endif
594 /*      if (cd->maxlocals > 0) */
595 /*              for (tt=0; tt<=4; tt++) { */
596 /*                      t = typeloop[tt]; */
597 /*                      printf("s %3i t %3i tt %3i rd->locals[0][t].type %3i \n",s,t,tt,rd->locals[0][t].type); */
598 /*              } */
599
600         if (m->isleafmethod) {
601                 methoddesc *md = m->parseddesc;
602
603                 iargcnt = md->argintreguse;
604                 fargcnt = md->argfltreguse;
605 #ifdef HAS_ADDRESS_REGISTER_FILE
606                 aargcnt = md->argadrreguse;
607 #endif
608                 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
609                         intalloc = -1; fltalloc = -1;
610                         for (tt = 0; tt <= 4; tt++) {
611                                 t = typeloop[tt];
612                                 v = &rd->locals[s][t];
613
614                                 if (v->type < 0)
615                                         continue;
616
617 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
618                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
619 #endif
620 #if defined(HAS_4BYTE_STACKSLOT)
621                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
622 #endif
623
624                                 /*
625                                  *  The order of
626                                  *
627                                  *  #ifdef HAS_ADDRESS_REGISTER_FILE
628                                  *  if (IS_ADR_TYPE) { 
629                                  *  ...
630                                  *  } else 
631                                  *  #endif
632                                  *  if (IS_FLT_DBL) {
633                                  *  ...
634                                  *  } else { / int & lng
635                                  *  ...
636                                  *  }
637                                  *
638                                  *  must not to be changed!
639                                  */
640
641 #ifdef HAS_ADDRESS_REGISTER_FILE
642                                 if (IS_ADR_TYPE(t)) {
643                                         if ((p < md->paramcount) && !md->params[p].inmemory) {
644                                                 v->flags = 0;
645                                                 v->regoff = rd->argadrregs[md->params[p].regoff];
646                                         }
647                                         if (rd->maxtmpadrreguse > 0) {
648                                                 rd->maxtmpadrreguse--;
649                                                 v->flags = 0;
650                                                 v->regoff = rd->tmpadrregs[rd->maxtmpadrreguse];
651                                         }
652                                         else if (rd->maxsavadrreguse > 0) {
653                                                 rd->maxsavadrreguse--;
654                                                 v->flags = 0;
655                                                 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
656                                         }
657                                         /* use unused argument registers as local registers */
658                                         else if ((p >= m->paramcount) &&
659                                                          (aargcnt < rd->adrreg_argnum)) {
660                                                 v->flags = 0;
661                                                 v->regoff = rd->argadrregs[aargcnt];
662                                                 aargcnt++;
663                                         }
664                                         else {
665                                                 v->flags |= INMEMORY;
666                                                 v->regoff = rd->ifmemuse;
667                                                 rd->ifmemuse++;
668                                         }                                               
669                                 } else {
670 #endif
671                                         if (IS_FLT_DBL_TYPE(t)) {
672                                                 if (fltalloc >= 0) {
673                                                         v->flags = rd->locals[s][fltalloc].flags;
674                                                         v->regoff = rd->locals[s][fltalloc].regoff;
675                                                 }
676                                                 else if ((p < md->paramcount) &&
677                                                                  !md->params[p].inmemory) {
678                                                         v->flags = 0;
679                                                         v->regoff = rd->argfltregs[md->params[p].regoff];
680                                                 }
681                                                 else if (rd->maxtmpfltreguse > 0) {
682                                                         rd->maxtmpfltreguse--;
683                                                         v->flags = 0;
684                                                         v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
685                                                 }
686                                                 else if (rd->maxsavfltreguse > 0) {
687                                                         rd->maxsavfltreguse--;
688                                                         v->flags = 0;
689                                                         v->regoff = rd->savfltregs[rd->maxsavfltreguse];
690                                                 }
691                                                 /* use unused argument registers as local registers */
692 /*                                              else if ((p >= m->paramcount) && */
693 /*                                                               (fargcnt < rd->fltreg_argnum)) { */
694 /*                                                      v->flags = 0; */
695 /*                                                      v->regoff = rd->argfltregs[fargcnt]; */
696 /*                                                      fargcnt++; */
697 /*                                              } */
698                                                 else {
699                                                         v->flags = INMEMORY;
700                                                         v->regoff = rd->maxmemuse;
701                                                         rd->maxmemuse += memneeded + 1;
702                                                 }
703                                                 fltalloc = t;
704
705                                         } else {
706 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
707                                                 /*
708                                                  * for i386 put all longs in memory
709                                                  */
710                                                 if (IS_2_WORD_TYPE(t)) {
711                                                         v->flags = INMEMORY;
712                                                         v->regoff = rd->maxmemuse;
713                                                         rd->maxmemuse += memneeded + 1;
714                                                 } else {
715 #endif
716                                                         if (intalloc >= 0) {
717                                                                 v->flags = rd->locals[s][intalloc].flags;
718                                                                 v->regoff = rd->locals[s][intalloc].regoff;
719                                                         }
720                                                         else if ((p < md->paramcount) && 
721                                                                          !md->params[p].inmemory) {
722                                                                 v->flags = 0;
723                                                                 v->regoff =
724                                                                         rd->argintregs[md->params[p].regoff];
725                                                         }
726                                                         else if (rd->maxtmpintreguse > intregsneeded) {
727                                                                 rd->maxtmpintreguse -= intregsneeded + 1;
728                                                                 v->flags = 0;
729                                                                 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
730                                                         }
731                                                         else if (rd->maxsavintreguse > intregsneeded) {
732                                                                 rd->maxsavintreguse -= intregsneeded + 1;
733                                                                 v->flags = 0;
734                                                                 v->regoff = rd->savintregs[rd->maxsavintreguse];
735                                                         }
736                                                         /*
737                                                          * use unused argument registers as local registers
738                                                          */
739 /*                                                      else if ((p >= m->paramcount) && */
740 /*                                                                       (iargcnt < rd->intreg_argnum)) { */
741 /*                                                              v->flags = 0; */
742 /*                                                              v->regoff = rd->argintregs[iargcnt]; */
743 /*                                                              iargcnt++; */
744 /*                                                      } */
745                                                         else {
746                                                                 v->flags = INMEMORY;
747                                                                 v->regoff = rd->maxmemuse;
748                                                                 rd->maxmemuse += memneeded + 1;
749                                                         }
750 #if defined(__I386__)
751                                                 }
752 #endif
753                                                 intalloc = t;
754                                         }
755 #ifdef HAS_ADDRESS_REGISTER_FILE
756                                 }
757 #endif
758                         } /* for (tt=0;...) */
759
760                         /* If the current parameter is a 2-word type, the next local slot */
761                         /* is skipped.                                                    */
762
763                         if (p < md->paramcount)
764                                 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
765                                         s++;
766                 }
767                 return;
768         }
769
770         for (s = 0; s < cd->maxlocals; s++) {
771                 intalloc = -1; fltalloc = -1;
772                 for (tt=0; tt<=4; tt++) {
773                         t = typeloop[tt];
774                         v = &rd->locals[s][t];
775 /*                      printf("s %3i t %3i tt %3i rd->locals[s][t].type %3i v->type %3i\n",s,t,tt,rd->locals[s][t].type, v->type); */
776                         if (v->type >= 0) {
777 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
778                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
779 #endif
780 #if defined(HAS_4BYTE_STACKSLOT)
781                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
782 #endif
783 #ifdef HAS_ADDRESS_REGISTER_FILE
784                                 if ( t == TYPE_ADR ) {
785                                         if (rd->maxsavadrreguse > 0) {
786                                                 rd->maxsavadrreguse--;
787                                                 v->flags = 0;
788                                                 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
789                                         }
790                                         else {
791                                                 v->flags = INMEMORY;
792                                                 v->regoff = rd->maxmemuse;
793                                                 rd->maxmemuse++;
794                                         }
795                                 } else {
796 #endif
797                                 if (IS_FLT_DBL_TYPE(t)) {
798                                         if (fltalloc >= 0) {
799                                                 v->flags = rd->locals[s][fltalloc].flags;
800                                                 v->regoff = rd->locals[s][fltalloc].regoff;
801                                         }
802                                         else if (rd->maxsavfltreguse > 0) {
803                                                 rd->maxsavfltreguse--;
804                                                 v->flags = 0;
805                                                 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
806                                         }
807                                         else {
808                                                 v->flags = INMEMORY;
809 #if defined(NEW_MEMORY) 
810                                                 if ( (memneeded) && (rd->maxmemuse&1))
811                                                         rd->maxmemuse++;
812 #endif
813                                                 v->regoff = rd->maxmemuse;
814                                                 rd->maxmemuse += memneeded + 1;
815                                         }
816                                         fltalloc = t;
817                                 }
818                                 else {
819 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
820                                         /*
821                                          * for i386 put all longs in memory
822                                          */
823                                         if (IS_2_WORD_TYPE(t)) {
824                                                 v->flags = INMEMORY;
825                                                 v->regoff = rd->maxmemuse;
826                                                 rd->maxmemuse += memneeded + 1;
827                                         } else {
828 #endif
829                                                 if (intalloc >= 0) {
830                                                         v->flags = rd->locals[s][intalloc].flags;
831                                                         v->regoff = rd->locals[s][intalloc].regoff;
832                                                 }
833                                                 else if (rd->maxsavintreguse > intregsneeded) {
834                                                         rd->maxsavintreguse -= intregsneeded+1;
835                                                         v->flags = 0;
836                                                         v->regoff = rd->savintregs[rd->maxsavintreguse];
837                                                 }
838                                                 else {
839                                                         v->flags = INMEMORY;
840                                                         v->regoff = rd->maxmemuse;
841                                                         rd->maxmemuse += memneeded + 1;
842                                                 }
843 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
844                                         }
845 #endif
846                                         intalloc = t;
847                                 }
848 #ifdef HAS_ADDRESS_REGISTER_FILE
849                                 }
850 #endif
851
852                         }
853                 }
854         }
855 }
856
857 static void reg_init_temp(methodinfo *m, registerdata *rd)
858 {
859         rd->freememtop = 0;
860 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
861         rd->freememtop_2 = 0;
862 #endif
863         rd->memuse = rd->ifmemuse;
864
865         rd->freetmpinttop = 0;
866         rd->freesavinttop = 0;
867         rd->freetmpflttop = 0;
868         rd->freesavflttop = 0;
869 #ifdef HAS_ADDRESS_REGISTER_FILE
870         rd->freetmpadrtop = 0;
871         rd->freesavadrtop = 0;
872 #endif
873
874         rd->tmpintreguse = rd->iftmpintregcnt;
875         rd->savintreguse = rd->ifsavintregcnt;
876         rd->tmpfltreguse = rd->iftmpfltregcnt;
877         rd->savfltreguse = rd->ifsavfltregcnt;
878 #ifdef HAS_ADDRESS_REGISTER_FILE
879         rd->tmpadrreguse = rd->iftmpadrregcnt;
880         rd->savadrreguse = rd->ifsavadrregcnt;
881 #endif
882
883         rd->freearginttop = 0;
884         rd->freeargflttop = 0;
885 #ifdef HAS_ADDRESS_REGISTER_FILE
886         rd->freeargadrtop = 0;
887 #endif
888
889 #if 0
890         if (!m->isleafmethod) {
891                 rd->argintreguse = rd->ifargintregcnt;
892                 rd->argfltreguse = rd->ifargfltregcnt;
893  #ifdef HAS_ADDRESS_REGISTER_FILE
894                 rd->argadrreguse = rd->ifargadrregcnt;
895  #endif
896         } else {
897 #endif
898                 rd->argintreguse = rd->intreg_argnum;
899                 rd->argfltreguse = rd->fltreg_argnum;
900 #ifdef HAS_ADDRESS_REGISTER_FILE
901                 rd->argadrreguse = rd->adrreg_argnum;
902 #endif
903 #if 0
904         }
905 #endif
906 }
907
908 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
909
910
911 static void reg_new_temp_func(registerdata *rd, stackptr s)
912 {
913         s4 intregsneeded;
914         s4 memneeded;
915         s4 tryagain;
916
917         /* Try to allocate a saved register if there is no temporary one          */
918         /* available. This is what happens during the second run.                 */
919         tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
920
921 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
922         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
923 #else
924         intregsneeded = 0;
925 #endif
926 #if defined(HAS_4BYTE_STACKSLOT)
927         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
928 #else
929         memneeded = 0;
930 #endif
931
932         for(; tryagain; --tryagain) {
933                 if (tryagain == 1) {
934                         if (!(s->flags & SAVEDVAR))
935                                 s->flags |= SAVEDTMP;
936 #ifdef HAS_ADDRESS_REGISTER_FILE
937                         if (s->type == TYPE_ADR) {
938                                 if (rd->freesavadrtop > 0) {
939                                         rd->freesavadrtop--;
940                                         s->regoff = rd->freesavadrregs[rd->freesavadrtop];
941                                         return;
942
943                                 } else if (rd->savadrreguse > 0) {
944                                         rd->savadrreguse--;
945                                         if (rd->savadrreguse < rd->maxsavadrreguse)
946                                                 rd->maxsavadrreguse = rd->savadrreguse;
947                                         s->regoff = rd->savadrregs[rd->savadrreguse];
948                                         return;
949                                 }
950                         } else {
951 #endif
952                         if (IS_FLT_DBL_TYPE(s->type)) {
953                                 if (rd->freesavflttop > 0) {
954                                         rd->freesavflttop--;
955                                         s->regoff = rd->freesavfltregs[rd->freesavflttop];
956                                         return;
957
958                                 } else if (rd->savfltreguse > 0) {
959                                         rd->savfltreguse--;
960                                         if (rd->savfltreguse < rd->maxsavfltreguse)
961                                                 rd->maxsavfltreguse = rd->savfltreguse;
962                                         s->regoff = rd->savfltregs[rd->savfltreguse];
963                                         return;
964                                 }
965
966                         } else {
967 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
968                                 /*
969                                  * for i386 put all longs in memory
970                                  */
971                                 if (!IS_2_WORD_TYPE(s->type)) {
972 #endif
973                                         if (rd->freesavinttop > intregsneeded) {
974                                                 rd->freesavinttop -= intregsneeded + 1;
975                                                 s->regoff = rd->freesavintregs[rd->freesavinttop];
976                                                 return;
977
978                                         } else if (rd->savintreguse > intregsneeded) {
979                                                 rd->savintreguse -= intregsneeded + 1;
980                                                 if (rd->savintreguse < rd->maxsavintreguse)
981                                                         rd->maxsavintreguse = rd->savintreguse;
982                                                 s->regoff = rd->savintregs[rd->savintreguse];
983                                                 return;
984                                         }
985 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
986                                 }
987 #endif
988                         }
989 #ifdef HAS_ADDRESS_REGISTER_FILE
990                         }
991 #endif
992                 } else {
993 #ifdef HAS_ADDRESS_REGISTER_FILE
994                         if (s->type == TYPE_ADR) {
995                                 if (rd->freetmpadrtop > 0) {
996                                         rd->freetmpadrtop--;
997                                         s->regoff = rd->freetmpadrregs[rd->freetmpadrtop];
998                                         return;
999
1000                                 } else if (rd->tmpadrreguse > 0) {
1001                                         rd->tmpadrreguse--;
1002                                         if (rd->tmpadrreguse < rd->maxtmpadrreguse)
1003                                                 rd->maxtmpadrreguse = rd->tmpadrreguse;
1004                                         s->regoff = rd->tmpadrregs[rd->tmpadrreguse];
1005                                         return;
1006                                 }
1007                         } else {
1008 #endif
1009                                 if (IS_FLT_DBL_TYPE(s->type)) {
1010                                         if (rd->freeargflttop > 0) {
1011                                                 rd->freeargflttop --;
1012                                                 s->regoff = rd->freeargfltregs[rd->freeargflttop];
1013                                                 s->flags |= TMPARG;
1014                                                 return;
1015                                         } else if (rd->argfltreguse < rd->fltreg_argnum) {
1016                                                 if (rd->argfltreguse > rd->maxargfltreguse)
1017                                                         rd->maxargfltreguse = rd->argfltreguse;
1018                                                 s->regoff = rd->argfltregs[rd->argfltreguse++];
1019                                                 s->flags |= TMPARG;
1020                                                 return;
1021                                         } else if (rd->freetmpflttop > 0) {
1022                                                 rd->freetmpflttop--;
1023                                                 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
1024                                                 return;
1025
1026                                         } else if (rd->tmpfltreguse > 0) {
1027                                                 rd->tmpfltreguse--;
1028                                                 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
1029                                                         rd->maxtmpfltreguse = rd->tmpfltreguse;
1030                                                 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
1031                                                 return;
1032                                         }
1033
1034                                 } else {
1035 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1036                                 /*
1037                                  * for i386 put all longs in memory
1038                                  */
1039                                 if (!IS_2_WORD_TYPE(s->type)) {
1040 #endif
1041                                         if (rd->freearginttop > intregsneeded) {
1042                                                 rd->freearginttop -= intregsneeded + 1;
1043                                                 s->regoff = rd->freeargintregs[rd->freearginttop];
1044                                                 s->flags |= TMPARG;
1045                                                 return;
1046                                         } else if (rd->argintreguse < rd->intreg_argnum - intregsneeded) {
1047                                                 if (rd->argintreguse > rd->maxargintreguse)
1048                                                         rd->maxargintreguse = rd->argintreguse;
1049                                                 s->regoff = rd->argintregs[rd->argintreguse];
1050                                                 s->flags |= TMPARG;
1051                                                 rd->argintreguse += intregsneeded + 1;
1052                                                 return;
1053                                         } else if (rd->freetmpinttop > intregsneeded) {
1054                                                 rd->freetmpinttop -= intregsneeded + 1;
1055                                                 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
1056                                                 return;
1057
1058                                         } else if (rd->tmpintreguse > intregsneeded) {
1059                                                 rd->tmpintreguse -= intregsneeded + 1;
1060                                                 if (rd->tmpintreguse < rd->maxtmpintreguse)
1061                                                         rd->maxtmpintreguse = rd->tmpintreguse;
1062                                                 s->regoff = rd->tmpintregs[rd->tmpintreguse];
1063                                                 return;
1064                                         }
1065 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1066                                 }
1067 #endif
1068                         }
1069 #ifdef HAS_ADDRESS_REGISTER_FILE
1070                         }
1071 #endif
1072                 }
1073         }
1074
1075 #if defined(NEW_MEMORY) 
1076 #if defined(HAS_4BYTE_STACKSLOT)
1077         if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
1078                 rd->freememtop_2--;
1079                 s->regoff = rd->freemem_2[rd->freememtop_2];
1080         } else
1081 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1082                 if ((memneeded == 0) && (rd->freememtop > 0)) {
1083                         rd->freememtop--;;
1084                         s->regoff = rd->freemem[rd->freememtop];
1085                 } else {
1086 #if defined(HAS_4BYTE_STACKSLOT)
1087 /* align 2 Word Types */
1088 /*                      if ((memneeded) && (rd->memuse & 1 == 1)) {  */
1089 /*                              rd->freemem[rd->freememtop] = rd->memuse; */
1090 /*                              rd->freememtop++; */
1091 /*                              rd->memuse++; */
1092 /*                      } */
1093 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1094                         s->regoff = rd->memuse;
1095                         rd->memuse += memneeded + 1;
1096                         if (rd->memuse > rd->maxmemuse)
1097                                 rd->maxmemuse = rd->memuse;
1098                 }
1099 #else /* defined(NEW_MEMORY) */
1100         if ((rd->freememtop > memneeded) && (memneeded == 0)) {
1101                 rd->freememtop -= memneeded + 1;
1102                 s->regoff = rd->freemem[rd->freememtop];
1103         } else {
1104                 s->regoff = rd->memuse;
1105                 rd->memuse += memneeded + 1;
1106                 if (rd->memuse > rd->maxmemuse)
1107                         rd->maxmemuse = rd->memuse;
1108         }
1109 #endif /* defined(NEW_MEMORY) */
1110         s->flags |= INMEMORY;
1111 }
1112
1113
1114 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
1115
1116
1117 static void reg_free_temp_func(registerdata *rd, stackptr s)
1118 {
1119         s4 intregsneeded;
1120         s4 memneeded;
1121
1122 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1123         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1124 #else
1125         intregsneeded = 0;
1126 #endif
1127 #if defined(HAS_4BYTE_STACKSLOT)
1128         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1129 #else
1130         memneeded = 0;
1131 #endif
1132
1133         if (s->flags & INMEMORY) {
1134 #if defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT)
1135                 if (memneeded > 0) {
1136                         rd->freemem_2[rd->freememtop_2] = s->regoff;
1137                         rd->freememtop_2++;
1138                 } else {
1139                         rd->freemem[rd->freememtop] = s->regoff;
1140                         rd->freememtop++;
1141                 }
1142 #else
1143                 rd->freemem[rd->freememtop] = s->regoff;
1144                 if (memneeded)
1145                         rd->freemem[rd->freememtop + 1] = s->regoff + 1;
1146                 rd->freememtop += memneeded + 1;
1147 #endif /* defined(NEW_MEMORY) && defined(HAS_4BYTE_STACKSLOT */
1148 #ifdef HAS_ADDRESS_REGISTER_FILE
1149         } else if (s->type == TYPE_ADR) {
1150                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1151                         s->flags &= ~SAVEDTMP;
1152                         rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
1153
1154                 } else
1155                         rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
1156 #endif
1157         } else if (IS_FLT_DBL_TYPE(s->type)) {
1158                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1159                         s->flags &= ~SAVEDTMP;
1160                         rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
1161                 } else
1162                         if (s->flags & TMPARG) {
1163                                 s->flags &= ~TMPARG;
1164                                 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1165                         } else
1166                                 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1167         } else {
1168                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1169                         s->flags &= ~SAVEDTMP;
1170                         rd->freesavintregs[rd->freesavinttop] = s->regoff;
1171 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1172                         if (intregsneeded)
1173                                 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
1174 #endif
1175                         rd->freesavinttop += intregsneeded + 1;
1176
1177                 } else if (s->flags & TMPARG) {
1178                         s->flags &= ~TMPARG;
1179                         rd->freeargintregs[rd->freearginttop] = s->regoff;
1180 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1181                         if (intregsneeded)
1182                                 rd->freeargintregs[rd->freearginttop + 1] = rd->secondregs[s->regoff];
1183 #endif
1184                         rd->freearginttop += intregsneeded + 1;
1185                 } else {
1186                         rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1187 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1188                         if (intregsneeded)
1189                                 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
1190 #endif 
1191                         rd->freetmpinttop += intregsneeded + 1;
1192                 }
1193         }
1194 }
1195
1196
1197
1198 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
1199 {
1200         s4 opcode;
1201         s4 i;
1202         s4 len;
1203         stackptr    src;
1204         stackptr    dst;
1205         instruction *iptr;
1206         basicblock  *bptr;
1207
1208         bptr = m->basicblocks;
1209
1210         while (bptr != NULL) {
1211                 if (bptr->flags >= BBREACHED) {
1212                         dst = bptr->instack;
1213
1214                         /* initialize temp registers */
1215                         reg_init_temp(m, rd);
1216
1217                         iptr = bptr->iinstr;
1218                         len = bptr->icount;
1219
1220                         while (--len >= 0)  {
1221                                 src = dst;
1222                                 dst = iptr->dst;
1223                                 opcode = iptr->opc;
1224
1225                                 switch (opcode) {
1226
1227                                         /* pop 0 push 0 */
1228
1229                                 case ICMD_NOP:
1230                                 case ICMD_ELSE_ICONST:
1231                                 case ICMD_CHECKNULL:
1232                                 case ICMD_CHECKASIZE:
1233                                 case ICMD_CHECKEXCEPTION:
1234                                 case ICMD_IINC:
1235                                 case ICMD_JSR:
1236                                 case ICMD_RET:
1237                                 case ICMD_RETURN:
1238                                 case ICMD_GOTO:
1239                                 case ICMD_PUTSTATICCONST:
1240                                 case ICMD_INLINE_START:
1241                                 case ICMD_INLINE_END:
1242                                         break;
1243
1244                                         /* pop 0 push 1 const */
1245                                         
1246                                 case ICMD_ICONST:
1247                                 case ICMD_LCONST:
1248                                 case ICMD_FCONST:
1249                                 case ICMD_DCONST:
1250                                 case ICMD_ACONST:
1251
1252                                         /* pop 0 push 1 load */
1253                                         
1254                                 case ICMD_ILOAD:
1255                                 case ICMD_LLOAD:
1256                                 case ICMD_FLOAD:
1257                                 case ICMD_DLOAD:
1258                                 case ICMD_ALOAD:
1259                                         reg_new_temp(rd, dst);
1260                                         break;
1261
1262                                         /* pop 2 push 1 */
1263
1264                                 case ICMD_IALOAD:
1265                                 case ICMD_LALOAD:
1266                                 case ICMD_FALOAD:
1267                                 case ICMD_DALOAD:
1268                                 case ICMD_AALOAD:
1269
1270                                 case ICMD_BALOAD:
1271                                 case ICMD_CALOAD:
1272                                 case ICMD_SALOAD:
1273                                         reg_free_temp(rd, src);
1274                                         reg_free_temp(rd, src->prev);
1275                                         reg_new_temp(rd, dst);
1276                                         break;
1277
1278                                         /* pop 3 push 0 */
1279
1280                                 case ICMD_IASTORE:
1281                                 case ICMD_LASTORE:
1282                                 case ICMD_FASTORE:
1283                                 case ICMD_DASTORE:
1284                                 case ICMD_AASTORE:
1285
1286                                 case ICMD_BASTORE:
1287                                 case ICMD_CASTORE:
1288                                 case ICMD_SASTORE:
1289                                         reg_free_temp(rd, src);
1290                                         reg_free_temp(rd, src->prev);
1291                                         reg_free_temp(rd, src->prev->prev);
1292                                         break;
1293
1294                                         /* pop 1 push 0 store */
1295
1296                                 case ICMD_ISTORE:
1297                                 case ICMD_LSTORE:
1298                                 case ICMD_FSTORE:
1299                                 case ICMD_DSTORE:
1300                                 case ICMD_ASTORE:
1301
1302                                         /* pop 1 push 0 */
1303
1304                                 case ICMD_POP:
1305
1306                                 case ICMD_IRETURN:
1307                                 case ICMD_LRETURN:
1308                                 case ICMD_FRETURN:
1309                                 case ICMD_DRETURN:
1310                                 case ICMD_ARETURN:
1311
1312                                 case ICMD_ATHROW:
1313
1314                                 case ICMD_PUTSTATIC:
1315                                 case ICMD_PUTFIELDCONST:
1316
1317                                         /* pop 1 push 0 branch */
1318
1319                                 case ICMD_IFNULL:
1320                                 case ICMD_IFNONNULL:
1321
1322                                 case ICMD_IFEQ:
1323                                 case ICMD_IFNE:
1324                                 case ICMD_IFLT:
1325                                 case ICMD_IFGE:
1326                                 case ICMD_IFGT:
1327                                 case ICMD_IFLE:
1328
1329                                 case ICMD_IF_LEQ:
1330                                 case ICMD_IF_LNE:
1331                                 case ICMD_IF_LLT:
1332                                 case ICMD_IF_LGE:
1333                                 case ICMD_IF_LGT:
1334                                 case ICMD_IF_LLE:
1335
1336                                         /* pop 1 push 0 table branch */
1337
1338                                 case ICMD_TABLESWITCH:
1339                                 case ICMD_LOOKUPSWITCH:
1340
1341                                 case ICMD_MONITORENTER:
1342                                 case ICMD_MONITOREXIT:
1343                                         reg_free_temp(rd, src);
1344                                         break;
1345
1346                                         /* pop 2 push 0 branch */
1347
1348                                 case ICMD_IF_ICMPEQ:
1349                                 case ICMD_IF_ICMPNE:
1350                                 case ICMD_IF_ICMPLT:
1351                                 case ICMD_IF_ICMPGE:
1352                                 case ICMD_IF_ICMPGT:
1353                                 case ICMD_IF_ICMPLE:
1354
1355                                 case ICMD_IF_LCMPEQ:
1356                                 case ICMD_IF_LCMPNE:
1357                                 case ICMD_IF_LCMPLT:
1358                                 case ICMD_IF_LCMPGE:
1359                                 case ICMD_IF_LCMPGT:
1360                                 case ICMD_IF_LCMPLE:
1361
1362                                 case ICMD_IF_ACMPEQ:
1363                                 case ICMD_IF_ACMPNE:
1364
1365                                         /* pop 2 push 0 */
1366
1367                                 case ICMD_POP2:
1368
1369                                 case ICMD_PUTFIELD:
1370
1371                                 case ICMD_IASTORECONST:
1372                                 case ICMD_LASTORECONST:
1373                                 case ICMD_AASTORECONST:
1374                                 case ICMD_BASTORECONST:
1375                                 case ICMD_CASTORECONST:
1376                                 case ICMD_SASTORECONST:
1377                                         reg_free_temp(rd, src);
1378                                         reg_free_temp(rd, src->prev);
1379                                         break;
1380
1381                                         /* pop 0 push 1 dup */
1382                                         
1383                                 case ICMD_DUP:
1384                                         reg_new_temp(rd, dst);
1385                                         break;
1386
1387                                         /* pop 0 push 2 dup */
1388                                         
1389                                 case ICMD_DUP2:
1390                                         reg_new_temp(rd, dst->prev);
1391                                         reg_new_temp(rd, dst);
1392                                         break;
1393
1394                                         /* pop 2 push 3 dup */
1395                                         
1396                                 case ICMD_DUP_X1:
1397                                         reg_free_temp(rd, src);
1398                                         reg_new_temp(rd, dst);
1399                                         reg_free_temp(rd, src->prev);
1400                                         reg_new_temp(rd, dst->prev);
1401                                         reg_new_temp(rd, dst->prev->prev);
1402                                         break;
1403
1404                                         /* pop 3 push 4 dup */
1405                                         
1406                                 case ICMD_DUP_X2:
1407                                         reg_free_temp(rd, src);
1408                                         reg_new_temp(rd, dst);
1409                                         reg_free_temp(rd, src->prev);
1410                                         reg_new_temp(rd, dst->prev);
1411                                         reg_free_temp(rd, src->prev->prev);
1412                                         reg_new_temp(rd, dst->prev->prev);
1413                                         reg_new_temp(rd, dst->prev->prev->prev);
1414                                         break;
1415
1416                                         /* pop 3 push 5 dup */
1417                                         
1418                                 case ICMD_DUP2_X1:
1419                                         reg_free_temp(rd, src);
1420                                         reg_new_temp(rd, dst);
1421                                         reg_free_temp(rd, src->prev);
1422                                         reg_new_temp(rd, dst->prev);
1423                                         reg_free_temp(rd, src->prev->prev);
1424                                         reg_new_temp(rd, dst->prev->prev);
1425                                         reg_new_temp(rd, dst->prev->prev->prev);
1426                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1427                                         break;
1428
1429                                         /* pop 4 push 6 dup */
1430                                         
1431                                 case ICMD_DUP2_X2:
1432                                         reg_free_temp(rd, src);
1433                                         reg_new_temp(rd, dst);
1434                                         reg_free_temp(rd, src->prev);
1435                                         reg_new_temp(rd, dst->prev);
1436                                         reg_free_temp(rd, src->prev->prev);
1437                                         reg_new_temp(rd, dst->prev->prev);
1438                                         reg_free_temp(rd, src->prev->prev->prev);
1439                                         reg_new_temp(rd, dst->prev->prev->prev);
1440                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1441                                         reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1442                                         break;
1443
1444                                         /* pop 2 push 2 swap */
1445                                         
1446                                 case ICMD_SWAP:
1447                                         reg_free_temp(rd, src);
1448                                         reg_new_temp(rd, dst->prev);
1449                                         reg_free_temp(rd, src->prev);
1450                                         reg_new_temp(rd, dst);
1451                                         break;
1452
1453                                         /* pop 2 push 1 */
1454                                         
1455                                 case ICMD_IADD:
1456                                 case ICMD_ISUB:
1457                                 case ICMD_IMUL:
1458                                 case ICMD_IDIV:
1459                                 case ICMD_IREM:
1460
1461                                 case ICMD_ISHL:
1462                                 case ICMD_ISHR:
1463                                 case ICMD_IUSHR:
1464                                 case ICMD_IAND:
1465                                 case ICMD_IOR:
1466                                 case ICMD_IXOR:
1467
1468                                 case ICMD_LADD:
1469                                 case ICMD_LSUB:
1470                                 case ICMD_LMUL:
1471                                 case ICMD_LDIV:
1472                                 case ICMD_LREM:
1473
1474                                 case ICMD_LOR:
1475                                 case ICMD_LAND:
1476                                 case ICMD_LXOR:
1477
1478                                 case ICMD_LSHL:
1479                                 case ICMD_LSHR:
1480                                 case ICMD_LUSHR:
1481
1482                                 case ICMD_FADD:
1483                                 case ICMD_FSUB:
1484                                 case ICMD_FMUL:
1485                                 case ICMD_FDIV:
1486                                 case ICMD_FREM:
1487
1488                                 case ICMD_DADD:
1489                                 case ICMD_DSUB:
1490                                 case ICMD_DMUL:
1491                                 case ICMD_DDIV:
1492                                 case ICMD_DREM:
1493
1494                                 case ICMD_LCMP:
1495                                 case ICMD_FCMPL:
1496                                 case ICMD_FCMPG:
1497                                 case ICMD_DCMPL:
1498                                 case ICMD_DCMPG:
1499                                         reg_free_temp(rd, src);
1500                                         reg_free_temp(rd, src->prev);
1501                                         reg_new_temp(rd, dst);
1502                                         break;
1503
1504                                         /* pop 1 push 1 */
1505                                         
1506                                 case ICMD_IADDCONST:
1507                                 case ICMD_ISUBCONST:
1508                                 case ICMD_IMULCONST:
1509                                 case ICMD_IMULPOW2:
1510                                 case ICMD_IDIVPOW2:
1511                                 case ICMD_IREMPOW2:
1512                                 case ICMD_IANDCONST:
1513                                 case ICMD_IORCONST:
1514                                 case ICMD_IXORCONST:
1515                                 case ICMD_ISHLCONST:
1516                                 case ICMD_ISHRCONST:
1517                                 case ICMD_IUSHRCONST:
1518
1519                                 case ICMD_LADDCONST:
1520                                 case ICMD_LSUBCONST:
1521                                 case ICMD_LMULCONST:
1522                                 case ICMD_LMULPOW2:
1523                                 case ICMD_LDIVPOW2:
1524                                 case ICMD_LREMPOW2:
1525                                 case ICMD_LANDCONST:
1526                                 case ICMD_LORCONST:
1527                                 case ICMD_LXORCONST:
1528                                 case ICMD_LSHLCONST:
1529                                 case ICMD_LSHRCONST:
1530                                 case ICMD_LUSHRCONST:
1531
1532                                 case ICMD_IFEQ_ICONST:
1533                                 case ICMD_IFNE_ICONST:
1534                                 case ICMD_IFLT_ICONST:
1535                                 case ICMD_IFGE_ICONST:
1536                                 case ICMD_IFGT_ICONST:
1537                                 case ICMD_IFLE_ICONST:
1538
1539                                 case ICMD_INEG:
1540                                 case ICMD_INT2BYTE:
1541                                 case ICMD_INT2CHAR:
1542                                 case ICMD_INT2SHORT:
1543                                 case ICMD_LNEG:
1544                                 case ICMD_FNEG:
1545                                 case ICMD_DNEG:
1546
1547                                 case ICMD_I2L:
1548                                 case ICMD_I2F:
1549                                 case ICMD_I2D:
1550                                 case ICMD_L2I:
1551                                 case ICMD_L2F:
1552                                 case ICMD_L2D:
1553                                 case ICMD_F2I:
1554                                 case ICMD_F2L:
1555                                 case ICMD_F2D:
1556                                 case ICMD_D2I:
1557                                 case ICMD_D2L:
1558                                 case ICMD_D2F:
1559
1560                                 case ICMD_CHECKCAST:
1561
1562                                 case ICMD_ARRAYLENGTH:
1563                                 case ICMD_INSTANCEOF:
1564
1565                                 case ICMD_NEWARRAY:
1566                                 case ICMD_ANEWARRAY:
1567
1568                                 case ICMD_GETFIELD:
1569                                         reg_free_temp(rd, src);
1570                                         reg_new_temp(rd, dst);
1571                                         break;
1572
1573                                         /* pop 0 push 1 */
1574                                         
1575                                 case ICMD_GETSTATIC:
1576
1577                                 case ICMD_NEW:
1578                                         reg_new_temp(rd, dst);
1579                                         break;
1580
1581                                         /* pop many push any */
1582                                         
1583                                 case ICMD_INVOKESTATIC:
1584                                 case ICMD_INVOKESPECIAL:
1585                                 case ICMD_INVOKEVIRTUAL:
1586                                 case ICMD_INVOKEINTERFACE:
1587                                         i = iptr->op1;
1588                                         while (--i >= 0) {
1589                                                 reg_free_temp(rd, src);
1590                                                 src = src->prev;
1591                                         }
1592                                         if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)
1593                                                 reg_new_temp(rd, dst);
1594                                         break;
1595
1596                                 case ICMD_BUILTIN:
1597                                         i = iptr->op1;
1598                                         while (--i >= 0) {
1599                                                 reg_free_temp(rd, src);
1600                                                 src = src->prev;
1601                                         }
1602                                         if (((builtintable_entry *) iptr->val.a)->md->returntype.type != TYPE_VOID)
1603                                                 reg_new_temp(rd, dst);
1604                                         break;
1605
1606                                 case ICMD_MULTIANEWARRAY:
1607                                         i = iptr->op1;
1608                                         while (--i >= 0) {
1609                                                 reg_free_temp(rd, src);
1610                                                 src = src->prev;
1611                                         }
1612                                         reg_new_temp(rd, dst);
1613                                         break;
1614
1615                                 default:
1616                                         throw_cacao_exception_exit(string_java_lang_InternalError,
1617                                                                                            "Unknown ICMD %d during register allocation",
1618                                                                                            iptr->opc);
1619                                 } /* switch */
1620                                 iptr++;
1621                         } /* while instructions */
1622                 } /* if */
1623                 bptr = bptr->next;
1624         } /* while blocks */
1625 }
1626
1627
1628 #ifdef STATISTICS
1629 void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
1630         int i,type;
1631         s4 len;
1632         stackptr    src, src_old;
1633         stackptr    dst;
1634         instruction *iptr;
1635         basicblock  *bptr;
1636         int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1637         bool in_register;
1638
1639         in_register = true;
1640
1641         size_interface = 0;
1642
1643                 /* count how many local variables are held in memory or register */
1644                 for(i=0; i < cd->maxlocals; i++)
1645                         for (type=0; type <=4; type++)
1646                                 if (rd->locals[i][type].type != -1) { /* valid local */
1647                                         if (rd->locals[i][type].flags & INMEMORY) {
1648                                                 count_locals_spilled++;
1649                                                 in_register=false;
1650                                         }
1651                                         else
1652                                                 count_locals_register++;
1653                                 }
1654                 /* count how many stack slots are held in memory or register */
1655
1656                 bptr = m->basicblocks;
1657                 while (bptr != NULL) {
1658                         if (bptr->flags >= BBREACHED) {
1659
1660 #ifdef LSRA
1661                         if (!opt_lsra) {
1662 #endif  
1663                                 /* check for memory moves from interface to BB instack */
1664                                 dst = bptr->instack;
1665                                 len = bptr->indepth;
1666                                 
1667                                 if (len > size_interface) size_interface = len;
1668
1669                                 while (dst != NULL) {
1670                                         len--;
1671                                         if (dst->varkind != STACKVAR) {
1672                                                 if ( (dst->flags & INMEMORY) ||
1673                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || 
1674                                                          ( (dst->flags & INMEMORY) && 
1675                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && 
1676                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1677                                                 {
1678                                                         /* one in memory or both inmemory at different offsets */
1679                                                         count_mem_move_bb++;
1680                                                         in_register=false;
1681                                                 }
1682                                         }
1683
1684                                         dst = dst->prev;
1685                                 }
1686
1687                                 /* check for memory moves from BB outstack to interface */
1688                                 dst = bptr->outstack;
1689                                 len = bptr->outdepth;
1690                                 if (len > size_interface) size_interface = len;
1691
1692                                 while (dst) {
1693                                         len--;
1694                                         if (dst->varkind != STACKVAR) {
1695                                                 if ( (dst->flags & INMEMORY) || \
1696                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1697                                                          ( (dst->flags & INMEMORY) && \
1698                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1699                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1700                                                 {
1701                                                         /* one in memory or both inmemory at different offsets */
1702                                                         count_mem_move_bb++;
1703                                                         in_register=false;
1704                                                 }
1705                                         }
1706
1707                                         dst = dst->prev;
1708                                 }
1709 #ifdef LSRA
1710                         }
1711 #endif  
1712
1713
1714                                 dst = bptr->instack;
1715                                 iptr = bptr->iinstr;
1716                                 len = bptr->icount;
1717                                 src_old = NULL;
1718
1719                                 while (--len >= 0)  {
1720                                         src = dst;
1721                                         dst = iptr->dst;
1722
1723                                         if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1724                                                 switch (src->varkind) {
1725                                                 case TEMPVAR:
1726                                                 case STACKVAR:
1727                                                         if (!(src->flags & INMEMORY)) 
1728                                                                 count_ss_register++;
1729                                                         else {
1730                                                                 count_ss_spilled++;
1731                                                                 in_register=false;
1732                                                         }                               
1733                                                         break;
1734                                                         /*                                      case LOCALVAR: */
1735                                                         /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1736                                                         /*                                                      count_ss_register++; */
1737                                                         /*                                              else */
1738                                                         /*                                                      count_ss_spilled++; */
1739                                                         /*                                              break; */
1740                                                 case ARGVAR:
1741                                                         if (!(src->flags & INMEMORY)) 
1742                                                                 count_argument_mem_ss++;
1743                                                         else
1744                                                                 count_argument_reg_ss++;
1745                                                         break;
1746
1747
1748                                                         /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
1749                                                         /*                                                      if (src->varnum < FLT_ARG_CNT) { */
1750                                                         /*                                                              count_ss_register++; */
1751                                                         /*                                                              break; */
1752                                                         /*                                                      } */
1753                                                         /*                                              } else { */
1754                                                         /* #if defined(__POWERPC__) */
1755                                                         /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1756                                                         /* #else */
1757                                                         /*                                                      if (src->varnum < INT_ARG_CNT) { */
1758                                                         /* #endif */
1759                                                         /*                                                              count_ss_register++; */
1760                                                         /*                                                              break; */
1761                                                         /*                                                      } */
1762                                                         /*                                              } */
1763                                                         /*                                              count_ss_spilled++; */
1764                                                         /*                                              break; */
1765                                                 }
1766                                         }
1767                                         src_old = src;
1768                                         
1769                                         iptr++;
1770                                 } /* while instructions */
1771                         } /* if */
1772                         bptr = bptr->next;
1773                 } /* while blocks */
1774                 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1775                 if (in_register) count_method_in_register++;
1776 }
1777 #endif
1778 /*
1779  * These are local overrides for various environment variables in Emacs.
1780  * Please do not remove this and leave it at the end of the file, where
1781  * Emacs will automagically detect them.
1782  * ---------------------------------------------------------------------
1783  * Local variables:
1784  * mode: c
1785  * indent-tabs-mode: t
1786  * c-basic-offset: 4
1787  * tab-width: 4
1788  * End:
1789  */