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