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