1 /* 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 1459 2004-11-05 16:23:02Z twisti $
39 #include "toolbox/memory.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 = MNEW(s4, rd->intreg_argnum);
92 rd->tmpintregs = MNEW(s4, rd->tmpintregcnt);
93 rd->savintregs = MNEW(s4, rd->savintregcnt);
94 rd->freeargintregs = MNEW(s4, rd->intreg_argnum);
95 rd->freetmpintregs = MNEW(s4, rd->tmpintregcnt);
96 rd->freesavintregs = MNEW(s4, rd->savintregcnt);
98 rd->secondregs = MNEW(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 = MNEW(s4, rd->fltreg_argnum);
172 rd->tmpfltregs = MNEW(s4, rd->tmpfltregcnt);
173 rd->savfltregs = MNEW(s4, rd->savfltregcnt);
174 rd->freeargfltregs = MNEW(s4, rd->fltreg_argnum);
175 rd->freetmpfltregs = MNEW(s4, rd->tmpfltregcnt);
176 rd->freesavfltregs = MNEW(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 = MNEW(s4, id->cummaxstack);
203 rd->locals = MNEW(varinfo5, id->cumlocals);
204 rd->interfaces = MNEW(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)
237 if (rd->argintregs) MFREE(rd->argintregs, s4, rd->intreg_argnum);
238 if (rd->argfltregs) MFREE(rd->argfltregs, s4, rd->fltreg_argnum);
239 if (rd->tmpintregs) MFREE(rd->tmpintregs, s4, rd->tmpintregcnt);
240 if (rd->savintregs) MFREE(rd->savintregs, s4, rd->savintregcnt);
241 if (rd->tmpfltregs) MFREE(rd->tmpfltregs, s4, rd->tmpfltregcnt);
242 if (rd->savfltregs) MFREE(rd->savfltregs, s4, rd->savfltregcnt);
244 if (rd->freeargintregs) MFREE(rd->freeargintregs, s4, rd->intreg_argnum);
245 if (rd->freeargfltregs) MFREE(rd->freeargfltregs, s4, rd->fltreg_argnum);
246 if (rd->freetmpintregs) MFREE(rd->freetmpintregs, s4, rd->tmpintregcnt);
247 if (rd->freesavintregs) MFREE(rd->freesavintregs, s4, rd->savintregcnt);
248 if (rd->freetmpfltregs) MFREE(rd->freetmpfltregs, s4, rd->tmpfltregcnt);
249 if (rd->freesavfltregs) MFREE(rd->freesavfltregs, s4, rd->savfltregcnt);
252 if (rd->secondregs) MFREE(rd->secondregs, s4, rd->intregsnum);
255 if (rd->freemem) MFREE(rd->freemem, s4, m->maxstack);
256 if (rd->locals) MFREE(rd->locals, varinfo5, m->maxlocals);
257 if (rd->interfaces) MFREE(rd->interfaces, varinfo5, m->maxstack);
261 /* reg_close *******************************************************************
265 *******************************************************************************/
273 /* function interface_regalloc *************************************************
275 allocates registers for all interface variables
277 *******************************************************************************/
279 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
281 interface_regalloc(m, cd, rd);
282 allocate_scratch_registers(m, rd);
283 local_regalloc(m, cd, rd);
287 /* function interface_regalloc *************************************************
289 allocates registers for all interface variables
291 *******************************************************************************/
293 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
296 int intalloc, fltalloc;
300 /* allocate stack space for passing arguments to called methods */
302 #ifndef SPECIALMEMUSE
303 #if defined(__X86_64__)
305 * XXX: we have a problem here, but allocating a little more stack space
306 * is better than having a bug
308 /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */
309 /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
310 if (rd->arguments_num > rd->fltreg_argnum)
311 rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum;
313 if (rd->arguments_num > rd->intreg_argnum)
314 rd->ifmemuse = rd->arguments_num - rd->intreg_argnum;
320 rd->iftmpintregcnt = rd->tmpintregcnt;
321 rd->ifsavintregcnt = rd->savintregcnt;
322 rd->iftmpfltregcnt = rd->tmpfltregcnt;
323 rd->ifsavfltregcnt = rd->savfltregcnt;
325 for (s = 0; s < cd->maxstack; s++) {
326 intalloc = -1; fltalloc = -1;
327 saved = (rd->interfaces[s][TYPE_INT].flags |
328 rd->interfaces[s][TYPE_LNG].flags |
329 rd->interfaces[s][TYPE_FLT].flags |
330 rd->interfaces[s][TYPE_DBL].flags |
331 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
333 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
334 v = &rd->interfaces[s][t];
337 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
340 if (IS_FLT_DBL_TYPE(t)) {
342 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
343 v->regoff = rd->interfaces[s][fltalloc].regoff;
345 else if (rd->iftmpfltregcnt > 0) {
346 rd->iftmpfltregcnt--;
347 v->regoff = rd->tmpfltregs[rd->iftmpfltregcnt];
349 else if (rd->ifsavfltregcnt > 0) {
350 rd->ifsavfltregcnt--;
351 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
354 v->flags |= INMEMORY;
355 v->regoff = rd->ifmemuse;
356 rd->ifmemuse += regsneeded + 1;
361 #if defined(__I386__)
363 * for i386 put all longs in memory
365 if (IS_2_WORD_TYPE(t)) {
366 v->flags |= INMEMORY;
367 v->regoff = rd->ifmemuse++;
371 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
372 v->regoff = rd->interfaces[s][intalloc].regoff;
374 else if (rd->iftmpintregcnt > regsneeded) {
375 rd->iftmpintregcnt -= regsneeded + 1;
376 v->regoff = rd->tmpintregs[rd->iftmpintregcnt];
378 else if (rd->ifsavintregcnt > regsneeded) {
379 rd->ifsavintregcnt -= regsneeded + 1;
380 v->regoff = rd->savintregs[rd->ifsavintregcnt];
383 v->flags |= INMEMORY;
384 v->regoff = rd->ifmemuse;
385 rd->ifmemuse += regsneeded + 1;
387 #if defined(__I386__)
394 if (IS_FLT_DBL_TYPE(t)) {
396 v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY;
397 v->regoff = rd->interfaces[s][fltalloc].regoff;
399 else if (rd->ifsavfltregcnt > 0) {
400 rd->ifsavfltregcnt--;
401 v->regoff = rd->savfltregs[rd->ifsavfltregcnt];
404 v->flags |= INMEMORY;
405 v->regoff = rd->ifmemuse;
406 rd->ifmemuse += regsneeded + 1;
411 #if defined(__I386__)
413 * for i386 put all longs in memory
415 if (IS_2_WORD_TYPE(t)) {
416 v->flags |= INMEMORY;
417 v->regoff = rd->ifmemuse++;
421 v->flags |= rd->interfaces[s][intalloc].flags & INMEMORY;
422 v->regoff = rd->interfaces[s][intalloc].regoff;
424 else if (rd->ifsavintregcnt > regsneeded) {
425 rd->ifsavintregcnt -= regsneeded + 1;
426 v->regoff = rd->savintregs[rd->ifsavintregcnt];
429 v->flags |= INMEMORY;
430 v->regoff = rd->ifmemuse;
431 rd->ifmemuse += regsneeded + 1;
433 #if defined(__I386__)
439 } /* if (type >= 0) */
443 rd->maxmemuse = rd->ifmemuse;
444 rd->maxargintreguse = -1;
445 rd->maxtmpintreguse = rd->iftmpintregcnt;
446 rd->maxsavintreguse = rd->ifsavintregcnt;
447 rd->maxargfltreguse = -1;
448 rd->maxtmpfltreguse = rd->iftmpfltregcnt;
449 rd->maxsavfltreguse = rd->ifsavfltregcnt;
454 /* function local_regalloc *****************************************************
456 allocates registers for all local variables
458 *******************************************************************************/
460 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
463 int intalloc, fltalloc;
466 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
468 if (m->isleafmethod) {
469 int arg, doublewordarg, iargcnt, fargcnt;
471 arg = 0, iargcnt = 0, fargcnt = 0;
473 for (s = 0; s < cd->maxlocals; s++) {
474 intalloc = -1; fltalloc = -1;
475 for (tt = 0; tt <= 4; tt++) {
477 v = &rd->locals[s][t];
481 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
483 if (IS_FLT_DBL_TYPE(t)) {
484 #if !defined(CONSECUTIVE_FLOATARGS)
488 v->flags = rd->locals[s][fltalloc].flags;
489 v->regoff = rd->locals[s][fltalloc].regoff;
491 else if (!doublewordarg && (arg < m->paramcount) &&
492 (fargcnt < rd->fltreg_argnum)) {
494 v->regoff = rd->argfltregs[fargcnt];
496 else if (rd->maxtmpfltreguse > 0) {
497 rd->maxtmpfltreguse--;
499 v->regoff = rd->tmpfltregs[rd->maxtmpfltreguse];
501 else if (rd->maxsavfltreguse > 0) {
502 rd->maxsavfltreguse--;
504 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
508 v->regoff = rd->maxmemuse;
509 rd->maxmemuse += regsneeded + 1;
515 #if defined(__I386__)
517 * for i386 put all longs in memory
519 if (IS_2_WORD_TYPE(t)) {
521 v->regoff = rd->maxmemuse++;
524 #if !defined(CONSECUTIVE_INTARGS)
528 v->flags = rd->locals[s][intalloc].flags;
529 v->regoff = rd->locals[s][intalloc].regoff;
531 else if (!doublewordarg && (arg < m->paramcount)
533 && ((regtouse = iargcnt) < rd->intreg_argnum)
535 && ((regtouse = s) < rd->intreg_argnum - regsneeded)
539 v->regoff = rd->argintregs[regtouse];
541 else if (rd->maxtmpintreguse > regsneeded) {
542 rd->maxtmpintreguse -= regsneeded + 1;
544 v->regoff = rd->tmpintregs[rd->maxtmpintreguse];
546 else if (rd->maxsavintreguse > regsneeded) {
547 rd->maxsavintreguse -= regsneeded + 1;
549 v->regoff = rd->savintregs[rd->maxsavintreguse];
552 * use unused argument registers as local registers
554 else if (!doublewordarg && (arg >= m->paramcount) &&
555 (iargcnt < rd->intreg_argnum)) {
557 v->regoff = rd->argintregs[iargcnt];
563 v->regoff = rd->maxmemuse;
564 rd->maxmemuse += regsneeded + 1;
566 #if defined(__I386__)
573 if (arg < m->paramcount) {
576 /* what type was the double arg? */
577 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
585 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
589 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
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 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
611 if (IS_FLT_DBL_TYPE(t)) {
613 v->flags = rd->locals[s][fltalloc].flags;
614 v->regoff = rd->locals[s][fltalloc].regoff;
616 else if (rd->maxsavfltreguse > 0) {
617 rd->maxsavfltreguse--;
619 v->regoff = rd->savfltregs[rd->maxsavfltreguse];
623 v->regoff = rd->maxmemuse;
624 rd->maxmemuse += regsneeded + 1;
629 #if defined(__I386__)
631 * for i386 put all longs in memory
633 if (IS_2_WORD_TYPE(t)) {
635 v->regoff = rd->maxmemuse++;
639 v->flags = rd->locals[s][intalloc].flags;
640 v->regoff = rd->locals[s][intalloc].regoff;
642 else if (rd->maxsavintreguse > regsneeded) {
643 rd->maxsavintreguse -= regsneeded+1;
645 v->regoff = rd->savintregs[rd->maxsavintreguse];
649 v->regoff = rd->maxmemuse;
650 rd->maxmemuse += regsneeded + 1;
652 #if defined(__I386__)
664 static void reg_init_temp(registerdata *rd)
667 rd->memuse = rd->ifmemuse;
669 rd->freetmpinttop = 0;
670 rd->freesavinttop = 0;
671 rd->freetmpflttop = 0;
672 rd->freesavflttop = 0;
674 rd->tmpintreguse = rd->iftmpintregcnt;
675 rd->savintreguse = rd->ifsavintregcnt;
676 rd->tmpfltreguse = rd->iftmpfltregcnt;
677 rd->savfltreguse = rd->ifsavfltregcnt;
679 /* all argument registers are available */
680 rd->argintreguse = rd->intreg_argnum;
681 rd->argfltreguse = rd->fltreg_argnum;
685 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
688 static void reg_new_temp_func(registerdata *rd, stackptr s)
693 /* Try to allocate a saved register if there is no temporary one */
694 /* available. This is what happens during the second run. */
695 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
698 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
703 for(; tryagain; --tryagain) {
705 if (!(s->flags & SAVEDVAR))
706 s->flags |= SAVEDTMP;
707 if (IS_FLT_DBL_TYPE(s->type)) {
708 if (rd->freesavflttop > 0) {
710 s->regoff = rd->freesavfltregs[rd->freesavflttop];
713 } else if (rd->savfltreguse > 0) {
715 if (rd->savfltreguse < rd->maxsavfltreguse)
716 rd->maxsavfltreguse = rd->savfltreguse;
717 s->regoff = rd->savfltregs[rd->savfltreguse];
722 #if defined(__I386__)
724 * for i386 put all longs in memory
726 if (!IS_2_WORD_TYPE(s->type)) {
728 if (rd->freesavinttop > regsneeded) {
729 rd->freesavinttop -= regsneeded + 1;
730 s->regoff = rd->freesavintregs[rd->freesavinttop];
733 } else if (rd->savintreguse > regsneeded) {
734 rd->savintreguse -= regsneeded + 1;
735 if (rd->savintreguse < rd->maxsavintreguse)
736 rd->maxsavintreguse = rd->savintreguse;
737 s->regoff = rd->savintregs[rd->savintreguse];
740 #if defined(__I386__)
746 if (IS_FLT_DBL_TYPE(s->type)) {
747 if (rd->freetmpflttop > 0) {
749 s->regoff = rd->freetmpfltregs[rd->freetmpflttop];
752 } else if (rd->tmpfltreguse > 0) {
754 if (rd->tmpfltreguse < rd->maxtmpfltreguse)
755 rd->maxtmpfltreguse = rd->tmpfltreguse;
756 s->regoff = rd->tmpfltregs[rd->tmpfltreguse];
761 #if defined(__I386__)
763 * for i386 put all longs in memory
765 if (!IS_2_WORD_TYPE(s->type)) {
767 if (rd->freetmpinttop > regsneeded) {
768 rd->freetmpinttop -= regsneeded + 1;
769 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
772 } else if (rd->tmpintreguse > regsneeded) {
773 rd->tmpintreguse -= regsneeded + 1;
774 if (rd->tmpintreguse < rd->maxtmpintreguse)
775 rd->maxtmpintreguse = rd->tmpintreguse;
776 s->regoff = rd->tmpintregs[rd->tmpintreguse];
779 #if defined(__I386__)
786 if (rd->freememtop > regsneeded) {
787 rd->freememtop -= regsneeded + 1;
788 s->regoff = rd->freemem[rd->freememtop];
791 s->regoff = rd->memuse;
792 rd->memuse += regsneeded + 1;
793 if (rd->memuse > rd->maxmemuse)
794 rd->maxmemuse = rd->memuse;
796 s->flags |= INMEMORY;
800 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
803 static void reg_free_temp_func(registerdata *rd, stackptr s)
808 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
813 if (s->flags & INMEMORY) {
814 rd->freemem[rd->freememtop] = s->regoff;
816 rd->freemem[rd->freememtop + 1] = s->regoff + 1;
817 rd->freememtop += regsneeded + 1;
819 } else if (IS_FLT_DBL_TYPE(s->type)) {
820 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
821 s->flags &= ~SAVEDTMP;
822 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
825 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
828 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
829 s->flags &= ~SAVEDTMP;
830 rd->freesavintregs[rd->freesavinttop] = s->regoff;
833 rd->freesavintregs[rd->freesavinttop + 1] = rd->secondregs[s->regoff];
835 rd->freesavinttop += regsneeded + 1;
838 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
841 rd->freetmpintregs[rd->freetmpinttop + 1] = rd->secondregs[s->regoff];
843 rd->freetmpinttop += regsneeded + 1;
850 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
860 bptr = m->basicblocks;
862 while (bptr != NULL) {
863 if (bptr->flags >= BBREACHED) {
866 /* initialize temp registers */
882 case ICMD_ELSE_ICONST:
883 case ICMD_CHECKASIZE:
884 case ICMD_CHECKEXCEPTION:
892 /* pop 0 push 1 const */
900 /* pop 0 push 1 load */
907 reg_new_temp(rd, dst);
921 reg_free_temp(rd, src);
922 reg_free_temp(rd, src->prev);
923 reg_new_temp(rd, dst);
937 reg_free_temp(rd, src);
938 reg_free_temp(rd, src->prev);
939 reg_free_temp(rd, src->prev->prev);
942 /* pop 1 push 0 store */
964 /* pop 1 push 0 branch */
983 /* pop 1 push 0 table branch */
985 case ICMD_TABLESWITCH:
986 case ICMD_LOOKUPSWITCH:
988 case ICMD_NULLCHECKPOP:
989 case ICMD_MONITORENTER:
990 case ICMD_MONITOREXIT:
991 reg_free_temp(rd, src);
994 /* pop 2 push 0 branch */
1000 case ICMD_IF_ICMPGT:
1001 case ICMD_IF_ICMPLE:
1003 case ICMD_IF_LCMPEQ:
1004 case ICMD_IF_LCMPNE:
1005 case ICMD_IF_LCMPLT:
1006 case ICMD_IF_LCMPGE:
1007 case ICMD_IF_LCMPGT:
1008 case ICMD_IF_LCMPLE:
1010 case ICMD_IF_ACMPEQ:
1011 case ICMD_IF_ACMPNE:
1019 case ICMD_IASTORECONST:
1020 case ICMD_LASTORECONST:
1021 case ICMD_AASTORECONST:
1022 case ICMD_BASTORECONST:
1023 case ICMD_CASTORECONST:
1024 case ICMD_SASTORECONST:
1025 reg_free_temp(rd, src);
1026 reg_free_temp(rd, src->prev);
1029 /* pop 0 push 1 dup */
1032 reg_new_temp(rd, dst);
1035 /* pop 0 push 2 dup */
1038 reg_new_temp(rd, dst->prev);
1039 reg_new_temp(rd, dst);
1042 /* pop 2 push 3 dup */
1045 reg_free_temp(rd, src);
1046 reg_new_temp(rd, dst);
1047 reg_free_temp(rd, src->prev);
1048 reg_new_temp(rd, dst->prev);
1049 reg_new_temp(rd, dst->prev->prev);
1052 /* pop 3 push 4 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_new_temp(rd, dst->prev->prev->prev);
1064 /* pop 3 push 5 dup */
1067 reg_free_temp(rd, src);
1068 reg_new_temp(rd, dst);
1069 reg_free_temp(rd, src->prev);
1070 reg_new_temp(rd, dst->prev);
1071 reg_free_temp(rd, src->prev->prev);
1072 reg_new_temp(rd, dst->prev->prev);
1073 reg_new_temp(rd, dst->prev->prev->prev);
1074 reg_new_temp(rd, dst->prev->prev->prev->prev);
1077 /* pop 4 push 6 dup */
1080 reg_free_temp(rd, src);
1081 reg_new_temp(rd, dst);
1082 reg_free_temp(rd, src->prev);
1083 reg_new_temp(rd, dst->prev);
1084 reg_free_temp(rd, src->prev->prev);
1085 reg_new_temp(rd, dst->prev->prev);
1086 reg_free_temp(rd, src->prev->prev->prev);
1087 reg_new_temp(rd, dst->prev->prev->prev);
1088 reg_new_temp(rd, dst->prev->prev->prev->prev);
1089 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1092 /* pop 2 push 2 swap */
1095 reg_free_temp(rd, src);
1096 reg_new_temp(rd, dst->prev);
1097 reg_free_temp(rd, src->prev);
1098 reg_new_temp(rd, dst);
1147 reg_free_temp(rd, src);
1148 reg_free_temp(rd, src->prev);
1149 reg_new_temp(rd, dst);
1154 case ICMD_IADDCONST:
1155 case ICMD_ISUBCONST:
1156 case ICMD_IMULCONST:
1159 case ICMD_IANDCONST:
1161 case ICMD_IXORCONST:
1162 case ICMD_ISHLCONST:
1163 case ICMD_ISHRCONST:
1164 case ICMD_IUSHRCONST:
1166 case ICMD_LADDCONST:
1167 case ICMD_LSUBCONST:
1168 case ICMD_LMULCONST:
1171 case ICMD_LANDCONST:
1173 case ICMD_LXORCONST:
1174 case ICMD_LSHLCONST:
1175 case ICMD_LSHRCONST:
1176 case ICMD_LUSHRCONST:
1178 case ICMD_IFEQ_ICONST:
1179 case ICMD_IFNE_ICONST:
1180 case ICMD_IFLT_ICONST:
1181 case ICMD_IFGE_ICONST:
1182 case ICMD_IFGT_ICONST:
1183 case ICMD_IFLE_ICONST:
1188 case ICMD_INT2SHORT:
1206 case ICMD_CHECKCAST:
1208 case ICMD_ARRAYLENGTH:
1209 case ICMD_INSTANCEOF:
1212 case ICMD_ANEWARRAY:
1215 reg_free_temp(rd, src);
1216 reg_new_temp(rd, dst);
1221 case ICMD_GETSTATIC:
1224 reg_new_temp(rd, dst);
1227 /* pop many push any */
1229 case ICMD_INVOKEVIRTUAL:
1230 case ICMD_INVOKESPECIAL:
1231 case ICMD_INVOKESTATIC:
1232 case ICMD_INVOKEINTERFACE:
1235 reg_free_temp(rd, src);
1238 if (((methodinfo *) iptr->val.a)->returntype != TYPE_VOID)
1239 reg_new_temp(rd, dst);
1243 reg_free_temp(rd, src);
1246 reg_free_temp(rd, src);
1249 reg_free_temp(rd, src);
1251 if (iptr->op1 != TYPE_VOID)
1252 reg_new_temp(rd, dst);
1255 case ICMD_MULTIANEWARRAY:
1258 reg_free_temp(rd, src);
1261 reg_new_temp(rd, dst);
1265 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1266 panic("Missing ICMD code during register allocation");
1269 } /* while instructions */
1272 } /* while blocks */
1277 * These are local overrides for various environment variables in Emacs.
1278 * Please do not remove this and leave it at the end of the file, where
1279 * Emacs will automagically detect them.
1280 * ---------------------------------------------------------------------
1283 * indent-tabs-mode: t