1 /* src/vm/jit/allocator/simplereg.c - register allocator
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
35 $Id: simplereg.c 6057 2006-11-27 14:58:43Z edwin $
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "mm/memory.h"
51 #include "vm/method.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/reg.h"
56 #include "vm/jit/allocator/simplereg.h"
57 #include "vm/jit/show.h"
61 # define LOG(args) printf args
67 /* function prototypes for this file ******************************************/
69 static void simplereg_allocate_interfaces(jitdata *jd);
70 static void simplereg_allocate_locals(jitdata *jd);
71 static void simplereg_allocate_temporaries(jitdata *jd);
74 /* total number of registers */
76 #if defined(HAS_ADDRESS_REGISTER_FILE)
77 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
79 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
83 /* macros for handling register stacks ****************************************/
85 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
86 #define AVAIL_BACK(cnt) ((cnt) > 0)
88 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
89 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
90 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
92 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
93 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
96 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
97 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
98 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
99 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
101 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
102 #define POP_FRONT_INT(stk, cnt, reg) \
104 if (intregsneeded) { \
105 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
109 POP_FRONT(stk, cnt, reg); \
112 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
115 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
116 #define POP_BACK_INT(stk, cnt, reg) \
118 if (intregsneeded) { \
120 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
123 POP_BACK(stk, cnt, reg); \
126 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
129 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
130 #define PUSH_BACK_INT(stk, cnt, reg) \
132 if (intregsneeded) { \
133 stk[cnt] = GET_LOW_REG(reg); \
134 stk[cnt + 1] = GET_HIGH_REG(reg); \
138 PUSH_BACK(stk, cnt, reg); \
141 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
144 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
145 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
146 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
148 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
149 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
150 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
152 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
153 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
154 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
156 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
157 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
158 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
160 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
161 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
162 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
164 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
165 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
166 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
168 #define TAKE_ARG_FLT(r) POP_FRONT(rd->argfltregs, rd->argfltreguse, r)
169 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
170 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
172 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
173 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
174 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
176 #define TAKE_ARG_INT(r) POP_FRONT_INT(rd->argintregs, rd->argintreguse, r)
177 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
178 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
180 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
181 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
182 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
184 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
185 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
186 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
188 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
189 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
190 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
192 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
193 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
194 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
196 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
197 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
198 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
200 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
201 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
202 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
205 /* macros for allocating memory slots ****************************************/
207 #define NEW_MEM_SLOT(r) \
210 rd->memuse += memneeded + 1; \
213 #define NEW_MEM_SLOT_ALIGNED(r) \
215 if ( (memneeded) && (rd->memuse & 1)) \
218 rd->memuse += memneeded + 1; \
221 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r) \
223 if ( (memneeded) && (rd->memuse & 1)) { \
224 PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse); \
228 rd->memuse += memneeded + 1; \
231 #if defined(ALIGN_LONGS_IN_MEMORY)
232 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT_ALIGNED(r)
234 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
237 #if defined(ALIGN_DOUBLES_IN_MEMORY)
238 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT_ALIGNED(r)
240 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
243 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
244 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
246 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
250 /* macros for creating/freeing temporary variables ***************************/
252 #define NEW_TEMP_REG(index) \
253 if ( ((index) >= jd->localcount) \
254 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
255 simplereg_new_temp(jd, (index))
258 #define FREE_TEMP_REG(index) \
259 if (((index) > jd->localcount) \
260 && (!(VAR(index)->flags & (PREALLOC)))) \
261 simplereg_free_temp(jd, (index))
264 /* macro for getting a unique register index *********************************/
266 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
267 #define REG_INDEX_NON_ADR(regoff, type) \
268 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
270 #define REG_INDEX_NON_ADR(regoff, type) \
271 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
274 #if defined(HAS_ADDRESS_REGISTER_FILE)
275 #define REG_INDEX(regoff, type) \
276 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
278 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
282 /* regalloc ********************************************************************
284 Does a simple register allocation.
286 *******************************************************************************/
288 bool regalloc(jitdata *jd)
290 /* There is a problem with the use of unused float argument
291 registers in leafmethods for stackslots on c7 (2 * Dual Core
292 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
293 benchmark is heaviliy increased. This could be prevented by
294 setting rd->argfltreguse to FLT_ARG_CNT before calling
295 simplereg_allocate_temporaries and setting it back to the original
296 value before calling simplereg_allocate_locals. */
298 simplereg_allocate_interfaces(jd);
299 simplereg_allocate_temporaries(jd);
300 simplereg_allocate_locals(jd);
308 /* simplereg_allocate_interfaces ***********************************************
310 Allocates registers for all interface variables.
312 *******************************************************************************/
314 static void simplereg_allocate_interfaces(jitdata *jd)
321 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
322 /* in case more vars are packed into this interface slot */
324 /* Allocate LNG and DBL types first to ensure 2 memory slots or */
325 /* registers on HAS_4BYTE_STACKSLOT architectures. */
326 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
328 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
332 /* get required compiler data */
338 /* rd->memuse was already set in stack.c to allocate stack space
339 for passing arguments to called methods. */
341 #if defined(__I386__)
342 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
343 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
349 if (jd->isleafmethod) {
350 /* Reserve argument register, which will be used for Locals acting */
352 if (rd->argintreguse < m->parseddesc->argintreguse)
353 rd->argintreguse = m->parseddesc->argintreguse;
354 if (rd->argfltreguse < m->parseddesc->argfltreguse)
355 rd->argfltreguse = m->parseddesc->argfltreguse;
356 #ifdef HAS_ADDRESS_REGISTER_FILE
357 if (rd->argadrreguse < m->parseddesc->argadrreguse)
358 rd->argadrreguse = m->parseddesc->argadrreguse;
362 for (s = 0; s < jd->maxinterfaces; s++) {
363 intalloc = -1; fltalloc = -1;
365 /* check if the interface at this stack depth must be a SAVEDVAR */
369 for (tt = 0; tt <=4; tt++) {
370 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
371 saved |= t & SAVEDVAR;
375 /* allocate reg/mem for each type the interface is used as */
377 for (tt = 0; tt <= 4; tt++) {
379 if (jd->interface_map[s * 5 + t].flags == UNUSED)
383 regoff = -1; /* initialize to invalid value */
385 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
386 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
389 #if defined(HAS_4BYTE_STACKSLOT)
390 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
394 #if defined(HAS_ADDRESS_REGISTER_FILE)
395 if (IS_ADR_TYPE(t)) {
396 if (!jd->isleafmethod && AVAIL_ARG_ADR) {
398 TAKE_ARG_ADR(regoff);
400 else if (AVAIL_TMP_ADR) {
401 TAKE_TMP_ADR(regoff);
403 else if (AVAIL_SAV_ADR) {
405 TAKE_SAV_ADR(regoff);
409 regoff = rd->memuse++;
412 else /* !IS_ADR_TYPE */
413 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
415 if (IS_FLT_DBL_TYPE(t)) {
417 /* Reuse memory slot(s)/register(s) for shared interface slots */
418 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
419 regoff = jd->interface_map[fltalloc].regoff;
421 else if (AVAIL_ARG_FLT) {
423 TAKE_ARG_FLT(regoff);
425 else if (AVAIL_TMP_FLT) {
426 TAKE_TMP_FLT(regoff);
428 else if (AVAIL_SAV_FLT) {
430 TAKE_SAV_FLT(regoff);
434 NEW_MEM_SLOT_FLT_DBL(regoff);
436 fltalloc = s * 5 + t;
438 else { /* !IS_FLT_DBL_TYPE(t) */
439 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
441 * for i386 put all longs in memory
443 if (IS_2_WORD_TYPE(t)) {
445 NEW_MEM_SLOT_INT_LNG(regoff);
448 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
450 /* Reuse memory slot(s)/register(s) for shared interface slots */
451 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
452 regoff = jd->interface_map[intalloc].regoff;
453 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
454 /* reuse lower half */
455 if (!(flags & INMEMORY)
456 && IS_2_WORD_TYPE(intalloc % 5))
457 regoff = GET_LOW_REG(regoff);
463 TAKE_ARG_INT(regoff);
465 else if (AVAIL_TMP_INT) {
466 TAKE_TMP_INT(regoff);
468 else if (AVAIL_SAV_INT) {
470 TAKE_SAV_INT(regoff);
474 NEW_MEM_SLOT_INT_LNG(regoff);
478 intalloc = s * 5 + t;
479 } /* if (IS_FLT_DBL_TYPE(t)) */
483 /* now the same like above, but without a chance to take a temporary register */
484 #ifdef HAS_ADDRESS_REGISTER_FILE
485 if (IS_ADR_TYPE(t)) {
487 TAKE_SAV_ADR(regoff);
491 regoff = rd->memuse++;
497 if (IS_FLT_DBL_TYPE(t)) {
499 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
500 regoff = jd->interface_map[fltalloc].regoff;
504 TAKE_SAV_FLT(regoff);
508 NEW_MEM_SLOT_FLT_DBL(regoff);
511 fltalloc = s * 5 + t;
513 else { /* IS_INT_LNG */
514 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
516 * for i386 put all longs in memory
518 if (IS_2_WORD_TYPE(t)) {
520 NEW_MEM_SLOT_INT_LNG(regoff);
526 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
527 regoff = jd->interface_map[intalloc].regoff;
528 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
529 /* reuse lower half */
530 if (!(flags & INMEMORY)
531 && IS_2_WORD_TYPE(intalloc % 5))
532 regoff = GET_LOW_REG(regoff);
537 TAKE_SAV_INT(regoff);
541 NEW_MEM_SLOT_INT_LNG(regoff);
546 } /* if (IS_FLT_DBL_TYPE(t) else */
547 } /* if (IS_ADR_TYPE(t)) else */
548 } /* if (saved) else */
552 jd->interface_map[5*s + t].flags = flags | INOUT;
553 jd->interface_map[5*s + t].regoff = regoff;
559 /* simplereg_allocate_locals_leafmethod ****************************************
561 Allocates registers for all local variables of a leafmethod.
563 *******************************************************************************/
565 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
573 int intalloc, fltalloc;
575 int intregsneeded = 0;
577 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
578 int fargcnt, iargcnt;
579 #ifdef HAS_ADDRESS_REGISTER_FILE
583 /* get required compiler data */
591 iargcnt = rd->argintreguse;
592 fargcnt = rd->argfltreguse;
593 #ifdef HAS_ADDRESS_REGISTER_FILE
594 aargcnt = rd->argadrreguse;
596 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
597 intalloc = -1; fltalloc = -1;
598 for (tt = 0; tt <= 4; tt++) {
600 lm = jd->local_map[s * 5 + t];
606 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
607 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
609 #if defined(HAS_4BYTE_STACKSLOT)
610 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
616 * #ifdef HAS_ADDRESS_REGISTER_FILE
623 * } else { / int & lng
627 * must not to be changed!
630 #ifdef HAS_ADDRESS_REGISTER_FILE
631 if (IS_ADR_TYPE(t)) {
632 if ((p < md->paramcount) && !md->params[p].inmemory) {
634 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
636 else if (AVAIL_TMP_ADR) {
638 TAKE_TMP_ADR(v->vv.regoff);
640 /* use unused argument registers as local registers */
641 else if ((p >= md->paramcount) &&
642 (aargcnt < ADR_ARG_CNT))
645 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
647 else if (AVAIL_SAV_ADR) {
649 TAKE_SAV_ADR(v->vv.regoff);
652 v->flags |= INMEMORY;
653 v->vv.regoff = rd->memuse++;
658 if (IS_FLT_DBL_TYPE(t)) {
660 v->flags = VAR(fltalloc)->flags;
661 v->vv.regoff = VAR(fltalloc)->vv.regoff;
663 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
664 /* We can only use float arguments as local variables,
665 * if we do not pass them in integer registers. */
666 else if ((p < md->paramcount) &&
667 !md->params[p].inmemory)
670 v->vv.regoff = rd->argfltregs[md->params[p].regoff];
673 else if (AVAIL_TMP_FLT) {
675 TAKE_TMP_FLT(v->vv.regoff);
677 /* use unused argument registers as local registers */
678 else if ((p >= md->paramcount) &&
679 (fargcnt < FLT_ARG_CNT))
682 POP_FRONT(rd->argfltregs, 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 defined(HAS_4BYTE_STACKSLOT) && !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))
724 v->vv.regoff = PACK_REGS(
725 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
726 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
730 rd->argintregs[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(rd->argintregs, 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 intalloc, fltalloc;
785 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
786 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
790 /* get required compiler data */
795 if (jd->isleafmethod) {
796 simplereg_allocate_locals_leafmethod(jd);
800 for (s = 0; s < jd->maxlocals; s++) {
801 intalloc = -1; fltalloc = -1;
802 for (tt=0; tt<=4; tt++) {
805 lm = jd->local_map[s * 5 + t];
811 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
812 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
815 #if defined(HAS_4BYTE_STACKSLOT)
816 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
819 #ifdef HAS_ADDRESS_REGISTER_FILE
820 if (IS_ADR_TYPE(t)) {
823 TAKE_SAV_ADR(v->vv.regoff);
827 v->vv.regoff = rd->memuse++;
832 if (IS_FLT_DBL_TYPE(t)) {
834 v->flags = VAR(fltalloc)->flags;
835 v->vv.regoff = VAR(fltalloc)->vv.regoff;
837 else if (AVAIL_SAV_FLT) {
839 TAKE_SAV_FLT(v->vv.regoff);
843 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
845 fltalloc = jd->local_map[s * 5 + t];
848 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
850 * for i386 put all longs in memory
852 if (IS_2_WORD_TYPE(t)) {
854 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
859 v->flags = VAR(intalloc)->flags;
860 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
861 if (!(v->flags & INMEMORY)
862 && IS_2_WORD_TYPE(VAR(intalloc)->type))
863 v->vv.regoff = GET_LOW_REG(
864 VAR(intalloc)->vv.regoff);
867 v->vv.regoff = VAR(intalloc)->vv.regoff;
869 else if (AVAIL_SAV_INT) {
871 TAKE_SAV_INT(v->vv.regoff);
875 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
877 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
880 intalloc = jd->local_map[s * 5 + t];
882 #ifdef HAS_ADDRESS_REGISTER_FILE
890 static void simplereg_init(jitdata *jd, registerdata *rd)
895 #if defined(HAS_4BYTE_STACKSLOT)
896 rd->freememtop_2 = 0;
899 rd->freetmpinttop = 0;
900 rd->freesavinttop = 0;
901 rd->freetmpflttop = 0;
902 rd->freesavflttop = 0;
903 #ifdef HAS_ADDRESS_REGISTER_FILE
904 rd->freetmpadrtop = 0;
905 rd->freesavadrtop = 0;
908 rd->freearginttop = 0;
909 rd->freeargflttop = 0;
910 #ifdef HAS_ADDRESS_REGISTER_FILE
911 rd->freeargadrtop = 0;
914 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
915 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
916 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
918 /* memcopycount is dynamically allocated when needed */
920 rd->memcopycount = NULL;
921 rd->memcopycountsize = 0;
923 rd->intusedinout = DMNEW(int, INT_REG_CNT);
924 MZERO(rd->intusedinout, int, INT_REG_CNT);
925 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
926 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
928 /* record the interface registers as used */
930 for (i=0; i<rd->argintreguse; ++i)
931 rd->intusedinout[rd->argintregs[i]] = 1;
932 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
933 rd->intusedinout[rd->tmpintregs[i]] = 1;
934 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
935 rd->intusedinout[rd->savintregs[i]] = 1;
937 for (i=0; i<rd->argfltreguse; ++i)
938 rd->fltusedinout[rd->argfltregs[i]] = 1;
939 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
940 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
941 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
942 rd->fltusedinout[rd->savfltregs[i]] = 1;
944 #ifdef HAS_ADDRESS_REGISTER_FILE
945 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
946 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
948 for (i=0; i<rd->argadrreguse; ++i)
949 rd->adrusedinout[rd->argadrregs[i]] = 1;
950 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
951 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
952 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
953 rd->adrusedinout[rd->savadrregs[i]] = 1;
958 static void simplereg_init_block(registerdata *rd)
962 /* remove all interface registers from the free lists */
964 for (i=0; i<rd->freearginttop; ++i)
965 if (rd->intusedinout[rd->freeargintregs[i]]) {
966 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
968 for (i=0; i<rd->freetmpinttop; ++i)
969 if (rd->intusedinout[rd->freetmpintregs[i]]) {
970 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
972 for (i=0; i<rd->freesavinttop; ++i)
973 if (rd->intusedinout[rd->freesavintregs[i]]) {
974 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
977 for (i=0; i<rd->freeargflttop; ++i)
978 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
979 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
981 for (i=0; i<rd->freetmpflttop; ++i)
982 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
983 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
985 for (i=0; i<rd->freesavflttop; ++i)
986 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
987 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
990 #ifdef HAS_ADDRESS_REGISTER_FILE
991 for (i=0; i<rd->freeargadrtop; ++i)
992 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
993 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
995 for (i=0; i<rd->freetmpadrtop; ++i)
996 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
997 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
999 for (i=0; i<rd->freesavadrtop; ++i)
1000 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1001 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1007 static void simplereg_new_temp(jitdata *jd, s4 index)
1009 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1020 /* Try to allocate a saved register if there is no temporary one */
1021 /* available. This is what happens during the second run. */
1022 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1024 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1025 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1028 #if defined(HAS_4BYTE_STACKSLOT)
1029 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1034 for(; tryagain; --tryagain) {
1035 if (tryagain == 1) {
1036 if (!(v->flags & SAVEDVAR))
1038 #ifdef HAS_ADDRESS_REGISTER_FILE
1039 if (IS_ADR_TYPE(v->type)) {
1040 if (AVAIL_FREE_SAV_ADR) {
1041 TAKE_FREE_SAV_ADR(v->vv.regoff);
1044 else if (AVAIL_SAV_ADR) {
1045 TAKE_SAV_ADR(v->vv.regoff);
1052 if (IS_FLT_DBL_TYPE(v->type)) {
1053 if (AVAIL_FREE_SAV_FLT) {
1054 TAKE_FREE_SAV_FLT(v->vv.regoff);
1057 else if (AVAIL_SAV_FLT) {
1058 TAKE_SAV_FLT(v->vv.regoff);
1063 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1065 * for i386 put all longs in memory
1067 if (!IS_2_WORD_TYPE(v->type))
1070 if (AVAIL_FREE_SAV_INT) {
1071 TAKE_FREE_SAV_INT(v->vv.regoff);
1074 else if (AVAIL_SAV_INT) {
1075 TAKE_SAV_INT(v->vv.regoff);
1082 else { /* tryagain == 2 */
1083 #ifdef HAS_ADDRESS_REGISTER_FILE
1084 if (IS_ADR_TYPE(v->type)) {
1085 if (AVAIL_FREE_TMP_ADR) {
1086 TAKE_FREE_TMP_ADR(v->vv.regoff);
1089 else if (AVAIL_TMP_ADR) {
1090 TAKE_TMP_ADR(v->vv.regoff);
1097 if (IS_FLT_DBL_TYPE(v->type)) {
1098 if (AVAIL_FREE_ARG_FLT) {
1100 TAKE_FREE_ARG_FLT(v->vv.regoff);
1103 else if (AVAIL_ARG_FLT) {
1105 TAKE_ARG_FLT(v->vv.regoff);
1108 else if (AVAIL_FREE_TMP_FLT) {
1109 TAKE_FREE_TMP_FLT(v->vv.regoff);
1112 else if (AVAIL_TMP_FLT) {
1113 TAKE_TMP_FLT(v->vv.regoff);
1119 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1121 * for i386 put all longs in memory
1123 if (!IS_2_WORD_TYPE(v->type))
1126 if (AVAIL_FREE_ARG_INT) {
1128 TAKE_FREE_ARG_INT(v->vv.regoff);
1131 else if (AVAIL_ARG_INT) {
1133 TAKE_ARG_INT(v->vv.regoff);
1136 else if (AVAIL_FREE_TMP_INT) {
1137 TAKE_FREE_TMP_INT(v->vv.regoff);
1140 else if (AVAIL_TMP_INT) {
1141 TAKE_TMP_INT(v->vv.regoff);
1144 } /* if (!IS_2_WORD_TYPE(s->type)) */
1145 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1146 } /* if (IS_ADR_TYPE(s->type)) */
1147 } /* if (tryagain == 1) else */
1148 } /* for(; tryagain; --tryagain) */
1150 /* spill to memory */
1152 v->flags |= INMEMORY;
1154 #if defined(HAS_4BYTE_STACKSLOT)
1155 if ((memneeded == 1) && (rd->freememtop_2 > 0))
1156 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1158 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1159 if ((memneeded == 0) && (rd->freememtop > 0))
1160 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1162 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1166 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1168 /* if this is a copy of another variable, just decrement the copy counter */
1170 /* XXX split reg/mem variables on arm may need special handling here */
1172 if (flags & INMEMORY) {
1176 if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
1177 rd->memcopycount[regoff]--;
1184 regindex = REG_INDEX(regoff, type);
1186 /* do not free interface registers that are needed as outvars */
1188 if (flags & INOUT) {
1189 if (rd->regisoutvar[regindex]) {
1190 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1194 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1197 if (rd->regcopycount[regindex]) {
1198 rd->regcopycount[regindex]--;
1203 if (flags & INMEMORY) {
1204 #if defined(HAS_4BYTE_STACKSLOT)
1205 if (IS_2_WORD_TYPE(type))
1206 PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1209 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1214 /* freeing a register */
1216 #ifdef HAS_ADDRESS_REGISTER_FILE
1217 if (IS_ADR_TYPE(type)) {
1218 if (flags & (SAVEDVAR | SAVREG))
1219 PUSH_FREE_SAV_ADR(regoff);
1221 PUSH_FREE_TMP_ADR(regoff);
1224 else if (IS_FLT_DBL_TYPE(type)) {
1225 if (flags & (SAVEDVAR | SAVREG))
1226 PUSH_FREE_SAV_FLT(regoff);
1227 else if (flags & ARGREG)
1228 PUSH_FREE_ARG_FLT(regoff);
1230 PUSH_FREE_TMP_FLT(regoff);
1232 else { /* IS_INT_LNG_TYPE */
1233 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1234 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1237 if (flags & (SAVEDVAR | SAVREG))
1238 PUSH_FREE_SAV_INT(regoff);
1239 else if (flags & ARGREG)
1240 PUSH_FREE_ARG_INT(regoff);
1242 PUSH_FREE_TMP_INT(regoff);
1247 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1253 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1257 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1262 /* do not coalesce local variables here */
1264 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1270 /* do not coalesce in/out vars or preallocated variables here */
1272 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1275 /* if the source is in memory, we can coalesce in any case */
1277 if (sv->flags & INMEMORY) {
1278 dv->flags |= INMEMORY;
1279 dv->vv.regoff = sv->vv.regoff;
1283 /* we do not allocate a REG_TMP to a REG_SAV variable */
1285 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1289 dv->vv.regoff = sv->vv.regoff;
1290 dv->flags |= sv->flags & (SAVREG | ARGREG);
1296 /* simplereg_allocate_temporaries **********************************************
1298 Allocate temporary (non-interface, non-local) registers.
1300 *******************************************************************************/
1302 static void simplereg_allocate_temporaries(jitdata *jd)
1310 builtintable_entry *bte;
1319 /* get required compiler data */
1324 /* initialize temp registers */
1326 simplereg_init(jd, rd);
1328 bptr = jd->basicblocks;
1330 while (bptr != NULL) {
1331 if (bptr->flags >= BBREACHED) {
1333 LOG(("\nallocating block L%03d\n", bptr->nr));
1335 simplereg_init_block(rd);
1337 /* assert that all copy counts are zero */
1339 #if !defined(NDEBUG)
1340 for (i=0; i < TOTAL_REG_CNT; ++i)
1341 assert(rd->regcopycount[i] == 0);
1344 /* reset outvar flags */
1346 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1348 /* set allocation of invars */
1350 for (i=0; i<bptr->indepth; ++i)
1352 v = VAR(bptr->invars[i]);
1353 if (v->type == TYPE_RET)
1356 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1357 v->flags = jd->interface_map[5*i + v->type].flags;
1359 if (!(v->flags & INMEMORY))
1360 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1363 /* set allocation of outvars */
1365 for (i=0; i<bptr->outdepth; ++i)
1367 v = VAR(bptr->outvars[i]);
1368 if (v->type == TYPE_RET)
1371 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1372 v->flags = jd->interface_map[5*i + v->type].flags;
1374 if (!(v->flags & INMEMORY)) {
1375 regindex = REG_INDEX(v->vv.regoff, v->type);
1376 rd->regcopycount[regindex] = 1;
1377 rd->regisoutvar[regindex] = 1;
1381 /* free interface registers not used in this block */
1383 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1385 regoff = jd->interface_map[i].regoff;
1386 flags = jd->interface_map[i].flags;
1388 if (!(flags & INMEMORY)) {
1389 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1390 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1391 flags, regoff, type));
1392 simplereg_free(rd, flags, regoff, type);
1394 /* mark it, so it is not freed again */
1395 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1400 /* reset copy counts */
1402 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1404 /* iterate over ICMDS to allocate temporary variables */
1406 iptr = bptr->iinstr;
1409 while (--len >= 0) {
1411 switch (iptr->opc) {
1417 case ICMD_CHECKNULL:
1422 case ICMD_PUTSTATICCONST:
1423 case ICMD_INLINE_START:
1424 case ICMD_INLINE_END:
1425 case ICMD_INLINE_BODY:
1428 /* pop 0 push 1 const */
1436 /* pop 0 push 1 load */
1443 NEW_TEMP_REG(iptr->dst.varindex);
1457 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1458 FREE_TEMP_REG(iptr->s1.varindex);
1459 NEW_TEMP_REG(iptr->dst.varindex);
1473 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1474 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1475 FREE_TEMP_REG(iptr->s1.varindex);
1478 /* pop 1 push 0 store */
1498 case ICMD_PUTSTATIC:
1499 case ICMD_PUTFIELDCONST:
1501 /* pop 1 push 0 branch */
1504 case ICMD_IFNONNULL:
1520 /* pop 1 push 0 table branch */
1522 case ICMD_TABLESWITCH:
1523 case ICMD_LOOKUPSWITCH:
1525 case ICMD_MONITORENTER:
1526 case ICMD_MONITOREXIT:
1527 FREE_TEMP_REG(iptr->s1.varindex);
1530 /* pop 2 push 0 branch */
1532 case ICMD_IF_ICMPEQ:
1533 case ICMD_IF_ICMPNE:
1534 case ICMD_IF_ICMPLT:
1535 case ICMD_IF_ICMPGE:
1536 case ICMD_IF_ICMPGT:
1537 case ICMD_IF_ICMPLE:
1539 case ICMD_IF_LCMPEQ:
1540 case ICMD_IF_LCMPNE:
1541 case ICMD_IF_LCMPLT:
1542 case ICMD_IF_LCMPGE:
1543 case ICMD_IF_LCMPGT:
1544 case ICMD_IF_LCMPLE:
1546 case ICMD_IF_FCMPEQ:
1547 case ICMD_IF_FCMPNE:
1549 case ICMD_IF_FCMPL_LT:
1550 case ICMD_IF_FCMPL_GE:
1551 case ICMD_IF_FCMPL_GT:
1552 case ICMD_IF_FCMPL_LE:
1554 case ICMD_IF_FCMPG_LT:
1555 case ICMD_IF_FCMPG_GE:
1556 case ICMD_IF_FCMPG_GT:
1557 case ICMD_IF_FCMPG_LE:
1559 case ICMD_IF_DCMPEQ:
1560 case ICMD_IF_DCMPNE:
1562 case ICMD_IF_DCMPL_LT:
1563 case ICMD_IF_DCMPL_GE:
1564 case ICMD_IF_DCMPL_GT:
1565 case ICMD_IF_DCMPL_LE:
1567 case ICMD_IF_DCMPG_LT:
1568 case ICMD_IF_DCMPG_GE:
1569 case ICMD_IF_DCMPG_GT:
1570 case ICMD_IF_DCMPG_LE:
1572 case ICMD_IF_ACMPEQ:
1573 case ICMD_IF_ACMPNE:
1581 case ICMD_IASTORECONST:
1582 case ICMD_LASTORECONST:
1583 case ICMD_AASTORECONST:
1584 case ICMD_BASTORECONST:
1585 case ICMD_CASTORECONST:
1586 case ICMD_SASTORECONST:
1587 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1588 FREE_TEMP_REG(iptr->s1.varindex);
1591 /* pop 0 push 1 copy */
1594 /* src === dst->prev (identical Stackslot Element) */
1595 /* src --> dst (copied value, take same reg/mem) */
1597 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1598 NEW_TEMP_REG(iptr->dst.varindex);
1601 v = VAROP(iptr->dst);
1603 if (v->flags & INMEMORY) {
1604 if (v->vv.regoff >= rd->memcopycountsize) {
1605 int newsize = (v->vv.regoff + 1) * 2;
1606 i = rd->memcopycountsize;
1607 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1608 MZERO(rd->memcopycount + i, int, newsize - i);
1609 rd->memcopycountsize = newsize;
1611 rd->memcopycount[v->vv.regoff]++;
1614 /* XXX split reg/mem variables on arm may need special handling here */
1616 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1618 rd->regcopycount[regindex]++;
1623 /* pop 1 push 1 move */
1626 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1627 NEW_TEMP_REG(iptr->dst.varindex);
1628 FREE_TEMP_REG(iptr->s1.varindex);
1678 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1679 FREE_TEMP_REG(iptr->s1.varindex);
1680 NEW_TEMP_REG(iptr->dst.varindex);
1685 case ICMD_IADDCONST:
1686 case ICMD_ISUBCONST:
1687 case ICMD_IMULCONST:
1691 case ICMD_IANDCONST:
1693 case ICMD_IXORCONST:
1694 case ICMD_ISHLCONST:
1695 case ICMD_ISHRCONST:
1696 case ICMD_IUSHRCONST:
1698 case ICMD_LADDCONST:
1699 case ICMD_LSUBCONST:
1700 case ICMD_LMULCONST:
1704 case ICMD_LANDCONST:
1706 case ICMD_LXORCONST:
1707 case ICMD_LSHLCONST:
1708 case ICMD_LSHRCONST:
1709 case ICMD_LUSHRCONST:
1714 case ICMD_INT2SHORT:
1732 case ICMD_CHECKCAST:
1734 case ICMD_ARRAYLENGTH:
1735 case ICMD_INSTANCEOF:
1738 case ICMD_ANEWARRAY:
1741 FREE_TEMP_REG(iptr->s1.varindex);
1742 NEW_TEMP_REG(iptr->dst.varindex);
1747 case ICMD_GETSTATIC:
1750 NEW_TEMP_REG(iptr->dst.varindex);
1753 /* pop many push any */
1755 case ICMD_INVOKESTATIC:
1756 case ICMD_INVOKESPECIAL:
1757 case ICMD_INVOKEVIRTUAL:
1758 case ICMD_INVOKEINTERFACE:
1759 INSTRUCTION_GET_METHODDESC(iptr,md);
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);
1771 bte = iptr->sx.s23.s3.bte;
1774 argp = iptr->sx.s23.s2.args;
1776 FREE_TEMP_REG(*argp);
1779 if (md->returntype.type != TYPE_VOID)
1780 NEW_TEMP_REG(iptr->dst.varindex);
1783 case ICMD_MULTIANEWARRAY:
1784 i = iptr->s1.argcount;
1785 argp = iptr->sx.s23.s2.args;
1787 FREE_TEMP_REG(*argp);
1790 NEW_TEMP_REG(iptr->dst.varindex);
1795 new_internalerror("Unknown ICMD %d during register allocation",
1800 } /* while instructions */
1803 } /* while blocks */
1807 #if defined(ENABLE_STATISTICS)
1808 void simplereg_make_statistics(jitdata *jd)
1815 stackptr src, src_old;
1819 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1823 /* get required compiler data */
1833 /* count how many local variables are held in memory or register */
1834 for(i=0; i < jd->localcount; i++) {
1835 if (VAR(i)->flags & INMEMORY) {
1836 count_locals_spilled++;
1840 count_locals_register++;
1844 /* count how many stack slots are held in memory or register */
1846 bptr = jd->basicblocks;
1848 while (bptr != NULL) {
1849 if (bptr->flags >= BBREACHED) {
1851 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1854 /* check for memory moves from interface to BB instack */
1855 len = bptr->indepth;
1857 if (len > size_interface) size_interface = len;
1861 var = VAR(bptr->invars[len]);
1863 /* invars statistics (currently none) */
1866 /* check for memory moves from BB outstack to interface */
1867 len = bptr->outdepth;
1868 if (len > size_interface) size_interface = len;
1872 var = VAR(bptr->outvars[len]);
1874 /* outvars statistics (currently none) */
1876 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1882 dst = bptr->instack;
1883 iptr = bptr->iinstr;
1887 while (--len >= 0) {
1889 dst = iptr->dst.var;
1891 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1892 switch (src->varkind) {
1895 if (!(src->flags & INMEMORY))
1896 count_ss_register++;
1902 /* case LOCALVAR: */
1903 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1904 /* count_ss_register++; */
1906 /* count_ss_spilled++; */
1909 if (!(src->flags & INMEMORY))
1910 count_argument_mem_ss++;
1912 count_argument_reg_ss++;
1916 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1917 /* if (src->varnum < FLT_ARG_CNT) { */
1918 /* count_ss_register++; */
1922 /* #if defined(__POWERPC__) */
1923 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1925 /* if (src->varnum < INT_ARG_CNT) { */
1927 /* count_ss_register++; */
1931 /* count_ss_spilled++; */
1938 } /* while instructions */
1943 } /* while blocks */
1945 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1946 if (in_register) count_method_in_register++;
1948 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1951 #endif /* defined(ENABLE_STATISTICS) */
1955 * These are local overrides for various environment variables in Emacs.
1956 * Please do not remove this and leave it at the end of the file, where
1957 * Emacs will automagically detect them.
1958 * ---------------------------------------------------------------------
1961 * indent-tabs-mode: t
1965 * vim:noexpandtab:sw=4:ts=4: