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