* src/vm/jit/allocator/simplereg.c (new_allocate_scratch_registers):
[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 5131 2006-07-14 16:54:11Z 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
59 /* function prototypes for this file ******************************************/
60
61 static void interface_regalloc(jitdata *jd);
62 static void local_regalloc(jitdata *jd);
63 static void new_allocate_scratch_registers(jitdata *jd);
64 static void allocate_scratch_registers(jitdata *jd);
65
66
67 /* regalloc ********************************************************************
68
69    Does a simple register allocation.
70         
71 *******************************************************************************/
72         
73 bool new_regalloc(jitdata *jd)
74 {
75         jitdata *newjd;
76
77         /* There is a problem with the use of unused float argument
78            registers in leafmethods for stackslots on c7 (2 * Dual Core
79            AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
80            benchmark is heaviliy increased. This could be prevented by
81            setting rd->argfltreguse to FLT_ARG_CNT before calling
82            allocate_scratch_registers and setting it back to the original
83            value before calling local_regalloc.  */
84
85         newjd = DNEW(jitdata);
86         *newjd = *jd;
87         newjd->rd = jd->new_rd;
88
89         interface_regalloc(newjd);
90         new_allocate_scratch_registers(newjd);
91         local_regalloc(newjd);
92
93         /* everthing's ok */
94
95         return true;
96 }
97
98 bool regalloc(jitdata *jd)
99 {
100         /* There is a problem with the use of unused float argument
101            registers in leafmethods for stackslots on c7 (2 * Dual Core
102            AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
103            benchmark is heaviliy increased. This could be prevented by
104            setting rd->argfltreguse to FLT_ARG_CNT before calling
105            allocate_scratch_registers and setting it back to the original
106            value before calling local_regalloc.  */
107
108         interface_regalloc(jd);
109         allocate_scratch_registers(jd);
110         local_regalloc(jd);
111
112         /* everthing's ok */
113
114         return true;
115 }
116
117
118 /* interface_regalloc **********************************************************
119
120    Allocates registers for all interface variables.
121         
122 *******************************************************************************/
123         
124 static void interface_regalloc(jitdata *jd)
125 {
126         methodinfo   *m;
127         codegendata  *cd;
128         registerdata *rd;
129
130         int     s, t, tt, saved;
131         int     intalloc, fltalloc; /* Remember allocated Register/Memory offset */
132                       /* in case a more vars are packed into this interface slot */
133         varinfo *v;
134         int             intregsneeded = 0;
135         int             memneeded = 0;
136     /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
137         /* on HAS_4BYTE_STACKSLOT architectures */
138         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
139
140         /* get required compiler data */
141
142         m  = jd->m;
143         cd = jd->cd;
144         rd = jd->rd;
145
146         /* rd->memuse was already set in stack.c to allocate stack space
147            for passing arguments to called methods. */
148
149 #if defined(__I386__)
150         if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
151                 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
152                 if (rd->memuse < 1)
153                         rd->memuse = 1;
154         }
155 #endif
156
157         if (jd->isleafmethod) {
158                 /* Reserve argument register, which will be used for Locals acting */
159                 /* as Parameters */
160                 if (rd->argintreguse < m->parseddesc->argintreguse)
161                         rd->argintreguse = m->parseddesc->argintreguse;
162                 if (rd->argfltreguse < m->parseddesc->argfltreguse)
163                         rd->argfltreguse = m->parseddesc->argfltreguse;
164 #ifdef HAS_ADDRESS_REGISTER_FILE
165                 if (rd->argadrreguse < m->parseddesc->argadrreguse)
166                         rd->argadrreguse = m->parseddesc->argadrreguse;
167 #endif
168
169         }
170
171         for (s = 0; s < cd->maxstack; s++) {
172                 intalloc = -1; fltalloc = -1;
173                 saved = (rd->interfaces[s][TYPE_INT].flags |
174                                  rd->interfaces[s][TYPE_LNG].flags |
175                          rd->interfaces[s][TYPE_FLT].flags |
176                                  rd->interfaces[s][TYPE_DBL].flags |
177                          rd->interfaces[s][TYPE_ADR].flags) & SAVEDVAR;
178  
179                 for (tt = 0; tt <= 4; tt++) {
180                         t = typeloop[tt];
181                         v = &rd->interfaces[s][t];
182                         if (v->type >= 0) {
183 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
184                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
185 #endif
186 #if defined(HAS_4BYTE_STACKSLOT)
187                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
188 #endif
189                                 if (!saved) {
190 #if defined(HAS_ADDRESS_REGISTER_FILE)
191                                         if (IS_ADR_TYPE(t)) {
192                                                 if (!jd->isleafmethod 
193                                                         &&(rd->argadrreguse < ADR_ARG_CNT)) {
194                                                         v->regoff = rd->argadrregs[rd->argadrreguse++];
195                                                 } else if (rd->tmpadrreguse > 0) {
196                                                                 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
197                                                 } else if (rd->savadrreguse > 0) {
198                                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
199                                                 } else {
200                                                         v->flags |= INMEMORY;
201                                                         v->regoff = rd->memuse++;
202                                                 }                                               
203                                         } else /* !IS_ADR_TYPE */
204 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
205                                         {
206                                                 if (IS_FLT_DBL_TYPE(t)) {
207                                                         if (fltalloc >= 0) {
208                        /* Reuse memory slot(s)/register(s) for shared interface slots */
209                                                                 v->flags |= rd->interfaces[s][fltalloc].flags
210                                                                         & INMEMORY;
211                                                                 v->regoff = rd->interfaces[s][fltalloc].regoff;
212                                                         } else if (rd->argfltreguse < FLT_ARG_CNT) {
213                                                                 v->regoff = rd->argfltregs[rd->argfltreguse++];
214                                                         } else if (rd->tmpfltreguse > 0) {
215                                                                 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
216                                                         } else if (rd->savfltreguse > 0) {
217                                                                 v->regoff = rd->savfltregs[--rd->savfltreguse];
218                                                         } else {
219                                                                 v->flags |= INMEMORY;
220 #if defined(ALIGN_DOUBLES_IN_MEMORY)
221                                                                 /* Align doubles in Memory */
222                                                                 if ( (memneeded) && (rd->memuse & 1))
223                                                                         rd->memuse++;
224 #endif
225                                                                 v->regoff = rd->memuse;
226                                                                 rd->memuse += memneeded + 1;
227                                                         }
228                                                         fltalloc = t;
229                                                 } else { /* !IS_FLT_DBL_TYPE(t) */
230 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
231                                                         /*
232                                                          * for i386 put all longs in memory
233                                                          */
234                                                         if (IS_2_WORD_TYPE(t)) {
235                                                                 v->flags |= INMEMORY;
236 #if defined(ALIGN_LONGS_IN_MEMORY)
237                                                                 /* Align longs in Memory */
238                                                                 if (rd->memuse & 1)
239                                                                         rd->memuse++;
240 #endif
241                                                                 v->regoff = rd->memuse;
242                                                                 rd->memuse += memneeded + 1;
243                                                         } else
244 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
245                                                                 if (intalloc >= 0) {
246                        /* Reuse memory slot(s)/register(s) for shared interface slots */
247                                                                         v->flags |= 
248                                                                                 rd->interfaces[s][intalloc].flags 
249                                                                                 & INMEMORY;
250 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
251                                                                         if (!(v->flags & INMEMORY) 
252                                                                                 && IS_2_WORD_TYPE(intalloc))
253                                                                                 v->regoff = GET_LOW_REG(
254                                                                                         rd->interfaces[s][intalloc].regoff);
255                                                                         else
256 #endif
257                                                                                 v->regoff = 
258                                                                                     rd->interfaces[s][intalloc].regoff;
259                                                                 } else 
260                                                                         if (rd->argintreguse + intregsneeded 
261                                                                                 < INT_ARG_CNT) {
262 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
263                                                                                 if (intregsneeded) 
264                                                                                         v->regoff=PACK_REGS( 
265                                                                                   rd->argintregs[rd->argintreguse],
266                                                                                   rd->argintregs[rd->argintreguse + 1]);
267                                                                                 else
268 #endif
269                                                                                         v->regoff = 
270                                                                                            rd->argintregs[rd->argintreguse];
271                                                                                 rd->argintreguse += intregsneeded + 1;
272                                                                         }
273                                                                         else if (rd->tmpintreguse > intregsneeded) {
274                                                                                 rd->tmpintreguse -= intregsneeded + 1;
275 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
276                                                                                 if (intregsneeded) 
277                                                                                         v->regoff=PACK_REGS( 
278                                                                                   rd->tmpintregs[rd->tmpintreguse],
279                                                                                   rd->tmpintregs[rd->tmpintreguse + 1]);
280                                                                                 else
281 #endif
282                                                                                         v->regoff = 
283                                                                                            rd->tmpintregs[rd->tmpintreguse];
284                                                                         }
285                                                                         else if (rd->savintreguse > intregsneeded) {
286                                                                                 rd->savintreguse -= intregsneeded + 1;
287                                                                                 v->regoff = 
288                                                                                         rd->savintregs[rd->savintreguse];
289 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
290                                                                                 if (intregsneeded) 
291                                                                                         v->regoff=PACK_REGS( 
292                                                                                   rd->savintregs[rd->savintreguse],
293                                                                                   rd->savintregs[rd->savintreguse + 1]);
294                                                                                 else
295 #endif
296                                                                                         v->regoff = 
297                                                                                            rd->savintregs[rd->savintreguse];
298                                                                         }
299                                                                         else {
300                                                                                 v->flags |= INMEMORY;
301 #if defined(ALIGN_LONGS_IN_MEMORY)
302                                                                                 /* Align longs in Memory */
303                                                                                 if ( (memneeded) && (rd->memuse & 1))
304                                                                                         rd->memuse++;
305 #endif
306                                                                                 v->regoff = rd->memuse;
307                                                                                 rd->memuse += memneeded + 1;
308                                                                         }
309
310                                                         intalloc = t;
311                                                 } /* if (IS_FLT_DBL_TYPE(t)) */
312                                         } 
313                                 } else { /* (saved) */
314 /* now the same like above, but without a chance to take a temporary register */
315 #ifdef HAS_ADDRESS_REGISTER_FILE
316                                         if (IS_ADR_TYPE(t)) {
317                                                 if (rd->savadrreguse > 0) {
318                                                         v->regoff = rd->savadrregs[--rd->savadrreguse];
319                                                 }
320                                                 else {
321                                                         v->flags |= INMEMORY;
322                                                         v->regoff = rd->memuse++;
323                                                 }                                               
324                                         } else
325 #endif
326                                         {
327                                                 if (IS_FLT_DBL_TYPE(t)) {
328                                                         if (fltalloc >= 0) {
329                                                                 v->flags |= rd->interfaces[s][fltalloc].flags
330                                                                         & INMEMORY;
331                                                                 v->regoff = rd->interfaces[s][fltalloc].regoff;
332                                                         } else
333                                                                 if (rd->savfltreguse > 0) {
334                                                                         v->regoff = rd->savfltregs[--rd->savfltreguse];
335                                                                 }
336                                                                 else {
337                                                                         v->flags |= INMEMORY;
338 #if defined(ALIGN_DOUBLES_IN_MEMORY)
339                                                                         /* Align doubles in Memory */
340                                                                         if ( (memneeded) && (rd->memuse & 1))
341                                                                                 rd->memuse++;
342 #endif
343                                                                         v->regoff = rd->memuse;
344                                                                         rd->memuse += memneeded + 1;
345                                                                 }
346                                                         fltalloc = t;
347                                                 }
348                                                 else { /* IS_INT_LNG */
349 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
350                                                         /*
351                                                          * for i386 put all longs in memory
352                                                          */
353                                                         if (IS_2_WORD_TYPE(t)) {
354                                                                 v->flags |= INMEMORY;
355 #if defined(ALIGN_LONGS_IN_MEMORY)
356                                                                 /* Align longs in Memory */
357                                                                 if (rd->memuse & 1)
358                                                                         rd->memuse++;
359 #endif
360                                                                 v->regoff = rd->memuse;
361                                                                 rd->memuse += memneeded + 1;
362                                                         } else
363 #endif
364                                                         {
365                                                                 if (intalloc >= 0) {
366                                                                         v->flags |= 
367                                                                    rd->interfaces[s][intalloc].flags & INMEMORY;
368 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
369                                                                         if (!(v->flags & INMEMORY)
370                                                                                 && IS_2_WORD_TYPE(intalloc))
371                                                                                 v->regoff =
372                                                                                         GET_LOW_REG(
373                                                                                         rd->interfaces[s][intalloc].regoff);
374                                                                         else
375 #endif
376                                                                                 v->regoff =
377                                                                                         rd->interfaces[s][intalloc].regoff;
378                                                                 } else {
379                                                                         if (rd->savintreguse > intregsneeded) {
380                                                                                 rd->savintreguse -= intregsneeded + 1;
381 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
382                                                                                 if (intregsneeded) 
383                                                                                         v->regoff = PACK_REGS( 
384                                                                                   rd->savintregs[rd->savintreguse],
385                                                                                   rd->savintregs[rd->savintreguse + 1]);
386                                                                                 else
387 #endif
388                                                                                         v->regoff =
389                                                                                            rd->savintregs[rd->savintreguse];
390                                                                         } else {
391                                                                                 v->flags |= INMEMORY;
392 #if defined(ALIGN_LONGS_IN_MEMORY)
393                                                                         /* Align longs in Memory */
394                                                                         if ( (memneeded) && (rd->memuse & 1))
395                                                                                 rd->memuse++;
396 #endif
397                                                                                 v->regoff = rd->memuse;
398                                                                                 rd->memuse += memneeded + 1;
399                                                                         }
400                                                                 }
401                                                                 intalloc = t;
402                                                         }
403                                                 } /* if (IS_FLT_DBL_TYPE(t) else */
404                                         } /* if (IS_ADR_TYPE(t)) else */
405                                 } /* if (saved) else */
406                         } /* if (type >= 0) */
407                 } /* for t */
408         } /* for s */
409 }
410
411
412 /* local_regalloc **************************************************************
413
414    Allocates registers for all local variables.
415         
416 *******************************************************************************/
417         
418 static void local_regalloc(jitdata *jd)
419 {
420         methodinfo   *m;
421         codegendata  *cd;
422         registerdata *rd;
423
424         int     p, s, t, tt;
425         int     intalloc, fltalloc;
426         varinfo *v;
427         int     intregsneeded = 0;
428         int     memneeded = 0;
429         int     typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
430         int     fargcnt, iargcnt;
431 #ifdef HAS_ADDRESS_REGISTER_FILE
432         int     aargcnt;
433 #endif
434
435         /* get required compiler data */
436
437         m  = jd->m;
438         cd = jd->cd;
439         rd = jd->rd;
440
441         if (jd->isleafmethod) {
442                 methoddesc *md = m->parseddesc;
443
444                 iargcnt = rd->argintreguse;
445                 fargcnt = rd->argfltreguse;
446 #ifdef HAS_ADDRESS_REGISTER_FILE
447                 aargcnt = rd->argadrreguse;
448 #endif
449                 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
450                         intalloc = -1; fltalloc = -1;
451                         for (tt = 0; tt <= 4; tt++) {
452                                 t = typeloop[tt];
453                                 v = &rd->locals[s][t];
454
455                                 if (v->type < 0)
456                                         continue;
457
458 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
459                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
460 #endif
461 #if defined(HAS_4BYTE_STACKSLOT)
462                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
463 #endif
464
465                                 /*
466                                  *  The order of
467                                  *
468                                  *  #ifdef HAS_ADDRESS_REGISTER_FILE
469                                  *  if (IS_ADR_TYPE) { 
470                                  *  ...
471                                  *  } else 
472                                  *  #endif
473                                  *  if (IS_FLT_DBL) {
474                                  *  ...
475                                  *  } else { / int & lng
476                                  *  ...
477                                  *  }
478                                  *
479                                  *  must not to be changed!
480                                  */
481
482 #ifdef HAS_ADDRESS_REGISTER_FILE
483                                 if (IS_ADR_TYPE(t)) {
484                                         if ((p < md->paramcount) && !md->params[p].inmemory) {
485                                                 v->flags = 0;
486                                                 v->regoff = rd->argadrregs[md->params[p].regoff];
487                                         }
488                                         else if (rd->tmpadrreguse > 0) {
489                                                 v->flags = 0;
490                                                 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
491                                         }
492                                         /* use unused argument registers as local registers */
493                                         else if ((p >= md->paramcount) &&
494                                                          (aargcnt < ADR_ARG_CNT)) {
495                                                 v->flags = 0;
496                                                 v->regoff = rd->argadrregs[aargcnt++];
497                                         }
498                                         else if (rd->savadrreguse > 0) {
499                                                 v->flags = 0;
500                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
501                                         }
502                                         else {
503                                                 v->flags |= INMEMORY;
504                                                 v->regoff = rd->memuse++;
505                                         }                                               
506                                 } else {
507 #endif
508                                         if (IS_FLT_DBL_TYPE(t)) {
509                                                 if (fltalloc >= 0) {
510                                                         v->flags = rd->locals[s][fltalloc].flags;
511                                                         v->regoff = rd->locals[s][fltalloc].regoff;
512                                                 }
513 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
514                                                 /* We can only use float arguments as local variables,
515                                                  * if we do not pass them in integer registers. */
516                                                 else if ((p < md->paramcount) &&
517                                                                  !md->params[p].inmemory) {
518                                                         v->flags = 0;
519                                                         v->regoff = rd->argfltregs[md->params[p].regoff];
520                                                 }
521 #endif
522                                                 else if (rd->tmpfltreguse > 0) {
523                                                         v->flags = 0;
524                                                         v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
525                                                 }
526                                                 /* use unused argument registers as local registers */
527                                                 else if ((p >= md->paramcount) &&
528                                                                  (fargcnt < FLT_ARG_CNT)) {
529                                                         v->flags = 0;
530                                                         v->regoff = rd->argfltregs[fargcnt];
531                                                         fargcnt++;
532                                                 }
533                                                 else if (rd->savfltreguse > 0) {
534                                                         v->flags = 0;
535                                                         v->regoff = rd->savfltregs[--rd->savfltreguse];
536                                                 }
537                                                 else {
538                                                         v->flags = INMEMORY;
539 #if defined(ALIGN_DOUBLES_IN_MEMORY)
540                                                         /* Align doubles in Memory */
541                                                         if ( (memneeded) && (rd->memuse & 1))
542                                                                 rd->memuse++;
543 #endif
544                                                         v->regoff = rd->memuse;
545                                                         rd->memuse += memneeded + 1;
546                                                 }
547                                                 fltalloc = t;
548
549                                         } else {
550 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
551                                                 /*
552                                                  * for i386 put all longs in memory
553                                                  */
554                                                 if (IS_2_WORD_TYPE(t)) {
555                                                         v->flags = INMEMORY;
556 #if defined(ALIGN_LONGS_IN_MEMORY)
557                                                         /* Align longs in Memory */
558                                                         if (rd->memuse & 1)
559                                                                 rd->memuse++;
560 #endif
561                                                         v->regoff = rd->memuse;
562                                                         rd->memuse += memneeded + 1;
563                                                 } else 
564 #endif
565                                                 {
566                                                         if (intalloc >= 0) {
567                                                                 v->flags = rd->locals[s][intalloc].flags;
568 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
569                                                                 if (!(v->flags & INMEMORY)
570                                                                         && IS_2_WORD_TYPE(intalloc))
571                                                                         v->regoff = GET_LOW_REG(
572                                                                                     rd->locals[s][intalloc].regoff);
573                                                                 else
574 #endif
575                                                                         v->regoff = rd->locals[s][intalloc].regoff;
576                                                         }
577                                                         else if ((p < md->paramcount) && 
578                                                                          !md->params[p].inmemory) {
579                                                                 v->flags = 0;
580 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
581                                                                 if (IS_2_WORD_TYPE(t))
582                                                                         v->regoff = PACK_REGS(
583                                                         rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
584                                                         rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
585                                                                         else
586 #endif
587                                                                                 v->regoff =
588                                                                                rd->argintregs[md->params[p].regoff];
589                                                         }
590                                                         else if (rd->tmpintreguse > intregsneeded) {
591                                                                 rd->tmpintreguse -= intregsneeded + 1;
592                                                                 v->flags = 0;
593 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
594                                                                 if (intregsneeded) 
595                                                                         v->regoff = PACK_REGS(
596                                                                             rd->tmpintregs[rd->tmpintreguse],
597                                                                                 rd->tmpintregs[rd->tmpintreguse + 1]);
598                                                                 else
599 #endif
600                                                                         v->regoff = 
601                                                                                 rd->tmpintregs[rd->tmpintreguse];
602                                                         }
603                                                         /*
604                                                          * use unused argument registers as local registers
605                                                          */
606                                                         else if ((p >= m->parseddesc->paramcount) &&
607                                                                          (iargcnt + intregsneeded < INT_ARG_CNT)) {
608                                                                 v->flags = 0;
609 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
610                                                                 if (intregsneeded) 
611                                                                         v->regoff=PACK_REGS( 
612                                                                                                    rd->argintregs[iargcnt],
613                                                                                                    rd->argintregs[iargcnt + 1]);
614                                                                 else
615 #endif
616                                                                         v->regoff = rd->argintregs[iargcnt];
617                                                                 iargcnt += intregsneeded + 1;
618                                                         }
619                                                         else if (rd->savintreguse > intregsneeded) {
620                                                                 rd->savintreguse -= intregsneeded + 1;
621                                                                 v->flags = 0;
622 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
623                                                                 if (intregsneeded) 
624                                                                         v->regoff = PACK_REGS(
625                                                                             rd->savintregs[rd->savintreguse],
626                                                                                 rd->savintregs[rd->savintreguse + 1]);
627                                                                 else
628 #endif
629                                                                         v->regoff =rd->savintregs[rd->savintreguse];
630                                                         }
631                                                         else {
632                                                                 v->flags = INMEMORY;
633 #if defined(ALIGN_LONGS_IN_MEMORY)
634                                                                 /* Align longs in Memory */
635                                                                 if ( (memneeded) && (rd->memuse & 1))
636                                                                         rd->memuse++;
637 #endif
638                                                                 v->regoff = rd->memuse;
639                                                                 rd->memuse += memneeded + 1;
640                                                         }
641                                                 }
642                                                 intalloc = t;
643                                         }
644 #ifdef HAS_ADDRESS_REGISTER_FILE
645                                 }
646 #endif
647                         } /* for (tt=0;...) */
648
649                         /* If the current parameter is a 2-word type, the next local slot */
650                         /* is skipped.                                                    */
651
652                         if (p < md->paramcount)
653                                 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
654                                         s++;
655                 }
656                 return;
657         }
658
659         for (s = 0; s < cd->maxlocals; s++) {
660                 intalloc = -1; fltalloc = -1;
661                 for (tt=0; tt<=4; tt++) {
662                         t = typeloop[tt];
663                         v = &rd->locals[s][t];
664
665                         if (v->type >= 0) {
666 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
667                                 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
668 #endif
669 #if defined(HAS_4BYTE_STACKSLOT)
670                                 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
671 #endif
672 #ifdef HAS_ADDRESS_REGISTER_FILE
673                                 if ( IS_ADR_TYPE(t) ) {
674                                         if (rd->savadrreguse > 0) {
675                                                 v->flags = 0;
676                                                 v->regoff = rd->savadrregs[--rd->savadrreguse];
677                                         }
678                                         else {
679                                                 v->flags = INMEMORY;
680                                                 v->regoff = rd->memuse++;
681                                         }
682                                 } else {
683 #endif
684                                 if (IS_FLT_DBL_TYPE(t)) {
685                                         if (fltalloc >= 0) {
686                                                 v->flags = rd->locals[s][fltalloc].flags;
687                                                 v->regoff = rd->locals[s][fltalloc].regoff;
688                                         }
689                                         else if (rd->savfltreguse > 0) {
690                                                 v->flags = 0;
691                                                 v->regoff = rd->savfltregs[--rd->savfltreguse];
692                                         }
693                                         else {
694                                                 v->flags = INMEMORY;
695 #if defined(ALIGN_DOUBLES_IN_MEMORY)
696                                                 /* Align doubles in Memory */
697                                                 if ( (memneeded) && (rd->memuse & 1))
698                                                         rd->memuse++;
699 #endif
700                                                 v->regoff = rd->memuse;
701                                                 rd->memuse += memneeded + 1;
702                                         }
703                                         fltalloc = t;
704                                 }
705                                 else {
706 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
707                                         /*
708                                          * for i386 put all longs in memory
709                                          */
710                                         if (IS_2_WORD_TYPE(t)) {
711                                                 v->flags = INMEMORY;
712 #if defined(ALIGN_LONGS_IN_MEMORY)
713                                                 /* Align longs in Memory */
714                                                 if (rd->memuse & 1)
715                                                         rd->memuse++;
716 #endif
717                                                 v->regoff = rd->memuse;
718                                                 rd->memuse += memneeded + 1;
719                                         } else {
720 #endif
721                                                 if (intalloc >= 0) {
722                                                         v->flags = rd->locals[s][intalloc].flags;
723 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
724                                                         if (!(v->flags & INMEMORY)
725                                                                 && IS_2_WORD_TYPE(intalloc))
726                                                                 v->regoff = GET_LOW_REG(
727                                                                             rd->locals[s][intalloc].regoff);
728                                                         else
729 #endif
730                                                                 v->regoff = rd->locals[s][intalloc].regoff;
731                                                 }
732                                                 else if (rd->savintreguse > intregsneeded) {
733                                                         rd->savintreguse -= intregsneeded+1;
734                                                         v->flags = 0;
735 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
736                                                                 if (intregsneeded) 
737                                                                         v->regoff = PACK_REGS(
738                                                                                 rd->savintregs[rd->savintreguse],
739                                                                             rd->savintregs[rd->savintreguse + 1]);
740                                                                 else
741 #endif
742                                                                         v->regoff =rd->savintregs[rd->savintreguse];
743                                                 }
744                                                 else {
745                                                         v->flags = INMEMORY;
746 #if defined(ALIGN_LONGS_IN_MEMORY)
747                                                         /* Align longs in Memory */
748                                                         if ( (memneeded) && (rd->memuse & 1))
749                                                                 rd->memuse++;
750 #endif
751                                                         v->regoff = rd->memuse;
752                                                         rd->memuse += memneeded + 1;
753                                                 }
754 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
755                                         }
756 #endif
757                                         intalloc = t;
758                                 }
759 #ifdef HAS_ADDRESS_REGISTER_FILE
760                                 }
761 #endif
762
763                         }
764                 }
765         }
766 }
767
768 static void reg_init_temp(methodinfo *m, registerdata *rd)
769 {
770         rd->freememtop = 0;
771 #if defined(HAS_4BYTE_STACKSLOT)
772         rd->freememtop_2 = 0;
773 #endif
774
775         rd->freetmpinttop = 0;
776         rd->freesavinttop = 0;
777         rd->freetmpflttop = 0;
778         rd->freesavflttop = 0;
779 #ifdef HAS_ADDRESS_REGISTER_FILE
780         rd->freetmpadrtop = 0;
781         rd->freesavadrtop = 0;
782 #endif
783
784         rd->freearginttop = 0;
785         rd->freeargflttop = 0;
786 #ifdef HAS_ADDRESS_REGISTER_FILE
787         rd->freeargadrtop = 0;
788 #endif
789 }
790
791
792 #define reg_new_temp(rd,s) if (s->varkind == TEMPVAR) reg_new_temp_func(rd, s)
793
794 static void reg_new_temp_func(registerdata *rd, stackptr s)
795 {
796         s4 intregsneeded;
797         s4 memneeded;
798         s4 tryagain;
799
800         /* Try to allocate a saved register if there is no temporary one          */
801         /* available. This is what happens during the second run.                 */
802         tryagain = (s->flags & SAVEDVAR) ? 1 : 2;
803
804 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
805         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
806 #else
807         intregsneeded = 0;
808 #endif
809 #if defined(HAS_4BYTE_STACKSLOT)
810         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
811 #else
812         memneeded = 0;
813 #endif
814
815         for(; tryagain; --tryagain) {
816                 if (tryagain == 1) {
817                         if (!(s->flags & SAVEDVAR))
818                                 s->flags |= SAVEDTMP;
819 #ifdef HAS_ADDRESS_REGISTER_FILE
820                         if (IS_ADR_TYPE(s->type)) {
821                                 if (rd->freesavadrtop > 0) {
822                                         s->regoff = rd->freesavadrregs[--rd->freesavadrtop];
823                                         return;
824                                 } else if (rd->savadrreguse > 0) {
825                                         s->regoff = rd->savadrregs[--rd->savadrreguse];
826                                         return;
827                                 }
828                         } else
829 #endif
830                         {
831                                 if (IS_FLT_DBL_TYPE(s->type)) {
832                                         if (rd->freesavflttop > 0) {
833                                                 s->regoff = rd->freesavfltregs[--rd->freesavflttop];
834                                                 return;
835                                         } else if (rd->savfltreguse > 0) {
836                                                 s->regoff = rd->savfltregs[--rd->savfltreguse];
837                                                 return;
838                                         }
839                                 } else {
840 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
841                                         /*
842                                          * for i386 put all longs in memory
843                                          */
844                                         if (!IS_2_WORD_TYPE(s->type))
845 #endif
846                                         {
847                                                 if (rd->freesavinttop > intregsneeded) {
848                                                         rd->freesavinttop -= intregsneeded + 1;
849 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
850                                                         if (intregsneeded)
851                                                                 s->regoff = PACK_REGS(
852                                                                 rd->freesavintregs[rd->freesavinttop],
853                                                                         rd->freesavintregs[rd->freesavinttop + 1]);
854                                                 else
855 #endif
856                                                                 s->regoff =
857                                                                         rd->freesavintregs[rd->freesavinttop];
858                                                         return;
859                                                 } else if (rd->savintreguse > intregsneeded) {
860                                                         rd->savintreguse -= intregsneeded + 1;
861 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
862                                                         if (intregsneeded)
863                                                                 s->regoff = PACK_REGS(
864                                                                         rd->savintregs[rd->savintreguse],
865                                                                 rd->savintregs[rd->savintreguse + 1]);
866                                                         else
867 #endif
868                                                                 s->regoff = rd->savintregs[rd->savintreguse];
869                                                         return;
870                                                 }
871                                         }
872                                 }
873                         }
874                 } else { /* tryagain == 2 */
875 #ifdef HAS_ADDRESS_REGISTER_FILE
876                         if (IS_ADR_TYPE(s->type)) {
877                                 if (rd->freetmpadrtop > 0) {
878                                         s->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
879                                         return;
880                                 } else if (rd->tmpadrreguse > 0) {
881                                         s->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
882                                         return;
883                                 }
884                         } else
885 #endif
886                         {
887                                 if (IS_FLT_DBL_TYPE(s->type)) {
888                                         if (rd->freeargflttop > 0) {
889                                                 s->regoff = rd->freeargfltregs[--rd->freeargflttop];
890                                                 s->flags |= TMPARG;
891                                                 return;
892                                         } else if (rd->argfltreguse < FLT_ARG_CNT) {
893                                                 s->regoff = rd->argfltregs[rd->argfltreguse++];
894                                                 s->flags |= TMPARG;
895                                                 return;
896                                         } else if (rd->freetmpflttop > 0) {
897                                                 s->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
898                                                 return;
899                                         } else if (rd->tmpfltreguse > 0) {
900                                                 s->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
901                                                 return;
902                                         }
903
904                                 } else {
905 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
906                                         /*
907                                          * for i386 put all longs in memory
908                                          */
909                                         if (!IS_2_WORD_TYPE(s->type))
910 #endif
911                                         {
912                                                 if (rd->freearginttop > intregsneeded) {
913                                                         rd->freearginttop -= intregsneeded + 1;
914                                                         s->flags |= TMPARG;
915 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
916                                                         if (intregsneeded) 
917                                                                 s->regoff = PACK_REGS(
918                                                                         rd->freeargintregs[rd->freearginttop],
919                                                                 rd->freeargintregs[rd->freearginttop + 1]);
920                                                         else
921 #endif
922                                                                 s->regoff =
923                                                                         rd->freeargintregs[rd->freearginttop];
924                                                         return;
925                                                 } else if (rd->argintreguse 
926                                                                    < INT_ARG_CNT - intregsneeded) {
927 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
928                                                         if (intregsneeded) 
929                                                                 s->regoff = PACK_REGS(
930                                                                         rd->argintregs[rd->argintreguse],
931                                                                     rd->argintregs[rd->argintreguse + 1]);
932                                                         else
933 #endif
934                                                                 s->regoff = rd->argintregs[rd->argintreguse];
935                                                         s->flags |= TMPARG;
936                                                         rd->argintreguse += intregsneeded + 1;
937                                                         return;
938                                                 } else if (rd->freetmpinttop > intregsneeded) {
939                                                         rd->freetmpinttop -= intregsneeded + 1;
940 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
941                                                         if (intregsneeded) 
942                                                                 s->regoff = PACK_REGS(
943                                                                         rd->freetmpintregs[rd->freetmpinttop],
944                                                                     rd->freetmpintregs[rd->freetmpinttop + 1]);
945                                                         else
946 #endif
947                                                                 s->regoff = rd->freetmpintregs[rd->freetmpinttop];
948                                                         return;
949                                                 } else if (rd->tmpintreguse > intregsneeded) {
950                                                         rd->tmpintreguse -= intregsneeded + 1;
951 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
952                                                         if (intregsneeded) 
953                                                                 s->regoff = PACK_REGS(
954                                                                         rd->tmpintregs[rd->tmpintreguse],
955                                                                     rd->tmpintregs[rd->tmpintreguse + 1]);
956                                                         else
957 #endif
958                                                                 s->regoff = rd->tmpintregs[rd->tmpintreguse];
959                                                         return;
960                                                 }
961                                         } /* if (!IS_2_WORD_TYPE(s->type)) */
962                                 } /* if (IS_FLT_DBL_TYPE(s->type)) */
963                         } /* if (IS_ADR_TYPE(s->type)) */
964                 } /* if (tryagain == 1) else */
965         } /* for(; tryagain; --tryagain) */
966
967 #if defined(HAS_4BYTE_STACKSLOT)
968         if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
969                 rd->freememtop_2--;
970                 s->regoff = rd->freemem_2[rd->freememtop_2];
971         } else
972 #endif /*defined(HAS_4BYTE_STACKSLOT) */
973                 if ((memneeded == 0) && (rd->freememtop > 0)) {
974                         rd->freememtop--;;
975                         s->regoff = rd->freemem[rd->freememtop];
976                 } else {
977 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
978                         /* align 2 Word Types */
979                         if ((memneeded) && ((rd->memuse & 1) == 1)) { 
980                                 /* Put patched memory slot on freemem */
981                                 rd->freemem[rd->freememtop++] = rd->memuse;
982                                 rd->memuse++;
983                         }
984 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
985                         s->regoff = rd->memuse;
986                         rd->memuse += memneeded + 1;
987                 }
988         s->flags |= INMEMORY;
989 }
990
991
992 #define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
993
994 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
995 /* alive using this reg/memory location */
996
997 static void reg_free_temp_func(registerdata *rd, stackptr s)
998 {
999         s4 intregsneeded;
1000         s4 memneeded;
1001
1002 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1003         intregsneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1004 #else
1005         intregsneeded = 0;
1006 #endif
1007
1008 #if defined(HAS_4BYTE_STACKSLOT)
1009         memneeded = (IS_2_WORD_TYPE(s->type)) ? 1 : 0;
1010 #else
1011         memneeded = 0;
1012 #endif
1013
1014         if (s->flags & INMEMORY) {
1015 #if defined(HAS_4BYTE_STACKSLOT)
1016                 if (memneeded > 0) {
1017                         rd->freemem_2[rd->freememtop_2] = s->regoff;
1018                         rd->freememtop_2++;
1019                 } else 
1020 #endif
1021                 {
1022                         rd->freemem[rd->freememtop] = s->regoff;
1023                         rd->freememtop++;
1024                 }
1025
1026 #ifdef HAS_ADDRESS_REGISTER_FILE
1027         } else if (IS_ADR_TYPE(s->type)) {
1028                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1029 /*                      s->flags &= ~SAVEDTMP; */
1030                         rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
1031                 } else
1032                         rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
1033 #endif
1034         } else if (IS_FLT_DBL_TYPE(s->type)) {
1035                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1036 /*                      s->flags &= ~SAVEDTMP; */
1037                         rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
1038                 } else if (s->flags & TMPARG) {
1039 /*                      s->flags &= ~TMPARG; */
1040                         rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
1041                 } else
1042                         rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
1043         } else { /* IS_INT_LNG_TYPE */
1044                 if (s->flags & (SAVEDVAR | SAVEDTMP)) {
1045 /*                      s->flags &= ~SAVEDTMP; */
1046 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1047                         if (intregsneeded) {
1048                                 rd->freesavintregs[rd->freesavinttop] =
1049                                         GET_LOW_REG(s->regoff);
1050                                 rd->freesavintregs[rd->freesavinttop + 1] =
1051                                         GET_HIGH_REG(s->regoff);
1052                         } else
1053 #endif
1054                                 rd->freesavintregs[rd->freesavinttop] = s->regoff;
1055                         rd->freesavinttop += intregsneeded + 1;
1056
1057                 } else if (s->flags & TMPARG) {
1058 /*                      s->flags &= ~TMPARG; */
1059 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1060                         if (intregsneeded) {
1061                                 rd->freeargintregs[rd->freearginttop] =
1062                                         GET_LOW_REG(s->regoff);
1063                                 rd->freeargintregs[rd->freearginttop + 1] =
1064                                         GET_HIGH_REG(s->regoff);
1065                         } else 
1066 #endif
1067                                 rd->freeargintregs[rd->freearginttop] = s->regoff;
1068                         rd->freearginttop += intregsneeded + 1;
1069                 } else {
1070 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1071                         if (intregsneeded) {
1072                                 rd->freetmpintregs[rd->freetmpinttop] =
1073                                         GET_LOW_REG(s->regoff);
1074                                 rd->freetmpintregs[rd->freetmpinttop + 1] =
1075                                         GET_HIGH_REG(s->regoff);
1076                         } else
1077 #endif
1078                                 rd->freetmpintregs[rd->freetmpinttop] = s->regoff;
1079                         rd->freetmpinttop += intregsneeded + 1;
1080                 }
1081         }
1082 }
1083
1084 static bool reg_alloc_dup(stackptr src, stackptr dst) {
1085         /* only copy TEMPVARS, do not mess with STACKVAR,      */
1086         /* LOCALVAR, or ARGVAR        */
1087         if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) {
1088                 /* can not allocate a REG_TMP to a REG_SAV Slot */
1089                 if (src->flags & INMEMORY) {
1090                         dst->regoff  = src->regoff;
1091                         dst->flags |= INMEMORY;
1092                         return true;
1093                 } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) {
1094                         dst->regoff  = src->regoff;
1095                         dst->flags |= src->flags & SAVEDTMP;
1096                         dst->flags |= src->flags & TMPARG;
1097                         return true;
1098 #if 0
1099                 } else if ((dst->flags & SAVEDVAR) == 0) {
1100                         /* can only use a REG_SAV as REG_TMP! */
1101                         dst->regoff = src->regoff;
1102                         dst->flags |= src->flags & TMPARG;
1103                         dst->flags |= SAVEDTMP;
1104                         return true;
1105 #endif
1106                 } 
1107         }
1108         /* no copy possible - allocate a new reg/memory location*/
1109         return false;
1110 }
1111
1112 /* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
1113 static void new_reg_mark_copy(registerdata *rd, stackptr *dupslots, 
1114                                                           int nin, int nout, int nthrough)
1115 {
1116         s4 src_regoff[4];
1117         s4 src_flags[4];
1118         stackptr dst_stackslots[6];
1119         int s_bottom, d_bottom, i, j, slots;
1120         bool found;
1121         stackptr sp;
1122         stackptr *argp;
1123
1124         assert(nin <= 4 && (nout + nthrough) <= 6);
1125
1126         /* remember all different Registers/Memory Location of used TEMPVAR       */
1127         /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY   */
1128         /* flag of the last (deepest) occurence */
1129         slots = nin;
1130         argp = dupslots + slots;
1131         for (s_bottom = 4; slots--; ) {
1132                 sp = *--argp;
1133                 if (sp->varkind == TEMPVAR) {
1134                         found = false;
1135                         for (i = 3; i >= s_bottom; i--) {
1136                                 if ((src_regoff[i] == sp->regoff) && 
1137                                         ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) ) 
1138                                 {
1139                                         src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
1140                                         found = true;
1141                                 }
1142                         }
1143                         if (!found) {
1144                                 s_bottom--;
1145                                 src_regoff[s_bottom] = sp->regoff;
1146                                 src_flags[s_bottom] = sp->flags;
1147                         }
1148                 }
1149         }
1150
1151         /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they   */
1152         /* have to be from the "lowest" upwards, and the stackelements list is    */
1153         /* linked from only top downwards */
1154         
1155         slots = nthrough + nout;
1156         argp = dupslots + nin + nout;
1157         for (d_bottom = 6; slots--; ) {
1158                 sp = *--argp;
1159                 if (sp->varkind == TEMPVAR) {
1160                         d_bottom--;
1161                         dst_stackslots[d_bottom] = sp;
1162                 }
1163         }
1164
1165         /* Mark all reused reg/mem in dst stacklots with STCOPY, if the           */
1166         /* corresponding src stackslot was marked STCOPY*/
1167         /* if the correspondig STCOPY from the src stackslot was not set, do not  */
1168         /* mark the lowest occurence at dst stackslots */
1169         /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst  */
1170         /* stacklots, so they are not freed afterwards */
1171         for (i = d_bottom; i < 6; i++) {
1172                 for (j = s_bottom; j < 4; j++) {
1173                         if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
1174                                  ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) ) 
1175                         {
1176                                 if (src_flags[j] & STCOPY) {
1177                                         dst_stackslots[i]->flags |= STCOPY;
1178                                 }
1179                                 else {
1180                                         src_flags[j] |= STCOPY;
1181                                         dst_stackslots[i]->flags &= ~STCOPY;
1182                                 }
1183                                 /* do not free reg/mem of src Stackslot */
1184                                 src_flags[j] |= STKEEP;
1185                         }
1186                 }
1187         }
1188
1189         /* free all reg/mem of src stack, which where not marked with STKEEP */
1190         for (j=s_bottom; j < 4; j++) {
1191                 if ((src_flags[j] & STKEEP)==0) {
1192                         /* free, if STCOPY of src stackslot is not set */
1193                         /* STCOPY is already checked in reg_free_temp macro! */
1194                         slots = nin;
1195                         argp = dupslots + slots;
1196                         while (--slots) {
1197                                 sp = *--argp;
1198                                 if ((src_regoff[j] == sp->regoff) && 
1199                                         ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) ) 
1200                                 {
1201                                         reg_free_temp(rd, sp);
1202                                 }
1203                         }
1204                 }
1205         }
1206 }
1207
1208 /* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
1209 static void reg_mark_copy(registerdata *rd, stackptr src_top, stackptr src_bottom, stackptr dst_top, stackptr dst_bottom) {
1210         s4 src_regoff[4];
1211         s4 src_flags[4];
1212         stackptr dst_stackslots[6];
1213         int s_bottom, d_bottom, i, j;
1214         bool found;
1215
1216         stackptr sp;
1217
1218         /* remember all different Registers/Memory Location of used TEMPVAR       */
1219         /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY   */
1220         /* flag of the last (deepest) occurence */
1221         for(s_bottom = 4, sp = src_top; sp >= src_bottom; sp = sp->prev) {
1222                 if (sp->varkind == TEMPVAR) {
1223                         found = false;
1224                         for( i = 3; i >= s_bottom; i--) {
1225                                 if ((src_regoff[i] == sp->regoff) && 
1226                                         ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) ) {
1227                                         src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
1228                                         found = true;
1229                                 }
1230                         }
1231                         if (!found) {
1232                                 s_bottom--;
1233                                 src_regoff[s_bottom] = sp->regoff;
1234                                 src_flags[s_bottom] = sp->flags;
1235                         }
1236                 }
1237         }
1238
1239         /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they   */
1240         /* have to be from the "lowest" upwards, and the stackelements list is    */
1241         /* linked from only top downwards */
1242         
1243         for(d_bottom = 6, sp =dst_top; sp >= dst_bottom; sp = sp->prev) {
1244                 if (sp->varkind == TEMPVAR) {
1245                         d_bottom--;
1246                         dst_stackslots[d_bottom] = sp;
1247                 }
1248         }
1249
1250         /* Mark all reused reg/mem in dst stacklots with STCOPY, if the           */
1251         /* corresponding src stackslot was marked STCOPY*/
1252         /* if the correspondig STCOPY from the src stackslot was not set, do not  */
1253         /* mark the lowest occurence at dst stackslots */
1254         /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst  */
1255         /* stacklots, so they are not freed afterwards */
1256         for(i = d_bottom; i < 6; i++) {
1257                 for(j = s_bottom; j < 4; j++) {
1258                         if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
1259                                  ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) ) {
1260                                 if (src_flags[j] & STCOPY)
1261                                         dst_stackslots[i]->flags |= STCOPY;
1262                                 else {
1263                                         src_flags[j] |= STCOPY;
1264                                         dst_stackslots[i]->flags &= ~STCOPY;
1265                                 }
1266                                 /* do not free reg/mem of src Stackslot */
1267                                 src_flags[j] |= STKEEP;
1268                         }
1269                 }
1270         }
1271
1272         /* free all reg/mem of src stack, which where not marked with STKEEP */
1273         for(j=s_bottom; j < 4; j++) {
1274                 if ((src_flags[j] & STKEEP)==0) {
1275                         /* free, if STCOPY of src stackslot is not set */
1276                         /* STCOPY is already checked in reg_free_temp macro! */
1277                         for(sp = src_top; sp >= src_bottom; sp = sp->prev)
1278                                 if ((src_regoff[j] == sp->regoff) && 
1279                                         ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) ) {
1280                                         reg_free_temp(rd, sp);
1281                                 }
1282                 }
1283         }
1284 }
1285
1286
1287 /* allocate_scratch_registers **************************************************
1288
1289    Allocate temporary (non-interface, non-local) registers.
1290
1291 *******************************************************************************/
1292
1293 static void new_allocate_scratch_registers(jitdata *jd)
1294 {
1295         methodinfo         *m;
1296         registerdata       *rd;
1297         s4                  i;
1298         s4                  len;
1299         new_instruction    *iptr;
1300         basicblock         *bptr;
1301         builtintable_entry *bte;
1302         methoddesc         *md;
1303         stackptr           *argp;
1304
1305         /* get required compiler data */
1306
1307         m  = jd->m;
1308         rd = jd->rd;
1309
1310         /* initialize temp registers */
1311         reg_init_temp(m, rd);
1312
1313         bptr = jd->new_basicblocks;
1314
1315         while (bptr != NULL) {
1316                 if (bptr->flags >= BBREACHED) {
1317                         iptr = /* XXX */ (new_instruction *) bptr->iinstr;
1318                         len = bptr->icount;
1319
1320                         while (--len >= 0)  {
1321                                 switch (iptr->opc) {
1322
1323                                         /* pop 0 push 0 */
1324
1325                                 case ICMD_NOP:
1326                                 case ICMD_ELSE_ICONST:
1327                                 case ICMD_CHECKNULL:
1328                                 case ICMD_IINC:
1329                                 case ICMD_JSR:
1330                                 case ICMD_RET:
1331                                 case ICMD_RETURN:
1332                                 case ICMD_GOTO:
1333                                 case ICMD_PUTSTATICCONST:
1334                                 case ICMD_INLINE_START:
1335                                 case ICMD_INLINE_END:
1336                                 case ICMD_INLINE_GOTO:
1337                                         break;
1338
1339                                         /* pop 0 push 1 const */
1340                                         
1341                                 case ICMD_ICONST:
1342                                 case ICMD_LCONST:
1343                                 case ICMD_FCONST:
1344                                 case ICMD_DCONST:
1345                                 case ICMD_ACONST:
1346
1347                                         /* pop 0 push 1 load */
1348                                         
1349                                 case ICMD_ILOAD:
1350                                 case ICMD_LLOAD:
1351                                 case ICMD_FLOAD:
1352                                 case ICMD_DLOAD:
1353                                 case ICMD_ALOAD:
1354                                         reg_new_temp(rd, iptr->dst.var);
1355                                         break;
1356
1357                                         /* pop 2 push 1 */
1358
1359                                 case ICMD_IALOAD:
1360                                 case ICMD_LALOAD:
1361                                 case ICMD_FALOAD:
1362                                 case ICMD_DALOAD:
1363                                 case ICMD_AALOAD:
1364
1365                                 case ICMD_BALOAD:
1366                                 case ICMD_CALOAD:
1367                                 case ICMD_SALOAD:
1368                                         reg_free_temp(rd, iptr->sx.s23.s2.var);
1369                                         reg_free_temp(rd, iptr->s1.var);
1370                                         reg_new_temp(rd, iptr->dst.var);
1371                                         break;
1372
1373                                         /* pop 3 push 0 */
1374
1375                                 case ICMD_IASTORE:
1376                                 case ICMD_LASTORE:
1377                                 case ICMD_FASTORE:
1378                                 case ICMD_DASTORE:
1379                                 case ICMD_AASTORE:
1380
1381                                 case ICMD_BASTORE:
1382                                 case ICMD_CASTORE:
1383                                 case ICMD_SASTORE:
1384                                         reg_free_temp(rd, iptr->sx.s23.s3.var);
1385                                         reg_free_temp(rd, iptr->sx.s23.s2.var);
1386                                         reg_free_temp(rd, iptr->s1.var);
1387                                         break;
1388
1389                                         /* pop 1 push 0 store */
1390
1391                                 case ICMD_ISTORE:
1392                                 case ICMD_LSTORE:
1393                                 case ICMD_FSTORE:
1394                                 case ICMD_DSTORE:
1395                                 case ICMD_ASTORE:
1396
1397                                         /* pop 1 push 0 */
1398
1399                                 case ICMD_POP:
1400
1401                                 case ICMD_IRETURN:
1402                                 case ICMD_LRETURN:
1403                                 case ICMD_FRETURN:
1404                                 case ICMD_DRETURN:
1405                                 case ICMD_ARETURN:
1406
1407                                 case ICMD_ATHROW:
1408
1409                                 case ICMD_PUTSTATIC:
1410                                 case ICMD_PUTFIELDCONST:
1411
1412                                         /* pop 1 push 0 branch */
1413
1414                                 case ICMD_IFNULL:
1415                                 case ICMD_IFNONNULL:
1416
1417                                 case ICMD_IFEQ:
1418                                 case ICMD_IFNE:
1419                                 case ICMD_IFLT:
1420                                 case ICMD_IFGE:
1421                                 case ICMD_IFGT:
1422                                 case ICMD_IFLE:
1423
1424                                 case ICMD_IF_LEQ:
1425                                 case ICMD_IF_LNE:
1426                                 case ICMD_IF_LLT:
1427                                 case ICMD_IF_LGE:
1428                                 case ICMD_IF_LGT:
1429                                 case ICMD_IF_LLE:
1430
1431                                         /* pop 1 push 0 table branch */
1432
1433                                 case ICMD_TABLESWITCH:
1434                                 case ICMD_LOOKUPSWITCH:
1435
1436                                 case ICMD_MONITORENTER:
1437                                 case ICMD_MONITOREXIT:
1438                                         reg_free_temp(rd, iptr->s1.var);
1439                                         break;
1440
1441                                         /* pop 2 push 0 branch */
1442
1443                                 case ICMD_IF_ICMPEQ:
1444                                 case ICMD_IF_ICMPNE:
1445                                 case ICMD_IF_ICMPLT:
1446                                 case ICMD_IF_ICMPGE:
1447                                 case ICMD_IF_ICMPGT:
1448                                 case ICMD_IF_ICMPLE:
1449
1450                                 case ICMD_IF_LCMPEQ:
1451                                 case ICMD_IF_LCMPNE:
1452                                 case ICMD_IF_LCMPLT:
1453                                 case ICMD_IF_LCMPGE:
1454                                 case ICMD_IF_LCMPGT:
1455                                 case ICMD_IF_LCMPLE:
1456
1457                                 case ICMD_IF_FCMPEQ:
1458                                 case ICMD_IF_FCMPNE:
1459
1460                                 case ICMD_IF_FCMPL_LT:
1461                                 case ICMD_IF_FCMPL_GE:
1462                                 case ICMD_IF_FCMPL_GT:
1463                                 case ICMD_IF_FCMPL_LE:
1464
1465                                 case ICMD_IF_FCMPG_LT:
1466                                 case ICMD_IF_FCMPG_GE:
1467                                 case ICMD_IF_FCMPG_GT:
1468                                 case ICMD_IF_FCMPG_LE:
1469
1470                                 case ICMD_IF_DCMPEQ:
1471                                 case ICMD_IF_DCMPNE:
1472
1473                                 case ICMD_IF_DCMPL_LT:
1474                                 case ICMD_IF_DCMPL_GE:
1475                                 case ICMD_IF_DCMPL_GT:
1476                                 case ICMD_IF_DCMPL_LE:
1477
1478                                 case ICMD_IF_DCMPG_LT:
1479                                 case ICMD_IF_DCMPG_GE:
1480                                 case ICMD_IF_DCMPG_GT:
1481                                 case ICMD_IF_DCMPG_LE:
1482
1483                                 case ICMD_IF_ACMPEQ:
1484                                 case ICMD_IF_ACMPNE:
1485
1486                                         /* pop 2 push 0 */
1487
1488                                 case ICMD_POP2:
1489
1490                                 case ICMD_PUTFIELD:
1491
1492                                 case ICMD_IASTORECONST:
1493                                 case ICMD_LASTORECONST:
1494                                 case ICMD_AASTORECONST:
1495                                 case ICMD_BASTORECONST:
1496                                 case ICMD_CASTORECONST:
1497                                 case ICMD_SASTORECONST:
1498                                         reg_free_temp(rd, iptr->sx.s23.s2.var);
1499                                         reg_free_temp(rd, iptr->s1.var);
1500                                         break;
1501
1502                                         /* pop 0 push 1 dup */
1503                                         
1504                                 case ICMD_DUP:
1505                                         /* src === dst->prev (identical Stackslot Element)     */
1506                                         /* src --> dst       (copied value, take same reg/mem) */
1507
1508                                         if (!reg_alloc_dup(iptr->s1.var, iptr->dst.var)) {
1509                                                 reg_new_temp(rd, iptr->dst.var);
1510                                         } else {
1511                                                 iptr->dst.var->flags |= STCOPY;
1512                                         }
1513                                         break;
1514
1515                                         /* pop 0 push 2 dup */
1516                                         
1517                                 case ICMD_DUP2:
1518                                         /* src->prev === dst->prev->prev->prev (identical Stackslot Element)     */
1519                                         /* src       === dst->prev->prev       (identical Stackslot Element)     */
1520                                         /* src->prev --> dst->prev             (copied value, take same reg/mem) */
1521                                         /* src       --> dst                   (copied value, take same reg/mem) */
1522                                                                                                 
1523                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0]))
1524                                                 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1525                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1]))
1526                                                 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1527                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2);
1528                                         break;
1529
1530                                         /* pop 2 push 3 dup */
1531                                         
1532                                 case ICMD_DUP_X1:
1533                                         /* src->prev --> dst->prev       (copied value, take same reg/mem) */
1534                                         /* src       --> dst             (copied value, take same reg/mem) */
1535                                         /* src       --> dst->prev->prev (copied value, take same reg/mem) */
1536                                                                                                 
1537                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
1538                                                 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1539                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2]))
1540                                                 reg_new_temp(rd, iptr->dst.dupslots[2+2]);
1541                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
1542                                                 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1543                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0);
1544                                         break;
1545
1546                                         /* pop 3 push 4 dup */
1547                                         
1548                                 case ICMD_DUP_X2:
1549                                         /* src->prev->prev --> dst->prev->prev        */
1550                                         /* src->prev       --> dst->prev              */
1551                                         /* src             --> dst                    */
1552                                         /* src             --> dst->prev->prev->prev  */
1553                                         
1554                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0]))
1555                                                 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1556                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3]))
1557                                                 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1558                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2]))
1559                                                 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1560                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1]))
1561                                                 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1562                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0);
1563                                         break;
1564
1565                                         /* pop 3 push 5 dup */
1566                                         
1567                                 case ICMD_DUP2_X1:
1568                                         /* src->prev->prev --> dst->prev->prev             */
1569                                         /* src->prev       --> dst->prev                   */
1570                                         /* src             --> dst                         */
1571                                         /* src->prev       --> dst->prev->prev->prev->prev */
1572                                         /* src             --> dst->prev->prev->prev       */
1573                                                                                                 
1574                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1]))
1575                                                 reg_new_temp(rd, iptr->dst.dupslots[3+1]);
1576                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4]))
1577                                                 reg_new_temp(rd, iptr->dst.dupslots[3+4]);
1578                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0]))
1579                                                 reg_new_temp(rd, iptr->dst.dupslots[3+0]);
1580                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3]))
1581                                                 reg_new_temp(rd, iptr->dst.dupslots[3+3]);
1582                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2]))
1583                                                 reg_new_temp(rd, iptr->dst.dupslots[3+2]);
1584                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0);
1585                                         break;
1586
1587                                         /* pop 4 push 6 dup */
1588                                         
1589                                 case ICMD_DUP2_X2:
1590                                         /* src->prev->prev->prev --> dst->prev->prev->prev             */
1591                                         /* src->prev->prev       --> dst->prev->prev                   */
1592                                         /* src->prev             --> dst->prev                         */
1593                                         /* src                   --> dst                               */
1594                                         /* src->prev             --> dst->prev->prev->prev->prev->prev */
1595                                         /* src                   --> dst->prev->prev->prev->prev       */
1596                                                                                                 
1597                                         if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1]))
1598                                                 reg_new_temp(rd, iptr->dst.dupslots[4+1]);
1599                                         if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5]))
1600                                                 reg_new_temp(rd, iptr->dst.dupslots[4+5]);
1601                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0]))
1602                                                 reg_new_temp(rd, iptr->dst.dupslots[4+0]);
1603                                         if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4]))
1604                                                 reg_new_temp(rd, iptr->dst.dupslots[4+4]);
1605                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3]))
1606                                                 reg_new_temp(rd, iptr->dst.dupslots[4+3]);
1607                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2]))
1608                                                 reg_new_temp(rd, iptr->dst.dupslots[4+2]);
1609                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0);
1610                                         break;
1611
1612                                         /* pop 2 push 2 swap */
1613                                         
1614                                 case ICMD_SWAP:
1615                                         /* src       --> dst->prev   (copy) */
1616                                         /* src->prev --> dst         (copy) */
1617                                                                                                 
1618                                         if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[+0]))
1619                                                 reg_new_temp(rd, iptr->dst.dupslots[2+0]);
1620                                         if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[+1]))
1621                                                 reg_new_temp(rd, iptr->dst.dupslots[2+1]);
1622                                         new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0);
1623                                         break;
1624
1625                                         /* pop 2 push 1 */
1626                                         
1627                                 case ICMD_IADD:
1628                                 case ICMD_ISUB:
1629                                 case ICMD_IMUL:
1630                                 case ICMD_IDIV:
1631                                 case ICMD_IREM:
1632
1633                                 case ICMD_ISHL:
1634                                 case ICMD_ISHR:
1635                                 case ICMD_IUSHR:
1636                                 case ICMD_IAND:
1637                                 case ICMD_IOR:
1638                                 case ICMD_IXOR:
1639
1640                                 case ICMD_LADD:
1641                                 case ICMD_LSUB:
1642                                 case ICMD_LMUL:
1643                                 case ICMD_LDIV:
1644                                 case ICMD_LREM:
1645
1646                                 case ICMD_LOR:
1647                                 case ICMD_LAND:
1648                                 case ICMD_LXOR:
1649
1650                                 case ICMD_LSHL:
1651                                 case ICMD_LSHR:
1652                                 case ICMD_LUSHR:
1653
1654                                 case ICMD_FADD:
1655                                 case ICMD_FSUB:
1656                                 case ICMD_FMUL:
1657                                 case ICMD_FDIV:
1658                                 case ICMD_FREM:
1659
1660                                 case ICMD_DADD:
1661                                 case ICMD_DSUB:
1662                                 case ICMD_DMUL:
1663                                 case ICMD_DDIV:
1664                                 case ICMD_DREM:
1665
1666                                 case ICMD_LCMP:
1667                                 case ICMD_FCMPL:
1668                                 case ICMD_FCMPG:
1669                                 case ICMD_DCMPL:
1670                                 case ICMD_DCMPG:
1671                                         reg_free_temp(rd, iptr->sx.s23.s2.var);
1672                                         reg_free_temp(rd, iptr->s1.var);
1673                                         reg_new_temp(rd, iptr->dst.var);
1674                                         break;
1675
1676                                         /* pop 1 push 1 */
1677                                         
1678                                 case ICMD_IADDCONST:
1679                                 case ICMD_ISUBCONST:
1680                                 case ICMD_IMULCONST:
1681                                 case ICMD_IMULPOW2:
1682                                 case ICMD_IDIVPOW2:
1683                                 case ICMD_IREMPOW2:
1684                                 case ICMD_IANDCONST:
1685                                 case ICMD_IORCONST:
1686                                 case ICMD_IXORCONST:
1687                                 case ICMD_ISHLCONST:
1688                                 case ICMD_ISHRCONST:
1689                                 case ICMD_IUSHRCONST:
1690
1691                                 case ICMD_LADDCONST:
1692                                 case ICMD_LSUBCONST:
1693                                 case ICMD_LMULCONST:
1694                                 case ICMD_LMULPOW2:
1695                                 case ICMD_LDIVPOW2:
1696                                 case ICMD_LREMPOW2:
1697                                 case ICMD_LANDCONST:
1698                                 case ICMD_LORCONST:
1699                                 case ICMD_LXORCONST:
1700                                 case ICMD_LSHLCONST:
1701                                 case ICMD_LSHRCONST:
1702                                 case ICMD_LUSHRCONST:
1703
1704                                 case ICMD_IFEQ_ICONST:
1705                                 case ICMD_IFNE_ICONST:
1706                                 case ICMD_IFLT_ICONST:
1707                                 case ICMD_IFGE_ICONST:
1708                                 case ICMD_IFGT_ICONST:
1709                                 case ICMD_IFLE_ICONST:
1710
1711                                 case ICMD_INEG:
1712                                 case ICMD_INT2BYTE:
1713                                 case ICMD_INT2CHAR:
1714                                 case ICMD_INT2SHORT:
1715                                 case ICMD_LNEG:
1716                                 case ICMD_FNEG:
1717                                 case ICMD_DNEG:
1718
1719                                 case ICMD_I2L:
1720                                 case ICMD_I2F:
1721                                 case ICMD_I2D:
1722                                 case ICMD_L2I:
1723                                 case ICMD_L2F:
1724                                 case ICMD_L2D:
1725                                 case ICMD_F2I:
1726                                 case ICMD_F2L:
1727                                 case ICMD_F2D:
1728                                 case ICMD_D2I:
1729                                 case ICMD_D2L:
1730                                 case ICMD_D2F:
1731
1732                                 case ICMD_CHECKCAST:
1733
1734                                 case ICMD_ARRAYLENGTH:
1735                                 case ICMD_INSTANCEOF:
1736
1737                                 case ICMD_NEWARRAY:
1738                                 case ICMD_ANEWARRAY:
1739
1740                                 case ICMD_GETFIELD:
1741                                         reg_free_temp(rd, iptr->s1.var);
1742                                         reg_new_temp(rd, iptr->dst.var);
1743                                         break;
1744
1745                                         /* pop 0 push 1 */
1746                                         
1747                                 case ICMD_GETSTATIC:
1748
1749                                 case ICMD_NEW:
1750                                         reg_new_temp(rd, iptr->dst.var);
1751                                         break;
1752
1753                                         /* pop many push any */
1754                                         
1755                                 case ICMD_INVOKESTATIC:
1756                                 case ICMD_INVOKESPECIAL:
1757                                 case ICMD_INVOKEVIRTUAL:
1758                                 case ICMD_INVOKEINTERFACE:
1759                                         NEW_INSTRUCTION_GET_METHODDESC(iptr,md);
1760                                         i = md->paramcount;
1761                                         argp = iptr->sx.s23.s2.args;
1762                                         while (--i >= 0) {
1763                                                 reg_free_temp(rd, *argp);
1764                                                 argp++;
1765                                         }
1766                                         if (md->returntype.type != TYPE_VOID)
1767                                                 reg_new_temp(rd, iptr->dst.var);
1768                                         break;
1769
1770                                 case ICMD_BUILTIN:
1771                                         bte = iptr->sx.s23.s3.bte;
1772                                         md = bte->md;
1773                                         i = md->paramcount;
1774                                         argp = iptr->sx.s23.s2.args;
1775                                         while (--i >= 0) {
1776                                                 reg_free_temp(rd, *argp);
1777                                                 argp++;
1778                                         }
1779                                         if (md->returntype.type != TYPE_VOID)
1780                                                 reg_new_temp(rd, iptr->dst.var);
1781                                         break;
1782
1783                                 case ICMD_MULTIANEWARRAY:
1784                                         i = iptr->s1.argcount;
1785                                         argp = iptr->sx.s23.s2.args;
1786                                         while (--i >= 0) {
1787                                                 reg_free_temp(rd, *argp);
1788                                                 argp++;
1789                                         }
1790                                         reg_new_temp(rd, iptr->dst.var);
1791                                         break;
1792
1793                                 default:
1794                                         *exceptionptr =
1795                                                 new_internalerror("Unknown ICMD %d during register allocation",
1796                                                                                   iptr->opc);
1797                                         return;
1798                                 } /* switch */
1799                                 iptr++;
1800                         } /* while instructions */
1801                 } /* if */
1802                 bptr = bptr->next;
1803         } /* while blocks */
1804 }
1805
1806 static void allocate_scratch_registers(jitdata *jd)
1807 {
1808         methodinfo         *m;
1809         registerdata       *rd;
1810         s4                  i;
1811         s4                  len;
1812         stackptr            src;
1813         stackptr            dst;
1814         instruction        *iptr;
1815         basicblock         *bptr;
1816         builtintable_entry *bte;
1817         methoddesc         *md;
1818
1819         /* get required compiler data */
1820
1821         m  = jd->m;
1822         rd = jd->rd;
1823
1824         /* initialize temp registers */
1825         reg_init_temp(m, rd);
1826
1827         bptr = m->basicblocks;
1828
1829         while (bptr != NULL) {
1830                 if (bptr->flags >= BBREACHED) {
1831                         dst = bptr->instack;
1832
1833                         iptr = bptr->iinstr;
1834                         len = bptr->icount;
1835
1836                         while (--len >= 0)  {
1837                                 src = dst;
1838                                 dst = iptr->dst;
1839
1840                                 switch (iptr->opc) {
1841
1842                                         /* pop 0 push 0 */
1843
1844                                 case ICMD_NOP:
1845                                 case ICMD_ELSE_ICONST:
1846                                 case ICMD_CHECKNULL:
1847                                 case ICMD_IINC:
1848                                 case ICMD_JSR:
1849                                 case ICMD_RET:
1850                                 case ICMD_RETURN:
1851                                 case ICMD_GOTO:
1852                                 case ICMD_PUTSTATICCONST:
1853                                 case ICMD_INLINE_START:
1854                                 case ICMD_INLINE_END:
1855                                 case ICMD_INLINE_GOTO:
1856                                         break;
1857
1858                                         /* pop 0 push 1 const */
1859                                         
1860                                 case ICMD_ICONST:
1861                                 case ICMD_LCONST:
1862                                 case ICMD_FCONST:
1863                                 case ICMD_DCONST:
1864                                 case ICMD_ACONST:
1865
1866                                         /* pop 0 push 1 load */
1867                                         
1868                                 case ICMD_ILOAD:
1869                                 case ICMD_LLOAD:
1870                                 case ICMD_FLOAD:
1871                                 case ICMD_DLOAD:
1872                                 case ICMD_ALOAD:
1873                                         reg_new_temp(rd, dst);
1874                                         break;
1875
1876                                         /* pop 2 push 1 */
1877
1878                                 case ICMD_IALOAD:
1879                                 case ICMD_LALOAD:
1880                                 case ICMD_FALOAD:
1881                                 case ICMD_DALOAD:
1882                                 case ICMD_AALOAD:
1883
1884                                 case ICMD_BALOAD:
1885                                 case ICMD_CALOAD:
1886                                 case ICMD_SALOAD:
1887                                         reg_free_temp(rd, src);
1888                                         reg_free_temp(rd, src->prev);
1889                                         reg_new_temp(rd, dst);
1890                                         break;
1891
1892                                         /* pop 3 push 0 */
1893
1894                                 case ICMD_IASTORE:
1895                                 case ICMD_LASTORE:
1896                                 case ICMD_FASTORE:
1897                                 case ICMD_DASTORE:
1898                                 case ICMD_AASTORE:
1899
1900                                 case ICMD_BASTORE:
1901                                 case ICMD_CASTORE:
1902                                 case ICMD_SASTORE:
1903                                         reg_free_temp(rd, src);
1904                                         reg_free_temp(rd, src->prev);
1905                                         reg_free_temp(rd, src->prev->prev);
1906                                         break;
1907
1908                                         /* pop 1 push 0 store */
1909
1910                                 case ICMD_ISTORE:
1911                                 case ICMD_LSTORE:
1912                                 case ICMD_FSTORE:
1913                                 case ICMD_DSTORE:
1914                                 case ICMD_ASTORE:
1915
1916                                         /* pop 1 push 0 */
1917
1918                                 case ICMD_POP:
1919
1920                                 case ICMD_IRETURN:
1921                                 case ICMD_LRETURN:
1922                                 case ICMD_FRETURN:
1923                                 case ICMD_DRETURN:
1924                                 case ICMD_ARETURN:
1925
1926                                 case ICMD_ATHROW:
1927
1928                                 case ICMD_PUTSTATIC:
1929                                 case ICMD_PUTFIELDCONST:
1930
1931                                         /* pop 1 push 0 branch */
1932
1933                                 case ICMD_IFNULL:
1934                                 case ICMD_IFNONNULL:
1935
1936                                 case ICMD_IFEQ:
1937                                 case ICMD_IFNE:
1938                                 case ICMD_IFLT:
1939                                 case ICMD_IFGE:
1940                                 case ICMD_IFGT:
1941                                 case ICMD_IFLE:
1942
1943                                 case ICMD_IF_LEQ:
1944                                 case ICMD_IF_LNE:
1945                                 case ICMD_IF_LLT:
1946                                 case ICMD_IF_LGE:
1947                                 case ICMD_IF_LGT:
1948                                 case ICMD_IF_LLE:
1949
1950                                         /* pop 1 push 0 table branch */
1951
1952                                 case ICMD_TABLESWITCH:
1953                                 case ICMD_LOOKUPSWITCH:
1954
1955                                 case ICMD_MONITORENTER:
1956                                 case ICMD_MONITOREXIT:
1957                                         reg_free_temp(rd, src);
1958                                         break;
1959
1960                                         /* pop 2 push 0 branch */
1961
1962                                 case ICMD_IF_ICMPEQ:
1963                                 case ICMD_IF_ICMPNE:
1964                                 case ICMD_IF_ICMPLT:
1965                                 case ICMD_IF_ICMPGE:
1966                                 case ICMD_IF_ICMPGT:
1967                                 case ICMD_IF_ICMPLE:
1968
1969                                 case ICMD_IF_LCMPEQ:
1970                                 case ICMD_IF_LCMPNE:
1971                                 case ICMD_IF_LCMPLT:
1972                                 case ICMD_IF_LCMPGE:
1973                                 case ICMD_IF_LCMPGT:
1974                                 case ICMD_IF_LCMPLE:
1975
1976                                 case ICMD_IF_FCMPEQ:
1977                                 case ICMD_IF_FCMPNE:
1978
1979                                 case ICMD_IF_FCMPL_LT:
1980                                 case ICMD_IF_FCMPL_GE:
1981                                 case ICMD_IF_FCMPL_GT:
1982                                 case ICMD_IF_FCMPL_LE:
1983
1984                                 case ICMD_IF_FCMPG_LT:
1985                                 case ICMD_IF_FCMPG_GE:
1986                                 case ICMD_IF_FCMPG_GT:
1987                                 case ICMD_IF_FCMPG_LE:
1988
1989                                 case ICMD_IF_DCMPEQ:
1990                                 case ICMD_IF_DCMPNE:
1991
1992                                 case ICMD_IF_DCMPL_LT:
1993                                 case ICMD_IF_DCMPL_GE:
1994                                 case ICMD_IF_DCMPL_GT:
1995                                 case ICMD_IF_DCMPL_LE:
1996
1997                                 case ICMD_IF_DCMPG_LT:
1998                                 case ICMD_IF_DCMPG_GE:
1999                                 case ICMD_IF_DCMPG_GT:
2000                                 case ICMD_IF_DCMPG_LE:
2001
2002                                 case ICMD_IF_ACMPEQ:
2003                                 case ICMD_IF_ACMPNE:
2004
2005                                         /* pop 2 push 0 */
2006
2007                                 case ICMD_POP2:
2008
2009                                 case ICMD_PUTFIELD:
2010
2011                                 case ICMD_IASTORECONST:
2012                                 case ICMD_LASTORECONST:
2013                                 case ICMD_AASTORECONST:
2014                                 case ICMD_BASTORECONST:
2015                                 case ICMD_CASTORECONST:
2016                                 case ICMD_SASTORECONST:
2017                                         reg_free_temp(rd, src);
2018                                         reg_free_temp(rd, src->prev);
2019                                         break;
2020
2021                                         /* pop 0 push 1 dup */
2022                                         
2023                                 case ICMD_DUP:
2024                                         /* src === dst->prev (identical Stackslot Element)     */
2025                                         /* src --> dst       (copied value, take same reg/mem) */
2026
2027                                         if (!reg_alloc_dup(src, dst)) {
2028                                                 reg_new_temp(rd, dst);
2029                                         } else {
2030                                                 dst->flags |= STCOPY;
2031                                         }
2032                                         break;
2033
2034                                         /* pop 0 push 2 dup */
2035                                         
2036                                 case ICMD_DUP2:
2037                                         /* src->prev === dst->prev->prev->prev (identical Stackslot Element)     */
2038                                         /* src       === dst->prev->prev       (identical Stackslot Element)     */
2039                                         /* src->prev --> dst->prev             (copied value, take same reg/mem) */
2040                                         /* src       --> dst                   (copied value, take same reg/mem) */
2041                                                                                                 
2042                                         if (!reg_alloc_dup(src->prev, dst->prev))
2043                                                 reg_new_temp(rd, dst->prev);
2044                                         if (!reg_alloc_dup(src, dst))
2045                                                 reg_new_temp(rd, dst);
2046                                         reg_mark_copy(rd, src, src->prev, dst, dst->prev->prev->prev);
2047                                         break;
2048
2049                                         /* pop 2 push 3 dup */
2050                                         
2051                                 case ICMD_DUP_X1:
2052                                         /* src->prev --> dst->prev       (copied value, take same reg/mem) */
2053                                         /* src       --> dst             (copied value, take same reg/mem) */
2054                                         /* src       --> dst->prev->prev (copied value, take same reg/mem) */
2055                                                                                                 
2056                                         if (!reg_alloc_dup(src, dst->prev->prev))
2057                                                 reg_new_temp(rd, dst->prev->prev);
2058                                         if (!reg_alloc_dup(src, dst))
2059                                                 reg_new_temp(rd, dst);
2060                                         if (!reg_alloc_dup(src->prev, dst->prev))
2061                                                 reg_new_temp(rd, dst->prev);
2062                                         reg_mark_copy(rd, src, src->prev, dst, dst->prev->prev);
2063                                         break;
2064
2065                                         /* pop 3 push 4 dup */
2066                                         
2067                                 case ICMD_DUP_X2:
2068                                         /* src->prev->prev --> dst->prev->prev        */
2069                                         /* src->prev       --> dst->prev              */
2070                                         /* src             --> dst                    */
2071                                         /* src             --> dst->prev->prev->prev  */
2072                                         
2073                                         if (!reg_alloc_dup(src, dst->prev->prev->prev))
2074                                                 reg_new_temp(rd, dst->prev->prev->prev);
2075                                         if (!reg_alloc_dup(src, dst))
2076                                                 reg_new_temp(rd, dst);
2077                                         if (!reg_alloc_dup(src->prev, dst->prev))
2078                                                 reg_new_temp(rd, dst->prev);
2079                                         if (!reg_alloc_dup(src->prev->prev, dst->prev->prev))
2080                                                 reg_new_temp(rd, dst->prev->prev);
2081                                         reg_mark_copy(rd, src, src->prev->prev, dst, dst->prev->prev->prev);
2082                                         break;
2083
2084                                         /* pop 3 push 5 dup */
2085                                         
2086                                 case ICMD_DUP2_X1:
2087                                         /* src->prev->prev --> dst->prev->prev             */
2088                                         /* src->prev       --> dst->prev                   */
2089                                         /* src             --> dst                         */
2090                                         /* src->prev       --> dst->prev->prev->prev->prev */
2091                                         /* src             --> dst->prev->prev->prev       */
2092                                                                                                 
2093                                         if (!reg_alloc_dup(src, dst->prev->prev->prev))
2094                                                 reg_new_temp(rd, dst->prev->prev->prev);
2095                                         if (!reg_alloc_dup(src, dst))
2096                                                 reg_new_temp(rd, dst);
2097                                         if (!reg_alloc_dup(src->prev, dst->prev->prev->prev->prev))
2098                                                 reg_new_temp(rd, dst->prev->prev->prev->prev);
2099                                         if (!reg_alloc_dup(src->prev, dst->prev))
2100                                                 reg_new_temp(rd, dst->prev);
2101                                         if (!reg_alloc_dup(src->prev->prev, dst->prev->prev))
2102                                                 reg_new_temp(rd, dst->prev->prev);
2103                                         reg_mark_copy(rd, src, src->prev->prev, dst, dst->prev->prev->prev->prev);
2104                                         break;
2105
2106                                         /* pop 4 push 6 dup */
2107                                         
2108                                 case ICMD_DUP2_X2:
2109                                         /* src->prev->prev->prev --> dst->prev->prev->prev             */
2110                                         /* src->prev->prev       --> dst->prev->prev                   */
2111                                         /* src->prev             --> dst->prev                         */
2112                                         /* src                   --> dst                               */
2113                                         /* src->prev             --> dst->prev->prev->prev->prev->prev */
2114                                         /* src                   --> dst->prev->prev->prev->prev       */
2115                                                                                                 
2116                                         if (!reg_alloc_dup(src, dst->prev->prev->prev->prev))
2117                                                 reg_new_temp(rd, dst->prev->prev->prev->prev);
2118                                         if (!reg_alloc_dup(src, dst))
2119                                                 reg_new_temp(rd, dst);
2120                                         if (!reg_alloc_dup(src->prev, dst->prev->prev->prev->prev->prev))
2121                                                 reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
2122                                         if (!reg_alloc_dup(src->prev, dst->prev))
2123                                                 reg_new_temp(rd, dst->prev);
2124                                         if (!reg_alloc_dup(src->prev->prev, dst->prev->prev))
2125                                                 reg_new_temp(rd, dst->prev->prev);
2126                                         if (!reg_alloc_dup(src->prev->prev->prev, dst->prev->prev->prev))
2127                                                 reg_new_temp(rd, dst->prev->prev->prev);
2128                                         reg_mark_copy(rd, src, src->prev->prev->prev, dst, dst->prev->prev->prev->prev->prev);
2129                                         break;
2130
2131                                         /* pop 2 push 2 swap */
2132                                         
2133                                 case ICMD_SWAP:
2134                                         /* src       --> dst->prev   (copy) */
2135                                         /* src->prev --> dst         (copy) */
2136                                                                                                 
2137                                         if (!reg_alloc_dup(src, dst->prev))
2138                                                 reg_new_temp(rd, dst->prev);
2139                                         if (!reg_alloc_dup(src->prev, dst))
2140                                                 reg_new_temp(rd, dst);
2141                                         reg_mark_copy(rd, src, src->prev, dst, dst->prev);
2142                                         break;
2143
2144                                         /* pop 2 push 1 */
2145                                         
2146                                 case ICMD_IADD:
2147                                 case ICMD_ISUB:
2148                                 case ICMD_IMUL:
2149                                 case ICMD_IDIV:
2150                                 case ICMD_IREM:
2151
2152                                 case ICMD_ISHL:
2153                                 case ICMD_ISHR:
2154                                 case ICMD_IUSHR:
2155                                 case ICMD_IAND:
2156                                 case ICMD_IOR:
2157                                 case ICMD_IXOR:
2158
2159                                 case ICMD_LADD:
2160                                 case ICMD_LSUB:
2161                                 case ICMD_LMUL:
2162                                 case ICMD_LDIV:
2163                                 case ICMD_LREM:
2164
2165                                 case ICMD_LOR:
2166                                 case ICMD_LAND:
2167                                 case ICMD_LXOR:
2168
2169                                 case ICMD_LSHL:
2170                                 case ICMD_LSHR:
2171                                 case ICMD_LUSHR:
2172
2173                                 case ICMD_FADD:
2174                                 case ICMD_FSUB:
2175                                 case ICMD_FMUL:
2176                                 case ICMD_FDIV:
2177                                 case ICMD_FREM:
2178
2179                                 case ICMD_DADD:
2180                                 case ICMD_DSUB:
2181                                 case ICMD_DMUL:
2182                                 case ICMD_DDIV:
2183                                 case ICMD_DREM:
2184
2185                                 case ICMD_LCMP:
2186                                 case ICMD_FCMPL:
2187                                 case ICMD_FCMPG:
2188                                 case ICMD_DCMPL:
2189                                 case ICMD_DCMPG:
2190                                         reg_free_temp(rd, src);
2191                                         reg_free_temp(rd, src->prev);
2192                                         reg_new_temp(rd, dst);
2193                                         break;
2194
2195                                         /* pop 1 push 1 */
2196                                         
2197                                 case ICMD_IADDCONST:
2198                                 case ICMD_ISUBCONST:
2199                                 case ICMD_IMULCONST:
2200                                 case ICMD_IMULPOW2:
2201                                 case ICMD_IDIVPOW2:
2202                                 case ICMD_IREMPOW2:
2203                                 case ICMD_IANDCONST:
2204                                 case ICMD_IORCONST:
2205                                 case ICMD_IXORCONST:
2206                                 case ICMD_ISHLCONST:
2207                                 case ICMD_ISHRCONST:
2208                                 case ICMD_IUSHRCONST:
2209
2210                                 case ICMD_LADDCONST:
2211                                 case ICMD_LSUBCONST:
2212                                 case ICMD_LMULCONST:
2213                                 case ICMD_LMULPOW2:
2214                                 case ICMD_LDIVPOW2:
2215                                 case ICMD_LREMPOW2:
2216                                 case ICMD_LANDCONST:
2217                                 case ICMD_LORCONST:
2218                                 case ICMD_LXORCONST:
2219                                 case ICMD_LSHLCONST:
2220                                 case ICMD_LSHRCONST:
2221                                 case ICMD_LUSHRCONST:
2222
2223                                 case ICMD_IFEQ_ICONST:
2224                                 case ICMD_IFNE_ICONST:
2225                                 case ICMD_IFLT_ICONST:
2226                                 case ICMD_IFGE_ICONST:
2227                                 case ICMD_IFGT_ICONST:
2228                                 case ICMD_IFLE_ICONST:
2229
2230                                 case ICMD_INEG:
2231                                 case ICMD_INT2BYTE:
2232                                 case ICMD_INT2CHAR:
2233                                 case ICMD_INT2SHORT:
2234                                 case ICMD_LNEG:
2235                                 case ICMD_FNEG:
2236                                 case ICMD_DNEG:
2237
2238                                 case ICMD_I2L:
2239                                 case ICMD_I2F:
2240                                 case ICMD_I2D:
2241                                 case ICMD_L2I:
2242                                 case ICMD_L2F:
2243                                 case ICMD_L2D:
2244                                 case ICMD_F2I:
2245                                 case ICMD_F2L:
2246                                 case ICMD_F2D:
2247                                 case ICMD_D2I:
2248                                 case ICMD_D2L:
2249                                 case ICMD_D2F:
2250
2251                                 case ICMD_CHECKCAST:
2252
2253                                 case ICMD_ARRAYLENGTH:
2254                                 case ICMD_INSTANCEOF:
2255
2256                                 case ICMD_NEWARRAY:
2257                                 case ICMD_ANEWARRAY:
2258
2259                                 case ICMD_GETFIELD:
2260                                         reg_free_temp(rd, src);
2261                                         reg_new_temp(rd, dst);
2262                                         break;
2263
2264                                         /* pop 0 push 1 */
2265                                         
2266                                 case ICMD_GETSTATIC:
2267
2268                                 case ICMD_NEW:
2269                                         reg_new_temp(rd, dst);
2270                                         break;
2271
2272                                         /* pop many push any */
2273                                         
2274                                 case ICMD_INVOKESTATIC:
2275                                 case ICMD_INVOKESPECIAL:
2276                                 case ICMD_INVOKEVIRTUAL:
2277                                 case ICMD_INVOKEINTERFACE:
2278                                         INSTRUCTION_GET_METHODDESC(iptr,md);
2279                                         i = md->paramcount;
2280                                         while (--i >= 0) {
2281                                                 reg_free_temp(rd, src);
2282                                                 src = src->prev;
2283                                         }
2284                                         if (md->returntype.type != TYPE_VOID)
2285                                                 reg_new_temp(rd, dst);
2286                                         break;
2287
2288                                 case ICMD_BUILTIN:
2289                                         bte = iptr->val.a;
2290                                         md = bte->md;
2291                                         i = md->paramcount;
2292                                         while (--i >= 0) {
2293                                                 reg_free_temp(rd, src);
2294                                                 src = src->prev;
2295                                         }
2296                                         if (md->returntype.type != TYPE_VOID)
2297                                                 reg_new_temp(rd, dst);
2298                                         break;
2299
2300                                 case ICMD_MULTIANEWARRAY:
2301                                         i = iptr->op1;
2302                                         while (--i >= 0) {
2303                                                 reg_free_temp(rd, src);
2304                                                 src = src->prev;
2305                                         }
2306                                         reg_new_temp(rd, dst);
2307                                         break;
2308
2309                                 default:
2310                                         *exceptionptr =
2311                                                 new_internalerror("Unknown ICMD %d during register allocation",
2312                                                                                   iptr->opc);
2313                                         return;
2314                                 } /* switch */
2315                                 iptr++;
2316                         } /* while instructions */
2317                 } /* if */
2318                 bptr = bptr->next;
2319         } /* while blocks */
2320 }
2321
2322
2323 #if defined(ENABLE_STATISTICS)
2324 void reg_make_statistics(jitdata *jd)
2325 {
2326         methodinfo   *m;
2327         codegendata  *cd;
2328         registerdata *rd;
2329         int i,type;
2330         s4 len;
2331         stackptr    src, src_old;
2332         stackptr    dst;
2333         instruction *iptr;
2334         basicblock  *bptr;
2335         int size_interface; /* == maximum size of in/out stack at basic block boundaries */
2336         bool in_register;
2337
2338         /* get required compiler data */
2339
2340         m  = jd->m;
2341         cd = jd->cd;
2342         rd = jd->rd;
2343
2344         in_register = true;
2345
2346         size_interface = 0;
2347
2348                 /* count how many local variables are held in memory or register */
2349                 for(i=0; i < cd->maxlocals; i++)
2350                         for (type=0; type <=4; type++)
2351                                 if (rd->locals[i][type].type != -1) { /* valid local */
2352                                         if (rd->locals[i][type].flags & INMEMORY) {
2353                                                 count_locals_spilled++;
2354                                                 in_register=false;
2355                                         }
2356                                         else
2357                                                 count_locals_register++;
2358                                 }
2359                 /* count how many stack slots are held in memory or register */
2360
2361                 bptr = m->basicblocks;
2362                 while (bptr != NULL) {
2363                         if (bptr->flags >= BBREACHED) {
2364
2365 #if defined(ENABLE_LSRA)
2366                         if (!opt_lsra) {
2367 #endif  
2368                                 /* check for memory moves from interface to BB instack */
2369                                 dst = bptr->instack;
2370                                 len = bptr->indepth;
2371                                 
2372                                 if (len > size_interface) size_interface = len;
2373
2374                                 while (dst != NULL) {
2375                                         len--;
2376                                         if (dst->varkind != STACKVAR) {
2377                                                 if ( (dst->flags & INMEMORY) ||
2378                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || 
2379                                                          ( (dst->flags & INMEMORY) && 
2380                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && 
2381                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
2382                                                 {
2383                                                         /* one in memory or both inmemory at different offsets */
2384                                                         count_mem_move_bb++;
2385                                                         in_register=false;
2386                                                 }
2387                                         }
2388
2389                                         dst = dst->prev;
2390                                 }
2391
2392                                 /* check for memory moves from BB outstack to interface */
2393                                 dst = bptr->outstack;
2394                                 len = bptr->outdepth;
2395                                 if (len > size_interface) size_interface = len;
2396
2397                                 while (dst) {
2398                                         len--;
2399                                         if (dst->varkind != STACKVAR) {
2400                                                 if ( (dst->flags & INMEMORY) || \
2401                                                          (rd->interfaces[len][dst->type].flags & INMEMORY) || \
2402                                                          ( (dst->flags & INMEMORY) && \
2403                                                            (rd->interfaces[len][dst->type].flags & INMEMORY) && \
2404                                                            (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
2405                                                 {
2406                                                         /* one in memory or both inmemory at different offsets */
2407                                                         count_mem_move_bb++;
2408                                                         in_register=false;
2409                                                 }
2410                                         }
2411
2412                                         dst = dst->prev;
2413                                 }
2414 #if defined(ENABLE_LSRA)
2415                         }
2416 #endif  
2417
2418
2419                                 dst = bptr->instack;
2420                                 iptr = bptr->iinstr;
2421                                 len = bptr->icount;
2422                                 src_old = NULL;
2423
2424                                 while (--len >= 0)  {
2425                                         src = dst;
2426                                         dst = iptr->dst;
2427
2428                                         if ((src!= NULL) && (src != src_old)) { /* new stackslot */
2429                                                 switch (src->varkind) {
2430                                                 case TEMPVAR:
2431                                                 case STACKVAR:
2432                                                         if (!(src->flags & INMEMORY)) 
2433                                                                 count_ss_register++;
2434                                                         else {
2435                                                                 count_ss_spilled++;
2436                                                                 in_register=false;
2437                                                         }                               
2438                                                         break;
2439                                                         /*                                      case LOCALVAR: */
2440                                                         /*                                              if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
2441                                                         /*                                                      count_ss_register++; */
2442                                                         /*                                              else */
2443                                                         /*                                                      count_ss_spilled++; */
2444                                                         /*                                              break; */
2445                                                 case ARGVAR:
2446                                                         if (!(src->flags & INMEMORY)) 
2447                                                                 count_argument_mem_ss++;
2448                                                         else
2449                                                                 count_argument_reg_ss++;
2450                                                         break;
2451
2452
2453                                                         /*                                              if (IS_FLT_DBL_TYPE(src->type)) { */
2454                                                         /*                                                      if (src->varnum < FLT_ARG_CNT) { */
2455                                                         /*                                                              count_ss_register++; */
2456                                                         /*                                                              break; */
2457                                                         /*                                                      } */
2458                                                         /*                                              } else { */
2459                                                         /* #if defined(__POWERPC__) */
2460                                                         /*                                                      if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
2461                                                         /* #else */
2462                                                         /*                                                      if (src->varnum < INT_ARG_CNT) { */
2463                                                         /* #endif */
2464                                                         /*                                                              count_ss_register++; */
2465                                                         /*                                                              break; */
2466                                                         /*                                                      } */
2467                                                         /*                                              } */
2468                                                         /*                                              count_ss_spilled++; */
2469                                                         /*                                              break; */
2470                                                 }
2471                                         }
2472                                         src_old = src;
2473                                         
2474                                         iptr++;
2475                                 } /* while instructions */
2476                         } /* if */
2477                         bptr = bptr->next;
2478                 } /* while blocks */
2479                 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
2480                 if (in_register) count_method_in_register++;
2481 }
2482 #endif /* defined(ENABLE_STATISTICS) */
2483
2484
2485 /*
2486  * These are local overrides for various environment variables in Emacs.
2487  * Please do not remove this and leave it at the end of the file, where
2488  * Emacs will automagically detect them.
2489  * ---------------------------------------------------------------------
2490  * Local variables:
2491  * mode: c
2492  * indent-tabs-mode: t
2493  * c-basic-offset: 4
2494  * tab-width: 4
2495  * End:
2496  * vim:noexpandtab:sw=4:ts=4:
2497  */