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