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