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 1753 2004-12-13 08:40:16Z 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 #if !defined(SPECIALMEMUSE)
282 /* For this to work properly the integer argument register count must be */
283 /* less or equal the float argument register count (e.g. x86_64). */
284 /* (arch.h: INT_ARG_CNT <= FLT_ARG_CNT) */
285 if (rd->arguments_num > INT_ARG_CNT) {
286 rd->ifmemuse = rd->arguments_num - INT_ARG_CNT;
293 rd->iftmpintregcnt = rd->tmpintregcnt;
294 rd->ifsavintregcnt = rd->savintregcnt;
295 rd->iftmpfltregcnt = rd->tmpfltregcnt;
296 rd->ifsavfltregcnt = rd->savfltregcnt;
298 for (s = 0; s < cd->maxstack; s++) {
299 intalloc = -1; fltalloc = -1;
300 saved = (rd->interfaces[s][TYPE_INT].flags |
301 rd->interfaces[s][TYPE_LNG].flags |
302 rd->interfaces[s][TYPE_FLT].flags |
303 rd->interfaces[s][TYPE_DBL].flags |
304 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
306 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
307 v = &rd->interfaces[s][t];
310 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
313 if (IS_FLT_DBL_TYPE(t)) {
315 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
316 v->regoff = rd->interfaces[s][fltalloc].regoff;
318 else if (rd->iftmpfltregcnt > 0) {
319 rd->iftmpfltregcnt--;
320 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
322 else if (rd->ifsavfltregcnt > 0) {
323 rd->ifsavfltregcnt--;
324 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
327 v->flags |= INMEMORY;
328 v->regoff = rd->ifmemuse;
329 rd->ifmemuse += regsneeded + 1;
334 #if defined(__I386__)
336 * for i386 put all longs in memory
338 if (IS_2_WORD_TYPE(t)) {
339 v->flags |= INMEMORY;
340 v->regoff = rd->ifmemuse++;
344 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
345 v->regoff = rd->interfaces[s][intalloc].regoff;
347 else if (rd->iftmpintregcnt > regsneeded) {
348 rd->iftmpintregcnt -= regsneeded + 1;
349 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
351 else if (rd->ifsavintregcnt > regsneeded) {
352 rd->ifsavintregcnt -= regsneeded + 1;
353 v->regoff = rd->savintregs[rd->ifsavintregcnt];
356 v->flags |= INMEMORY;
357 v->regoff = rd->ifmemuse;
358 rd->ifmemuse += regsneeded + 1;
360 #if defined(__I386__)
367 if (IS_FLT_DBL_TYPE(t)) {
369 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
370 v->regoff = rd->interfaces[s][fltalloc].regoff;
372 else if (rd->ifsavfltregcnt > 0) {
373 rd->ifsavfltregcnt--;
374 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
377 v->flags |= INMEMORY;
378 v->regoff = rd->ifmemuse;
379 rd->ifmemuse += regsneeded + 1;
384 #if defined(__I386__)
386 * for i386 put all longs in memory
388 if (IS_2_WORD_TYPE(t)) {
389 v->flags |= INMEMORY;
390 v->regoff = rd->ifmemuse++;
394 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
395 v->regoff = rd->interfaces[s][intalloc].regoff;
397 else if (rd->ifsavintregcnt > regsneeded) {
398 rd->ifsavintregcnt -= regsneeded + 1;
399 v->regoff = rd->savintregs[rd->ifsavintregcnt];
402 v->flags |= INMEMORY;
403 v->regoff = rd->ifmemuse;
404 rd->ifmemuse += regsneeded + 1;
406 #if defined(__I386__)
412 } /* if (type >= 0) */
416 rd->maxmemuse = rd->ifmemuse;
417 rd->maxargintreguse = -1;
418 rd->maxtmpintreguse = rd->iftmpintregcnt;
419 rd->maxsavintreguse = rd->ifsavintregcnt;
420 rd->maxargfltreguse = -1;
421 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
422 rd->maxsavfltreguse = rd->ifsavfltregcnt;
427 /* function local_regalloc *****************************************************
429 allocates registers for all local variables
431 *******************************************************************************/
433 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
436 int intalloc, fltalloc;
439 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
441 if (m->isleafmethod) {
442 int arg, doublewordarg, iargcnt, fargcnt;
444 arg = 0, iargcnt = 0, fargcnt = 0;
446 for (s = 0; s < cd->maxlocals; s++) {
447 intalloc = -1; fltalloc = -1;
448 for (tt = 0; tt <= 4; tt++) {
450 v = &rd->locals[s][t];
454 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
456 if (IS_FLT_DBL_TYPE(t)) {
457 #if !defined(CONSECUTIVE_FLOATARGS)
461 v->flags = rd->locals[s][fltalloc].flags;
462 v->regoff = rd->locals[s][fltalloc].regoff;
464 else if (!doublewordarg && (arg < m->paramcount) &&
465 (fargcnt < rd->fltreg_argnum)) {
467 v->regoff = rd->argfltregs[fargcnt];
469 else if (rd->maxtmpfltreguse > 0) {
470 rd->maxtmpfltreguse--;
472 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
474 else if (rd->maxsavfltreguse > 0) {
475 rd->maxsavfltreguse--;
477 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
481 v->regoff = rd->maxmemuse;
482 rd->maxmemuse += regsneeded + 1;
488 #if defined(__I386__)
490 * for i386 put all longs in memory
492 if (IS_2_WORD_TYPE(t)) {
494 v->regoff = rd->maxmemuse++;
497 #if !defined(CONSECUTIVE_INTARGS)
501 v->flags = rd->locals[s][intalloc].flags;
502 v->regoff = rd->locals[s][intalloc].regoff;
504 else if (!doublewordarg && (arg < m->paramcount)
506 && ((regtouse = iargcnt) < rd->intreg_argnum)
508 && ((regtouse = s) < rd->intreg_argnum - regsneeded)
512 v->regoff = rd->argintregs[regtouse];
514 else if (rd->maxtmpintreguse > regsneeded) {
515 rd->maxtmpintreguse -= regsneeded + 1;
517 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
519 else if (rd->maxsavintreguse > regsneeded) {
520 rd->maxsavintreguse -= regsneeded + 1;
522 v->regoff = rd->savintregs[rd->maxsavintreguse];
525 * use unused argument registers as local registers
527 else if (!doublewordarg && (arg >= m->paramcount) &&
528 (iargcnt < rd->intreg_argnum)) {
530 v->regoff = rd->argintregs[iargcnt];
536 v->regoff = rd->maxmemuse;
537 rd->maxmemuse += regsneeded + 1;
539 #if defined(__I386__)
546 if (arg < m->paramcount) {
549 /* what type was the double arg? */
550 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
558 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
562 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
575 for (s = 0; s < cd->maxlocals; s++) {
576 intalloc = -1; fltalloc = -1;
577 for (tt=0; tt<=4; tt++) {
579 v = &rd->locals[s][t];
582 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
584 if (IS_FLT_DBL_TYPE(t)) {
586 v->flags = rd->locals[s][fltalloc].flags;
587 v->regoff = rd->locals[s][fltalloc].regoff;
589 else if (rd->maxsavfltreguse > 0) {
590 rd->maxsavfltreguse--;
592 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
596 v->regoff = rd->maxmemuse;
597 rd->maxmemuse += regsneeded + 1;
602 #if defined(__I386__)
604 * for i386 put all longs in memory
606 if (IS_2_WORD_TYPE(t)) {
608 v->regoff = rd->maxmemuse++;
612 v->flags = rd->locals[s][intalloc].flags;
613 v->regoff = rd->locals[s][intalloc].regoff;
615 else if (rd->maxsavintreguse > regsneeded) {
616 rd->maxsavintreguse -= regsneeded+1;
618 v->regoff = rd->savintregs[rd->maxsavintreguse];
622 v->regoff = rd->maxmemuse;
623 rd->maxmemuse += regsneeded + 1;
625 #if defined(__I386__)
637 static void reg_init_temp(registerdata *rd)
640 rd->memuse = rd->ifmemuse;
642 rd->freetmpinttop = 0;
643 rd->freesavinttop = 0;
644 rd->freetmpflttop = 0;
645 rd->freesavflttop = 0;
647 rd->tmpintreguse = rd->iftmpintregcnt;
648 rd->savintreguse = rd->ifsavintregcnt;
649 rd->tmpfltreguse = rd->iftmpfltregcnt;
650 rd->savfltreguse = rd->ifsavfltregcnt;
652 /* all argument registers are available */
653 rd->argintreguse = rd->intreg_argnum;
654 rd->argfltreguse = rd->fltreg_argnum;
658 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
661 static void reg_new_temp_func(registerdata *rd, stackptr s)
666 /* Try to allocate a saved register if there is no temporary one */
667 /* available. This is what happens during the second run. */
668 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
671 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
676 for(; tryagain; --tryagain) {
678 if (!(s->flags & SAVEDVAR))
679 s->flags |= SAVEDTMP;
680 if (IS_FLT_DBL_TYPE(s->type)) {
681 if (rd->freesavflttop > 0) {
683 s->regoff = rd->freesavfltregs[rd->freesavflttop];
686 } else if (rd->savfltreguse > 0) {
688 if (rd->savfltreguse < rd->maxsavfltreguse)
689 rd->maxsavfltreguse = rd->savfltreguse;
690 s->regoff = rd->savfltregs[rd->savfltreguse];
695 #if defined(__I386__)
697 * for i386 put all longs in memory
699 if (!IS_2_WORD_TYPE(s->type)) {
701 if (rd->freesavinttop > regsneeded) {
702 rd->freesavinttop -= regsneeded + 1;
703 s->regoff = rd->freesavintregs[rd->freesavinttop];
706 } else if (rd->savintreguse > regsneeded) {
707 rd->savintreguse -= regsneeded + 1;
708 if (rd->savintreguse < rd->maxsavintreguse)
709 rd->maxsavintreguse = rd->savintreguse;
710 s->regoff = rd->savintregs[rd->savintreguse];
713 #if defined(__I386__)
719 if (IS_FLT_DBL_TYPE(s->type)) {
720 if (rd->freetmpflttop > 0) {
722 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
725 } else if (rd->tmpfltreguse > 0) {
727 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
728 rd->maxtmpfltreguse = rd->tmpfltreguse;
729 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
734 #if defined(__I386__)
736 * for i386 put all longs in memory
738 if (!IS_2_WORD_TYPE(s->type)) {
740 if (rd->freetmpinttop > regsneeded) {
741 rd->freetmpinttop -= regsneeded + 1;
742 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
745 } else if (rd->tmpintreguse > regsneeded) {
746 rd->tmpintreguse -= regsneeded + 1;
747 if (rd->tmpintreguse < rd->maxtmpintreguse)
748 rd->maxtmpintreguse = rd->tmpintreguse;
749 s->regoff = rd->tmpintregs[rd->tmpintreguse];
752 #if defined(__I386__)
759 if (rd->freememtop > regsneeded) {
760 rd->freememtop -= regsneeded + 1;
761 s->regoff = rd->freemem[rd->freememtop];
764 s->regoff = rd->memuse;
765 rd->memuse += regsneeded + 1;
766 if (rd->memuse > rd->maxmemuse)
767 rd->maxmemuse = rd->memuse;
769 s->flags |= INMEMORY;
773 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
776 static void reg_free_temp_func(registerdata *rd, stackptr s)
781 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
786 if (s->flags & INMEMORY) {
787 rd->freemem[rd->freememtop] = s->regoff;
789 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
790 rd->freememtop += regsneeded + 1;
792 } else if (IS_FLT_DBL_TYPE(s->type)) {
793 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
794 s->flags &= ~SAVEDTMP;
795 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
798 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
801 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
802 s->flags &= ~SAVEDTMP;
803 rd->freesavintregs[rd->freesavinttop] = s->regoff;
806 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
808 rd->freesavinttop += regsneeded + 1;
811 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
814 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
816 rd->freetmpinttop += regsneeded + 1;
823 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
833 bptr = m->basicblocks;
835 while (bptr != NULL) {
836 if (bptr->flags >= BBREACHED) {
839 /* initialize temp registers */
855 case ICMD_ELSE_ICONST:
856 case ICMD_CHECKASIZE:
857 case ICMD_CHECKEXCEPTION:
863 case ICMD_INLINE_START:
864 case ICMD_INLINE_END:
867 /* pop 0 push 1 const */
875 /* pop 0 push 1 load */
882 reg_new_temp(rd, dst);
896 reg_free_temp(rd, src);
897 reg_free_temp(rd, src->prev);
898 reg_new_temp(rd, dst);
912 reg_free_temp(rd, src);
913 reg_free_temp(rd, src->prev);
914 reg_free_temp(rd, src->prev->prev);
917 /* pop 1 push 0 store */
939 /* pop 1 push 0 branch */
958 /* pop 1 push 0 table branch */
960 case ICMD_TABLESWITCH:
961 case ICMD_LOOKUPSWITCH:
963 case ICMD_NULLCHECKPOP:
964 case ICMD_MONITORENTER:
965 case ICMD_MONITOREXIT:
966 reg_free_temp(rd, src);
969 /* pop 2 push 0 branch */
994 case ICMD_IASTORECONST:
995 case ICMD_LASTORECONST:
996 case ICMD_AASTORECONST:
997 case ICMD_BASTORECONST:
998 case ICMD_CASTORECONST:
999 case ICMD_SASTORECONST:
1000 reg_free_temp(rd, src);
1001 reg_free_temp(rd, src->prev);
1004 /* pop 0 push 1 dup */
1007 reg_new_temp(rd, dst);
1010 /* pop 0 push 2 dup */
1013 reg_new_temp(rd, dst->prev);
1014 reg_new_temp(rd, dst);
1017 /* pop 2 push 3 dup */
1020 reg_free_temp(rd, src);
1021 reg_new_temp(rd, dst);
1022 reg_free_temp(rd, src->prev);
1023 reg_new_temp(rd, dst->prev);
1024 reg_new_temp(rd, dst->prev->prev);
1027 /* pop 3 push 4 dup */
1030 reg_free_temp(rd, src);
1031 reg_new_temp(rd, dst);
1032 reg_free_temp(rd, src->prev);
1033 reg_new_temp(rd, dst->prev);
1034 reg_free_temp(rd, src->prev->prev);
1035 reg_new_temp(rd, dst->prev->prev);
1036 reg_new_temp(rd, dst->prev->prev->prev);
1039 /* pop 3 push 5 dup */
1042 reg_free_temp(rd, src);
1043 reg_new_temp(rd, dst);
1044 reg_free_temp(rd, src->prev);
1045 reg_new_temp(rd, dst->prev);
1046 reg_free_temp(rd, src->prev->prev);
1047 reg_new_temp(rd, dst->prev->prev);
1048 reg_new_temp(rd, dst->prev->prev->prev);
1049 reg_new_temp(rd, dst->prev->prev->prev->prev);
1052 /* pop 4 push 6 dup */
1055 reg_free_temp(rd, src);
1056 reg_new_temp(rd, dst);
1057 reg_free_temp(rd, src->prev);
1058 reg_new_temp(rd, dst->prev);
1059 reg_free_temp(rd, src->prev->prev);
1060 reg_new_temp(rd, dst->prev->prev);
1061 reg_free_temp(rd, src->prev->prev->prev);
1062 reg_new_temp(rd, dst->prev->prev->prev);
1063 reg_new_temp(rd, dst->prev->prev->prev->prev);
1064 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1067 /* pop 2 push 2 swap */
1070 reg_free_temp(rd, src);
1071 reg_new_temp(rd, dst->prev);
1072 reg_free_temp(rd, src->prev);
1073 reg_new_temp(rd, dst);
1122 reg_free_temp(rd, src);
1123 reg_free_temp(rd, src->prev);
1124 reg_new_temp(rd, dst);
1129 case ICMD_IADDCONST:
1130 case ICMD_ISUBCONST:
1131 case ICMD_IMULCONST:
1134 case ICMD_IANDCONST:
1136 case ICMD_IXORCONST:
1137 case ICMD_ISHLCONST:
1138 case ICMD_ISHRCONST:
1139 case ICMD_IUSHRCONST:
1141 case ICMD_LADDCONST:
1142 case ICMD_LSUBCONST:
1143 case ICMD_LMULCONST:
1146 case ICMD_LANDCONST:
1148 case ICMD_LXORCONST:
1149 case ICMD_LSHLCONST:
1150 case ICMD_LSHRCONST:
1151 case ICMD_LUSHRCONST:
1153 case ICMD_IFEQ_ICONST:
1154 case ICMD_IFNE_ICONST:
1155 case ICMD_IFLT_ICONST:
1156 case ICMD_IFGE_ICONST:
1157 case ICMD_IFGT_ICONST:
1158 case ICMD_IFLE_ICONST:
1163 case ICMD_INT2SHORT:
1181 case ICMD_CHECKCAST:
1183 case ICMD_ARRAYLENGTH:
1184 case ICMD_INSTANCEOF:
1187 case ICMD_ANEWARRAY:
1190 reg_free_temp(rd, src);
1191 reg_new_temp(rd, dst);
1196 case ICMD_GETSTATIC:
1199 reg_new_temp(rd, dst);
1202 /* pop many push any */
1204 case ICMD_INVOKEVIRTUAL:
1205 case ICMD_INVOKESPECIAL:
1206 case ICMD_INVOKESTATIC:
1207 case ICMD_INVOKEINTERFACE:
1210 reg_free_temp(rd, src);
1213 if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1214 reg_new_temp(rd, dst);
1218 reg_free_temp(rd, src);
1221 reg_free_temp(rd, src);
1224 reg_free_temp(rd, src);
1226 if (iptr->op1 != TYPE_VOID)
1227 reg_new_temp(rd, dst);
1230 case ICMD_MULTIANEWARRAY:
1233 reg_free_temp(rd, src);
1236 reg_new_temp(rd, dst);
1240 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1241 panic("Missing ICMD code during register allocation");
1244 } /* while instructions */
1247 } /* while blocks */
1252 * These are local overrides for various environment variables in Emacs.
1253 * Please do not remove this and leave it at the end of the file, where
1254 * Emacs will automagically detect them.
1255 * ---------------------------------------------------------------------
1258 * indent-tabs-mode: t