1 /* 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 1735 2004-12-07 14:33:27Z twisti $
37 #include "mm/memory.h"
38 #include "vm/jit/reg.h"
41 /* function prototypes for this file */
43 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
44 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
45 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
48 /* reg_init ********************************************************************
52 *******************************************************************************/
60 /* reg_setup *******************************************************************
64 *******************************************************************************/
66 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
71 /* setup the integer register table */
72 rd->intreg_argnum = 0;
76 for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
77 switch (nregdescint[rd->intregsnum]) {
90 rd->argintregs = DMNEW(s4, rd->intreg_argnum);
91 rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
92 rd->savintregs = DMNEW(s4, rd->savintregcnt);
93 rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
94 rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
95 rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
97 rd->secondregs = DMNEW(s4, rd->intregsnum);
100 rd->intreg_argnum = 0;
101 rd->argintreguse = 0;
102 rd->tmpintreguse = 0;
103 rd->savintreguse = 0;
105 for (i = 0; i < rd->intregsnum; i++) {
106 switch (nregdescint[i]) {
111 rd->savintregs[rd->savintreguse++] = i;
114 rd->tmpintregs[rd->tmpintreguse++] = i;
117 rd->argintregs[rd->intreg_argnum++] = i;
123 #if defined(__X86_64__)
125 * on x86_64 the argument registers are not in ascending order
126 * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
128 i = rd->argintregs[3];
129 rd->argintregs[3] = rd->argintregs[0];
130 rd->argintregs[0] = i;
132 i = rd->argintregs[2];
133 rd->argintregs[2] = rd->argintregs[1];
134 rd->argintregs[1] = i;
138 for (i = 1; i < rd->intreg_argnum; i++)
139 rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
140 for (i = 1; i < rd->tmpintregcnt; i++)
141 rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
142 for (i = 1; i < rd->savintregcnt; i++)
143 rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
145 rd->secondregs[REG_ITMP1] = REG_ITMP2;
146 rd->secondregs[REG_ITMP3] = REG_ITMP2;
147 rd->secondregs[REG_RESULT] = REG_RESULT + 1;
148 rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
151 /* setup the float register table */
152 rd->fltreg_argnum = 0;
153 rd->tmpfltregcnt = 0;
154 rd->savfltregcnt = 0;
156 for (rd->floatregsnum = 0; nregdescfloat[rd->floatregsnum] != REG_END; rd->floatregsnum++) {
157 switch (nregdescfloat[rd->floatregsnum]) {
170 rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
171 rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
172 rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
173 rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
174 rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
175 rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
177 rd->fltreg_argnum = 0;
178 rd->argfltreguse = 0;
179 rd->tmpfltreguse = 0;
180 rd->savfltreguse = 0;
182 for (i = 0; i < rd->floatregsnum; i++) {
183 switch (nregdescfloat[i]) {
185 rd->floatreg_ret = i;
188 rd->savfltregs[rd->savfltreguse++] = i;
191 rd->tmpfltregs[rd->tmpfltreguse++] = i;
194 rd->argfltregs[rd->fltreg_argnum++] = i;
201 rd->freemem = DMNEW(s4, id->cummaxstack);
202 rd->locals = DMNEW(varinfo5, id->cumlocals);
203 rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
205 for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
206 v[0][TYPE_INT].type = -1;
207 v[0][TYPE_LNG].type = -1;
208 v[0][TYPE_FLT].type = -1;
209 v[0][TYPE_DBL].type = -1;
210 v[0][TYPE_ADR].type = -1;
213 for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
214 v[0][TYPE_INT].type = -1;
215 v[0][TYPE_INT].flags = 0;
216 v[0][TYPE_LNG].type = -1;
217 v[0][TYPE_LNG].flags = 0;
218 v[0][TYPE_FLT].type = -1;
219 v[0][TYPE_FLT].flags = 0;
220 v[0][TYPE_DBL].type = -1;
221 v[0][TYPE_DBL].flags = 0;
222 v[0][TYPE_ADR].type = -1;
223 v[0][TYPE_ADR].flags = 0;
228 /* function reg_free ***********************************************************
230 releases all allocated space for registers
232 *******************************************************************************/
234 void reg_free(methodinfo *m, registerdata *rd)
240 /* reg_close *******************************************************************
244 *******************************************************************************/
252 /* function interface_regalloc *************************************************
254 allocates registers for all interface variables
256 *******************************************************************************/
258 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
260 interface_regalloc(m, cd, rd);
261 allocate_scratch_registers(m, rd);
262 local_regalloc(m, cd, rd);
266 /* function interface_regalloc *************************************************
268 allocates registers for all interface variables
270 *******************************************************************************/
272 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
275 int intalloc, fltalloc;
279 /* allocate stack space for passing arguments to called methods */
281 #ifndef SPECIALMEMUSE
282 #if defined(__X86_64__)
284 * XXX: we have a problem here, but allocating a little more stack space
285 * is better than having a bug
287 /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */
288 /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
289 if (rd->arguments_num > rd->fltreg_argnum)
290 rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum;
292 if (rd->arguments_num > rd->intreg_argnum)
293 rd->ifmemuse = rd->arguments_num - rd->intreg_argnum;
299 rd->iftmpintregcnt = rd->tmpintregcnt;
300 rd->ifsavintregcnt = rd->savintregcnt;
301 rd->iftmpfltregcnt = rd->tmpfltregcnt;
302 rd->ifsavfltregcnt = rd->savfltregcnt;
304 for (s = 0; s < cd->maxstack; s++) {
305 intalloc = -1; fltalloc = -1;
306 saved = (rd->interfaces[s][TYPE_INT].flags |
307 rd->interfaces[s][TYPE_LNG].flags |
308 rd->interfaces[s][TYPE_FLT].flags |
309 rd->interfaces[s][TYPE_DBL].flags |
310 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
312 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
313 v = &rd->interfaces[s][t];
316 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
319 if (IS_FLT_DBL_TYPE(t)) {
321 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
322 v->regoff = rd->interfaces[s][fltalloc].regoff;
324 else if (rd->iftmpfltregcnt > 0) {
325 rd->iftmpfltregcnt--;
326 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
328 else if (rd->ifsavfltregcnt > 0) {
329 rd->ifsavfltregcnt--;
330 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
333 v->flags |= INMEMORY;
334 v->regoff = rd->ifmemuse;
335 rd->ifmemuse += regsneeded + 1;
340 #if defined(__I386__)
342 * for i386 put all longs in memory
344 if (IS_2_WORD_TYPE(t)) {
345 v->flags |= INMEMORY;
346 v->regoff = rd->ifmemuse++;
350 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
351 v->regoff = rd->interfaces[s][intalloc].regoff;
353 else if (rd->iftmpintregcnt > regsneeded) {
354 rd->iftmpintregcnt -= regsneeded + 1;
355 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
357 else if (rd->ifsavintregcnt > regsneeded) {
358 rd->ifsavintregcnt -= regsneeded + 1;
359 v->regoff = rd->savintregs[rd->ifsavintregcnt];
362 v->flags |= INMEMORY;
363 v->regoff = rd->ifmemuse;
364 rd->ifmemuse += regsneeded + 1;
366 #if defined(__I386__)
373 if (IS_FLT_DBL_TYPE(t)) {
375 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
376 v->regoff = rd->interfaces[s][fltalloc].regoff;
378 else if (rd->ifsavfltregcnt > 0) {
379 rd->ifsavfltregcnt--;
380 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
383 v->flags |= INMEMORY;
384 v->regoff = rd->ifmemuse;
385 rd->ifmemuse += regsneeded + 1;
390 #if defined(__I386__)
392 * for i386 put all longs in memory
394 if (IS_2_WORD_TYPE(t)) {
395 v->flags |= INMEMORY;
396 v->regoff = rd->ifmemuse++;
400 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
401 v->regoff = rd->interfaces[s][intalloc].regoff;
403 else if (rd->ifsavintregcnt > regsneeded) {
404 rd->ifsavintregcnt -= regsneeded + 1;
405 v->regoff = rd->savintregs[rd->ifsavintregcnt];
408 v->flags |= INMEMORY;
409 v->regoff = rd->ifmemuse;
410 rd->ifmemuse += regsneeded + 1;
412 #if defined(__I386__)
418 } /* if (type >= 0) */
422 rd->maxmemuse = rd->ifmemuse;
423 rd->maxargintreguse = -1;
424 rd->maxtmpintreguse = rd->iftmpintregcnt;
425 rd->maxsavintreguse = rd->ifsavintregcnt;
426 rd->maxargfltreguse = -1;
427 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
428 rd->maxsavfltreguse = rd->ifsavfltregcnt;
433 /* function local_regalloc *****************************************************
435 allocates registers for all local variables
437 *******************************************************************************/
439 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
442 int intalloc, fltalloc;
445 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
447 if (m->isleafmethod) {
448 int arg, doublewordarg, iargcnt, fargcnt;
450 arg = 0, iargcnt = 0, fargcnt = 0;
452 for (s = 0; s < cd->maxlocals; s++) {
453 intalloc = -1; fltalloc = -1;
454 for (tt = 0; tt <= 4; tt++) {
456 v = &rd->locals[s][t];
460 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
462 if (IS_FLT_DBL_TYPE(t)) {
463 #if !defined(CONSECUTIVE_FLOATARGS)
467 v->flags = rd->locals[s][fltalloc].flags;
468 v->regoff = rd->locals[s][fltalloc].regoff;
470 else if (!doublewordarg && (arg < m->paramcount) &&
471 (fargcnt < rd->fltreg_argnum)) {
473 v->regoff = rd->argfltregs[fargcnt];
475 else if (rd->maxtmpfltreguse > 0) {
476 rd->maxtmpfltreguse--;
478 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
480 else if (rd->maxsavfltreguse > 0) {
481 rd->maxsavfltreguse--;
483 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
487 v->regoff = rd->maxmemuse;
488 rd->maxmemuse += regsneeded + 1;
494 #if defined(__I386__)
496 * for i386 put all longs in memory
498 if (IS_2_WORD_TYPE(t)) {
500 v->regoff = rd->maxmemuse++;
503 #if !defined(CONSECUTIVE_INTARGS)
507 v->flags = rd->locals[s][intalloc].flags;
508 v->regoff = rd->locals[s][intalloc].regoff;
510 else if (!doublewordarg && (arg < m->paramcount)
512 && ((regtouse = iargcnt) < rd->intreg_argnum)
514 && ((regtouse = s) < rd->intreg_argnum - regsneeded)
518 v->regoff = rd->argintregs[regtouse];
520 else if (rd->maxtmpintreguse > regsneeded) {
521 rd->maxtmpintreguse -= regsneeded + 1;
523 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
525 else if (rd->maxsavintreguse > regsneeded) {
526 rd->maxsavintreguse -= regsneeded + 1;
528 v->regoff = rd->savintregs[rd->maxsavintreguse];
531 * use unused argument registers as local registers
533 else if (!doublewordarg && (arg >= m->paramcount) &&
534 (iargcnt < rd->intreg_argnum)) {
536 v->regoff = rd->argintregs[iargcnt];
542 v->regoff = rd->maxmemuse;
543 rd->maxmemuse += regsneeded + 1;
545 #if defined(__I386__)
552 if (arg < m->paramcount) {
555 /* what type was the double arg? */
556 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
564 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
568 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
581 for (s = 0; s < cd->maxlocals; s++) {
582 intalloc = -1; fltalloc = -1;
583 for (tt=0; tt<=4; tt++) {
585 v = &rd->locals[s][t];
588 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
590 if (IS_FLT_DBL_TYPE(t)) {
592 v->flags = rd->locals[s][fltalloc].flags;
593 v->regoff = rd->locals[s][fltalloc].regoff;
595 else if (rd->maxsavfltreguse > 0) {
596 rd->maxsavfltreguse--;
598 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
602 v->regoff = rd->maxmemuse;
603 rd->maxmemuse += regsneeded + 1;
608 #if defined(__I386__)
610 * for i386 put all longs in memory
612 if (IS_2_WORD_TYPE(t)) {
614 v->regoff = rd->maxmemuse++;
618 v->flags = rd->locals[s][intalloc].flags;
619 v->regoff = rd->locals[s][intalloc].regoff;
621 else if (rd->maxsavintreguse > regsneeded) {
622 rd->maxsavintreguse -= regsneeded+1;
624 v->regoff = rd->savintregs[rd->maxsavintreguse];
628 v->regoff = rd->maxmemuse;
629 rd->maxmemuse += regsneeded + 1;
631 #if defined(__I386__)
643 static void reg_init_temp(registerdata *rd)
646 rd->memuse = rd->ifmemuse;
648 rd->freetmpinttop = 0;
649 rd->freesavinttop = 0;
650 rd->freetmpflttop = 0;
651 rd->freesavflttop = 0;
653 rd->tmpintreguse = rd->iftmpintregcnt;
654 rd->savintreguse = rd->ifsavintregcnt;
655 rd->tmpfltreguse = rd->iftmpfltregcnt;
656 rd->savfltreguse = rd->ifsavfltregcnt;
658 /* all argument registers are available */
659 rd->argintreguse = rd->intreg_argnum;
660 rd->argfltreguse = rd->fltreg_argnum;
664 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
667 static void reg_new_temp_func(registerdata *rd, stackptr s)
672 /* Try to allocate a saved register if there is no temporary one */
673 /* available. This is what happens during the second run. */
674 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
677 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
682 for(; tryagain; --tryagain) {
684 if (!(s->flags & SAVEDVAR))
685 s->flags |= SAVEDTMP;
686 if (IS_FLT_DBL_TYPE(s->type)) {
687 if (rd->freesavflttop > 0) {
689 s->regoff = rd->freesavfltregs[rd->freesavflttop];
692 } else if (rd->savfltreguse > 0) {
694 if (rd->savfltreguse < rd->maxsavfltreguse)
695 rd->maxsavfltreguse = rd->savfltreguse;
696 s->regoff = rd->savfltregs[rd->savfltreguse];
701 #if defined(__I386__)
703 * for i386 put all longs in memory
705 if (!IS_2_WORD_TYPE(s->type)) {
707 if (rd->freesavinttop > regsneeded) {
708 rd->freesavinttop -= regsneeded + 1;
709 s->regoff = rd->freesavintregs[rd->freesavinttop];
712 } else if (rd->savintreguse > regsneeded) {
713 rd->savintreguse -= regsneeded + 1;
714 if (rd->savintreguse < rd->maxsavintreguse)
715 rd->maxsavintreguse = rd->savintreguse;
716 s->regoff = rd->savintregs[rd->savintreguse];
719 #if defined(__I386__)
725 if (IS_FLT_DBL_TYPE(s->type)) {
726 if (rd->freetmpflttop > 0) {
728 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
731 } else if (rd->tmpfltreguse > 0) {
733 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
734 rd->maxtmpfltreguse = rd->tmpfltreguse;
735 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
740 #if defined(__I386__)
742 * for i386 put all longs in memory
744 if (!IS_2_WORD_TYPE(s->type)) {
746 if (rd->freetmpinttop > regsneeded) {
747 rd->freetmpinttop -= regsneeded + 1;
748 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
751 } else if (rd->tmpintreguse > regsneeded) {
752 rd->tmpintreguse -= regsneeded + 1;
753 if (rd->tmpintreguse < rd->maxtmpintreguse)
754 rd->maxtmpintreguse = rd->tmpintreguse;
755 s->regoff = rd->tmpintregs[rd->tmpintreguse];
758 #if defined(__I386__)
765 if (rd->freememtop > regsneeded) {
766 rd->freememtop -= regsneeded + 1;
767 s->regoff = rd->freemem[rd->freememtop];
770 s->regoff = rd->memuse;
771 rd->memuse += regsneeded + 1;
772 if (rd->memuse > rd->maxmemuse)
773 rd->maxmemuse = rd->memuse;
775 s->flags |= INMEMORY;
779 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
782 static void reg_free_temp_func(registerdata *rd, stackptr s)
787 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
792 if (s->flags & INMEMORY) {
793 rd->freemem[rd->freememtop] = s->regoff;
795 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
796 rd->freememtop += regsneeded + 1;
798 } else if (IS_FLT_DBL_TYPE(s->type)) {
799 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
800 s->flags &= ~SAVEDTMP;
801 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
804 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
807 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
808 s->flags &= ~SAVEDTMP;
809 rd->freesavintregs[rd->freesavinttop] = s->regoff;
812 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
814 rd->freesavinttop += regsneeded + 1;
817 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
820 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
822 rd->freetmpinttop += regsneeded + 1;
829 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
839 bptr = m->basicblocks;
841 while (bptr != NULL) {
842 if (bptr->flags >= BBREACHED) {
845 /* initialize temp registers */
861 case ICMD_ELSE_ICONST:
862 case ICMD_CHECKASIZE:
863 case ICMD_CHECKEXCEPTION:
869 case ICMD_INLINE_START:
870 case ICMD_INLINE_END:
873 /* pop 0 push 1 const */
881 /* pop 0 push 1 load */
888 reg_new_temp(rd, dst);
902 reg_free_temp(rd, src);
903 reg_free_temp(rd, src->prev);
904 reg_new_temp(rd, dst);
918 reg_free_temp(rd, src);
919 reg_free_temp(rd, src->prev);
920 reg_free_temp(rd, src->prev->prev);
923 /* pop 1 push 0 store */
945 /* pop 1 push 0 branch */
964 /* pop 1 push 0 table branch */
966 case ICMD_TABLESWITCH:
967 case ICMD_LOOKUPSWITCH:
969 case ICMD_NULLCHECKPOP:
970 case ICMD_MONITORENTER:
971 case ICMD_MONITOREXIT:
972 reg_free_temp(rd, src);
975 /* pop 2 push 0 branch */
1000 case ICMD_IASTORECONST:
1001 case ICMD_LASTORECONST:
1002 case ICMD_AASTORECONST:
1003 case ICMD_BASTORECONST:
1004 case ICMD_CASTORECONST:
1005 case ICMD_SASTORECONST:
1006 reg_free_temp(rd, src);
1007 reg_free_temp(rd, src->prev);
1010 /* pop 0 push 1 dup */
1013 reg_new_temp(rd, dst);
1016 /* pop 0 push 2 dup */
1019 reg_new_temp(rd, dst->prev);
1020 reg_new_temp(rd, dst);
1023 /* pop 2 push 3 dup */
1026 reg_free_temp(rd, src);
1027 reg_new_temp(rd, dst);
1028 reg_free_temp(rd, src->prev);
1029 reg_new_temp(rd, dst->prev);
1030 reg_new_temp(rd, dst->prev->prev);
1033 /* pop 3 push 4 dup */
1036 reg_free_temp(rd, src);
1037 reg_new_temp(rd, dst);
1038 reg_free_temp(rd, src->prev);
1039 reg_new_temp(rd, dst->prev);
1040 reg_free_temp(rd, src->prev->prev);
1041 reg_new_temp(rd, dst->prev->prev);
1042 reg_new_temp(rd, dst->prev->prev->prev);
1045 /* pop 3 push 5 dup */
1048 reg_free_temp(rd, src);
1049 reg_new_temp(rd, dst);
1050 reg_free_temp(rd, src->prev);
1051 reg_new_temp(rd, dst->prev);
1052 reg_free_temp(rd, src->prev->prev);
1053 reg_new_temp(rd, dst->prev->prev);
1054 reg_new_temp(rd, dst->prev->prev->prev);
1055 reg_new_temp(rd, dst->prev->prev->prev->prev);
1058 /* pop 4 push 6 dup */
1061 reg_free_temp(rd, src);
1062 reg_new_temp(rd, dst);
1063 reg_free_temp(rd, src->prev);
1064 reg_new_temp(rd, dst->prev);
1065 reg_free_temp(rd, src->prev->prev);
1066 reg_new_temp(rd, dst->prev->prev);
1067 reg_free_temp(rd, src->prev->prev->prev);
1068 reg_new_temp(rd, dst->prev->prev->prev);
1069 reg_new_temp(rd, dst->prev->prev->prev->prev);
1070 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1073 /* pop 2 push 2 swap */
1076 reg_free_temp(rd, src);
1077 reg_new_temp(rd, dst->prev);
1078 reg_free_temp(rd, src->prev);
1079 reg_new_temp(rd, dst);
1128 reg_free_temp(rd, src);
1129 reg_free_temp(rd, src->prev);
1130 reg_new_temp(rd, dst);
1135 case ICMD_IADDCONST:
1136 case ICMD_ISUBCONST:
1137 case ICMD_IMULCONST:
1140 case ICMD_IANDCONST:
1142 case ICMD_IXORCONST:
1143 case ICMD_ISHLCONST:
1144 case ICMD_ISHRCONST:
1145 case ICMD_IUSHRCONST:
1147 case ICMD_LADDCONST:
1148 case ICMD_LSUBCONST:
1149 case ICMD_LMULCONST:
1152 case ICMD_LANDCONST:
1154 case ICMD_LXORCONST:
1155 case ICMD_LSHLCONST:
1156 case ICMD_LSHRCONST:
1157 case ICMD_LUSHRCONST:
1159 case ICMD_IFEQ_ICONST:
1160 case ICMD_IFNE_ICONST:
1161 case ICMD_IFLT_ICONST:
1162 case ICMD_IFGE_ICONST:
1163 case ICMD_IFGT_ICONST:
1164 case ICMD_IFLE_ICONST:
1169 case ICMD_INT2SHORT:
1187 case ICMD_CHECKCAST:
1189 case ICMD_ARRAYLENGTH:
1190 case ICMD_INSTANCEOF:
1193 case ICMD_ANEWARRAY:
1196 reg_free_temp(rd, src);
1197 reg_new_temp(rd, dst);
1202 case ICMD_GETSTATIC:
1205 reg_new_temp(rd, dst);
1208 /* pop many push any */
1210 case ICMD_INVOKEVIRTUAL:
1211 case ICMD_INVOKESPECIAL:
1212 case ICMD_INVOKESTATIC:
1213 case ICMD_INVOKEINTERFACE:
1216 reg_free_temp(rd, src);
1219 if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1220 reg_new_temp(rd, dst);
1224 reg_free_temp(rd, src);
1227 reg_free_temp(rd, src);
1230 reg_free_temp(rd, src);
1232 if (iptr->op1 != TYPE_VOID)
1233 reg_new_temp(rd, dst);
1236 case ICMD_MULTIANEWARRAY:
1239 reg_free_temp(rd, src);
1242 reg_new_temp(rd, dst);
1246 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1247 panic("Missing ICMD code during register allocation");
1250 } /* while instructions */
1253 } /* while blocks */
1258 * These are local overrides for various environment variables in Emacs.
1259 * Please do not remove this and leave it at the end of the file, where
1260 * Emacs will automagically detect them.
1261 * ---------------------------------------------------------------------
1264 * indent-tabs-mode: t