1 /* src/vm/jit/allocator/simplereg.c - 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
35 $Id: simplereg.c 4454 2006-02-06 00:02:50Z edwin $
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "mm/memory.h"
51 #include "vm/method.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/reg.h"
56 #include "vm/jit/allocator/simplereg.h"
58 /* function prototypes for this file */
60 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
61 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
62 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
65 /* function interface_regalloc *************************************************
67 allocates registers for all interface variables
69 *******************************************************************************/
71 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
73 interface_regalloc(m, cd, rd);
74 allocate_scratch_registers(m, rd);
75 local_regalloc(m, cd, rd);
79 /* function interface_regalloc *************************************************
81 allocates registers for all interface variables
83 *******************************************************************************/
85 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
88 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
89 /* in case a more vars are packed into this interface slot */
91 int intregsneeded = 0;
93 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
94 /* on HAS_4BYTE_STACKSLOT architectures */
95 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
97 /* rd->memuse was already set in stack.c to allocate stack space for */
98 /* passing arguments to called methods */
100 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
101 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
107 if (m->isleafmethod) {
108 /* Reserve argument register, which will be used for Locals acting */
110 if (rd->argintreguse < m->parseddesc->argintreguse)
111 rd->argintreguse = m->parseddesc->argintreguse;
112 if (rd->argfltreguse < m->parseddesc->argfltreguse)
113 rd->argfltreguse = m->parseddesc->argfltreguse;
114 #ifdef HAS_ADDRESS_REGISTER_FILE
115 if (rd->argadrreguse < m->parseddesc->argadrreguse)
116 rd->argadrreguse = m->parseddesc->argadrreguse;
121 for (s = 0; s < cd->maxstack; s++) {
122 intalloc = -1; fltalloc = -1;
123 saved = (rd->interfaces[s][TYPE_INT].flags |
124 rd->interfaces[s][TYPE_LNG].flags |
125 rd->interfaces[s][TYPE_FLT].flags |
126 rd->interfaces[s][TYPE_DBL].flags |
127 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
129 for (tt = 0; tt <= 4; tt++) {
131 v = &rd->interfaces[s][t];
133 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
134 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
136 #if defined(HAS_4BYTE_STACKSLOT)
137 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
140 #if defined(HAS_ADDRESS_REGISTER_FILE)
141 if (IS_ADR_TYPE(t)) {
143 &&(rd->argadrreguse < ADR_ARG_CNT)) {
144 v->regoff = rd->argadrregs[rd->argadrreguse++];
145 } else if (rd->tmpadrreguse > 0) {
146 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
147 } else if (rd->savadrreguse > 0) {
148 v->regoff = rd->savadrregs[--rd->savadrreguse];
150 v->flags |= INMEMORY;
151 v->regoff = rd->memuse++;
153 } else /* !IS_ADR_TYPE */
154 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
156 if (IS_FLT_DBL_TYPE(t)) {
158 /* Reuse memory slot(s)/register(s) for shared interface slots */
159 v->flags |= rd->interfaces[s][fltalloc].flags
161 v->regoff = rd->interfaces[s][fltalloc].regoff;
162 } else if (!m->isleafmethod
163 && (rd->argfltreguse < FLT_ARG_CNT)) {
164 v->regoff = rd->argfltregs[rd->argfltreguse++];
165 } else if (rd->tmpfltreguse > 0) {
166 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
167 } else if (rd->savfltreguse > 0) {
168 v->regoff = rd->savfltregs[--rd->savfltreguse];
170 v->flags |= INMEMORY;
171 #if defined(ALIGN_DOUBLES_IN_MEMORY)
172 /* Align doubles in Memory */
173 if ( (memneeded) && (rd->memuse & 1))
176 v->regoff = rd->memuse;
177 rd->memuse += memneeded + 1;
180 } else { /* !IS_FLT_DBL_TYPE(t) */
181 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
183 * for i386 put all longs in memory
185 if (IS_2_WORD_TYPE(t)) {
186 v->flags |= INMEMORY;
187 #if defined(ALIGN_LONGS_IN_MEMORY)
188 /* Align longs in Memory */
192 v->regoff = rd->memuse;
193 rd->memuse += memneeded + 1;
195 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
197 /* Reuse memory slot(s)/register(s) for shared interface slots */
199 rd->interfaces[s][intalloc].flags
201 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
202 if (!(v->flags & INMEMORY)
203 && IS_2_WORD_TYPE(intalloc))
204 v->regoff = GET_LOW_REG(
205 rd->interfaces[s][intalloc].regoff);
209 rd->interfaces[s][intalloc].regoff;
211 if (!m->isleafmethod &&
213 + intregsneeded < INT_ARG_CNT)) {
214 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
217 rd->argintregs[rd->argintreguse],
218 rd->argintregs[rd->argintreguse + 1]);
222 rd->argintregs[rd->argintreguse];
223 rd->argintreguse += intregsneeded + 1;
225 else if (rd->tmpintreguse > intregsneeded) {
226 rd->tmpintreguse -= intregsneeded + 1;
227 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
230 rd->tmpintregs[rd->tmpintreguse],
231 rd->tmpintregs[rd->tmpintreguse + 1]);
235 rd->tmpintregs[rd->tmpintreguse];
237 else if (rd->savintreguse > intregsneeded) {
238 rd->savintreguse -= intregsneeded + 1;
240 rd->savintregs[rd->savintreguse];
241 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
244 rd->savintregs[rd->savintreguse],
245 rd->savintregs[rd->savintreguse + 1]);
249 rd->savintregs[rd->savintreguse];
252 v->flags |= INMEMORY;
253 #if defined(ALIGN_LONGS_IN_MEMORY)
254 /* Align longs in Memory */
255 if ( (memneeded) && (rd->memuse & 1))
258 v->regoff = rd->memuse;
259 rd->memuse += memneeded + 1;
263 } /* if (IS_FLT_DBL_TYPE(t)) */
265 } else { /* (saved) */
266 /* now the same like above, but without a chance to take a temporary register */
267 #ifdef HAS_ADDRESS_REGISTER_FILE
268 if (IS_ADR_TYPE(t)) {
269 if (rd->savadrreguse > 0) {
270 v->regoff = rd->savadrregs[--rd->savadrreguse];
273 v->flags |= INMEMORY;
274 v->regoff = rd->memuse++;
279 if (IS_FLT_DBL_TYPE(t)) {
281 v->flags |= rd->interfaces[s][fltalloc].flags
283 v->regoff = rd->interfaces[s][fltalloc].regoff;
285 if (rd->savfltreguse > 0) {
286 v->regoff = rd->savfltregs[--rd->savfltreguse];
289 v->flags |= INMEMORY;
290 #if defined(ALIGN_DOUBLES_IN_MEMORY)
291 /* Align doubles in Memory */
292 if ( (memneeded) && (rd->memuse & 1))
295 v->regoff = rd->memuse;
296 rd->memuse += memneeded + 1;
300 else { /* IS_INT_LNG */
301 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
303 * for i386 put all longs in memory
305 if (IS_2_WORD_TYPE(t)) {
306 v->flags |= INMEMORY;
307 #if defined(ALIGN_LONGS_IN_MEMORY)
308 /* Align longs in Memory */
312 v->regoff = rd->memuse;
313 rd->memuse += memneeded + 1;
319 rd->interfaces[s][intalloc].flags & INMEMORY;
320 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
321 if (!(v->flags & INMEMORY)
322 && IS_2_WORD_TYPE(intalloc))
325 rd->interfaces[s][intalloc].regoff);
329 rd->interfaces[s][intalloc].regoff;
331 if (rd->savintreguse > intregsneeded) {
332 rd->savintreguse -= intregsneeded + 1;
333 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
335 v->regoff = PACK_REGS(
336 rd->savintregs[rd->savintreguse],
337 rd->savintregs[rd->savintreguse + 1]);
341 rd->savintregs[rd->savintreguse];
343 v->flags |= INMEMORY;
344 #if defined(ALIGN_LONGS_IN_MEMORY)
345 /* Align longs in Memory */
346 if ( (memneeded) && (rd->memuse & 1))
349 v->regoff = rd->memuse;
350 rd->memuse += memneeded + 1;
355 } /* if (IS_FLT_DBL_TYPE(t) else */
356 } /* if (IS_ADR_TYPE(t)) else */
357 } /* if (saved) else */
358 } /* if (type >= 0) */
365 /* function local_regalloc *****************************************************
367 allocates registers for all local variables
369 *******************************************************************************/
371 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
374 int intalloc, fltalloc;
376 int intregsneeded = 0;
378 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
379 int fargcnt, iargcnt;
380 #ifdef HAS_ADDRESS_REGISTER_FILE
384 if (m->isleafmethod) {
385 methoddesc *md = m->parseddesc;
387 iargcnt = rd->argintreguse;
388 fargcnt = rd->argfltreguse;
389 #ifdef HAS_ADDRESS_REGISTER_FILE
390 aargcnt = rd->argadrreguse;
392 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
393 intalloc = -1; fltalloc = -1;
394 for (tt = 0; tt <= 4; tt++) {
396 v = &rd->locals[s][t];
401 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
402 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
404 #if defined(HAS_4BYTE_STACKSLOT)
405 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
411 * #ifdef HAS_ADDRESS_REGISTER_FILE
418 * } else { / int & lng
422 * must not to be changed!
425 #ifdef HAS_ADDRESS_REGISTER_FILE
426 if (IS_ADR_TYPE(t)) {
427 if ((p < md->paramcount) && !md->params[p].inmemory) {
429 v->regoff = rd->argadrregs[md->params[p].regoff];
431 else if (rd->tmpadrreguse > 0) {
433 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
435 /* use unused argument registers as local registers */
436 else if ((p >= md->paramcount) &&
437 (aargcnt < ADR_ARG_CNT)) {
439 v->regoff = rd->argadrregs[aargcnt++];
441 else if (rd->savadrreguse > 0) {
443 v->regoff = rd->savadrregs[--rd->savadrreguse];
446 v->flags |= INMEMORY;
447 v->regoff = rd->memuse++;
451 if (IS_FLT_DBL_TYPE(t)) {
453 v->flags = rd->locals[s][fltalloc].flags;
454 v->regoff = rd->locals[s][fltalloc].regoff;
456 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
457 /* We can only use float arguments as local variables,
458 * if we do not pass them in integer registers. */
459 else if ((p < md->paramcount) &&
460 !md->params[p].inmemory) {
462 v->regoff = rd->argfltregs[md->params[p].regoff];
465 else if (rd->tmpfltreguse > 0) {
467 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
469 /* use unused argument registers as local registers */
470 else if ((p >= md->paramcount) &&
471 (fargcnt < FLT_ARG_CNT)) {
473 v->regoff = rd->argfltregs[fargcnt];
476 else if (rd->savfltreguse > 0) {
478 v->regoff = rd->savfltregs[--rd->savfltreguse];
482 #if defined(ALIGN_DOUBLES_IN_MEMORY)
483 /* Align doubles in Memory */
484 if ( (memneeded) && (rd->memuse & 1))
487 v->regoff = rd->memuse;
488 rd->memuse += memneeded + 1;
493 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
495 * for i386 put all longs in memory
497 if (IS_2_WORD_TYPE(t)) {
499 #if defined(ALIGN_LONGS_IN_MEMORY)
500 /* Align longs in Memory */
504 v->regoff = rd->memuse;
505 rd->memuse += memneeded + 1;
510 v->flags = rd->locals[s][intalloc].flags;
511 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
512 if (!(v->flags & INMEMORY)
513 && IS_2_WORD_TYPE(intalloc))
514 v->regoff = GET_LOW_REG(
515 rd->locals[s][intalloc].regoff);
518 v->regoff = rd->locals[s][intalloc].regoff;
520 else if ((p < md->paramcount) &&
521 !md->params[p].inmemory) {
523 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
524 if (IS_2_WORD_TYPE(t))
525 v->regoff = PACK_REGS(
526 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
527 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
531 rd->argintregs[md->params[p].regoff];
533 else if (rd->tmpintreguse > intregsneeded) {
534 rd->tmpintreguse -= intregsneeded + 1;
536 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
538 v->regoff = PACK_REGS(
539 rd->tmpintregs[rd->tmpintreguse],
540 rd->tmpintregs[rd->tmpintreguse + 1]);
544 rd->tmpintregs[rd->tmpintreguse];
547 * use unused argument registers as local registers
549 else if ((p >= m->parseddesc->paramcount) &&
550 (iargcnt + intregsneeded < INT_ARG_CNT)) {
552 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
555 rd->argintregs[iargcnt],
556 rd->argintregs[iargcnt + 1]);
559 v->regoff = rd->argintregs[iargcnt];
560 iargcnt += intregsneeded + 1;
562 else if (rd->savintreguse > intregsneeded) {
563 rd->savintreguse -= intregsneeded + 1;
565 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
567 v->regoff = PACK_REGS(
568 rd->savintregs[rd->savintreguse],
569 rd->savintregs[rd->savintreguse + 1]);
572 v->regoff =rd->savintregs[rd->savintreguse];
576 #if defined(ALIGN_LONGS_IN_MEMORY)
577 /* Align longs in Memory */
578 if ( (memneeded) && (rd->memuse & 1))
581 v->regoff = rd->memuse;
582 rd->memuse += memneeded + 1;
587 #ifdef HAS_ADDRESS_REGISTER_FILE
590 } /* for (tt=0;...) */
592 /* If the current parameter is a 2-word type, the next local slot */
595 if (p < md->paramcount)
596 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
602 for (s = 0; s < cd->maxlocals; s++) {
603 intalloc = -1; fltalloc = -1;
604 for (tt=0; tt<=4; tt++) {
606 v = &rd->locals[s][t];
609 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
610 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
612 #if defined(HAS_4BYTE_STACKSLOT)
613 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
615 #ifdef HAS_ADDRESS_REGISTER_FILE
616 if ( IS_ADR_TYPE(t) ) {
617 if (rd->savadrreguse > 0) {
619 v->regoff = rd->savadrregs[--rd->savadrreguse];
623 v->regoff = rd->memuse++;
627 if (IS_FLT_DBL_TYPE(t)) {
629 v->flags = rd->locals[s][fltalloc].flags;
630 v->regoff = rd->locals[s][fltalloc].regoff;
632 else if (rd->savfltreguse > 0) {
634 v->regoff = rd->savfltregs[--rd->savfltreguse];
638 #if defined(ALIGN_DOUBLES_IN_MEMORY)
639 /* Align doubles in Memory */
640 if ( (memneeded) && (rd->memuse & 1))
643 v->regoff = rd->memuse;
644 rd->memuse += memneeded + 1;
649 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
651 * for i386 put all longs in memory
653 if (IS_2_WORD_TYPE(t)) {
655 #if defined(ALIGN_LONGS_IN_MEMORY)
656 /* Align longs in Memory */
660 v->regoff = rd->memuse;
661 rd->memuse += memneeded + 1;
665 v->flags = rd->locals[s][intalloc].flags;
666 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
667 if (!(v->flags & INMEMORY)
668 && IS_2_WORD_TYPE(intalloc))
669 v->regoff = GET_LOW_REG(
670 rd->locals[s][intalloc].regoff);
673 v->regoff = rd->locals[s][intalloc].regoff;
675 else if (rd->savintreguse > intregsneeded) {
676 rd->savintreguse -= intregsneeded+1;
678 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
680 v->regoff = PACK_REGS(
681 rd->savintregs[rd->savintreguse],
682 rd->savintregs[rd->savintreguse + 1]);
685 v->regoff =rd->savintregs[rd->savintreguse];
689 #if defined(ALIGN_LONGS_IN_MEMORY)
690 /* Align longs in Memory */
691 if ( (memneeded) && (rd->memuse & 1))
694 v->regoff = rd->memuse;
695 rd->memuse += memneeded + 1;
697 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
702 #ifdef HAS_ADDRESS_REGISTER_FILE
711 static void reg_init_temp(methodinfo *m, registerdata *rd)
714 #if defined(HAS_4BYTE_STACKSLOT)
715 rd->freememtop_2 = 0;
718 rd->freetmpinttop = 0;
719 rd->freesavinttop = 0;
720 rd->freetmpflttop = 0;
721 rd->freesavflttop = 0;
722 #ifdef HAS_ADDRESS_REGISTER_FILE
723 rd->freetmpadrtop = 0;
724 rd->freesavadrtop = 0;
727 rd->freearginttop = 0;
728 rd->freeargflttop = 0;
729 #ifdef HAS_ADDRESS_REGISTER_FILE
730 rd->freeargadrtop = 0;
735 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
737 static void reg_new_temp_func(registerdata *rd, stackptr s)
743 /* Try to allocate a saved register if there is no temporary one */
744 /* available. This is what happens during the second run. */
745 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
747 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
748 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
752 #if defined(HAS_4BYTE_STACKSLOT)
753 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
758 for(; tryagain; --tryagain) {
760 if (!(s->flags & SAVEDVAR))
761 s->flags |= SAVEDTMP;
762 #ifdef HAS_ADDRESS_REGISTER_FILE
763 if (IS_ADR_TYPE(s->type)) {
764 if (rd->freesavadrtop > 0) {
765 s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
767 } else if (rd->savadrreguse > 0) {
768 s->regoff = rd->savadrregs[--rd->savadrreguse];
774 if (IS_FLT_DBL_TYPE(s->type)) {
775 if (rd->freesavflttop > 0) {
776 s->regoff = rd->freesavfltregs[--rd->freesavflttop];
778 } else if (rd->savfltreguse > 0) {
779 s->regoff = rd->savfltregs[--rd->savfltreguse];
783 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
785 * for i386 put all longs in memory
787 if (!IS_2_WORD_TYPE(s->type))
790 if (rd->freesavinttop > intregsneeded) {
791 rd->freesavinttop -= intregsneeded + 1;
792 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
794 s->regoff = PACK_REGS(
795 rd->freesavintregs[rd->freesavinttop],
796 rd->freesavintregs[rd->freesavinttop + 1]);
800 rd->freesavintregs[rd->freesavinttop];
802 } else if (rd->savintreguse > intregsneeded) {
803 rd->savintreguse -= intregsneeded + 1;
804 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
806 s->regoff = PACK_REGS(
807 rd->savintregs[rd->savintreguse],
808 rd->savintregs[rd->savintreguse + 1]);
811 s->regoff = rd->savintregs[rd->savintreguse];
817 } else { /* tryagain == 2 */
818 #ifdef HAS_ADDRESS_REGISTER_FILE
819 if (IS_ADR_TYPE(s->type)) {
820 if (rd->freetmpadrtop > 0) {
821 s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
823 } else if (rd->tmpadrreguse > 0) {
824 s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
830 if (IS_FLT_DBL_TYPE(s->type)) {
831 if (rd->freeargflttop > 0) {
832 s->regoff = rd->freeargfltregs[--rd->freeargflttop];
835 } else if (rd->argfltreguse < FLT_ARG_CNT) {
836 s->regoff = rd->argfltregs[rd->argfltreguse++];
839 } else if (rd->freetmpflttop > 0) {
840 s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
842 } else if (rd->tmpfltreguse > 0) {
843 s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
848 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
850 * for i386 put all longs in memory
852 if (!IS_2_WORD_TYPE(s->type))
855 if (rd->freearginttop > intregsneeded) {
856 rd->freearginttop -= intregsneeded + 1;
858 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
860 s->regoff = PACK_REGS(
861 rd->freeargintregs[rd->freearginttop],
862 rd->freeargintregs[rd->freearginttop + 1]);
866 rd->freeargintregs[rd->freearginttop];
868 } else if (rd->argintreguse
869 < INT_ARG_CNT - intregsneeded) {
870 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
872 s->regoff = PACK_REGS(
873 rd->argintregs[rd->argintreguse],
874 rd->argintregs[rd->argintreguse + 1]);
877 s->regoff = rd->argintregs[rd->argintreguse];
879 rd->argintreguse += intregsneeded + 1;
881 } else if (rd->freetmpinttop > intregsneeded) {
882 rd->freetmpinttop -= intregsneeded + 1;
883 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
885 s->regoff = PACK_REGS(
886 rd->freetmpintregs[rd->freetmpinttop],
887 rd->freetmpintregs[rd->freetmpinttop + 1]);
890 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
892 } else if (rd->tmpintreguse > intregsneeded) {
893 rd->tmpintreguse -= intregsneeded + 1;
894 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
896 s->regoff = PACK_REGS(
897 rd->tmpintregs[rd->tmpintreguse],
898 rd->tmpintregs[rd->tmpintreguse + 1]);
901 s->regoff = rd->tmpintregs[rd->tmpintreguse];
904 } /* if (!IS_2_WORD_TYPE(s->type)) */
905 } /* if (IS_FLT_DBL_TYPE(s->type)) */
906 } /* if (IS_ADR_TYPE(s->type)) */
907 } /* if (tryagain == 1) else */
908 } /* for(; tryagain; --tryagain) */
910 #if defined(HAS_4BYTE_STACKSLOT)
911 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
913 s->regoff = rd->freemem_2[rd->freememtop_2];
915 #endif /*defined(HAS_4BYTE_STACKSLOT) */
916 if ((memneeded == 0) && (rd->freememtop > 0)) {
918 s->regoff = rd->freemem[rd->freememtop];
920 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
921 /* align 2 Word Types */
922 if ((memneeded) && ((rd->memuse & 1) == 1)) {
923 /* Put patched memory slot on freemem */
924 rd->freemem[rd->freememtop++] = rd->memuse;
927 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
928 s->regoff = rd->memuse;
929 rd->memuse += memneeded + 1;
931 s->flags |= INMEMORY;
935 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
937 static void reg_free_temp_func(registerdata *rd, stackptr s)
942 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
943 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
948 #if defined(HAS_4BYTE_STACKSLOT)
949 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
954 if (s->flags & INMEMORY) {
955 #if defined(HAS_4BYTE_STACKSLOT)
957 rd->freemem_2[rd->freememtop_2] = s->regoff;
962 rd->freemem[rd->freememtop] = s->regoff;
966 #ifdef HAS_ADDRESS_REGISTER_FILE
967 } else if (IS_ADR_TYPE(s->type)) {
968 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
969 s->flags &= ~SAVEDTMP;
970 rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
972 rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
974 } else if (IS_FLT_DBL_TYPE(s->type)) {
975 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
976 s->flags &= ~SAVEDTMP;
977 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
978 } else if (s->flags & TMPARG) {
980 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
982 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
983 } else { /* IS_INT_LNG_TYPE */
984 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
985 s->flags &= ~SAVEDTMP;
986 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
988 rd->freesavintregs[rd->freesavinttop] =
989 GET_LOW_REG(s->regoff);
990 rd->freesavintregs[rd->freesavinttop + 1] =
991 GET_HIGH_REG(s->regoff);
994 rd->freesavintregs[rd->freesavinttop] = s->regoff;
995 rd->freesavinttop += intregsneeded + 1;
997 } else if (s->flags & TMPARG) {
999 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1000 if (intregsneeded) {
1001 rd->freeargintregs[rd->freearginttop] =
1002 GET_LOW_REG(s->regoff);
1003 rd->freeargintregs[rd->freearginttop + 1] =
1004 GET_HIGH_REG(s->regoff);
1007 rd->freeargintregs[rd->freearginttop] = s->regoff;
1008 rd->freearginttop += intregsneeded + 1;
1010 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1011 if (intregsneeded) {
1012 rd->freetmpintregs[rd->freetmpinttop] =
1013 GET_LOW_REG(s->regoff);
1014 rd->freetmpintregs[rd->freetmpinttop + 1] =
1015 GET_HIGH_REG(s->regoff);
1018 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1019 rd->freetmpinttop += intregsneeded + 1;
1026 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
1036 builtintable_entry *bte;
1039 /* initialize temp registers */
1040 reg_init_temp(m, rd);
1042 bptr = m->basicblocks;
1044 while (bptr != NULL) {
1045 if (bptr->flags >= BBREACHED) {
1046 dst = bptr->instack;
1049 iptr = bptr->iinstr;
1052 while (--len >= 0) {
1062 case ICMD_ELSE_ICONST:
1063 case ICMD_CHECKNULL:
1069 case ICMD_PUTSTATICCONST:
1070 case ICMD_INLINE_START:
1071 case ICMD_INLINE_END:
1072 case ICMD_INLINE_GOTO:
1075 /* pop 0 push 1 const */
1083 /* pop 0 push 1 load */
1090 reg_new_temp(rd, dst);
1104 reg_free_temp(rd, src);
1105 reg_free_temp(rd, src->prev);
1106 reg_new_temp(rd, dst);
1120 reg_free_temp(rd, src);
1121 reg_free_temp(rd, src->prev);
1122 reg_free_temp(rd, src->prev->prev);
1125 /* pop 1 push 0 store */
1145 case ICMD_PUTSTATIC:
1146 case ICMD_PUTFIELDCONST:
1148 /* pop 1 push 0 branch */
1151 case ICMD_IFNONNULL:
1167 /* pop 1 push 0 table branch */
1169 case ICMD_TABLESWITCH:
1170 case ICMD_LOOKUPSWITCH:
1172 case ICMD_MONITORENTER:
1173 case ICMD_MONITOREXIT:
1174 reg_free_temp(rd, src);
1177 /* pop 2 push 0 branch */
1179 case ICMD_IF_ICMPEQ:
1180 case ICMD_IF_ICMPNE:
1181 case ICMD_IF_ICMPLT:
1182 case ICMD_IF_ICMPGE:
1183 case ICMD_IF_ICMPGT:
1184 case ICMD_IF_ICMPLE:
1186 case ICMD_IF_LCMPEQ:
1187 case ICMD_IF_LCMPNE:
1188 case ICMD_IF_LCMPLT:
1189 case ICMD_IF_LCMPGE:
1190 case ICMD_IF_LCMPGT:
1191 case ICMD_IF_LCMPLE:
1193 case ICMD_IF_ACMPEQ:
1194 case ICMD_IF_ACMPNE:
1202 case ICMD_IASTORECONST:
1203 case ICMD_LASTORECONST:
1204 case ICMD_AASTORECONST:
1205 case ICMD_BASTORECONST:
1206 case ICMD_CASTORECONST:
1207 case ICMD_SASTORECONST:
1208 reg_free_temp(rd, src);
1209 reg_free_temp(rd, src->prev);
1212 /* pop 0 push 1 dup */
1215 reg_new_temp(rd, dst);
1218 /* pop 0 push 2 dup */
1221 reg_new_temp(rd, dst->prev);
1222 reg_new_temp(rd, dst);
1225 /* pop 2 push 3 dup */
1228 reg_free_temp(rd, src);
1229 reg_new_temp(rd, dst);
1230 reg_free_temp(rd, src->prev);
1231 reg_new_temp(rd, dst->prev);
1232 reg_new_temp(rd, dst->prev->prev);
1235 /* pop 3 push 4 dup */
1238 reg_free_temp(rd, src);
1239 reg_new_temp(rd, dst);
1240 reg_free_temp(rd, src->prev);
1241 reg_new_temp(rd, dst->prev);
1242 reg_free_temp(rd, src->prev->prev);
1243 reg_new_temp(rd, dst->prev->prev);
1244 reg_new_temp(rd, dst->prev->prev->prev);
1247 /* pop 3 push 5 dup */
1250 reg_free_temp(rd, src);
1251 reg_new_temp(rd, dst);
1252 reg_free_temp(rd, src->prev);
1253 reg_new_temp(rd, dst->prev);
1254 reg_free_temp(rd, src->prev->prev);
1255 reg_new_temp(rd, dst->prev->prev);
1256 reg_new_temp(rd, dst->prev->prev->prev);
1257 reg_new_temp(rd, dst->prev->prev->prev->prev);
1260 /* pop 4 push 6 dup */
1263 reg_free_temp(rd, src);
1264 reg_new_temp(rd, dst);
1265 reg_free_temp(rd, src->prev);
1266 reg_new_temp(rd, dst->prev);
1267 reg_free_temp(rd, src->prev->prev);
1268 reg_new_temp(rd, dst->prev->prev);
1269 reg_free_temp(rd, src->prev->prev->prev);
1270 reg_new_temp(rd, dst->prev->prev->prev);
1271 reg_new_temp(rd, dst->prev->prev->prev->prev);
1272 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1275 /* pop 2 push 2 swap */
1278 reg_free_temp(rd, src);
1279 reg_new_temp(rd, dst->prev);
1280 reg_free_temp(rd, src->prev);
1281 reg_new_temp(rd, dst);
1330 reg_free_temp(rd, src);
1331 reg_free_temp(rd, src->prev);
1332 reg_new_temp(rd, dst);
1337 case ICMD_IADDCONST:
1338 case ICMD_ISUBCONST:
1339 case ICMD_IMULCONST:
1343 case ICMD_IANDCONST:
1345 case ICMD_IXORCONST:
1346 case ICMD_ISHLCONST:
1347 case ICMD_ISHRCONST:
1348 case ICMD_IUSHRCONST:
1350 case ICMD_LADDCONST:
1351 case ICMD_LSUBCONST:
1352 case ICMD_LMULCONST:
1356 case ICMD_LANDCONST:
1358 case ICMD_LXORCONST:
1359 case ICMD_LSHLCONST:
1360 case ICMD_LSHRCONST:
1361 case ICMD_LUSHRCONST:
1363 case ICMD_IFEQ_ICONST:
1364 case ICMD_IFNE_ICONST:
1365 case ICMD_IFLT_ICONST:
1366 case ICMD_IFGE_ICONST:
1367 case ICMD_IFGT_ICONST:
1368 case ICMD_IFLE_ICONST:
1373 case ICMD_INT2SHORT:
1391 case ICMD_CHECKCAST:
1393 case ICMD_ARRAYLENGTH:
1394 case ICMD_INSTANCEOF:
1397 case ICMD_ANEWARRAY:
1400 reg_free_temp(rd, src);
1401 reg_new_temp(rd, dst);
1406 case ICMD_GETSTATIC:
1409 reg_new_temp(rd, dst);
1412 /* pop many push any */
1414 case ICMD_INVOKESTATIC:
1415 case ICMD_INVOKESPECIAL:
1416 case ICMD_INVOKEVIRTUAL:
1417 case ICMD_INVOKEINTERFACE:
1421 md = lm->parseddesc;
1423 unresolved_method *um = iptr->target;
1424 md = um->methodref->parseddesc.md;
1428 reg_free_temp(rd, src);
1431 if (md->returntype.type != TYPE_VOID)
1432 reg_new_temp(rd, dst);
1440 reg_free_temp(rd, src);
1443 if (md->returntype.type != TYPE_VOID)
1444 reg_new_temp(rd, dst);
1447 case ICMD_MULTIANEWARRAY:
1450 reg_free_temp(rd, src);
1453 reg_new_temp(rd, dst);
1458 new_internalerror("Unknown ICMD %d during register allocation",
1463 } /* while instructions */
1466 } /* while blocks */
1470 #if defined(ENABLE_STATISTICS)
1471 void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
1474 stackptr src, src_old;
1478 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1485 /* count how many local variables are held in memory or register */
1486 for(i=0; i < cd->maxlocals; i++)
1487 for (type=0; type <=4; type++)
1488 if (rd->locals[i][type].type != -1) { /* valid local */
1489 if (rd->locals[i][type].flags & INMEMORY) {
1490 count_locals_spilled++;
1494 count_locals_register++;
1496 /* count how many stack slots are held in memory or register */
1498 bptr = m->basicblocks;
1499 while (bptr != NULL) {
1500 if (bptr->flags >= BBREACHED) {
1502 #if defined(ENABLE_LSRA)
1505 /* check for memory moves from interface to BB instack */
1506 dst = bptr->instack;
1507 len = bptr->indepth;
1509 if (len > size_interface) size_interface = len;
1511 while (dst != NULL) {
1513 if (dst->varkind != STACKVAR) {
1514 if ( (dst->flags & INMEMORY) ||
1515 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1516 ( (dst->flags & INMEMORY) &&
1517 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1518 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1520 /* one in memory or both inmemory at different offsets */
1521 count_mem_move_bb++;
1529 /* check for memory moves from BB outstack to interface */
1530 dst = bptr->outstack;
1531 len = bptr->outdepth;
1532 if (len > size_interface) size_interface = len;
1536 if (dst->varkind != STACKVAR) {
1537 if ( (dst->flags & INMEMORY) || \
1538 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1539 ( (dst->flags & INMEMORY) && \
1540 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1541 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1543 /* one in memory or both inmemory at different offsets */
1544 count_mem_move_bb++;
1551 #if defined(ENABLE_LSRA)
1556 dst = bptr->instack;
1557 iptr = bptr->iinstr;
1561 while (--len >= 0) {
1565 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1566 switch (src->varkind) {
1569 if (!(src->flags & INMEMORY))
1570 count_ss_register++;
1576 /* case LOCALVAR: */
1577 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1578 /* count_ss_register++; */
1580 /* count_ss_spilled++; */
1583 if (!(src->flags & INMEMORY))
1584 count_argument_mem_ss++;
1586 count_argument_reg_ss++;
1590 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1591 /* if (src->varnum < FLT_ARG_CNT) { */
1592 /* count_ss_register++; */
1596 /* #if defined(__POWERPC__) */
1597 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1599 /* if (src->varnum < INT_ARG_CNT) { */
1601 /* count_ss_register++; */
1605 /* count_ss_spilled++; */
1612 } /* while instructions */
1615 } /* while blocks */
1616 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1617 if (in_register) count_method_in_register++;
1619 #endif /* defined(ENABLE_STATISTICS) */
1623 * These are local overrides for various environment variables in Emacs.
1624 * Please do not remove this and leave it at the end of the file, where
1625 * Emacs will automagically detect them.
1626 * ---------------------------------------------------------------------
1629 * indent-tabs-mode: t
1633 * vim:noexpandtab:sw=4:ts=4: