1 /* src/vm/jit/reg.inc - register allocator
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
32 $Id: reg.inc 2333 2005-04-22 13:26:36Z twisti $
38 #include "mm/memory.h"
39 #include "vm/method.h"
40 #include "vm/resolve.h"
41 #include "vm/jit/reg.h"
44 /* function prototypes for this file */
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);
51 /* reg_init ********************************************************************
55 *******************************************************************************/
63 /* reg_setup *******************************************************************
67 *******************************************************************************/
69 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
74 /* setup the integer register table */
75 rd->intreg_argnum = 0;
79 for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
80 switch (nregdescint[rd->intregsnum]) {
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);
100 rd->secondregs = DMNEW(s4, rd->intregsnum);
103 rd->intreg_argnum = 0;
104 rd->argintreguse = 0;
105 rd->tmpintreguse = 0;
106 rd->savintreguse = 0;
108 for (i = 0; i < rd->intregsnum; i++) {
109 switch (nregdescint[i]) {
114 rd->savintregs[rd->savintreguse++] = i;
117 rd->tmpintregs[rd->tmpintreguse++] = i;
120 rd->argintregs[rd->intreg_argnum++] = i;
126 #if defined(__X86_64__)
128 * on x86_64 the argument registers are not in ascending order
129 * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
131 i = rd->argintregs[3];
132 rd->argintregs[3] = rd->argintregs[0];
133 rd->argintregs[0] = i;
135 i = rd->argintregs[2];
136 rd->argintregs[2] = rd->argintregs[1];
137 rd->argintregs[1] = i;
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];
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;
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;
160 for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) {
161 switch (nregdescadr[rd->adrregsnum]) {
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);
181 rd->adrreg_argnum = 0;
182 rd->argadrreguse = 0;
183 rd->tmpadrreguse = 0;
184 rd->savadrreguse = 0;
186 for (i = 0; i < rd->adrregsnum; i++) {
187 switch (nregdescadr[i]) {
192 rd->savadrregs[rd->savadrreguse++] = i;
195 rd->tmpadrregs[rd->tmpadrreguse++] = i;
198 rd->argadrregs[rd->adrreg_argnum++] = i;
204 /* #if defined(????) */
206 * on xdsp the argument registers are in ascending order ???
211 /* setup the float register table */
212 rd->fltreg_argnum = 0;
213 rd->tmpfltregcnt = 0;
214 rd->savfltregcnt = 0;
216 for (rd->fltregsnum = 0; nregdescfloat[rd->fltregsnum] != REG_END; rd->fltregsnum++) {
217 switch (nregdescfloat[rd->fltregsnum]) {
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);
237 rd->fltreg_argnum = 0;
238 rd->argfltreguse = 0;
239 rd->tmpfltreguse = 0;
240 rd->savfltreguse = 0;
242 for (i = 0; i < rd->fltregsnum; i++) {
243 switch (nregdescfloat[i]) {
248 rd->savfltregs[rd->savfltreguse++] = i;
251 rd->tmpfltregs[rd->tmpfltreguse++] = i;
254 rd->argfltregs[rd->fltreg_argnum++] = i;
261 rd->freemem = DMNEW(s4, id->cummaxstack);
262 rd->locals = DMNEW(varinfo5, id->cumlocals);
263 rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
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;
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;
286 rd->ifmemuse = 6 + 8; /* 6*4=24 byte linkage area + 8*4=32 byte minimum parameter Area */
288 rd->ifmemuse = 0; /* init to zero -> analyse_stack will set it to a higher value, if appropriate */
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*/
298 /* function reg_free ***********************************************************
300 releases all allocated space for registers
302 *******************************************************************************/
304 void reg_free(methodinfo *m, registerdata *rd)
310 /* reg_close *******************************************************************
314 *******************************************************************************/
322 /* function interface_regalloc *************************************************
324 allocates registers for all interface variables
326 *******************************************************************************/
328 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
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);
341 /* function interface_regalloc *************************************************
343 allocates registers for all interface variables
345 *******************************************************************************/
347 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
350 int intalloc, fltalloc; /* ?per Interface slot only one flt or one int type can be allocated to a register? */
354 /* allocate stack space for passing arguments to called methods */
355 #ifdef INVOKE_NEW_DEBUG
358 if (compileverbose) {
359 printf("analyse: argintru %3i argfltru %3i ifmemu %3i\n", rd->argintreguse, rd->argfltreguse, 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;
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");
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;
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;
399 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
400 v = &rd->interfaces[s][t];
403 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
406 #ifdef HAS_ADDRESS_REGISTER_FILE
408 #if defined(HAS_ADDRESS_REGISTER_FILE)
409 if (!m->isleafmethod &&(rd->ifargadrregcnt < rd->adrreg_argnum)) {
410 v->regoff = rd->argadrregs[rd->ifargadrregcnt++];
413 if (rd->iftmpadrregcnt > 0) {
414 rd->iftmpadrregcnt--;
415 v->regoff = rd->tmpadrregs[rd->iftmpadrregcnt];
417 else if (rd->ifsavadrregcnt > 0) {
418 rd->ifsavadrregcnt--;
419 v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
422 v->flags |= INMEMORY;
423 v->regoff = rd->ifmemuse;
424 rd->ifmemuse += regsneeded + 1;
428 if (IS_FLT_DBL_TYPE(t)) {
430 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
431 v->regoff = rd->interfaces[s][fltalloc].regoff;
433 else if (!m->isleafmethod &&(rd->ifargfltregcnt < rd->fltreg_argnum)) {
434 v->regoff = rd->argfltregs[rd->ifargfltregcnt++];
436 else if (rd->iftmpfltregcnt > 0) {
437 rd->iftmpfltregcnt--;
438 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
440 else if (rd->ifsavfltregcnt > 0) {
441 rd->ifsavfltregcnt--;
442 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
445 v->flags |= INMEMORY;
446 v->regoff = rd->ifmemuse;
447 rd->ifmemuse += regsneeded + 1;
452 #if defined(__I386__)
454 * for i386 put all longs in memory
456 if (IS_2_WORD_TYPE(t)) {
457 v->flags |= INMEMORY;
458 v->regoff = rd->ifmemuse++;
462 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
463 v->regoff = rd->interfaces[s][intalloc].regoff;
465 else if (!m->isleafmethod &&(rd->ifargintregcnt +regsneeded < rd->intreg_argnum)) {
466 v->regoff = rd->argintregs[rd->ifargintregcnt];
467 rd->ifargintregcnt+=regsneeded+1;
469 else if (rd->iftmpintregcnt > regsneeded) {
470 rd->iftmpintregcnt -= regsneeded + 1;
471 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
473 else if (rd->ifsavintregcnt > regsneeded) {
474 rd->ifsavintregcnt -= regsneeded + 1;
475 v->regoff = rd->savintregs[rd->ifsavintregcnt];
478 v->flags |= INMEMORY;
479 v->regoff = rd->ifmemuse;
480 rd->ifmemuse += regsneeded + 1;
482 #if defined(__I386__)
487 #ifdef HAS_ADDRESS_REGISTER_FILE
492 #ifdef HAS_ADDRESS_REGISTER_FILE
494 if (rd->ifsavadrregcnt > 0) {
495 rd->ifsavadrregcnt--;
496 v->regoff = rd->savadrregs[rd->ifsavadrregcnt];
499 v->flags |= INMEMORY;
500 v->regoff = rd->ifmemuse;
501 rd->ifmemuse += regsneeded + 1;
505 if (IS_FLT_DBL_TYPE(t)) {
507 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
508 v->regoff = rd->interfaces[s][fltalloc].regoff;
510 else if (rd->ifsavfltregcnt > 0) {
511 rd->ifsavfltregcnt--;
512 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
515 v->flags |= INMEMORY;
516 v->regoff = rd->ifmemuse;
517 rd->ifmemuse += regsneeded + 1;
522 #if defined(__I386__)
524 * for i386 put all longs in memory
526 if (IS_2_WORD_TYPE(t)) {
527 v->flags |= INMEMORY;
528 v->regoff = rd->ifmemuse++;
532 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
533 v->regoff = rd->interfaces[s][intalloc].regoff;
535 else if (rd->ifsavintregcnt > regsneeded) {
536 rd->ifsavintregcnt -= regsneeded + 1;
537 v->regoff = rd->savintregs[rd->ifsavintregcnt];
540 v->flags |= INMEMORY;
541 v->regoff = rd->ifmemuse;
542 rd->ifmemuse += regsneeded + 1;
544 #if defined(__I386__)
549 #ifdef HAS_ADDRESS_REGISTER_FILE
553 } /* if (type >= 0) */
557 rd->maxmemuse = rd->ifmemuse;
559 rd->maxargintreguse = rd->ifargintregcnt;
560 rd->maxargfltreguse = rd->ifargfltregcnt;
562 rd->maxtmpintreguse = rd->iftmpintregcnt;
563 rd->maxsavintreguse = rd->ifsavintregcnt;
565 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
566 rd->maxsavfltreguse = rd->ifsavfltregcnt;
568 #if defined(HAS_ADDRESS_REGISTER_FILE)
570 rd->maxargadrreguse = rd->ifargadrregcnt;
571 rd->maxtmpadrreguse = rd->iftmpadrregcnt;
572 rd->maxsavadrreguse = rd->ifsavadrregcnt;
578 /* function local_regalloc *****************************************************
580 allocates registers for all local variables
582 *******************************************************************************/
584 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
587 int intalloc, fltalloc;
590 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
592 if (m->isleafmethod) {
593 int arg, doublewordarg, iargcnt, fargcnt;
594 #ifdef HAS_ADDRESS_REGISTER_FILE
598 arg = 0, iargcnt = 0, fargcnt = 0;
599 #ifdef HAS_ADDRESS_REGISTER_FILE
603 for (s = 0; s < cd->maxlocals; s++) {
604 intalloc = -1; fltalloc = -1;
605 for (tt = 0; tt <= 4; tt++) {
607 v = &rd->locals[s][t];
611 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
613 #ifdef HAS_ADDRESS_REGISTER_FILE
615 /* doublewordarg not possible for xdsp */
616 #if !defined(CONSECUTIVE_ADDRESSARGS)
619 if ((arg < m->paramcount) && (aargcnt < rd->adrreg_argnum)) {
621 v->regoff = rd->argadrregs[aargcnt];
623 if (rd->maxtmpadrreguse > 0) {
624 rd->maxtmpadrreguse--;
626 v->regoff = rd->tmpadrregs[rd->maxtmpadrreguse];
628 else if (rd->maxsavadrreguse > 0) {
629 rd->maxsavadrreguse--;
631 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
634 v->flags |= INMEMORY;
635 v->regoff = rd->ifmemuse;
636 rd->ifmemuse += regsneeded + 1;
640 if (IS_FLT_DBL_TYPE(t)) {
641 #if !defined(CONSECUTIVE_FLOATARGS)
645 v->flags = rd->locals[s][fltalloc].flags;
646 v->regoff = rd->locals[s][fltalloc].regoff;
648 else if (!doublewordarg && (arg < m->paramcount) &&
649 (fargcnt < rd->fltreg_argnum)) {
651 v->regoff = rd->argfltregs[fargcnt];
653 else if (rd->maxtmpfltreguse > 0) {
654 rd->maxtmpfltreguse--;
656 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
658 else if (rd->maxsavfltreguse > 0) {
659 rd->maxsavfltreguse--;
661 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
665 v->regoff = rd->maxmemuse;
666 rd->maxmemuse += regsneeded + 1;
672 #if defined(__I386__)
674 * for i386 put all longs in memory
676 if (IS_2_WORD_TYPE(t)) {
678 v->regoff = rd->maxmemuse++;
681 #if !defined(CONSECUTIVE_INTARGS)
685 v->flags = rd->locals[s][intalloc].flags;
686 v->regoff = rd->locals[s][intalloc].regoff;
688 else if (!doublewordarg && (arg < m->paramcount)
690 && ((regtouse = iargcnt) < rd->intreg_argnum)
692 && ((regtouse = s) < rd->intreg_argnum - regsneeded)
696 v->regoff = rd->argintregs[regtouse];
698 else if (rd->maxtmpintreguse > regsneeded) {
699 rd->maxtmpintreguse -= regsneeded + 1;
701 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
703 else if (rd->maxsavintreguse > regsneeded) {
704 rd->maxsavintreguse -= regsneeded + 1;
706 v->regoff = rd->savintregs[rd->maxsavintreguse];
709 * use unused argument registers as local registers
711 else if (!doublewordarg && (arg >= m->paramcount) &&
712 (iargcnt < rd->intreg_argnum)) {
714 v->regoff = rd->argintregs[iargcnt];
720 v->regoff = rd->maxmemuse;
721 rd->maxmemuse += regsneeded + 1;
723 #if defined(__I386__)
728 #ifdef HAS_ADDRESS_REGISTER_FILE
733 if (arg < m->paramcount) {
736 /* what type was the double arg? */
737 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
745 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
749 #ifdef HAS_ADDRESS_REGISTER_FILE
750 if ( TYPE_ADR == m->paramtypes[arg] ) {
754 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
760 #ifdef HAS_ADDRESS_REGISTER_FILE
770 for (s = 0; s < cd->maxlocals; s++) {
771 intalloc = -1; fltalloc = -1;
772 for (tt=0; tt<=4; tt++) {
774 v = &rd->locals[s][t];
777 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
779 #ifdef HAS_ADDRESS_REGISTER_FILE
780 if ( t == TYPE_ADR ) {
781 if (rd->maxsavadrreguse > 0) {
782 rd->maxsavadrreguse--;
784 v->regoff = rd->savadrregs[rd->maxsavadrreguse];
788 v->regoff = rd->maxmemuse;
789 rd->maxmemuse += regsneeded + 1;
793 if (IS_FLT_DBL_TYPE(t)) {
795 v->flags = rd->locals[s][fltalloc].flags;
796 v->regoff = rd->locals[s][fltalloc].regoff;
798 else if (rd->maxsavfltreguse > 0) {
799 rd->maxsavfltreguse--;
801 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
805 v->regoff = rd->maxmemuse;
806 rd->maxmemuse += regsneeded + 1;
811 #if defined(__I386__)
813 * for i386 put all longs in memory
815 if (IS_2_WORD_TYPE(t)) {
817 v->regoff = rd->maxmemuse++;
821 v->flags = rd->locals[s][intalloc].flags;
822 v->regoff = rd->locals[s][intalloc].regoff;
824 else if (rd->maxsavintreguse > regsneeded) {
825 rd->maxsavintreguse -= regsneeded+1;
827 v->regoff = rd->savintregs[rd->maxsavintreguse];
831 v->regoff = rd->maxmemuse;
832 rd->maxmemuse += regsneeded + 1;
834 #if defined(__I386__)
839 #ifdef HAS_ADDRESS_REGISTER_FILE
848 static void reg_init_temp(methodinfo *m, registerdata *rd)
851 rd->memuse = rd->ifmemuse;
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;
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;
871 rd->freearginttop = 0;
872 rd->freeargflttop = 0;
873 #ifdef HAS_ADDRESS_REGISTER_FILE
874 rd->freeargadrtop = 0;
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;
884 rd->argintreguse = rd->intreg_argnum;
885 rd->argfltreguse = rd->fltreg_argnum;
886 #ifdef HAS_ADDRESS_REGISTER_FILE
887 rd->argadrreguse = rd->adrreg_argnum;
892 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
895 static void reg_new_temp_func(registerdata *rd, stackptr s)
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;
905 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
910 for(; tryagain; --tryagain) {
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) {
918 s->regoff = rd->freesavadrregs[rd->freesavadrtop];
921 } else if (rd->savadrreguse > 0) {
923 if (rd->savadrreguse < rd->maxsavadrreguse)
924 rd->maxsavadrreguse = rd->savadrreguse;
925 s->regoff = rd->savadrregs[rd->savadrreguse];
930 if (IS_FLT_DBL_TYPE(s->type)) {
931 if (rd->freesavflttop > 0) {
933 s->regoff = rd->freesavfltregs[rd->freesavflttop];
936 } else if (rd->savfltreguse > 0) {
938 if (rd->savfltreguse < rd->maxsavfltreguse)
939 rd->maxsavfltreguse = rd->savfltreguse;
940 s->regoff = rd->savfltregs[rd->savfltreguse];
945 #if defined(__I386__)
947 * for i386 put all longs in memory
949 if (!IS_2_WORD_TYPE(s->type)) {
951 if (rd->freesavinttop > regsneeded) {
952 rd->freesavinttop -= regsneeded + 1;
953 s->regoff = rd->freesavintregs[rd->freesavinttop];
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];
963 #if defined(__I386__)
967 #ifdef HAS_ADDRESS_REGISTER_FILE
971 #ifdef HAS_ADDRESS_REGISTER_FILE
972 if (s->type == TYPE_ADR) {
973 if (rd->freetmpadrtop > 0) {
975 s->regoff = rd->freetmpadrregs[rd->freetmpadrtop];
978 } else if (rd->tmpadrreguse > 0) {
980 if (rd->tmpadrreguse < rd->maxtmpadrreguse)
981 rd->maxtmpadrreguse = rd->tmpadrreguse;
982 s->regoff = rd->tmpadrregs[rd->tmpadrreguse];
987 if (IS_FLT_DBL_TYPE(s->type)) {
988 if (rd->freeargflttop > 0) {
989 rd->freeargflttop --;
990 s->regoff = rd->freeargfltregs[rd->freeargflttop];
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++];
999 } else if (rd->freetmpflttop > 0) {
1000 rd->freetmpflttop--;
1001 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
1004 } else if (rd->tmpfltreguse > 0) {
1006 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
1007 rd->maxtmpfltreguse = rd->tmpfltreguse;
1008 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
1013 #if defined(__I386__)
1015 * for i386 put all longs in memory
1017 if (!IS_2_WORD_TYPE(s->type)) {
1019 if (rd->freearginttop > regsneeded) {
1020 rd->freearginttop -= regsneeded + 1;
1021 s->regoff = rd->freeargintregs[rd->freearginttop];
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];
1029 rd->argintreguse += regsneeded + 1;
1031 } else if (rd->freetmpinttop > regsneeded) {
1032 rd->freetmpinttop -= regsneeded + 1;
1033 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
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];
1043 #if defined(__I386__)
1047 #ifdef HAS_ADDRESS_REGISTER_FILE
1053 if (rd->freememtop > regsneeded) {
1054 rd->freememtop -= regsneeded + 1;
1055 s->regoff = rd->freemem[rd->freememtop];
1058 s->regoff = rd->memuse;
1059 rd->memuse += regsneeded + 1;
1060 if (rd->memuse > rd->maxmemuse)
1061 rd->maxmemuse = rd->memuse;
1063 s->flags |= INMEMORY;
1067 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
1070 static void reg_free_temp_func(registerdata *rd, stackptr s)
1075 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1080 if (s->flags & INMEMORY) {
1081 rd->freemem[rd->freememtop] = s->regoff;
1083 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
1084 rd->freememtop += regsneeded + 1;
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;
1093 rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
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;
1100 if (s->flags & TMPARG) {
1101 s->flags &= ~TMPARG;
1102 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1104 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1106 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1107 s->flags &= ~SAVEDTMP;
1108 rd->freesavintregs[rd->freesavinttop] = s->regoff;
1111 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
1113 rd->freesavinttop += regsneeded + 1;
1115 } else if (s->flags & TMPARG) {
1116 s->flags &= ~TMPARG;
1117 rd->freeargintregs[rd->freearginttop] = s->regoff;
1120 rd->freeargintregs[rd->freearginttop + 1] = rd->secondregs[s->regoff];
1122 rd->freearginttop += regsneeded + 1;
1124 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1127 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
1129 rd->freetmpinttop += regsneeded + 1;
1136 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
1146 bptr = m->basicblocks;
1148 while (bptr != NULL) {
1149 if (bptr->flags >= BBREACHED) {
1150 dst = bptr->instack;
1152 /* initialize temp registers */
1153 reg_init_temp(m, rd);
1155 iptr = bptr->iinstr;
1158 while (--len >= 0) {
1168 case ICMD_ELSE_ICONST:
1169 case ICMD_CHECKASIZE:
1170 case ICMD_CHECKEXCEPTION:
1176 case ICMD_PUTSTATICCONST:
1177 case ICMD_INLINE_START:
1178 case ICMD_INLINE_END:
1181 /* pop 0 push 1 const */
1189 /* pop 0 push 1 load */
1196 reg_new_temp(rd, dst);
1210 reg_free_temp(rd, src);
1211 reg_free_temp(rd, src->prev);
1212 reg_new_temp(rd, dst);
1226 reg_free_temp(rd, src);
1227 reg_free_temp(rd, src->prev);
1228 reg_free_temp(rd, src->prev->prev);
1231 /* pop 1 push 0 store */
1251 case ICMD_PUTSTATIC:
1252 case ICMD_PUTFIELDCONST:
1254 /* pop 1 push 0 branch */
1257 case ICMD_IFNONNULL:
1273 /* pop 1 push 0 table branch */
1275 case ICMD_TABLESWITCH:
1276 case ICMD_LOOKUPSWITCH:
1278 case ICMD_NULLCHECKPOP:
1279 case ICMD_MONITORENTER:
1280 case ICMD_MONITOREXIT:
1281 reg_free_temp(rd, src);
1284 /* pop 2 push 0 branch */
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:
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:
1300 case ICMD_IF_ACMPEQ:
1301 case ICMD_IF_ACMPNE:
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);
1319 /* pop 0 push 1 dup */
1322 reg_new_temp(rd, dst);
1325 /* pop 0 push 2 dup */
1328 reg_new_temp(rd, dst->prev);
1329 reg_new_temp(rd, dst);
1332 /* pop 2 push 3 dup */
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);
1342 /* pop 3 push 4 dup */
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);
1354 /* pop 3 push 5 dup */
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);
1367 /* pop 4 push 6 dup */
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);
1382 /* pop 2 push 2 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);
1437 reg_free_temp(rd, src);
1438 reg_free_temp(rd, src->prev);
1439 reg_new_temp(rd, dst);
1444 case ICMD_IADDCONST:
1445 case ICMD_ISUBCONST:
1446 case ICMD_IMULCONST:
1450 case ICMD_IANDCONST:
1452 case ICMD_IXORCONST:
1453 case ICMD_ISHLCONST:
1454 case ICMD_ISHRCONST:
1455 case ICMD_IUSHRCONST:
1457 case ICMD_LADDCONST:
1458 case ICMD_LSUBCONST:
1459 case ICMD_LMULCONST:
1463 case ICMD_LANDCONST:
1465 case ICMD_LXORCONST:
1466 case ICMD_LSHLCONST:
1467 case ICMD_LSHRCONST:
1468 case ICMD_LUSHRCONST:
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:
1480 case ICMD_INT2SHORT:
1498 case ICMD_CHECKCAST:
1500 case ICMD_ARRAYLENGTH:
1501 case ICMD_INSTANCEOF:
1504 case ICMD_ANEWARRAY:
1507 reg_free_temp(rd, src);
1508 reg_new_temp(rd, dst);
1513 case ICMD_GETSTATIC:
1516 reg_new_temp(rd, dst);
1519 /* pop many push any */
1521 case ICMD_INVOKEVIRTUAL:
1522 case ICMD_INVOKESPECIAL:
1523 case ICMD_INVOKESTATIC:
1524 case ICMD_INVOKEINTERFACE:
1527 reg_free_temp(rd, src);
1530 #if defined(__X86_64__) || defined(__I386__)
1531 if (((unresolved_method *) iptr->target)->methodref->parseddesc.md->returntype.type != TYPE_VOID)
1533 if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1535 reg_new_temp(rd, dst);
1539 reg_free_temp(rd, src);
1542 reg_free_temp(rd, src);
1545 reg_free_temp(rd, src);
1547 if (iptr->op1 != TYPE_VOID)
1548 reg_new_temp(rd, dst);
1551 case ICMD_MULTIANEWARRAY:
1554 reg_free_temp(rd, src);
1557 reg_new_temp(rd, dst);
1561 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1562 panic("Missing ICMD code during register allocation");
1565 } /* while instructions */
1568 } /* while blocks */
1573 void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
1576 stackptr src, src_old;
1580 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
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++;
1596 count_locals_register++;
1598 /* count how many stack slots are held in memory or register */
1600 bptr = m->basicblocks;
1601 while (bptr != NULL) {
1602 if (bptr->flags >= BBREACHED) {
1607 /* check for memory moves from interface to BB instack */
1608 dst = bptr->instack;
1609 len = bptr->indepth;
1611 if (len > size_interface) size_interface = len;
1613 while (dst != NULL) {
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) ))
1622 /* one in memory or both inmemory at different offsets */
1623 count_mem_move_bb++;
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;
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) ))
1645 /* one in memory or both inmemory at different offsets */
1646 count_mem_move_bb++;
1658 dst = bptr->instack;
1659 iptr = bptr->iinstr;
1663 while (--len >= 0) {
1667 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1668 switch (src->varkind) {
1671 if (!(src->flags & INMEMORY))
1672 count_ss_register++;
1678 /* case LOCALVAR: */
1679 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1680 /* count_ss_register++; */
1682 /* count_ss_spilled++; */
1685 if (!(src->flags & INMEMORY))
1686 count_argument_mem_ss++;
1688 count_argument_reg_ss++;
1692 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1693 /* if (src->varnum < FLT_ARG_CNT) { */
1694 /* count_ss_register++; */
1698 /* #if defined(__POWERPC__) */
1699 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1701 /* if (src->varnum < INT_ARG_CNT) { */
1703 /* count_ss_register++; */
1707 /* count_ss_spilled++; */
1714 } /* while instructions */
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++;
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 * ---------------------------------------------------------------------
1729 * indent-tabs-mode: t