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