1 /* src/vm/jit/allocator/simplereg.c - 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
35 $Id: simplereg.c 5310 2006-09-05 11:34:49Z edwin $
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "mm/memory.h"
51 #include "vm/method.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/reg.h"
56 #include "vm/jit/allocator/simplereg.h"
59 /* function prototypes for this file ******************************************/
61 static void interface_regalloc(jitdata *jd);
62 static void local_regalloc(jitdata *jd);
63 static void new_allocate_scratch_registers(jitdata *jd);
64 static void allocate_scratch_registers(jitdata *jd);
67 /* regalloc ********************************************************************
69 Does a simple register allocation.
71 *******************************************************************************/
73 bool new_regalloc(jitdata *jd)
77 /* There is a problem with the use of unused float argument
78 registers in leafmethods for stackslots on c7 (2 * Dual Core
79 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
80 benchmark is heaviliy increased. This could be prevented by
81 setting rd->argfltreguse to FLT_ARG_CNT before calling
82 allocate_scratch_registers and setting it back to the original
83 value before calling local_regalloc. */
85 newjd = DNEW(jitdata);
87 newjd->rd = jd->new_rd;
89 interface_regalloc(newjd);
90 new_allocate_scratch_registers(newjd);
91 local_regalloc(newjd);
99 /* interface_regalloc **********************************************************
101 Allocates registers for all interface variables.
103 *******************************************************************************/
105 static void interface_regalloc(jitdata *jd)
112 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
113 /* in case a more vars are packed into this interface slot */
115 int intregsneeded = 0;
117 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
118 /* on HAS_4BYTE_STACKSLOT architectures */
119 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
121 /* get required compiler data */
127 /* rd->memuse was already set in stack.c to allocate stack space
128 for passing arguments to called methods. */
130 #if defined(__I386__)
131 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
132 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
138 if (jd->isleafmethod) {
139 /* Reserve argument register, which will be used for Locals acting */
141 if (rd->argintreguse < m->parseddesc->argintreguse)
142 rd->argintreguse = m->parseddesc->argintreguse;
143 if (rd->argfltreguse < m->parseddesc->argfltreguse)
144 rd->argfltreguse = m->parseddesc->argfltreguse;
145 #ifdef HAS_ADDRESS_REGISTER_FILE
146 if (rd->argadrreguse < m->parseddesc->argadrreguse)
147 rd->argadrreguse = m->parseddesc->argadrreguse;
152 for (s = 0; s < cd->maxstack; s++) {
153 intalloc = -1; fltalloc = -1;
154 saved = (rd->interfaces[s][TYPE_INT].flags |
155 rd->interfaces[s][TYPE_LNG].flags |
156 rd->interfaces[s][TYPE_FLT].flags |
157 rd->interfaces[s][TYPE_DBL].flags |
158 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
160 for (tt = 0; tt <= 4; tt++) {
162 v = &rd->interfaces[s][t];
164 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
165 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
167 #if defined(HAS_4BYTE_STACKSLOT)
168 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
171 #if defined(HAS_ADDRESS_REGISTER_FILE)
172 if (IS_ADR_TYPE(t)) {
173 if (!jd->isleafmethod
174 &&(rd->argadrreguse < ADR_ARG_CNT)) {
175 v->regoff = rd->argadrregs[rd->argadrreguse++];
176 } else if (rd->tmpadrreguse > 0) {
177 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
178 } else if (rd->savadrreguse > 0) {
179 v->regoff = rd->savadrregs[--rd->savadrreguse];
181 v->flags |= INMEMORY;
182 v->regoff = rd->memuse++;
184 } else /* !IS_ADR_TYPE */
185 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
187 if (IS_FLT_DBL_TYPE(t)) {
189 /* Reuse memory slot(s)/register(s) for shared interface slots */
190 v->flags |= rd->interfaces[s][fltalloc].flags
192 v->regoff = rd->interfaces[s][fltalloc].regoff;
193 } else if (rd->argfltreguse < FLT_ARG_CNT) {
194 v->regoff = rd->argfltregs[rd->argfltreguse++];
195 } else if (rd->tmpfltreguse > 0) {
196 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
197 } else if (rd->savfltreguse > 0) {
198 v->regoff = rd->savfltregs[--rd->savfltreguse];
200 v->flags |= INMEMORY;
201 #if defined(ALIGN_DOUBLES_IN_MEMORY)
202 /* Align doubles in Memory */
203 if ( (memneeded) && (rd->memuse & 1))
206 v->regoff = rd->memuse;
207 rd->memuse += memneeded + 1;
210 } else { /* !IS_FLT_DBL_TYPE(t) */
211 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
213 * for i386 put all longs in memory
215 if (IS_2_WORD_TYPE(t)) {
216 v->flags |= INMEMORY;
217 #if defined(ALIGN_LONGS_IN_MEMORY)
218 /* Align longs in Memory */
222 v->regoff = rd->memuse;
223 rd->memuse += memneeded + 1;
225 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
227 /* Reuse memory slot(s)/register(s) for shared interface slots */
229 rd->interfaces[s][intalloc].flags
231 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
232 if (!(v->flags & INMEMORY)
233 && IS_2_WORD_TYPE(intalloc))
234 v->regoff = GET_LOW_REG(
235 rd->interfaces[s][intalloc].regoff);
239 rd->interfaces[s][intalloc].regoff;
241 if (rd->argintreguse + intregsneeded
243 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
246 rd->argintregs[rd->argintreguse],
247 rd->argintregs[rd->argintreguse + 1]);
251 rd->argintregs[rd->argintreguse];
252 rd->argintreguse += intregsneeded + 1;
254 else if (rd->tmpintreguse > intregsneeded) {
255 rd->tmpintreguse -= intregsneeded + 1;
256 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
259 rd->tmpintregs[rd->tmpintreguse],
260 rd->tmpintregs[rd->tmpintreguse + 1]);
264 rd->tmpintregs[rd->tmpintreguse];
266 else if (rd->savintreguse > intregsneeded) {
267 rd->savintreguse -= intregsneeded + 1;
269 rd->savintregs[rd->savintreguse];
270 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
273 rd->savintregs[rd->savintreguse],
274 rd->savintregs[rd->savintreguse + 1]);
278 rd->savintregs[rd->savintreguse];
281 v->flags |= INMEMORY;
282 #if defined(ALIGN_LONGS_IN_MEMORY)
283 /* Align longs in Memory */
284 if ( (memneeded) && (rd->memuse & 1))
287 v->regoff = rd->memuse;
288 rd->memuse += memneeded + 1;
292 } /* if (IS_FLT_DBL_TYPE(t)) */
294 } else { /* (saved) */
295 /* now the same like above, but without a chance to take a temporary register */
296 #ifdef HAS_ADDRESS_REGISTER_FILE
297 if (IS_ADR_TYPE(t)) {
298 if (rd->savadrreguse > 0) {
299 v->regoff = rd->savadrregs[--rd->savadrreguse];
302 v->flags |= INMEMORY;
303 v->regoff = rd->memuse++;
308 if (IS_FLT_DBL_TYPE(t)) {
310 v->flags |= rd->interfaces[s][fltalloc].flags
312 v->regoff = rd->interfaces[s][fltalloc].regoff;
314 if (rd->savfltreguse > 0) {
315 v->regoff = rd->savfltregs[--rd->savfltreguse];
318 v->flags |= INMEMORY;
319 #if defined(ALIGN_DOUBLES_IN_MEMORY)
320 /* Align doubles in Memory */
321 if ( (memneeded) && (rd->memuse & 1))
324 v->regoff = rd->memuse;
325 rd->memuse += memneeded + 1;
329 else { /* IS_INT_LNG */
330 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
332 * for i386 put all longs in memory
334 if (IS_2_WORD_TYPE(t)) {
335 v->flags |= INMEMORY;
336 #if defined(ALIGN_LONGS_IN_MEMORY)
337 /* Align longs in Memory */
341 v->regoff = rd->memuse;
342 rd->memuse += memneeded + 1;
348 rd->interfaces[s][intalloc].flags & INMEMORY;
349 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
350 if (!(v->flags & INMEMORY)
351 && IS_2_WORD_TYPE(intalloc))
354 rd->interfaces[s][intalloc].regoff);
358 rd->interfaces[s][intalloc].regoff;
360 if (rd->savintreguse > intregsneeded) {
361 rd->savintreguse -= intregsneeded + 1;
362 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
364 v->regoff = PACK_REGS(
365 rd->savintregs[rd->savintreguse],
366 rd->savintregs[rd->savintreguse + 1]);
370 rd->savintregs[rd->savintreguse];
372 v->flags |= INMEMORY;
373 #if defined(ALIGN_LONGS_IN_MEMORY)
374 /* Align longs in Memory */
375 if ( (memneeded) && (rd->memuse & 1))
378 v->regoff = rd->memuse;
379 rd->memuse += memneeded + 1;
384 } /* if (IS_FLT_DBL_TYPE(t) else */
385 } /* if (IS_ADR_TYPE(t)) else */
386 } /* if (saved) else */
387 } /* if (type >= 0) */
393 /* local_regalloc **************************************************************
395 Allocates registers for all local variables.
397 *******************************************************************************/
399 static void local_regalloc(jitdata *jd)
406 int intalloc, fltalloc;
408 int intregsneeded = 0;
410 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
411 int fargcnt, iargcnt;
412 #ifdef HAS_ADDRESS_REGISTER_FILE
416 /* get required compiler data */
422 if (jd->isleafmethod) {
423 methoddesc *md = m->parseddesc;
425 iargcnt = rd->argintreguse;
426 fargcnt = rd->argfltreguse;
427 #ifdef HAS_ADDRESS_REGISTER_FILE
428 aargcnt = rd->argadrreguse;
430 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
431 intalloc = -1; fltalloc = -1;
432 for (tt = 0; tt <= 4; tt++) {
434 v = &rd->locals[s][t];
439 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
440 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
442 #if defined(HAS_4BYTE_STACKSLOT)
443 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
449 * #ifdef HAS_ADDRESS_REGISTER_FILE
456 * } else { / int & lng
460 * must not to be changed!
463 #ifdef HAS_ADDRESS_REGISTER_FILE
464 if (IS_ADR_TYPE(t)) {
465 if ((p < md->paramcount) && !md->params[p].inmemory) {
467 v->regoff = rd->argadrregs[md->params[p].regoff];
469 else if (rd->tmpadrreguse > 0) {
471 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
473 /* use unused argument registers as local registers */
474 else if ((p >= md->paramcount) &&
475 (aargcnt < ADR_ARG_CNT)) {
477 v->regoff = rd->argadrregs[aargcnt++];
479 else if (rd->savadrreguse > 0) {
481 v->regoff = rd->savadrregs[--rd->savadrreguse];
484 v->flags |= INMEMORY;
485 v->regoff = rd->memuse++;
489 if (IS_FLT_DBL_TYPE(t)) {
491 v->flags = rd->locals[s][fltalloc].flags;
492 v->regoff = rd->locals[s][fltalloc].regoff;
494 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
495 /* We can only use float arguments as local variables,
496 * if we do not pass them in integer registers. */
497 else if ((p < md->paramcount) &&
498 !md->params[p].inmemory) {
500 v->regoff = rd->argfltregs[md->params[p].regoff];
503 else if (rd->tmpfltreguse > 0) {
505 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
507 /* use unused argument registers as local registers */
508 else if ((p >= md->paramcount) &&
509 (fargcnt < FLT_ARG_CNT)) {
511 v->regoff = rd->argfltregs[fargcnt];
514 else if (rd->savfltreguse > 0) {
516 v->regoff = rd->savfltregs[--rd->savfltreguse];
520 #if defined(ALIGN_DOUBLES_IN_MEMORY)
521 /* Align doubles in Memory */
522 if ( (memneeded) && (rd->memuse & 1))
525 v->regoff = rd->memuse;
526 rd->memuse += memneeded + 1;
531 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
533 * for i386 put all longs in memory
535 if (IS_2_WORD_TYPE(t)) {
537 #if defined(ALIGN_LONGS_IN_MEMORY)
538 /* Align longs in Memory */
542 v->regoff = rd->memuse;
543 rd->memuse += memneeded + 1;
548 v->flags = rd->locals[s][intalloc].flags;
549 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
550 if (!(v->flags & INMEMORY)
551 && IS_2_WORD_TYPE(intalloc))
552 v->regoff = GET_LOW_REG(
553 rd->locals[s][intalloc].regoff);
556 v->regoff = rd->locals[s][intalloc].regoff;
558 else if ((p < md->paramcount) &&
559 !md->params[p].inmemory) {
561 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
562 if (IS_2_WORD_TYPE(t))
563 v->regoff = PACK_REGS(
564 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
565 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
569 rd->argintregs[md->params[p].regoff];
571 else if (rd->tmpintreguse > intregsneeded) {
572 rd->tmpintreguse -= intregsneeded + 1;
574 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
576 v->regoff = PACK_REGS(
577 rd->tmpintregs[rd->tmpintreguse],
578 rd->tmpintregs[rd->tmpintreguse + 1]);
582 rd->tmpintregs[rd->tmpintreguse];
585 * use unused argument registers as local registers
587 else if ((p >= m->parseddesc->paramcount) &&
588 (iargcnt + intregsneeded < INT_ARG_CNT)) {
590 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
593 rd->argintregs[iargcnt],
594 rd->argintregs[iargcnt + 1]);
597 v->regoff = rd->argintregs[iargcnt];
598 iargcnt += intregsneeded + 1;
600 else if (rd->savintreguse > intregsneeded) {
601 rd->savintreguse -= intregsneeded + 1;
603 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
605 v->regoff = PACK_REGS(
606 rd->savintregs[rd->savintreguse],
607 rd->savintregs[rd->savintreguse + 1]);
610 v->regoff =rd->savintregs[rd->savintreguse];
614 #if defined(ALIGN_LONGS_IN_MEMORY)
615 /* Align longs in Memory */
616 if ( (memneeded) && (rd->memuse & 1))
619 v->regoff = rd->memuse;
620 rd->memuse += memneeded + 1;
625 #ifdef HAS_ADDRESS_REGISTER_FILE
628 } /* for (tt=0;...) */
630 /* If the current parameter is a 2-word type, the next local slot */
633 if (p < md->paramcount)
634 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
640 for (s = 0; s < cd->maxlocals; s++) {
641 intalloc = -1; fltalloc = -1;
642 for (tt=0; tt<=4; tt++) {
644 v = &rd->locals[s][t];
647 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
648 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
650 #if defined(HAS_4BYTE_STACKSLOT)
651 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
653 #ifdef HAS_ADDRESS_REGISTER_FILE
654 if ( IS_ADR_TYPE(t) ) {
655 if (rd->savadrreguse > 0) {
657 v->regoff = rd->savadrregs[--rd->savadrreguse];
661 v->regoff = rd->memuse++;
665 if (IS_FLT_DBL_TYPE(t)) {
667 v->flags = rd->locals[s][fltalloc].flags;
668 v->regoff = rd->locals[s][fltalloc].regoff;
670 else if (rd->savfltreguse > 0) {
672 v->regoff = rd->savfltregs[--rd->savfltreguse];
676 #if defined(ALIGN_DOUBLES_IN_MEMORY)
677 /* Align doubles in Memory */
678 if ( (memneeded) && (rd->memuse & 1))
681 v->regoff = rd->memuse;
682 rd->memuse += memneeded + 1;
687 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
689 * for i386 put all longs in memory
691 if (IS_2_WORD_TYPE(t)) {
693 #if defined(ALIGN_LONGS_IN_MEMORY)
694 /* Align longs in Memory */
698 v->regoff = rd->memuse;
699 rd->memuse += memneeded + 1;
703 v->flags = rd->locals[s][intalloc].flags;
704 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
705 if (!(v->flags & INMEMORY)
706 && IS_2_WORD_TYPE(intalloc))
707 v->regoff = GET_LOW_REG(
708 rd->locals[s][intalloc].regoff);
711 v->regoff = rd->locals[s][intalloc].regoff;
713 else if (rd->savintreguse > intregsneeded) {
714 rd->savintreguse -= intregsneeded+1;
716 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
718 v->regoff = PACK_REGS(
719 rd->savintregs[rd->savintreguse],
720 rd->savintregs[rd->savintreguse + 1]);
723 v->regoff =rd->savintregs[rd->savintreguse];
727 #if defined(ALIGN_LONGS_IN_MEMORY)
728 /* Align longs in Memory */
729 if ( (memneeded) && (rd->memuse & 1))
732 v->regoff = rd->memuse;
733 rd->memuse += memneeded + 1;
735 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
740 #ifdef HAS_ADDRESS_REGISTER_FILE
749 static void reg_init_temp(methodinfo *m, registerdata *rd)
752 #if defined(HAS_4BYTE_STACKSLOT)
753 rd->freememtop_2 = 0;
756 rd->freetmpinttop = 0;
757 rd->freesavinttop = 0;
758 rd->freetmpflttop = 0;
759 rd->freesavflttop = 0;
760 #ifdef HAS_ADDRESS_REGISTER_FILE
761 rd->freetmpadrtop = 0;
762 rd->freesavadrtop = 0;
765 rd->freearginttop = 0;
766 rd->freeargflttop = 0;
767 #ifdef HAS_ADDRESS_REGISTER_FILE
768 rd->freeargadrtop = 0;
773 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
775 static void reg_new_temp_func(registerdata *rd, stackptr s)
781 /* Try to allocate a saved register if there is no temporary one */
782 /* available. This is what happens during the second run. */
783 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
785 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
786 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
790 #if defined(HAS_4BYTE_STACKSLOT)
791 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
796 for(; tryagain; --tryagain) {
798 if (!(s->flags & SAVEDVAR))
799 s->flags |= SAVEDTMP;
800 #ifdef HAS_ADDRESS_REGISTER_FILE
801 if (IS_ADR_TYPE(s->type)) {
802 if (rd->freesavadrtop > 0) {
803 s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
805 } else if (rd->savadrreguse > 0) {
806 s->regoff = rd->savadrregs[--rd->savadrreguse];
812 if (IS_FLT_DBL_TYPE(s->type)) {
813 if (rd->freesavflttop > 0) {
814 s->regoff = rd->freesavfltregs[--rd->freesavflttop];
816 } else if (rd->savfltreguse > 0) {
817 s->regoff = rd->savfltregs[--rd->savfltreguse];
821 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
823 * for i386 put all longs in memory
825 if (!IS_2_WORD_TYPE(s->type))
828 if (rd->freesavinttop > intregsneeded) {
829 rd->freesavinttop -= intregsneeded + 1;
830 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
832 s->regoff = PACK_REGS(
833 rd->freesavintregs[rd->freesavinttop],
834 rd->freesavintregs[rd->freesavinttop + 1]);
838 rd->freesavintregs[rd->freesavinttop];
840 } else if (rd->savintreguse > intregsneeded) {
841 rd->savintreguse -= intregsneeded + 1;
842 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
844 s->regoff = PACK_REGS(
845 rd->savintregs[rd->savintreguse],
846 rd->savintregs[rd->savintreguse + 1]);
849 s->regoff = rd->savintregs[rd->savintreguse];
855 } else { /* tryagain == 2 */
856 #ifdef HAS_ADDRESS_REGISTER_FILE
857 if (IS_ADR_TYPE(s->type)) {
858 if (rd->freetmpadrtop > 0) {
859 s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
861 } else if (rd->tmpadrreguse > 0) {
862 s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
868 if (IS_FLT_DBL_TYPE(s->type)) {
869 if (rd->freeargflttop > 0) {
870 s->regoff = rd->freeargfltregs[--rd->freeargflttop];
873 } else if (rd->argfltreguse < FLT_ARG_CNT) {
874 s->regoff = rd->argfltregs[rd->argfltreguse++];
877 } else if (rd->freetmpflttop > 0) {
878 s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
880 } else if (rd->tmpfltreguse > 0) {
881 s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
886 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
888 * for i386 put all longs in memory
890 if (!IS_2_WORD_TYPE(s->type))
893 if (rd->freearginttop > intregsneeded) {
894 rd->freearginttop -= intregsneeded + 1;
896 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
898 s->regoff = PACK_REGS(
899 rd->freeargintregs[rd->freearginttop],
900 rd->freeargintregs[rd->freearginttop + 1]);
904 rd->freeargintregs[rd->freearginttop];
906 } else if (rd->argintreguse
907 < INT_ARG_CNT - intregsneeded) {
908 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
910 s->regoff = PACK_REGS(
911 rd->argintregs[rd->argintreguse],
912 rd->argintregs[rd->argintreguse + 1]);
915 s->regoff = rd->argintregs[rd->argintreguse];
917 rd->argintreguse += intregsneeded + 1;
919 } else if (rd->freetmpinttop > intregsneeded) {
920 rd->freetmpinttop -= intregsneeded + 1;
921 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
923 s->regoff = PACK_REGS(
924 rd->freetmpintregs[rd->freetmpinttop],
925 rd->freetmpintregs[rd->freetmpinttop + 1]);
928 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
930 } else if (rd->tmpintreguse > intregsneeded) {
931 rd->tmpintreguse -= intregsneeded + 1;
932 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
934 s->regoff = PACK_REGS(
935 rd->tmpintregs[rd->tmpintreguse],
936 rd->tmpintregs[rd->tmpintreguse + 1]);
939 s->regoff = rd->tmpintregs[rd->tmpintreguse];
942 } /* if (!IS_2_WORD_TYPE(s->type)) */
943 } /* if (IS_FLT_DBL_TYPE(s->type)) */
944 } /* if (IS_ADR_TYPE(s->type)) */
945 } /* if (tryagain == 1) else */
946 } /* for(; tryagain; --tryagain) */
948 #if defined(HAS_4BYTE_STACKSLOT)
949 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
951 s->regoff = rd->freemem_2[rd->freememtop_2];
953 #endif /*defined(HAS_4BYTE_STACKSLOT) */
954 if ((memneeded == 0) && (rd->freememtop > 0)) {
956 s->regoff = rd->freemem[rd->freememtop];
958 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
959 /* align 2 Word Types */
960 if ((memneeded) && ((rd->memuse & 1) == 1)) {
961 /* Put patched memory slot on freemem */
962 rd->freemem[rd->freememtop++] = rd->memuse;
965 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
966 s->regoff = rd->memuse;
967 rd->memuse += memneeded + 1;
969 s->flags |= INMEMORY;
973 #define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
975 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
976 /* alive using this reg/memory location */
978 static void reg_free_temp_func(registerdata *rd, stackptr s)
983 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
984 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
989 #if defined(HAS_4BYTE_STACKSLOT)
990 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
995 if (s->flags & INMEMORY) {
996 #if defined(HAS_4BYTE_STACKSLOT)
998 rd->freemem_2[rd->freememtop_2] = s->regoff;
1003 rd->freemem[rd->freememtop] = s->regoff;
1007 #ifdef HAS_ADDRESS_REGISTER_FILE
1008 } else if (IS_ADR_TYPE(s->type)) {
1009 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1010 /* s->flags &= ~SAVEDTMP; */
1011 rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
1013 rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
1015 } else if (IS_FLT_DBL_TYPE(s->type)) {
1016 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1017 /* s->flags &= ~SAVEDTMP; */
1018 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
1019 } else if (s->flags & TMPARG) {
1020 /* s->flags &= ~TMPARG; */
1021 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1023 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1024 } else { /* IS_INT_LNG_TYPE */
1025 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1026 /* s->flags &= ~SAVEDTMP; */
1027 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1028 if (intregsneeded) {
1029 rd->freesavintregs[rd->freesavinttop] =
1030 GET_LOW_REG(s->regoff);
1031 rd->freesavintregs[rd->freesavinttop + 1] =
1032 GET_HIGH_REG(s->regoff);
1035 rd->freesavintregs[rd->freesavinttop] = s->regoff;
1036 rd->freesavinttop += intregsneeded + 1;
1038 } else if (s->flags & TMPARG) {
1039 /* s->flags &= ~TMPARG; */
1040 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1041 if (intregsneeded) {
1042 rd->freeargintregs[rd->freearginttop] =
1043 GET_LOW_REG(s->regoff);
1044 rd->freeargintregs[rd->freearginttop + 1] =
1045 GET_HIGH_REG(s->regoff);
1048 rd->freeargintregs[rd->freearginttop] = s->regoff;
1049 rd->freearginttop += intregsneeded + 1;
1051 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1052 if (intregsneeded) {
1053 rd->freetmpintregs[rd->freetmpinttop] =
1054 GET_LOW_REG(s->regoff);
1055 rd->freetmpintregs[rd->freetmpinttop + 1] =
1056 GET_HIGH_REG(s->regoff);
1059 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1060 rd->freetmpinttop += intregsneeded + 1;
1065 static bool reg_alloc_dup(stackptr src, stackptr dst) {
1066 /* only copy TEMPVARS, do not mess with STACKVAR, */
1067 /* LOCALVAR, or ARGVAR */
1068 if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) {
1069 /* can not allocate a REG_TMP to a REG_SAV Slot */
1070 if (src->flags & INMEMORY) {
1071 dst->regoff = src->regoff;
1072 dst->flags |= INMEMORY;
1074 } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) {
1075 dst->regoff = src->regoff;
1076 dst->flags |= src->flags & SAVEDTMP;
1077 dst->flags |= src->flags & TMPARG;
1080 } else if ((dst->flags & SAVEDVAR) == 0) {
1081 /* can only use a REG_SAV as REG_TMP! */
1082 dst->regoff = src->regoff;
1083 dst->flags |= src->flags & TMPARG;
1084 dst->flags |= SAVEDTMP;
1089 /* no copy possible - allocate a new reg/memory location*/
1093 /* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
1094 static void new_reg_mark_copy(registerdata *rd, stackptr *dupslots,
1095 int nin, int nout, int nthrough)
1099 stackptr dst_stackslots[6];
1100 int s_bottom, d_bottom, i, j, slots;
1105 assert(nin <= 4 && (nout + nthrough) <= 6);
1107 /* remember all different Registers/Memory Location of used TEMPVAR */
1108 /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY */
1109 /* flag of the last (deepest) occurence */
1111 argp = dupslots + slots;
1112 for (s_bottom = 4; slots--; ) {
1114 if (sp->varkind == TEMPVAR) {
1116 for (i = 3; i >= s_bottom; i--) {
1117 if ((src_regoff[i] == sp->regoff) &&
1118 ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) )
1120 src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
1126 src_regoff[s_bottom] = sp->regoff;
1127 src_flags[s_bottom] = sp->flags;
1132 /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they */
1133 /* have to be from the "lowest" upwards, and the stackelements list is */
1134 /* linked from only top downwards */
1136 slots = nthrough + nout;
1137 argp = dupslots + nin + nout;
1138 for (d_bottom = 6; slots--; ) {
1140 if (sp->varkind == TEMPVAR) {
1142 dst_stackslots[d_bottom] = sp;
1146 /* Mark all reused reg/mem in dst stacklots with STCOPY, if the */
1147 /* corresponding src stackslot was marked STCOPY*/
1148 /* if the correspondig STCOPY from the src stackslot was not set, do not */
1149 /* mark the lowest occurence at dst stackslots */
1150 /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst */
1151 /* stacklots, so they are not freed afterwards */
1152 for (i = d_bottom; i < 6; i++) {
1153 for (j = s_bottom; j < 4; j++) {
1154 if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
1155 ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) )
1157 if (src_flags[j] & STCOPY) {
1158 dst_stackslots[i]->flags |= STCOPY;
1161 src_flags[j] |= STCOPY;
1162 dst_stackslots[i]->flags &= ~STCOPY;
1164 /* do not free reg/mem of src Stackslot */
1165 src_flags[j] |= STKEEP;
1170 /* free all reg/mem of src stack, which where not marked with STKEEP */
1171 for (j=s_bottom; j < 4; j++) {
1172 if ((src_flags[j] & STKEEP)==0) {
1173 /* free, if STCOPY of src stackslot is not set */
1174 /* STCOPY is already checked in reg_free_temp macro! */
1176 argp = dupslots + slots;
1179 if ((src_regoff[j] == sp->regoff) &&
1180 ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) )
1182 reg_free_temp(rd, sp);
1190 /* allocate_scratch_registers **************************************************
1192 Allocate temporary (non-interface, non-local) registers.
1194 *******************************************************************************/
1196 static void new_allocate_scratch_registers(jitdata *jd)
1202 new_instruction *iptr;
1204 builtintable_entry *bte;
1208 /* get required compiler data */
1213 /* initialize temp registers */
1214 reg_init_temp(m, rd);
1216 bptr = jd->new_basicblocks;
1218 while (bptr != NULL) {
1219 if (bptr->flags >= BBREACHED) {
1220 iptr = /* XXX */ (new_instruction *) bptr->iinstr;
1223 while (--len >= 0) {
1224 switch (iptr->opc) {
1229 case ICMD_CHECKNULL:
1235 case ICMD_PUTSTATICCONST:
1236 case ICMD_INLINE_START:
1237 case ICMD_INLINE_END:
1238 case ICMD_INLINE_GOTO:
1241 /* pop 0 push 1 const */
1249 /* pop 0 push 1 load */
1256 reg_new_temp(rd, iptr->dst.var);
1270 reg_free_temp(rd, iptr->sx.s23.s2.var);
1271 reg_free_temp(rd, iptr->s1.var);
1272 reg_new_temp(rd, iptr->dst.var);
1286 reg_free_temp(rd, iptr->sx.s23.s3.var);
1287 reg_free_temp(rd, iptr->sx.s23.s2.var);
1288 reg_free_temp(rd, iptr->s1.var);
1291 /* pop 1 push 0 store */
1311 case ICMD_PUTSTATIC:
1312 case ICMD_PUTFIELDCONST:
1314 /* pop 1 push 0 branch */
1317 case ICMD_IFNONNULL:
1333 /* pop 1 push 0 table branch */
1335 case ICMD_TABLESWITCH:
1336 case ICMD_LOOKUPSWITCH:
1338 case ICMD_MONITORENTER:
1339 case ICMD_MONITOREXIT:
1340 reg_free_temp(rd, iptr->s1.var);
1343 /* pop 2 push 0 branch */
1345 case ICMD_IF_ICMPEQ:
1346 case ICMD_IF_ICMPNE:
1347 case ICMD_IF_ICMPLT:
1348 case ICMD_IF_ICMPGE:
1349 case ICMD_IF_ICMPGT:
1350 case ICMD_IF_ICMPLE:
1352 case ICMD_IF_LCMPEQ:
1353 case ICMD_IF_LCMPNE:
1354 case ICMD_IF_LCMPLT:
1355 case ICMD_IF_LCMPGE:
1356 case ICMD_IF_LCMPGT:
1357 case ICMD_IF_LCMPLE:
1359 case ICMD_IF_FCMPEQ:
1360 case ICMD_IF_FCMPNE:
1362 case ICMD_IF_FCMPL_LT:
1363 case ICMD_IF_FCMPL_GE:
1364 case ICMD_IF_FCMPL_GT:
1365 case ICMD_IF_FCMPL_LE:
1367 case ICMD_IF_FCMPG_LT:
1368 case ICMD_IF_FCMPG_GE:
1369 case ICMD_IF_FCMPG_GT:
1370 case ICMD_IF_FCMPG_LE:
1372 case ICMD_IF_DCMPEQ:
1373 case ICMD_IF_DCMPNE:
1375 case ICMD_IF_DCMPL_LT:
1376 case ICMD_IF_DCMPL_GE:
1377 case ICMD_IF_DCMPL_GT:
1378 case ICMD_IF_DCMPL_LE:
1380 case ICMD_IF_DCMPG_LT:
1381 case ICMD_IF_DCMPG_GE:
1382 case ICMD_IF_DCMPG_GT:
1383 case ICMD_IF_DCMPG_LE:
1385 case ICMD_IF_ACMPEQ:
1386 case ICMD_IF_ACMPNE:
1394 case ICMD_IASTORECONST:
1395 case ICMD_LASTORECONST:
1396 case ICMD_AASTORECONST:
1397 case ICMD_BASTORECONST:
1398 case ICMD_CASTORECONST:
1399 case ICMD_SASTORECONST:
1400 reg_free_temp(rd, iptr->sx.s23.s2.var);
1401 reg_free_temp(rd, iptr->s1.var);
1404 /* pop 0 push 1 dup */
1407 /* src === dst->prev (identical Stackslot Element) */
1408 /* src --> dst (copied value, take same reg/mem) */
1410 if (!reg_alloc_dup(iptr->s1.var, iptr->dst.var)) {
1411 reg_new_temp(rd, iptr->dst.var);
1413 iptr->dst.var->flags |= STCOPY;
1417 /* pop 0 push 2 dup */
1420 /* src->prev === dst->prev->prev->prev (identical Stackslot Element) */
1421 /* src === dst->prev->prev (identical Stackslot Element) */
1422 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1423 /* src --> dst (copied value, take same reg/mem) */
1425 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0]))
1426 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1427 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1]))
1428 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1429 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2);
1432 /* pop 2 push 3 dup */
1435 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1436 /* src --> dst (copied value, take same reg/mem) */
1437 /* src --> dst->prev->prev (copied value, take same reg/mem) */
1439 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
1440 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1441 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2]))
1442 reg_new_temp(rd, iptr->dst.dupslots[2+2]);
1443 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
1444 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1445 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0);
1448 /* pop 3 push 4 dup */
1451 /* src->prev->prev --> dst->prev->prev */
1452 /* src->prev --> dst->prev */
1454 /* src --> dst->prev->prev->prev */
1456 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0]))
1457 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1458 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3]))
1459 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1460 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2]))
1461 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1462 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1]))
1463 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1464 new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0);
1467 /* pop 3 push 5 dup */
1470 /* src->prev->prev --> dst->prev->prev */
1471 /* src->prev --> dst->prev */
1473 /* src->prev --> dst->prev->prev->prev->prev */
1474 /* src --> dst->prev->prev->prev */
1476 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1]))
1477 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1478 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4]))
1479 reg_new_temp(rd, iptr->dst.dupslots[3+4]);
1480 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0]))
1481 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1482 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3]))
1483 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1484 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2]))
1485 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1486 new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0);
1489 /* pop 4 push 6 dup */
1492 /* src->prev->prev->prev --> dst->prev->prev->prev */
1493 /* src->prev->prev --> dst->prev->prev */
1494 /* src->prev --> dst->prev */
1496 /* src->prev --> dst->prev->prev->prev->prev->prev */
1497 /* src --> dst->prev->prev->prev->prev */
1499 if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1]))
1500 reg_new_temp(rd, iptr->dst.dupslots[4+1]);
1501 if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5]))
1502 reg_new_temp(rd, iptr->dst.dupslots[4+5]);
1503 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0]))
1504 reg_new_temp(rd, iptr->dst.dupslots[4+0]);
1505 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4]))
1506 reg_new_temp(rd, iptr->dst.dupslots[4+4]);
1507 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3]))
1508 reg_new_temp(rd, iptr->dst.dupslots[4+3]);
1509 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2]))
1510 reg_new_temp(rd, iptr->dst.dupslots[4+2]);
1511 new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0);
1514 /* pop 2 push 2 swap */
1517 /* src --> dst->prev (copy) */
1518 /* src->prev --> dst (copy) */
1520 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
1521 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1522 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
1523 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1524 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0);
1573 reg_free_temp(rd, iptr->sx.s23.s2.var);
1574 reg_free_temp(rd, iptr->s1.var);
1575 reg_new_temp(rd, iptr->dst.var);
1580 case ICMD_IADDCONST:
1581 case ICMD_ISUBCONST:
1582 case ICMD_IMULCONST:
1586 case ICMD_IANDCONST:
1588 case ICMD_IXORCONST:
1589 case ICMD_ISHLCONST:
1590 case ICMD_ISHRCONST:
1591 case ICMD_IUSHRCONST:
1593 case ICMD_LADDCONST:
1594 case ICMD_LSUBCONST:
1595 case ICMD_LMULCONST:
1599 case ICMD_LANDCONST:
1601 case ICMD_LXORCONST:
1602 case ICMD_LSHLCONST:
1603 case ICMD_LSHRCONST:
1604 case ICMD_LUSHRCONST:
1609 case ICMD_INT2SHORT:
1627 case ICMD_CHECKCAST:
1629 case ICMD_ARRAYLENGTH:
1630 case ICMD_INSTANCEOF:
1633 case ICMD_ANEWARRAY:
1636 reg_free_temp(rd, iptr->s1.var);
1637 reg_new_temp(rd, iptr->dst.var);
1642 case ICMD_GETSTATIC:
1645 reg_new_temp(rd, iptr->dst.var);
1648 /* pop many push any */
1650 case ICMD_INVOKESTATIC:
1651 case ICMD_INVOKESPECIAL:
1652 case ICMD_INVOKEVIRTUAL:
1653 case ICMD_INVOKEINTERFACE:
1654 INSTRUCTION_GET_METHODDESC(iptr,md);
1656 argp = iptr->sx.s23.s2.args;
1658 reg_free_temp(rd, *argp);
1661 if (md->returntype.type != TYPE_VOID)
1662 reg_new_temp(rd, iptr->dst.var);
1666 bte = iptr->sx.s23.s3.bte;
1669 argp = iptr->sx.s23.s2.args;
1671 reg_free_temp(rd, *argp);
1674 if (md->returntype.type != TYPE_VOID)
1675 reg_new_temp(rd, iptr->dst.var);
1678 case ICMD_MULTIANEWARRAY:
1679 i = iptr->s1.argcount;
1680 argp = iptr->sx.s23.s2.args;
1682 reg_free_temp(rd, *argp);
1685 reg_new_temp(rd, iptr->dst.var);
1690 new_internalerror("Unknown ICMD %d during register allocation",
1695 } /* while instructions */
1698 } /* while blocks */
1702 #if defined(ENABLE_STATISTICS)
1703 void reg_make_statistics(jitdata *jd)
1710 stackptr src, src_old;
1714 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1717 /* get required compiler data */
1727 /* count how many local variables are held in memory or register */
1728 for(i=0; i < cd->maxlocals; i++)
1729 for (type=0; type <=4; type++)
1730 if (rd->locals[i][type].type != -1) { /* valid local */
1731 if (rd->locals[i][type].flags & INMEMORY) {
1732 count_locals_spilled++;
1736 count_locals_register++;
1738 /* count how many stack slots are held in memory or register */
1740 bptr = m->basicblocks;
1741 while (bptr != NULL) {
1742 if (bptr->flags >= BBREACHED) {
1744 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1747 /* check for memory moves from interface to BB instack */
1748 dst = bptr->instack;
1749 len = bptr->indepth;
1751 if (len > size_interface) size_interface = len;
1753 while (dst != NULL) {
1755 if (dst->varkind != STACKVAR) {
1756 if ( (dst->flags & INMEMORY) ||
1757 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1758 ( (dst->flags & INMEMORY) &&
1759 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1760 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1762 /* one in memory or both inmemory at different offsets */
1763 count_mem_move_bb++;
1771 /* check for memory moves from BB outstack to interface */
1772 dst = bptr->outstack;
1773 len = bptr->outdepth;
1774 if (len > size_interface) size_interface = len;
1778 if (dst->varkind != STACKVAR) {
1779 if ( (dst->flags & INMEMORY) || \
1780 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1781 ( (dst->flags & INMEMORY) && \
1782 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1783 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1785 /* one in memory or both inmemory at different offsets */
1786 count_mem_move_bb++;
1793 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1798 dst = bptr->instack;
1799 iptr = bptr->iinstr;
1803 while (--len >= 0) {
1807 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1808 switch (src->varkind) {
1811 if (!(src->flags & INMEMORY))
1812 count_ss_register++;
1818 /* case LOCALVAR: */
1819 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1820 /* count_ss_register++; */
1822 /* count_ss_spilled++; */
1825 if (!(src->flags & INMEMORY))
1826 count_argument_mem_ss++;
1828 count_argument_reg_ss++;
1832 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1833 /* if (src->varnum < FLT_ARG_CNT) { */
1834 /* count_ss_register++; */
1838 /* #if defined(__POWERPC__) */
1839 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1841 /* if (src->varnum < INT_ARG_CNT) { */
1843 /* count_ss_register++; */
1847 /* count_ss_spilled++; */
1854 } /* while instructions */
1857 } /* while blocks */
1858 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1859 if (in_register) count_method_in_register++;
1861 printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1864 #endif /* defined(ENABLE_STATISTICS) */
1868 * These are local overrides for various environment variables in Emacs.
1869 * Please do not remove this and leave it at the end of the file, where
1870 * Emacs will automagically detect them.
1871 * ---------------------------------------------------------------------
1874 * indent-tabs-mode: t
1878 * vim:noexpandtab:sw=4:ts=4: