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