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