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