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