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