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 5343 2006-09-05 21:20:33Z twisti $
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)
75 /* There is a problem with the use of unused float argument
76 registers in leafmethods for stackslots on c7 (2 * Dual Core
77 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
78 benchmark is heaviliy increased. This could be prevented by
79 setting rd->argfltreguse to FLT_ARG_CNT before calling
80 allocate_scratch_registers and setting it back to the original
81 value before calling local_regalloc. */
83 interface_regalloc(jd);
84 new_allocate_scratch_registers(jd);
93 /* interface_regalloc **********************************************************
95 Allocates registers for all interface variables.
97 *******************************************************************************/
99 static void interface_regalloc(jitdata *jd)
106 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
107 /* in case a more vars are packed into this interface slot */
109 int intregsneeded = 0;
111 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
112 /* on HAS_4BYTE_STACKSLOT architectures */
113 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
115 /* get required compiler data */
121 /* rd->memuse was already set in stack.c to allocate stack space
122 for passing arguments to called methods. */
124 #if defined(__I386__)
125 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
126 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
132 if (jd->isleafmethod) {
133 /* Reserve argument register, which will be used for Locals acting */
135 if (rd->argintreguse < m->parseddesc->argintreguse)
136 rd->argintreguse = m->parseddesc->argintreguse;
137 if (rd->argfltreguse < m->parseddesc->argfltreguse)
138 rd->argfltreguse = m->parseddesc->argfltreguse;
139 #ifdef HAS_ADDRESS_REGISTER_FILE
140 if (rd->argadrreguse < m->parseddesc->argadrreguse)
141 rd->argadrreguse = m->parseddesc->argadrreguse;
146 for (s = 0; s < cd->maxstack; s++) {
147 intalloc = -1; fltalloc = -1;
148 saved = (rd->interfaces[s][TYPE_INT].flags |
149 rd->interfaces[s][TYPE_LNG].flags |
150 rd->interfaces[s][TYPE_FLT].flags |
151 rd->interfaces[s][TYPE_DBL].flags |
152 rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
154 for (tt = 0; tt <= 4; tt++) {
156 v = &rd->interfaces[s][t];
158 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
159 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
161 #if defined(HAS_4BYTE_STACKSLOT)
162 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
165 #if defined(HAS_ADDRESS_REGISTER_FILE)
166 if (IS_ADR_TYPE(t)) {
167 if (!jd->isleafmethod
168 &&(rd->argadrreguse < ADR_ARG_CNT)) {
169 v->regoff = rd->argadrregs[rd->argadrreguse++];
170 } else if (rd->tmpadrreguse > 0) {
171 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
172 } else if (rd->savadrreguse > 0) {
173 v->regoff = rd->savadrregs[--rd->savadrreguse];
175 v->flags |= INMEMORY;
176 v->regoff = rd->memuse++;
178 } else /* !IS_ADR_TYPE */
179 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
181 if (IS_FLT_DBL_TYPE(t)) {
183 /* Reuse memory slot(s)/register(s) for shared interface slots */
184 v->flags |= rd->interfaces[s][fltalloc].flags
186 v->regoff = rd->interfaces[s][fltalloc].regoff;
187 } else if (rd->argfltreguse < FLT_ARG_CNT) {
188 v->regoff = rd->argfltregs[rd->argfltreguse++];
189 } else if (rd->tmpfltreguse > 0) {
190 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
191 } else if (rd->savfltreguse > 0) {
192 v->regoff = rd->savfltregs[--rd->savfltreguse];
194 v->flags |= INMEMORY;
195 #if defined(ALIGN_DOUBLES_IN_MEMORY)
196 /* Align doubles in Memory */
197 if ( (memneeded) && (rd->memuse & 1))
200 v->regoff = rd->memuse;
201 rd->memuse += memneeded + 1;
204 } else { /* !IS_FLT_DBL_TYPE(t) */
205 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
207 * for i386 put all longs in memory
209 if (IS_2_WORD_TYPE(t)) {
210 v->flags |= INMEMORY;
211 #if defined(ALIGN_LONGS_IN_MEMORY)
212 /* Align longs in Memory */
216 v->regoff = rd->memuse;
217 rd->memuse += memneeded + 1;
219 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
221 /* Reuse memory slot(s)/register(s) for shared interface slots */
223 rd->interfaces[s][intalloc].flags
225 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
226 if (!(v->flags & INMEMORY)
227 && IS_2_WORD_TYPE(intalloc))
228 v->regoff = GET_LOW_REG(
229 rd->interfaces[s][intalloc].regoff);
233 rd->interfaces[s][intalloc].regoff;
235 if (rd->argintreguse + intregsneeded
237 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
240 rd->argintregs[rd->argintreguse],
241 rd->argintregs[rd->argintreguse + 1]);
245 rd->argintregs[rd->argintreguse];
246 rd->argintreguse += intregsneeded + 1;
248 else if (rd->tmpintreguse > intregsneeded) {
249 rd->tmpintreguse -= intregsneeded + 1;
250 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
253 rd->tmpintregs[rd->tmpintreguse],
254 rd->tmpintregs[rd->tmpintreguse + 1]);
258 rd->tmpintregs[rd->tmpintreguse];
260 else if (rd->savintreguse > intregsneeded) {
261 rd->savintreguse -= intregsneeded + 1;
263 rd->savintregs[rd->savintreguse];
264 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
267 rd->savintregs[rd->savintreguse],
268 rd->savintregs[rd->savintreguse + 1]);
272 rd->savintregs[rd->savintreguse];
275 v->flags |= INMEMORY;
276 #if defined(ALIGN_LONGS_IN_MEMORY)
277 /* Align longs in Memory */
278 if ( (memneeded) && (rd->memuse & 1))
281 v->regoff = rd->memuse;
282 rd->memuse += memneeded + 1;
286 } /* if (IS_FLT_DBL_TYPE(t)) */
288 } else { /* (saved) */
289 /* now the same like above, but without a chance to take a temporary register */
290 #ifdef HAS_ADDRESS_REGISTER_FILE
291 if (IS_ADR_TYPE(t)) {
292 if (rd->savadrreguse > 0) {
293 v->regoff = rd->savadrregs[--rd->savadrreguse];
296 v->flags |= INMEMORY;
297 v->regoff = rd->memuse++;
302 if (IS_FLT_DBL_TYPE(t)) {
304 v->flags |= rd->interfaces[s][fltalloc].flags
306 v->regoff = rd->interfaces[s][fltalloc].regoff;
308 if (rd->savfltreguse > 0) {
309 v->regoff = rd->savfltregs[--rd->savfltreguse];
312 v->flags |= INMEMORY;
313 #if defined(ALIGN_DOUBLES_IN_MEMORY)
314 /* Align doubles in Memory */
315 if ( (memneeded) && (rd->memuse & 1))
318 v->regoff = rd->memuse;
319 rd->memuse += memneeded + 1;
323 else { /* IS_INT_LNG */
324 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
326 * for i386 put all longs in memory
328 if (IS_2_WORD_TYPE(t)) {
329 v->flags |= INMEMORY;
330 #if defined(ALIGN_LONGS_IN_MEMORY)
331 /* Align longs in Memory */
335 v->regoff = rd->memuse;
336 rd->memuse += memneeded + 1;
342 rd->interfaces[s][intalloc].flags & INMEMORY;
343 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
344 if (!(v->flags & INMEMORY)
345 && IS_2_WORD_TYPE(intalloc))
348 rd->interfaces[s][intalloc].regoff);
352 rd->interfaces[s][intalloc].regoff;
354 if (rd->savintreguse > intregsneeded) {
355 rd->savintreguse -= intregsneeded + 1;
356 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
358 v->regoff = PACK_REGS(
359 rd->savintregs[rd->savintreguse],
360 rd->savintregs[rd->savintreguse + 1]);
364 rd->savintregs[rd->savintreguse];
366 v->flags |= INMEMORY;
367 #if defined(ALIGN_LONGS_IN_MEMORY)
368 /* Align longs in Memory */
369 if ( (memneeded) && (rd->memuse & 1))
372 v->regoff = rd->memuse;
373 rd->memuse += memneeded + 1;
378 } /* if (IS_FLT_DBL_TYPE(t) else */
379 } /* if (IS_ADR_TYPE(t)) else */
380 } /* if (saved) else */
381 } /* if (type >= 0) */
387 /* local_regalloc **************************************************************
389 Allocates registers for all local variables.
391 *******************************************************************************/
393 static void local_regalloc(jitdata *jd)
400 int intalloc, fltalloc;
402 int intregsneeded = 0;
404 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
405 int fargcnt, iargcnt;
406 #ifdef HAS_ADDRESS_REGISTER_FILE
410 /* get required compiler data */
416 if (jd->isleafmethod) {
417 methoddesc *md = m->parseddesc;
419 iargcnt = rd->argintreguse;
420 fargcnt = rd->argfltreguse;
421 #ifdef HAS_ADDRESS_REGISTER_FILE
422 aargcnt = rd->argadrreguse;
424 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
425 intalloc = -1; fltalloc = -1;
426 for (tt = 0; tt <= 4; tt++) {
428 v = &rd->locals[s][t];
433 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
434 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
436 #if defined(HAS_4BYTE_STACKSLOT)
437 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
443 * #ifdef HAS_ADDRESS_REGISTER_FILE
450 * } else { / int & lng
454 * must not to be changed!
457 #ifdef HAS_ADDRESS_REGISTER_FILE
458 if (IS_ADR_TYPE(t)) {
459 if ((p < md->paramcount) && !md->params[p].inmemory) {
461 v->regoff = rd->argadrregs[md->params[p].regoff];
463 else if (rd->tmpadrreguse > 0) {
465 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
467 /* use unused argument registers as local registers */
468 else if ((p >= md->paramcount) &&
469 (aargcnt < ADR_ARG_CNT)) {
471 v->regoff = rd->argadrregs[aargcnt++];
473 else if (rd->savadrreguse > 0) {
475 v->regoff = rd->savadrregs[--rd->savadrreguse];
478 v->flags |= INMEMORY;
479 v->regoff = rd->memuse++;
483 if (IS_FLT_DBL_TYPE(t)) {
485 v->flags = rd->locals[s][fltalloc].flags;
486 v->regoff = rd->locals[s][fltalloc].regoff;
488 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
489 /* We can only use float arguments as local variables,
490 * if we do not pass them in integer registers. */
491 else if ((p < md->paramcount) &&
492 !md->params[p].inmemory) {
494 v->regoff = rd->argfltregs[md->params[p].regoff];
497 else if (rd->tmpfltreguse > 0) {
499 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
501 /* use unused argument registers as local registers */
502 else if ((p >= md->paramcount) &&
503 (fargcnt < FLT_ARG_CNT)) {
505 v->regoff = rd->argfltregs[fargcnt];
508 else if (rd->savfltreguse > 0) {
510 v->regoff = rd->savfltregs[--rd->savfltreguse];
514 #if defined(ALIGN_DOUBLES_IN_MEMORY)
515 /* Align doubles in Memory */
516 if ( (memneeded) && (rd->memuse & 1))
519 v->regoff = rd->memuse;
520 rd->memuse += memneeded + 1;
525 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
527 * for i386 put all longs in memory
529 if (IS_2_WORD_TYPE(t)) {
531 #if defined(ALIGN_LONGS_IN_MEMORY)
532 /* Align longs in Memory */
536 v->regoff = rd->memuse;
537 rd->memuse += memneeded + 1;
542 v->flags = rd->locals[s][intalloc].flags;
543 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
544 if (!(v->flags & INMEMORY)
545 && IS_2_WORD_TYPE(intalloc))
546 v->regoff = GET_LOW_REG(
547 rd->locals[s][intalloc].regoff);
550 v->regoff = rd->locals[s][intalloc].regoff;
552 else if ((p < md->paramcount) &&
553 !md->params[p].inmemory) {
555 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
556 if (IS_2_WORD_TYPE(t))
557 v->regoff = PACK_REGS(
558 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
559 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
563 rd->argintregs[md->params[p].regoff];
565 else if (rd->tmpintreguse > intregsneeded) {
566 rd->tmpintreguse -= intregsneeded + 1;
568 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
570 v->regoff = PACK_REGS(
571 rd->tmpintregs[rd->tmpintreguse],
572 rd->tmpintregs[rd->tmpintreguse + 1]);
576 rd->tmpintregs[rd->tmpintreguse];
579 * use unused argument registers as local registers
581 else if ((p >= m->parseddesc->paramcount) &&
582 (iargcnt + intregsneeded < INT_ARG_CNT)) {
584 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
587 rd->argintregs[iargcnt],
588 rd->argintregs[iargcnt + 1]);
591 v->regoff = rd->argintregs[iargcnt];
592 iargcnt += intregsneeded + 1;
594 else if (rd->savintreguse > intregsneeded) {
595 rd->savintreguse -= intregsneeded + 1;
597 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
599 v->regoff = PACK_REGS(
600 rd->savintregs[rd->savintreguse],
601 rd->savintregs[rd->savintreguse + 1]);
604 v->regoff =rd->savintregs[rd->savintreguse];
608 #if defined(ALIGN_LONGS_IN_MEMORY)
609 /* Align longs in Memory */
610 if ( (memneeded) && (rd->memuse & 1))
613 v->regoff = rd->memuse;
614 rd->memuse += memneeded + 1;
619 #ifdef HAS_ADDRESS_REGISTER_FILE
622 } /* for (tt=0;...) */
624 /* If the current parameter is a 2-word type, the next local slot */
627 if (p < md->paramcount)
628 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
634 for (s = 0; s < cd->maxlocals; s++) {
635 intalloc = -1; fltalloc = -1;
636 for (tt=0; tt<=4; tt++) {
638 v = &rd->locals[s][t];
641 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
642 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
644 #if defined(HAS_4BYTE_STACKSLOT)
645 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
647 #ifdef HAS_ADDRESS_REGISTER_FILE
648 if ( IS_ADR_TYPE(t) ) {
649 if (rd->savadrreguse > 0) {
651 v->regoff = rd->savadrregs[--rd->savadrreguse];
655 v->regoff = rd->memuse++;
659 if (IS_FLT_DBL_TYPE(t)) {
661 v->flags = rd->locals[s][fltalloc].flags;
662 v->regoff = rd->locals[s][fltalloc].regoff;
664 else if (rd->savfltreguse > 0) {
666 v->regoff = rd->savfltregs[--rd->savfltreguse];
670 #if defined(ALIGN_DOUBLES_IN_MEMORY)
671 /* Align doubles in Memory */
672 if ( (memneeded) && (rd->memuse & 1))
675 v->regoff = rd->memuse;
676 rd->memuse += memneeded + 1;
681 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
683 * for i386 put all longs in memory
685 if (IS_2_WORD_TYPE(t)) {
687 #if defined(ALIGN_LONGS_IN_MEMORY)
688 /* Align longs in Memory */
692 v->regoff = rd->memuse;
693 rd->memuse += memneeded + 1;
697 v->flags = rd->locals[s][intalloc].flags;
698 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
699 if (!(v->flags & INMEMORY)
700 && IS_2_WORD_TYPE(intalloc))
701 v->regoff = GET_LOW_REG(
702 rd->locals[s][intalloc].regoff);
705 v->regoff = rd->locals[s][intalloc].regoff;
707 else if (rd->savintreguse > intregsneeded) {
708 rd->savintreguse -= intregsneeded+1;
710 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
712 v->regoff = PACK_REGS(
713 rd->savintregs[rd->savintreguse],
714 rd->savintregs[rd->savintreguse + 1]);
717 v->regoff =rd->savintregs[rd->savintreguse];
721 #if defined(ALIGN_LONGS_IN_MEMORY)
722 /* Align longs in Memory */
723 if ( (memneeded) && (rd->memuse & 1))
726 v->regoff = rd->memuse;
727 rd->memuse += memneeded + 1;
729 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
734 #ifdef HAS_ADDRESS_REGISTER_FILE
743 static void reg_init_temp(methodinfo *m, registerdata *rd)
746 #if defined(HAS_4BYTE_STACKSLOT)
747 rd->freememtop_2 = 0;
750 rd->freetmpinttop = 0;
751 rd->freesavinttop = 0;
752 rd->freetmpflttop = 0;
753 rd->freesavflttop = 0;
754 #ifdef HAS_ADDRESS_REGISTER_FILE
755 rd->freetmpadrtop = 0;
756 rd->freesavadrtop = 0;
759 rd->freearginttop = 0;
760 rd->freeargflttop = 0;
761 #ifdef HAS_ADDRESS_REGISTER_FILE
762 rd->freeargadrtop = 0;
767 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
769 static void reg_new_temp_func(registerdata *rd, stackptr s)
775 /* Try to allocate a saved register if there is no temporary one */
776 /* available. This is what happens during the second run. */
777 tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
779 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
780 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
784 #if defined(HAS_4BYTE_STACKSLOT)
785 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
790 for(; tryagain; --tryagain) {
792 if (!(s->flags & SAVEDVAR))
793 s->flags |= SAVEDTMP;
794 #ifdef HAS_ADDRESS_REGISTER_FILE
795 if (IS_ADR_TYPE(s->type)) {
796 if (rd->freesavadrtop > 0) {
797 s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
799 } else if (rd->savadrreguse > 0) {
800 s->regoff = rd->savadrregs[--rd->savadrreguse];
806 if (IS_FLT_DBL_TYPE(s->type)) {
807 if (rd->freesavflttop > 0) {
808 s->regoff = rd->freesavfltregs[--rd->freesavflttop];
810 } else if (rd->savfltreguse > 0) {
811 s->regoff = rd->savfltregs[--rd->savfltreguse];
815 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
817 * for i386 put all longs in memory
819 if (!IS_2_WORD_TYPE(s->type))
822 if (rd->freesavinttop > intregsneeded) {
823 rd->freesavinttop -= intregsneeded + 1;
824 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
826 s->regoff = PACK_REGS(
827 rd->freesavintregs[rd->freesavinttop],
828 rd->freesavintregs[rd->freesavinttop + 1]);
832 rd->freesavintregs[rd->freesavinttop];
834 } else if (rd->savintreguse > intregsneeded) {
835 rd->savintreguse -= intregsneeded + 1;
836 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
838 s->regoff = PACK_REGS(
839 rd->savintregs[rd->savintreguse],
840 rd->savintregs[rd->savintreguse + 1]);
843 s->regoff = rd->savintregs[rd->savintreguse];
849 } else { /* tryagain == 2 */
850 #ifdef HAS_ADDRESS_REGISTER_FILE
851 if (IS_ADR_TYPE(s->type)) {
852 if (rd->freetmpadrtop > 0) {
853 s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
855 } else if (rd->tmpadrreguse > 0) {
856 s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
862 if (IS_FLT_DBL_TYPE(s->type)) {
863 if (rd->freeargflttop > 0) {
864 s->regoff = rd->freeargfltregs[--rd->freeargflttop];
867 } else if (rd->argfltreguse < FLT_ARG_CNT) {
868 s->regoff = rd->argfltregs[rd->argfltreguse++];
871 } else if (rd->freetmpflttop > 0) {
872 s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
874 } else if (rd->tmpfltreguse > 0) {
875 s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
880 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
882 * for i386 put all longs in memory
884 if (!IS_2_WORD_TYPE(s->type))
887 if (rd->freearginttop > intregsneeded) {
888 rd->freearginttop -= intregsneeded + 1;
890 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
892 s->regoff = PACK_REGS(
893 rd->freeargintregs[rd->freearginttop],
894 rd->freeargintregs[rd->freearginttop + 1]);
898 rd->freeargintregs[rd->freearginttop];
900 } else if (rd->argintreguse
901 < INT_ARG_CNT - intregsneeded) {
902 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
904 s->regoff = PACK_REGS(
905 rd->argintregs[rd->argintreguse],
906 rd->argintregs[rd->argintreguse + 1]);
909 s->regoff = rd->argintregs[rd->argintreguse];
911 rd->argintreguse += intregsneeded + 1;
913 } else if (rd->freetmpinttop > intregsneeded) {
914 rd->freetmpinttop -= intregsneeded + 1;
915 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
917 s->regoff = PACK_REGS(
918 rd->freetmpintregs[rd->freetmpinttop],
919 rd->freetmpintregs[rd->freetmpinttop + 1]);
922 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
924 } else if (rd->tmpintreguse > intregsneeded) {
925 rd->tmpintreguse -= intregsneeded + 1;
926 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
928 s->regoff = PACK_REGS(
929 rd->tmpintregs[rd->tmpintreguse],
930 rd->tmpintregs[rd->tmpintreguse + 1]);
933 s->regoff = rd->tmpintregs[rd->tmpintreguse];
936 } /* if (!IS_2_WORD_TYPE(s->type)) */
937 } /* if (IS_FLT_DBL_TYPE(s->type)) */
938 } /* if (IS_ADR_TYPE(s->type)) */
939 } /* if (tryagain == 1) else */
940 } /* for(; tryagain; --tryagain) */
942 #if defined(HAS_4BYTE_STACKSLOT)
943 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
945 s->regoff = rd->freemem_2[rd->freememtop_2];
947 #endif /*defined(HAS_4BYTE_STACKSLOT) */
948 if ((memneeded == 0) && (rd->freememtop > 0)) {
950 s->regoff = rd->freemem[rd->freememtop];
952 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
953 /* align 2 Word Types */
954 if ((memneeded) && ((rd->memuse & 1) == 1)) {
955 /* Put patched memory slot on freemem */
956 rd->freemem[rd->freememtop++] = rd->memuse;
959 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
960 s->regoff = rd->memuse;
961 rd->memuse += memneeded + 1;
963 s->flags |= INMEMORY;
967 #define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
969 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
970 /* alive using this reg/memory location */
972 static void reg_free_temp_func(registerdata *rd, stackptr s)
977 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
978 intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
983 #if defined(HAS_4BYTE_STACKSLOT)
984 memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
989 if (s->flags & INMEMORY) {
990 #if defined(HAS_4BYTE_STACKSLOT)
992 rd->freemem_2[rd->freememtop_2] = s->regoff;
997 rd->freemem[rd->freememtop] = s->regoff;
1001 #ifdef HAS_ADDRESS_REGISTER_FILE
1002 } else if (IS_ADR_TYPE(s->type)) {
1003 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1004 /* s->flags &= ~SAVEDTMP; */
1005 rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
1007 rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
1009 } else if (IS_FLT_DBL_TYPE(s->type)) {
1010 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1011 /* s->flags &= ~SAVEDTMP; */
1012 rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
1013 } else if (s->flags & TMPARG) {
1014 /* s->flags &= ~TMPARG; */
1015 rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1017 rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1018 } else { /* IS_INT_LNG_TYPE */
1019 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1020 /* s->flags &= ~SAVEDTMP; */
1021 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1022 if (intregsneeded) {
1023 rd->freesavintregs[rd->freesavinttop] =
1024 GET_LOW_REG(s->regoff);
1025 rd->freesavintregs[rd->freesavinttop + 1] =
1026 GET_HIGH_REG(s->regoff);
1029 rd->freesavintregs[rd->freesavinttop] = s->regoff;
1030 rd->freesavinttop += intregsneeded + 1;
1032 } else if (s->flags & TMPARG) {
1033 /* s->flags &= ~TMPARG; */
1034 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1035 if (intregsneeded) {
1036 rd->freeargintregs[rd->freearginttop] =
1037 GET_LOW_REG(s->regoff);
1038 rd->freeargintregs[rd->freearginttop + 1] =
1039 GET_HIGH_REG(s->regoff);
1042 rd->freeargintregs[rd->freearginttop] = s->regoff;
1043 rd->freearginttop += intregsneeded + 1;
1045 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1046 if (intregsneeded) {
1047 rd->freetmpintregs[rd->freetmpinttop] =
1048 GET_LOW_REG(s->regoff);
1049 rd->freetmpintregs[rd->freetmpinttop + 1] =
1050 GET_HIGH_REG(s->regoff);
1053 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1054 rd->freetmpinttop += intregsneeded + 1;
1059 static bool reg_alloc_dup(stackptr src, stackptr dst) {
1060 /* only copy TEMPVARS, do not mess with STACKVAR, */
1061 /* LOCALVAR, or ARGVAR */
1062 if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) {
1063 /* can not allocate a REG_TMP to a REG_SAV Slot */
1064 if (src->flags & INMEMORY) {
1065 dst->regoff = src->regoff;
1066 dst->flags |= INMEMORY;
1068 } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) {
1069 dst->regoff = src->regoff;
1070 dst->flags |= src->flags & SAVEDTMP;
1071 dst->flags |= src->flags & TMPARG;
1074 } else if ((dst->flags & SAVEDVAR) == 0) {
1075 /* can only use a REG_SAV as REG_TMP! */
1076 dst->regoff = src->regoff;
1077 dst->flags |= src->flags & TMPARG;
1078 dst->flags |= SAVEDTMP;
1083 /* no copy possible - allocate a new reg/memory location*/
1087 /* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
1088 static void new_reg_mark_copy(registerdata *rd, stackptr *dupslots,
1089 int nin, int nout, int nthrough)
1093 stackptr dst_stackslots[6];
1094 int s_bottom, d_bottom, i, j, slots;
1099 assert(nin <= 4 && (nout + nthrough) <= 6);
1101 /* remember all different Registers/Memory Location of used TEMPVAR */
1102 /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY */
1103 /* flag of the last (deepest) occurence */
1105 argp = dupslots + slots;
1106 for (s_bottom = 4; slots--; ) {
1108 if (sp->varkind == TEMPVAR) {
1110 for (i = 3; i >= s_bottom; i--) {
1111 if ((src_regoff[i] == sp->regoff) &&
1112 ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) )
1114 src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
1120 src_regoff[s_bottom] = sp->regoff;
1121 src_flags[s_bottom] = sp->flags;
1126 /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they */
1127 /* have to be from the "lowest" upwards, and the stackelements list is */
1128 /* linked from only top downwards */
1130 slots = nthrough + nout;
1131 argp = dupslots + nin + nout;
1132 for (d_bottom = 6; slots--; ) {
1134 if (sp->varkind == TEMPVAR) {
1136 dst_stackslots[d_bottom] = sp;
1140 /* Mark all reused reg/mem in dst stacklots with STCOPY, if the */
1141 /* corresponding src stackslot was marked STCOPY*/
1142 /* if the correspondig STCOPY from the src stackslot was not set, do not */
1143 /* mark the lowest occurence at dst stackslots */
1144 /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst */
1145 /* stacklots, so they are not freed afterwards */
1146 for (i = d_bottom; i < 6; i++) {
1147 for (j = s_bottom; j < 4; j++) {
1148 if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
1149 ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) )
1151 if (src_flags[j] & STCOPY) {
1152 dst_stackslots[i]->flags |= STCOPY;
1155 src_flags[j] |= STCOPY;
1156 dst_stackslots[i]->flags &= ~STCOPY;
1158 /* do not free reg/mem of src Stackslot */
1159 src_flags[j] |= STKEEP;
1164 /* free all reg/mem of src stack, which where not marked with STKEEP */
1165 for (j=s_bottom; j < 4; j++) {
1166 if ((src_flags[j] & STKEEP)==0) {
1167 /* free, if STCOPY of src stackslot is not set */
1168 /* STCOPY is already checked in reg_free_temp macro! */
1170 argp = dupslots + slots;
1173 if ((src_regoff[j] == sp->regoff) &&
1174 ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) )
1176 reg_free_temp(rd, sp);
1184 /* allocate_scratch_registers **************************************************
1186 Allocate temporary (non-interface, non-local) registers.
1188 *******************************************************************************/
1190 static void new_allocate_scratch_registers(jitdata *jd)
1198 builtintable_entry *bte;
1202 /* get required compiler data */
1207 /* initialize temp registers */
1209 reg_init_temp(m, rd);
1211 bptr = jd->new_basicblocks;
1213 while (bptr != NULL) {
1214 if (bptr->flags >= BBREACHED) {
1215 iptr = bptr->iinstr;
1218 while (--len >= 0) {
1219 switch (iptr->opc) {
1224 case ICMD_CHECKNULL:
1230 case ICMD_PUTSTATICCONST:
1231 case ICMD_INLINE_START:
1232 case ICMD_INLINE_END:
1233 case ICMD_INLINE_GOTO:
1236 /* pop 0 push 1 const */
1244 /* pop 0 push 1 load */
1251 reg_new_temp(rd, iptr->dst.var);
1265 reg_free_temp(rd, iptr->sx.s23.s2.var);
1266 reg_free_temp(rd, iptr->s1.var);
1267 reg_new_temp(rd, iptr->dst.var);
1281 reg_free_temp(rd, iptr->sx.s23.s3.var);
1282 reg_free_temp(rd, iptr->sx.s23.s2.var);
1283 reg_free_temp(rd, iptr->s1.var);
1286 /* pop 1 push 0 store */
1306 case ICMD_PUTSTATIC:
1307 case ICMD_PUTFIELDCONST:
1309 /* pop 1 push 0 branch */
1312 case ICMD_IFNONNULL:
1328 /* pop 1 push 0 table branch */
1330 case ICMD_TABLESWITCH:
1331 case ICMD_LOOKUPSWITCH:
1333 case ICMD_MONITORENTER:
1334 case ICMD_MONITOREXIT:
1335 reg_free_temp(rd, iptr->s1.var);
1338 /* pop 2 push 0 branch */
1340 case ICMD_IF_ICMPEQ:
1341 case ICMD_IF_ICMPNE:
1342 case ICMD_IF_ICMPLT:
1343 case ICMD_IF_ICMPGE:
1344 case ICMD_IF_ICMPGT:
1345 case ICMD_IF_ICMPLE:
1347 case ICMD_IF_LCMPEQ:
1348 case ICMD_IF_LCMPNE:
1349 case ICMD_IF_LCMPLT:
1350 case ICMD_IF_LCMPGE:
1351 case ICMD_IF_LCMPGT:
1352 case ICMD_IF_LCMPLE:
1354 case ICMD_IF_FCMPEQ:
1355 case ICMD_IF_FCMPNE:
1357 case ICMD_IF_FCMPL_LT:
1358 case ICMD_IF_FCMPL_GE:
1359 case ICMD_IF_FCMPL_GT:
1360 case ICMD_IF_FCMPL_LE:
1362 case ICMD_IF_FCMPG_LT:
1363 case ICMD_IF_FCMPG_GE:
1364 case ICMD_IF_FCMPG_GT:
1365 case ICMD_IF_FCMPG_LE:
1367 case ICMD_IF_DCMPEQ:
1368 case ICMD_IF_DCMPNE:
1370 case ICMD_IF_DCMPL_LT:
1371 case ICMD_IF_DCMPL_GE:
1372 case ICMD_IF_DCMPL_GT:
1373 case ICMD_IF_DCMPL_LE:
1375 case ICMD_IF_DCMPG_LT:
1376 case ICMD_IF_DCMPG_GE:
1377 case ICMD_IF_DCMPG_GT:
1378 case ICMD_IF_DCMPG_LE:
1380 case ICMD_IF_ACMPEQ:
1381 case ICMD_IF_ACMPNE:
1389 case ICMD_IASTORECONST:
1390 case ICMD_LASTORECONST:
1391 case ICMD_AASTORECONST:
1392 case ICMD_BASTORECONST:
1393 case ICMD_CASTORECONST:
1394 case ICMD_SASTORECONST:
1395 reg_free_temp(rd, iptr->sx.s23.s2.var);
1396 reg_free_temp(rd, iptr->s1.var);
1399 /* pop 0 push 1 dup */
1402 /* src === dst->prev (identical Stackslot Element) */
1403 /* src --> dst (copied value, take same reg/mem) */
1405 if (!reg_alloc_dup(iptr->s1.var, iptr->dst.var)) {
1406 reg_new_temp(rd, iptr->dst.var);
1408 iptr->dst.var->flags |= STCOPY;
1412 /* pop 0 push 2 dup */
1415 /* src->prev === dst->prev->prev->prev (identical Stackslot Element) */
1416 /* src === dst->prev->prev (identical Stackslot Element) */
1417 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1418 /* src --> dst (copied value, take same reg/mem) */
1420 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0]))
1421 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1422 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1]))
1423 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1424 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2);
1427 /* pop 2 push 3 dup */
1430 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1431 /* src --> dst (copied value, take same reg/mem) */
1432 /* src --> dst->prev->prev (copied value, take same reg/mem) */
1434 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
1435 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1436 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2]))
1437 reg_new_temp(rd, iptr->dst.dupslots[2+2]);
1438 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
1439 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1440 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0);
1443 /* pop 3 push 4 dup */
1446 /* src->prev->prev --> dst->prev->prev */
1447 /* src->prev --> dst->prev */
1449 /* src --> dst->prev->prev->prev */
1451 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0]))
1452 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1453 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3]))
1454 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1455 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2]))
1456 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1457 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1]))
1458 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1459 new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0);
1462 /* pop 3 push 5 dup */
1465 /* src->prev->prev --> dst->prev->prev */
1466 /* src->prev --> dst->prev */
1468 /* src->prev --> dst->prev->prev->prev->prev */
1469 /* src --> dst->prev->prev->prev */
1471 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1]))
1472 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1473 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4]))
1474 reg_new_temp(rd, iptr->dst.dupslots[3+4]);
1475 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0]))
1476 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1477 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3]))
1478 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1479 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2]))
1480 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1481 new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0);
1484 /* pop 4 push 6 dup */
1487 /* src->prev->prev->prev --> dst->prev->prev->prev */
1488 /* src->prev->prev --> dst->prev->prev */
1489 /* src->prev --> dst->prev */
1491 /* src->prev --> dst->prev->prev->prev->prev->prev */
1492 /* src --> dst->prev->prev->prev->prev */
1494 if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1]))
1495 reg_new_temp(rd, iptr->dst.dupslots[4+1]);
1496 if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5]))
1497 reg_new_temp(rd, iptr->dst.dupslots[4+5]);
1498 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0]))
1499 reg_new_temp(rd, iptr->dst.dupslots[4+0]);
1500 if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4]))
1501 reg_new_temp(rd, iptr->dst.dupslots[4+4]);
1502 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3]))
1503 reg_new_temp(rd, iptr->dst.dupslots[4+3]);
1504 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2]))
1505 reg_new_temp(rd, iptr->dst.dupslots[4+2]);
1506 new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0);
1509 /* pop 2 push 2 swap */
1512 /* src --> dst->prev (copy) */
1513 /* src->prev --> dst (copy) */
1515 if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
1516 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1517 if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
1518 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1519 new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0);
1568 reg_free_temp(rd, iptr->sx.s23.s2.var);
1569 reg_free_temp(rd, iptr->s1.var);
1570 reg_new_temp(rd, iptr->dst.var);
1575 case ICMD_IADDCONST:
1576 case ICMD_ISUBCONST:
1577 case ICMD_IMULCONST:
1581 case ICMD_IANDCONST:
1583 case ICMD_IXORCONST:
1584 case ICMD_ISHLCONST:
1585 case ICMD_ISHRCONST:
1586 case ICMD_IUSHRCONST:
1588 case ICMD_LADDCONST:
1589 case ICMD_LSUBCONST:
1590 case ICMD_LMULCONST:
1594 case ICMD_LANDCONST:
1596 case ICMD_LXORCONST:
1597 case ICMD_LSHLCONST:
1598 case ICMD_LSHRCONST:
1599 case ICMD_LUSHRCONST:
1604 case ICMD_INT2SHORT:
1622 case ICMD_CHECKCAST:
1624 case ICMD_ARRAYLENGTH:
1625 case ICMD_INSTANCEOF:
1628 case ICMD_ANEWARRAY:
1631 reg_free_temp(rd, iptr->s1.var);
1632 reg_new_temp(rd, iptr->dst.var);
1637 case ICMD_GETSTATIC:
1640 reg_new_temp(rd, iptr->dst.var);
1643 /* pop many push any */
1645 case ICMD_INVOKESTATIC:
1646 case ICMD_INVOKESPECIAL:
1647 case ICMD_INVOKEVIRTUAL:
1648 case ICMD_INVOKEINTERFACE:
1649 INSTRUCTION_GET_METHODDESC(iptr,md);
1651 argp = iptr->sx.s23.s2.args;
1653 reg_free_temp(rd, *argp);
1656 if (md->returntype.type != TYPE_VOID)
1657 reg_new_temp(rd, iptr->dst.var);
1661 bte = iptr->sx.s23.s3.bte;
1664 argp = iptr->sx.s23.s2.args;
1666 reg_free_temp(rd, *argp);
1669 if (md->returntype.type != TYPE_VOID)
1670 reg_new_temp(rd, iptr->dst.var);
1673 case ICMD_MULTIANEWARRAY:
1674 i = iptr->s1.argcount;
1675 argp = iptr->sx.s23.s2.args;
1677 reg_free_temp(rd, *argp);
1680 reg_new_temp(rd, iptr->dst.var);
1685 new_internalerror("Unknown ICMD %d during register allocation",
1690 } /* while instructions */
1693 } /* while blocks */
1697 #if defined(ENABLE_STATISTICS)
1698 void reg_make_statistics(jitdata *jd)
1705 stackptr src, src_old;
1709 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1712 /* get required compiler data */
1722 /* count how many local variables are held in memory or register */
1723 for(i=0; i < cd->maxlocals; i++)
1724 for (type=0; type <=4; type++)
1725 if (rd->locals[i][type].type != -1) { /* valid local */
1726 if (rd->locals[i][type].flags & INMEMORY) {
1727 count_locals_spilled++;
1731 count_locals_register++;
1734 /* count how many stack slots are held in memory or register */
1736 bptr = jd->new_basicblocks;
1738 while (bptr != NULL) {
1739 if (bptr->flags >= BBREACHED) {
1741 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1744 /* check for memory moves from interface to BB instack */
1745 dst = bptr->instack;
1746 len = bptr->indepth;
1748 if (len > size_interface) size_interface = len;
1750 while (dst != NULL) {
1752 if (dst->varkind != STACKVAR) {
1753 if ( (dst->flags & INMEMORY) ||
1754 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1755 ( (dst->flags & INMEMORY) &&
1756 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1757 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1759 /* one in memory or both inmemory at different offsets */
1760 count_mem_move_bb++;
1768 /* check for memory moves from BB outstack to interface */
1769 dst = bptr->outstack;
1770 len = bptr->outdepth;
1771 if (len > size_interface) size_interface = len;
1775 if (dst->varkind != STACKVAR) {
1776 if ( (dst->flags & INMEMORY) || \
1777 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1778 ( (dst->flags & INMEMORY) && \
1779 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1780 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1782 /* one in memory or both inmemory at different offsets */
1783 count_mem_move_bb++;
1790 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1795 dst = bptr->instack;
1796 iptr = bptr->iinstr;
1800 while (--len >= 0) {
1802 dst = iptr->dst.var;
1804 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1805 switch (src->varkind) {
1808 if (!(src->flags & INMEMORY))
1809 count_ss_register++;
1815 /* case LOCALVAR: */
1816 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1817 /* count_ss_register++; */
1819 /* count_ss_spilled++; */
1822 if (!(src->flags & INMEMORY))
1823 count_argument_mem_ss++;
1825 count_argument_reg_ss++;
1829 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1830 /* if (src->varnum < FLT_ARG_CNT) { */
1831 /* count_ss_register++; */
1835 /* #if defined(__POWERPC__) */
1836 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1838 /* if (src->varnum < INT_ARG_CNT) { */
1840 /* count_ss_register++; */
1844 /* count_ss_spilled++; */
1851 } /* while instructions */
1854 } /* while blocks */
1855 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1856 if (in_register) count_method_in_register++;
1858 printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1861 #endif /* defined(ENABLE_STATISTICS) */
1865 * These are local overrides for various environment variables in Emacs.
1866 * Please do not remove this and leave it at the end of the file, where
1867 * Emacs will automagically detect them.
1868 * ---------------------------------------------------------------------
1871 * indent-tabs-mode: t
1875 * vim:noexpandtab:sw=4:ts=4: