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 1274 2004-07-05 17:24:40Z twisti $
39 #include "toolbox/memory.h"
42 /* function prototypes for this file */
44 static void interface_regalloc(methodinfo *m);
45 static void local_regalloc(methodinfo *m);
46 static void allocate_scratch_registers(methodinfo *m);
49 /* function reg_init ***********************************************************
51 initialises the register-allocator
53 *******************************************************************************/
55 void reg_init(methodinfo *m)
63 /* allocate registers structure */
64 m->registerdata = NEW(registerdata);
66 /* keep code size smaller */
69 /* setup the integer register table */
74 for (r->intregsnum = 0; nregdescint[r->intregsnum] != REG_END; r->intregsnum++) {
75 switch (nregdescint[r->intregsnum]) {
76 case REG_SAV: r->savintregcnt++;
78 case REG_TMP: r->tmpintregcnt++;
80 case REG_ARG: r->intreg_argnum++;
84 r->argintregs = MNEW(s4, r->intreg_argnum);
85 r->tmpintregs = MNEW(s4, r->tmpintregcnt);
86 r->savintregs = MNEW(s4, r->savintregcnt);
87 r->freeargintregs = MNEW(s4, r->intreg_argnum);
88 r->freetmpintregs = MNEW(s4, r->tmpintregcnt);
89 r->freesavintregs = MNEW(s4, r->savintregcnt);
91 r->secondregs = MNEW(s4, r->intregsnum);
99 for (n = 0; n < r->intregsnum; n++) {
100 switch (nregdescint[n]) {
101 case REG_RET: r->intreg_ret = n;
103 case REG_SAV: r->savintregs[r->savintreguse++] = n;
105 case REG_TMP: r->tmpintregs[r->tmpintreguse++] = n;
107 case REG_ARG: r->argintregs[r->intreg_argnum++] = n;
113 #if defined(__I386__)
115 this assumes that we have 3 tmp regs (%ecx, %edx, %ebx)
116 sort to [ %ebx, %edx, %ecx ]
118 n = r->tmpintregs[0];
119 r->tmpintregs[0] = r->tmpintregs[2];
120 r->tmpintregs[2] = n;
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 n = r->argintregs[3];
129 r->argintregs[3] = r->argintregs[0];
130 r->argintregs[0] = n;
132 n = r->argintregs[2];
133 r->argintregs[2] = r->argintregs[1];
134 r->argintregs[1] = n;
138 for (n = 1; n < r->intreg_argnum; n++)
139 r->secondregs[r->argintregs[n - 1]] = r->argintregs[n];
140 for (n = 1; n < r->tmpintregcnt; n++)
141 r->secondregs[r->tmpintregs[n - 1]] = r->tmpintregs[n];
142 for (n = 1; n < r->savintregcnt; n++)
143 r->secondregs[r->savintregs[n - 1]] = r->savintregs[n];
145 r->secondregs[REG_ITMP1] = REG_ITMP2;
146 r->secondregs[REG_ITMP3] = REG_ITMP2;
147 r->secondregs[REG_RESULT] = REG_RESULT + 1;
148 r->secondregs[r->argintregs[r->intreg_argnum - 1]] = REG_ITMP3;
151 /* setup the float register table */
152 r->fltreg_argnum = 0;
156 for (r->floatregsnum = 0; nregdescfloat[r->floatregsnum] != REG_END; r->floatregsnum++) {
157 switch (nregdescfloat[r->floatregsnum]) {
158 case REG_SAV: r->savfltregcnt++;
160 case REG_TMP: r->tmpfltregcnt++;
162 case REG_ARG: r->fltreg_argnum++;
167 r->argfltregs = MNEW(s4, r->fltreg_argnum);
168 r->tmpfltregs = MNEW(s4, r->tmpfltregcnt);
169 r->savfltregs = MNEW(s4, r->savfltregcnt);
170 r->freeargfltregs = MNEW(s4, r->fltreg_argnum);
171 r->freetmpfltregs = MNEW(s4, r->tmpfltregcnt);
172 r->freesavfltregs = MNEW(s4, r->savfltregcnt);
174 r->fltreg_argnum = 0;
179 for (n = 0; n < r->floatregsnum; n++) {
180 switch (nregdescfloat[n]) {
185 r->savfltregs[r->savfltreguse++] = n;
188 r->tmpfltregs[r->tmpfltreguse++] = n;
191 r->argfltregs[r->fltreg_argnum++] = n;
199 void reg_setup(methodinfo *m)
204 m->registerdata->freemem = MNEW(s4, m->maxstack);
205 m->registerdata->locals = MNEW(varinfo5, m->maxlocals);
206 m->registerdata->interfaces = MNEW(varinfo5, m->maxstack);
208 for (v = m->registerdata->locals, i = m->maxlocals; i > 0; v++, i--) {
209 v[0][TYPE_INT].type = -1;
210 v[0][TYPE_LNG].type = -1;
211 v[0][TYPE_FLT].type = -1;
212 v[0][TYPE_DBL].type = -1;
213 v[0][TYPE_ADR].type = -1;
216 for (v = m->registerdata->interfaces, i = m->maxstack; i > 0; v++, i--) {
217 v[0][TYPE_INT].type = -1;
218 v[0][TYPE_INT].flags = 0;
219 v[0][TYPE_LNG].type = -1;
220 v[0][TYPE_LNG].flags = 0;
221 v[0][TYPE_FLT].type = -1;
222 v[0][TYPE_FLT].flags = 0;
223 v[0][TYPE_DBL].type = -1;
224 v[0][TYPE_DBL].flags = 0;
225 v[0][TYPE_ADR].type = -1;
226 v[0][TYPE_ADR].flags = 0;
231 /* function reg_close **********************************************************
233 releases all allocated space for registers
235 *******************************************************************************/
237 void reg_close(methodinfo *m)
241 /* keep code size smaller */
244 if (r->argintregs) MFREE(r->argintregs, int, r->intreg_argnum);
245 if (r->argfltregs) MFREE(r->argfltregs, int, r->fltreg_argnum);
246 if (r->tmpintregs) MFREE(r->tmpintregs, int, r->tmpintregcnt);
247 if (r->savintregs) MFREE(r->savintregs, int, r->savintregcnt);
248 if (r->tmpfltregs) MFREE(r->tmpfltregs, int, r->tmpfltregcnt);
249 if (r->savfltregs) MFREE(r->savfltregs, int, r->savfltregcnt);
251 if (r->freeargintregs) MFREE(r->freeargintregs, int, r->intreg_argnum);
252 if (r->freeargfltregs) MFREE(r->freeargfltregs, int, r->fltreg_argnum);
253 if (r->freetmpintregs) MFREE(r->freetmpintregs, int, r->tmpintregcnt);
254 if (r->freesavintregs) MFREE(r->freesavintregs, int, r->savintregcnt);
255 if (r->freetmpfltregs) MFREE(r->freetmpfltregs, int, r->tmpfltregcnt);
256 if (r->freesavfltregs) MFREE(r->freesavfltregs, int, r->savfltregcnt);
259 if (secondregs) MFREE(r->secondregs, int, r->intregsnum);
262 if (r->freemem) MFREE(r->freemem, s4, m->maxstack);
263 if (r->locals) MFREE(r->locals, varinfo5, m->maxlocals);
264 if (r->interfaces) MFREE(r->interfaces, varinfo5, m->maxstack);
266 FREE(m->registerdata, registerdata);
270 /* function interface_regalloc *************************************************
272 allocates registers for all interface variables
274 *******************************************************************************/
276 void regalloc(methodinfo *m)
278 #if defined(__I386__)
279 /* remove %ecx and/or %edx from tmpintregs */
280 int origtmpintregcnt = m->registerdata->tmpintregcnt;
281 if (method_uses_ecx) m->registerdata->tmpintregcnt--;
282 if (method_uses_edx) m->registerdata->tmpintregcnt--;
285 interface_regalloc(m);
286 allocate_scratch_registers(m);
289 #if defined(__I386__)
290 m->registerdata->tmpintregcnt = origtmpintregcnt;
295 /* function interface_regalloc *************************************************
297 allocates registers for all interface variables
299 *******************************************************************************/
301 static void interface_regalloc(methodinfo *m)
304 int intalloc, fltalloc;
309 /* allocate stack space for passing arguments to called methods */
311 /* keep code size smaller */
314 #ifndef SPECIALMEMUSE
315 #if defined(__X86_64__)
317 * XXX: we have a problem here, but allocating a little more stack space
318 * is better than having a bug
320 /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */
321 /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */
322 if (r->arguments_num > r->fltreg_argnum)
323 r->ifmemuse = r->arguments_num - r->fltreg_argnum;
325 if (r->arguments_num > r->intreg_argnum)
326 r->ifmemuse = r->arguments_num - r->intreg_argnum;
332 r->iftmpintregcnt = r->tmpintregcnt;
333 r->ifsavintregcnt = r->savintregcnt;
334 r->iftmpfltregcnt = r->tmpfltregcnt;
335 r->ifsavfltregcnt = r->savfltregcnt;
337 for (s = 0; s < m->maxstack; s++) {
338 intalloc = -1; fltalloc = -1;
339 saved = (r->interfaces[s][TYPE_INT].flags |
340 r->interfaces[s][TYPE_LNG].flags |
341 r->interfaces[s][TYPE_FLT].flags |
342 r->interfaces[s][TYPE_DBL].flags |
343 r->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
345 for (t = TYPE_INT; t <= TYPE_ADR; t++) {
346 v = &r->interfaces[s][t];
349 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
352 if (IS_FLT_DBL_TYPE(t)) {
354 v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
355 v->regoff = r->interfaces[s][fltalloc].regoff;
357 else if (r->iftmpfltregcnt > 0) {
359 v->regoff = r->tmpfltregs[r->iftmpfltregcnt];
361 else if (r->ifsavfltregcnt > 0) {
363 v->regoff = r->savfltregs[r->ifsavfltregcnt];
366 v->flags |= INMEMORY;
367 v->regoff = r->ifmemuse;
368 r->ifmemuse += regsneeded + 1;
373 #if defined(__I386__)
375 * for i386 put all longs in memory
377 if (IS_2_WORD_TYPE(t)) {
378 v->flags |= INMEMORY;
379 v->regoff = r->ifmemuse++;
383 v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
384 v->regoff = r->interfaces[s][intalloc].regoff;
386 else if (r->iftmpintregcnt > regsneeded) {
387 r->iftmpintregcnt -= regsneeded + 1;
388 v->regoff = r->tmpintregs[r->iftmpintregcnt];
390 else if (r->ifsavintregcnt > regsneeded) {
391 r->ifsavintregcnt -= regsneeded + 1;
392 v->regoff = r->savintregs[r->ifsavintregcnt];
395 v->flags |= INMEMORY;
396 v->regoff = r->ifmemuse;
397 r->ifmemuse += regsneeded + 1;
399 #if defined(__I386__)
406 if (IS_FLT_DBL_TYPE(t)) {
408 v->flags |= r->interfaces[s][fltalloc].flags & INMEMORY;
409 v->regoff = r->interfaces[s][fltalloc].regoff;
411 else if (r->ifsavfltregcnt > 0) {
413 v->regoff = r->savfltregs[r->ifsavfltregcnt];
416 v->flags |= INMEMORY;
417 v->regoff = r->ifmemuse;
418 r->ifmemuse += regsneeded + 1;
423 #if defined(__I386__)
425 * for i386 put all longs in memory
427 if (IS_2_WORD_TYPE(t)) {
428 v->flags |= INMEMORY;
429 v->regoff = r->ifmemuse++;
433 v->flags |= r->interfaces[s][intalloc].flags & INMEMORY;
434 v->regoff = r->interfaces[s][intalloc].regoff;
436 else if (r->ifsavintregcnt > regsneeded) {
437 r->ifsavintregcnt -= regsneeded + 1;
438 v->regoff = r->savintregs[r->ifsavintregcnt];
441 v->flags |= INMEMORY;
442 v->regoff = r->ifmemuse;
443 r->ifmemuse += regsneeded + 1;
445 #if defined(__I386__)
451 } /* if (type >= 0) */
455 r->maxmemuse = r->ifmemuse;
456 r->maxargintreguse = -1;
457 r->maxtmpintreguse = r->iftmpintregcnt;
458 r->maxsavintreguse = r->ifsavintregcnt;
459 r->maxargfltreguse = -1;
460 r->maxtmpfltreguse = r->iftmpfltregcnt;
461 r->maxsavfltreguse = r->ifsavfltregcnt;
466 /* function local_regalloc *****************************************************
468 allocates registers for all local variables
470 *******************************************************************************/
472 static void local_regalloc(methodinfo *m)
475 int intalloc, fltalloc;
478 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
481 /* keep code size smaller */
484 if (m->isleafmethod) {
485 int arg, doublewordarg, iargcnt, fargcnt;
487 arg = 0, iargcnt = 0, fargcnt = 0;
489 for (s = 0; s < m->maxlocals; s++) {
490 intalloc = -1; fltalloc = -1;
491 for (tt = 0; tt <= 4; tt++) {
493 v = &r->locals[s][t];
497 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
499 if (IS_FLT_DBL_TYPE(t)) {
500 #if !defined(CONSECUTIVE_FLOATARGS)
504 v->flags = r->locals[s][fltalloc].flags;
505 v->regoff = r->locals[s][fltalloc].regoff;
507 else if (!doublewordarg && (arg < m->paramcount) &&
508 (fargcnt < r->fltreg_argnum)) {
510 v->regoff = r->argfltregs[fargcnt];
512 else if (r->maxtmpfltreguse > 0) {
513 r->maxtmpfltreguse--;
515 v->regoff = r->tmpfltregs[r->maxtmpfltreguse];
517 else if (r->maxsavfltreguse > 0) {
518 r->maxsavfltreguse--;
520 v->regoff = r->savfltregs[r->maxsavfltreguse];
524 v->regoff = r->maxmemuse;
525 r->maxmemuse += regsneeded + 1;
531 #if defined(__I386__)
533 * for i386 put all longs in memory
535 if (IS_2_WORD_TYPE(t)) {
537 v->regoff = r->maxmemuse++;
540 #if !defined(CONSECUTIVE_INTARGS)
544 v->flags = r->locals[s][intalloc].flags;
545 v->regoff = r->locals[s][intalloc].regoff;
547 else if (!doublewordarg && (arg < m->paramcount)
549 && ((regtouse = iargcnt) < r->intreg_argnum)
551 && ((regtouse = s) < r->intreg_argnum - regsneeded)
555 v->regoff = r->argintregs[regtouse];
557 else if (r->maxtmpintreguse > regsneeded) {
558 r->maxtmpintreguse -= regsneeded + 1;
560 v->regoff = r->tmpintregs[r->maxtmpintreguse];
562 else if (r->maxsavintreguse > regsneeded) {
563 r->maxsavintreguse -= regsneeded + 1;
565 v->regoff = r->savintregs[r->maxsavintreguse];
568 * use unused argument registers as local registers
570 else if (!doublewordarg && (arg >= m->paramcount) &&
571 (iargcnt < r->intreg_argnum)) {
573 v->regoff = r->argintregs[iargcnt];
579 v->regoff = r->maxmemuse;
580 r->maxmemuse += regsneeded + 1;
582 #if defined(__I386__)
589 if (arg < m->paramcount) {
592 /* what type was the double arg? */
593 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
601 } else if (IS_2_WORD_TYPE(m->paramtypes[arg])) {
605 if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) {
618 for (s = 0; s < m->maxlocals; s++) {
619 intalloc = -1; fltalloc = -1;
620 for (tt=0; tt<=4; tt++) {
622 v = &r->locals[s][t];
625 regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
627 if (IS_FLT_DBL_TYPE(t)) {
629 v->flags = r->locals[s][fltalloc].flags;
630 v->regoff = r->locals[s][fltalloc].regoff;
632 else if (r->maxsavfltreguse > 0) {
633 r->maxsavfltreguse--;
635 v->regoff = r->savfltregs[r->maxsavfltreguse];
639 v->regoff = r->maxmemuse;
640 r->maxmemuse += regsneeded + 1;
645 #if defined(__I386__)
647 * for i386 put all longs in memory
649 if (IS_2_WORD_TYPE(t)) {
651 v->regoff = r->maxmemuse++;
655 v->flags = r->locals[s][intalloc].flags;
656 v->regoff = r->locals[s][intalloc].regoff;
658 else if (r->maxsavintreguse > regsneeded) {
659 r->maxsavintreguse -= regsneeded+1;
661 v->regoff = r->savintregs[r->maxsavintreguse];
665 v->regoff = r->maxmemuse;
666 r->maxmemuse += regsneeded + 1;
668 #if defined(__I386__)
680 static void reg_init_temp(methodinfo *m)
684 /* keep code size smaller */
688 r->memuse = r->ifmemuse;
690 r->freetmpinttop = 0;
691 r->freesavinttop = 0;
692 r->freetmpflttop = 0;
693 r->freesavflttop = 0;
695 r->tmpintreguse = r->iftmpintregcnt;
696 r->savintreguse = r->ifsavintregcnt;
697 r->tmpfltreguse = r->iftmpfltregcnt;
698 r->savfltreguse = r->ifsavfltregcnt;
700 /* all argument registers are available */
701 r->argintreguse = r->intreg_argnum;
702 r->argfltreguse = r->fltreg_argnum;
706 #define reg_new_temp(m,s) if (s->varkind == TEMPVAR) reg_new_temp_func(m, s)
709 static void reg_new_temp_func(methodinfo *m, stackptr s)
715 /* keep code size smaller */
718 /* Try to allocate a saved register if there is no temporary one */
719 /* available. This is what happens during the second run. */
720 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
723 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
726 for(; tryagain; --tryagain) {
728 if (!(s->flags & SAVEDVAR))
729 s->flags |= SAVEDTMP;
730 if (IS_FLT_DBL_TYPE(s->type)) {
731 if (r->freesavflttop > 0) {
733 s->regoff = r->freesavfltregs[r->freesavflttop];
736 else if (r->savfltreguse > 0) {
738 if (r->savfltreguse < r->maxsavfltreguse)
739 r->maxsavfltreguse = r->savfltreguse;
740 s->regoff = r->savfltregs[r->savfltreguse];
745 #if defined(__I386__)
747 * for i386 put all longs in memory
749 if (!IS_2_WORD_TYPE(s->type)) {
751 if (r->freesavinttop > regsneeded) {
752 r->freesavinttop -= regsneeded + 1;
753 s->regoff = r->freesavintregs[r->freesavinttop];
756 else if (r->savintreguse > regsneeded) {
757 r->savintreguse -= regsneeded + 1;
758 if (r->savintreguse < r->maxsavintreguse)
759 r->maxsavintreguse = r->savintreguse;
760 s->regoff = r->savintregs[r->savintreguse];
763 #if defined(__I386__)
769 if (IS_FLT_DBL_TYPE(s->type)) {
770 if (r->freetmpflttop > 0) {
772 s->regoff = r->freetmpfltregs[r->freetmpflttop];
775 else if (r->tmpfltreguse > 0) {
777 if (r->tmpfltreguse < r->maxtmpfltreguse)
778 r->maxtmpfltreguse = r->tmpfltreguse;
779 s->regoff = r->tmpfltregs[r->tmpfltreguse];
784 #if defined(__I386__)
786 * for i386 put all longs in memory
788 if (!IS_2_WORD_TYPE(s->type)) {
790 if (r->freetmpinttop > regsneeded) {
791 r->freetmpinttop -= regsneeded + 1;
792 s->regoff = r->freetmpintregs[r->freetmpinttop];
795 else if (r->tmpintreguse > regsneeded) {
796 r->tmpintreguse -= regsneeded + 1;
797 if (r->tmpintreguse < r->maxtmpintreguse)
798 r->maxtmpintreguse = r->tmpintreguse;
799 s->regoff = r->tmpintregs[r->tmpintreguse];
802 #if defined(__I386__)
809 if (r->freememtop > regsneeded) {
810 r->freememtop -= regsneeded + 1;
811 s->regoff = r->freemem[r->freememtop];
814 s->regoff = r->memuse;
815 r->memuse += regsneeded + 1;
816 if (r->memuse > r->maxmemuse)
817 r->maxmemuse = r->memuse;
819 s->flags |= INMEMORY;
823 #define reg_free_temp(m,s) if (s->varkind == TEMPVAR) reg_free_temp_func(m, s)
826 static void reg_free_temp_func(methodinfo *m, stackptr s)
831 /* keep code size smaller */
835 regsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
838 if (s->flags & INMEMORY) {
839 r->freemem[r->freememtop] = s->regoff;
841 r->freemem[r->freememtop + 1] = s->regoff + 1;
842 r->freememtop += regsneeded + 1;
844 else if (IS_FLT_DBL_TYPE(s->type)) {
845 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
846 s->flags &= ~SAVEDTMP;
847 r->freesavfltregs[r->freesavflttop++] = s->regoff;
849 r->freetmpfltregs[r->freetmpflttop++] = s->regoff;
852 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
853 s->flags &= ~SAVEDTMP;
854 r->freesavintregs[r->freesavinttop] = s->regoff;
857 r->freesavintregs[r->freesavinttop + 1] = r->secondregs[s->regoff];
859 r->freesavinttop += regsneeded + 1;
861 r->freetmpintregs[r->freetmpinttop] = s->regoff;
864 r->freetmpintregs[r->freetmpinttop + 1] = r->secondregs[s->regoff];
866 r->freetmpinttop += regsneeded + 1;
873 static void allocate_scratch_registers(methodinfo *m)
883 bptr = m->basicblocks;
885 while (bptr != NULL) {
886 if (bptr->flags >= BBREACHED) {
889 /* initialize temp registers */
905 case ICMD_ELSE_ICONST:
906 case ICMD_CHECKASIZE:
907 case ICMD_CHECKEXCEPTION:
915 /* pop 0 push 1 const */
923 /* pop 0 push 1 load */
930 reg_new_temp(m, dst);
945 reg_free_temp(m, src);
946 reg_free_temp(m, src->prev);
947 reg_new_temp(m, dst);
962 reg_free_temp(m, src);
963 reg_free_temp(m, src->prev);
964 reg_free_temp(m, src->prev->prev);
967 /* pop 1 push 0 store */
989 /* pop 1 push 0 branch */
1008 /* pop 1 push 0 table branch */
1010 case ICMD_TABLESWITCH:
1011 case ICMD_LOOKUPSWITCH:
1013 case ICMD_NULLCHECKPOP:
1014 case ICMD_MONITORENTER:
1015 case ICMD_MONITOREXIT:
1016 reg_free_temp(m, src);
1019 /* pop 2 push 0 branch */
1021 case ICMD_IF_ICMPEQ:
1022 case ICMD_IF_ICMPNE:
1023 case ICMD_IF_ICMPLT:
1024 case ICMD_IF_ICMPGE:
1025 case ICMD_IF_ICMPGT:
1026 case ICMD_IF_ICMPLE:
1028 case ICMD_IF_LCMPEQ:
1029 case ICMD_IF_LCMPNE:
1030 case ICMD_IF_LCMPLT:
1031 case ICMD_IF_LCMPGE:
1032 case ICMD_IF_LCMPGT:
1033 case ICMD_IF_LCMPLE:
1035 case ICMD_IF_ACMPEQ:
1036 case ICMD_IF_ACMPNE:
1044 case ICMD_IASTORECONST:
1045 case ICMD_LASTORECONST:
1046 case ICMD_AASTORECONST:
1047 case ICMD_BASTORECONST:
1048 case ICMD_CASTORECONST:
1049 case ICMD_SASTORECONST:
1050 reg_free_temp(m, src);
1051 reg_free_temp(m, src->prev);
1054 /* pop 0 push 1 dup */
1057 reg_new_temp(m, dst);
1060 /* pop 0 push 2 dup */
1063 reg_new_temp(m, dst->prev);
1064 reg_new_temp(m, dst);
1067 /* pop 2 push 3 dup */
1070 reg_new_temp(m, dst->prev->prev);
1071 reg_new_temp(m, dst->prev);
1072 reg_new_temp(m, dst);
1073 reg_free_temp(m, src);
1074 reg_free_temp(m, src->prev);
1077 /* pop 3 push 4 dup */
1080 reg_new_temp(m, dst->prev->prev->prev);
1081 reg_new_temp(m, dst->prev->prev);
1082 reg_new_temp(m, dst->prev);
1083 reg_new_temp(m, dst);
1084 reg_free_temp(m, src);
1085 reg_free_temp(m, src->prev);
1086 reg_free_temp(m, src->prev->prev);
1089 /* pop 3 push 5 dup */
1092 reg_new_temp(m, dst->prev->prev->prev->prev);
1093 reg_new_temp(m, dst->prev->prev->prev);
1094 reg_new_temp(m, dst->prev->prev);
1095 reg_new_temp(m, dst->prev);
1096 reg_new_temp(m, dst);
1097 reg_free_temp(m, src);
1098 reg_free_temp(m, src->prev);
1099 reg_free_temp(m, src->prev->prev);
1102 /* pop 4 push 6 dup */
1105 reg_new_temp(m, dst->prev->prev->prev->prev->prev);
1106 reg_new_temp(m, dst->prev->prev->prev->prev);
1107 reg_new_temp(m, dst->prev->prev->prev);
1108 reg_new_temp(m, dst->prev->prev);
1109 reg_new_temp(m, dst->prev);
1110 reg_new_temp(m, dst);
1111 reg_free_temp(m, src);
1112 reg_free_temp(m, src->prev);
1113 reg_free_temp(m, src->prev->prev);
1114 reg_free_temp(m, src->prev->prev->prev);
1117 /* pop 2 push 2 swap */
1120 reg_new_temp(m, dst->prev);
1121 reg_new_temp(m, dst);
1122 reg_free_temp(m, src);
1123 reg_free_temp(m, src->prev);
1172 reg_free_temp(m, src);
1173 reg_free_temp(m, src->prev);
1174 reg_new_temp(m, dst);
1179 case ICMD_IADDCONST:
1180 case ICMD_ISUBCONST:
1181 case ICMD_IMULCONST:
1184 case ICMD_IANDCONST:
1186 case ICMD_IXORCONST:
1187 case ICMD_ISHLCONST:
1188 case ICMD_ISHRCONST:
1189 case ICMD_IUSHRCONST:
1191 case ICMD_LADDCONST:
1192 case ICMD_LSUBCONST:
1193 case ICMD_LMULCONST:
1196 case ICMD_LANDCONST:
1198 case ICMD_LXORCONST:
1199 case ICMD_LSHLCONST:
1200 case ICMD_LSHRCONST:
1201 case ICMD_LUSHRCONST:
1203 case ICMD_IFEQ_ICONST:
1204 case ICMD_IFNE_ICONST:
1205 case ICMD_IFLT_ICONST:
1206 case ICMD_IFGE_ICONST:
1207 case ICMD_IFGT_ICONST:
1208 case ICMD_IFLE_ICONST:
1213 case ICMD_INT2SHORT:
1231 case ICMD_CHECKCAST:
1233 case ICMD_ARRAYLENGTH:
1234 case ICMD_INSTANCEOF:
1237 case ICMD_ANEWARRAY:
1240 reg_free_temp(m, src);
1241 reg_new_temp(m, dst);
1246 case ICMD_GETSTATIC:
1250 reg_new_temp(m, dst);
1253 /* pop many push any */
1255 case ICMD_INVOKEVIRTUAL:
1256 case ICMD_INVOKESPECIAL:
1257 case ICMD_INVOKESTATIC:
1258 case ICMD_INVOKEINTERFACE:
1262 reg_free_temp(m, src);
1265 if (((methodinfo*)iptr->val.a)->returntype != TYPE_VOID)
1266 reg_new_temp(m, dst);
1271 reg_free_temp(m, src);
1274 reg_free_temp(m, src);
1277 reg_free_temp(m, src);
1279 if (iptr->op1 != TYPE_VOID)
1280 reg_new_temp(m, dst);
1283 case ICMD_MULTIANEWARRAY:
1286 reg_free_temp(m, src);
1289 reg_new_temp(m, dst);
1293 printf("ICMD %d at %d\n", iptr->opc, (s4) (iptr - m->instructions));
1294 panic("Missing ICMD code during register allocation");
1297 } /* while instructions */
1300 } /* while blocks */
1305 * These are local overrides for various environment variables in Emacs.
1306 * Please do not remove this and leave it at the end of the file, where
1307 * Emacs will automagically detect them.
1308 * ---------------------------------------------------------------------
1311 * indent-tabs-mode: t