a70db51f28ba43d0e6ed5383f2db2565afa22b56
[cacao.git] / src / vm / jit / allocator / simplereg.c
1 /* src/vm/jit/allocator/simplereg.c - register allocator
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    Changes: Stefan Ring
30             Christian Thalinger
31                         Christian Ullrich
32             Michael Starzinger
33
34    $Id: simplereg.c 4080 2006-01-02 21:01:58Z christian $
35
36 */
37
38
39 #include "config.h"
40 #include "vm/types.h"
41
42 #include <assert.h>
43
44 #include "arch.h"
45 #include "md-abi.h"
46
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "mm/memory.h"
50 #include "vm/method.h"
51 #include "vm/options.h"
52 #include "vm/resolve.h"
53 #include "vm/stringlocal.h"
54 #include "vm/jit/reg.h"
55 #include "vm/jit/allocator/simplereg.h"
56
57 /* function prototypes for this file */
58
59 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
60 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
61 static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
62
63
64 /* function interface_regalloc *************************************************
65
66         allocates registers for all interface variables
67         
68 *******************************************************************************/
69         
70 void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
71 {
72         interface_regalloc(m, cd, rd);
73         allocate_scratch_registers(m, rd);
74         local_regalloc(m, cd, rd);
75 }
76
77
78 /* function interface_regalloc *************************************************
79
80         allocates registers for all interface variables
81         
82 *******************************************************************************/
83         
84 static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
85 {
86         int     s, t, tt, saved;
87         int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
88                       /* in case a more vars are packed into this interface slot */
89         varinfo *v;
90         int             intregsneeded = 0;
91         int             memneeded = 0;
92     /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
93         /* on HAS_4BYTE_STACKSLOT architectures */
94         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
95
96         /* rd->memuse was already set in stack.c to allocate stack space for */
97         /* passing arguments to called methods                               */
98 #if defined(__I386__)
99         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
100                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
101                 if (rd->memuse < 1)
102                         rd->memuse = 1;
103         }
104 #endif
105
106         for (s = 0; s < cd->maxstack; s++) {
107                 intalloc = -1; fltalloc = -1;
108                 saved = (rd->interfaces[s][TYPE_INT].flags |
109                                  rd->interfaces[s][TYPE_LNG].flags |
110                          rd->interfaces[s][TYPE_FLT].flags |
111                                  rd->interfaces[s][TYPE_DBL].flags |
112                          rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
113  
114                 for (tt = 0; tt <= 4; tt++) {
115                         t = typeloop[tt];
116                         v = &rd->interfaces[s][t];
117                         if (v->type >= 0) {
118 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
119                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
120 #endif
121 #if defined(HAS_4BYTE_STACKSLOT)
122                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
123 #endif
124                                 if (!saved) {
125 #if defined(HAS_ADDRESS_REGISTER_FILE)
126                                         if (IS_ADR_TYPE(t)) {
127                                                 if (!m->isleafmethod 
128                                                         &&(rd->argadrreguse < ADR_ARG_CNT)) {
129                                                         v->regoff = rd->argadrregs[rd->argadrreguse++];
130                                                 } else if (rd->tmpadrreguse > 0) {
131                                                                 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
132                                                 } else if (rd->savadrreguse > 0) {
133                                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
134                                                 } else {
135                                                         v->flags |= INMEMORY;
136                                                         v->regoff = rd->memuse++;
137                                                 }                                               
138                                         } else /* !IS_ADR_TYPE */
139 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
140                                         {
141                                                 if (IS_FLT_DBL_TYPE(t)) {
142                                                         if (fltalloc >= 0) {
143                        /* Reuse memory slot(s)/register(s) for shared interface slots */
144                                                                 v->flags |= rd->interfaces[s][fltalloc].flags
145                                                                         & INMEMORY;
146                                                                 v->regoff = rd->interfaces[s][fltalloc].regoff;
147                                                         } else if (!m->isleafmethod 
148                                                                            && (rd->argfltreguse < FLT_ARG_CNT)) {
149                                                                 v->regoff = rd->argfltregs[rd->argfltreguse++];
150                                                         } else if (rd->tmpfltreguse > 0) {
151                                                                 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
152                                                         } else if (rd->savfltreguse > 0) {
153                                                                 v->regoff = rd->savfltregs[--rd->savfltreguse];
154                                                         } else {
155                                                                 v->flags |= INMEMORY;
156                                                                 v->regoff = rd->memuse;
157                                                                 rd->memuse += memneeded + 1;
158                                                         }
159                                                         fltalloc = t;
160                                                 } else { /* !IS_FLT_DBL_TYPE(t) */
161 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
162                                                         /*
163                                                          * for i386 put all longs in memory
164                                                          */
165                                                         if (IS_2_WORD_TYPE(t)) {
166                                                                 v->flags |= INMEMORY;
167                                                                 v->regoff = rd->memuse;
168                                                                 rd->memuse += memneeded + 1;
169                                                         } else
170 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
171 /* #if !defined(HAS_4BYTE_STACKSLOT) */
172                                                                 if (intalloc >= 0) {
173                        /* Reuse memory slot(s)/register(s) for shared interface slots */
174                                                                         v->flags |= 
175                                                                                 rd->interfaces[s][intalloc].flags 
176                                                                                 & INMEMORY;
177 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
178                                                                         if (!(v->flags & INMEMORY) 
179                                                                                 && IS_2_WORD_TYPE(intalloc))
180                                                                                 v->regoff = GET_LOW_REG(
181                                                                                         rd->interfaces[s][intalloc].regoff);
182                                                                         else
183 #endif
184                                                                                 v->regoff = 
185                                                                                     rd->interfaces[s][intalloc].regoff;
186                                                                 } else 
187 /* #endif *//* !defined(HAS_4BYTE_STACKSLOT) */
188                                                                         if (!m->isleafmethod && 
189                                                                                 (rd->argintreguse 
190                                                                                  + intregsneeded < INT_ARG_CNT)) {
191 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
192                                                                                 if (intregsneeded) 
193                                                                                         v->regoff=PACK_REGS( 
194                                                                                   rd->argintregs[rd->argintreguse],
195                                                                                   rd->argintregs[rd->argintreguse + 1]);
196                                                                                 else
197 #endif
198                                                                                         v->regoff = 
199                                                                                            rd->argintregs[rd->argintreguse];
200                                                                                 rd->argintreguse += intregsneeded + 1;
201                                                                         }
202                                                                         else if (rd->tmpintreguse > intregsneeded) {
203                                                                                 rd->tmpintreguse -= intregsneeded + 1;
204 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
205                                                                                 if (intregsneeded) 
206                                                                                         v->regoff=PACK_REGS( 
207                                                                                   rd->tmpintregs[rd->tmpintreguse],
208                                                                                   rd->tmpintregs[rd->tmpintreguse + 1]);
209                                                                                 else
210 #endif
211                                                                                         v->regoff = 
212                                                                                            rd->tmpintregs[rd->tmpintreguse];
213                                                                         }
214                                                                         else if (rd->savintreguse > intregsneeded) {
215                                                                                 rd->savintreguse -= intregsneeded + 1;
216                                                                                 v->regoff = 
217                                                                                         rd->savintregs[rd->savintreguse];
218 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
219                                                                                 if (intregsneeded) 
220                                                                                         v->regoff=PACK_REGS( 
221                                                                                   rd->savintregs[rd->savintreguse],
222                                                                                   rd->savintregs[rd->savintreguse + 1]);
223                                                                                 else
224 #endif
225                                                                                         v->regoff = 
226                                                                                            rd->savintregs[rd->savintreguse];
227                                                                         }
228                                                                         else {
229                                                                                 v->flags |= INMEMORY;
230                                                                                 v->regoff = rd->memuse;
231                                                                                 rd->memuse += memneeded + 1;
232                                                                         }
233
234                                                         intalloc = t;
235                                                 } /* if (IS_FLT_DBL_TYPE(t)) */
236                                         } 
237                                 } else { /* (saved) */
238 /* now the same like above, but without a chance to take a temporary register */
239 #ifdef HAS_ADDRESS_REGISTER_FILE
240                                         if (IS_ADR_TYPE(t)) {
241                                                 if (rd->savadrreguse > 0) {
242                                                         v->regoff = rd->savadrregs[--rd->savadrreguse];
243                                                 }
244                                                 else {
245                                                         v->flags |= INMEMORY;
246                                                         v->regoff = rd->memuse++;
247                                                 }                                               
248                                         } else
249 #endif
250                                         {
251                                                 if (IS_FLT_DBL_TYPE(t)) {
252                                                         if (fltalloc >= 0) {
253                                                                 v->flags |= rd->interfaces[s][fltalloc].flags
254                                                                         & INMEMORY;
255                                                                 v->regoff = rd->interfaces[s][fltalloc].regoff;
256                                                         } else
257                                                                 if (rd->savfltreguse > 0) {
258                                                                         v->regoff = rd->savfltregs[--rd->savfltreguse];
259                                                                 }
260                                                                 else {
261                                                                         v->flags |= INMEMORY;
262                                                                         v->regoff = rd->memuse;
263                                                                         rd->memuse += memneeded + 1;
264                                                                 }
265                                                         fltalloc = t;
266                                                 }
267                                                 else { /* IS_INT_LNG */
268 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
269                                                         /*
270                                                          * for i386 put all longs in memory
271                                                          */
272                                                         if (IS_2_WORD_TYPE(t)) {
273                                                                 v->flags |= INMEMORY;
274                                                                 v->regoff = rd->memuse;
275                                                                 rd->memuse += memneeded + 1;
276                                                         } else
277 #endif
278                                                         {
279 /* #if !defined(HAS_4BYTE_STACKSLOT) */
280                                                                 if (intalloc >= 0) {
281                                                                         v->flags |= 
282                                                                    rd->interfaces[s][intalloc].flags & INMEMORY;
283 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
284                                                                         if (!(v->flags & INMEMORY)
285                                                                                 && IS_2_WORD_TYPE(intalloc))
286                                                                                 v->regoff =
287                                                                                         GET_LOW_REG(
288                                                                                         rd->interfaces[s][intalloc].regoff);
289                                                                         else
290 #endif
291                                                                                 v->regoff =
292                                                                                         rd->interfaces[s][intalloc].regoff;
293                                                                 } else
294 /* #endif */
295                                                                 {
296                                                                         if (rd->savintreguse > intregsneeded) {
297                                                                                 rd->savintreguse -= intregsneeded + 1;
298 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
299                                                                                 if (intregsneeded) 
300                                                                                         v->regoff = PACK_REGS( 
301                                                                                   rd->savintregs[rd->savintreguse],
302                                                                                   rd->savintregs[rd->savintreguse + 1]);
303                                                                                 else
304 #endif
305                                                                                         v->regoff =
306                                                                                            rd->savintregs[rd->savintreguse];
307                                                                         } else {
308                                                                                 v->flags |= INMEMORY;
309                                                                                 v->regoff = rd->memuse;
310                                                                                 rd->memuse += memneeded + 1;
311                                                                         }
312                                                                 }
313                                                                 intalloc = t;
314                                                         }
315                                                 } /* if (IS_FLT_DBL_TYPE(t) else */
316                                         } /* if (IS_ADR_TYPE(t)) else */
317                                 } /* if (saved) else */
318                         } /* if (type >= 0) */
319                 } /* for t */
320         } /* for s */
321 }
322
323
324
325 /* function local_regalloc *****************************************************
326
327         allocates registers for all local variables
328         
329 *******************************************************************************/
330         
331 static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
332 {
333         int     p, s, t, tt;
334         int     intalloc, fltalloc;
335         varinfo *v;
336         int     intregsneeded = 0;
337         int     memneeded = 0;
338         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
339         int     fargcnt, iargcnt;
340 #ifdef HAS_ADDRESS_REGISTER_FILE
341         int     aargcnt;
342 #endif
343
344         if (m->isleafmethod) {
345                 methoddesc *md = m->parseddesc;
346
347                 iargcnt = md->argintreguse;
348                 fargcnt = md->argfltreguse;
349 #ifdef HAS_ADDRESS_REGISTER_FILE
350                 aargcnt = md->argadrreguse;
351 #endif
352                 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
353                         intalloc = -1; fltalloc = -1;
354                         for (tt = 0; tt <= 4; tt++) {
355                                 t = typeloop[tt];
356                                 v = &rd->locals[s][t];
357
358                                 if (v->type < 0)
359                                         continue;
360
361 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
362                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
363 #endif
364 #if defined(HAS_4BYTE_STACKSLOT)
365                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
366 #endif
367
368                                 /*
369                                  *  The order of
370                                  *
371                                  *  #ifdef HAS_ADDRESS_REGISTER_FILE
372                                  *  if (IS_ADR_TYPE) { 
373                                  *  ...
374                                  *  } else 
375                                  *  #endif
376                                  *  if (IS_FLT_DBL) {
377                                  *  ...
378                                  *  } else { / int & lng
379                                  *  ...
380                                  *  }
381                                  *
382                                  *  must not to be changed!
383                                  */
384
385 #ifdef HAS_ADDRESS_REGISTER_FILE
386                                 if (IS_ADR_TYPE(t)) {
387                                         if ((p < md->paramcount) && !md->params[p].inmemory) {
388                                                 v->flags = 0;
389                                                 v->regoff = rd->argadrregs[md->params[p].regoff];
390                                         }
391                                         if (rd->tmpadrreguse > 0) {
392                                                 v->flags = 0;
393                                                 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
394                                         }
395                                         else if (rd->savadrreguse > 0) {
396                                                 v->flags = 0;
397                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
398                                         }
399                                         /* use unused argument registers as local registers */
400                                         else if ((p >= md->paramcount) &&
401                                                          (aargcnt < ADR_ARG_CNT)) {
402                                                 v->flags = 0;
403                                                 v->regoff = rd->argadrregs[aargcnt++];
404                                         }
405                                         else {
406                                                 v->flags |= INMEMORY;
407                                                 v->regoff = rd->memuse++;
408                                         }                                               
409                                 } else {
410 #endif
411                                         if (IS_FLT_DBL_TYPE(t)) {
412                                                 if (fltalloc >= 0) {
413                                                         v->flags = rd->locals[s][fltalloc].flags;
414                                                         v->regoff = rd->locals[s][fltalloc].regoff;
415                                                 }
416 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
417                                                 /* We can only use float arguments as local variables,
418                                                  * if we do not pass them in integer registers. */
419                                                 else if ((p < md->paramcount) &&
420                                                                  !md->params[p].inmemory) {
421                                                         v->flags = 0;
422                                                         v->regoff = rd->argfltregs[md->params[p].regoff];
423                                                 }
424 #endif
425                                                 else if (rd->tmpfltreguse > 0) {
426                                                         v->flags = 0;
427                                                         v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
428                                                 }
429                                                 else if (rd->savfltreguse > 0) {
430                                                         v->flags = 0;
431                                                         v->regoff = rd->savfltregs[--rd->savfltreguse];
432                                                 }
433                                                 /* use unused argument registers as local registers */
434                                                 else if ((p >= m->paramcount) &&
435                                                                  (fargcnt < FLT_ARG_CNT)) {
436                                                         v->flags = 0;
437                                                         v->regoff = rd->argfltregs[fargcnt];
438                                                         fargcnt++;
439                                                 }
440                                                 else {
441                                                         v->flags = INMEMORY;
442                                                         v->regoff = rd->memuse;
443                                                         rd->memuse += memneeded + 1;
444                                                 }
445                                                 fltalloc = t;
446
447                                         } else {
448 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
449                                                 /*
450                                                  * for i386 put all longs in memory
451                                                  */
452                                                 if (IS_2_WORD_TYPE(t)) {
453                                                         v->flags = INMEMORY;
454                                                         v->regoff = rd->memuse;
455                                                         rd->memuse += memneeded + 1;
456                                                 } else 
457 #endif
458                                                 {
459                                                         if (intalloc >= 0) {
460                                                                 v->flags = rd->locals[s][intalloc].flags;
461 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
462                                                                 if (!(v->flags & INMEMORY)
463                                                                         && IS_2_WORD_TYPE(intalloc))
464                                                                         v->regoff = GET_LOW_REG(
465                                                                                     rd->locals[s][intalloc].regoff);
466                                                                 else
467 #endif
468                                                                         v->regoff = rd->locals[s][intalloc].regoff;
469                                                         }
470                                                         else if ((p < md->paramcount) && 
471                                                                          !md->params[p].inmemory) {
472                                                                 v->flags = 0;
473 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
474                                                                 if (IS_2_WORD_TYPE(t))
475 /* For ARM: - if GET_LOW_REG(md->params[p].regoff) == R4, prevent here that   */
476 /* rd->argintregs[GET_HIGH_REG(md->...)) is used!                             */
477                                                                         v->regoff = PACK_REGS(
478                                                         rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
479                                                         rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
480                                                                         else
481 #endif
482                                                                                 v->regoff =
483                                                                                rd->argintregs[md->params[p].regoff];
484                                                         }
485                                                         else if (rd->tmpintreguse > intregsneeded) {
486                                                                 rd->tmpintreguse -= intregsneeded + 1;
487                                                                 v->flags = 0;
488 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
489                                                                 if (intregsneeded) 
490                                                                         v->regoff = PACK_REGS(
491                                                                             rd->tmpintregs[rd->tmpintreguse],
492                                                                                 rd->tmpintregs[rd->tmpintreguse + 1]);
493                                                                 else
494 #endif
495                                                                         v->regoff = 
496                                                                                 rd->tmpintregs[rd->tmpintreguse];
497                                                         }
498                                                         else if (rd->savintreguse > intregsneeded) {
499                                                                 rd->savintreguse -= intregsneeded + 1;
500                                                                 v->flags = 0;
501 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
502                                                                 if (intregsneeded) 
503                                                                         v->regoff = PACK_REGS(
504                                                                             rd->savintregs[rd->savintreguse],
505                                                                                 rd->savintregs[rd->savintreguse + 1]);
506                                                                 else
507 #endif
508                                                                         v->regoff =rd->savintregs[rd->savintreguse];
509                                                         }
510                                                         /*
511                                                          * use unused argument registers as local registers
512                                                          */
513                                                         else if ((p >= m->paramcount) &&
514                                                                          (iargcnt < INT_ARG_CNT)) {
515                                                                 v->flags = 0;
516                                                                 v->regoff = rd->argintregs[iargcnt];
517                                                                 iargcnt++;
518                                                         }
519                                                         else {
520                                                                 v->flags = INMEMORY;
521                                                                 v->regoff = rd->memuse;
522                                                                 rd->memuse += memneeded + 1;
523                                                         }
524                                                 }
525                                                 intalloc = t;
526                                         }
527 #ifdef HAS_ADDRESS_REGISTER_FILE
528                                 }
529 #endif
530                         } /* for (tt=0;...) */
531
532                         /* If the current parameter is a 2-word type, the next local slot */
533                         /* is skipped.                                                    */
534
535                         if (p < md->paramcount)
536                                 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
537                                         s++;
538                 }
539                 return;
540         }
541
542         for (s = 0; s < cd->maxlocals; s++) {
543                 intalloc = -1; fltalloc = -1;
544                 for (tt=0; tt<=4; tt++) {
545                         t = typeloop[tt];
546                         v = &rd->locals[s][t];
547
548                         if (v->type >= 0) {
549 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
550                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
551 #endif
552 #if defined(HAS_4BYTE_STACKSLOT)
553                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
554 #endif
555 #ifdef HAS_ADDRESS_REGISTER_FILE
556                                 if ( IS_ADR_TYPE(t) ) {
557                                         if (rd->savadrreguse > 0) {
558                                                 v->flags = 0;
559                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
560                                         }
561                                         else {
562                                                 v->flags = INMEMORY;
563                                                 v->regoff = rd->memuse++;
564                                         }
565                                 } else {
566 #endif
567                                 if (IS_FLT_DBL_TYPE(t)) {
568                                         if (fltalloc >= 0) {
569                                                 v->flags = rd->locals[s][fltalloc].flags;
570                                                 v->regoff = rd->locals[s][fltalloc].regoff;
571                                         }
572                                         else if (rd->savfltreguse > 0) {
573                                                 v->flags = 0;
574                                                 v->regoff = rd->savfltregs[--rd->savfltreguse];
575                                         }
576                                         else {
577                                                 v->flags = INMEMORY;
578                                                 /* Align doubles in Memory */
579                                                 if ( (memneeded) && (rd->memuse & 1))
580                                                         rd->memuse++;
581                                                 v->regoff = rd->memuse;
582                                                 rd->memuse += memneeded + 1;
583                                         }
584                                         fltalloc = t;
585                                 }
586                                 else {
587 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
588                                         /*
589                                          * for i386 put all longs in memory
590                                          */
591                                         if (IS_2_WORD_TYPE(t)) {
592                                                 v->flags = INMEMORY;
593                                                 v->regoff = rd->memuse;
594                                                 rd->memuse += memneeded + 1;
595                                         } else {
596 #endif
597                                                 if (intalloc >= 0) {
598                                                         v->flags = rd->locals[s][intalloc].flags;
599 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
600                                                         if (!(v->flags & INMEMORY)
601                                                                 && IS_2_WORD_TYPE(intalloc))
602                                                                 v->regoff = GET_LOW_REG(
603                                                                             rd->locals[s][intalloc].regoff);
604                                                         else
605 #endif
606                                                                 v->regoff = rd->locals[s][intalloc].regoff;
607                                                 }
608                                                 else if (rd->savintreguse > intregsneeded) {
609                                                         rd->savintreguse -= intregsneeded+1;
610                                                         v->flags = 0;
611 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
612                                                                 if (intregsneeded) 
613                                                                         v->regoff = PACK_REGS(
614                                                                                 rd->savintregs[rd->savintreguse],
615                                                                             rd->savintregs[rd->savintreguse + 1]);
616                                                                 else
617 #endif
618                                                                         v->regoff =rd->savintregs[rd->savintreguse];
619                                                 }
620                                                 else {
621                                                         v->flags = INMEMORY;
622                                                         v->regoff = rd->memuse;
623                                                         rd->memuse += memneeded + 1;
624                                                 }
625 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
626                                         }
627 #endif
628                                         intalloc = t;
629                                 }
630 #ifdef HAS_ADDRESS_REGISTER_FILE
631                                 }
632 #endif
633
634                         }
635                 }
636         }
637 }
638
639 static void reg_init_temp(methodinfo *m, registerdata *rd)
640 {
641         rd->freememtop = 0;
642 #if defined(HAS_4BYTE_STACKSLOT)
643         rd->freememtop_2 = 0;
644 #endif
645
646         rd->freetmpinttop = 0;
647         rd->freesavinttop = 0;
648         rd->freetmpflttop = 0;
649         rd->freesavflttop = 0;
650 #ifdef HAS_ADDRESS_REGISTER_FILE
651         rd->freetmpadrtop = 0;
652         rd->freesavadrtop = 0;
653 #endif
654
655         rd->freearginttop = 0;
656         rd->freeargflttop = 0;
657 #ifdef HAS_ADDRESS_REGISTER_FILE
658         rd->freeargadrtop = 0;
659 #endif
660
661         if (m->isleafmethod) {
662                 /* Don't use not used Argument Registers in Leafmethods -> they could */
663                 /* already be in use for Locals passed as parameter to this Method    */
664                 rd->argintreguse = INT_ARG_CNT;
665                 rd->argfltreguse = FLT_ARG_CNT;
666 #ifdef HAS_ADDRESS_REGISTER_FILE
667                 rd->argadrreguse = ADR_ARG_CNT;
668 #endif
669         }
670 }
671
672
673 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
674
675 static void reg_new_temp_func(registerdata *rd, stackptr s)
676 {
677         s4 intregsneeded;
678         s4 memneeded;
679         s4 tryagain;
680
681         /* Try to allocate a saved register if there is no temporary one          */
682         /* available. This is what happens during the second run.                 */
683         tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
684
685 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
686         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
687 #else
688         intregsneeded = 0;
689 #endif
690 #if defined(HAS_4BYTE_STACKSLOT)
691         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
692 #else
693         memneeded = 0;
694 #endif
695
696         for(; tryagain; --tryagain) {
697                 if (tryagain == 1) {
698                         if (!(s->flags & SAVEDVAR))
699                                 s->flags |= SAVEDTMP;
700 #ifdef HAS_ADDRESS_REGISTER_FILE
701                         if (IS_ADR_TYPE(s->type)) {
702                                 if (rd->freesavadrtop > 0) {
703                                         s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
704                                         return;
705                                 } else if (rd->savadrreguse > 0) {
706                                         s->regoff = rd->savadrregs[--rd->savadrreguse];
707                                         return;
708                                 }
709                         } else
710 #endif
711                         {
712                                 if (IS_FLT_DBL_TYPE(s->type)) {
713                                         if (rd->freesavflttop > 0) {
714                                                 s->regoff = rd->freesavfltregs[--rd->freesavflttop];
715                                                 return;
716                                         } else if (rd->savfltreguse > 0) {
717                                                 s->regoff = rd->savfltregs[--rd->savfltreguse];
718                                                 return;
719                                         }
720                                 } else {
721 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
722                                         /*
723                                          * for i386 put all longs in memory
724                                          */
725                                         if (!IS_2_WORD_TYPE(s->type))
726 #endif
727                                         {
728                                                 if (rd->freesavinttop > intregsneeded) {
729                                                         rd->freesavinttop -= intregsneeded + 1;
730 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
731                                                         if (intregsneeded)
732                                                                 s->regoff = PACK_REGS(
733                                                                 rd->freesavintregs[rd->freesavinttop],
734                                                                         rd->freesavintregs[rd->freesavinttop + 1]);
735                                                 else
736 #endif
737                                                                 s->regoff =
738                                                                         rd->freesavintregs[rd->freesavinttop];
739                                                         return;
740                                                 } else if (rd->savintreguse > intregsneeded) {
741                                                         rd->savintreguse -= intregsneeded + 1;
742 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
743                                                         if (intregsneeded)
744                                                                 s->regoff = PACK_REGS(
745                                                                         rd->savintregs[rd->savintreguse],
746                                                                 rd->savintregs[rd->savintreguse + 1]);
747                                                         else
748 #endif
749                                                                 s->regoff = rd->savintregs[rd->savintreguse];
750                                                         return;
751                                                 }
752                                         }
753                                 }
754                         }
755                 } else { /* tryagain == 2 */
756 #ifdef HAS_ADDRESS_REGISTER_FILE
757                         if (IS_ADR_TYPE(s->type)) {
758                                 if (rd->freetmpadrtop > 0) {
759                                         s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
760                                         return;
761                                 } else if (rd->tmpadrreguse > 0) {
762                                         s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
763                                         return;
764                                 }
765                         } else
766 #endif
767                         {
768                                 if (IS_FLT_DBL_TYPE(s->type)) {
769                                         if (rd->freeargflttop > 0) {
770                                                 s->regoff = rd->freeargfltregs[--rd->freeargflttop];
771                                                 s->flags |= TMPARG;
772                                                 return;
773                                         } else if (rd->argfltreguse < FLT_ARG_CNT) {
774                                                 s->regoff = rd->argfltregs[rd->argfltreguse++];
775                                                 s->flags |= TMPARG;
776                                                 return;
777                                         } else if (rd->freetmpflttop > 0) {
778                                                 s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
779                                                 return;
780                                         } else if (rd->tmpfltreguse > 0) {
781                                                 s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
782                                                 return;
783                                         }
784
785                                 } else {
786 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
787                                         /*
788                                          * for i386 put all longs in memory
789                                          */
790                                         if (!IS_2_WORD_TYPE(s->type))
791 #endif
792                                         {
793                                                 if (rd->freearginttop > intregsneeded) {
794                                                         rd->freearginttop -= intregsneeded + 1;
795                                                         s->flags |= TMPARG;
796 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
797                                                         if (intregsneeded) 
798                                                                 s->regoff = PACK_REGS(
799                                                                         rd->freeargintregs[rd->freearginttop],
800                                                                 rd->freeargintregs[rd->freearginttop + 1]);
801                                                         else
802 #endif
803                                                                 s->regoff =
804                                                                         rd->freeargintregs[rd->freearginttop];
805                                                         return;
806                                                 } else if (rd->argintreguse 
807                                                                    < INT_ARG_CNT - intregsneeded) {
808 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
809                                                         if (intregsneeded) 
810                                                                 s->regoff = PACK_REGS(
811                                                                         rd->argintregs[rd->argintreguse],
812                                                                     rd->argintregs[rd->argintreguse + 1]);
813                                                         else
814 #endif
815                                                                 s->regoff = rd->argintregs[rd->argintreguse];
816                                                         s->flags |= TMPARG;
817                                                         rd->argintreguse += intregsneeded + 1;
818                                                         return;
819                                                 } else if (rd->freetmpinttop > intregsneeded) {
820                                                         rd->freetmpinttop -= intregsneeded + 1;
821 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
822                                                         if (intregsneeded) 
823                                                                 s->regoff = PACK_REGS(
824                                                                         rd->freetmpintregs[rd->freetmpinttop],
825                                                                     rd->freetmpintregs[rd->freetmpinttop + 1]);
826                                                         else
827 #endif
828                                                                 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
829                                                         return;
830                                                 } else if (rd->tmpintreguse > intregsneeded) {
831                                                         rd->tmpintreguse -= intregsneeded + 1;
832 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
833                                                         if (intregsneeded) 
834                                                                 s->regoff = PACK_REGS(
835                                                                         rd->tmpintregs[rd->tmpintreguse],
836                                                                     rd->tmpintregs[rd->tmpintreguse + 1]);
837                                                         else
838 #endif
839                                                                 s->regoff = rd->tmpintregs[rd->tmpintreguse];
840                                                         return;
841                                                 }
842                                         } /* if (!IS_2_WORD_TYPE(s->type)) */
843                                 } /* if (IS_FLT_DBL_TYPE(s->type)) */
844                         } /* if (IS_ADR_TYPE(s->type)) */
845                 } /* if (tryagain == 1) else */
846         } /* for(; tryagain; --tryagain) */
847
848 #if defined(HAS_4BYTE_STACKSLOT)
849         if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
850                 rd->freememtop_2--;
851                 s->regoff = rd->freemem_2[rd->freememtop_2];
852         } else
853 #endif /*defined(HAS_4BYTE_STACKSLOT) */
854                 if ((memneeded == 0) && (rd->freememtop > 0)) {
855                         rd->freememtop--;;
856                         s->regoff = rd->freemem[rd->freememtop];
857                 } else {
858 #if defined(HAS_4BYTE_STACKSLOT)
859                         /* align 2 Word Types */
860                         if ((memneeded) && ((rd->memuse & 1) == 1)) { 
861                                 /* Put patched memory slot on freemem */
862                                 rd->freemem[rd->freememtop++] = rd->memuse;
863                                 rd->memuse++;
864                         }
865 #endif /*defined(HAS_4BYTE_STACKSLOT) */
866                         s->regoff = rd->memuse;
867                         rd->memuse += memneeded + 1;
868                 }
869         s->flags |= INMEMORY;
870 }
871
872
873 #define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
874
875 static void reg_free_temp_func(registerdata *rd, stackptr s)
876 {
877         s4 intregsneeded;
878         s4 memneeded;
879
880 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
881         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
882 #else
883         intregsneeded = 0;
884 #endif
885
886 #if defined(HAS_4BYTE_STACKSLOT)
887         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
888 #else
889         memneeded = 0;
890 #endif
891
892         if (s->flags & INMEMORY) {
893 #if defined(HAS_4BYTE_STACKSLOT)
894                 if (memneeded > 0) {
895                         rd->freemem_2[rd->freememtop_2] = s->regoff;
896                         rd->freememtop_2++;
897                 } else 
898 #endif
899                 {
900                         rd->freemem[rd->freememtop] = s->regoff;
901                         rd->freememtop++;
902                 }
903
904 #ifdef HAS_ADDRESS_REGISTER_FILE
905         } else if (IS_ADR_TYPE(s->type)) {
906                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
907                         s->flags &= ~SAVEDTMP;
908                         rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
909                 } else
910                         rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
911 #endif
912         } else if (IS_FLT_DBL_TYPE(s->type)) {
913                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
914                         s->flags &= ~SAVEDTMP;
915                         rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
916                 } else if (s->flags & TMPARG) {
917                         s->flags &= ~TMPARG;
918                         rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
919                 } else
920                         rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
921         } else { /* IS_INT_LNG_TYPE */
922                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
923                         s->flags &= ~SAVEDTMP;
924 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
925                         if (intregsneeded) {
926                                 rd->freesavintregs[rd->freesavinttop] =
927                                         GET_LOW_REG(s->regoff);
928                                 rd->freesavintregs[rd->freesavinttop + 1] =
929                                         GET_HIGH_REG(s->regoff);
930                         } else
931 #endif
932                                 rd->freesavintregs[rd->freesavinttop] = s->regoff;
933                         rd->freesavinttop += intregsneeded + 1;
934
935                 } else if (s->flags & TMPARG) {
936                         s->flags &= ~TMPARG;
937 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
938                         if (intregsneeded) {
939                                 rd->freeargintregs[rd->freearginttop] =
940                                         GET_LOW_REG(s->regoff);
941                                 rd->freeargintregs[rd->freearginttop + 1] =
942                                         GET_HIGH_REG(s->regoff);
943                         } else 
944 #endif
945                                 rd->freeargintregs[rd->freearginttop] = s->regoff;
946                         rd->freearginttop += intregsneeded + 1;
947                 } else {
948 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
949                         if (intregsneeded) {
950                                 rd->freetmpintregs[rd->freetmpinttop] =
951                                         GET_LOW_REG(s->regoff);
952                                 rd->freetmpintregs[rd->freetmpinttop + 1] =
953                                         GET_HIGH_REG(s->regoff);
954                         } else
955 #endif
956                                 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
957                         rd->freetmpinttop += intregsneeded + 1;
958                 }
959         }
960 }
961
962
963
964 static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
965 {
966         s4                  opcode;
967         s4                  i;
968         s4                  len;
969         stackptr            src;
970         stackptr            dst;
971         instruction        *iptr;
972         basicblock         *bptr;
973         methodinfo         *lm;
974         builtintable_entry *bte;
975         methoddesc         *md;
976
977         /* initialize temp registers */
978         reg_init_temp(m, rd);
979
980         bptr = m->basicblocks;
981
982         while (bptr != NULL) {
983                 if (bptr->flags >= BBREACHED) {
984                         dst = bptr->instack;
985
986
987                         iptr = bptr->iinstr;
988                         len = bptr->icount;
989
990                         while (--len >= 0)  {
991                                 src = dst;
992                                 dst = iptr->dst;
993                                 opcode = iptr->opc;
994
995                                 switch (opcode) {
996
997                                         /* pop 0 push 0 */
998
999                                 case ICMD_NOP:
1000                                 case ICMD_ELSE_ICONST:
1001                                 case ICMD_CHECKNULL:
1002                                 case ICMD_IINC:
1003                                 case ICMD_JSR:
1004                                 case ICMD_RET:
1005                                 case ICMD_RETURN:
1006                                 case ICMD_GOTO:
1007                                 case ICMD_PUTSTATICCONST:
1008                                 case ICMD_INLINE_START:
1009                                 case ICMD_INLINE_END:
1010                                         break;
1011
1012                                         /* pop 0 push 1 const */
1013                                         
1014                                 case ICMD_ICONST:
1015                                 case ICMD_LCONST:
1016                                 case ICMD_FCONST:
1017                                 case ICMD_DCONST:
1018                                 case ICMD_ACONST:
1019
1020                                         /* pop 0 push 1 load */
1021                                         
1022                                 case ICMD_ILOAD:
1023                                 case ICMD_LLOAD:
1024                                 case ICMD_FLOAD:
1025                                 case ICMD_DLOAD:
1026                                 case ICMD_ALOAD:
1027                                         reg_new_temp(rd, dst);
1028                                         break;
1029
1030                                         /* pop 2 push 1 */
1031
1032                                 case ICMD_IALOAD:
1033                                 case ICMD_LALOAD:
1034                                 case ICMD_FALOAD:
1035                                 case ICMD_DALOAD:
1036                                 case ICMD_AALOAD:
1037
1038                                 case ICMD_BALOAD:
1039                                 case ICMD_CALOAD:
1040                                 case ICMD_SALOAD:
1041                                         reg_free_temp(rd, src);
1042                                         reg_free_temp(rd, src->prev);
1043                                         reg_new_temp(rd, dst);
1044                                         break;
1045
1046                                         /* pop 3 push 0 */
1047
1048                                 case ICMD_IASTORE:
1049                                 case ICMD_LASTORE:
1050                                 case ICMD_FASTORE:
1051                                 case ICMD_DASTORE:
1052                                 case ICMD_AASTORE:
1053
1054                                 case ICMD_BASTORE:
1055                                 case ICMD_CASTORE:
1056                                 case ICMD_SASTORE:
1057                                         reg_free_temp(rd, src);
1058                                         reg_free_temp(rd, src->prev);
1059                                         reg_free_temp(rd, src->prev->prev);
1060                                         break;
1061
1062                                         /* pop 1 push 0 store */
1063
1064                                 case ICMD_ISTORE:
1065                                 case ICMD_LSTORE:
1066                                 case ICMD_FSTORE:
1067                                 case ICMD_DSTORE:
1068                                 case ICMD_ASTORE:
1069
1070                                         /* pop 1 push 0 */
1071
1072                                 case ICMD_POP:
1073
1074                                 case ICMD_IRETURN:
1075                                 case ICMD_LRETURN:
1076                                 case ICMD_FRETURN:
1077                                 case ICMD_DRETURN:
1078                                 case ICMD_ARETURN:
1079
1080                                 case ICMD_ATHROW:
1081
1082                                 case ICMD_PUTSTATIC:
1083                                 case ICMD_PUTFIELDCONST:
1084
1085                                         /* pop 1 push 0 branch */
1086
1087                                 case ICMD_IFNULL:
1088                                 case ICMD_IFNONNULL:
1089
1090                                 case ICMD_IFEQ:
1091                                 case ICMD_IFNE:
1092                                 case ICMD_IFLT:
1093                                 case ICMD_IFGE:
1094                                 case ICMD_IFGT:
1095                                 case ICMD_IFLE:
1096
1097                                 case ICMD_IF_LEQ:
1098                                 case ICMD_IF_LNE:
1099                                 case ICMD_IF_LLT:
1100                                 case ICMD_IF_LGE:
1101                                 case ICMD_IF_LGT:
1102                                 case ICMD_IF_LLE:
1103
1104                                         /* pop 1 push 0 table branch */
1105
1106                                 case ICMD_TABLESWITCH:
1107                                 case ICMD_LOOKUPSWITCH:
1108
1109                                 case ICMD_MONITORENTER:
1110                                 case ICMD_MONITOREXIT:
1111                                         reg_free_temp(rd, src);
1112                                         break;
1113
1114                                         /* pop 2 push 0 branch */
1115
1116                                 case ICMD_IF_ICMPEQ:
1117                                 case ICMD_IF_ICMPNE:
1118                                 case ICMD_IF_ICMPLT:
1119                                 case ICMD_IF_ICMPGE:
1120                                 case ICMD_IF_ICMPGT:
1121                                 case ICMD_IF_ICMPLE:
1122
1123                                 case ICMD_IF_LCMPEQ:
1124                                 case ICMD_IF_LCMPNE:
1125                                 case ICMD_IF_LCMPLT:
1126                                 case ICMD_IF_LCMPGE:
1127                                 case ICMD_IF_LCMPGT:
1128                                 case ICMD_IF_LCMPLE:
1129
1130                                 case ICMD_IF_ACMPEQ:
1131                                 case ICMD_IF_ACMPNE:
1132
1133                                         /* pop 2 push 0 */
1134
1135                                 case ICMD_POP2:
1136
1137                                 case ICMD_PUTFIELD:
1138
1139                                 case ICMD_IASTORECONST:
1140                                 case ICMD_LASTORECONST:
1141                                 case ICMD_AASTORECONST:
1142                                 case ICMD_BASTORECONST:
1143                                 case ICMD_CASTORECONST:
1144                                 case ICMD_SASTORECONST:
1145                                         reg_free_temp(rd, src);
1146                                         reg_free_temp(rd, src->prev);
1147                                         break;
1148
1149                                         /* pop 0 push 1 dup */
1150                                         
1151                                 case ICMD_DUP:
1152                                         reg_new_temp(rd, dst);
1153                                         break;
1154
1155                                         /* pop 0 push 2 dup */
1156                                         
1157                                 case ICMD_DUP2:
1158                                         reg_new_temp(rd, dst->prev);
1159                                         reg_new_temp(rd, dst);
1160                                         break;
1161
1162                                         /* pop 2 push 3 dup */
1163                                         
1164                                 case ICMD_DUP_X1:
1165                                         reg_free_temp(rd, src);
1166                                         reg_new_temp(rd, dst);
1167                                         reg_free_temp(rd, src->prev);
1168                                         reg_new_temp(rd, dst->prev);
1169                                         reg_new_temp(rd, dst->prev->prev);
1170                                         break;
1171
1172                                         /* pop 3 push 4 dup */
1173                                         
1174                                 case ICMD_DUP_X2:
1175                                         reg_free_temp(rd, src);
1176                                         reg_new_temp(rd, dst);
1177                                         reg_free_temp(rd, src->prev);
1178                                         reg_new_temp(rd, dst->prev);
1179                                         reg_free_temp(rd, src->prev->prev);
1180                                         reg_new_temp(rd, dst->prev->prev);
1181                                         reg_new_temp(rd, dst->prev->prev->prev);
1182                                         break;
1183
1184                                         /* pop 3 push 5 dup */
1185                                         
1186                                 case ICMD_DUP2_X1:
1187                                         reg_free_temp(rd, src);
1188                                         reg_new_temp(rd, dst);
1189                                         reg_free_temp(rd, src->prev);
1190                                         reg_new_temp(rd, dst->prev);
1191                                         reg_free_temp(rd, src->prev->prev);
1192                                         reg_new_temp(rd, dst->prev->prev);
1193                                         reg_new_temp(rd, dst->prev->prev->prev);
1194                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1195                                         break;
1196
1197                                         /* pop 4 push 6 dup */
1198                                         
1199                                 case ICMD_DUP2_X2:
1200                                         reg_free_temp(rd, src);
1201                                         reg_new_temp(rd, dst);
1202                                         reg_free_temp(rd, src->prev);
1203                                         reg_new_temp(rd, dst->prev);
1204                                         reg_free_temp(rd, src->prev->prev);
1205                                         reg_new_temp(rd, dst->prev->prev);
1206                                         reg_free_temp(rd, src->prev->prev->prev);
1207                                         reg_new_temp(rd, dst->prev->prev->prev);
1208                                         reg_new_temp(rd, dst->prev->prev->prev->prev);
1209                                         reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
1210                                         break;
1211
1212                                         /* pop 2 push 2 swap */
1213                                         
1214                                 case ICMD_SWAP:
1215                                         reg_free_temp(rd, src);
1216                                         reg_new_temp(rd, dst->prev);
1217                                         reg_free_temp(rd, src->prev);
1218                                         reg_new_temp(rd, dst);
1219                                         break;
1220
1221                                         /* pop 2 push 1 */
1222                                         
1223                                 case ICMD_IADD:
1224                                 case ICMD_ISUB:
1225                                 case ICMD_IMUL:
1226                                 case ICMD_IDIV:
1227                                 case ICMD_IREM:
1228
1229                                 case ICMD_ISHL:
1230                                 case ICMD_ISHR:
1231                                 case ICMD_IUSHR:
1232                                 case ICMD_IAND:
1233                                 case ICMD_IOR:
1234                                 case ICMD_IXOR:
1235
1236                                 case ICMD_LADD:
1237                                 case ICMD_LSUB:
1238                                 case ICMD_LMUL:
1239                                 case ICMD_LDIV:
1240                                 case ICMD_LREM:
1241
1242                                 case ICMD_LOR:
1243                                 case ICMD_LAND:
1244                                 case ICMD_LXOR:
1245
1246                                 case ICMD_LSHL:
1247                                 case ICMD_LSHR:
1248                                 case ICMD_LUSHR:
1249
1250                                 case ICMD_FADD:
1251                                 case ICMD_FSUB:
1252                                 case ICMD_FMUL:
1253                                 case ICMD_FDIV:
1254                                 case ICMD_FREM:
1255
1256                                 case ICMD_DADD:
1257                                 case ICMD_DSUB:
1258                                 case ICMD_DMUL:
1259                                 case ICMD_DDIV:
1260                                 case ICMD_DREM:
1261
1262                                 case ICMD_LCMP:
1263                                 case ICMD_FCMPL:
1264                                 case ICMD_FCMPG:
1265                                 case ICMD_DCMPL:
1266                                 case ICMD_DCMPG:
1267                                         reg_free_temp(rd, src);
1268                                         reg_free_temp(rd, src->prev);
1269                                         reg_new_temp(rd, dst);
1270                                         break;
1271
1272                                         /* pop 1 push 1 */
1273                                         
1274                                 case ICMD_IADDCONST:
1275                                 case ICMD_ISUBCONST:
1276                                 case ICMD_IMULCONST:
1277                                 case ICMD_IMULPOW2:
1278                                 case ICMD_IDIVPOW2:
1279                                 case ICMD_IREMPOW2:
1280                                 case ICMD_IANDCONST:
1281                                 case ICMD_IORCONST:
1282                                 case ICMD_IXORCONST:
1283                                 case ICMD_ISHLCONST:
1284                                 case ICMD_ISHRCONST:
1285                                 case ICMD_IUSHRCONST:
1286
1287                                 case ICMD_LADDCONST:
1288                                 case ICMD_LSUBCONST:
1289                                 case ICMD_LMULCONST:
1290                                 case ICMD_LMULPOW2:
1291                                 case ICMD_LDIVPOW2:
1292                                 case ICMD_LREMPOW2:
1293                                 case ICMD_LANDCONST:
1294                                 case ICMD_LORCONST:
1295                                 case ICMD_LXORCONST:
1296                                 case ICMD_LSHLCONST:
1297                                 case ICMD_LSHRCONST:
1298                                 case ICMD_LUSHRCONST:
1299
1300                                 case ICMD_IFEQ_ICONST:
1301                                 case ICMD_IFNE_ICONST:
1302                                 case ICMD_IFLT_ICONST:
1303                                 case ICMD_IFGE_ICONST:
1304                                 case ICMD_IFGT_ICONST:
1305                                 case ICMD_IFLE_ICONST:
1306
1307                                 case ICMD_INEG:
1308                                 case ICMD_INT2BYTE:
1309                                 case ICMD_INT2CHAR:
1310                                 case ICMD_INT2SHORT:
1311                                 case ICMD_LNEG:
1312                                 case ICMD_FNEG:
1313                                 case ICMD_DNEG:
1314
1315                                 case ICMD_I2L:
1316                                 case ICMD_I2F:
1317                                 case ICMD_I2D:
1318                                 case ICMD_L2I:
1319                                 case ICMD_L2F:
1320                                 case ICMD_L2D:
1321                                 case ICMD_F2I:
1322                                 case ICMD_F2L:
1323                                 case ICMD_F2D:
1324                                 case ICMD_D2I:
1325                                 case ICMD_D2L:
1326                                 case ICMD_D2F:
1327
1328                                 case ICMD_CHECKCAST:
1329
1330                                 case ICMD_ARRAYLENGTH:
1331                                 case ICMD_INSTANCEOF:
1332
1333                                 case ICMD_NEWARRAY:
1334                                 case ICMD_ANEWARRAY:
1335
1336                                 case ICMD_GETFIELD:
1337                                         reg_free_temp(rd, src);
1338                                         reg_new_temp(rd, dst);
1339                                         break;
1340
1341                                         /* pop 0 push 1 */
1342                                         
1343                                 case ICMD_GETSTATIC:
1344
1345                                 case ICMD_NEW:
1346                                         reg_new_temp(rd, dst);
1347                                         break;
1348
1349                                         /* pop many push any */
1350                                         
1351                                 case ICMD_INVOKESTATIC:
1352                                 case ICMD_INVOKESPECIAL:
1353                                 case ICMD_INVOKEVIRTUAL:
1354                                 case ICMD_INVOKEINTERFACE:
1355                                         lm = iptr->val.a;
1356
1357                                         if (lm)
1358                                                 md = lm->parseddesc;
1359                                         else {
1360                                                 unresolved_method *um = iptr->target;
1361                                                 md = um->methodref->parseddesc.md;
1362                                         }
1363                                         i = md->paramcount;
1364                                         while (--i >= 0) {
1365                                                 reg_free_temp(rd, src);
1366                                                 src = src->prev;
1367                                         }
1368                                         if (md->returntype.type != TYPE_VOID)
1369                                                 reg_new_temp(rd, dst);
1370                                         break;
1371
1372                                 case ICMD_BUILTIN:
1373                                         bte = iptr->val.a;
1374                                         md = bte->md;
1375                                         i = md->paramcount;
1376                                         while (--i >= 0) {
1377                                                 reg_free_temp(rd, src);
1378                                                 src = src->prev;
1379                                         }
1380                                         if (md->returntype.type != TYPE_VOID)
1381                                                 reg_new_temp(rd, dst);
1382                                         break;
1383
1384                                 case ICMD_MULTIANEWARRAY:
1385                                         i = iptr->op1;
1386                                         while (--i >= 0) {
1387                                                 reg_free_temp(rd, src);
1388                                                 src = src->prev;
1389                                         }
1390                                         reg_new_temp(rd, dst);
1391                                         break;
1392
1393                                 default:
1394                                         throw_cacao_exception_exit(string_java_lang_InternalError,
1395                                                                                            "Unknown ICMD %d during register allocation",
1396                                                                                            iptr->opc);
1397                                 } /* switch */
1398                                 iptr++;
1399                         } /* while instructions */
1400                 } /* if */
1401                 bptr = bptr->next;
1402         } /* while blocks */
1403 }
1404
1405
1406 #if defined(ENABLE_STATISTICS)
1407 void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
1408         int i,type;
1409         s4 len;
1410         stackptr    src, src_old;
1411         stackptr    dst;
1412         instruction *iptr;
1413         basicblock  *bptr;
1414         int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1415         bool in_register;
1416
1417         in_register = true;
1418
1419         size_interface = 0;
1420
1421                 /* count how many local variables are held in memory or register */
1422                 for(i=0; i < cd->maxlocals; i++)
1423                         for (type=0; type <=4; type++)
1424                                 if (rd->locals[i][type].type != -1) { /* valid local */
1425                                         if (rd->locals[i][type].flags & INMEMORY) {
1426                                                 count_locals_spilled++;
1427                                                 in_register=false;
1428                                         }
1429                                         else
1430                                                 count_locals_register++;
1431                                 }
1432                 /* count how many stack slots are held in memory or register */
1433
1434                 bptr = m->basicblocks;
1435                 while (bptr != NULL) {
1436                         if (bptr->flags >= BBREACHED) {
1437
1438 #if defined(ENABLE_LSRA)
1439                         if (!opt_lsra) {
1440 #endif  
1441                                 /* check for memory moves from interface to BB instack */
1442                                 dst = bptr->instack;
1443                                 len = bptr->indepth;
1444                                 
1445                                 if (len > size_interface) size_interface = len;
1446
1447                                 while (dst != NULL) {
1448                                         len--;
1449                                         if (dst->varkind != STACKVAR) {
1450                                                 if ( (dst->flags & INMEMORY) ||
1451                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || 
1452                                                          ( (dst->flags & INMEMORY) && 
1453                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && 
1454                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1455                                                 {
1456                                                         /* one in memory or both inmemory at different offsets */
1457                                                         count_mem_move_bb++;
1458                                                         in_register=false;
1459                                                 }
1460                                         }
1461
1462                                         dst = dst->prev;
1463                                 }
1464
1465                                 /* check for memory moves from BB outstack to interface */
1466                                 dst = bptr->outstack;
1467                                 len = bptr->outdepth;
1468                                 if (len > size_interface) size_interface = len;
1469
1470                                 while (dst) {
1471                                         len--;
1472                                         if (dst->varkind != STACKVAR) {
1473                                                 if ( (dst->flags & INMEMORY) || \
1474                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1475                                                          ( (dst->flags & INMEMORY) && \
1476                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1477                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1478                                                 {
1479                                                         /* one in memory or both inmemory at different offsets */
1480                                                         count_mem_move_bb++;
1481                                                         in_register=false;
1482                                                 }
1483                                         }
1484
1485                                         dst = dst->prev;
1486                                 }
1487 #if defined(ENABLE_LSRA)
1488                         }
1489 #endif  
1490
1491
1492                                 dst = bptr->instack;
1493                                 iptr = bptr->iinstr;
1494                                 len = bptr->icount;
1495                                 src_old = NULL;
1496
1497                                 while (--len >= 0)  {
1498                                         src = dst;
1499                                         dst = iptr->dst;
1500
1501                                         if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1502                                                 switch (src->varkind) {
1503                                                 case TEMPVAR:
1504                                                 case STACKVAR:
1505                                                         if (!(src->flags & INMEMORY)) 
1506                                                                 count_ss_register++;
1507                                                         else {
1508                                                                 count_ss_spilled++;
1509                                                                 in_register=false;
1510                                                         }                               
1511                                                         break;
1512                                                         /*                                      case LOCALVAR: */
1513                                                         /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1514                                                         /*                                                      count_ss_register++; */
1515                                                         /*                                              else */
1516                                                         /*                                                      count_ss_spilled++; */
1517                                                         /*                                              break; */
1518                                                 case ARGVAR:
1519                                                         if (!(src->flags & INMEMORY)) 
1520                                                                 count_argument_mem_ss++;
1521                                                         else
1522                                                                 count_argument_reg_ss++;
1523                                                         break;
1524
1525
1526                                                         /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
1527                                                         /*                                                      if (src->varnum < FLT_ARG_CNT) { */
1528                                                         /*                                                              count_ss_register++; */
1529                                                         /*                                                              break; */
1530                                                         /*                                                      } */
1531                                                         /*                                              } else { */
1532                                                         /* #if defined(__POWERPC__) */
1533                                                         /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1534                                                         /* #else */
1535                                                         /*                                                      if (src->varnum < INT_ARG_CNT) { */
1536                                                         /* #endif */
1537                                                         /*                                                              count_ss_register++; */
1538                                                         /*                                                              break; */
1539                                                         /*                                                      } */
1540                                                         /*                                              } */
1541                                                         /*                                              count_ss_spilled++; */
1542                                                         /*                                              break; */
1543                                                 }
1544                                         }
1545                                         src_old = src;
1546                                         
1547                                         iptr++;
1548                                 } /* while instructions */
1549                         } /* if */
1550                         bptr = bptr->next;
1551                 } /* while blocks */
1552                 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1553                 if (in_register) count_method_in_register++;
1554 }
1555 #endif /* defined(ENABLE_STATISTICS) */
1556
1557
1558 /*
1559  * These are local overrides for various environment variables in Emacs.
1560  * Please do not remove this and leave it at the end of the file, where
1561  * Emacs will automagically detect them.
1562  * ---------------------------------------------------------------------
1563  * Local variables:
1564  * mode: c
1565  * indent-tabs-mode: t
1566  * c-basic-offset: 4
1567  * tab-width: 4
1568  * End:
1569  */