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