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