1 /* src/vm/jit/allocator/simplereg.c - register allocator
3 Copyright (C) 1996-2005, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
36 #include "mm/memory.h"
38 #include "vm/builtin.h"
39 #include "vm/exceptions.h"
40 #include "vm/resolve.h"
41 #include "vm/stringlocal.h"
43 #include "vm/jit/abi.h"
44 #include "vm/jit/reg.h"
45 #include "vm/jit/show.h"
46 #include "vm/jit/allocator/simplereg.h"
48 #include "vmcore/method.h"
49 #include "vmcore/options.h"
53 # define LOG(args) printf args
59 /* function prototypes for this file ******************************************/
61 static void simplereg_allocate_interfaces(jitdata *jd);
62 static void simplereg_allocate_locals(jitdata *jd);
63 static void simplereg_allocate_temporaries(jitdata *jd);
66 /* size of a stackslot used by the internal ABI */
68 #if defined(HAS_4BYTE_STACKSLOT)
69 # define SIZE_OF_STACKSLOT 4
71 # define SIZE_OF_STACKSLOT 8
75 /* total number of registers */
77 #if defined(HAS_ADDRESS_REGISTER_FILE)
78 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
80 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
84 /* macros for handling register stacks ****************************************/
86 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
87 #define AVAIL_BACK(cnt) ((cnt) > 0)
89 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
90 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
91 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
93 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
94 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
97 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
98 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
99 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
100 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
102 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
103 #define POP_FRONT_INT(stk, cnt, reg) \
105 if (intregsneeded) { \
106 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
110 POP_FRONT(stk, cnt, reg); \
113 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
116 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
117 #define POP_BACK_INT(stk, cnt, reg) \
119 if (intregsneeded) { \
121 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
124 POP_BACK(stk, cnt, reg); \
127 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
130 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
131 #define PUSH_BACK_INT(stk, cnt, reg) \
133 if (intregsneeded) { \
134 stk[cnt] = GET_LOW_REG(reg); \
135 stk[cnt + 1] = GET_HIGH_REG(reg); \
139 PUSH_BACK(stk, cnt, reg); \
142 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
145 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
146 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
147 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
149 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
150 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
151 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
153 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
154 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
155 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
157 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
158 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
159 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
161 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
162 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
163 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
165 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
166 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
167 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
169 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
170 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
171 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
173 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
174 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
175 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
177 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
178 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
179 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
181 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
182 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
183 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
185 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
186 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
187 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
189 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
190 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
191 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
193 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
194 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
195 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
197 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
198 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
199 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
201 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
202 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
203 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
206 /* macros for allocating memory slots ****************************************/
208 #define NEW_MEM_SLOT(r) \
210 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
211 rd->memuse += memneeded + 1; \
214 #define NEW_MEM_SLOT_ALIGNED(r) \
216 if ( (memneeded) && (rd->memuse & 1)) \
218 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
219 rd->memuse += memneeded + 1; \
222 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r) \
224 if ( (memneeded) && (rd->memuse & 1)) { \
225 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
228 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
229 rd->memuse += memneeded + 1; \
232 #if defined(ALIGN_LONGS_IN_MEMORY)
233 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT_ALIGNED(r)
235 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
238 #if defined(ALIGN_DOUBLES_IN_MEMORY)
239 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT_ALIGNED(r)
241 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
244 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
245 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
247 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
251 /* macros for creating/freeing temporary variables ***************************/
253 #define NEW_TEMP_REG(index) \
254 if ( ((index) >= jd->localcount) \
255 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
256 simplereg_new_temp(jd, (index))
259 #define FREE_TEMP_REG(index) \
260 if (((index) > jd->localcount) \
261 && (!(VAR(index)->flags & (PREALLOC)))) \
262 simplereg_free_temp(jd, (index))
265 /* macro for getting a unique register index *********************************/
267 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
268 #define REG_INDEX_NON_ADR(regoff, type) \
269 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
271 #define REG_INDEX_NON_ADR(regoff, type) \
272 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
275 #if defined(HAS_ADDRESS_REGISTER_FILE)
276 #define REG_INDEX(regoff, type) \
277 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
279 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
283 /* regalloc ********************************************************************
285 Does a simple register allocation.
287 *******************************************************************************/
289 bool regalloc(jitdata *jd)
291 /* There is a problem with the use of unused float argument
292 registers in leafmethods for stackslots on c7 (2 * Dual Core
293 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
294 benchmark is heaviliy increased. This could be prevented by
295 setting rd->argfltreguse to FLT_ARG_CNT before calling
296 simplereg_allocate_temporaries and setting it back to the original
297 value before calling simplereg_allocate_locals. */
299 simplereg_allocate_interfaces(jd);
300 simplereg_allocate_temporaries(jd);
301 simplereg_allocate_locals(jd);
309 /* simplereg_allocate_interfaces ***********************************************
311 Allocates registers for all interface variables.
313 *******************************************************************************/
315 static void simplereg_allocate_interfaces(jitdata *jd)
323 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
324 /* in case more vars are packed into this interface slot */
326 /* Allocate LNG and DBL types first to ensure 2 memory slots or */
327 /* registers on HAS_4BYTE_STACKSLOT architectures. */
328 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
330 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
334 /* get required compiler data */
341 /* rd->memuse was already set in stack.c to allocate stack space
342 for passing arguments to called methods. */
344 #if defined(__I386__)
345 if (checksync && code_is_synchronized(code)) {
346 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
352 if (code_is_leafmethod(code)) {
353 /* Reserve argument register, which will be used for Locals acting */
355 if (rd->argintreguse < m->parseddesc->argintreguse)
356 rd->argintreguse = m->parseddesc->argintreguse;
357 if (rd->argfltreguse < m->parseddesc->argfltreguse)
358 rd->argfltreguse = m->parseddesc->argfltreguse;
359 #ifdef HAS_ADDRESS_REGISTER_FILE
360 if (rd->argadrreguse < m->parseddesc->argadrreguse)
361 rd->argadrreguse = m->parseddesc->argadrreguse;
365 for (s = 0; s < jd->maxinterfaces; s++) {
366 intalloc = -1; fltalloc = -1;
368 /* check if the interface at this stack depth must be a SAVEDVAR */
372 for (tt = 0; tt <=4; tt++) {
373 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
374 saved |= t & SAVEDVAR;
378 /* allocate reg/mem for each type the interface is used as */
380 for (tt = 0; tt <= 4; tt++) {
382 if (jd->interface_map[s * 5 + t].flags == UNUSED)
386 regoff = -1; /* initialize to invalid value */
388 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
389 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
392 #if defined(HAS_4BYTE_STACKSLOT)
393 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
397 #if defined(HAS_ADDRESS_REGISTER_FILE)
398 if (IS_ADR_TYPE(t)) {
399 if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
401 TAKE_ARG_ADR(regoff);
403 else if (AVAIL_TMP_ADR) {
404 TAKE_TMP_ADR(regoff);
406 else if (AVAIL_SAV_ADR) {
408 TAKE_SAV_ADR(regoff);
412 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
415 else /* !IS_ADR_TYPE */
416 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
418 if (IS_FLT_DBL_TYPE(t)) {
420 /* Reuse memory slot(s)/register(s) for shared interface slots */
421 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
422 regoff = jd->interface_map[fltalloc].regoff;
424 else if (AVAIL_ARG_FLT) {
426 TAKE_ARG_FLT(regoff);
428 else if (AVAIL_TMP_FLT) {
429 TAKE_TMP_FLT(regoff);
431 else if (AVAIL_SAV_FLT) {
433 TAKE_SAV_FLT(regoff);
437 NEW_MEM_SLOT_FLT_DBL(regoff);
439 fltalloc = s * 5 + t;
441 else { /* !IS_FLT_DBL_TYPE(t) */
442 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
444 * for i386 put all longs in memory
446 if (IS_2_WORD_TYPE(t)) {
448 NEW_MEM_SLOT_INT_LNG(regoff);
453 /* Reuse memory slot(s)/register(s) for shared interface slots */
454 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
455 regoff = jd->interface_map[intalloc].regoff;
456 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
457 /* reuse lower half */
458 if (!(flags & INMEMORY)
459 && IS_2_WORD_TYPE(intalloc % 5))
460 regoff = GET_LOW_REG(regoff);
466 TAKE_ARG_INT(regoff);
468 else if (AVAIL_TMP_INT) {
469 TAKE_TMP_INT(regoff);
471 else if (AVAIL_SAV_INT) {
473 TAKE_SAV_INT(regoff);
477 NEW_MEM_SLOT_INT_LNG(regoff);
481 intalloc = s * 5 + t;
482 } /* if (IS_FLT_DBL_TYPE(t)) */
486 /* now the same like above, but without a chance to take a temporary register */
487 #ifdef HAS_ADDRESS_REGISTER_FILE
488 if (IS_ADR_TYPE(t)) {
490 TAKE_SAV_ADR(regoff);
494 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
500 if (IS_FLT_DBL_TYPE(t)) {
502 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
503 regoff = jd->interface_map[fltalloc].regoff;
507 TAKE_SAV_FLT(regoff);
511 NEW_MEM_SLOT_FLT_DBL(regoff);
514 fltalloc = s * 5 + t;
516 else { /* IS_INT_LNG */
517 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
519 * for i386 put all longs in memory
521 if (IS_2_WORD_TYPE(t)) {
523 NEW_MEM_SLOT_INT_LNG(regoff);
529 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
530 regoff = jd->interface_map[intalloc].regoff;
531 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
532 /* reuse lower half */
533 if (!(flags & INMEMORY)
534 && IS_2_WORD_TYPE(intalloc % 5))
535 regoff = GET_LOW_REG(regoff);
540 TAKE_SAV_INT(regoff);
544 NEW_MEM_SLOT_INT_LNG(regoff);
549 } /* if (IS_FLT_DBL_TYPE(t) else */
550 } /* if (IS_ADR_TYPE(t)) else */
551 } /* if (saved) else */
555 jd->interface_map[5*s + t].flags = flags | INOUT;
556 jd->interface_map[5*s + t].regoff = regoff;
562 /* simplereg_allocate_locals_leafmethod ****************************************
564 Allocates registers for all local variables of a leafmethod.
566 *******************************************************************************/
568 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
575 int p, s, t, tt, varindex;
576 int intalloc, fltalloc;
578 int intregsneeded = 0;
580 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
581 int fargcnt, iargcnt;
582 #ifdef HAS_ADDRESS_REGISTER_FILE
586 /* get required compiler data */
594 iargcnt = rd->argintreguse;
595 fargcnt = rd->argfltreguse;
596 #ifdef HAS_ADDRESS_REGISTER_FILE
597 aargcnt = rd->argadrreguse;
599 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
600 intalloc = -1; fltalloc = -1;
601 for (tt = 0; tt <= 4; tt++) {
603 varindex = jd->local_map[s * 5 + t];
604 if (varindex == UNUSED)
609 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
610 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
612 #if defined(HAS_4BYTE_STACKSLOT)
613 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
619 * #ifdef HAS_ADDRESS_REGISTER_FILE
626 * } else { / int & lng
630 * must not to be changed!
633 #ifdef HAS_ADDRESS_REGISTER_FILE
634 if (IS_ADR_TYPE(t)) {
635 if ((p < md->paramcount) && !md->params[p].inmemory) {
637 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
639 else if (AVAIL_TMP_ADR) {
641 TAKE_TMP_ADR(v->vv.regoff);
643 /* use unused argument registers as local registers */
644 else if ((p >= md->paramcount) &&
645 (aargcnt < ADR_ARG_CNT))
648 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
650 else if (AVAIL_SAV_ADR) {
652 TAKE_SAV_ADR(v->vv.regoff);
655 v->flags |= INMEMORY;
656 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
661 if (IS_FLT_DBL_TYPE(t)) {
663 v->flags = VAR(fltalloc)->flags;
664 v->vv.regoff = VAR(fltalloc)->vv.regoff;
666 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
667 /* We can only use float arguments as local variables,
668 * if we do not pass them in integer registers. */
669 else if ((p < md->paramcount) && !md->params[p].inmemory) {
671 v->vv.regoff = md->params[p].regoff;
674 else if (AVAIL_TMP_FLT) {
676 TAKE_TMP_FLT(v->vv.regoff);
678 /* use unused argument registers as local registers */
679 else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
681 POP_FRONT(abi_registers_float_argument,
682 fargcnt, v->vv.regoff);
684 else if (AVAIL_SAV_FLT) {
686 TAKE_SAV_FLT(v->vv.regoff);
690 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
692 fltalloc = jd->local_map[s * 5 + t];
696 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
698 * for i386 put all longs in memory
700 if (IS_2_WORD_TYPE(t)) {
702 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
708 v->flags = VAR(intalloc)->flags;
709 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
710 if (!(v->flags & INMEMORY)
711 && IS_2_WORD_TYPE(VAR(intalloc)->type))
712 v->vv.regoff = GET_LOW_REG(
713 VAR(intalloc)->vv.regoff);
716 v->vv.regoff = VAR(intalloc)->vv.regoff;
718 else if ((p < md->paramcount) &&
719 !md->params[p].inmemory)
722 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
723 if (IS_2_WORD_TYPE(t))
725 PACK_REGS(GET_LOW_REG(md->params[p].regoff),
726 GET_HIGH_REG(md->params[p].regoff));
729 v->vv.regoff = 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(abi_registers_integer_argument,
743 iargcnt, v->vv.regoff);
745 else if (AVAIL_SAV_INT) {
747 TAKE_SAV_INT(v->vv.regoff);
751 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
754 intalloc = jd->local_map[s * 5 + t];
756 #ifdef HAS_ADDRESS_REGISTER_FILE
759 } /* for (tt=0;...) */
761 /* If the current parameter is a 2-word type, the next local slot */
764 if (p < md->paramcount)
765 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
770 /* simplereg_allocate_locals ***************************************************
772 Allocates registers for all local variables.
774 *******************************************************************************/
776 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 */
797 if (code_is_leafmethod(code)) {
798 simplereg_allocate_locals_leafmethod(jd);
802 for (s = 0; s < jd->maxlocals; s++) {
803 intalloc = -1; fltalloc = -1;
804 for (tt=0; tt<=4; tt++) {
807 varindex = jd->local_map[s * 5 + t];
808 if (varindex == UNUSED)
813 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
814 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
817 #if defined(HAS_4BYTE_STACKSLOT)
818 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
821 #ifdef HAS_ADDRESS_REGISTER_FILE
822 if (IS_ADR_TYPE(t)) {
825 TAKE_SAV_ADR(v->vv.regoff);
829 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
834 if (IS_FLT_DBL_TYPE(t)) {
836 v->flags = VAR(fltalloc)->flags;
837 v->vv.regoff = VAR(fltalloc)->vv.regoff;
839 else if (AVAIL_SAV_FLT) {
841 TAKE_SAV_FLT(v->vv.regoff);
845 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
847 fltalloc = jd->local_map[s * 5 + t];
850 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
852 * for i386 put all longs in memory
854 if (IS_2_WORD_TYPE(t)) {
856 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
861 v->flags = VAR(intalloc)->flags;
862 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
863 if (!(v->flags & INMEMORY)
864 && IS_2_WORD_TYPE(VAR(intalloc)->type))
865 v->vv.regoff = GET_LOW_REG(
866 VAR(intalloc)->vv.regoff);
869 v->vv.regoff = VAR(intalloc)->vv.regoff;
871 else if (AVAIL_SAV_INT) {
873 TAKE_SAV_INT(v->vv.regoff);
877 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
879 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
882 intalloc = jd->local_map[s * 5 + t];
884 #ifdef HAS_ADDRESS_REGISTER_FILE
892 static void simplereg_init(jitdata *jd, registerdata *rd)
897 #if defined(HAS_4BYTE_STACKSLOT)
898 rd->freememtop_2 = 0;
901 rd->freetmpinttop = 0;
902 rd->freesavinttop = 0;
903 rd->freetmpflttop = 0;
904 rd->freesavflttop = 0;
905 #ifdef HAS_ADDRESS_REGISTER_FILE
906 rd->freetmpadrtop = 0;
907 rd->freesavadrtop = 0;
910 rd->freearginttop = 0;
911 rd->freeargflttop = 0;
912 #ifdef HAS_ADDRESS_REGISTER_FILE
913 rd->freeargadrtop = 0;
916 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
917 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
918 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
920 /* memcopycount is dynamically allocated when needed */
922 rd->memcopycount = NULL;
923 rd->memcopycountsize = 0;
925 rd->intusedinout = DMNEW(int, INT_REG_CNT);
926 MZERO(rd->intusedinout, int, INT_REG_CNT);
927 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
928 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
930 /* record the interface registers as used */
932 for (i=0; i<rd->argintreguse; ++i)
933 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
934 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
935 rd->intusedinout[rd->tmpintregs[i]] = 1;
936 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
937 rd->intusedinout[rd->savintregs[i]] = 1;
939 for (i=0; i<rd->argfltreguse; ++i)
940 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
941 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
942 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
943 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
944 rd->fltusedinout[rd->savfltregs[i]] = 1;
946 #ifdef HAS_ADDRESS_REGISTER_FILE
947 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
948 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
950 for (i=0; i<rd->argadrreguse; ++i)
951 rd->adrusedinout[rd->argadrregs[i]] = 1;
952 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
953 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
954 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
955 rd->adrusedinout[rd->savadrregs[i]] = 1;
960 static void simplereg_init_block(registerdata *rd)
964 /* remove all interface registers from the free lists */
966 for (i=0; i<rd->freearginttop; ++i)
967 if (rd->intusedinout[rd->freeargintregs[i]]) {
968 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
970 for (i=0; i<rd->freetmpinttop; ++i)
971 if (rd->intusedinout[rd->freetmpintregs[i]]) {
972 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
974 for (i=0; i<rd->freesavinttop; ++i)
975 if (rd->intusedinout[rd->freesavintregs[i]]) {
976 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
979 for (i=0; i<rd->freeargflttop; ++i)
980 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
981 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
983 for (i=0; i<rd->freetmpflttop; ++i)
984 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
985 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
987 for (i=0; i<rd->freesavflttop; ++i)
988 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
989 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
992 #ifdef HAS_ADDRESS_REGISTER_FILE
993 for (i=0; i<rd->freeargadrtop; ++i)
994 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
995 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
997 for (i=0; i<rd->freetmpadrtop; ++i)
998 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
999 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
1001 for (i=0; i<rd->freesavadrtop; ++i)
1002 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1003 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1009 static void simplereg_new_temp(jitdata *jd, s4 index)
1011 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1022 /* assert that constants are not allocated */
1024 assert(v->type != TYPE_RET);
1026 /* Try to allocate a saved register if there is no temporary one */
1027 /* available. This is what happens during the second run. */
1028 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1030 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1031 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1034 #if defined(HAS_4BYTE_STACKSLOT)
1035 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1040 for(; tryagain; --tryagain) {
1041 if (tryagain == 1) {
1042 if (!(v->flags & SAVEDVAR))
1044 #ifdef HAS_ADDRESS_REGISTER_FILE
1045 if (IS_ADR_TYPE(v->type)) {
1046 if (AVAIL_FREE_SAV_ADR) {
1047 TAKE_FREE_SAV_ADR(v->vv.regoff);
1050 else if (AVAIL_SAV_ADR) {
1051 TAKE_SAV_ADR(v->vv.regoff);
1058 if (IS_FLT_DBL_TYPE(v->type)) {
1059 if (AVAIL_FREE_SAV_FLT) {
1060 TAKE_FREE_SAV_FLT(v->vv.regoff);
1063 else if (AVAIL_SAV_FLT) {
1064 TAKE_SAV_FLT(v->vv.regoff);
1069 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1071 * for i386 put all longs in memory
1073 if (!IS_2_WORD_TYPE(v->type))
1076 if (AVAIL_FREE_SAV_INT) {
1077 TAKE_FREE_SAV_INT(v->vv.regoff);
1080 else if (AVAIL_SAV_INT) {
1081 TAKE_SAV_INT(v->vv.regoff);
1088 else { /* tryagain == 2 */
1089 #ifdef HAS_ADDRESS_REGISTER_FILE
1090 if (IS_ADR_TYPE(v->type)) {
1091 if (AVAIL_FREE_TMP_ADR) {
1092 TAKE_FREE_TMP_ADR(v->vv.regoff);
1095 else if (AVAIL_TMP_ADR) {
1096 TAKE_TMP_ADR(v->vv.regoff);
1103 if (IS_FLT_DBL_TYPE(v->type)) {
1104 if (AVAIL_FREE_ARG_FLT) {
1106 TAKE_FREE_ARG_FLT(v->vv.regoff);
1109 else if (AVAIL_ARG_FLT) {
1111 TAKE_ARG_FLT(v->vv.regoff);
1114 else if (AVAIL_FREE_TMP_FLT) {
1115 TAKE_FREE_TMP_FLT(v->vv.regoff);
1118 else if (AVAIL_TMP_FLT) {
1119 TAKE_TMP_FLT(v->vv.regoff);
1125 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1127 * for i386 put all longs in memory
1129 if (!IS_2_WORD_TYPE(v->type))
1132 if (AVAIL_FREE_ARG_INT) {
1134 TAKE_FREE_ARG_INT(v->vv.regoff);
1137 else if (AVAIL_ARG_INT) {
1139 TAKE_ARG_INT(v->vv.regoff);
1142 else if (AVAIL_FREE_TMP_INT) {
1143 TAKE_FREE_TMP_INT(v->vv.regoff);
1146 else if (AVAIL_TMP_INT) {
1147 TAKE_TMP_INT(v->vv.regoff);
1150 } /* if (!IS_2_WORD_TYPE(s->type)) */
1151 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1152 } /* if (IS_ADR_TYPE(s->type)) */
1153 } /* if (tryagain == 1) else */
1154 } /* for(; tryagain; --tryagain) */
1156 /* spill to memory */
1158 v->flags |= INMEMORY;
1160 #if defined(HAS_4BYTE_STACKSLOT)
1161 if ((memneeded == 1) && (rd->freememtop_2 > 0))
1162 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1164 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1165 if ((memneeded == 0) && (rd->freememtop > 0))
1166 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1168 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1172 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1174 /* assert that constants are not freed */
1176 assert(type != TYPE_RET);
1178 /* if this is a copy of another variable, just decrement the copy counter */
1180 if (flags & INMEMORY) {
1186 memindex = regoff / SIZE_OF_STACKSLOT;
1188 if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
1189 rd->memcopycount[memindex]--;
1196 regindex = REG_INDEX(regoff, type);
1198 /* do not free interface registers that are needed as outvars */
1200 if (flags & INOUT) {
1201 if (rd->regisoutvar[regindex]) {
1202 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1206 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1209 if (rd->regcopycount[regindex]) {
1210 rd->regcopycount[regindex]--;
1215 if (flags & INMEMORY) {
1216 #if defined(HAS_4BYTE_STACKSLOT)
1217 if (IS_2_WORD_TYPE(type))
1218 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1221 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1226 /* freeing a register */
1228 #ifdef HAS_ADDRESS_REGISTER_FILE
1229 if (IS_ADR_TYPE(type)) {
1230 if (flags & (SAVEDVAR | SAVREG))
1231 PUSH_FREE_SAV_ADR(regoff);
1233 PUSH_FREE_TMP_ADR(regoff);
1236 else if (IS_FLT_DBL_TYPE(type)) {
1237 if (flags & (SAVEDVAR | SAVREG))
1238 PUSH_FREE_SAV_FLT(regoff);
1239 else if (flags & ARGREG)
1240 PUSH_FREE_ARG_FLT(regoff);
1242 PUSH_FREE_TMP_FLT(regoff);
1244 else { /* IS_INT_LNG_TYPE */
1245 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1246 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1249 if (flags & (SAVEDVAR | SAVREG))
1250 PUSH_FREE_SAV_INT(regoff);
1251 else if (flags & ARGREG)
1252 PUSH_FREE_ARG_INT(regoff);
1254 PUSH_FREE_TMP_INT(regoff);
1259 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1265 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1269 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1274 /* do not coalesce local variables here */
1276 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1282 /* do not coalesce in/out vars or preallocated variables here */
1284 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1287 /* if the source is in memory, we can coalesce in any case */
1289 if (sv->flags & INMEMORY) {
1290 dv->flags |= INMEMORY;
1291 dv->vv.regoff = sv->vv.regoff;
1295 /* we do not allocate a REG_TMP to a REG_SAV variable */
1297 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1301 dv->vv.regoff = sv->vv.regoff;
1302 dv->flags |= sv->flags & (SAVREG | ARGREG);
1308 /* simplereg_allocate_temporaries **********************************************
1310 Allocate temporary (non-interface, non-local) registers.
1312 *******************************************************************************/
1314 static void simplereg_allocate_temporaries(jitdata *jd)
1322 builtintable_entry *bte;
1331 /* get required compiler data */
1336 /* initialize temp registers */
1338 simplereg_init(jd, rd);
1340 bptr = jd->basicblocks;
1342 while (bptr != NULL) {
1343 if (bptr->flags >= BBREACHED) {
1345 LOG(("\nallocating block L%03d\n", bptr->nr));
1347 simplereg_init_block(rd);
1349 /* assert that all copy counts are zero */
1351 #if !defined(NDEBUG) && !defined(ENABLE_SSA)
1352 for (i=0; i < TOTAL_REG_CNT; ++i)
1353 assert(rd->regcopycount[i] == 0);
1356 /* reset outvar flags */
1358 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1360 /* set allocation of invars */
1362 for (i=0; i<bptr->indepth; ++i)
1364 v = VAR(bptr->invars[i]);
1365 if (v->type == TYPE_RET)
1368 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1369 v->flags = jd->interface_map[5*i + v->type].flags;
1371 if (!(v->flags & INMEMORY))
1372 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1375 /* set allocation of outvars */
1377 for (i=0; i<bptr->outdepth; ++i)
1379 v = VAR(bptr->outvars[i]);
1380 if (v->type == TYPE_RET)
1383 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1384 v->flags = jd->interface_map[5*i + v->type].flags;
1386 if (!(v->flags & INMEMORY)) {
1387 regindex = REG_INDEX(v->vv.regoff, v->type);
1388 rd->regcopycount[regindex] = 1;
1389 rd->regisoutvar[regindex] = 1;
1393 /* free interface registers not used in this block */
1395 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1397 regoff = jd->interface_map[i].regoff;
1398 flags = jd->interface_map[i].flags;
1400 if (!(flags & INMEMORY)) {
1401 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1402 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1403 flags, regoff, type));
1404 simplereg_free(rd, flags, regoff, type);
1406 /* mark it, so it is not freed again */
1407 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1412 /* reset copy counts */
1414 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1416 /* iterate over ICMDS to allocate temporary variables */
1418 iptr = bptr->iinstr;
1421 while (--len >= 0) {
1423 switch (iptr->opc) {
1429 case ICMD_CHECKNULL:
1434 case ICMD_PUTSTATICCONST:
1435 case ICMD_INLINE_START:
1436 case ICMD_INLINE_END:
1437 case ICMD_INLINE_BODY:
1440 /* pop 0 push 1 const */
1448 /* pop 0 push 1 load */
1455 NEW_TEMP_REG(iptr->dst.varindex);
1469 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1470 FREE_TEMP_REG(iptr->s1.varindex);
1471 NEW_TEMP_REG(iptr->dst.varindex);
1485 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1486 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1487 FREE_TEMP_REG(iptr->s1.varindex);
1490 /* pop 1 push 0 store */
1510 case ICMD_PUTSTATIC:
1511 case ICMD_PUTFIELDCONST:
1513 /* pop 1 push 0 branch */
1516 case ICMD_IFNONNULL:
1532 /* pop 1 push 0 table branch */
1534 case ICMD_TABLESWITCH:
1535 case ICMD_LOOKUPSWITCH:
1537 case ICMD_MONITORENTER:
1538 case ICMD_MONITOREXIT:
1539 FREE_TEMP_REG(iptr->s1.varindex);
1542 /* pop 2 push 0 branch */
1544 case ICMD_IF_ICMPEQ:
1545 case ICMD_IF_ICMPNE:
1546 case ICMD_IF_ICMPLT:
1547 case ICMD_IF_ICMPGE:
1548 case ICMD_IF_ICMPGT:
1549 case ICMD_IF_ICMPLE:
1551 case ICMD_IF_LCMPEQ:
1552 case ICMD_IF_LCMPNE:
1553 case ICMD_IF_LCMPLT:
1554 case ICMD_IF_LCMPGE:
1555 case ICMD_IF_LCMPGT:
1556 case ICMD_IF_LCMPLE:
1558 case ICMD_IF_ACMPEQ:
1559 case ICMD_IF_ACMPNE:
1567 case ICMD_IASTORECONST:
1568 case ICMD_LASTORECONST:
1569 case ICMD_AASTORECONST:
1570 case ICMD_BASTORECONST:
1571 case ICMD_CASTORECONST:
1572 case ICMD_SASTORECONST:
1573 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1574 FREE_TEMP_REG(iptr->s1.varindex);
1577 /* pop 0 push 1 copy */
1580 /* src === dst->prev (identical Stackslot Element) */
1581 /* src --> dst (copied value, take same reg/mem) */
1583 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1584 NEW_TEMP_REG(iptr->dst.varindex);
1587 v = VAROP(iptr->dst);
1589 if (v->flags & INMEMORY) {
1590 int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
1591 if (memindex >= rd->memcopycountsize) {
1592 int newsize = (memindex + 1) * 2;
1593 i = rd->memcopycountsize;
1594 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1595 MZERO(rd->memcopycount + i, int, newsize - i);
1596 rd->memcopycountsize = newsize;
1598 rd->memcopycount[memindex]++;
1601 /* XXX split reg/mem variables on arm may need special handling here */
1603 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1605 rd->regcopycount[regindex]++;
1610 /* pop 1 push 1 move */
1613 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1614 NEW_TEMP_REG(iptr->dst.varindex);
1615 FREE_TEMP_REG(iptr->s1.varindex);
1665 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1666 FREE_TEMP_REG(iptr->s1.varindex);
1667 NEW_TEMP_REG(iptr->dst.varindex);
1672 case ICMD_IADDCONST:
1673 case ICMD_ISUBCONST:
1674 case ICMD_IMULCONST:
1678 case ICMD_IANDCONST:
1680 case ICMD_IXORCONST:
1681 case ICMD_ISHLCONST:
1682 case ICMD_ISHRCONST:
1683 case ICMD_IUSHRCONST:
1685 case ICMD_LADDCONST:
1686 case ICMD_LSUBCONST:
1687 case ICMD_LMULCONST:
1691 case ICMD_LANDCONST:
1693 case ICMD_LXORCONST:
1694 case ICMD_LSHLCONST:
1695 case ICMD_LSHRCONST:
1696 case ICMD_LUSHRCONST:
1701 case ICMD_INT2SHORT:
1719 case ICMD_CHECKCAST:
1721 case ICMD_ARRAYLENGTH:
1722 case ICMD_INSTANCEOF:
1725 case ICMD_ANEWARRAY:
1728 FREE_TEMP_REG(iptr->s1.varindex);
1729 NEW_TEMP_REG(iptr->dst.varindex);
1734 case ICMD_GETSTATIC:
1737 NEW_TEMP_REG(iptr->dst.varindex);
1740 /* pop many push any */
1742 case ICMD_INVOKESTATIC:
1743 case ICMD_INVOKESPECIAL:
1744 case ICMD_INVOKEVIRTUAL:
1745 case ICMD_INVOKEINTERFACE:
1746 INSTRUCTION_GET_METHODDESC(iptr,md);
1748 argp = iptr->sx.s23.s2.args;
1750 FREE_TEMP_REG(*argp);
1753 if (md->returntype.type != TYPE_VOID)
1754 NEW_TEMP_REG(iptr->dst.varindex);
1758 bte = iptr->sx.s23.s3.bte;
1761 argp = iptr->sx.s23.s2.args;
1763 FREE_TEMP_REG(*argp);
1766 if (md->returntype.type != TYPE_VOID)
1767 NEW_TEMP_REG(iptr->dst.varindex);
1770 case ICMD_MULTIANEWARRAY:
1771 i = iptr->s1.argcount;
1772 argp = iptr->sx.s23.s2.args;
1774 FREE_TEMP_REG(*argp);
1777 NEW_TEMP_REG(iptr->dst.varindex);
1781 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1786 } /* while instructions */
1789 } /* while blocks */
1793 #if defined(ENABLE_STATISTICS)
1794 void simplereg_make_statistics(jitdata *jd)
1802 stackelement_t* src, src_old;
1803 stackelement_t* dst;
1807 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1811 /* get required compiler data */
1821 /* count how many local variables are held in memory or register */
1822 for(i=0; i < jd->localcount; i++) {
1823 if (VAR(i)->flags & INMEMORY) {
1824 count_locals_spilled++;
1828 count_locals_register++;
1832 /* count how many stack slots are held in memory or register */
1834 bptr = jd->basicblocks;
1836 while (bptr != NULL) {
1837 if (bptr->flags >= BBREACHED) {
1839 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1842 /* check for memory moves from interface to BB instack */
1843 len = bptr->indepth;
1845 if (len > size_interface) size_interface = len;
1849 var = VAR(bptr->invars[len]);
1851 /* invars statistics (currently none) */
1854 /* check for memory moves from BB outstack to interface */
1855 len = bptr->outdepth;
1856 if (len > size_interface) size_interface = len;
1860 var = VAR(bptr->outvars[len]);
1862 /* outvars statistics (currently none) */
1864 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1870 dst = bptr->instack;
1871 iptr = bptr->iinstr;
1875 while (--len >= 0) {
1877 dst = iptr->dst.var;
1879 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1880 switch (src->varkind) {
1883 if (!(src->flags & INMEMORY))
1884 count_ss_register++;
1890 /* case LOCALVAR: */
1891 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1892 /* count_ss_register++; */
1894 /* count_ss_spilled++; */
1897 if (!(src->flags & INMEMORY))
1898 count_argument_mem_ss++;
1900 count_argument_reg_ss++;
1904 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1905 /* if (src->varnum < FLT_ARG_CNT) { */
1906 /* count_ss_register++; */
1910 /* #if defined(__POWERPC__) */
1911 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1913 /* if (src->varnum < INT_ARG_CNT) { */
1915 /* count_ss_register++; */
1919 /* count_ss_spilled++; */
1926 } /* while instructions */
1931 } /* while blocks */
1933 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1934 if (in_register) count_method_in_register++;
1936 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1939 #endif /* defined(ENABLE_STATISTICS) */
1943 * These are local overrides for various environment variables in Emacs.
1944 * Please do not remove this and leave it at the end of the file, where
1945 * Emacs will automagically detect them.
1946 * ---------------------------------------------------------------------
1949 * indent-tabs-mode: t
1953 * vim:noexpandtab:sw=4:ts=4: