Merged revisions 8187-8244 via svnmerge from
[cacao.git] / src / vm / jit / allocator / simplereg.c
1 /* src/vm/jit/allocator/simplereg.c - register allocator
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    $Id: simplereg.c 8210 2007-07-18 12:51:00Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33
34 #include "vm/types.h"
35
36 #include "arch.h"
37 #include "md-abi.h"
38
39 #include "mm/memory.h"
40
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/resolve.h"
44 #include "vm/stringlocal.h"
45
46 #include "vm/jit/abi.h"
47 #include "vm/jit/reg.h"
48 #include "vm/jit/show.h"
49 #include "vm/jit/allocator/simplereg.h"
50
51 #include "vmcore/method.h"
52 #include "vmcore/options.h"
53
54
55 #if 0
56 #    define LOG(args) printf args
57 #else
58 #    define LOG(args)
59 #endif
60
61
62 /* function prototypes for this file ******************************************/
63
64 static void simplereg_allocate_interfaces(jitdata *jd);
65 static void simplereg_allocate_locals(jitdata *jd);
66 static void simplereg_allocate_temporaries(jitdata *jd);
67
68
69 /* size of a stackslot used by the internal ABI */
70
71 #if defined(HAS_4BYTE_STACKSLOT)
72 # define SIZE_OF_STACKSLOT 4
73 #else 
74 # define SIZE_OF_STACKSLOT 8
75 #endif
76
77
78 /* total number of registers */
79
80 #if defined(HAS_ADDRESS_REGISTER_FILE)
81 #define TOTAL_REG_CNT  (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
82 #else
83 #define TOTAL_REG_CNT  (INT_REG_CNT + FLT_REG_CNT)
84 #endif
85
86
87 /* macros for handling register stacks ****************************************/
88
89 #define AVAIL_FRONT(cnt, limit)   ((cnt) < (limit))
90 #define AVAIL_BACK(cnt)           ((cnt) > 0)
91
92 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
93 #define AVAIL_FRONT_INT(cnt, limit)   ((cnt) < (limit) - intregsneeded)
94 #define AVAIL_BACK_INT(cnt)           ((cnt) > intregsneeded)
95 #else
96 #define AVAIL_FRONT_INT(cnt, limit)   AVAIL_FRONT(cnt, limit)
97 #define AVAIL_BACK_INT(cnt)           AVAIL_BACK(cnt)
98 #endif
99
100 #define POP_FRONT(stk, cnt, reg)   do {  reg = stk[cnt++];    } while (0)
101 #define POP_BACK(stk, cnt, reg)    do {  reg = stk[--cnt];    } while (0)
102 #define PUSH_FRONT(stk, cnt, reg)  do {  stk[--cnt] = (reg);  } while (0)
103 #define PUSH_BACK(stk, cnt, reg)   do {  stk[cnt++] = (reg);  } while (0)
104
105 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
106 #define POP_FRONT_INT(stk, cnt, reg)                                 \
107     do {                                                             \
108         if (intregsneeded) {                                         \
109             reg = PACK_REGS(stk[cnt], stk[cnt+1]);                   \
110             cnt += 2;                                                \
111         }                                                            \
112         else                                                         \
113             POP_FRONT(stk, cnt, reg);                                \
114     } while (0)
115 #else
116 #define POP_FRONT_INT(stk, cnt, reg)  POP_FRONT(stk, cnt, reg)
117 #endif
118
119 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
120 #define POP_BACK_INT(stk, cnt, reg)                                  \
121     do {                                                             \
122         if (intregsneeded) {                                         \
123             cnt -= 2;                                                \
124             reg = PACK_REGS(stk[cnt], stk[cnt+1]);                   \
125         }                                                            \
126         else                                                         \
127             POP_BACK(stk, cnt, reg);                                 \
128     } while (0)
129 #else
130 #define POP_BACK_INT(stk, cnt, reg)  POP_BACK(stk, cnt, reg)
131 #endif
132
133 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
134 #define PUSH_BACK_INT(stk, cnt, reg)                                 \
135     do {                                                             \
136         if (intregsneeded) {                                         \
137             stk[cnt] = GET_LOW_REG(reg);                             \
138             stk[cnt + 1] = GET_HIGH_REG(reg);                        \
139             cnt += 2;                                                \
140         }                                                            \
141         else                                                         \
142             PUSH_BACK(stk, cnt, reg);                                \
143     } while (0)
144 #else
145 #define PUSH_BACK_INT(stk, cnt, reg)  PUSH_BACK(stk, cnt, reg)
146 #endif
147
148 #define AVAIL_ARG_FLT  AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
149 #define AVAIL_TMP_FLT  AVAIL_BACK(rd->tmpfltreguse)
150 #define AVAIL_SAV_FLT  AVAIL_BACK(rd->savfltreguse)
151
152 #define AVAIL_ARG_ADR  AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
153 #define AVAIL_TMP_ADR  AVAIL_BACK(rd->tmpadrreguse)
154 #define AVAIL_SAV_ADR  AVAIL_BACK(rd->savadrreguse)
155
156 #define AVAIL_ARG_INT  AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
157 #define AVAIL_TMP_INT  AVAIL_BACK_INT(rd->tmpintreguse)
158 #define AVAIL_SAV_INT  AVAIL_BACK_INT(rd->savintreguse)
159
160 #define AVAIL_FREE_ARG_FLT  AVAIL_BACK(rd->freeargflttop)
161 #define AVAIL_FREE_TMP_FLT  AVAIL_BACK(rd->freetmpflttop)
162 #define AVAIL_FREE_SAV_FLT  AVAIL_BACK(rd->freesavflttop)
163
164 #define AVAIL_FREE_ARG_ADR  AVAIL_BACK(rd->freeargadrtop)
165 #define AVAIL_FREE_TMP_ADR  AVAIL_BACK(rd->freetmpadrtop)
166 #define AVAIL_FREE_SAV_ADR  AVAIL_BACK(rd->freesavadrtop)
167
168 #define AVAIL_FREE_ARG_INT  AVAIL_BACK_INT(rd->freearginttop)
169 #define AVAIL_FREE_TMP_INT  AVAIL_BACK_INT(rd->freetmpinttop)
170 #define AVAIL_FREE_SAV_INT  AVAIL_BACK_INT(rd->freesavinttop)
171
172 #define TAKE_ARG_FLT(r)  POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
173 #define TAKE_TMP_FLT(r)  POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
174 #define TAKE_SAV_FLT(r)  POP_BACK(rd->savfltregs, rd->savfltreguse, r)
175
176 #define TAKE_ARG_ADR(r)  POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
177 #define TAKE_TMP_ADR(r)  POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
178 #define TAKE_SAV_ADR(r)  POP_BACK(rd->savadrregs, rd->savadrreguse, r)
179
180 #define TAKE_ARG_INT(r)  POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
181 #define TAKE_TMP_INT(r)  POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
182 #define TAKE_SAV_INT(r)  POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
183
184 #define TAKE_FREE_ARG_FLT(r)  POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
185 #define TAKE_FREE_TMP_FLT(r)  POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
186 #define TAKE_FREE_SAV_FLT(r)  POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
187
188 #define TAKE_FREE_ARG_ADR(r)  POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
189 #define TAKE_FREE_TMP_ADR(r)  POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
190 #define TAKE_FREE_SAV_ADR(r)  POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
191
192 #define TAKE_FREE_ARG_INT(r)  POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
193 #define TAKE_FREE_TMP_INT(r)  POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
194 #define TAKE_FREE_SAV_INT(r)  POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
195
196 #define PUSH_FREE_ARG_FLT(r)  PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
197 #define PUSH_FREE_TMP_FLT(r)  PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
198 #define PUSH_FREE_SAV_FLT(r)  PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
199
200 #define PUSH_FREE_ARG_ADR(r)  PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
201 #define PUSH_FREE_TMP_ADR(r)  PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
202 #define PUSH_FREE_SAV_ADR(r)  PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
203
204 #define PUSH_FREE_ARG_INT(r)  PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
205 #define PUSH_FREE_TMP_INT(r)  PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
206 #define PUSH_FREE_SAV_INT(r)  PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
207
208
209 /* macros for allocating memory slots ****************************************/
210
211 #define NEW_MEM_SLOT(r)                                              \
212     do {                                                             \
213         (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
214         rd->memuse += memneeded + 1;                                 \
215     } while (0)
216
217 #define NEW_MEM_SLOT_ALIGNED(r)                                      \
218     do {                                                             \
219         if ( (memneeded) && (rd->memuse & 1))                        \
220             rd->memuse++;                                            \
221         (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
222         rd->memuse += memneeded + 1;                                 \
223     } while (0)
224
225 #define NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)                        \
226     do {                                                             \
227         if ( (memneeded) && (rd->memuse & 1)) {                      \
228                         PUSH_BACK(rd->freemem, rd->freememtop, rd->memuse);      \
229             rd->memuse++;                                            \
230                 }                                                            \
231         (r) = rd->memuse * SIZE_OF_STACKSLOT;                        \
232         rd->memuse += memneeded + 1;                                 \
233     } while (0)
234
235 #if defined(ALIGN_LONGS_IN_MEMORY)
236 #define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT_ALIGNED(r)
237 #else
238 #define NEW_MEM_SLOT_INT_LNG(r)  NEW_MEM_SLOT(r)
239 #endif
240
241 #if defined(ALIGN_DOUBLES_IN_MEMORY)
242 #define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT_ALIGNED(r)
243 #else
244 #define NEW_MEM_SLOT_FLT_DBL(r)  NEW_MEM_SLOT(r)
245 #endif
246
247 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
248 #define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT_ALIGNED_REUSE_PADDING(r)
249 #else
250 #define NEW_MEM_SLOT_REUSE_PADDING(r)  NEW_MEM_SLOT(r)
251 #endif
252
253
254 /* macros for creating/freeing temporary variables ***************************/
255
256 #define NEW_TEMP_REG(index)                                          \
257     if ( ((index) >= jd->localcount)                                 \
258          && (!(VAR(index)->flags & (INOUT | PREALLOC))) )            \
259         simplereg_new_temp(jd, (index))
260
261
262 #define FREE_TEMP_REG(index)                                         \
263     if (((index) > jd->localcount)                                   \
264         && (!(VAR(index)->flags & (PREALLOC))))                      \
265         simplereg_free_temp(jd, (index))
266
267
268 /* macro for getting a unique register index *********************************/
269
270 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
271 #define REG_INDEX_NON_ADR(regoff, type)                              \
272     (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
273 #else
274 #define REG_INDEX_NON_ADR(regoff, type)                              \
275     (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
276 #endif
277
278 #if defined(HAS_ADDRESS_REGISTER_FILE)
279 #define REG_INDEX(regoff, type)                                      \
280     (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
281 #else
282 #define REG_INDEX(regoff, type)  REG_INDEX_NON_ADR(regoff, type)
283 #endif
284
285
286 /* regalloc ********************************************************************
287
288    Does a simple register allocation.
289         
290 *******************************************************************************/
291         
292 bool regalloc(jitdata *jd)
293 {
294         /* There is a problem with the use of unused float argument
295            registers in leafmethods for stackslots on c7 (2 * Dual Core
296            AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
297            benchmark is heaviliy increased. This could be prevented by
298            setting rd->argfltreguse to FLT_ARG_CNT before calling
299            simplereg_allocate_temporaries and setting it back to the original
300            value before calling simplereg_allocate_locals.  */
301
302         simplereg_allocate_interfaces(jd);
303         simplereg_allocate_temporaries(jd);
304         simplereg_allocate_locals(jd);
305
306         /* everthing's ok */
307
308         return true;
309 }
310
311
312 /* simplereg_allocate_interfaces ***********************************************
313
314    Allocates registers for all interface variables.
315         
316 *******************************************************************************/
317         
318 static void simplereg_allocate_interfaces(jitdata *jd)
319 {
320         methodinfo   *m;
321         codegendata  *cd;
322         registerdata *rd;
323
324         int     s, t, tt, saved;
325         int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
326                         /* in case more vars are packed into this interface slot */
327         int             memneeded = 0;
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 };
331         int     flags, regoff;
332 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
333         int             intregsneeded;
334 #endif
335
336         /* get required compiler data */
337
338         m  = jd->m;
339         cd = jd->cd;
340         rd = jd->rd;
341
342         /* rd->memuse was already set in stack.c to allocate stack space
343            for passing arguments to called methods. */
344
345 #if defined(__I386__)
346         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
347                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
348                 if (rd->memuse < 1)
349                         rd->memuse = 1;
350         }
351 #endif
352
353         if (jd->isleafmethod) {
354                 /* Reserve argument register, which will be used for Locals acting */
355                 /* as Parameters */
356                 if (rd->argintreguse < m->parseddesc->argintreguse)
357                         rd->argintreguse = m->parseddesc->argintreguse;
358                 if (rd->argfltreguse < m->parseddesc->argfltreguse)
359                         rd->argfltreguse = m->parseddesc->argfltreguse;
360 #ifdef HAS_ADDRESS_REGISTER_FILE
361                 if (rd->argadrreguse < m->parseddesc->argadrreguse)
362                         rd->argadrreguse = m->parseddesc->argadrreguse;
363 #endif
364         }
365
366         for (s = 0; s < jd->maxinterfaces; s++) {
367                 intalloc = -1; fltalloc = -1;
368
369                 /* check if the interface at this stack depth must be a SAVEDVAR */
370
371                 saved = 0;
372
373                 for (tt = 0; tt <=4; tt++) {
374                         if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
375                                 saved |= t & SAVEDVAR;
376                         }
377                 }
378
379                 /* allocate reg/mem for each type the interface is used as */
380
381                 for (tt = 0; tt <= 4; tt++) {
382                         t = typeloop[tt];
383                         if (jd->interface_map[s * 5 + t].flags == UNUSED)
384                                 continue;
385
386                         flags = saved;
387                         regoff = -1; /* initialize to invalid value */
388
389 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
390                         intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
391 #endif
392
393 #if defined(HAS_4BYTE_STACKSLOT)
394                         memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
395 #endif
396
397                         if (!saved) {
398 #if defined(HAS_ADDRESS_REGISTER_FILE)
399                                 if (IS_ADR_TYPE(t)) {
400                                         if (!jd->isleafmethod && AVAIL_ARG_ADR) {
401                                                 flags |= ARGREG;
402                                                 TAKE_ARG_ADR(regoff);
403                                         } 
404                                         else if (AVAIL_TMP_ADR) {
405                                                 TAKE_TMP_ADR(regoff);
406                                         } 
407                                         else if (AVAIL_SAV_ADR) {
408                                                 flags |= SAVREG;
409                                                 TAKE_SAV_ADR(regoff);
410                                         } 
411                                         else {
412                                                 flags |= INMEMORY;
413                                                 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
414                                         }                                               
415                                 } 
416                                 else /* !IS_ADR_TYPE */
417 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
418                                 {
419                                         if (IS_FLT_DBL_TYPE(t)) {
420                                                 if (fltalloc >= 0) {
421                                                         /* Reuse memory slot(s)/register(s) for shared interface slots */
422                                                         flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
423                                                         regoff = jd->interface_map[fltalloc].regoff;
424                                                 } 
425                                                 else if (AVAIL_ARG_FLT) {
426                                                         flags |= ARGREG;
427                                                         TAKE_ARG_FLT(regoff);
428                                                 } 
429                                                 else if (AVAIL_TMP_FLT) {
430                                                         TAKE_TMP_FLT(regoff);
431                                                 } 
432                                                 else if (AVAIL_SAV_FLT) {
433                                                         flags |= SAVREG;
434                                                         TAKE_SAV_FLT(regoff);
435                                                 } 
436                                                 else {
437                                                         flags |= INMEMORY;
438                                                         NEW_MEM_SLOT_FLT_DBL(regoff);
439                                                 }
440                                                 fltalloc = s * 5 + t;
441                                         }
442                                         else { /* !IS_FLT_DBL_TYPE(t) */
443 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
444                                                 /*
445                                                  * for i386 put all longs in memory
446                                                  */
447                                                 if (IS_2_WORD_TYPE(t)) {
448                                                         flags |= INMEMORY;
449                                                         NEW_MEM_SLOT_INT_LNG(regoff);
450                                                 } 
451                                                 else
452 #endif
453                                                         if (intalloc >= 0) {
454                                                                 /* Reuse memory slot(s)/register(s) for shared interface slots */
455                                                                 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
456                                                                 regoff = jd->interface_map[intalloc].regoff;
457 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
458                                                                 /* reuse lower half */
459                                                                 if (!(flags & INMEMORY) 
460                                                                                 && IS_2_WORD_TYPE(intalloc % 5))
461                                                                         regoff = GET_LOW_REG(regoff);
462 #endif
463                                                         } 
464                                                         else {
465                                                                 if (AVAIL_ARG_INT) {
466                                                                         flags |= ARGREG;
467                                                                         TAKE_ARG_INT(regoff);
468                                                                 }
469                                                                 else if (AVAIL_TMP_INT) {
470                                                                         TAKE_TMP_INT(regoff);
471                                                                 }
472                                                                 else if (AVAIL_SAV_INT) {
473                                                                         flags |= SAVREG;
474                                                                         TAKE_SAV_INT(regoff);
475                                                                 }
476                                                                 else {
477                                                                         flags |= INMEMORY;
478                                                                         NEW_MEM_SLOT_INT_LNG(regoff);
479                                                                 }
480                                                         }
481
482                                                 intalloc = s * 5 + t;
483                                         } /* if (IS_FLT_DBL_TYPE(t)) */
484                                 } 
485                         } 
486                         else { /* (saved) */
487                                 /* now the same like above, but without a chance to take a temporary register */
488 #ifdef HAS_ADDRESS_REGISTER_FILE
489                                 if (IS_ADR_TYPE(t)) {
490                                         if (AVAIL_SAV_ADR) {
491                                                 TAKE_SAV_ADR(regoff);
492                                         }
493                                         else {
494                                                 flags |= INMEMORY;
495                                                 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
496                                         }                                               
497                                 } 
498                                 else
499 #endif
500                                 {
501                                         if (IS_FLT_DBL_TYPE(t)) {
502                                                 if (fltalloc >= 0) {
503                                                         flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
504                                                         regoff = jd->interface_map[fltalloc].regoff;
505                                                 } 
506                                                 else {
507                                                         if (AVAIL_SAV_FLT) {
508                                                                 TAKE_SAV_FLT(regoff);
509                                                         }
510                                                         else {
511                                                                 flags |= INMEMORY;
512                                                                 NEW_MEM_SLOT_FLT_DBL(regoff);
513                                                         }
514                                                 }
515                                                 fltalloc = s * 5 + t;
516                                         }
517                                         else { /* IS_INT_LNG */
518 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
519                                                 /*
520                                                  * for i386 put all longs in memory
521                                                  */
522                                                 if (IS_2_WORD_TYPE(t)) {
523                                                         flags |= INMEMORY;
524                                                         NEW_MEM_SLOT_INT_LNG(regoff);
525                                                 } 
526                                                 else
527 #endif
528                                                 {
529                                                         if (intalloc >= 0) {
530                                                                 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
531                                                                 regoff = jd->interface_map[intalloc].regoff;
532 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
533                                                                 /*  reuse lower half */
534                                                                 if (!(flags & INMEMORY)
535                                                                                 && IS_2_WORD_TYPE(intalloc % 5))
536                                                                         regoff = GET_LOW_REG(regoff);
537 #endif
538                                                         } 
539                                                         else {
540                                                                 if (AVAIL_SAV_INT) {
541                                                                         TAKE_SAV_INT(regoff);
542                                                                 } 
543                                                                 else {
544                                                                         flags |= INMEMORY;
545                                                                         NEW_MEM_SLOT_INT_LNG(regoff);
546                                                                 }
547                                                         }
548                                                         intalloc = s*5 + t;
549                                                 }
550                                         } /* if (IS_FLT_DBL_TYPE(t) else */
551                                 } /* if (IS_ADR_TYPE(t)) else */
552                         } /* if (saved) else */
553                         /* if (type >= 0) */
554
555                         assert(regoff >= 0);
556                         jd->interface_map[5*s + t].flags = flags | INOUT;
557                         jd->interface_map[5*s + t].regoff = regoff;
558                 } /* for t */
559         } /* for s */
560 }
561
562
563 /* simplereg_allocate_locals_leafmethod ****************************************
564
565    Allocates registers for all local variables of a leafmethod.
566         
567 *******************************************************************************/
568         
569 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
570 {
571         methodinfo   *m;
572         codegendata  *cd;
573         registerdata *rd;
574         methoddesc *md;
575
576         int     p, s, t, tt, varindex;
577         int     intalloc, fltalloc;
578         varinfo *v;
579         int     intregsneeded = 0;
580         int     memneeded = 0;
581         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
582         int     fargcnt, iargcnt;
583 #ifdef HAS_ADDRESS_REGISTER_FILE
584         int     aargcnt;
585 #endif
586
587         /* get required compiler data */
588
589         m  = jd->m;
590         cd = jd->cd;
591         rd = jd->rd;
592
593         md = m->parseddesc;
594
595         iargcnt = rd->argintreguse;
596         fargcnt = rd->argfltreguse;
597 #ifdef HAS_ADDRESS_REGISTER_FILE
598         aargcnt = rd->argadrreguse;
599 #endif
600         for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
601                 intalloc = -1; fltalloc = -1;
602                 for (tt = 0; tt <= 4; tt++) {
603                         t = typeloop[tt];
604                         varindex = jd->local_map[s * 5 + t];
605                         if (varindex == UNUSED)
606                                 continue;
607
608                         v = VAR(varindex);
609
610 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
611                         intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
612 #endif
613 #if defined(HAS_4BYTE_STACKSLOT)
614                         memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
615 #endif
616
617                         /*
618                          *  The order of
619                          *
620                          *  #ifdef HAS_ADDRESS_REGISTER_FILE
621                          *  if (IS_ADR_TYPE) { 
622                          *  ...
623                          *  } else 
624                          *  #endif
625                          *  if (IS_FLT_DBL) {
626                          *  ...
627                          *  } else { / int & lng
628                          *  ...
629                          *  }
630                          *
631                          *  must not to be changed!
632                          */
633
634 #ifdef HAS_ADDRESS_REGISTER_FILE
635                         if (IS_ADR_TYPE(t)) {
636                                 if ((p < md->paramcount) && !md->params[p].inmemory) {
637                                         v->flags = 0;
638                                         v->vv.regoff = rd->argadrregs[md->params[p].regoff];
639                                 }
640                                 else if (AVAIL_TMP_ADR) {
641                                         v->flags = 0;
642                                         TAKE_TMP_ADR(v->vv.regoff);
643                                 }
644                                 /* use unused argument registers as local registers */
645                                 else if ((p >= md->paramcount) &&
646                                                  (aargcnt < ADR_ARG_CNT)) 
647                                 {
648                                         v->flags = 0;
649                                         POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
650                                 }
651                                 else if (AVAIL_SAV_ADR) {
652                                         v->flags = 0;
653                                         TAKE_SAV_ADR(v->vv.regoff);
654                                 }
655                                 else {
656                                         v->flags |= INMEMORY;
657                                         v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
658                                 }                                               
659                         } 
660                         else {
661 #endif
662                                 if (IS_FLT_DBL_TYPE(t)) {
663                                         if (fltalloc >= 0) {
664                                                 v->flags = VAR(fltalloc)->flags;
665                                                 v->vv.regoff = VAR(fltalloc)->vv.regoff;
666                                         }
667 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
668                                         /* We can only use float arguments as local variables,
669                                          * if we do not pass them in integer registers. */
670                                         else if ((p < md->paramcount) && !md->params[p].inmemory) {
671                                                 v->flags = 0;
672                                                 v->vv.regoff = md->params[p].regoff;
673                                         }
674 #endif
675                                         else if (AVAIL_TMP_FLT) {
676                                                 v->flags = 0;
677                                                 TAKE_TMP_FLT(v->vv.regoff);
678                                         }
679                                         /* use unused argument registers as local registers */
680                                         else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
681                                                 v->flags = 0;
682                                                 POP_FRONT(abi_registers_float_argument,
683                                                                   fargcnt, v->vv.regoff);
684                                         }
685                                         else if (AVAIL_SAV_FLT) {
686                                                 v->flags = 0;
687                                                 TAKE_SAV_FLT(v->vv.regoff);
688                                         }
689                                         else {
690                                                 v->flags = INMEMORY;
691                                                 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
692                                         }
693                                         fltalloc = jd->local_map[s * 5 + t];
694
695                                 } 
696                                 else {
697 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
698                                         /*
699                                          * for i386 put all longs in memory
700                                          */
701                                         if (IS_2_WORD_TYPE(t)) {
702                                                 v->flags = INMEMORY;
703                                                 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
704                                         } 
705                                         else 
706 #endif
707                                         {
708                                                 if (intalloc >= 0) {
709                                                         v->flags = VAR(intalloc)->flags;
710 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
711                                                         if (!(v->flags & INMEMORY)
712                                                                 && IS_2_WORD_TYPE(VAR(intalloc)->type))
713                                                                 v->vv.regoff = GET_LOW_REG(
714                                                                                                 VAR(intalloc)->vv.regoff);
715                                                         else
716 #endif
717                                                                 v->vv.regoff = VAR(intalloc)->vv.regoff;
718                                                 }
719                                                 else if ((p < md->paramcount) && 
720                                                                  !md->params[p].inmemory) 
721                                                 {
722                                                         v->flags = 0;
723 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
724                                                         if (IS_2_WORD_TYPE(t))
725                                                                 v->vv.regoff =
726                                                                         PACK_REGS(GET_LOW_REG(md->params[p].regoff),
727                                                                                           GET_HIGH_REG(md->params[p].regoff));
728                                                                 else
729 #endif
730                                                                         v->vv.regoff = md->params[p].regoff;
731                                                 }
732                                                 else if (AVAIL_TMP_INT) {
733                                                         v->flags = 0;
734                                                         TAKE_TMP_INT(v->vv.regoff);
735                                                 }
736                                                 /*
737                                                  * use unused argument registers as local registers
738                                                  */
739                                                 else if ((p >= m->parseddesc->paramcount) &&
740                                                                  (iargcnt + intregsneeded < INT_ARG_CNT)) 
741                                                 {
742                                                         v->flags = 0;
743                                                         POP_FRONT_INT(abi_registers_integer_argument,
744                                                                                   iargcnt, v->vv.regoff);
745                                                 }
746                                                 else if (AVAIL_SAV_INT) {
747                                                         v->flags = 0;
748                                                         TAKE_SAV_INT(v->vv.regoff);
749                                                 }
750                                                 else {
751                                                         v->flags = INMEMORY;
752                                                         NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
753                                                 }
754                                         }
755                                         intalloc = jd->local_map[s * 5 + t];
756                                 }
757 #ifdef HAS_ADDRESS_REGISTER_FILE
758                         }
759 #endif
760                 } /* for (tt=0;...) */
761
762                 /* If the current parameter is a 2-word type, the next local slot */
763                 /* is skipped.                                                    */
764
765                 if (p < md->paramcount)
766                         if (IS_2_WORD_TYPE(md->paramtypes[p].type))
767                                 s++;
768         }
769 }
770
771 /* simplereg_allocate_locals ***************************************************
772
773    Allocates registers for all local variables.
774         
775 *******************************************************************************/
776         
777 static void simplereg_allocate_locals(jitdata *jd)
778 {
779         codegendata  *cd;
780         registerdata *rd;
781
782         int     s, t, tt, varindex;
783         int     intalloc, fltalloc;
784         varinfo *v;
785         int     memneeded = 0;
786         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
787 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
788         s4 intregsneeded;
789 #endif
790
791         /* get required compiler data */
792
793         cd = jd->cd;
794         rd = jd->rd;
795
796         if (jd->isleafmethod) {
797                 simplereg_allocate_locals_leafmethod(jd);
798                 return;
799         }
800
801         for (s = 0; s < jd->maxlocals; s++) {
802                 intalloc = -1; fltalloc = -1;
803                 for (tt=0; tt<=4; tt++) {
804                         t = typeloop[tt];
805
806                         varindex = jd->local_map[s * 5 + t];
807                         if (varindex == UNUSED)
808                                 continue;
809
810                         v = VAR(varindex);
811
812 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
813                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
814 #endif
815
816 #if defined(HAS_4BYTE_STACKSLOT)
817                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
818 #endif
819
820 #ifdef HAS_ADDRESS_REGISTER_FILE
821                                 if (IS_ADR_TYPE(t)) {
822                                         if (AVAIL_SAV_ADR) {
823                                                 v->flags = 0;
824                                                 TAKE_SAV_ADR(v->vv.regoff);
825                                         }
826                                         else {
827                                                 v->flags = INMEMORY;
828                                                 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
829                                         }
830                                 } 
831                                 else {
832 #endif
833                                 if (IS_FLT_DBL_TYPE(t)) {
834                                         if (fltalloc >= 0) {
835                                                 v->flags = VAR(fltalloc)->flags;
836                                                 v->vv.regoff = VAR(fltalloc)->vv.regoff;
837                                         }
838                                         else if (AVAIL_SAV_FLT) {
839                                                 v->flags = 0;
840                                                 TAKE_SAV_FLT(v->vv.regoff);
841                                         }
842                                         else {
843                                                 v->flags = INMEMORY;
844                                                 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
845                                         }
846                                         fltalloc = jd->local_map[s * 5 + t];
847                                 }
848                                 else {
849 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
850                                         /*
851                                          * for i386 put all longs in memory
852                                          */
853                                         if (IS_2_WORD_TYPE(t)) {
854                                                 v->flags = INMEMORY;
855                                                 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
856                                         } 
857                                         else {
858 #endif
859                                                 if (intalloc >= 0) {
860                                                         v->flags = VAR(intalloc)->flags;
861 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
862                                                         if (!(v->flags & INMEMORY)
863                                                                 && IS_2_WORD_TYPE(VAR(intalloc)->type))
864                                                                 v->vv.regoff = GET_LOW_REG(
865                                                                                             VAR(intalloc)->vv.regoff);
866                                                         else
867 #endif
868                                                                 v->vv.regoff = VAR(intalloc)->vv.regoff;
869                                                 }
870                                                 else if (AVAIL_SAV_INT) {
871                                                         v->flags = 0;
872                                                         TAKE_SAV_INT(v->vv.regoff);
873                                                 }
874                                                 else {
875                                                         v->flags = INMEMORY;
876                                                         NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
877                                                 }
878 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
879                                         }
880 #endif
881                                         intalloc = jd->local_map[s * 5 + t];
882                                 }
883 #ifdef HAS_ADDRESS_REGISTER_FILE
884                                 }
885 #endif
886                 }
887         }
888 }
889
890
891 static void simplereg_init(jitdata *jd, registerdata *rd)
892 {
893         int i;
894
895         rd->freememtop = 0;
896 #if defined(HAS_4BYTE_STACKSLOT)
897         rd->freememtop_2 = 0;
898 #endif
899
900         rd->freetmpinttop = 0;
901         rd->freesavinttop = 0;
902         rd->freetmpflttop = 0;
903         rd->freesavflttop = 0;
904 #ifdef HAS_ADDRESS_REGISTER_FILE
905         rd->freetmpadrtop = 0;
906         rd->freesavadrtop = 0;
907 #endif
908
909         rd->freearginttop = 0;
910         rd->freeargflttop = 0;
911 #ifdef HAS_ADDRESS_REGISTER_FILE
912         rd->freeargadrtop = 0;
913 #endif
914
915         rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
916         rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
917         MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
918
919         /* memcopycount is dynamically allocated when needed */
920
921         rd->memcopycount = NULL;
922         rd->memcopycountsize = 0;
923
924         rd->intusedinout = DMNEW(int, INT_REG_CNT);
925         MZERO(rd->intusedinout, int, INT_REG_CNT);
926         rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
927         MZERO(rd->fltusedinout, int, FLT_REG_CNT);
928
929         /* record the interface registers as used */
930
931         for (i=0; i<rd->argintreguse; ++i)
932                 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
933         for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
934                 rd->intusedinout[rd->tmpintregs[i]] = 1;
935         for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
936                 rd->intusedinout[rd->savintregs[i]] = 1;
937
938         for (i=0; i<rd->argfltreguse; ++i)
939                 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
940         for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
941                 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
942         for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
943                 rd->fltusedinout[rd->savfltregs[i]] = 1;
944
945 #ifdef HAS_ADDRESS_REGISTER_FILE
946         rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
947         MZERO(rd->adrusedinout, int, ADR_REG_CNT);
948
949         for (i=0; i<rd->argadrreguse; ++i)
950                 rd->adrusedinout[rd->argadrregs[i]] = 1;
951         for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
952                 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
953         for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
954                 rd->adrusedinout[rd->savadrregs[i]] = 1;
955 #endif
956 }
957
958
959 static void simplereg_init_block(registerdata *rd)
960 {
961         int i;
962
963         /* remove all interface registers from the free lists */
964
965         for (i=0; i<rd->freearginttop; ++i)
966                 if (rd->intusedinout[rd->freeargintregs[i]]) {
967                         rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
968                 }
969         for (i=0; i<rd->freetmpinttop; ++i)
970                 if (rd->intusedinout[rd->freetmpintregs[i]]) {
971                         rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
972                 }
973         for (i=0; i<rd->freesavinttop; ++i)
974                 if (rd->intusedinout[rd->freesavintregs[i]]) {
975                         rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
976                 }
977
978         for (i=0; i<rd->freeargflttop; ++i)
979                 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
980                         rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
981                 }
982         for (i=0; i<rd->freetmpflttop; ++i)
983                 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
984                         rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
985                 }
986         for (i=0; i<rd->freesavflttop; ++i)
987                 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
988                         rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
989                 }
990
991 #ifdef HAS_ADDRESS_REGISTER_FILE
992         for (i=0; i<rd->freeargadrtop; ++i)
993                 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
994                         rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
995                 }
996         for (i=0; i<rd->freetmpadrtop; ++i)
997                 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
998                         rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
999                 }
1000         for (i=0; i<rd->freesavadrtop; ++i)
1001                 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
1002                         rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
1003                 }
1004 #endif
1005 }
1006
1007
1008 static void simplereg_new_temp(jitdata *jd, s4 index)
1009 {
1010 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1011         s4 intregsneeded;
1012 #endif
1013         s4 memneeded;
1014         s4 tryagain;
1015         registerdata *rd;
1016         varinfo      *v;
1017
1018         rd = jd->rd;
1019         v = VAR(index);
1020
1021         /* assert that constants are not allocated */
1022
1023         assert(v->type != TYPE_RET);
1024
1025         /* Try to allocate a saved register if there is no temporary one          */
1026         /* available. This is what happens during the second run.                 */
1027         tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
1028
1029 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
1030         intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1031 #endif
1032
1033 #if defined(HAS_4BYTE_STACKSLOT)
1034         memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1035 #else
1036         memneeded = 0;
1037 #endif
1038
1039         for(; tryagain; --tryagain) {
1040                 if (tryagain == 1) {
1041                         if (!(v->flags & SAVEDVAR))
1042                                 v->flags |= SAVREG;
1043 #ifdef HAS_ADDRESS_REGISTER_FILE
1044                         if (IS_ADR_TYPE(v->type)) {
1045                                 if (AVAIL_FREE_SAV_ADR) {
1046                                         TAKE_FREE_SAV_ADR(v->vv.regoff);
1047                                         return;
1048                                 } 
1049                                 else if (AVAIL_SAV_ADR) {
1050                                         TAKE_SAV_ADR(v->vv.regoff);
1051                                         return;
1052                                 }
1053                         } 
1054                         else
1055 #endif
1056                         {
1057                                 if (IS_FLT_DBL_TYPE(v->type)) {
1058                                         if (AVAIL_FREE_SAV_FLT) {
1059                                                 TAKE_FREE_SAV_FLT(v->vv.regoff);
1060                                                 return;
1061                                         } 
1062                                         else if (AVAIL_SAV_FLT) {
1063                                                 TAKE_SAV_FLT(v->vv.regoff);
1064                                                 return;
1065                                         }
1066                                 } 
1067                                 else {
1068 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1069                                         /*
1070                                          * for i386 put all longs in memory
1071                                          */
1072                                         if (!IS_2_WORD_TYPE(v->type))
1073 #endif
1074                                         {
1075                                                 if (AVAIL_FREE_SAV_INT) {
1076                                                         TAKE_FREE_SAV_INT(v->vv.regoff);
1077                                                         return;
1078                                                 } 
1079                                                 else if (AVAIL_SAV_INT) {
1080                                                         TAKE_SAV_INT(v->vv.regoff);
1081                                                         return;
1082                                                 }
1083                                         }
1084                                 }
1085                         }
1086                 } 
1087                 else { /* tryagain == 2 */
1088 #ifdef HAS_ADDRESS_REGISTER_FILE
1089                         if (IS_ADR_TYPE(v->type)) {
1090                                 if (AVAIL_FREE_TMP_ADR) {
1091                                         TAKE_FREE_TMP_ADR(v->vv.regoff);
1092                                         return;
1093                                 } 
1094                                 else if (AVAIL_TMP_ADR) {
1095                                         TAKE_TMP_ADR(v->vv.regoff);
1096                                         return;
1097                                 }
1098                         } 
1099                         else
1100 #endif
1101                         {
1102                                 if (IS_FLT_DBL_TYPE(v->type)) {
1103                                         if (AVAIL_FREE_ARG_FLT) {
1104                                                 v->flags |= ARGREG;
1105                                                 TAKE_FREE_ARG_FLT(v->vv.regoff);
1106                                                 return;
1107                                         } 
1108                                         else if (AVAIL_ARG_FLT) {
1109                                                 v->flags |= ARGREG;
1110                                                 TAKE_ARG_FLT(v->vv.regoff);
1111                                                 return;
1112                                         } 
1113                                         else if (AVAIL_FREE_TMP_FLT) {
1114                                                 TAKE_FREE_TMP_FLT(v->vv.regoff);
1115                                                 return;
1116                                         } 
1117                                         else if (AVAIL_TMP_FLT) {
1118                                                 TAKE_TMP_FLT(v->vv.regoff);
1119                                                 return;
1120                                         }
1121
1122                                 } 
1123                                 else {
1124 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1125                                         /*
1126                                          * for i386 put all longs in memory
1127                                          */
1128                                         if (!IS_2_WORD_TYPE(v->type))
1129 #endif
1130                                         {
1131                                                 if (AVAIL_FREE_ARG_INT) {
1132                                                         v->flags |= ARGREG;
1133                                                         TAKE_FREE_ARG_INT(v->vv.regoff);
1134                                                         return;
1135                                                 } 
1136                                                 else if (AVAIL_ARG_INT) {
1137                                                         v->flags |= ARGREG;
1138                                                         TAKE_ARG_INT(v->vv.regoff);
1139                                                         return;
1140                                                 } 
1141                                                 else if (AVAIL_FREE_TMP_INT) {
1142                                                         TAKE_FREE_TMP_INT(v->vv.regoff);
1143                                                         return;
1144                                                 } 
1145                                                 else if (AVAIL_TMP_INT) {
1146                                                         TAKE_TMP_INT(v->vv.regoff);
1147                                                         return;
1148                                                 }
1149                                         } /* if (!IS_2_WORD_TYPE(s->type)) */
1150                                 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1151                         } /* if (IS_ADR_TYPE(s->type)) */
1152                 } /* if (tryagain == 1) else */
1153         } /* for(; tryagain; --tryagain) */
1154
1155         /* spill to memory */
1156
1157         v->flags |= INMEMORY;
1158
1159 #if defined(HAS_4BYTE_STACKSLOT)
1160         if ((memneeded == 1) && (rd->freememtop_2 > 0))
1161                 POP_BACK(rd->freemem_2, rd->freememtop_2, v->vv.regoff);
1162         else
1163 #endif /*defined(HAS_4BYTE_STACKSLOT) */
1164                 if ((memneeded == 0) && (rd->freememtop > 0))
1165                         POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1166                 else
1167                         NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1168 }
1169
1170
1171 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1172 {
1173         /* assert that constants are not freed */
1174
1175         assert(type != TYPE_RET);
1176
1177         /* if this is a copy of another variable, just decrement the copy counter */
1178
1179         if (flags & INMEMORY) {
1180                 if (flags & INOUT)
1181                         return;
1182
1183                 #warning this will be more efficient if we divide it by SIZE_OF_STACKSLOT
1184
1185                 if (regoff < rd->memcopycountsize && rd->memcopycount[regoff]) {
1186                         rd->memcopycount[regoff]--;
1187                         return;
1188                 }
1189         }
1190         else {
1191                 s4 regindex;
1192
1193                 regindex = REG_INDEX(regoff, type);
1194
1195                 /* do not free interface registers that are needed as outvars */
1196
1197                 if (flags & INOUT) {
1198                         if (rd->regisoutvar[regindex]) {
1199                                 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1200                                 return;
1201                         }
1202
1203                         LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1204                 }
1205
1206                 if (rd->regcopycount[regindex]) {
1207                         rd->regcopycount[regindex]--;
1208                         return;
1209                 }
1210         }
1211
1212         if (flags & INMEMORY) {
1213 #if defined(HAS_4BYTE_STACKSLOT)
1214                 if (IS_2_WORD_TYPE(type))
1215                         PUSH_BACK(rd->freemem_2, rd->freememtop_2, regoff);
1216                 else 
1217 #endif
1218                         PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1219
1220                 return;
1221         } 
1222
1223         /* freeing a register */
1224
1225 #ifdef HAS_ADDRESS_REGISTER_FILE
1226         if (IS_ADR_TYPE(type)) {
1227                 if (flags & (SAVEDVAR | SAVREG))
1228                         PUSH_FREE_SAV_ADR(regoff);
1229                 else
1230                         PUSH_FREE_TMP_ADR(regoff);
1231         } 
1232 #endif
1233         else if (IS_FLT_DBL_TYPE(type)) {
1234                 if (flags & (SAVEDVAR | SAVREG))
1235                         PUSH_FREE_SAV_FLT(regoff);
1236                 else if (flags & ARGREG)
1237                         PUSH_FREE_ARG_FLT(regoff);
1238                 else
1239                         PUSH_FREE_TMP_FLT(regoff);
1240         } 
1241         else { /* IS_INT_LNG_TYPE */
1242 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1243                 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1244 #endif
1245
1246                 if (flags & (SAVEDVAR | SAVREG))
1247                         PUSH_FREE_SAV_INT(regoff);
1248                 else if (flags & ARGREG)
1249                         PUSH_FREE_ARG_INT(regoff);
1250                 else
1251                         PUSH_FREE_TMP_INT(regoff);
1252         }
1253 }
1254
1255
1256 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1257 {
1258         varinfo *v;
1259
1260         v = VAR(index);
1261
1262         simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1263 }
1264
1265
1266 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1267 {
1268         varinfo *sv;
1269         varinfo *dv;
1270
1271         /* do not coalesce local variables here */
1272
1273         if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1274                 return false;
1275
1276         sv = VAR(srcindex);
1277         dv = VAR(dstindex);
1278
1279         /* do not coalesce in/out vars or preallocated variables here */
1280
1281         if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1282                 return false;
1283
1284         /* if the source is in memory, we can coalesce in any case */
1285
1286         if (sv->flags & INMEMORY) {
1287                 dv->flags |= INMEMORY;
1288                 dv->vv.regoff = sv->vv.regoff;
1289                 return true;
1290         }
1291
1292         /* we do not allocate a REG_TMP to a REG_SAV variable */
1293
1294         if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1295                 return false;
1296
1297         /* coalesce */
1298         dv->vv.regoff = sv->vv.regoff;
1299         dv->flags |= sv->flags & (SAVREG | ARGREG);
1300
1301         return true;
1302 }
1303
1304
1305 /* simplereg_allocate_temporaries **********************************************
1306
1307    Allocate temporary (non-interface, non-local) registers.
1308
1309 *******************************************************************************/
1310
1311 static void simplereg_allocate_temporaries(jitdata *jd)
1312 {
1313         methodinfo         *m;
1314         registerdata       *rd;
1315         s4                  i;
1316         s4                  len;
1317         instruction        *iptr;
1318         basicblock         *bptr;
1319         builtintable_entry *bte;
1320         methoddesc         *md;
1321         s4                 *argp;
1322         varinfo            *v;
1323         s4                  flags;
1324         s4                  regoff;
1325         s4                  type;
1326         s4                  regindex;
1327
1328         /* get required compiler data */
1329
1330         m  = jd->m;
1331         rd = jd->rd;
1332
1333         /* initialize temp registers */
1334
1335         simplereg_init(jd, rd);
1336
1337         bptr = jd->basicblocks;
1338
1339         while (bptr != NULL) {
1340                 if (bptr->flags >= BBREACHED) {
1341
1342                         LOG(("\nallocating block L%03d\n", bptr->nr));
1343
1344                         simplereg_init_block(rd);
1345
1346                         /* assert that all copy counts are zero */
1347
1348 #if !defined(NDEBUG)
1349                         for (i=0; i < TOTAL_REG_CNT; ++i)
1350                                 assert(rd->regcopycount[i] == 0);
1351 #endif
1352
1353                         /* reset outvar flags */
1354
1355                         MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1356
1357                         /* set allocation of invars */
1358
1359                         for (i=0; i<bptr->indepth; ++i) 
1360                         {
1361                                 v = VAR(bptr->invars[i]);
1362                                 if (v->type == TYPE_RET)
1363                                         continue;
1364
1365                                 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1366                                 v->flags  = jd->interface_map[5*i + v->type].flags;
1367
1368                                 if (!(v->flags & INMEMORY))
1369                                         rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1370                         }
1371
1372                         /* set allocation of outvars */
1373
1374                         for (i=0; i<bptr->outdepth; ++i) 
1375                         {
1376                                 v = VAR(bptr->outvars[i]);
1377                                 if (v->type == TYPE_RET)
1378                                         continue;
1379
1380                                 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1381                                 v->flags  = jd->interface_map[5*i + v->type].flags;
1382
1383                                 if (!(v->flags & INMEMORY)) {
1384                                         regindex = REG_INDEX(v->vv.regoff, v->type);
1385                                         rd->regcopycount[regindex] = 1;
1386                                         rd->regisoutvar[regindex] = 1;
1387                                 }
1388                         }
1389
1390                         /* free interface registers not used in this block */
1391
1392                         for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1393                                 type = i%5;
1394                                 regoff = jd->interface_map[i].regoff;
1395                                 flags = jd->interface_map[i].flags;
1396
1397                                 if (!(flags & INMEMORY)) {
1398                                         if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1399                                                 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n", 
1400                                                                         flags, regoff, type));
1401                                                 simplereg_free(rd, flags, regoff, type);
1402
1403                                                 /* mark it, so it is not freed again */
1404                                                 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1405                                         }
1406                                 }
1407                         }
1408
1409                         /* reset copy counts */
1410
1411                         MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1412
1413                         /* iterate over ICMDS to allocate temporary variables */
1414
1415                         iptr = bptr->iinstr;
1416                         len = bptr->icount;
1417
1418                         while (--len >= 0)  {
1419
1420                                 switch (iptr->opc) {
1421
1422                                         /* pop 0 push 0 */
1423
1424                                 case ICMD_JSR:
1425                                 case ICMD_NOP:
1426                                 case ICMD_CHECKNULL:
1427                                 case ICMD_IINC:
1428                                 case ICMD_RET:
1429                                 case ICMD_RETURN:
1430                                 case ICMD_GOTO:
1431                                 case ICMD_PUTSTATICCONST:
1432                                 case ICMD_INLINE_START:
1433                                 case ICMD_INLINE_END:
1434                                 case ICMD_INLINE_BODY:
1435                                         break;
1436
1437                                         /* pop 0 push 1 const */
1438                                         
1439                                 case ICMD_ICONST:
1440                                 case ICMD_LCONST:
1441                                 case ICMD_FCONST:
1442                                 case ICMD_DCONST:
1443                                 case ICMD_ACONST:
1444
1445                                         /* pop 0 push 1 load */
1446                                         
1447                                 case ICMD_ILOAD:
1448                                 case ICMD_LLOAD:
1449                                 case ICMD_FLOAD:
1450                                 case ICMD_DLOAD:
1451                                 case ICMD_ALOAD:
1452                                         NEW_TEMP_REG(iptr->dst.varindex);
1453                                         break;
1454
1455                                         /* pop 2 push 1 */
1456
1457                                 case ICMD_IALOAD:
1458                                 case ICMD_LALOAD:
1459                                 case ICMD_FALOAD:
1460                                 case ICMD_DALOAD:
1461                                 case ICMD_AALOAD:
1462
1463                                 case ICMD_BALOAD:
1464                                 case ICMD_CALOAD:
1465                                 case ICMD_SALOAD:
1466                                         FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1467                                         FREE_TEMP_REG(iptr->s1.varindex);
1468                                         NEW_TEMP_REG(iptr->dst.varindex);
1469                                         break;
1470
1471                                         /* pop 3 push 0 */
1472
1473                                 case ICMD_IASTORE:
1474                                 case ICMD_LASTORE:
1475                                 case ICMD_FASTORE:
1476                                 case ICMD_DASTORE:
1477                                 case ICMD_AASTORE:
1478
1479                                 case ICMD_BASTORE:
1480                                 case ICMD_CASTORE:
1481                                 case ICMD_SASTORE:
1482                                         FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1483                                         FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1484                                         FREE_TEMP_REG(iptr->s1.varindex);
1485                                         break;
1486
1487                                         /* pop 1 push 0 store */
1488
1489                                 case ICMD_ISTORE:
1490                                 case ICMD_LSTORE:
1491                                 case ICMD_FSTORE:
1492                                 case ICMD_DSTORE:
1493                                 case ICMD_ASTORE:
1494
1495                                         /* pop 1 push 0 */
1496
1497                                 case ICMD_POP:
1498
1499                                 case ICMD_IRETURN:
1500                                 case ICMD_LRETURN:
1501                                 case ICMD_FRETURN:
1502                                 case ICMD_DRETURN:
1503                                 case ICMD_ARETURN:
1504
1505                                 case ICMD_ATHROW:
1506
1507                                 case ICMD_PUTSTATIC:
1508                                 case ICMD_PUTFIELDCONST:
1509
1510                                         /* pop 1 push 0 branch */
1511
1512                                 case ICMD_IFNULL:
1513                                 case ICMD_IFNONNULL:
1514
1515                                 case ICMD_IFEQ:
1516                                 case ICMD_IFNE:
1517                                 case ICMD_IFLT:
1518                                 case ICMD_IFGE:
1519                                 case ICMD_IFGT:
1520                                 case ICMD_IFLE:
1521
1522                                 case ICMD_IF_LEQ:
1523                                 case ICMD_IF_LNE:
1524                                 case ICMD_IF_LLT:
1525                                 case ICMD_IF_LGE:
1526                                 case ICMD_IF_LGT:
1527                                 case ICMD_IF_LLE:
1528
1529                                         /* pop 1 push 0 table branch */
1530
1531                                 case ICMD_TABLESWITCH:
1532                                 case ICMD_LOOKUPSWITCH:
1533
1534                                 case ICMD_MONITORENTER:
1535                                 case ICMD_MONITOREXIT:
1536                                         FREE_TEMP_REG(iptr->s1.varindex);
1537                                         break;
1538
1539                                         /* pop 2 push 0 branch */
1540
1541                                 case ICMD_IF_ICMPEQ:
1542                                 case ICMD_IF_ICMPNE:
1543                                 case ICMD_IF_ICMPLT:
1544                                 case ICMD_IF_ICMPGE:
1545                                 case ICMD_IF_ICMPGT:
1546                                 case ICMD_IF_ICMPLE:
1547
1548                                 case ICMD_IF_LCMPEQ:
1549                                 case ICMD_IF_LCMPNE:
1550                                 case ICMD_IF_LCMPLT:
1551                                 case ICMD_IF_LCMPGE:
1552                                 case ICMD_IF_LCMPGT:
1553                                 case ICMD_IF_LCMPLE:
1554
1555                                 case ICMD_IF_FCMPEQ:
1556                                 case ICMD_IF_FCMPNE:
1557
1558                                 case ICMD_IF_FCMPL_LT:
1559                                 case ICMD_IF_FCMPL_GE:
1560                                 case ICMD_IF_FCMPL_GT:
1561                                 case ICMD_IF_FCMPL_LE:
1562
1563                                 case ICMD_IF_FCMPG_LT:
1564                                 case ICMD_IF_FCMPG_GE:
1565                                 case ICMD_IF_FCMPG_GT:
1566                                 case ICMD_IF_FCMPG_LE:
1567
1568                                 case ICMD_IF_DCMPEQ:
1569                                 case ICMD_IF_DCMPNE:
1570
1571                                 case ICMD_IF_DCMPL_LT:
1572                                 case ICMD_IF_DCMPL_GE:
1573                                 case ICMD_IF_DCMPL_GT:
1574                                 case ICMD_IF_DCMPL_LE:
1575
1576                                 case ICMD_IF_DCMPG_LT:
1577                                 case ICMD_IF_DCMPG_GE:
1578                                 case ICMD_IF_DCMPG_GT:
1579                                 case ICMD_IF_DCMPG_LE:
1580
1581                                 case ICMD_IF_ACMPEQ:
1582                                 case ICMD_IF_ACMPNE:
1583
1584                                         /* pop 2 push 0 */
1585
1586                                 case ICMD_POP2:
1587
1588                                 case ICMD_PUTFIELD:
1589
1590                                 case ICMD_IASTORECONST:
1591                                 case ICMD_LASTORECONST:
1592                                 case ICMD_AASTORECONST:
1593                                 case ICMD_BASTORECONST:
1594                                 case ICMD_CASTORECONST:
1595                                 case ICMD_SASTORECONST:
1596                                         FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1597                                         FREE_TEMP_REG(iptr->s1.varindex);
1598                                         break;
1599
1600                                         /* pop 0 push 1 copy */
1601                                         
1602                                 case ICMD_COPY:
1603                                         /* src === dst->prev (identical Stackslot Element)     */
1604                                         /* src --> dst       (copied value, take same reg/mem) */
1605
1606                                         if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1607                                                 NEW_TEMP_REG(iptr->dst.varindex);
1608                                         } 
1609                                         else {
1610                                                 v = VAROP(iptr->dst);
1611
1612                                                 if (v->flags & INMEMORY) {
1613                                                         if (v->vv.regoff >= rd->memcopycountsize) {
1614                                                                 int newsize = (v->vv.regoff + 1) * 2;
1615                                                                 i = rd->memcopycountsize;
1616                                                                 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1617                                                                 MZERO(rd->memcopycount + i, int, newsize - i);
1618                                                                 rd->memcopycountsize = newsize;
1619                                                         }
1620                                                         rd->memcopycount[v->vv.regoff]++;
1621                                                 }
1622                                                 else {
1623                                                         /* XXX split reg/mem variables on arm may need special handling here */
1624
1625                                                         s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1626
1627                                                         rd->regcopycount[regindex]++;
1628                                                 }
1629                                         }
1630                                         break;
1631
1632                                         /* pop 1 push 1 move */
1633
1634                                 case ICMD_MOVE:
1635                                         if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1636                                                 NEW_TEMP_REG(iptr->dst.varindex);
1637                                                 FREE_TEMP_REG(iptr->s1.varindex);
1638                                         }
1639                                         break;
1640
1641                                         /* pop 2 push 1 */
1642                                         
1643                                 case ICMD_IADD:
1644                                 case ICMD_ISUB:
1645                                 case ICMD_IMUL:
1646                                 case ICMD_IDIV:
1647                                 case ICMD_IREM:
1648
1649                                 case ICMD_ISHL:
1650                                 case ICMD_ISHR:
1651                                 case ICMD_IUSHR:
1652                                 case ICMD_IAND:
1653                                 case ICMD_IOR:
1654                                 case ICMD_IXOR:
1655
1656                                 case ICMD_LADD:
1657                                 case ICMD_LSUB:
1658                                 case ICMD_LMUL:
1659                                 case ICMD_LDIV:
1660                                 case ICMD_LREM:
1661
1662                                 case ICMD_LOR:
1663                                 case ICMD_LAND:
1664                                 case ICMD_LXOR:
1665
1666                                 case ICMD_LSHL:
1667                                 case ICMD_LSHR:
1668                                 case ICMD_LUSHR:
1669
1670                                 case ICMD_FADD:
1671                                 case ICMD_FSUB:
1672                                 case ICMD_FMUL:
1673                                 case ICMD_FDIV:
1674                                 case ICMD_FREM:
1675
1676                                 case ICMD_DADD:
1677                                 case ICMD_DSUB:
1678                                 case ICMD_DMUL:
1679                                 case ICMD_DDIV:
1680                                 case ICMD_DREM:
1681
1682                                 case ICMD_LCMP:
1683                                 case ICMD_FCMPL:
1684                                 case ICMD_FCMPG:
1685                                 case ICMD_DCMPL:
1686                                 case ICMD_DCMPG:
1687                                         FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1688                                         FREE_TEMP_REG(iptr->s1.varindex);
1689                                         NEW_TEMP_REG(iptr->dst.varindex);
1690                                         break;
1691
1692                                         /* pop 1 push 1 */
1693                                         
1694                                 case ICMD_IADDCONST:
1695                                 case ICMD_ISUBCONST:
1696                                 case ICMD_IMULCONST:
1697                                 case ICMD_IMULPOW2:
1698                                 case ICMD_IDIVPOW2:
1699                                 case ICMD_IREMPOW2:
1700                                 case ICMD_IANDCONST:
1701                                 case ICMD_IORCONST:
1702                                 case ICMD_IXORCONST:
1703                                 case ICMD_ISHLCONST:
1704                                 case ICMD_ISHRCONST:
1705                                 case ICMD_IUSHRCONST:
1706
1707                                 case ICMD_LADDCONST:
1708                                 case ICMD_LSUBCONST:
1709                                 case ICMD_LMULCONST:
1710                                 case ICMD_LMULPOW2:
1711                                 case ICMD_LDIVPOW2:
1712                                 case ICMD_LREMPOW2:
1713                                 case ICMD_LANDCONST:
1714                                 case ICMD_LORCONST:
1715                                 case ICMD_LXORCONST:
1716                                 case ICMD_LSHLCONST:
1717                                 case ICMD_LSHRCONST:
1718                                 case ICMD_LUSHRCONST:
1719
1720                                 case ICMD_INEG:
1721                                 case ICMD_INT2BYTE:
1722                                 case ICMD_INT2CHAR:
1723                                 case ICMD_INT2SHORT:
1724                                 case ICMD_LNEG:
1725                                 case ICMD_FNEG:
1726                                 case ICMD_DNEG:
1727
1728                                 case ICMD_I2L:
1729                                 case ICMD_I2F:
1730                                 case ICMD_I2D:
1731                                 case ICMD_L2I:
1732                                 case ICMD_L2F:
1733                                 case ICMD_L2D:
1734                                 case ICMD_F2I:
1735                                 case ICMD_F2L:
1736                                 case ICMD_F2D:
1737                                 case ICMD_D2I:
1738                                 case ICMD_D2L:
1739                                 case ICMD_D2F:
1740
1741                                 case ICMD_CHECKCAST:
1742
1743                                 case ICMD_ARRAYLENGTH:
1744                                 case ICMD_INSTANCEOF:
1745
1746                                 case ICMD_NEWARRAY:
1747                                 case ICMD_ANEWARRAY:
1748
1749                                 case ICMD_GETFIELD:
1750                                         FREE_TEMP_REG(iptr->s1.varindex);
1751                                         NEW_TEMP_REG(iptr->dst.varindex);
1752                                         break;
1753
1754                                         /* pop 0 push 1 */
1755                                         
1756                                 case ICMD_GETSTATIC:
1757
1758                                 case ICMD_NEW:
1759                                         NEW_TEMP_REG(iptr->dst.varindex);
1760                                         break;
1761
1762                                         /* pop many push any */
1763                                         
1764                                 case ICMD_INVOKESTATIC:
1765                                 case ICMD_INVOKESPECIAL:
1766                                 case ICMD_INVOKEVIRTUAL:
1767                                 case ICMD_INVOKEINTERFACE:
1768                                         INSTRUCTION_GET_METHODDESC(iptr,md);
1769                                         i = md->paramcount;
1770                                         argp = iptr->sx.s23.s2.args;
1771                                         while (--i >= 0) {
1772                                                 FREE_TEMP_REG(*argp);
1773                                                 argp++;
1774                                         }
1775                                         if (md->returntype.type != TYPE_VOID)
1776                                                 NEW_TEMP_REG(iptr->dst.varindex);
1777                                         break;
1778
1779                                 case ICMD_BUILTIN:
1780                                         bte = iptr->sx.s23.s3.bte;
1781                                         md = bte->md;
1782                                         i = md->paramcount;
1783                                         argp = iptr->sx.s23.s2.args;
1784                                         while (--i >= 0) {
1785                                                 FREE_TEMP_REG(*argp);
1786                                                 argp++;
1787                                         }
1788                                         if (md->returntype.type != TYPE_VOID)
1789                                                 NEW_TEMP_REG(iptr->dst.varindex);
1790                                         break;
1791
1792                                 case ICMD_MULTIANEWARRAY:
1793                                         i = iptr->s1.argcount;
1794                                         argp = iptr->sx.s23.s2.args;
1795                                         while (--i >= 0) {
1796                                                 FREE_TEMP_REG(*argp);
1797                                                 argp++;
1798                                         }
1799                                         NEW_TEMP_REG(iptr->dst.varindex);
1800                                         break;
1801
1802                                 default:
1803                                         exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1804                                                                                                    iptr->opc);
1805                                         return;
1806                                 } /* switch */
1807                                 iptr++;
1808                         } /* while instructions */
1809                 } /* if */
1810                 bptr = bptr->next;
1811         } /* while blocks */
1812 }
1813
1814
1815 #if defined(ENABLE_STATISTICS)
1816 void simplereg_make_statistics(jitdata *jd)
1817 {
1818         methodinfo   *m;
1819         codegendata  *cd;
1820         registerdata *rd;
1821         int i;
1822         s4 len;
1823 #if 0
1824         stackptr    src, src_old;
1825         stackptr    dst;
1826         instruction *iptr;
1827 #endif
1828         basicblock  *bptr;
1829         int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1830         bool in_register;
1831         varinfo *var;
1832
1833         /* get required compiler data */
1834
1835         m  = jd->m;
1836         cd = jd->cd;
1837         rd = jd->rd;
1838
1839         in_register = true;
1840
1841         size_interface = 0;
1842
1843                 /* count how many local variables are held in memory or register */
1844                 for(i=0; i < jd->localcount; i++) {
1845                         if (VAR(i)->flags & INMEMORY) {
1846                                 count_locals_spilled++;
1847                                 in_register=false;
1848                         }
1849                         else {
1850                                 count_locals_register++;
1851                         }
1852                 }
1853
1854                 /* count how many stack slots are held in memory or register */
1855
1856                 bptr = jd->basicblocks;
1857
1858                 while (bptr != NULL) {
1859                         if (bptr->flags >= BBREACHED) {
1860
1861 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1862                         if (!opt_lsra) {
1863 #endif  
1864                                 /* check for memory moves from interface to BB instack */
1865                                 len = bptr->indepth;
1866                                 
1867                                 if (len > size_interface) size_interface = len;
1868
1869                                 while (len) {
1870                                         len--;
1871                                         var = VAR(bptr->invars[len]);
1872
1873                                         /* invars statistics (currently none) */
1874                                 }
1875
1876                                 /* check for memory moves from BB outstack to interface */
1877                                 len = bptr->outdepth;
1878                                 if (len > size_interface) size_interface = len;
1879
1880                                 while (len) {
1881                                         len--;
1882                                         var = VAR(bptr->outvars[len]);
1883
1884                                         /* outvars statistics (currently none) */
1885                                 }
1886 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1887                         }
1888 #endif  
1889
1890
1891 #if 0
1892                                 dst = bptr->instack;
1893                                 iptr = bptr->iinstr;
1894                                 len = bptr->icount;
1895                                 src_old = NULL;
1896
1897                                 while (--len >= 0)  {
1898                                         src = dst;
1899                                         dst = iptr->dst.var;
1900
1901                                         if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1902                                                 switch (src->varkind) {
1903                                                 case TEMPVAR:
1904                                                 case STACKVAR:
1905                                                         if (!(src->flags & INMEMORY)) 
1906                                                                 count_ss_register++;
1907                                                         else {
1908                                                                 count_ss_spilled++;
1909                                                                 in_register=false;
1910                                                         }                               
1911                                                         break;
1912                                                         /*                                      case LOCALVAR: */
1913                                                         /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1914                                                         /*                                                      count_ss_register++; */
1915                                                         /*                                              else */
1916                                                         /*                                                      count_ss_spilled++; */
1917                                                         /*                                              break; */
1918                                                 case ARGVAR:
1919                                                         if (!(src->flags & INMEMORY)) 
1920                                                                 count_argument_mem_ss++;
1921                                                         else
1922                                                                 count_argument_reg_ss++;
1923                                                         break;
1924
1925
1926                                                         /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
1927                                                         /*                                                      if (src->varnum < FLT_ARG_CNT) { */
1928                                                         /*                                                              count_ss_register++; */
1929                                                         /*                                                              break; */
1930                                                         /*                                                      } */
1931                                                         /*                                              } else { */
1932                                                         /* #if defined(__POWERPC__) */
1933                                                         /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1934                                                         /* #else */
1935                                                         /*                                                      if (src->varnum < INT_ARG_CNT) { */
1936                                                         /* #endif */
1937                                                         /*                                                              count_ss_register++; */
1938                                                         /*                                                              break; */
1939                                                         /*                                                      } */
1940                                                         /*                                              } */
1941                                                         /*                                              count_ss_spilled++; */
1942                                                         /*                                              break; */
1943                                                 }
1944                                         }
1945                                         src_old = src;
1946                                         
1947                                         iptr++;
1948                                 } /* while instructions */
1949 #endif
1950                         } /* if */
1951
1952                         bptr = bptr->next;
1953                 } /* while blocks */
1954
1955                 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1956                 if (in_register) count_method_in_register++;
1957                 if (in_register) {
1958 /*                      printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1959                 }
1960 }
1961 #endif /* defined(ENABLE_STATISTICS) */
1962
1963
1964 /*
1965  * These are local overrides for various environment variables in Emacs.
1966  * Please do not remove this and leave it at the end of the file, where
1967  * Emacs will automagically detect them.
1968  * ---------------------------------------------------------------------
1969  * Local variables:
1970  * mode: c
1971  * indent-tabs-mode: t
1972  * c-basic-offset: 4
1973  * tab-width: 4
1974  * End:
1975  * vim:noexpandtab:sw=4:ts=4:
1976  */