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