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