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