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