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