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 $Id: simplereg.c 8210 2007-07-18 12:51:00Z twisti $
39 #include "mm/memory.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/resolve.h"
44 #include "vm/stringlocal.h"
46 #include "vm/jit/abi.h"
47 #include "vm/jit/reg.h"
48 #include "vm/jit/show.h"
49 #include "vm/jit/allocator/simplereg.h"
51 #include "vmcore/method.h"
52 #include "vmcore/options.h"
56 # define LOG(args) printf args
62 /* function prototypes for this file ******************************************/
64 static void simplereg_allocate_interfaces(jitdata *jd);
65 static void simplereg_allocate_locals(jitdata *jd);
66 static void simplereg_allocate_temporaries(jitdata *jd);
69 /* size of a stackslot used by the internal ABI */
71 #if defined(HAS_4BYTE_STACKSLOT)
72 # define SIZE_OF_STACKSLOT 4
74 # define SIZE_OF_STACKSLOT 8
78 /* total number of registers */
80 #if defined(HAS_ADDRESS_REGISTER_FILE)
81 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
83 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
87 /* macros for handling register stacks ****************************************/
89 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
90 #define AVAIL_BACK(cnt) ((cnt) > 0)
92 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
93 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
94 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
96 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
97 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
100 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
101 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
102 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
103 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
105 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
106 #define POP_FRONT_INT(stk, cnt, reg) \
108 if (intregsneeded) { \
109 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
113 POP_FRONT(stk, cnt, reg); \
116 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
119 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
120 #define POP_BACK_INT(stk, cnt, reg) \
122 if (intregsneeded) { \
124 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
127 POP_BACK(stk, cnt, reg); \
130 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
133 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
134 #define PUSH_BACK_INT(stk, cnt, reg) \
136 if (intregsneeded) { \
137 stk[cnt] = GET_LOW_REG(reg); \
138 stk[cnt + 1] = GET_HIGH_REG(reg); \
142 PUSH_BACK(stk, cnt, reg); \
145 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
148 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
149 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
150 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
152 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
153 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
154 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
156 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
157 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
158 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
160 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
161 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
162 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
164 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
165 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
166 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
168 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
169 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
170 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
172 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
173 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
174 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
176 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
177 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
178 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
180 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
181 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
182 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
184 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
185 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
186 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
188 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
189 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
190 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
192 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
193 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
194 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
196 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
197 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
198 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
200 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
201 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
202 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
204 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
205 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
206 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
209 /* macros for allocating memory slots ****************************************/
211 #define NEW_MEM_SLOT(r) \
213 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
214 rd->memuse += memneeded + 1; \
217 #define NEW_MEM_SLOT_ALIGNED(r) \
219 if ( (memneeded) && (rd->memuse & 1)) \
221 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
222 rd->memuse += memneeded + 1; \
225 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r) \
227 if ( (memneeded) && (rd->memuse & 1)) { \
228 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
231 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
232 rd->memuse += memneeded + 1; \
235 #if defined(ALIGN_LONGS_IN_MEMORY)
236 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT_ALIGNED(r)
238 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
241 #if defined(ALIGN_DOUBLES_IN_MEMORY)
242 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT_ALIGNED(r)
244 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
247 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
248 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
250 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
254 /* macros for creating/freeing temporary variables ***************************/
256 #define NEW_TEMP_REG(index) \
257 if ( ((index) >= jd->localcount) \
258 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
259 simplereg_new_temp(jd, (index))
262 #define FREE_TEMP_REG(index) \
263 if (((index) > jd->localcount) \
264 && (!(VAR(index)->flags & (PREALLOC)))) \
265 simplereg_free_temp(jd, (index))
268 /* macro for getting a unique register index *********************************/
270 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
271 #define REG_INDEX_NON_ADR(regoff, type) \
272 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
274 #define REG_INDEX_NON_ADR(regoff, type) \
275 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
278 #if defined(HAS_ADDRESS_REGISTER_FILE)
279 #define REG_INDEX(regoff, type) \
280 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
282 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
286 /* regalloc ********************************************************************
288 Does a simple register allocation.
290 *******************************************************************************/
292 bool regalloc(jitdata *jd)
294 /* There is a problem with the use of unused float argument
295 registers in leafmethods for stackslots on c7 (2 * Dual Core
296 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
297 benchmark is heaviliy increased. This could be prevented by
298 setting rd->argfltreguse to FLT_ARG_CNT before calling
299 simplereg_allocate_temporaries and setting it back to the original
300 value before calling simplereg_allocate_locals. */
302 simplereg_allocate_interfaces(jd);
303 simplereg_allocate_temporaries(jd);
304 simplereg_allocate_locals(jd);
312 /* simplereg_allocate_interfaces ***********************************************
314 Allocates registers for all interface variables.
316 *******************************************************************************/
318 static void simplereg_allocate_interfaces(jitdata *jd)
325 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
326 /* in case more vars are packed into this interface slot */
328 /* Allocate LNG and DBL types first to ensure 2 memory slots or */
329 /* registers on HAS_4BYTE_STACKSLOT architectures. */
330 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
332 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
336 /* get required compiler data */
342 /* rd->memuse was already set in stack.c to allocate stack space
343 for passing arguments to called methods. */
345 #if defined(__I386__)
346 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
347 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
353 if (jd->isleafmethod) {
354 /* Reserve argument register, which will be used for Locals acting */
356 if (rd->argintreguse < m->parseddesc->argintreguse)
357 rd->argintreguse = m->parseddesc->argintreguse;
358 if (rd->argfltreguse < m->parseddesc->argfltreguse)
359 rd->argfltreguse = m->parseddesc->argfltreguse;
360 #ifdef HAS_ADDRESS_REGISTER_FILE
361 if (rd->argadrreguse < m->parseddesc->argadrreguse)
362 rd->argadrreguse = m->parseddesc->argadrreguse;
366 for (s = 0; s < jd->maxinterfaces; s++) {
367 intalloc = -1; fltalloc = -1;
369 /* check if the interface at this stack depth must be a SAVEDVAR */
373 for (tt = 0; tt <=4; tt++) {
374 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
375 saved |= t & SAVEDVAR;
379 /* allocate reg/mem for each type the interface is used as */
381 for (tt = 0; tt <= 4; tt++) {
383 if (jd->interface_map[s * 5 + t].flags == UNUSED)
387 regoff = -1; /* initialize to invalid value */
389 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
390 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
393 #if defined(HAS_4BYTE_STACKSLOT)
394 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
398 #if defined(HAS_ADDRESS_REGISTER_FILE)
399 if (IS_ADR_TYPE(t)) {
400 if (!jd->isleafmethod && AVAIL_ARG_ADR) {
402 TAKE_ARG_ADR(regoff);
404 else if (AVAIL_TMP_ADR) {
405 TAKE_TMP_ADR(regoff);
407 else if (AVAIL_SAV_ADR) {
409 TAKE_SAV_ADR(regoff);
413 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
416 else /* !IS_ADR_TYPE */
417 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
419 if (IS_FLT_DBL_TYPE(t)) {
421 /* Reuse memory slot(s)/register(s) for shared interface slots */
422 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
423 regoff = jd->interface_map[fltalloc].regoff;
425 else if (AVAIL_ARG_FLT) {
427 TAKE_ARG_FLT(regoff);
429 else if (AVAIL_TMP_FLT) {
430 TAKE_TMP_FLT(regoff);
432 else if (AVAIL_SAV_FLT) {
434 TAKE_SAV_FLT(regoff);
438 NEW_MEM_SLOT_FLT_DBL(regoff);
440 fltalloc = s * 5 + t;
442 else { /* !IS_FLT_DBL_TYPE(t) */
443 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
445 * for i386 put all longs in memory
447 if (IS_2_WORD_TYPE(t)) {
449 NEW_MEM_SLOT_INT_LNG(regoff);
454 /* Reuse memory slot(s)/register(s) for shared interface slots */
455 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
456 regoff = jd->interface_map[intalloc].regoff;
457 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
458 /* reuse lower half */
459 if (!(flags & INMEMORY)
460 && IS_2_WORD_TYPE(intalloc % 5))
461 regoff = GET_LOW_REG(regoff);
467 TAKE_ARG_INT(regoff);
469 else if (AVAIL_TMP_INT) {
470 TAKE_TMP_INT(regoff);
472 else if (AVAIL_SAV_INT) {
474 TAKE_SAV_INT(regoff);
478 NEW_MEM_SLOT_INT_LNG(regoff);
482 intalloc = s * 5 + t;
483 } /* if (IS_FLT_DBL_TYPE(t)) */
487 /* now the same like above, but without a chance to take a temporary register */
488 #ifdef HAS_ADDRESS_REGISTER_FILE
489 if (IS_ADR_TYPE(t)) {
491 TAKE_SAV_ADR(regoff);
495 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
501 if (IS_FLT_DBL_TYPE(t)) {
503 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
504 regoff = jd->interface_map[fltalloc].regoff;
508 TAKE_SAV_FLT(regoff);
512 NEW_MEM_SLOT_FLT_DBL(regoff);
515 fltalloc = s * 5 + t;
517 else { /* IS_INT_LNG */
518 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
520 * for i386 put all longs in memory
522 if (IS_2_WORD_TYPE(t)) {
524 NEW_MEM_SLOT_INT_LNG(regoff);
530 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
531 regoff = jd->interface_map[intalloc].regoff;
532 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
533 /* reuse lower half */
534 if (!(flags & INMEMORY)
535 && IS_2_WORD_TYPE(intalloc % 5))
536 regoff = GET_LOW_REG(regoff);
541 TAKE_SAV_INT(regoff);
545 NEW_MEM_SLOT_INT_LNG(regoff);
550 } /* if (IS_FLT_DBL_TYPE(t) else */
551 } /* if (IS_ADR_TYPE(t)) else */
552 } /* if (saved) else */
556 jd->interface_map[5*s + t].flags = flags | INOUT;
557 jd->interface_map[5*s + t].regoff = regoff;
563 /* simplereg_allocate_locals_leafmethod ****************************************
565 Allocates registers for all local variables of a leafmethod.
567 *******************************************************************************/
569 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
576 int p, s, t, tt, varindex;
577 int intalloc, fltalloc;
579 int intregsneeded = 0;
581 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
582 int fargcnt, iargcnt;
583 #ifdef HAS_ADDRESS_REGISTER_FILE
587 /* get required compiler data */
595 iargcnt = rd->argintreguse;
596 fargcnt = rd->argfltreguse;
597 #ifdef HAS_ADDRESS_REGISTER_FILE
598 aargcnt = rd->argadrreguse;
600 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
601 intalloc = -1; fltalloc = -1;
602 for (tt = 0; tt <= 4; tt++) {
604 varindex = jd->local_map[s * 5 + t];
605 if (varindex == UNUSED)
610 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
611 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
613 #if defined(HAS_4BYTE_STACKSLOT)
614 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
620 * #ifdef HAS_ADDRESS_REGISTER_FILE
627 * } else { / int & lng
631 * must not to be changed!
634 #ifdef HAS_ADDRESS_REGISTER_FILE
635 if (IS_ADR_TYPE(t)) {
636 if ((p < md->paramcount) && !md->params[p].inmemory) {
638 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
640 else if (AVAIL_TMP_ADR) {
642 TAKE_TMP_ADR(v->vv.regoff);
644 /* use unused argument registers as local registers */
645 else if ((p >= md->paramcount) &&
646 (aargcnt < ADR_ARG_CNT))
649 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
651 else if (AVAIL_SAV_ADR) {
653 TAKE_SAV_ADR(v->vv.regoff);
656 v->flags |= INMEMORY;
657 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
662 if (IS_FLT_DBL_TYPE(t)) {
664 v->flags = VAR(fltalloc)->flags;
665 v->vv.regoff = VAR(fltalloc)->vv.regoff;
667 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
668 /* We can only use float arguments as local variables,
669 * if we do not pass them in integer registers. */
670 else if ((p < md->paramcount) && !md->params[p].inmemory) {
672 v->vv.regoff = md->params[p].regoff;
675 else if (AVAIL_TMP_FLT) {
677 TAKE_TMP_FLT(v->vv.regoff);
679 /* use unused argument registers as local registers */
680 else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
682 POP_FRONT(abi_registers_float_argument,
683 fargcnt, v->vv.regoff);
685 else if (AVAIL_SAV_FLT) {
687 TAKE_SAV_FLT(v->vv.regoff);
691 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
693 fltalloc = jd->local_map[s * 5 + t];
697 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
699 * for i386 put all longs in memory
701 if (IS_2_WORD_TYPE(t)) {
703 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
709 v->flags = VAR(intalloc)->flags;
710 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
711 if (!(v->flags & INMEMORY)
712 && IS_2_WORD_TYPE(VAR(intalloc)->type))
713 v->vv.regoff = GET_LOW_REG(
714 VAR(intalloc)->vv.regoff);
717 v->vv.regoff = VAR(intalloc)->vv.regoff;
719 else if ((p < md->paramcount) &&
720 !md->params[p].inmemory)
723 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
724 if (IS_2_WORD_TYPE(t))
726 PACK_REGS(GET_LOW_REG(md->params[p].regoff),
727 GET_HIGH_REG(md->params[p].regoff));
730 v->vv.regoff = md->params[p].regoff;
732 else if (AVAIL_TMP_INT) {
734 TAKE_TMP_INT(v->vv.regoff);
737 * use unused argument registers as local registers
739 else if ((p >= m->parseddesc->paramcount) &&
740 (iargcnt + intregsneeded < INT_ARG_CNT))
743 POP_FRONT_INT(abi_registers_integer_argument,
744 iargcnt, v->vv.regoff);
746 else if (AVAIL_SAV_INT) {
748 TAKE_SAV_INT(v->vv.regoff);
752 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
755 intalloc = jd->local_map[s * 5 + t];
757 #ifdef HAS_ADDRESS_REGISTER_FILE
760 } /* for (tt=0;...) */
762 /* If the current parameter is a 2-word type, the next local slot */
765 if (p < md->paramcount)
766 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
771 /* simplereg_allocate_locals ***************************************************
773 Allocates registers for all local variables.
775 *******************************************************************************/
777 static void simplereg_allocate_locals(jitdata *jd)
782 int s, t, tt, varindex;
783 int intalloc, fltalloc;
786 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
787 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
791 /* get required compiler data */
796 if (jd->isleafmethod) {
797 simplereg_allocate_locals_leafmethod(jd);
801 for (s = 0; s < jd->maxlocals; s++) {
802 intalloc = -1; fltalloc = -1;
803 for (tt=0; tt<=4; tt++) {
806 varindex = jd->local_map[s * 5 + t];
807 if (varindex == UNUSED)
812 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
813 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
816 #if defined(HAS_4BYTE_STACKSLOT)
817 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
820 #ifdef HAS_ADDRESS_REGISTER_FILE
821 if (IS_ADR_TYPE(t)) {
824 TAKE_SAV_ADR(v->vv.regoff);
828 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
833 if (IS_FLT_DBL_TYPE(t)) {
835 v->flags = VAR(fltalloc)->flags;
836 v->vv.regoff = VAR(fltalloc)->vv.regoff;
838 else if (AVAIL_SAV_FLT) {
840 TAKE_SAV_FLT(v->vv.regoff);
844 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
846 fltalloc = jd->local_map[s * 5 + t];
849 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
851 * for i386 put all longs in memory
853 if (IS_2_WORD_TYPE(t)) {
855 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
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 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
878 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
881 intalloc = jd->local_map[s * 5 + t];
883 #ifdef HAS_ADDRESS_REGISTER_FILE
891 static void simplereg_init(jitdata *jd, registerdata *rd)
896 #if defined(HAS_4BYTE_STACKSLOT)
897 rd->freememtop_2 = 0;
900 rd->freetmpinttop = 0;
901 rd->freesavinttop = 0;
902 rd->freetmpflttop = 0;
903 rd->freesavflttop = 0;
904 #ifdef HAS_ADDRESS_REGISTER_FILE
905 rd->freetmpadrtop = 0;
906 rd->freesavadrtop = 0;
909 rd->freearginttop = 0;
910 rd->freeargflttop = 0;
911 #ifdef HAS_ADDRESS_REGISTER_FILE
912 rd->freeargadrtop = 0;
915 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
916 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
917 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
919 /* memcopycount is dynamically allocated when needed */
921 rd->memcopycount = NULL;
922 rd->memcopycountsize = 0;
924 rd->intusedinout = DMNEW(int, INT_REG_CNT);
925 MZERO(rd->intusedinout, int, INT_REG_CNT);
926 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
927 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
929 /* record the interface registers as used */
931 for (i=0; i<rd->argintreguse; ++i)
932 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
933 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
934 rd->intusedinout[rd->tmpintregs[i]] = 1;
935 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
936 rd->intusedinout[rd->savintregs[i]] = 1;
938 for (i=0; i<rd->argfltreguse; ++i)
939 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
940 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
941 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
942 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
943 rd->fltusedinout[rd->savfltregs[i]] = 1;
945 #ifdef HAS_ADDRESS_REGISTER_FILE
946 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
947 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
949 for (i=0; i<rd->argadrreguse; ++i)
950 rd->adrusedinout[rd->argadrregs[i]] = 1;
951 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
952 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
953 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
954 rd->adrusedinout[rd->savadrregs[i]] = 1;
959 static void simplereg_init_block(registerdata *rd)
963 /* remove all interface registers from the free lists */
965 for (i=0; i<rd->freearginttop; ++i)
966 if (rd->intusedinout[rd->freeargintregs[i]]) {
967 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
969 for (i=0; i<rd->freetmpinttop; ++i)
970 if (rd->intusedinout[rd->freetmpintregs[i]]) {
971 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
973 for (i=0; i<rd->freesavinttop; ++i)
974 if (rd->intusedinout[rd->freesavintregs[i]]) {
975 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
978 for (i=0; i<rd->freeargflttop; ++i)
979 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
980 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
982 for (i=0; i<rd->freetmpflttop; ++i)
983 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
984 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
986 for (i=0; i<rd->freesavflttop; ++i)
987 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
988 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
991 #ifdef HAS_ADDRESS_REGISTER_FILE
992 for (i=0; i<rd->freeargadrtop; ++i)
993 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
994 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
996 for (i=0; i<rd->freetmpadrtop; ++i)
997 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
998 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
1000 for (i=0; i<rd->freesavadrtop; ++i)
1001 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1002 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1008 static void simplereg_new_temp(jitdata *jd, s4 index)
1010 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1021 /* assert that constants are not allocated */
1023 assert(v->type != TYPE_RET);
1025 /* Try to allocate a saved register if there is no temporary one */
1026 /* available. This is what happens during the second run. */
1027 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1029 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1030 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1033 #if defined(HAS_4BYTE_STACKSLOT)
1034 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1039 for(; tryagain; --tryagain) {
1040 if (tryagain == 1) {
1041 if (!(v->flags & SAVEDVAR))
1043 #ifdef HAS_ADDRESS_REGISTER_FILE
1044 if (IS_ADR_TYPE(v->type)) {
1045 if (AVAIL_FREE_SAV_ADR) {
1046 TAKE_FREE_SAV_ADR(v->vv.regoff);
1049 else if (AVAIL_SAV_ADR) {
1050 TAKE_SAV_ADR(v->vv.regoff);
1057 if (IS_FLT_DBL_TYPE(v->type)) {
1058 if (AVAIL_FREE_SAV_FLT) {
1059 TAKE_FREE_SAV_FLT(v->vv.regoff);
1062 else if (AVAIL_SAV_FLT) {
1063 TAKE_SAV_FLT(v->vv.regoff);
1068 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1070 * for i386 put all longs in memory
1072 if (!IS_2_WORD_TYPE(v->type))
1075 if (AVAIL_FREE_SAV_INT) {
1076 TAKE_FREE_SAV_INT(v->vv.regoff);
1079 else if (AVAIL_SAV_INT) {
1080 TAKE_SAV_INT(v->vv.regoff);
1087 else { /* tryagain == 2 */
1088 #ifdef HAS_ADDRESS_REGISTER_FILE
1089 if (IS_ADR_TYPE(v->type)) {
1090 if (AVAIL_FREE_TMP_ADR) {
1091 TAKE_FREE_TMP_ADR(v->vv.regoff);
1094 else if (AVAIL_TMP_ADR) {
1095 TAKE_TMP_ADR(v->vv.regoff);
1102 if (IS_FLT_DBL_TYPE(v->type)) {
1103 if (AVAIL_FREE_ARG_FLT) {
1105 TAKE_FREE_ARG_FLT(v->vv.regoff);
1108 else if (AVAIL_ARG_FLT) {
1110 TAKE_ARG_FLT(v->vv.regoff);
1113 else if (AVAIL_FREE_TMP_FLT) {
1114 TAKE_FREE_TMP_FLT(v->vv.regoff);
1117 else if (AVAIL_TMP_FLT) {
1118 TAKE_TMP_FLT(v->vv.regoff);
1124 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1126 * for i386 put all longs in memory
1128 if (!IS_2_WORD_TYPE(v->type))
1131 if (AVAIL_FREE_ARG_INT) {
1133 TAKE_FREE_ARG_INT(v->vv.regoff);
1136 else if (AVAIL_ARG_INT) {
1138 TAKE_ARG_INT(v->vv.regoff);
1141 else if (AVAIL_FREE_TMP_INT) {
1142 TAKE_FREE_TMP_INT(v->vv.regoff);
1145 else if (AVAIL_TMP_INT) {
1146 TAKE_TMP_INT(v->vv.regoff);
1149 } /* if (!IS_2_WORD_TYPE(s->type)) */
1150 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1151 } /* if (IS_ADR_TYPE(s->type)) */
1152 } /* if (tryagain == 1) else */
1153 } /* for(; tryagain; --tryagain) */
1155 /* spill to memory */
1157 v->flags |= INMEMORY;
1159 #if defined(HAS_4BYTE_STACKSLOT)
1160 if ((memneeded == 1) && (rd->freememtop_2 > 0))
1161 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1163 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1164 if ((memneeded == 0) && (rd->freememtop > 0))
1165 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1167 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1171 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1173 /* assert that constants are not freed */
1175 assert(type != TYPE_RET);
1177 /* if this is a copy of another variable, just decrement the copy counter */
1179 if (flags & INMEMORY) {
1183 #warning this will be more efficient if we divide it by SIZE_OF_STACKSLOT
1185 if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
1186 rd->memcopycount[regoff]--;
1193 regindex = REG_INDEX(regoff, type);
1195 /* do not free interface registers that are needed as outvars */
1197 if (flags & INOUT) {
1198 if (rd->regisoutvar[regindex]) {
1199 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1203 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1206 if (rd->regcopycount[regindex]) {
1207 rd->regcopycount[regindex]--;
1212 if (flags & INMEMORY) {
1213 #if defined(HAS_4BYTE_STACKSLOT)
1214 if (IS_2_WORD_TYPE(type))
1215 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1218 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1223 /* freeing a register */
1225 #ifdef HAS_ADDRESS_REGISTER_FILE
1226 if (IS_ADR_TYPE(type)) {
1227 if (flags & (SAVEDVAR | SAVREG))
1228 PUSH_FREE_SAV_ADR(regoff);
1230 PUSH_FREE_TMP_ADR(regoff);
1233 else if (IS_FLT_DBL_TYPE(type)) {
1234 if (flags & (SAVEDVAR | SAVREG))
1235 PUSH_FREE_SAV_FLT(regoff);
1236 else if (flags & ARGREG)
1237 PUSH_FREE_ARG_FLT(regoff);
1239 PUSH_FREE_TMP_FLT(regoff);
1241 else { /* IS_INT_LNG_TYPE */
1242 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1243 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1246 if (flags & (SAVEDVAR | SAVREG))
1247 PUSH_FREE_SAV_INT(regoff);
1248 else if (flags & ARGREG)
1249 PUSH_FREE_ARG_INT(regoff);
1251 PUSH_FREE_TMP_INT(regoff);
1256 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1262 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1266 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1271 /* do not coalesce local variables here */
1273 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1279 /* do not coalesce in/out vars or preallocated variables here */
1281 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1284 /* if the source is in memory, we can coalesce in any case */
1286 if (sv->flags & INMEMORY) {
1287 dv->flags |= INMEMORY;
1288 dv->vv.regoff = sv->vv.regoff;
1292 /* we do not allocate a REG_TMP to a REG_SAV variable */
1294 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1298 dv->vv.regoff = sv->vv.regoff;
1299 dv->flags |= sv->flags & (SAVREG | ARGREG);
1305 /* simplereg_allocate_temporaries **********************************************
1307 Allocate temporary (non-interface, non-local) registers.
1309 *******************************************************************************/
1311 static void simplereg_allocate_temporaries(jitdata *jd)
1319 builtintable_entry *bte;
1328 /* get required compiler data */
1333 /* initialize temp registers */
1335 simplereg_init(jd, rd);
1337 bptr = jd->basicblocks;
1339 while (bptr != NULL) {
1340 if (bptr->flags >= BBREACHED) {
1342 LOG(("\nallocating block L%03d\n", bptr->nr));
1344 simplereg_init_block(rd);
1346 /* assert that all copy counts are zero */
1348 #if !defined(NDEBUG)
1349 for (i=0; i < TOTAL_REG_CNT; ++i)
1350 assert(rd->regcopycount[i] == 0);
1353 /* reset outvar flags */
1355 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1357 /* set allocation of invars */
1359 for (i=0; i<bptr->indepth; ++i)
1361 v = VAR(bptr->invars[i]);
1362 if (v->type == TYPE_RET)
1365 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1366 v->flags = jd->interface_map[5*i + v->type].flags;
1368 if (!(v->flags & INMEMORY))
1369 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1372 /* set allocation of outvars */
1374 for (i=0; i<bptr->outdepth; ++i)
1376 v = VAR(bptr->outvars[i]);
1377 if (v->type == TYPE_RET)
1380 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1381 v->flags = jd->interface_map[5*i + v->type].flags;
1383 if (!(v->flags & INMEMORY)) {
1384 regindex = REG_INDEX(v->vv.regoff, v->type);
1385 rd->regcopycount[regindex] = 1;
1386 rd->regisoutvar[regindex] = 1;
1390 /* free interface registers not used in this block */
1392 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1394 regoff = jd->interface_map[i].regoff;
1395 flags = jd->interface_map[i].flags;
1397 if (!(flags & INMEMORY)) {
1398 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1399 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1400 flags, regoff, type));
1401 simplereg_free(rd, flags, regoff, type);
1403 /* mark it, so it is not freed again */
1404 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1409 /* reset copy counts */
1411 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1413 /* iterate over ICMDS to allocate temporary variables */
1415 iptr = bptr->iinstr;
1418 while (--len >= 0) {
1420 switch (iptr->opc) {
1426 case ICMD_CHECKNULL:
1431 case ICMD_PUTSTATICCONST:
1432 case ICMD_INLINE_START:
1433 case ICMD_INLINE_END:
1434 case ICMD_INLINE_BODY:
1437 /* pop 0 push 1 const */
1445 /* pop 0 push 1 load */
1452 NEW_TEMP_REG(iptr->dst.varindex);
1466 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1467 FREE_TEMP_REG(iptr->s1.varindex);
1468 NEW_TEMP_REG(iptr->dst.varindex);
1482 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1483 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1484 FREE_TEMP_REG(iptr->s1.varindex);
1487 /* pop 1 push 0 store */
1507 case ICMD_PUTSTATIC:
1508 case ICMD_PUTFIELDCONST:
1510 /* pop 1 push 0 branch */
1513 case ICMD_IFNONNULL:
1529 /* pop 1 push 0 table branch */
1531 case ICMD_TABLESWITCH:
1532 case ICMD_LOOKUPSWITCH:
1534 case ICMD_MONITORENTER:
1535 case ICMD_MONITOREXIT:
1536 FREE_TEMP_REG(iptr->s1.varindex);
1539 /* pop 2 push 0 branch */
1541 case ICMD_IF_ICMPEQ:
1542 case ICMD_IF_ICMPNE:
1543 case ICMD_IF_ICMPLT:
1544 case ICMD_IF_ICMPGE:
1545 case ICMD_IF_ICMPGT:
1546 case ICMD_IF_ICMPLE:
1548 case ICMD_IF_LCMPEQ:
1549 case ICMD_IF_LCMPNE:
1550 case ICMD_IF_LCMPLT:
1551 case ICMD_IF_LCMPGE:
1552 case ICMD_IF_LCMPGT:
1553 case ICMD_IF_LCMPLE:
1555 case ICMD_IF_FCMPEQ:
1556 case ICMD_IF_FCMPNE:
1558 case ICMD_IF_FCMPL_LT:
1559 case ICMD_IF_FCMPL_GE:
1560 case ICMD_IF_FCMPL_GT:
1561 case ICMD_IF_FCMPL_LE:
1563 case ICMD_IF_FCMPG_LT:
1564 case ICMD_IF_FCMPG_GE:
1565 case ICMD_IF_FCMPG_GT:
1566 case ICMD_IF_FCMPG_LE:
1568 case ICMD_IF_DCMPEQ:
1569 case ICMD_IF_DCMPNE:
1571 case ICMD_IF_DCMPL_LT:
1572 case ICMD_IF_DCMPL_GE:
1573 case ICMD_IF_DCMPL_GT:
1574 case ICMD_IF_DCMPL_LE:
1576 case ICMD_IF_DCMPG_LT:
1577 case ICMD_IF_DCMPG_GE:
1578 case ICMD_IF_DCMPG_GT:
1579 case ICMD_IF_DCMPG_LE:
1581 case ICMD_IF_ACMPEQ:
1582 case ICMD_IF_ACMPNE:
1590 case ICMD_IASTORECONST:
1591 case ICMD_LASTORECONST:
1592 case ICMD_AASTORECONST:
1593 case ICMD_BASTORECONST:
1594 case ICMD_CASTORECONST:
1595 case ICMD_SASTORECONST:
1596 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1597 FREE_TEMP_REG(iptr->s1.varindex);
1600 /* pop 0 push 1 copy */
1603 /* src === dst->prev (identical Stackslot Element) */
1604 /* src --> dst (copied value, take same reg/mem) */
1606 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1607 NEW_TEMP_REG(iptr->dst.varindex);
1610 v = VAROP(iptr->dst);
1612 if (v->flags & INMEMORY) {
1613 if (v->vv.regoff >= rd->memcopycountsize) {
1614 int newsize = (v->vv.regoff + 1) * 2;
1615 i = rd->memcopycountsize;
1616 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1617 MZERO(rd->memcopycount + i, int, newsize - i);
1618 rd->memcopycountsize = newsize;
1620 rd->memcopycount[v->vv.regoff]++;
1623 /* XXX split reg/mem variables on arm may need special handling here */
1625 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1627 rd->regcopycount[regindex]++;
1632 /* pop 1 push 1 move */
1635 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1636 NEW_TEMP_REG(iptr->dst.varindex);
1637 FREE_TEMP_REG(iptr->s1.varindex);
1687 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1688 FREE_TEMP_REG(iptr->s1.varindex);
1689 NEW_TEMP_REG(iptr->dst.varindex);
1694 case ICMD_IADDCONST:
1695 case ICMD_ISUBCONST:
1696 case ICMD_IMULCONST:
1700 case ICMD_IANDCONST:
1702 case ICMD_IXORCONST:
1703 case ICMD_ISHLCONST:
1704 case ICMD_ISHRCONST:
1705 case ICMD_IUSHRCONST:
1707 case ICMD_LADDCONST:
1708 case ICMD_LSUBCONST:
1709 case ICMD_LMULCONST:
1713 case ICMD_LANDCONST:
1715 case ICMD_LXORCONST:
1716 case ICMD_LSHLCONST:
1717 case ICMD_LSHRCONST:
1718 case ICMD_LUSHRCONST:
1723 case ICMD_INT2SHORT:
1741 case ICMD_CHECKCAST:
1743 case ICMD_ARRAYLENGTH:
1744 case ICMD_INSTANCEOF:
1747 case ICMD_ANEWARRAY:
1750 FREE_TEMP_REG(iptr->s1.varindex);
1751 NEW_TEMP_REG(iptr->dst.varindex);
1756 case ICMD_GETSTATIC:
1759 NEW_TEMP_REG(iptr->dst.varindex);
1762 /* pop many push any */
1764 case ICMD_INVOKESTATIC:
1765 case ICMD_INVOKESPECIAL:
1766 case ICMD_INVOKEVIRTUAL:
1767 case ICMD_INVOKEINTERFACE:
1768 INSTRUCTION_GET_METHODDESC(iptr,md);
1770 argp = iptr->sx.s23.s2.args;
1772 FREE_TEMP_REG(*argp);
1775 if (md->returntype.type != TYPE_VOID)
1776 NEW_TEMP_REG(iptr->dst.varindex);
1780 bte = iptr->sx.s23.s3.bte;
1783 argp = iptr->sx.s23.s2.args;
1785 FREE_TEMP_REG(*argp);
1788 if (md->returntype.type != TYPE_VOID)
1789 NEW_TEMP_REG(iptr->dst.varindex);
1792 case ICMD_MULTIANEWARRAY:
1793 i = iptr->s1.argcount;
1794 argp = iptr->sx.s23.s2.args;
1796 FREE_TEMP_REG(*argp);
1799 NEW_TEMP_REG(iptr->dst.varindex);
1803 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1808 } /* while instructions */
1811 } /* while blocks */
1815 #if defined(ENABLE_STATISTICS)
1816 void simplereg_make_statistics(jitdata *jd)
1824 stackptr src, src_old;
1829 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1833 /* get required compiler data */
1843 /* count how many local variables are held in memory or register */
1844 for(i=0; i < jd->localcount; i++) {
1845 if (VAR(i)->flags & INMEMORY) {
1846 count_locals_spilled++;
1850 count_locals_register++;
1854 /* count how many stack slots are held in memory or register */
1856 bptr = jd->basicblocks;
1858 while (bptr != NULL) {
1859 if (bptr->flags >= BBREACHED) {
1861 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1864 /* check for memory moves from interface to BB instack */
1865 len = bptr->indepth;
1867 if (len > size_interface) size_interface = len;
1871 var = VAR(bptr->invars[len]);
1873 /* invars statistics (currently none) */
1876 /* check for memory moves from BB outstack to interface */
1877 len = bptr->outdepth;
1878 if (len > size_interface) size_interface = len;
1882 var = VAR(bptr->outvars[len]);
1884 /* outvars statistics (currently none) */
1886 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1892 dst = bptr->instack;
1893 iptr = bptr->iinstr;
1897 while (--len >= 0) {
1899 dst = iptr->dst.var;
1901 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1902 switch (src->varkind) {
1905 if (!(src->flags & INMEMORY))
1906 count_ss_register++;
1912 /* case LOCALVAR: */
1913 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1914 /* count_ss_register++; */
1916 /* count_ss_spilled++; */
1919 if (!(src->flags & INMEMORY))
1920 count_argument_mem_ss++;
1922 count_argument_reg_ss++;
1926 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1927 /* if (src->varnum < FLT_ARG_CNT) { */
1928 /* count_ss_register++; */
1932 /* #if defined(__POWERPC__) */
1933 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1935 /* if (src->varnum < INT_ARG_CNT) { */
1937 /* count_ss_register++; */
1941 /* count_ss_spilled++; */
1948 } /* while instructions */
1953 } /* while blocks */
1955 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1956 if (in_register) count_method_in_register++;
1958 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1961 #endif /* defined(ENABLE_STATISTICS) */
1965 * These are local overrides for various environment variables in Emacs.
1966 * Please do not remove this and leave it at the end of the file, where
1967 * Emacs will automagically detect them.
1968 * ---------------------------------------------------------------------
1971 * indent-tabs-mode: t
1975 * vim:noexpandtab:sw=4:ts=4: