1 /* vm/jit/reg.inc - register allocator
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
33 $Id: reg.inc 1621 2004-11-30 13:06:55Z twisti $
38 #include "mm/memory.h"
39 #include "vm/jit/reg.h"
42 /* function prototypes for this file */
44 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
45 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
46 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
49 /* reg_init ********************************************************************
53 *******************************************************************************/
61 /* reg_setup *******************************************************************
65 *******************************************************************************/
67 void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id)
72 /* setup the integer register table */
73 rd->intreg_argnum = 0;
77 for (rd->intregsnum = 0; nregdescint[rd->intregsnum] != REG_END; rd->intregsnum++) {
78 switch (nregdescint[rd->intregsnum]) {
91 rd->argintregs = DMNEW(s4, rd->intreg_argnum);
92 rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt);
93 rd->savintregs = DMNEW(s4, rd->savintregcnt);
94 rd->freeargintregs = DMNEW(s4, rd->intreg_argnum);
95 rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt);
96 rd->freesavintregs = DMNEW(s4, rd->savintregcnt);
98 rd->secondregs = DMNEW(s4, rd->intregsnum);
101 rd->intreg_argnum = 0;
102 rd->argintreguse = 0;
103 rd->tmpintreguse = 0;
104 rd->savintreguse = 0;
106 for (i = 0; i < rd->intregsnum; i++) {
107 switch (nregdescint[i]) {
112 rd->savintregs[rd->savintreguse++] = i;
115 rd->tmpintregs[rd->tmpintreguse++] = i;
118 rd->argintregs[rd->intreg_argnum++] = i;
124 #if defined(__X86_64__)
126 * on x86_64 the argument registers are not in ascending order
127 * a00 (%rdi) <-> a03 (%rcx) and a01 (%rsi) <-> a02 (%rdx)
129 i = rd->argintregs[3];
130 rd->argintregs[3] = rd->argintregs[0];
131 rd->argintregs[0] = i;
133 i = rd->argintregs[2];
134 rd->argintregs[2] = rd->argintregs[1];
135 rd->argintregs[1] = i;
139 for (i = 1; i < rd->intreg_argnum; i++)
140 rd->secondregs[rd->argintregs[i - 1]] = rd->argintregs[i];
141 for (i = 1; i < rd->tmpintregcnt; i++)
142 rd->secondregs[rd->tmpintregs[i - 1]] = rd->tmpintregs[i];
143 for (i = 1; i < rd->savintregcnt; i++)
144 rd->secondregs[rd->savintregs[i - 1]] = rd->savintregs[i];
146 rd->secondregs[REG_ITMP1] = REG_ITMP2;
147 rd->secondregs[REG_ITMP3] = REG_ITMP2;
148 rd->secondregs[REG_RESULT] = REG_RESULT + 1;
149 rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3;
152 /* setup the float register table */
153 rd->fltreg_argnum = 0;
154 rd->tmpfltregcnt = 0;
155 rd->savfltregcnt = 0;
157 for (rd->floatregsnum = 0; nregdescfloat[rd->floatregsnum] != REG_END; rd->floatregsnum++) {
158 switch (nregdescfloat[rd->floatregsnum]) {
171 rd->argfltregs = DMNEW(s4, rd->fltreg_argnum);
172 rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
173 rd->savfltregs = DMNEW(s4, rd->savfltregcnt);
174 rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum);
175 rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt);
176 rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt);
178 rd->fltreg_argnum = 0;
179 rd->argfltreguse = 0;
180 rd->tmpfltreguse = 0;
181 rd->savfltreguse = 0;
183 for (i = 0; i < rd->floatregsnum; i++) {
184 switch (nregdescfloat[i]) {
186 rd->floatreg_ret = i;
189 rd->savfltregs[rd->savfltreguse++] = i;
192 rd->tmpfltregs[rd->tmpfltreguse++] = i;
195 rd->argfltregs[rd->fltreg_argnum++] = i;
202 rd->freemem = DMNEW(s4, id->cummaxstack);
203 rd->locals = DMNEW(varinfo5, id->cumlocals);
204 rd->interfaces = DMNEW(varinfo5, id->cummaxstack);
206 for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) {
207 v[0][TYPE_INT].type = -1;
208 v[0][TYPE_LNG].type = -1;
209 v[0][TYPE_FLT].type = -1;
210 v[0][TYPE_DBL].type = -1;
211 v[0][TYPE_ADR].type = -1;
214 for (v = rd->interfaces, i = id->cummaxstack; i > 0; v++, i--) {
215 v[0][TYPE_INT].type = -1;
216 v[0][TYPE_INT].flags = 0;
217 v[0][TYPE_LNG].type = -1;
218 v[0][TYPE_LNG].flags = 0;
219 v[0][TYPE_FLT].type = -1;
220 v[0][TYPE_FLT].flags = 0;
221 v[0][TYPE_DBL].type = -1;
222 v[0][TYPE_DBL].flags = 0;
223 v[0][TYPE_ADR].type = -1;
224 v[0][TYPE_ADR].flags = 0;
229 /* function reg_free ***********************************************************
231 releases all allocated space for registers
233 *******************************************************************************/
235 void reg_free(methodinfo *m, registerdata *rd)
241 /* reg_close *******************************************************************
245 *******************************************************************************/
253 /* function interface_regalloc *************************************************
255 allocates registers for all interface variables
257 *******************************************************************************/
259 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
261 interface_regalloc(m, cd, rd);
262 allocate_scratch_registers(m, rd);
263 local_regalloc(m, cd, rd);
267 /* function interface_regalloc *************************************************
269 allocates registers for all interface variables
271 *******************************************************************************/
273 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
276 int intalloc, fltalloc;
280 /* allocate stack space for passing arguments to called methods */
282 #ifndef SPECIALMEMUSE
283 #if defined(__X86_64__)
285 * XXX: we have a problem here, but allocating a little more stack space
286 * is better than having a bug
288 /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */
289 /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
290 if (rd->arguments_num > rd->fltreg_argnum)
291 rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum;
293 if (rd->arguments_num > rd->intreg_argnum)
294 rd->ifmemuse = rd->arguments_num - rd->intreg_argnum;
300 rd->iftmpintregcnt = rd->tmpintregcnt;
301 rd->ifsavintregcnt = rd->savintregcnt;
302 rd->iftmpfltregcnt = rd->tmpfltregcnt;
303 rd->ifsavfltregcnt = rd->savfltregcnt;
305 for (s = 0; s < cd->maxstack; s++) {
306 intalloc = -1; fltalloc = -1;
307 saved = (rd->interfaces[s][TYPE_INT].flags |
308 rd->interfaces[s][TYPE_LNG].flags |
309 rd->interfaces[s][TYPE_FLT].flags |
310 rd->interfaces[s][TYPE_DBL].flags |
311 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
313 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
314 v = &rd->interfaces[s][t];
317 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
320 if (IS_FLT_DBL_TYPE(t)) {
322 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
323 v->regoff = rd->interfaces[s][fltalloc].regoff;
325 else if (rd->iftmpfltregcnt > 0) {
326 rd->iftmpfltregcnt--;
327 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
329 else if (rd->ifsavfltregcnt > 0) {
330 rd->ifsavfltregcnt--;
331 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
334 v->flags |= INMEMORY;
335 v->regoff = rd->ifmemuse;
336 rd->ifmemuse += regsneeded + 1;
341 #if defined(__I386__)
343 * for i386 put all longs in memory
345 if (IS_2_WORD_TYPE(t)) {
346 v->flags |= INMEMORY;
347 v->regoff = rd->ifmemuse++;
351 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
352 v->regoff = rd->interfaces[s][intalloc].regoff;
354 else if (rd->iftmpintregcnt > regsneeded) {
355 rd->iftmpintregcnt -= regsneeded + 1;
356 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
358 else if (rd->ifsavintregcnt > regsneeded) {
359 rd->ifsavintregcnt -= regsneeded + 1;
360 v->regoff = rd->savintregs[rd->ifsavintregcnt];
363 v->flags |= INMEMORY;
364 v->regoff = rd->ifmemuse;
365 rd->ifmemuse += regsneeded + 1;
367 #if defined(__I386__)
374 if (IS_FLT_DBL_TYPE(t)) {
376 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
377 v->regoff = rd->interfaces[s][fltalloc].regoff;
379 else if (rd->ifsavfltregcnt > 0) {
380 rd->ifsavfltregcnt--;
381 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
384 v->flags |= INMEMORY;
385 v->regoff = rd->ifmemuse;
386 rd->ifmemuse += regsneeded + 1;
391 #if defined(__I386__)
393 * for i386 put all longs in memory
395 if (IS_2_WORD_TYPE(t)) {
396 v->flags |= INMEMORY;
397 v->regoff = rd->ifmemuse++;
401 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
402 v->regoff = rd->interfaces[s][intalloc].regoff;
404 else if (rd->ifsavintregcnt > regsneeded) {
405 rd->ifsavintregcnt -= regsneeded + 1;
406 v->regoff = rd->savintregs[rd->ifsavintregcnt];
409 v->flags |= INMEMORY;
410 v->regoff = rd->ifmemuse;
411 rd->ifmemuse += regsneeded + 1;
413 #if defined(__I386__)
419 } /* if (type >= 0) */
423 rd->maxmemuse = rd->ifmemuse;
424 rd->maxargintreguse = -1;
425 rd->maxtmpintreguse = rd->iftmpintregcnt;
426 rd->maxsavintreguse = rd->ifsavintregcnt;
427 rd->maxargfltreguse = -1;
428 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
429 rd->maxsavfltreguse = rd->ifsavfltregcnt;
434 /* function local_regalloc *****************************************************
436 allocates registers for all local variables
438 *******************************************************************************/
440 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
443 int intalloc, fltalloc;
446 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
448 if (m->isleafmethod) {
449 int arg, doublewordarg, iargcnt, fargcnt;
451 arg = 0, iargcnt = 0, fargcnt = 0;
453 for (s = 0; s < cd->maxlocals; s++) {
454 intalloc = -1; fltalloc = -1;
455 for (tt = 0; tt <= 4; tt++) {
457 v = &rd->locals[s][t];
461 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
463 if (IS_FLT_DBL_TYPE(t)) {
464 #if !defined(CONSECUTIVE_FLOATARGS)
468 v->flags = rd->locals[s][fltalloc].flags;
469 v->regoff = rd->locals[s][fltalloc].regoff;
471 else if (!doublewordarg && (arg < m->paramcount) &&
472 (fargcnt < rd->fltreg_argnum)) {
474 v->regoff = rd->argfltregs[fargcnt];
476 else if (rd->maxtmpfltreguse > 0) {
477 rd->maxtmpfltreguse--;
479 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
481 else if (rd->maxsavfltreguse > 0) {
482 rd->maxsavfltreguse--;
484 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
488 v->regoff = rd->maxmemuse;
489 rd->maxmemuse += regsneeded + 1;
495 #if defined(__I386__)
497 * for i386 put all longs in memory
499 if (IS_2_WORD_TYPE(t)) {
501 v->regoff = rd->maxmemuse++;
504 #if !defined(CONSECUTIVE_INTARGS)
508 v->flags = rd->locals[s][intalloc].flags;
509 v->regoff = rd->locals[s][intalloc].regoff;
511 else if (!doublewordarg && (arg < m->paramcount)
513 && ((regtouse = iargcnt) < rd->intreg_argnum)
515 && ((regtouse = s) < rd->intreg_argnum - regsneeded)
519 v->regoff = rd->argintregs[regtouse];
521 else if (rd->maxtmpintreguse > regsneeded) {
522 rd->maxtmpintreguse -= regsneeded + 1;
524 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
526 else if (rd->maxsavintreguse > regsneeded) {
527 rd->maxsavintreguse -= regsneeded + 1;
529 v->regoff = rd->savintregs[rd->maxsavintreguse];
532 * use unused argument registers as local registers
534 else if (!doublewordarg && (arg >= m->paramcount) &&
535 (iargcnt < rd->intreg_argnum)) {
537 v->regoff = rd->argintregs[iargcnt];
543 v->regoff = rd->maxmemuse;
544 rd->maxmemuse += regsneeded + 1;
546 #if defined(__I386__)
553 if (arg < m->paramcount) {
556 /* what type was the double arg? */
557 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
565 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
569 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
582 for (s = 0; s < cd->maxlocals; s++) {
583 intalloc = -1; fltalloc = -1;
584 for (tt=0; tt<=4; tt++) {
586 v = &rd->locals[s][t];
589 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
591 if (IS_FLT_DBL_TYPE(t)) {
593 v->flags = rd->locals[s][fltalloc].flags;
594 v->regoff = rd->locals[s][fltalloc].regoff;
596 else if (rd->maxsavfltreguse > 0) {
597 rd->maxsavfltreguse--;
599 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
603 v->regoff = rd->maxmemuse;
604 rd->maxmemuse += regsneeded + 1;
609 #if defined(__I386__)
611 * for i386 put all longs in memory
613 if (IS_2_WORD_TYPE(t)) {
615 v->regoff = rd->maxmemuse++;
619 v->flags = rd->locals[s][intalloc].flags;
620 v->regoff = rd->locals[s][intalloc].regoff;
622 else if (rd->maxsavintreguse > regsneeded) {
623 rd->maxsavintreguse -= regsneeded+1;
625 v->regoff = rd->savintregs[rd->maxsavintreguse];
629 v->regoff = rd->maxmemuse;
630 rd->maxmemuse += regsneeded + 1;
632 #if defined(__I386__)
644 static void reg_init_temp(registerdata *rd)
647 rd->memuse = rd->ifmemuse;
649 rd->freetmpinttop = 0;
650 rd->freesavinttop = 0;
651 rd->freetmpflttop = 0;
652 rd->freesavflttop = 0;
654 rd->tmpintreguse = rd->iftmpintregcnt;
655 rd->savintreguse = rd->ifsavintregcnt;
656 rd->tmpfltreguse = rd->iftmpfltregcnt;
657 rd->savfltreguse = rd->ifsavfltregcnt;
659 /* all argument registers are available */
660 rd->argintreguse = rd->intreg_argnum;
661 rd->argfltreguse = rd->fltreg_argnum;
665 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
668 static void reg_new_temp_func(registerdata *rd, stackptr s)
673 /* Try to allocate a saved register if there is no temporary one */
674 /* available. This is what happens during the second run. */
675 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
678 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
683 for(; tryagain; --tryagain) {
685 if (!(s->flags & SAVEDVAR))
686 s->flags |= SAVEDTMP;
687 if (IS_FLT_DBL_TYPE(s->type)) {
688 if (rd->freesavflttop > 0) {
690 s->regoff = rd->freesavfltregs[rd->freesavflttop];
693 } else if (rd->savfltreguse > 0) {
695 if (rd->savfltreguse < rd->maxsavfltreguse)
696 rd->maxsavfltreguse = rd->savfltreguse;
697 s->regoff = rd->savfltregs[rd->savfltreguse];
702 #if defined(__I386__)
704 * for i386 put all longs in memory
706 if (!IS_2_WORD_TYPE(s->type)) {
708 if (rd->freesavinttop > regsneeded) {
709 rd->freesavinttop -= regsneeded + 1;
710 s->regoff = rd->freesavintregs[rd->freesavinttop];
713 } else if (rd->savintreguse > regsneeded) {
714 rd->savintreguse -= regsneeded + 1;
715 if (rd->savintreguse < rd->maxsavintreguse)
716 rd->maxsavintreguse = rd->savintreguse;
717 s->regoff = rd->savintregs[rd->savintreguse];
720 #if defined(__I386__)
726 if (IS_FLT_DBL_TYPE(s->type)) {
727 if (rd->freetmpflttop > 0) {
729 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
732 } else if (rd->tmpfltreguse > 0) {
734 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
735 rd->maxtmpfltreguse = rd->tmpfltreguse;
736 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
741 #if defined(__I386__)
743 * for i386 put all longs in memory
745 if (!IS_2_WORD_TYPE(s->type)) {
747 if (rd->freetmpinttop > regsneeded) {
748 rd->freetmpinttop -= regsneeded + 1;
749 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
752 } else if (rd->tmpintreguse > regsneeded) {
753 rd->tmpintreguse -= regsneeded + 1;
754 if (rd->tmpintreguse < rd->maxtmpintreguse)
755 rd->maxtmpintreguse = rd->tmpintreguse;
756 s->regoff = rd->tmpintregs[rd->tmpintreguse];
759 #if defined(__I386__)
766 if (rd->freememtop > regsneeded) {
767 rd->freememtop -= regsneeded + 1;
768 s->regoff = rd->freemem[rd->freememtop];
771 s->regoff = rd->memuse;
772 rd->memuse += regsneeded + 1;
773 if (rd->memuse > rd->maxmemuse)
774 rd->maxmemuse = rd->memuse;
776 s->flags |= INMEMORY;
780 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
783 static void reg_free_temp_func(registerdata *rd, stackptr s)
788 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
793 if (s->flags & INMEMORY) {
794 rd->freemem[rd->freememtop] = s->regoff;
796 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
797 rd->freememtop += regsneeded + 1;
799 } else if (IS_FLT_DBL_TYPE(s->type)) {
800 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
801 s->flags &= ~SAVEDTMP;
802 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
805 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
808 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
809 s->flags &= ~SAVEDTMP;
810 rd->freesavintregs[rd->freesavinttop] = s->regoff;
813 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
815 rd->freesavinttop += regsneeded + 1;
818 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
821 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
823 rd->freetmpinttop += regsneeded + 1;
830 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
840 bptr = m->basicblocks;
842 while (bptr != NULL) {
843 if (bptr->flags >= BBREACHED) {
846 /* initialize temp registers */
862 case ICMD_ELSE_ICONST:
863 case ICMD_CHECKASIZE:
864 case ICMD_CHECKEXCEPTION:
870 case ICMD_INLINE_START:
871 case ICMD_INLINE_END:
874 /* pop 0 push 1 const */
882 /* pop 0 push 1 load */
889 reg_new_temp(rd, dst);
903 reg_free_temp(rd, src);
904 reg_free_temp(rd, src->prev);
905 reg_new_temp(rd, dst);
919 reg_free_temp(rd, src);
920 reg_free_temp(rd, src->prev);
921 reg_free_temp(rd, src->prev->prev);
924 /* pop 1 push 0 store */
946 /* pop 1 push 0 branch */
965 /* pop 1 push 0 table branch */
967 case ICMD_TABLESWITCH:
968 case ICMD_LOOKUPSWITCH:
970 case ICMD_NULLCHECKPOP:
971 case ICMD_MONITORENTER:
972 case ICMD_MONITOREXIT:
973 reg_free_temp(rd, src);
976 /* pop 2 push 0 branch */
1001 case ICMD_IASTORECONST:
1002 case ICMD_LASTORECONST:
1003 case ICMD_AASTORECONST:
1004 case ICMD_BASTORECONST:
1005 case ICMD_CASTORECONST:
1006 case ICMD_SASTORECONST:
1007 reg_free_temp(rd, src);
1008 reg_free_temp(rd, src->prev);
1011 /* pop 0 push 1 dup */
1014 reg_new_temp(rd, dst);
1017 /* pop 0 push 2 dup */
1020 reg_new_temp(rd, dst->prev);
1021 reg_new_temp(rd, dst);
1024 /* pop 2 push 3 dup */
1027 reg_free_temp(rd, src);
1028 reg_new_temp(rd, dst);
1029 reg_free_temp(rd, src->prev);
1030 reg_new_temp(rd, dst->prev);
1031 reg_new_temp(rd, dst->prev->prev);
1034 /* pop 3 push 4 dup */
1037 reg_free_temp(rd, src);
1038 reg_new_temp(rd, dst);
1039 reg_free_temp(rd, src->prev);
1040 reg_new_temp(rd, dst->prev);
1041 reg_free_temp(rd, src->prev->prev);
1042 reg_new_temp(rd, dst->prev->prev);
1043 reg_new_temp(rd, dst->prev->prev->prev);
1046 /* pop 3 push 5 dup */
1049 reg_free_temp(rd, src);
1050 reg_new_temp(rd, dst);
1051 reg_free_temp(rd, src->prev);
1052 reg_new_temp(rd, dst->prev);
1053 reg_free_temp(rd, src->prev->prev);
1054 reg_new_temp(rd, dst->prev->prev);
1055 reg_new_temp(rd, dst->prev->prev->prev);
1056 reg_new_temp(rd, dst->prev->prev->prev->prev);
1059 /* pop 4 push 6 dup */
1062 reg_free_temp(rd, src);
1063 reg_new_temp(rd, dst);
1064 reg_free_temp(rd, src->prev);
1065 reg_new_temp(rd, dst->prev);
1066 reg_free_temp(rd, src->prev->prev);
1067 reg_new_temp(rd, dst->prev->prev);
1068 reg_free_temp(rd, src->prev->prev->prev);
1069 reg_new_temp(rd, dst->prev->prev->prev);
1070 reg_new_temp(rd, dst->prev->prev->prev->prev);
1071 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1074 /* pop 2 push 2 swap */
1077 reg_free_temp(rd, src);
1078 reg_new_temp(rd, dst->prev);
1079 reg_free_temp(rd, src->prev);
1080 reg_new_temp(rd, dst);
1129 reg_free_temp(rd, src);
1130 reg_free_temp(rd, src->prev);
1131 reg_new_temp(rd, dst);
1136 case ICMD_IADDCONST:
1137 case ICMD_ISUBCONST:
1138 case ICMD_IMULCONST:
1141 case ICMD_IANDCONST:
1143 case ICMD_IXORCONST:
1144 case ICMD_ISHLCONST:
1145 case ICMD_ISHRCONST:
1146 case ICMD_IUSHRCONST:
1148 case ICMD_LADDCONST:
1149 case ICMD_LSUBCONST:
1150 case ICMD_LMULCONST:
1153 case ICMD_LANDCONST:
1155 case ICMD_LXORCONST:
1156 case ICMD_LSHLCONST:
1157 case ICMD_LSHRCONST:
1158 case ICMD_LUSHRCONST:
1160 case ICMD_IFEQ_ICONST:
1161 case ICMD_IFNE_ICONST:
1162 case ICMD_IFLT_ICONST:
1163 case ICMD_IFGE_ICONST:
1164 case ICMD_IFGT_ICONST:
1165 case ICMD_IFLE_ICONST:
1170 case ICMD_INT2SHORT:
1188 case ICMD_CHECKCAST:
1190 case ICMD_ARRAYLENGTH:
1191 case ICMD_INSTANCEOF:
1194 case ICMD_ANEWARRAY:
1197 reg_free_temp(rd, src);
1198 reg_new_temp(rd, dst);
1203 case ICMD_GETSTATIC:
1206 reg_new_temp(rd, dst);
1209 /* pop many push any */
1211 case ICMD_INVOKEVIRTUAL:
1212 case ICMD_INVOKESPECIAL:
1213 case ICMD_INVOKESTATIC:
1214 case ICMD_INVOKEINTERFACE:
1217 reg_free_temp(rd, src);
1220 if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1221 reg_new_temp(rd, dst);
1225 reg_free_temp(rd, src);
1228 reg_free_temp(rd, src);
1231 reg_free_temp(rd, src);
1233 if (iptr->op1 != TYPE_VOID)
1234 reg_new_temp(rd, dst);
1237 case ICMD_MULTIANEWARRAY:
1240 reg_free_temp(rd, src);
1243 reg_new_temp(rd, dst);
1247 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1248 panic("Missing ICMD code during register allocation");
1251 } /* while instructions */
1254 } /* while blocks */
1259 * These are local overrides for various environment variables in Emacs.
1260 * Please do not remove this and leave it at the end of the file, where
1261 * Emacs will automagically detect them.
1262 * ---------------------------------------------------------------------
1265 * indent-tabs-mode: t