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 5710 2006-10-06 23:41:02Z 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"
57 #include "vm/jit/show.h"
61 # define LOG(args) printf args
67 /* function prototypes for this file ******************************************/
69 static void simplereg_allocate_interfaces(jitdata *jd);
70 static void simplereg_allocate_locals(jitdata *jd);
71 static void simplereg_allocate_temporaries(jitdata *jd);
74 /* macros for handling register stacks ****************************************/
76 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
77 #define AVAIL_BACK(cnt) ((cnt) > 0)
79 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
80 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
81 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
83 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
84 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
87 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
88 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
89 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
90 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
92 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
93 #define POP_FRONT_INT(stk, cnt, reg) \
95 if (intregsneeded) { \
96 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
100 POP_FRONT(stk, cnt, reg); \
103 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
106 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
107 #define POP_BACK_INT(stk, cnt, reg) \
109 if (intregsneeded) { \
111 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
114 POP_BACK(stk, cnt, reg); \
117 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
120 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
121 #define PUSH_BACK_INT(stk, cnt, reg) \
123 if (intregsneeded) { \
124 stk[cnt] = GET_LOW_REG(reg); \
125 stk[cnt + 1] = GET_HIGH_REG(reg); \
129 PUSH_BACK(stk, cnt, reg); \
132 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
135 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
136 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
137 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
139 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
140 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
141 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
143 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
144 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
145 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
147 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
148 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
149 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
151 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
152 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
153 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
155 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
156 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
157 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
159 #define TAKE_ARG_FLT(r) POP_FRONT(rd->argfltregs, rd->argfltreguse, r)
160 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
161 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
163 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
164 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
165 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
167 #define TAKE_ARG_INT(r) POP_FRONT_INT(rd->argintregs, rd->argintreguse, r)
168 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
169 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
171 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
172 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
173 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
175 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
176 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
177 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
179 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
180 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
181 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
183 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
184 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
185 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
187 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
188 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
189 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
191 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
192 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
193 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
196 /* macros for creating/freeing temporary variables ***************************/
198 #define NEW_TEMP_REG(index) \
199 if ( ((index) >= jd->localcount) \
200 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
201 simplereg_new_temp(jd, (index))
204 #define FREE_TEMP_REG(index) \
205 if (((index) > jd->localcount) \
206 && (!(VAR(index)->flags & (PREALLOC)))) \
207 simplereg_free_temp(jd, (index))
210 /* macro for getting a unique register index *********************************/
212 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
213 #define SIMPLEREG_REG_INDEX(regoff, type) \
214 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
216 #define SIMPLEREG_REG_INDEX(regoff, type) \
217 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
221 /* regalloc ********************************************************************
223 Does a simple register allocation.
225 *******************************************************************************/
227 bool regalloc(jitdata *jd)
229 /* There is a problem with the use of unused float argument
230 registers in leafmethods for stackslots on c7 (2 * Dual Core
231 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
232 benchmark is heaviliy increased. This could be prevented by
233 setting rd->argfltreguse to FLT_ARG_CNT before calling
234 simplereg_allocate_temporaries and setting it back to the original
235 value before calling simplereg_allocate_locals. */
237 simplereg_allocate_interfaces(jd);
238 simplereg_allocate_temporaries(jd);
239 simplereg_allocate_locals(jd);
247 /* simplereg_allocate_interfaces ***********************************************
249 Allocates registers for all interface variables.
251 *******************************************************************************/
253 static void simplereg_allocate_interfaces(jitdata *jd)
260 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
261 /* in case more vars are packed into this interface slot */
263 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
264 /* on HAS_4BYTE_STACKSLOT architectures */
265 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
267 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
271 /* get required compiler data */
277 /* rd->memuse was already set in stack.c to allocate stack space
278 for passing arguments to called methods. */
280 #if defined(__I386__)
281 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
282 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
288 if (jd->isleafmethod) {
289 /* Reserve argument register, which will be used for Locals acting */
291 if (rd->argintreguse < m->parseddesc->argintreguse)
292 rd->argintreguse = m->parseddesc->argintreguse;
293 if (rd->argfltreguse < m->parseddesc->argfltreguse)
294 rd->argfltreguse = m->parseddesc->argfltreguse;
295 #ifdef HAS_ADDRESS_REGISTER_FILE
296 if (rd->argadrreguse < m->parseddesc->argadrreguse)
297 rd->argadrreguse = m->parseddesc->argadrreguse;
302 for (s = 0; s < cd->maxstack; s++) {
303 intalloc = -1; fltalloc = -1;
307 for (tt = 0; tt <=4; tt++) {
308 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
309 saved |= t & SAVEDVAR;
313 for (tt = 0; tt <= 4; tt++) {
315 if (jd->interface_map[s * 5 + t].flags == UNUSED)
319 regoff = -1; /* XXX for debugging */
321 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
322 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
325 #if defined(HAS_4BYTE_STACKSLOT)
326 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
329 #if defined(HAS_ADDRESS_REGISTER_FILE)
330 if (IS_ADR_TYPE(t)) {
331 if (!jd->isleafmethod && AVAIL_ARG_ADR) {
333 TAKE_ARG_ADR(regoff);
335 else if (AVAIL_TMP_ADR) {
336 TAKE_TMP_ADR(regoff);
338 else if (AVAIL_SAV_ADR) {
340 TAKE_SAV_ADR(regoff);
344 regoff = rd->memuse++;
347 else /* !IS_ADR_TYPE */
348 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
350 if (IS_FLT_DBL_TYPE(t)) {
352 /* Reuse memory slot(s)/register(s) for shared interface slots */
353 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
354 regoff = jd->interface_map[fltalloc].regoff;
356 else if (AVAIL_ARG_FLT) {
358 TAKE_ARG_FLT(regoff);
360 else if (AVAIL_TMP_FLT) {
361 TAKE_TMP_FLT(regoff);
363 else if (AVAIL_SAV_FLT) {
365 TAKE_SAV_FLT(regoff);
369 #if defined(ALIGN_DOUBLES_IN_MEMORY)
370 /* Align doubles in Memory */
371 if ( (memneeded) && (rd->memuse & 1))
375 rd->memuse += memneeded + 1;
377 fltalloc = s * 5 + t;
379 else { /* !IS_FLT_DBL_TYPE(t) */
380 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
382 * for i386 put all longs in memory
384 if (IS_2_WORD_TYPE(t)) {
386 #if defined(ALIGN_LONGS_IN_MEMORY)
387 /* Align longs in Memory */
392 rd->memuse += memneeded + 1;
395 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
397 /* Reuse memory slot(s)/register(s) for shared interface slots */
398 flags |= jd->interface_map[intalloc].flags & INMEMORY;
399 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
400 if (!(flags & INMEMORY)
401 && IS_2_WORD_TYPE(intalloc % 5))
402 regoff = GET_LOW_REG(
403 jd->interface_map[intalloc].regoff);
407 jd->interface_map[intalloc].regoff;
412 TAKE_ARG_INT(regoff);
414 else if (AVAIL_TMP_INT) {
415 TAKE_TMP_INT(regoff);
417 else if (AVAIL_SAV_INT) {
419 TAKE_SAV_INT(regoff);
423 #if defined(ALIGN_LONGS_IN_MEMORY)
424 /* Align longs in Memory */
425 if ( (memneeded) && (rd->memuse & 1))
429 rd->memuse += memneeded + 1;
433 intalloc = s * 5 + t;
434 } /* if (IS_FLT_DBL_TYPE(t)) */
438 /* now the same like above, but without a chance to take a temporary register */
439 #ifdef HAS_ADDRESS_REGISTER_FILE
440 if (IS_ADR_TYPE(t)) {
442 TAKE_SAV_ADR(regoff);
446 regoff = rd->memuse++;
452 if (IS_FLT_DBL_TYPE(t)) {
454 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
455 regoff = jd->interface_map[fltalloc].regoff;
459 TAKE_SAV_FLT(regoff);
463 #if defined(ALIGN_DOUBLES_IN_MEMORY)
464 /* Align doubles in Memory */
465 if ( (memneeded) && (rd->memuse & 1))
469 rd->memuse += memneeded + 1;
472 fltalloc = s * 5 + t;
474 else { /* IS_INT_LNG */
475 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
477 * for i386 put all longs in memory
479 if (IS_2_WORD_TYPE(t)) {
481 #if defined(ALIGN_LONGS_IN_MEMORY)
482 /* Align longs in Memory */
487 rd->memuse += memneeded + 1;
493 flags |= jd->interface_map[intalloc].flags & INMEMORY;
494 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
495 if (!(flags & INMEMORY)
496 && IS_2_WORD_TYPE(intalloc % 5))
499 jd->interface_map[intalloc].regoff);
503 jd->interface_map[intalloc].regoff;
507 TAKE_SAV_INT(regoff);
511 #if defined(ALIGN_LONGS_IN_MEMORY)
512 /* Align longs in Memory */
513 if ( (memneeded) && (rd->memuse & 1))
517 rd->memuse += memneeded + 1;
522 } /* if (IS_FLT_DBL_TYPE(t) else */
523 } /* if (IS_ADR_TYPE(t)) else */
524 } /* if (saved) else */
528 jd->interface_map[5*s + t].flags = flags | INOUT;
529 jd->interface_map[5*s + t].regoff = regoff;
535 /* simplereg_allocate_locals_leafmethod ****************************************
537 Allocates registers for all local variables of a leafmethod.
539 *******************************************************************************/
541 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
548 int intalloc, fltalloc;
550 int intregsneeded = 0;
552 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
553 int fargcnt, iargcnt;
554 #ifdef HAS_ADDRESS_REGISTER_FILE
558 /* get required compiler data */
564 methoddesc *md = m->parseddesc;
566 iargcnt = rd->argintreguse;
567 fargcnt = rd->argfltreguse;
568 #ifdef HAS_ADDRESS_REGISTER_FILE
569 aargcnt = rd->argadrreguse;
571 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
572 intalloc = -1; fltalloc = -1;
573 for (tt = 0; tt <= 4; tt++) {
575 lm = jd->local_map[s * 5 + t];
581 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
582 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
584 #if defined(HAS_4BYTE_STACKSLOT)
585 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
591 * #ifdef HAS_ADDRESS_REGISTER_FILE
598 * } else { / int & lng
602 * must not to be changed!
605 #ifdef HAS_ADDRESS_REGISTER_FILE
606 if (IS_ADR_TYPE(t)) {
607 if ((p < md->paramcount) && !md->params[p].inmemory) {
609 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
611 else if (AVAIL_TMP_ADR) {
613 TAKE_TMP_ADR(v->vv.regoff);
615 /* use unused argument registers as local registers */
616 else if ((p >= md->paramcount) &&
617 (aargcnt < ADR_ARG_CNT)) {
619 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
621 else if (AVAIL_SAV_ADR) {
623 TAKE_SAV_ADR(v->vv.regoff);
626 v->flags |= INMEMORY;
627 v->vv.regoff = rd->memuse++;
632 if (IS_FLT_DBL_TYPE(t)) {
634 v->flags = VAR(fltalloc)->flags;
635 v->vv.regoff = VAR(fltalloc)->vv.regoff;
637 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
638 /* We can only use float arguments as local variables,
639 * if we do not pass them in integer registers. */
640 else if ((p < md->paramcount) &&
641 !md->params[p].inmemory) {
643 v->vv.regoff = rd->argfltregs[md->params[p].regoff];
646 else if (AVAIL_TMP_FLT) {
648 TAKE_TMP_FLT(v->vv.regoff);
650 /* use unused argument registers as local registers */
651 else if ((p >= md->paramcount) &&
652 (fargcnt < FLT_ARG_CNT)) {
654 POP_FRONT(rd->argfltregs, fargcnt, v->vv.regoff);
656 else if (AVAIL_SAV_FLT) {
658 TAKE_SAV_FLT(v->vv.regoff);
662 #if defined(ALIGN_DOUBLES_IN_MEMORY)
663 /* Align doubles in Memory */
664 if ( (memneeded) && (rd->memuse & 1))
667 v->vv.regoff = rd->memuse;
668 rd->memuse += memneeded + 1;
670 fltalloc = jd->local_map[s * 5 + t];
674 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
676 * for i386 put all longs in memory
678 if (IS_2_WORD_TYPE(t)) {
680 #if defined(ALIGN_LONGS_IN_MEMORY)
681 /* Align longs in Memory */
685 v->vv.regoff = rd->memuse;
686 rd->memuse += memneeded + 1;
692 v->flags = VAR(intalloc)->flags;
693 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
694 if (!(v->flags & INMEMORY)
695 && IS_2_WORD_TYPE(VAR(intalloc)->type))
696 v->vv.regoff = GET_LOW_REG(
697 VAR(intalloc)->vv.regoff);
700 v->vv.regoff = VAR(intalloc)->vv.regoff;
702 else if ((p < md->paramcount) &&
703 !md->params[p].inmemory) {
705 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
706 if (IS_2_WORD_TYPE(t))
707 v->vv.regoff = PACK_REGS(
708 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
709 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
713 rd->argintregs[md->params[p].regoff];
715 else if (AVAIL_TMP_INT) {
717 TAKE_TMP_INT(v->vv.regoff);
720 * use unused argument registers as local registers
722 else if ((p >= m->parseddesc->paramcount) &&
723 (iargcnt + intregsneeded < INT_ARG_CNT))
726 POP_FRONT_INT(rd->argintregs, iargcnt, v->vv.regoff);
728 else if (AVAIL_SAV_INT) {
730 TAKE_SAV_INT(v->vv.regoff);
734 #if defined(ALIGN_LONGS_IN_MEMORY)
735 /* Align longs in Memory */
736 if ( (memneeded) && (rd->memuse & 1))
739 v->vv.regoff = rd->memuse;
740 rd->memuse += memneeded + 1;
743 intalloc = jd->local_map[s * 5 + t];
745 #ifdef HAS_ADDRESS_REGISTER_FILE
748 } /* for (tt=0;...) */
750 /* If the current parameter is a 2-word type, the next local slot */
753 if (p < md->paramcount)
754 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
759 /* simplereg_allocate_locals ***************************************************
761 Allocates registers for all local variables.
763 *******************************************************************************/
765 static void simplereg_allocate_locals(jitdata *jd)
771 int intalloc, fltalloc;
774 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
775 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
779 /* get required compiler data */
784 if (jd->isleafmethod) {
785 simplereg_allocate_locals_leafmethod(jd);
789 for (s = 0; s < cd->maxlocals; s++) {
790 intalloc = -1; fltalloc = -1;
791 for (tt=0; tt<=4; tt++) {
794 lm = jd->local_map[s * 5 + t];
800 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
801 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
804 #if defined(HAS_4BYTE_STACKSLOT)
805 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
808 #ifdef HAS_ADDRESS_REGISTER_FILE
809 if (IS_ADR_TYPE(t)) {
812 TAKE_SAV_ADR(v->vv.regoff);
816 v->vv.regoff = rd->memuse++;
821 if (IS_FLT_DBL_TYPE(t)) {
823 v->flags = VAR(fltalloc)->flags;
824 v->vv.regoff = VAR(fltalloc)->vv.regoff;
826 else if (AVAIL_SAV_FLT) {
828 TAKE_SAV_FLT(v->vv.regoff);
832 #if defined(ALIGN_DOUBLES_IN_MEMORY)
833 /* Align doubles in Memory */
834 if ( (memneeded) && (rd->memuse & 1))
837 v->vv.regoff = rd->memuse;
838 rd->memuse += memneeded + 1;
840 fltalloc = jd->local_map[s * 5 + t];
843 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
845 * for i386 put all longs in memory
847 if (IS_2_WORD_TYPE(t)) {
849 #if defined(ALIGN_LONGS_IN_MEMORY)
850 /* Align longs in Memory */
854 v->vv.regoff = rd->memuse;
855 rd->memuse += memneeded + 1;
860 v->flags = VAR(intalloc)->flags;
861 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
862 if (!(v->flags & INMEMORY)
863 && IS_2_WORD_TYPE(VAR(intalloc)->type))
864 v->vv.regoff = GET_LOW_REG(
865 VAR(intalloc)->vv.regoff);
868 v->vv.regoff = VAR(intalloc)->vv.regoff;
870 else if (AVAIL_SAV_INT) {
872 TAKE_SAV_INT(v->vv.regoff);
876 #if defined(ALIGN_LONGS_IN_MEMORY)
877 /* Align longs in Memory */
878 if ( (memneeded) && (rd->memuse & 1))
881 v->vv.regoff = rd->memuse;
882 rd->memuse += memneeded + 1;
884 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
887 intalloc = jd->local_map[s * 5 + t];
889 #ifdef HAS_ADDRESS_REGISTER_FILE
897 static void simplereg_init(jitdata *jd, registerdata *rd)
902 #if defined(HAS_4BYTE_STACKSLOT)
903 rd->freememtop_2 = 0;
906 rd->freetmpinttop = 0;
907 rd->freesavinttop = 0;
908 rd->freetmpflttop = 0;
909 rd->freesavflttop = 0;
910 #ifdef HAS_ADDRESS_REGISTER_FILE
911 rd->freetmpadrtop = 0;
912 rd->freesavadrtop = 0;
915 rd->freearginttop = 0;
916 rd->freeargflttop = 0;
917 #ifdef HAS_ADDRESS_REGISTER_FILE
918 rd->freeargadrtop = 0;
921 rd->regisoutvar = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
922 rd->regcopycount = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
923 MZERO(rd->regcopycount, int, INT_REG_CNT + FLT_REG_CNT);
925 /* memcopycount is dynamically allocated when needed */
927 rd->memcopycount = NULL;
928 rd->memcopycountsize = 0;
930 rd->intusedinout = DMNEW(int, INT_REG_CNT);
931 MZERO(rd->intusedinout, int, INT_REG_CNT);
932 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
933 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
935 /* record the interface registers as used */
937 for (i=0; i<rd->argintreguse; ++i)
938 rd->intusedinout[rd->argintregs[i]] = 1;
939 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
940 rd->intusedinout[rd->tmpintregs[i]] = 1;
941 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
942 rd->intusedinout[rd->savintregs[i]] = 1;
944 for (i=0; i<rd->argfltreguse; ++i)
945 rd->fltusedinout[rd->argfltregs[i]] = 1;
946 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
947 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
948 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
949 rd->fltusedinout[rd->savfltregs[i]] = 1;
951 #ifdef HAS_ADDRESS_REGISTER_FILE
952 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
953 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
955 for (i=0; i<rd->argadrreguse; ++i)
956 rd->adrusedinout[rd->argadrregs[i]] = 1;
957 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
958 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
959 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
960 rd->adrusedinout[rd->savadrregs[i]] = 1;
965 static void simplereg_init_block(registerdata *rd)
969 /* remove all interface registers from the free lists */
971 for (i=0; i<rd->freearginttop; ++i)
972 if (rd->intusedinout[rd->freeargintregs[i]]) {
973 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
975 for (i=0; i<rd->freetmpinttop; ++i)
976 if (rd->intusedinout[rd->freetmpintregs[i]]) {
977 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
979 for (i=0; i<rd->freesavinttop; ++i)
980 if (rd->intusedinout[rd->freesavintregs[i]]) {
981 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
984 for (i=0; i<rd->freeargflttop; ++i)
985 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
986 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
988 for (i=0; i<rd->freetmpflttop; ++i)
989 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
990 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
992 for (i=0; i<rd->freesavflttop; ++i)
993 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
994 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
997 #ifdef HAS_ADDRESS_REGISTER_FILE
998 for (i=0; i<rd->freeargadrtop; ++i)
999 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
1000 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
1002 for (i=0; i<rd->freetmpadrtop; ++i)
1003 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
1004 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
1006 for (i=0; i<rd->freesavadrtop; ++i)
1007 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1008 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1014 static void simplereg_new_temp(jitdata *jd, s4 index)
1016 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1027 /* Try to allocate a saved register if there is no temporary one */
1028 /* available. This is what happens during the second run. */
1029 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1031 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1032 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1035 #if defined(HAS_4BYTE_STACKSLOT)
1036 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1041 for(; tryagain; --tryagain) {
1042 if (tryagain == 1) {
1043 if (!(v->flags & SAVEDVAR))
1045 #ifdef HAS_ADDRESS_REGISTER_FILE
1046 if (IS_ADR_TYPE(v->type)) {
1047 if (AVAIL_FREE_SAV_ADR) {
1048 TAKE_FREE_SAV_ADR(v->vv.regoff);
1051 else if (AVAIL_SAV_ADR) {
1052 TAKE_SAV_ADR(v->vv.regoff);
1059 if (IS_FLT_DBL_TYPE(v->type)) {
1060 if (AVAIL_FREE_SAV_FLT) {
1061 TAKE_FREE_SAV_FLT(v->vv.regoff);
1064 else if (AVAIL_SAV_FLT) {
1065 TAKE_SAV_FLT(v->vv.regoff);
1070 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1072 * for i386 put all longs in memory
1074 if (!IS_2_WORD_TYPE(v->type))
1077 if (AVAIL_FREE_SAV_INT) {
1078 TAKE_FREE_SAV_INT(v->vv.regoff);
1081 else if (AVAIL_SAV_INT) {
1082 TAKE_SAV_INT(v->vv.regoff);
1089 else { /* tryagain == 2 */
1090 #ifdef HAS_ADDRESS_REGISTER_FILE
1091 if (IS_ADR_TYPE(v->type)) {
1092 if (AVAIL_FREE_TMP_ADR) {
1093 TAKE_FREE_TMP_ADR(v->vv.regoff);
1096 else if (AVAIL_TMP_ADR) {
1097 TAKE_TMP_ADR(v->vv.regoff);
1104 if (IS_FLT_DBL_TYPE(v->type)) {
1105 if (AVAIL_FREE_ARG_FLT) {
1107 TAKE_FREE_ARG_FLT(v->vv.regoff);
1110 else if (AVAIL_ARG_FLT) {
1112 TAKE_ARG_FLT(v->vv.regoff);
1115 else if (AVAIL_FREE_TMP_FLT) {
1116 TAKE_FREE_TMP_FLT(v->vv.regoff);
1119 else if (AVAIL_TMP_FLT) {
1120 TAKE_TMP_FLT(v->vv.regoff);
1126 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1128 * for i386 put all longs in memory
1130 if (!IS_2_WORD_TYPE(v->type))
1133 if (AVAIL_FREE_ARG_INT) {
1135 TAKE_FREE_ARG_INT(v->vv.regoff);
1138 else if (AVAIL_ARG_INT) {
1140 TAKE_ARG_INT(v->vv.regoff);
1143 else if (AVAIL_FREE_TMP_INT) {
1144 TAKE_FREE_TMP_INT(v->vv.regoff);
1147 else if (AVAIL_TMP_INT) {
1148 TAKE_TMP_INT(v->vv.regoff);
1151 } /* if (!IS_2_WORD_TYPE(s->type)) */
1152 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1153 } /* if (IS_ADR_TYPE(s->type)) */
1154 } /* if (tryagain == 1) else */
1155 } /* for(; tryagain; --tryagain) */
1157 #if defined(HAS_4BYTE_STACKSLOT)
1158 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
1159 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1162 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1163 if ((memneeded == 0) && (rd->freememtop > 0)) {
1164 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1167 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
1168 /* align 2 Word Types */
1169 if ((memneeded) && ((rd->memuse & 1) == 1)) {
1170 /* Put patched memory slot on freemem */
1171 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse);
1174 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
1175 v->vv.regoff = rd->memuse;
1176 rd->memuse += memneeded + 1;
1178 v->flags |= INMEMORY;
1182 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1184 /* if this is a copy of another variable, just decrement the copy counter */
1186 /* XXX split reg/mem variables on arm may need special handling here */
1188 if (flags & INMEMORY) {
1192 if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
1193 rd->memcopycount[regoff]--;
1200 regindex = SIMPLEREG_REG_INDEX(regoff, type);
1202 /* do not free interface registers that are needed as outvars */
1204 if (flags & INOUT) {
1205 if (rd->regisoutvar[regindex]) {
1206 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1210 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1213 if (rd->regcopycount[regindex]) {
1214 rd->regcopycount[regindex]--;
1219 if (flags & INMEMORY) {
1220 #if defined(HAS_4BYTE_STACKSLOT)
1221 if (IS_2_WORD_TYPE(type))
1222 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1225 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1230 /* freeing a register */
1232 #ifdef HAS_ADDRESS_REGISTER_FILE
1233 if (IS_ADR_TYPE(type)) {
1234 if (flags & (SAVEDVAR | SAVREG))
1235 PUSH_FREE_SAV_ADR(regoff);
1237 PUSH_FREE_TMP_ADR(regoff);
1240 else if (IS_FLT_DBL_TYPE(type)) {
1241 if (flags & (SAVEDVAR | SAVREG))
1242 PUSH_FREE_SAV_FLT(regoff);
1243 else if (flags & ARGREG)
1244 PUSH_FREE_ARG_FLT(regoff);
1246 PUSH_FREE_TMP_FLT(regoff);
1248 else { /* IS_INT_LNG_TYPE */
1249 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1250 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1253 if (flags & (SAVEDVAR | SAVREG))
1254 PUSH_FREE_SAV_INT(regoff);
1255 else if (flags & ARGREG)
1256 PUSH_FREE_ARG_INT(regoff);
1258 PUSH_FREE_TMP_INT(regoff);
1263 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1269 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1273 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1278 /* do not coalesce local variables here */
1280 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1286 /* do not coalesce in/out vars or preallocated variables here */
1288 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1291 /* if the source is in memory, we can coalesce in any case */
1293 if (sv->flags & INMEMORY) {
1294 dv->flags |= INMEMORY;
1295 dv->vv.regoff = sv->vv.regoff;
1299 /* we do not allocate a REG_TMP to a REG_SAV variable */
1301 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1305 dv->vv.regoff = sv->vv.regoff;
1306 dv->flags |= sv->flags & (SAVREG | ARGREG);
1312 /* simplereg_allocate_temporaries **********************************************
1314 Allocate temporary (non-interface, non-local) registers.
1316 *******************************************************************************/
1318 static void simplereg_allocate_temporaries(jitdata *jd)
1326 builtintable_entry *bte;
1335 /* get required compiler data */
1340 /* initialize temp registers */
1342 simplereg_init(jd, rd);
1344 bptr = jd->basicblocks;
1346 while (bptr != NULL) {
1347 if (bptr->flags >= BBREACHED) {
1349 LOG(("\nallocating block L%03d\n", bptr->nr));
1351 simplereg_init_block(rd);
1353 /* assert that all copy counts are zero */
1355 #if !defined(NDEBUG)
1356 for (i=0; i < INT_REG_CNT + FLT_REG_CNT; ++i)
1357 assert(rd->regcopycount[i] == 0);
1360 /* reset outvar flags */
1362 MZERO(rd->regisoutvar, int, INT_REG_CNT + FLT_REG_CNT);
1364 /* set allocation of invars */
1366 for (i=0; i<bptr->indepth; ++i)
1368 v = VAR(bptr->invars[i]);
1370 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1371 v->flags = jd->interface_map[5*i + v->type].flags;
1373 if (!(v->flags & INMEMORY))
1374 rd->regcopycount[SIMPLEREG_REG_INDEX(v->vv.regoff, v->type)] = 1;
1377 /* set allocation of outvars */
1379 for (i=0; i<bptr->outdepth; ++i)
1381 v = VAR(bptr->outvars[i]);
1383 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1384 v->flags = jd->interface_map[5*i + v->type].flags;
1386 if (!(v->flags & INMEMORY)) {
1387 regindex = SIMPLEREG_REG_INDEX(v->vv.regoff, v->type);
1388 rd->regcopycount[regindex] = 1;
1389 rd->regisoutvar[regindex] = 1;
1393 /* free interface registers not used in this block */
1395 for (i=0; i < 5 * m->maxstack; ++i) {
1397 regoff = jd->interface_map[i].regoff;
1398 flags = jd->interface_map[i].flags;
1400 if (!(flags & INMEMORY)) {
1401 if (!rd->regcopycount[SIMPLEREG_REG_INDEX(regoff, type)]) {
1402 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1403 flags, regoff, type));
1404 simplereg_free(rd, flags, regoff, type);
1406 /* mark it, so it is not freed again */
1407 rd->regcopycount[SIMPLEREG_REG_INDEX(regoff, type)] = -1;
1412 /* reset copy counts */
1414 for (i=0; i < INT_REG_CNT + FLT_REG_CNT; ++i)
1415 rd->regcopycount[i] = 0;
1417 /* iterate over ICMDS to allocate temporary variables */
1419 iptr = bptr->iinstr;
1422 while (--len >= 0) {
1424 switch (iptr->opc) {
1429 #if !defined(NDEBUG)
1430 /* avoid problems with show_allocation */
1431 VAROP(iptr->dst)->vv.regoff = 0;
1434 case ICMD_CHECKNULL:
1439 case ICMD_PUTSTATICCONST:
1440 case ICMD_INLINE_START:
1441 case ICMD_INLINE_END:
1442 case ICMD_INLINE_GOTO:
1445 /* pop 0 push 1 const */
1453 /* pop 0 push 1 load */
1460 NEW_TEMP_REG(iptr->dst.varindex);
1474 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1475 FREE_TEMP_REG(iptr->s1.varindex);
1476 NEW_TEMP_REG(iptr->dst.varindex);
1490 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1491 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1492 FREE_TEMP_REG(iptr->s1.varindex);
1495 /* pop 1 push 0 store */
1515 case ICMD_PUTSTATIC:
1516 case ICMD_PUTFIELDCONST:
1518 /* pop 1 push 0 branch */
1521 case ICMD_IFNONNULL:
1537 /* pop 1 push 0 table branch */
1539 case ICMD_TABLESWITCH:
1540 case ICMD_LOOKUPSWITCH:
1542 case ICMD_MONITORENTER:
1543 case ICMD_MONITOREXIT:
1544 FREE_TEMP_REG(iptr->s1.varindex);
1547 /* pop 2 push 0 branch */
1549 case ICMD_IF_ICMPEQ:
1550 case ICMD_IF_ICMPNE:
1551 case ICMD_IF_ICMPLT:
1552 case ICMD_IF_ICMPGE:
1553 case ICMD_IF_ICMPGT:
1554 case ICMD_IF_ICMPLE:
1556 case ICMD_IF_LCMPEQ:
1557 case ICMD_IF_LCMPNE:
1558 case ICMD_IF_LCMPLT:
1559 case ICMD_IF_LCMPGE:
1560 case ICMD_IF_LCMPGT:
1561 case ICMD_IF_LCMPLE:
1563 case ICMD_IF_FCMPEQ:
1564 case ICMD_IF_FCMPNE:
1566 case ICMD_IF_FCMPL_LT:
1567 case ICMD_IF_FCMPL_GE:
1568 case ICMD_IF_FCMPL_GT:
1569 case ICMD_IF_FCMPL_LE:
1571 case ICMD_IF_FCMPG_LT:
1572 case ICMD_IF_FCMPG_GE:
1573 case ICMD_IF_FCMPG_GT:
1574 case ICMD_IF_FCMPG_LE:
1576 case ICMD_IF_DCMPEQ:
1577 case ICMD_IF_DCMPNE:
1579 case ICMD_IF_DCMPL_LT:
1580 case ICMD_IF_DCMPL_GE:
1581 case ICMD_IF_DCMPL_GT:
1582 case ICMD_IF_DCMPL_LE:
1584 case ICMD_IF_DCMPG_LT:
1585 case ICMD_IF_DCMPG_GE:
1586 case ICMD_IF_DCMPG_GT:
1587 case ICMD_IF_DCMPG_LE:
1589 case ICMD_IF_ACMPEQ:
1590 case ICMD_IF_ACMPNE:
1598 case ICMD_IASTORECONST:
1599 case ICMD_LASTORECONST:
1600 case ICMD_AASTORECONST:
1601 case ICMD_BASTORECONST:
1602 case ICMD_CASTORECONST:
1603 case ICMD_SASTORECONST:
1604 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1605 FREE_TEMP_REG(iptr->s1.varindex);
1608 /* pop 0 push 1 copy */
1611 /* src === dst->prev (identical Stackslot Element) */
1612 /* src --> dst (copied value, take same reg/mem) */
1614 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1615 NEW_TEMP_REG(iptr->dst.varindex);
1618 v = VAROP(iptr->dst);
1620 if (v->flags & INMEMORY) {
1621 if (v->vv.regoff >= rd->memcopycountsize) {
1622 int newsize = (v->vv.regoff + 1) * 2;
1623 i = rd->memcopycountsize;
1624 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1625 MZERO(rd->memcopycount + i, int, newsize - i);
1626 rd->memcopycountsize = newsize;
1628 rd->memcopycount[v->vv.regoff]++;
1631 /* XXX split reg/mem variables on arm may need special handling here */
1633 s4 regindex = SIMPLEREG_REG_INDEX(v->vv.regoff, v->type);
1635 rd->regcopycount[regindex]++;
1640 /* pop 1 push 1 move */
1643 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1644 NEW_TEMP_REG(iptr->dst.varindex);
1645 FREE_TEMP_REG(iptr->s1.varindex);
1695 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1696 FREE_TEMP_REG(iptr->s1.varindex);
1697 NEW_TEMP_REG(iptr->dst.varindex);
1702 case ICMD_IADDCONST:
1703 case ICMD_ISUBCONST:
1704 case ICMD_IMULCONST:
1708 case ICMD_IANDCONST:
1710 case ICMD_IXORCONST:
1711 case ICMD_ISHLCONST:
1712 case ICMD_ISHRCONST:
1713 case ICMD_IUSHRCONST:
1715 case ICMD_LADDCONST:
1716 case ICMD_LSUBCONST:
1717 case ICMD_LMULCONST:
1721 case ICMD_LANDCONST:
1723 case ICMD_LXORCONST:
1724 case ICMD_LSHLCONST:
1725 case ICMD_LSHRCONST:
1726 case ICMD_LUSHRCONST:
1731 case ICMD_INT2SHORT:
1749 case ICMD_CHECKCAST:
1751 case ICMD_ARRAYLENGTH:
1752 case ICMD_INSTANCEOF:
1755 case ICMD_ANEWARRAY:
1758 FREE_TEMP_REG(iptr->s1.varindex);
1759 NEW_TEMP_REG(iptr->dst.varindex);
1764 case ICMD_GETSTATIC:
1767 NEW_TEMP_REG(iptr->dst.varindex);
1770 /* pop many push any */
1772 case ICMD_INVOKESTATIC:
1773 case ICMD_INVOKESPECIAL:
1774 case ICMD_INVOKEVIRTUAL:
1775 case ICMD_INVOKEINTERFACE:
1776 INSTRUCTION_GET_METHODDESC(iptr,md);
1778 argp = iptr->sx.s23.s2.args;
1780 FREE_TEMP_REG(*argp);
1783 if (md->returntype.type != TYPE_VOID)
1784 NEW_TEMP_REG(iptr->dst.varindex);
1788 bte = iptr->sx.s23.s3.bte;
1791 argp = iptr->sx.s23.s2.args;
1793 FREE_TEMP_REG(*argp);
1796 if (md->returntype.type != TYPE_VOID)
1797 NEW_TEMP_REG(iptr->dst.varindex);
1800 case ICMD_MULTIANEWARRAY:
1801 i = iptr->s1.argcount;
1802 argp = iptr->sx.s23.s2.args;
1804 FREE_TEMP_REG(*argp);
1807 NEW_TEMP_REG(iptr->dst.varindex);
1812 new_internalerror("Unknown ICMD %d during register allocation",
1817 } /* while instructions */
1820 } /* while blocks */
1824 #if defined(ENABLE_STATISTICS)
1825 void simplereg_make_statistics(jitdata *jd)
1832 stackptr src, src_old;
1836 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1840 /* get required compiler data */
1850 /* count how many local variables are held in memory or register */
1851 for(i=0; i < jd->localcount; i++) {
1852 if (VAR(i)->flags & INMEMORY) {
1853 count_locals_spilled++;
1857 count_locals_register++;
1861 /* count how many stack slots are held in memory or register */
1863 bptr = jd->basicblocks;
1865 while (bptr != NULL) {
1866 if (bptr->flags >= BBREACHED) {
1868 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1871 /* check for memory moves from interface to BB instack */
1872 len = bptr->indepth;
1874 if (len > size_interface) size_interface = len;
1878 var = VAR(bptr->invars[len]);
1880 /* invars statistics (currently none) */
1883 /* check for memory moves from BB outstack to interface */
1884 len = bptr->outdepth;
1885 if (len > size_interface) size_interface = len;
1889 var = VAR(bptr->outvars[len]);
1891 /* outvars statistics (currently none) */
1893 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1899 dst = bptr->instack;
1900 iptr = bptr->iinstr;
1904 while (--len >= 0) {
1906 dst = iptr->dst.var;
1908 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1909 switch (src->varkind) {
1912 if (!(src->flags & INMEMORY))
1913 count_ss_register++;
1919 /* case LOCALVAR: */
1920 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1921 /* count_ss_register++; */
1923 /* count_ss_spilled++; */
1926 if (!(src->flags & INMEMORY))
1927 count_argument_mem_ss++;
1929 count_argument_reg_ss++;
1933 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1934 /* if (src->varnum < FLT_ARG_CNT) { */
1935 /* count_ss_register++; */
1939 /* #if defined(__POWERPC__) */
1940 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1942 /* if (src->varnum < INT_ARG_CNT) { */
1944 /* count_ss_register++; */
1948 /* count_ss_spilled++; */
1955 } /* while instructions */
1960 } /* while blocks */
1962 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1963 if (in_register) count_method_in_register++;
1965 printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1968 #endif /* defined(ENABLE_STATISTICS) */
1972 * These are local overrides for various environment variables in Emacs.
1973 * Please do not remove this and leave it at the end of the file, where
1974 * Emacs will automagically detect them.
1975 * ---------------------------------------------------------------------
1978 * indent-tabs-mode: t
1982 * vim:noexpandtab:sw=4:ts=4: