1 /* src/vm/jit/allocator/simplereg.c - register allocator
3 Copyright (C) 1996-2005, 2007 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
34 $Id: simplereg.c 6286 2007-01-10 10:03:38Z twisti $
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "mm/memory.h"
50 #include "vm/method.h"
51 #include "vm/options.h"
52 #include "vm/resolve.h"
53 #include "vm/stringlocal.h"
54 #include "vm/jit/reg.h"
55 #include "vm/jit/allocator/simplereg.h"
56 #include "vm/jit/show.h"
60 # define LOG(args) printf args
66 /* function prototypes for this file ******************************************/
68 static void simplereg_allocate_interfaces(jitdata *jd);
69 static void simplereg_allocate_locals(jitdata *jd);
70 static void simplereg_allocate_temporaries(jitdata *jd);
73 /* total number of registers */
75 #if defined(HAS_ADDRESS_REGISTER_FILE)
76 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
78 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
82 /* macros for handling register stacks ****************************************/
84 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
85 #define AVAIL_BACK(cnt) ((cnt) > 0)
87 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
88 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
89 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
91 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
92 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
95 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
96 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
97 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
98 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
100 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
101 #define POP_FRONT_INT(stk, cnt, reg) \
103 if (intregsneeded) { \
104 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
108 POP_FRONT(stk, cnt, reg); \
111 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
114 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
115 #define POP_BACK_INT(stk, cnt, reg) \
117 if (intregsneeded) { \
119 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
122 POP_BACK(stk, cnt, reg); \
125 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
128 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
129 #define PUSH_BACK_INT(stk, cnt, reg) \
131 if (intregsneeded) { \
132 stk[cnt] = GET_LOW_REG(reg); \
133 stk[cnt + 1] = GET_HIGH_REG(reg); \
137 PUSH_BACK(stk, cnt, reg); \
140 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
143 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
144 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
145 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
147 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
148 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
149 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
151 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
152 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
153 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
155 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
156 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
157 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
159 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
160 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
161 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
163 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
164 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
165 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
167 #define TAKE_ARG_FLT(r) POP_FRONT(rd->argfltregs, rd->argfltreguse, r)
168 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
169 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
171 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
172 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
173 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
175 #define TAKE_ARG_INT(r) POP_FRONT_INT(rd->argintregs, rd->argintreguse, r)
176 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
177 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
179 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
180 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
181 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
183 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
184 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
185 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
187 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
188 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
189 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
191 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
192 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
193 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
195 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
196 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
197 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
199 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
200 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
201 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
204 /* macros for allocating memory slots ****************************************/
206 #define NEW_MEM_SLOT(r) \
209 rd->memuse += memneeded + 1; \
212 #define NEW_MEM_SLOT_ALIGNED(r) \
214 if ( (memneeded) && (rd->memuse & 1)) \
217 rd->memuse += memneeded + 1; \
220 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r) \
222 if ( (memneeded) && (rd->memuse & 1)) { \
223 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
227 rd->memuse += memneeded + 1; \
230 #if defined(ALIGN_LONGS_IN_MEMORY)
231 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT_ALIGNED(r)
233 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
236 #if defined(ALIGN_DOUBLES_IN_MEMORY)
237 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT_ALIGNED(r)
239 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
242 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
243 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
245 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
249 /* macros for creating/freeing temporary variables ***************************/
251 #define NEW_TEMP_REG(index) \
252 if ( ((index) >= jd->localcount) \
253 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
254 simplereg_new_temp(jd, (index))
257 #define FREE_TEMP_REG(index) \
258 if (((index) > jd->localcount) \
259 && (!(VAR(index)->flags & (PREALLOC)))) \
260 simplereg_free_temp(jd, (index))
263 /* macro for getting a unique register index *********************************/
265 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
266 #define REG_INDEX_NON_ADR(regoff, type) \
267 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
269 #define REG_INDEX_NON_ADR(regoff, type) \
270 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
273 #if defined(HAS_ADDRESS_REGISTER_FILE)
274 #define REG_INDEX(regoff, type) \
275 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
277 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
281 /* regalloc ********************************************************************
283 Does a simple register allocation.
285 *******************************************************************************/
287 bool regalloc(jitdata *jd)
289 /* There is a problem with the use of unused float argument
290 registers in leafmethods for stackslots on c7 (2 * Dual Core
291 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
292 benchmark is heaviliy increased. This could be prevented by
293 setting rd->argfltreguse to FLT_ARG_CNT before calling
294 simplereg_allocate_temporaries and setting it back to the original
295 value before calling simplereg_allocate_locals. */
297 simplereg_allocate_interfaces(jd);
298 simplereg_allocate_temporaries(jd);
299 simplereg_allocate_locals(jd);
307 /* simplereg_allocate_interfaces ***********************************************
309 Allocates registers for all interface variables.
311 *******************************************************************************/
313 static void simplereg_allocate_interfaces(jitdata *jd)
320 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
321 /* in case more vars are packed into this interface slot */
323 /* Allocate LNG and DBL types first to ensure 2 memory slots or */
324 /* registers on HAS_4BYTE_STACKSLOT architectures. */
325 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
327 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
331 /* get required compiler data */
337 /* rd->memuse was already set in stack.c to allocate stack space
338 for passing arguments to called methods. */
340 #if defined(__I386__)
341 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
342 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
348 if (jd->isleafmethod) {
349 /* Reserve argument register, which will be used for Locals acting */
351 if (rd->argintreguse < m->parseddesc->argintreguse)
352 rd->argintreguse = m->parseddesc->argintreguse;
353 if (rd->argfltreguse < m->parseddesc->argfltreguse)
354 rd->argfltreguse = m->parseddesc->argfltreguse;
355 #ifdef HAS_ADDRESS_REGISTER_FILE
356 if (rd->argadrreguse < m->parseddesc->argadrreguse)
357 rd->argadrreguse = m->parseddesc->argadrreguse;
361 for (s = 0; s < jd->maxinterfaces; s++) {
362 intalloc = -1; fltalloc = -1;
364 /* check if the interface at this stack depth must be a SAVEDVAR */
368 for (tt = 0; tt <=4; tt++) {
369 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
370 saved |= t & SAVEDVAR;
374 /* allocate reg/mem for each type the interface is used as */
376 for (tt = 0; tt <= 4; tt++) {
378 if (jd->interface_map[s * 5 + t].flags == UNUSED)
382 regoff = -1; /* initialize to invalid value */
384 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
385 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
388 #if defined(HAS_4BYTE_STACKSLOT)
389 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
393 #if defined(HAS_ADDRESS_REGISTER_FILE)
394 if (IS_ADR_TYPE(t)) {
395 if (!jd->isleafmethod && AVAIL_ARG_ADR) {
397 TAKE_ARG_ADR(regoff);
399 else if (AVAIL_TMP_ADR) {
400 TAKE_TMP_ADR(regoff);
402 else if (AVAIL_SAV_ADR) {
404 TAKE_SAV_ADR(regoff);
408 regoff = rd->memuse++;
411 else /* !IS_ADR_TYPE */
412 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
414 if (IS_FLT_DBL_TYPE(t)) {
416 /* Reuse memory slot(s)/register(s) for shared interface slots */
417 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
418 regoff = jd->interface_map[fltalloc].regoff;
420 else if (AVAIL_ARG_FLT) {
422 TAKE_ARG_FLT(regoff);
424 else if (AVAIL_TMP_FLT) {
425 TAKE_TMP_FLT(regoff);
427 else if (AVAIL_SAV_FLT) {
429 TAKE_SAV_FLT(regoff);
433 NEW_MEM_SLOT_FLT_DBL(regoff);
435 fltalloc = s * 5 + t;
437 else { /* !IS_FLT_DBL_TYPE(t) */
438 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
440 * for i386 put all longs in memory
442 if (IS_2_WORD_TYPE(t)) {
444 NEW_MEM_SLOT_INT_LNG(regoff);
447 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
449 /* Reuse memory slot(s)/register(s) for shared interface slots */
450 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
451 regoff = jd->interface_map[intalloc].regoff;
452 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
453 /* reuse lower half */
454 if (!(flags & INMEMORY)
455 && IS_2_WORD_TYPE(intalloc % 5))
456 regoff = GET_LOW_REG(regoff);
462 TAKE_ARG_INT(regoff);
464 else if (AVAIL_TMP_INT) {
465 TAKE_TMP_INT(regoff);
467 else if (AVAIL_SAV_INT) {
469 TAKE_SAV_INT(regoff);
473 NEW_MEM_SLOT_INT_LNG(regoff);
477 intalloc = s * 5 + t;
478 } /* if (IS_FLT_DBL_TYPE(t)) */
482 /* now the same like above, but without a chance to take a temporary register */
483 #ifdef HAS_ADDRESS_REGISTER_FILE
484 if (IS_ADR_TYPE(t)) {
486 TAKE_SAV_ADR(regoff);
490 regoff = rd->memuse++;
496 if (IS_FLT_DBL_TYPE(t)) {
498 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
499 regoff = jd->interface_map[fltalloc].regoff;
503 TAKE_SAV_FLT(regoff);
507 NEW_MEM_SLOT_FLT_DBL(regoff);
510 fltalloc = s * 5 + t;
512 else { /* IS_INT_LNG */
513 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
515 * for i386 put all longs in memory
517 if (IS_2_WORD_TYPE(t)) {
519 NEW_MEM_SLOT_INT_LNG(regoff);
525 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
526 regoff = jd->interface_map[intalloc].regoff;
527 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
528 /* reuse lower half */
529 if (!(flags & INMEMORY)
530 && IS_2_WORD_TYPE(intalloc % 5))
531 regoff = GET_LOW_REG(regoff);
536 TAKE_SAV_INT(regoff);
540 NEW_MEM_SLOT_INT_LNG(regoff);
545 } /* if (IS_FLT_DBL_TYPE(t) else */
546 } /* if (IS_ADR_TYPE(t)) else */
547 } /* if (saved) else */
551 jd->interface_map[5*s + t].flags = flags | INOUT;
552 jd->interface_map[5*s + t].regoff = regoff;
558 /* simplereg_allocate_locals_leafmethod ****************************************
560 Allocates registers for all local variables of a leafmethod.
562 *******************************************************************************/
564 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
572 int intalloc, fltalloc;
574 int intregsneeded = 0;
576 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
577 int fargcnt, iargcnt;
578 #ifdef HAS_ADDRESS_REGISTER_FILE
582 /* get required compiler data */
590 iargcnt = rd->argintreguse;
591 fargcnt = rd->argfltreguse;
592 #ifdef HAS_ADDRESS_REGISTER_FILE
593 aargcnt = rd->argadrreguse;
595 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
596 intalloc = -1; fltalloc = -1;
597 for (tt = 0; tt <= 4; tt++) {
599 lm = jd->local_map[s * 5 + t];
605 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
606 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
608 #if defined(HAS_4BYTE_STACKSLOT)
609 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
615 * #ifdef HAS_ADDRESS_REGISTER_FILE
622 * } else { / int & lng
626 * must not to be changed!
629 #ifdef HAS_ADDRESS_REGISTER_FILE
630 if (IS_ADR_TYPE(t)) {
631 if ((p < md->paramcount) && !md->params[p].inmemory) {
633 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
635 else if (AVAIL_TMP_ADR) {
637 TAKE_TMP_ADR(v->vv.regoff);
639 /* use unused argument registers as local registers */
640 else if ((p >= md->paramcount) &&
641 (aargcnt < ADR_ARG_CNT))
644 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
646 else if (AVAIL_SAV_ADR) {
648 TAKE_SAV_ADR(v->vv.regoff);
651 v->flags |= INMEMORY;
652 v->vv.regoff = rd->memuse++;
657 if (IS_FLT_DBL_TYPE(t)) {
659 v->flags = VAR(fltalloc)->flags;
660 v->vv.regoff = VAR(fltalloc)->vv.regoff;
662 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
663 /* We can only use float arguments as local variables,
664 * if we do not pass them in integer registers. */
665 else if ((p < md->paramcount) &&
666 !md->params[p].inmemory)
669 v->vv.regoff = rd->argfltregs[md->params[p].regoff];
672 else if (AVAIL_TMP_FLT) {
674 TAKE_TMP_FLT(v->vv.regoff);
676 /* use unused argument registers as local registers */
677 else if ((p >= md->paramcount) &&
678 (fargcnt < FLT_ARG_CNT))
681 POP_FRONT(rd->argfltregs, fargcnt, v->vv.regoff);
683 else if (AVAIL_SAV_FLT) {
685 TAKE_SAV_FLT(v->vv.regoff);
689 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
691 fltalloc = jd->local_map[s * 5 + t];
695 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
697 * for i386 put all longs in memory
699 if (IS_2_WORD_TYPE(t)) {
701 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
707 v->flags = VAR(intalloc)->flags;
708 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
709 if (!(v->flags & INMEMORY)
710 && IS_2_WORD_TYPE(VAR(intalloc)->type))
711 v->vv.regoff = GET_LOW_REG(
712 VAR(intalloc)->vv.regoff);
715 v->vv.regoff = VAR(intalloc)->vv.regoff;
717 else if ((p < md->paramcount) &&
718 !md->params[p].inmemory)
721 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
722 if (IS_2_WORD_TYPE(t))
723 v->vv.regoff = PACK_REGS(
724 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
725 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
729 rd->argintregs[md->params[p].regoff];
731 else if (AVAIL_TMP_INT) {
733 TAKE_TMP_INT(v->vv.regoff);
736 * use unused argument registers as local registers
738 else if ((p >= m->parseddesc->paramcount) &&
739 (iargcnt + intregsneeded < INT_ARG_CNT))
742 POP_FRONT_INT(rd->argintregs, iargcnt, v->vv.regoff);
744 else if (AVAIL_SAV_INT) {
746 TAKE_SAV_INT(v->vv.regoff);
750 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
753 intalloc = jd->local_map[s * 5 + t];
755 #ifdef HAS_ADDRESS_REGISTER_FILE
758 } /* for (tt=0;...) */
760 /* If the current parameter is a 2-word type, the next local slot */
763 if (p < md->paramcount)
764 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
769 /* simplereg_allocate_locals ***************************************************
771 Allocates registers for all local variables.
773 *******************************************************************************/
775 static void simplereg_allocate_locals(jitdata *jd)
781 int intalloc, fltalloc;
784 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
785 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
789 /* get required compiler data */
794 if (jd->isleafmethod) {
795 simplereg_allocate_locals_leafmethod(jd);
799 for (s = 0; s < jd->maxlocals; s++) {
800 intalloc = -1; fltalloc = -1;
801 for (tt=0; tt<=4; tt++) {
804 lm = jd->local_map[s * 5 + t];
810 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
811 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
814 #if defined(HAS_4BYTE_STACKSLOT)
815 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
818 #ifdef HAS_ADDRESS_REGISTER_FILE
819 if (IS_ADR_TYPE(t)) {
822 TAKE_SAV_ADR(v->vv.regoff);
826 v->vv.regoff = rd->memuse++;
831 if (IS_FLT_DBL_TYPE(t)) {
833 v->flags = VAR(fltalloc)->flags;
834 v->vv.regoff = VAR(fltalloc)->vv.regoff;
836 else if (AVAIL_SAV_FLT) {
838 TAKE_SAV_FLT(v->vv.regoff);
842 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
844 fltalloc = jd->local_map[s * 5 + t];
847 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
849 * for i386 put all longs in memory
851 if (IS_2_WORD_TYPE(t)) {
853 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
858 v->flags = VAR(intalloc)->flags;
859 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
860 if (!(v->flags & INMEMORY)
861 && IS_2_WORD_TYPE(VAR(intalloc)->type))
862 v->vv.regoff = GET_LOW_REG(
863 VAR(intalloc)->vv.regoff);
866 v->vv.regoff = VAR(intalloc)->vv.regoff;
868 else if (AVAIL_SAV_INT) {
870 TAKE_SAV_INT(v->vv.regoff);
874 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
876 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
879 intalloc = jd->local_map[s * 5 + t];
881 #ifdef HAS_ADDRESS_REGISTER_FILE
889 static void simplereg_init(jitdata *jd, registerdata *rd)
894 #if defined(HAS_4BYTE_STACKSLOT)
895 rd->freememtop_2 = 0;
898 rd->freetmpinttop = 0;
899 rd->freesavinttop = 0;
900 rd->freetmpflttop = 0;
901 rd->freesavflttop = 0;
902 #ifdef HAS_ADDRESS_REGISTER_FILE
903 rd->freetmpadrtop = 0;
904 rd->freesavadrtop = 0;
907 rd->freearginttop = 0;
908 rd->freeargflttop = 0;
909 #ifdef HAS_ADDRESS_REGISTER_FILE
910 rd->freeargadrtop = 0;
913 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
914 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
915 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
917 /* memcopycount is dynamically allocated when needed */
919 rd->memcopycount = NULL;
920 rd->memcopycountsize = 0;
922 rd->intusedinout = DMNEW(int, INT_REG_CNT);
923 MZERO(rd->intusedinout, int, INT_REG_CNT);
924 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
925 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
927 /* record the interface registers as used */
929 for (i=0; i<rd->argintreguse; ++i)
930 rd->intusedinout[rd->argintregs[i]] = 1;
931 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
932 rd->intusedinout[rd->tmpintregs[i]] = 1;
933 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
934 rd->intusedinout[rd->savintregs[i]] = 1;
936 for (i=0; i<rd->argfltreguse; ++i)
937 rd->fltusedinout[rd->argfltregs[i]] = 1;
938 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
939 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
940 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
941 rd->fltusedinout[rd->savfltregs[i]] = 1;
943 #ifdef HAS_ADDRESS_REGISTER_FILE
944 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
945 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
947 for (i=0; i<rd->argadrreguse; ++i)
948 rd->adrusedinout[rd->argadrregs[i]] = 1;
949 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
950 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
951 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
952 rd->adrusedinout[rd->savadrregs[i]] = 1;
957 static void simplereg_init_block(registerdata *rd)
961 /* remove all interface registers from the free lists */
963 for (i=0; i<rd->freearginttop; ++i)
964 if (rd->intusedinout[rd->freeargintregs[i]]) {
965 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
967 for (i=0; i<rd->freetmpinttop; ++i)
968 if (rd->intusedinout[rd->freetmpintregs[i]]) {
969 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
971 for (i=0; i<rd->freesavinttop; ++i)
972 if (rd->intusedinout[rd->freesavintregs[i]]) {
973 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
976 for (i=0; i<rd->freeargflttop; ++i)
977 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
978 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
980 for (i=0; i<rd->freetmpflttop; ++i)
981 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
982 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
984 for (i=0; i<rd->freesavflttop; ++i)
985 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
986 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
989 #ifdef HAS_ADDRESS_REGISTER_FILE
990 for (i=0; i<rd->freeargadrtop; ++i)
991 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
992 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
994 for (i=0; i<rd->freetmpadrtop; ++i)
995 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
996 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
998 for (i=0; i<rd->freesavadrtop; ++i)
999 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1000 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1006 static void simplereg_new_temp(jitdata *jd, s4 index)
1008 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1019 /* assert that constants are not allocated */
1021 assert(v->type != TYPE_RET);
1023 /* Try to allocate a saved register if there is no temporary one */
1024 /* available. This is what happens during the second run. */
1025 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1027 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1028 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1031 #if defined(HAS_4BYTE_STACKSLOT)
1032 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1037 for(; tryagain; --tryagain) {
1038 if (tryagain == 1) {
1039 if (!(v->flags & SAVEDVAR))
1041 #ifdef HAS_ADDRESS_REGISTER_FILE
1042 if (IS_ADR_TYPE(v->type)) {
1043 if (AVAIL_FREE_SAV_ADR) {
1044 TAKE_FREE_SAV_ADR(v->vv.regoff);
1047 else if (AVAIL_SAV_ADR) {
1048 TAKE_SAV_ADR(v->vv.regoff);
1055 if (IS_FLT_DBL_TYPE(v->type)) {
1056 if (AVAIL_FREE_SAV_FLT) {
1057 TAKE_FREE_SAV_FLT(v->vv.regoff);
1060 else if (AVAIL_SAV_FLT) {
1061 TAKE_SAV_FLT(v->vv.regoff);
1066 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1068 * for i386 put all longs in memory
1070 if (!IS_2_WORD_TYPE(v->type))
1073 if (AVAIL_FREE_SAV_INT) {
1074 TAKE_FREE_SAV_INT(v->vv.regoff);
1077 else if (AVAIL_SAV_INT) {
1078 TAKE_SAV_INT(v->vv.regoff);
1085 else { /* tryagain == 2 */
1086 #ifdef HAS_ADDRESS_REGISTER_FILE
1087 if (IS_ADR_TYPE(v->type)) {
1088 if (AVAIL_FREE_TMP_ADR) {
1089 TAKE_FREE_TMP_ADR(v->vv.regoff);
1092 else if (AVAIL_TMP_ADR) {
1093 TAKE_TMP_ADR(v->vv.regoff);
1100 if (IS_FLT_DBL_TYPE(v->type)) {
1101 if (AVAIL_FREE_ARG_FLT) {
1103 TAKE_FREE_ARG_FLT(v->vv.regoff);
1106 else if (AVAIL_ARG_FLT) {
1108 TAKE_ARG_FLT(v->vv.regoff);
1111 else if (AVAIL_FREE_TMP_FLT) {
1112 TAKE_FREE_TMP_FLT(v->vv.regoff);
1115 else if (AVAIL_TMP_FLT) {
1116 TAKE_TMP_FLT(v->vv.regoff);
1122 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1124 * for i386 put all longs in memory
1126 if (!IS_2_WORD_TYPE(v->type))
1129 if (AVAIL_FREE_ARG_INT) {
1131 TAKE_FREE_ARG_INT(v->vv.regoff);
1134 else if (AVAIL_ARG_INT) {
1136 TAKE_ARG_INT(v->vv.regoff);
1139 else if (AVAIL_FREE_TMP_INT) {
1140 TAKE_FREE_TMP_INT(v->vv.regoff);
1143 else if (AVAIL_TMP_INT) {
1144 TAKE_TMP_INT(v->vv.regoff);
1147 } /* if (!IS_2_WORD_TYPE(s->type)) */
1148 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1149 } /* if (IS_ADR_TYPE(s->type)) */
1150 } /* if (tryagain == 1) else */
1151 } /* for(; tryagain; --tryagain) */
1153 /* spill to memory */
1155 v->flags |= INMEMORY;
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);
1161 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1162 if ((memneeded == 0) && (rd->freememtop > 0))
1163 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1165 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1169 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1171 /* assert that constants are not freed */
1173 assert(type != TYPE_RET);
1175 /* if this is a copy of another variable, just decrement the copy counter */
1177 /* XXX split reg/mem variables on arm may need special handling here */
1179 if (flags & INMEMORY) {
1183 if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
1184 rd->memcopycount[regoff]--;
1191 regindex = REG_INDEX(regoff, type);
1193 /* do not free interface registers that are needed as outvars */
1195 if (flags & INOUT) {
1196 if (rd->regisoutvar[regindex]) {
1197 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1201 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1204 if (rd->regcopycount[regindex]) {
1205 rd->regcopycount[regindex]--;
1210 if (flags & INMEMORY) {
1211 #if defined(HAS_4BYTE_STACKSLOT)
1212 if (IS_2_WORD_TYPE(type))
1213 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1216 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1221 /* freeing a register */
1223 #ifdef HAS_ADDRESS_REGISTER_FILE
1224 if (IS_ADR_TYPE(type)) {
1225 if (flags & (SAVEDVAR | SAVREG))
1226 PUSH_FREE_SAV_ADR(regoff);
1228 PUSH_FREE_TMP_ADR(regoff);
1231 else if (IS_FLT_DBL_TYPE(type)) {
1232 if (flags & (SAVEDVAR | SAVREG))
1233 PUSH_FREE_SAV_FLT(regoff);
1234 else if (flags & ARGREG)
1235 PUSH_FREE_ARG_FLT(regoff);
1237 PUSH_FREE_TMP_FLT(regoff);
1239 else { /* IS_INT_LNG_TYPE */
1240 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1241 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1244 if (flags & (SAVEDVAR | SAVREG))
1245 PUSH_FREE_SAV_INT(regoff);
1246 else if (flags & ARGREG)
1247 PUSH_FREE_ARG_INT(regoff);
1249 PUSH_FREE_TMP_INT(regoff);
1254 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1260 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1264 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1269 /* do not coalesce local variables here */
1271 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1277 /* do not coalesce in/out vars or preallocated variables here */
1279 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1282 /* if the source is in memory, we can coalesce in any case */
1284 if (sv->flags & INMEMORY) {
1285 dv->flags |= INMEMORY;
1286 dv->vv.regoff = sv->vv.regoff;
1290 /* we do not allocate a REG_TMP to a REG_SAV variable */
1292 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1296 dv->vv.regoff = sv->vv.regoff;
1297 dv->flags |= sv->flags & (SAVREG | ARGREG);
1303 /* simplereg_allocate_temporaries **********************************************
1305 Allocate temporary (non-interface, non-local) registers.
1307 *******************************************************************************/
1309 static void simplereg_allocate_temporaries(jitdata *jd)
1317 builtintable_entry *bte;
1326 /* get required compiler data */
1331 /* initialize temp registers */
1333 simplereg_init(jd, rd);
1335 bptr = jd->basicblocks;
1337 while (bptr != NULL) {
1338 if (bptr->flags >= BBREACHED) {
1340 LOG(("\nallocating block L%03d\n", bptr->nr));
1342 simplereg_init_block(rd);
1344 /* assert that all copy counts are zero */
1346 #if !defined(NDEBUG)
1347 for (i=0; i < TOTAL_REG_CNT; ++i)
1348 assert(rd->regcopycount[i] == 0);
1351 /* reset outvar flags */
1353 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1355 /* set allocation of invars */
1357 for (i=0; i<bptr->indepth; ++i)
1359 v = VAR(bptr->invars[i]);
1360 if (v->type == TYPE_RET)
1363 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1364 v->flags = jd->interface_map[5*i + v->type].flags;
1366 if (!(v->flags & INMEMORY))
1367 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1370 /* set allocation of outvars */
1372 for (i=0; i<bptr->outdepth; ++i)
1374 v = VAR(bptr->outvars[i]);
1375 if (v->type == TYPE_RET)
1378 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1379 v->flags = jd->interface_map[5*i + v->type].flags;
1381 if (!(v->flags & INMEMORY)) {
1382 regindex = REG_INDEX(v->vv.regoff, v->type);
1383 rd->regcopycount[regindex] = 1;
1384 rd->regisoutvar[regindex] = 1;
1388 /* free interface registers not used in this block */
1390 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1392 regoff = jd->interface_map[i].regoff;
1393 flags = jd->interface_map[i].flags;
1395 if (!(flags & INMEMORY)) {
1396 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1397 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1398 flags, regoff, type));
1399 simplereg_free(rd, flags, regoff, type);
1401 /* mark it, so it is not freed again */
1402 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1407 /* reset copy counts */
1409 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1411 /* iterate over ICMDS to allocate temporary variables */
1413 iptr = bptr->iinstr;
1416 while (--len >= 0) {
1418 switch (iptr->opc) {
1424 case ICMD_CHECKNULL:
1429 case ICMD_PUTSTATICCONST:
1430 case ICMD_INLINE_START:
1431 case ICMD_INLINE_END:
1432 case ICMD_INLINE_BODY:
1435 /* pop 0 push 1 const */
1443 /* pop 0 push 1 load */
1450 NEW_TEMP_REG(iptr->dst.varindex);
1464 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1465 FREE_TEMP_REG(iptr->s1.varindex);
1466 NEW_TEMP_REG(iptr->dst.varindex);
1480 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1481 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1482 FREE_TEMP_REG(iptr->s1.varindex);
1485 /* pop 1 push 0 store */
1505 case ICMD_PUTSTATIC:
1506 case ICMD_PUTFIELDCONST:
1508 /* pop 1 push 0 branch */
1511 case ICMD_IFNONNULL:
1527 /* pop 1 push 0 table branch */
1529 case ICMD_TABLESWITCH:
1530 case ICMD_LOOKUPSWITCH:
1532 case ICMD_MONITORENTER:
1533 case ICMD_MONITOREXIT:
1534 FREE_TEMP_REG(iptr->s1.varindex);
1537 /* pop 2 push 0 branch */
1539 case ICMD_IF_ICMPEQ:
1540 case ICMD_IF_ICMPNE:
1541 case ICMD_IF_ICMPLT:
1542 case ICMD_IF_ICMPGE:
1543 case ICMD_IF_ICMPGT:
1544 case ICMD_IF_ICMPLE:
1546 case ICMD_IF_LCMPEQ:
1547 case ICMD_IF_LCMPNE:
1548 case ICMD_IF_LCMPLT:
1549 case ICMD_IF_LCMPGE:
1550 case ICMD_IF_LCMPGT:
1551 case ICMD_IF_LCMPLE:
1553 case ICMD_IF_FCMPEQ:
1554 case ICMD_IF_FCMPNE:
1556 case ICMD_IF_FCMPL_LT:
1557 case ICMD_IF_FCMPL_GE:
1558 case ICMD_IF_FCMPL_GT:
1559 case ICMD_IF_FCMPL_LE:
1561 case ICMD_IF_FCMPG_LT:
1562 case ICMD_IF_FCMPG_GE:
1563 case ICMD_IF_FCMPG_GT:
1564 case ICMD_IF_FCMPG_LE:
1566 case ICMD_IF_DCMPEQ:
1567 case ICMD_IF_DCMPNE:
1569 case ICMD_IF_DCMPL_LT:
1570 case ICMD_IF_DCMPL_GE:
1571 case ICMD_IF_DCMPL_GT:
1572 case ICMD_IF_DCMPL_LE:
1574 case ICMD_IF_DCMPG_LT:
1575 case ICMD_IF_DCMPG_GE:
1576 case ICMD_IF_DCMPG_GT:
1577 case ICMD_IF_DCMPG_LE:
1579 case ICMD_IF_ACMPEQ:
1580 case ICMD_IF_ACMPNE:
1588 case ICMD_IASTORECONST:
1589 case ICMD_LASTORECONST:
1590 case ICMD_AASTORECONST:
1591 case ICMD_BASTORECONST:
1592 case ICMD_CASTORECONST:
1593 case ICMD_SASTORECONST:
1594 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1595 FREE_TEMP_REG(iptr->s1.varindex);
1598 /* pop 0 push 1 copy */
1601 /* src === dst->prev (identical Stackslot Element) */
1602 /* src --> dst (copied value, take same reg/mem) */
1604 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1605 NEW_TEMP_REG(iptr->dst.varindex);
1608 v = VAROP(iptr->dst);
1610 if (v->flags & INMEMORY) {
1611 if (v->vv.regoff >= rd->memcopycountsize) {
1612 int newsize = (v->vv.regoff + 1) * 2;
1613 i = rd->memcopycountsize;
1614 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1615 MZERO(rd->memcopycount + i, int, newsize - i);
1616 rd->memcopycountsize = newsize;
1618 rd->memcopycount[v->vv.regoff]++;
1621 /* XXX split reg/mem variables on arm may need special handling here */
1623 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1625 rd->regcopycount[regindex]++;
1630 /* pop 1 push 1 move */
1633 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1634 NEW_TEMP_REG(iptr->dst.varindex);
1635 FREE_TEMP_REG(iptr->s1.varindex);
1685 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1686 FREE_TEMP_REG(iptr->s1.varindex);
1687 NEW_TEMP_REG(iptr->dst.varindex);
1692 case ICMD_IADDCONST:
1693 case ICMD_ISUBCONST:
1694 case ICMD_IMULCONST:
1698 case ICMD_IANDCONST:
1700 case ICMD_IXORCONST:
1701 case ICMD_ISHLCONST:
1702 case ICMD_ISHRCONST:
1703 case ICMD_IUSHRCONST:
1705 case ICMD_LADDCONST:
1706 case ICMD_LSUBCONST:
1707 case ICMD_LMULCONST:
1711 case ICMD_LANDCONST:
1713 case ICMD_LXORCONST:
1714 case ICMD_LSHLCONST:
1715 case ICMD_LSHRCONST:
1716 case ICMD_LUSHRCONST:
1721 case ICMD_INT2SHORT:
1739 case ICMD_CHECKCAST:
1741 case ICMD_ARRAYLENGTH:
1742 case ICMD_INSTANCEOF:
1745 case ICMD_ANEWARRAY:
1748 FREE_TEMP_REG(iptr->s1.varindex);
1749 NEW_TEMP_REG(iptr->dst.varindex);
1754 case ICMD_GETSTATIC:
1757 NEW_TEMP_REG(iptr->dst.varindex);
1760 /* pop many push any */
1762 case ICMD_INVOKESTATIC:
1763 case ICMD_INVOKESPECIAL:
1764 case ICMD_INVOKEVIRTUAL:
1765 case ICMD_INVOKEINTERFACE:
1766 INSTRUCTION_GET_METHODDESC(iptr,md);
1768 argp = iptr->sx.s23.s2.args;
1770 FREE_TEMP_REG(*argp);
1773 if (md->returntype.type != TYPE_VOID)
1774 NEW_TEMP_REG(iptr->dst.varindex);
1778 bte = iptr->sx.s23.s3.bte;
1781 argp = iptr->sx.s23.s2.args;
1783 FREE_TEMP_REG(*argp);
1786 if (md->returntype.type != TYPE_VOID)
1787 NEW_TEMP_REG(iptr->dst.varindex);
1790 case ICMD_MULTIANEWARRAY:
1791 i = iptr->s1.argcount;
1792 argp = iptr->sx.s23.s2.args;
1794 FREE_TEMP_REG(*argp);
1797 NEW_TEMP_REG(iptr->dst.varindex);
1801 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1806 } /* while instructions */
1809 } /* while blocks */
1813 #if defined(ENABLE_STATISTICS)
1814 void simplereg_make_statistics(jitdata *jd)
1821 stackptr src, src_old;
1825 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1829 /* get required compiler data */
1839 /* count how many local variables are held in memory or register */
1840 for(i=0; i < jd->localcount; i++) {
1841 if (VAR(i)->flags & INMEMORY) {
1842 count_locals_spilled++;
1846 count_locals_register++;
1850 /* count how many stack slots are held in memory or register */
1852 bptr = jd->basicblocks;
1854 while (bptr != NULL) {
1855 if (bptr->flags >= BBREACHED) {
1857 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1860 /* check for memory moves from interface to BB instack */
1861 len = bptr->indepth;
1863 if (len > size_interface) size_interface = len;
1867 var = VAR(bptr->invars[len]);
1869 /* invars statistics (currently none) */
1872 /* check for memory moves from BB outstack to interface */
1873 len = bptr->outdepth;
1874 if (len > size_interface) size_interface = len;
1878 var = VAR(bptr->outvars[len]);
1880 /* outvars statistics (currently none) */
1882 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1888 dst = bptr->instack;
1889 iptr = bptr->iinstr;
1893 while (--len >= 0) {
1895 dst = iptr->dst.var;
1897 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1898 switch (src->varkind) {
1901 if (!(src->flags & INMEMORY))
1902 count_ss_register++;
1908 /* case LOCALVAR: */
1909 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1910 /* count_ss_register++; */
1912 /* count_ss_spilled++; */
1915 if (!(src->flags & INMEMORY))
1916 count_argument_mem_ss++;
1918 count_argument_reg_ss++;
1922 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1923 /* if (src->varnum < FLT_ARG_CNT) { */
1924 /* count_ss_register++; */
1928 /* #if defined(__POWERPC__) */
1929 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1931 /* if (src->varnum < INT_ARG_CNT) { */
1933 /* count_ss_register++; */
1937 /* count_ss_spilled++; */
1944 } /* while instructions */
1949 } /* while blocks */
1951 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1952 if (in_register) count_method_in_register++;
1954 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1957 #endif /* defined(ENABLE_STATISTICS) */
1961 * These are local overrides for various environment variables in Emacs.
1962 * Please do not remove this and leave it at the end of the file, where
1963 * Emacs will automagically detect them.
1964 * ---------------------------------------------------------------------
1967 * indent-tabs-mode: t
1971 * vim:noexpandtab:sw=4:ts=4: