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
38 #include "mm/memory.h"
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
42 #include "vm/resolve.h"
43 #include "vm/stringlocal.h"
45 #include "vm/jit/abi.h"
46 #include "vm/jit/reg.h"
47 #include "vm/jit/show.h"
48 #include "vm/jit/allocator/simplereg.h"
50 #include "vmcore/method.h"
51 #include "vmcore/options.h"
55 # define LOG(args) printf args
61 /* function prototypes for this file ******************************************/
63 static void simplereg_allocate_interfaces(jitdata *jd);
64 static void simplereg_allocate_locals(jitdata *jd);
65 static void simplereg_allocate_temporaries(jitdata *jd);
68 /* size of a stackslot used by the internal ABI */
70 #if defined(HAS_4BYTE_STACKSLOT)
71 # define SIZE_OF_STACKSLOT 4
73 # define SIZE_OF_STACKSLOT 8
77 /* total number of registers */
79 #if defined(HAS_ADDRESS_REGISTER_FILE)
80 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
82 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
86 /* macros for handling register stacks ****************************************/
88 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
89 #define AVAIL_BACK(cnt) ((cnt) > 0)
91 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
92 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
93 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
95 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
96 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
99 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
100 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
101 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
102 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
104 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
105 #define POP_FRONT_INT(stk, cnt, reg) \
107 if (intregsneeded) { \
108 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
112 POP_FRONT(stk, cnt, reg); \
115 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
118 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
119 #define POP_BACK_INT(stk, cnt, reg) \
121 if (intregsneeded) { \
123 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
126 POP_BACK(stk, cnt, reg); \
129 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
132 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
133 #define PUSH_BACK_INT(stk, cnt, reg) \
135 if (intregsneeded) { \
136 stk[cnt] = GET_LOW_REG(reg); \
137 stk[cnt + 1] = GET_HIGH_REG(reg); \
141 PUSH_BACK(stk, cnt, reg); \
144 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
147 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
148 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
149 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
151 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
152 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
153 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
155 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
156 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
157 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
159 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
160 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
161 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
163 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
164 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
165 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
167 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
168 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
169 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
171 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
172 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
173 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
175 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
176 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
177 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
179 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
180 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
181 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
183 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
184 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
185 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
187 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
188 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
189 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
191 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
192 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
193 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
195 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
196 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
197 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
199 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
200 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
201 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
203 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
204 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
205 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
208 /* macros for allocating memory slots ****************************************/
210 #define NEW_MEM_SLOT(r) \
212 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
213 rd->memuse += memneeded + 1; \
216 #define NEW_MEM_SLOT_ALIGNED(r) \
218 if ( (memneeded) && (rd->memuse & 1)) \
220 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
221 rd->memuse += memneeded + 1; \
224 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r) \
226 if ( (memneeded) && (rd->memuse & 1)) { \
227 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
230 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
231 rd->memuse += memneeded + 1; \
234 #if defined(ALIGN_LONGS_IN_MEMORY)
235 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT_ALIGNED(r)
237 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
240 #if defined(ALIGN_DOUBLES_IN_MEMORY)
241 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT_ALIGNED(r)
243 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
246 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
247 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
249 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
253 /* macros for creating/freeing temporary variables ***************************/
255 #define NEW_TEMP_REG(index) \
256 if ( ((index) >= jd->localcount) \
257 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
258 simplereg_new_temp(jd, (index))
261 #define FREE_TEMP_REG(index) \
262 if (((index) > jd->localcount) \
263 && (!(VAR(index)->flags & (PREALLOC)))) \
264 simplereg_free_temp(jd, (index))
267 /* macro for getting a unique register index *********************************/
269 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
270 #define REG_INDEX_NON_ADR(regoff, type) \
271 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
273 #define REG_INDEX_NON_ADR(regoff, type) \
274 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
277 #if defined(HAS_ADDRESS_REGISTER_FILE)
278 #define REG_INDEX(regoff, type) \
279 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
281 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
285 /* regalloc ********************************************************************
287 Does a simple register allocation.
289 *******************************************************************************/
291 bool regalloc(jitdata *jd)
293 /* There is a problem with the use of unused float argument
294 registers in leafmethods for stackslots on c7 (2 * Dual Core
295 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
296 benchmark is heaviliy increased. This could be prevented by
297 setting rd->argfltreguse to FLT_ARG_CNT before calling
298 simplereg_allocate_temporaries and setting it back to the original
299 value before calling simplereg_allocate_locals. */
301 simplereg_allocate_interfaces(jd);
302 simplereg_allocate_temporaries(jd);
303 simplereg_allocate_locals(jd);
311 /* simplereg_allocate_interfaces ***********************************************
313 Allocates registers for all interface variables.
315 *******************************************************************************/
317 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 */
343 /* rd->memuse was already set in stack.c to allocate stack space
344 for passing arguments to called methods. */
346 #if defined(__I386__)
347 if (checksync && code_is_synchronized(code)) {
348 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
354 if (code_is_leafmethod(code)) {
355 /* Reserve argument register, which will be used for Locals acting */
357 if (rd->argintreguse < m->parseddesc->argintreguse)
358 rd->argintreguse = m->parseddesc->argintreguse;
359 if (rd->argfltreguse < m->parseddesc->argfltreguse)
360 rd->argfltreguse = m->parseddesc->argfltreguse;
361 #ifdef HAS_ADDRESS_REGISTER_FILE
362 if (rd->argadrreguse < m->parseddesc->argadrreguse)
363 rd->argadrreguse = m->parseddesc->argadrreguse;
367 for (s = 0; s < jd->maxinterfaces; s++) {
368 intalloc = -1; fltalloc = -1;
370 /* check if the interface at this stack depth must be a SAVEDVAR */
374 for (tt = 0; tt <=4; tt++) {
375 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
376 saved |= t & SAVEDVAR;
380 /* allocate reg/mem for each type the interface is used as */
382 for (tt = 0; tt <= 4; tt++) {
384 if (jd->interface_map[s * 5 + t].flags == UNUSED)
388 regoff = -1; /* initialize to invalid value */
390 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
391 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
394 #if defined(HAS_4BYTE_STACKSLOT)
395 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
399 #if defined(HAS_ADDRESS_REGISTER_FILE)
400 if (IS_ADR_TYPE(t)) {
401 if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
403 TAKE_ARG_ADR(regoff);
405 else if (AVAIL_TMP_ADR) {
406 TAKE_TMP_ADR(regoff);
408 else if (AVAIL_SAV_ADR) {
410 TAKE_SAV_ADR(regoff);
414 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
417 else /* !IS_ADR_TYPE */
418 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
420 if (IS_FLT_DBL_TYPE(t)) {
422 /* Reuse memory slot(s)/register(s) for shared interface slots */
423 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
424 regoff = jd->interface_map[fltalloc].regoff;
426 else if (AVAIL_ARG_FLT) {
428 TAKE_ARG_FLT(regoff);
430 else if (AVAIL_TMP_FLT) {
431 TAKE_TMP_FLT(regoff);
433 else if (AVAIL_SAV_FLT) {
435 TAKE_SAV_FLT(regoff);
439 NEW_MEM_SLOT_FLT_DBL(regoff);
441 fltalloc = s * 5 + t;
443 else { /* !IS_FLT_DBL_TYPE(t) */
444 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
446 * for i386 put all longs in memory
448 if (IS_2_WORD_TYPE(t)) {
450 NEW_MEM_SLOT_INT_LNG(regoff);
455 /* Reuse memory slot(s)/register(s) for shared interface slots */
456 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
457 regoff = jd->interface_map[intalloc].regoff;
458 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
459 /* reuse lower half */
460 if (!(flags & INMEMORY)
461 && IS_2_WORD_TYPE(intalloc % 5))
462 regoff = GET_LOW_REG(regoff);
468 TAKE_ARG_INT(regoff);
470 else if (AVAIL_TMP_INT) {
471 TAKE_TMP_INT(regoff);
473 else if (AVAIL_SAV_INT) {
475 TAKE_SAV_INT(regoff);
479 NEW_MEM_SLOT_INT_LNG(regoff);
483 intalloc = s * 5 + t;
484 } /* if (IS_FLT_DBL_TYPE(t)) */
488 /* now the same like above, but without a chance to take a temporary register */
489 #ifdef HAS_ADDRESS_REGISTER_FILE
490 if (IS_ADR_TYPE(t)) {
492 TAKE_SAV_ADR(regoff);
496 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
502 if (IS_FLT_DBL_TYPE(t)) {
504 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
505 regoff = jd->interface_map[fltalloc].regoff;
509 TAKE_SAV_FLT(regoff);
513 NEW_MEM_SLOT_FLT_DBL(regoff);
516 fltalloc = s * 5 + t;
518 else { /* IS_INT_LNG */
519 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
521 * for i386 put all longs in memory
523 if (IS_2_WORD_TYPE(t)) {
525 NEW_MEM_SLOT_INT_LNG(regoff);
531 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
532 regoff = jd->interface_map[intalloc].regoff;
533 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
534 /* reuse lower half */
535 if (!(flags & INMEMORY)
536 && IS_2_WORD_TYPE(intalloc % 5))
537 regoff = GET_LOW_REG(regoff);
542 TAKE_SAV_INT(regoff);
546 NEW_MEM_SLOT_INT_LNG(regoff);
551 } /* if (IS_FLT_DBL_TYPE(t) else */
552 } /* if (IS_ADR_TYPE(t)) else */
553 } /* if (saved) else */
557 jd->interface_map[5*s + t].flags = flags | INOUT;
558 jd->interface_map[5*s + t].regoff = regoff;
564 /* simplereg_allocate_locals_leafmethod ****************************************
566 Allocates registers for all local variables of a leafmethod.
568 *******************************************************************************/
570 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
577 int p, s, t, tt, varindex;
578 int intalloc, fltalloc;
580 int intregsneeded = 0;
582 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
583 int fargcnt, iargcnt;
584 #ifdef HAS_ADDRESS_REGISTER_FILE
588 /* get required compiler data */
596 iargcnt = rd->argintreguse;
597 fargcnt = rd->argfltreguse;
598 #ifdef HAS_ADDRESS_REGISTER_FILE
599 aargcnt = rd->argadrreguse;
601 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
602 intalloc = -1; fltalloc = -1;
603 for (tt = 0; tt <= 4; tt++) {
605 varindex = jd->local_map[s * 5 + t];
606 if (varindex == UNUSED)
611 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
612 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
614 #if defined(HAS_4BYTE_STACKSLOT)
615 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
621 * #ifdef HAS_ADDRESS_REGISTER_FILE
628 * } else { / int & lng
632 * must not to be changed!
635 #ifdef HAS_ADDRESS_REGISTER_FILE
636 if (IS_ADR_TYPE(t)) {
637 if ((p < md->paramcount) && !md->params[p].inmemory) {
639 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
641 else if (AVAIL_TMP_ADR) {
643 TAKE_TMP_ADR(v->vv.regoff);
645 /* use unused argument registers as local registers */
646 else if ((p >= md->paramcount) &&
647 (aargcnt < ADR_ARG_CNT))
650 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
652 else if (AVAIL_SAV_ADR) {
654 TAKE_SAV_ADR(v->vv.regoff);
657 v->flags |= INMEMORY;
658 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
663 if (IS_FLT_DBL_TYPE(t)) {
665 v->flags = VAR(fltalloc)->flags;
666 v->vv.regoff = VAR(fltalloc)->vv.regoff;
668 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
669 /* We can only use float arguments as local variables,
670 * if we do not pass them in integer registers. */
671 else if ((p < md->paramcount) && !md->params[p].inmemory) {
673 v->vv.regoff = md->params[p].regoff;
676 else if (AVAIL_TMP_FLT) {
678 TAKE_TMP_FLT(v->vv.regoff);
680 /* use unused argument registers as local registers */
681 else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
683 POP_FRONT(abi_registers_float_argument,
684 fargcnt, v->vv.regoff);
686 else if (AVAIL_SAV_FLT) {
688 TAKE_SAV_FLT(v->vv.regoff);
692 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
694 fltalloc = jd->local_map[s * 5 + t];
698 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
700 * for i386 put all longs in memory
702 if (IS_2_WORD_TYPE(t)) {
704 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
710 v->flags = VAR(intalloc)->flags;
711 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
712 if (!(v->flags & INMEMORY)
713 && IS_2_WORD_TYPE(VAR(intalloc)->type))
714 v->vv.regoff = GET_LOW_REG(
715 VAR(intalloc)->vv.regoff);
718 v->vv.regoff = VAR(intalloc)->vv.regoff;
720 else if ((p < md->paramcount) &&
721 !md->params[p].inmemory)
724 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
725 if (IS_2_WORD_TYPE(t))
727 PACK_REGS(GET_LOW_REG(md->params[p].regoff),
728 GET_HIGH_REG(md->params[p].regoff));
731 v->vv.regoff = md->params[p].regoff;
733 else if (AVAIL_TMP_INT) {
735 TAKE_TMP_INT(v->vv.regoff);
738 * use unused argument registers as local registers
740 else if ((p >= m->parseddesc->paramcount) &&
741 (iargcnt + intregsneeded < INT_ARG_CNT))
744 POP_FRONT_INT(abi_registers_integer_argument,
745 iargcnt, v->vv.regoff);
747 else if (AVAIL_SAV_INT) {
749 TAKE_SAV_INT(v->vv.regoff);
753 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
756 intalloc = jd->local_map[s * 5 + t];
758 #ifdef HAS_ADDRESS_REGISTER_FILE
761 } /* for (tt=0;...) */
763 /* If the current parameter is a 2-word type, the next local slot */
766 if (p < md->paramcount)
767 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
772 /* simplereg_allocate_locals ***************************************************
774 Allocates registers for all local variables.
776 *******************************************************************************/
778 static void simplereg_allocate_locals(jitdata *jd)
784 int s, t, tt, varindex;
785 int intalloc, fltalloc;
788 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
789 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
793 /* get required compiler data */
799 if (code_is_leafmethod(code)) {
800 simplereg_allocate_locals_leafmethod(jd);
804 for (s = 0; s < jd->maxlocals; s++) {
805 intalloc = -1; fltalloc = -1;
806 for (tt=0; tt<=4; tt++) {
809 varindex = jd->local_map[s * 5 + t];
810 if (varindex == UNUSED)
815 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
816 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
819 #if defined(HAS_4BYTE_STACKSLOT)
820 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
823 #ifdef HAS_ADDRESS_REGISTER_FILE
824 if (IS_ADR_TYPE(t)) {
827 TAKE_SAV_ADR(v->vv.regoff);
831 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
836 if (IS_FLT_DBL_TYPE(t)) {
838 v->flags = VAR(fltalloc)->flags;
839 v->vv.regoff = VAR(fltalloc)->vv.regoff;
841 else if (AVAIL_SAV_FLT) {
843 TAKE_SAV_FLT(v->vv.regoff);
847 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
849 fltalloc = jd->local_map[s * 5 + t];
852 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
854 * for i386 put all longs in memory
856 if (IS_2_WORD_TYPE(t)) {
858 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
863 v->flags = VAR(intalloc)->flags;
864 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
865 if (!(v->flags & INMEMORY)
866 && IS_2_WORD_TYPE(VAR(intalloc)->type))
867 v->vv.regoff = GET_LOW_REG(
868 VAR(intalloc)->vv.regoff);
871 v->vv.regoff = VAR(intalloc)->vv.regoff;
873 else if (AVAIL_SAV_INT) {
875 TAKE_SAV_INT(v->vv.regoff);
879 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
881 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
884 intalloc = jd->local_map[s * 5 + t];
886 #ifdef HAS_ADDRESS_REGISTER_FILE
894 static void simplereg_init(jitdata *jd, registerdata *rd)
899 #if defined(HAS_4BYTE_STACKSLOT)
900 rd->freememtop_2 = 0;
903 rd->freetmpinttop = 0;
904 rd->freesavinttop = 0;
905 rd->freetmpflttop = 0;
906 rd->freesavflttop = 0;
907 #ifdef HAS_ADDRESS_REGISTER_FILE
908 rd->freetmpadrtop = 0;
909 rd->freesavadrtop = 0;
912 rd->freearginttop = 0;
913 rd->freeargflttop = 0;
914 #ifdef HAS_ADDRESS_REGISTER_FILE
915 rd->freeargadrtop = 0;
918 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
919 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
920 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
922 /* memcopycount is dynamically allocated when needed */
924 rd->memcopycount = NULL;
925 rd->memcopycountsize = 0;
927 rd->intusedinout = DMNEW(int, INT_REG_CNT);
928 MZERO(rd->intusedinout, int, INT_REG_CNT);
929 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
930 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
932 /* record the interface registers as used */
934 for (i=0; i<rd->argintreguse; ++i)
935 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
936 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
937 rd->intusedinout[rd->tmpintregs[i]] = 1;
938 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
939 rd->intusedinout[rd->savintregs[i]] = 1;
941 for (i=0; i<rd->argfltreguse; ++i)
942 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
943 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
944 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
945 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
946 rd->fltusedinout[rd->savfltregs[i]] = 1;
948 #ifdef HAS_ADDRESS_REGISTER_FILE
949 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
950 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
952 for (i=0; i<rd->argadrreguse; ++i)
953 rd->adrusedinout[rd->argadrregs[i]] = 1;
954 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
955 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
956 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
957 rd->adrusedinout[rd->savadrregs[i]] = 1;
962 static void simplereg_init_block(registerdata *rd)
966 /* remove all interface registers from the free lists */
968 for (i=0; i<rd->freearginttop; ++i)
969 if (rd->intusedinout[rd->freeargintregs[i]]) {
970 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
972 for (i=0; i<rd->freetmpinttop; ++i)
973 if (rd->intusedinout[rd->freetmpintregs[i]]) {
974 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
976 for (i=0; i<rd->freesavinttop; ++i)
977 if (rd->intusedinout[rd->freesavintregs[i]]) {
978 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
981 for (i=0; i<rd->freeargflttop; ++i)
982 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
983 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
985 for (i=0; i<rd->freetmpflttop; ++i)
986 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
987 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
989 for (i=0; i<rd->freesavflttop; ++i)
990 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
991 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
994 #ifdef HAS_ADDRESS_REGISTER_FILE
995 for (i=0; i<rd->freeargadrtop; ++i)
996 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
997 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
999 for (i=0; i<rd->freetmpadrtop; ++i)
1000 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
1001 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
1003 for (i=0; i<rd->freesavadrtop; ++i)
1004 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1005 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1011 static void simplereg_new_temp(jitdata *jd, s4 index)
1013 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1024 /* assert that constants are not allocated */
1026 assert(v->type != TYPE_RET);
1028 /* Try to allocate a saved register if there is no temporary one */
1029 /* available. This is what happens during the second run. */
1030 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1032 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1033 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1036 #if defined(HAS_4BYTE_STACKSLOT)
1037 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1042 for(; tryagain; --tryagain) {
1043 if (tryagain == 1) {
1044 if (!(v->flags & SAVEDVAR))
1046 #ifdef HAS_ADDRESS_REGISTER_FILE
1047 if (IS_ADR_TYPE(v->type)) {
1048 if (AVAIL_FREE_SAV_ADR) {
1049 TAKE_FREE_SAV_ADR(v->vv.regoff);
1052 else if (AVAIL_SAV_ADR) {
1053 TAKE_SAV_ADR(v->vv.regoff);
1060 if (IS_FLT_DBL_TYPE(v->type)) {
1061 if (AVAIL_FREE_SAV_FLT) {
1062 TAKE_FREE_SAV_FLT(v->vv.regoff);
1065 else if (AVAIL_SAV_FLT) {
1066 TAKE_SAV_FLT(v->vv.regoff);
1071 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1073 * for i386 put all longs in memory
1075 if (!IS_2_WORD_TYPE(v->type))
1078 if (AVAIL_FREE_SAV_INT) {
1079 TAKE_FREE_SAV_INT(v->vv.regoff);
1082 else if (AVAIL_SAV_INT) {
1083 TAKE_SAV_INT(v->vv.regoff);
1090 else { /* tryagain == 2 */
1091 #ifdef HAS_ADDRESS_REGISTER_FILE
1092 if (IS_ADR_TYPE(v->type)) {
1093 if (AVAIL_FREE_TMP_ADR) {
1094 TAKE_FREE_TMP_ADR(v->vv.regoff);
1097 else if (AVAIL_TMP_ADR) {
1098 TAKE_TMP_ADR(v->vv.regoff);
1105 if (IS_FLT_DBL_TYPE(v->type)) {
1106 if (AVAIL_FREE_ARG_FLT) {
1108 TAKE_FREE_ARG_FLT(v->vv.regoff);
1111 else if (AVAIL_ARG_FLT) {
1113 TAKE_ARG_FLT(v->vv.regoff);
1116 else if (AVAIL_FREE_TMP_FLT) {
1117 TAKE_FREE_TMP_FLT(v->vv.regoff);
1120 else if (AVAIL_TMP_FLT) {
1121 TAKE_TMP_FLT(v->vv.regoff);
1127 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1129 * for i386 put all longs in memory
1131 if (!IS_2_WORD_TYPE(v->type))
1134 if (AVAIL_FREE_ARG_INT) {
1136 TAKE_FREE_ARG_INT(v->vv.regoff);
1139 else if (AVAIL_ARG_INT) {
1141 TAKE_ARG_INT(v->vv.regoff);
1144 else if (AVAIL_FREE_TMP_INT) {
1145 TAKE_FREE_TMP_INT(v->vv.regoff);
1148 else if (AVAIL_TMP_INT) {
1149 TAKE_TMP_INT(v->vv.regoff);
1152 } /* if (!IS_2_WORD_TYPE(s->type)) */
1153 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1154 } /* if (IS_ADR_TYPE(s->type)) */
1155 } /* if (tryagain == 1) else */
1156 } /* for(; tryagain; --tryagain) */
1158 /* spill to memory */
1160 v->flags |= INMEMORY;
1162 #if defined(HAS_4BYTE_STACKSLOT)
1163 if ((memneeded == 1) && (rd->freememtop_2 > 0))
1164 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1166 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1167 if ((memneeded == 0) && (rd->freememtop > 0))
1168 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1170 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1174 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1176 /* assert that constants are not freed */
1178 assert(type != TYPE_RET);
1180 /* if this is a copy of another variable, just decrement the copy counter */
1182 if (flags & INMEMORY) {
1188 memindex = regoff / SIZE_OF_STACKSLOT;
1190 if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
1191 rd->memcopycount[memindex]--;
1198 regindex = REG_INDEX(regoff, type);
1200 /* do not free interface registers that are needed as outvars */
1202 if (flags & INOUT) {
1203 if (rd->regisoutvar[regindex]) {
1204 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1208 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1211 if (rd->regcopycount[regindex]) {
1212 rd->regcopycount[regindex]--;
1217 if (flags & INMEMORY) {
1218 #if defined(HAS_4BYTE_STACKSLOT)
1219 if (IS_2_WORD_TYPE(type))
1220 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1223 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1228 /* freeing a register */
1230 #ifdef HAS_ADDRESS_REGISTER_FILE
1231 if (IS_ADR_TYPE(type)) {
1232 if (flags & (SAVEDVAR | SAVREG))
1233 PUSH_FREE_SAV_ADR(regoff);
1235 PUSH_FREE_TMP_ADR(regoff);
1238 else if (IS_FLT_DBL_TYPE(type)) {
1239 if (flags & (SAVEDVAR | SAVREG))
1240 PUSH_FREE_SAV_FLT(regoff);
1241 else if (flags & ARGREG)
1242 PUSH_FREE_ARG_FLT(regoff);
1244 PUSH_FREE_TMP_FLT(regoff);
1246 else { /* IS_INT_LNG_TYPE */
1247 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1248 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1251 if (flags & (SAVEDVAR | SAVREG))
1252 PUSH_FREE_SAV_INT(regoff);
1253 else if (flags & ARGREG)
1254 PUSH_FREE_ARG_INT(regoff);
1256 PUSH_FREE_TMP_INT(regoff);
1261 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1267 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1271 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1276 /* do not coalesce local variables here */
1278 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1284 /* do not coalesce in/out vars or preallocated variables here */
1286 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1289 /* if the source is in memory, we can coalesce in any case */
1291 if (sv->flags & INMEMORY) {
1292 dv->flags |= INMEMORY;
1293 dv->vv.regoff = sv->vv.regoff;
1297 /* we do not allocate a REG_TMP to a REG_SAV variable */
1299 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1303 dv->vv.regoff = sv->vv.regoff;
1304 dv->flags |= sv->flags & (SAVREG | ARGREG);
1310 /* simplereg_allocate_temporaries **********************************************
1312 Allocate temporary (non-interface, non-local) registers.
1314 *******************************************************************************/
1316 static void simplereg_allocate_temporaries(jitdata *jd)
1324 builtintable_entry *bte;
1333 /* get required compiler data */
1338 /* initialize temp registers */
1340 simplereg_init(jd, rd);
1342 bptr = jd->basicblocks;
1344 while (bptr != NULL) {
1345 if (bptr->flags >= BBREACHED) {
1347 LOG(("\nallocating block L%03d\n", bptr->nr));
1349 simplereg_init_block(rd);
1351 /* assert that all copy counts are zero */
1353 #if !defined(NDEBUG) && !defined(ENABLE_SSA)
1354 for (i=0; i < TOTAL_REG_CNT; ++i)
1355 assert(rd->regcopycount[i] == 0);
1358 /* reset outvar flags */
1360 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1362 /* set allocation of invars */
1364 for (i=0; i<bptr->indepth; ++i)
1366 v = VAR(bptr->invars[i]);
1367 if (v->type == TYPE_RET)
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[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]);
1382 if (v->type == TYPE_RET)
1385 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1386 v->flags = jd->interface_map[5*i + v->type].flags;
1388 if (!(v->flags & INMEMORY)) {
1389 regindex = REG_INDEX(v->vv.regoff, v->type);
1390 rd->regcopycount[regindex] = 1;
1391 rd->regisoutvar[regindex] = 1;
1395 /* free interface registers not used in this block */
1397 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1399 regoff = jd->interface_map[i].regoff;
1400 flags = jd->interface_map[i].flags;
1402 if (!(flags & INMEMORY)) {
1403 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1404 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1405 flags, regoff, type));
1406 simplereg_free(rd, flags, regoff, type);
1408 /* mark it, so it is not freed again */
1409 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1414 /* reset copy counts */
1416 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1418 /* iterate over ICMDS to allocate temporary variables */
1420 iptr = bptr->iinstr;
1423 while (--len >= 0) {
1425 switch (iptr->opc) {
1431 case ICMD_CHECKNULL:
1436 case ICMD_PUTSTATICCONST:
1437 case ICMD_INLINE_START:
1438 case ICMD_INLINE_END:
1439 case ICMD_INLINE_BODY:
1442 /* pop 0 push 1 const */
1450 /* pop 0 push 1 load */
1457 NEW_TEMP_REG(iptr->dst.varindex);
1471 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1472 FREE_TEMP_REG(iptr->s1.varindex);
1473 NEW_TEMP_REG(iptr->dst.varindex);
1487 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1488 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1489 FREE_TEMP_REG(iptr->s1.varindex);
1492 /* pop 1 push 0 store */
1512 case ICMD_PUTSTATIC:
1513 case ICMD_PUTFIELDCONST:
1515 /* pop 1 push 0 branch */
1518 case ICMD_IFNONNULL:
1534 /* pop 1 push 0 table branch */
1536 case ICMD_TABLESWITCH:
1537 case ICMD_LOOKUPSWITCH:
1539 case ICMD_MONITORENTER:
1540 case ICMD_MONITOREXIT:
1541 FREE_TEMP_REG(iptr->s1.varindex);
1544 /* pop 2 push 0 branch */
1546 case ICMD_IF_ICMPEQ:
1547 case ICMD_IF_ICMPNE:
1548 case ICMD_IF_ICMPLT:
1549 case ICMD_IF_ICMPGE:
1550 case ICMD_IF_ICMPGT:
1551 case ICMD_IF_ICMPLE:
1553 case ICMD_IF_LCMPEQ:
1554 case ICMD_IF_LCMPNE:
1555 case ICMD_IF_LCMPLT:
1556 case ICMD_IF_LCMPGE:
1557 case ICMD_IF_LCMPGT:
1558 case ICMD_IF_LCMPLE:
1560 case ICMD_IF_ACMPEQ:
1561 case ICMD_IF_ACMPNE:
1569 case ICMD_IASTORECONST:
1570 case ICMD_LASTORECONST:
1571 case ICMD_AASTORECONST:
1572 case ICMD_BASTORECONST:
1573 case ICMD_CASTORECONST:
1574 case ICMD_SASTORECONST:
1575 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1576 FREE_TEMP_REG(iptr->s1.varindex);
1579 /* pop 0 push 1 copy */
1582 /* src === dst->prev (identical Stackslot Element) */
1583 /* src --> dst (copied value, take same reg/mem) */
1585 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1586 NEW_TEMP_REG(iptr->dst.varindex);
1589 v = VAROP(iptr->dst);
1591 if (v->flags & INMEMORY) {
1592 int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
1593 if (memindex >= rd->memcopycountsize) {
1594 int newsize = (memindex + 1) * 2;
1595 i = rd->memcopycountsize;
1596 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1597 MZERO(rd->memcopycount + i, int, newsize - i);
1598 rd->memcopycountsize = newsize;
1600 rd->memcopycount[memindex]++;
1603 /* XXX split reg/mem variables on arm may need special handling here */
1605 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1607 rd->regcopycount[regindex]++;
1612 /* pop 1 push 1 move */
1615 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1616 NEW_TEMP_REG(iptr->dst.varindex);
1617 FREE_TEMP_REG(iptr->s1.varindex);
1667 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1668 FREE_TEMP_REG(iptr->s1.varindex);
1669 NEW_TEMP_REG(iptr->dst.varindex);
1674 case ICMD_IADDCONST:
1675 case ICMD_ISUBCONST:
1676 case ICMD_IMULCONST:
1680 case ICMD_IANDCONST:
1682 case ICMD_IXORCONST:
1683 case ICMD_ISHLCONST:
1684 case ICMD_ISHRCONST:
1685 case ICMD_IUSHRCONST:
1687 case ICMD_LADDCONST:
1688 case ICMD_LSUBCONST:
1689 case ICMD_LMULCONST:
1693 case ICMD_LANDCONST:
1695 case ICMD_LXORCONST:
1696 case ICMD_LSHLCONST:
1697 case ICMD_LSHRCONST:
1698 case ICMD_LUSHRCONST:
1703 case ICMD_INT2SHORT:
1721 case ICMD_CHECKCAST:
1723 case ICMD_ARRAYLENGTH:
1724 case ICMD_INSTANCEOF:
1727 case ICMD_ANEWARRAY:
1730 FREE_TEMP_REG(iptr->s1.varindex);
1731 NEW_TEMP_REG(iptr->dst.varindex);
1736 case ICMD_GETSTATIC:
1739 NEW_TEMP_REG(iptr->dst.varindex);
1742 /* pop many push any */
1744 case ICMD_INVOKESTATIC:
1745 case ICMD_INVOKESPECIAL:
1746 case ICMD_INVOKEVIRTUAL:
1747 case ICMD_INVOKEINTERFACE:
1748 INSTRUCTION_GET_METHODDESC(iptr,md);
1750 argp = iptr->sx.s23.s2.args;
1752 FREE_TEMP_REG(*argp);
1755 if (md->returntype.type != TYPE_VOID)
1756 NEW_TEMP_REG(iptr->dst.varindex);
1760 bte = iptr->sx.s23.s3.bte;
1763 argp = iptr->sx.s23.s2.args;
1765 FREE_TEMP_REG(*argp);
1768 if (md->returntype.type != TYPE_VOID)
1769 NEW_TEMP_REG(iptr->dst.varindex);
1772 case ICMD_MULTIANEWARRAY:
1773 i = iptr->s1.argcount;
1774 argp = iptr->sx.s23.s2.args;
1776 FREE_TEMP_REG(*argp);
1779 NEW_TEMP_REG(iptr->dst.varindex);
1783 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1788 } /* while instructions */
1791 } /* while blocks */
1795 #if defined(ENABLE_STATISTICS)
1796 void simplereg_make_statistics(jitdata *jd)
1804 stackptr src, src_old;
1809 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1813 /* get required compiler data */
1823 /* count how many local variables are held in memory or register */
1824 for(i=0; i < jd->localcount; i++) {
1825 if (VAR(i)->flags & INMEMORY) {
1826 count_locals_spilled++;
1830 count_locals_register++;
1834 /* count how many stack slots are held in memory or register */
1836 bptr = jd->basicblocks;
1838 while (bptr != NULL) {
1839 if (bptr->flags >= BBREACHED) {
1841 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1844 /* check for memory moves from interface to BB instack */
1845 len = bptr->indepth;
1847 if (len > size_interface) size_interface = len;
1851 var = VAR(bptr->invars[len]);
1853 /* invars statistics (currently none) */
1856 /* check for memory moves from BB outstack to interface */
1857 len = bptr->outdepth;
1858 if (len > size_interface) size_interface = len;
1862 var = VAR(bptr->outvars[len]);
1864 /* outvars statistics (currently none) */
1866 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1872 dst = bptr->instack;
1873 iptr = bptr->iinstr;
1877 while (--len >= 0) {
1879 dst = iptr->dst.var;
1881 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1882 switch (src->varkind) {
1885 if (!(src->flags & INMEMORY))
1886 count_ss_register++;
1892 /* case LOCALVAR: */
1893 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1894 /* count_ss_register++; */
1896 /* count_ss_spilled++; */
1899 if (!(src->flags & INMEMORY))
1900 count_argument_mem_ss++;
1902 count_argument_reg_ss++;
1906 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1907 /* if (src->varnum < FLT_ARG_CNT) { */
1908 /* count_ss_register++; */
1912 /* #if defined(__POWERPC__) */
1913 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1915 /* if (src->varnum < INT_ARG_CNT) { */
1917 /* count_ss_register++; */
1921 /* count_ss_spilled++; */
1928 } /* while instructions */
1933 } /* while blocks */
1935 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1936 if (in_register) count_method_in_register++;
1938 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1941 #endif /* defined(ENABLE_STATISTICS) */
1945 * These are local overrides for various environment variables in Emacs.
1946 * Please do not remove this and leave it at the end of the file, where
1947 * Emacs will automagically detect them.
1948 * ---------------------------------------------------------------------
1951 * indent-tabs-mode: t
1955 * vim:noexpandtab:sw=4:ts=4: