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